commit 0d4d428ff8cdf06ff155ee5772484f7523c64e99 Author: hunterXS Date: Tue Nov 25 10:21:47 2025 +0800 第一次提交瑞昱 diff --git a/bin/default_bin/disable_bank_switch/bank0/OTAHeader_Bank0_1.0.0.1-ec07866bbeadf7671d97d84486513198.bin b/bin/default_bin/disable_bank_switch/bank0/OTAHeader_Bank0_1.0.0.1-ec07866bbeadf7671d97d84486513198.bin new file mode 100644 index 0000000..96bc1d3 Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/OTAHeader_Bank0_1.0.0.1-ec07866bbeadf7671d97d84486513198.bin differ diff --git a/bin/default_bin/disable_bank_switch/bank0/Patch_MP_release_1.0.373.16_97d1534a-a35c65a75c39e17c02f822fbf02f26f6.bin b/bin/default_bin/disable_bank_switch/bank0/Patch_MP_release_1.0.373.16_97d1534a-a35c65a75c39e17c02f822fbf02f26f6.bin new file mode 100644 index 0000000..a55398a Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/Patch_MP_release_1.0.373.16_97d1534a-a35c65a75c39e17c02f822fbf02f26f6.bin differ diff --git a/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/App.trace b/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/App.trace new file mode 100644 index 0000000..d326b7b Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/App.trace differ diff --git a/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/app_MP_sdk_1.3.1.1_483dbbfa-6c9609bb373286c000f8bb4593f25a11.bin b/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/app_MP_sdk_1.3.1.1_483dbbfa-6c9609bb373286c000f8bb4593f25a11.bin new file mode 100644 index 0000000..6ee3c8f Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/ble_peripheral/app_MP_sdk_1.3.1.1_483dbbfa-6c9609bb373286c000f8bb4593f25a11.bin differ diff --git a/bin/default_bin/disable_bank_switch/bank0/fsbl_MP_master##_1.1.0.0_dea0248d-818a246824b295b221dda5e3cc347abd.bin b/bin/default_bin/disable_bank_switch/bank0/fsbl_MP_master##_1.1.0.0_dea0248d-818a246824b295b221dda5e3cc347abd.bin new file mode 100644 index 0000000..d568b96 Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/fsbl_MP_master##_1.1.0.0_dea0248d-818a246824b295b221dda5e3cc347abd.bin differ diff --git a/bin/default_bin/disable_bank_switch/bank0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin b/bin/default_bin/disable_bank_switch/bank0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin new file mode 100644 index 0000000..2d07506 Binary files /dev/null and b/bin/default_bin/disable_bank_switch/bank0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin differ diff --git a/bin/default_bin/disable_bank_switch/configFile_2024.06.12.09-e43ac4237b5c34a3a8ddf60f7fbff42b.bin b/bin/default_bin/disable_bank_switch/configFile_2024.06.12.09-e43ac4237b5c34a3a8ddf60f7fbff42b.bin new file mode 100644 index 0000000..e090fab Binary files /dev/null and b/bin/default_bin/disable_bank_switch/configFile_2024.06.12.09-e43ac4237b5c34a3a8ddf60f7fbff42b.bin differ diff --git a/bin/default_bin/disable_bank_switch/flash map.ini b/bin/default_bin/disable_bank_switch/flash map.ini new file mode 100644 index 0000000..e8f34b2 --- /dev/null +++ b/bin/default_bin/disable_bank_switch/flash map.ini @@ -0,0 +1,70 @@ +[Property] +IC_TYPE=554542 +FLASH_SIZE=512 +OTA_SWITCH=Disable +IMG_HDR_SIZE=1024 +[HighLevel] +OEM_CFG_ADDR=0x00801000 +OEM_CFG_SIZE=0x00001000 +OTA_BANK0_ADDR=0x00802000 +OTA_BANK0_SIZE=0x00055000 +OTA_BANK1_ADDR=0x00857000 +OTA_BANK1_SIZE=0x00000000 +FTL_ADDR=0x00857000 +FTL_SIZE=0x00004000 +OTA_TMP_ADDR=0x0085B000 +OTA_TMP_SIZE=0x00025000 +USER_DATA1_ADDR=0x00880000 +USER_DATA1_SIZE=0x00000000 +USER_DATA2_ADDR=0x00880000 +USER_DATA2_SIZE=0x00000000 +[OTABank] +BANK0_OTA_HDR_ADDR=0x00802000 +BANK0_OTA_HDR_SIZE=0x00001000 +BANK0_FSBL_ADDR=0x0080D000 +BANK0_FSBL_SIZE=0x00001000 +BANK0_ROM_PATCH_ADDR=0x00803000 +BANK0_ROM_PATCH_SIZE=0x0000A000 +BANK0_UPPERSTACK_ADDR=0x0080E000 +BANK0_UPPERSTACK_SIZE=0x00024000 +BANK0_APP_ADDR=0x00832000 +BANK0_APP_SIZE=0x00025000 +BANK0_APP_DATA1_ADDR=0x00857000 +BANK0_APP_DATA1_SIZE=0x00000000 +BANK0_APP_DATA2_ADDR=0x00857000 +BANK0_APP_DATA2_SIZE=0x00000000 +BANK0_APP_DATA3_ADDR=0x00857000 +BANK0_APP_DATA3_SIZE=0x00000000 +BANK0_APP_DATA4_ADDR=0x00857000 +BANK0_APP_DATA4_SIZE=0x00000000 +BANK0_APP_DATA5_ADDR=0x00857000 +BANK0_APP_DATA5_SIZE=0x00000000 +BANK0_APP_DATA6_ADDR=0x00857000 +BANK0_APP_DATA6_SIZE=0x00000000 +BANK1_OTA_HDR_ADDR=0x00000000 +BANK1_OTA_HDR_SIZE=0x00000000 +BANK1_FSBL_ADDR=0x00000000 +BANK1_FSBL_SIZE=0x00000000 +BANK1_ROM_PATCH_ADDR=0x00000000 +BANK1_ROM_PATCH_SIZE=0x00000000 +BANK1_UPPERSTACK_ADDR=0x00000000 +BANK1_UPPERSTACK_SIZE=0x00000000 +BANK1_APP_ADDR=0x00000000 +BANK1_APP_SIZE=0x00000000 +BANK1_APP_DATA1_ADDR=0x00000000 +BANK1_APP_DATA1_SIZE=0x00000000 +BANK1_APP_DATA2_ADDR=0x00000000 +BANK1_APP_DATA2_SIZE=0x00000000 +BANK1_APP_DATA3_ADDR=0x00000000 +BANK1_APP_DATA3_SIZE=0x00000000 +BANK1_APP_DATA4_ADDR=0x00000000 +BANK1_APP_DATA4_SIZE=0x00000000 +BANK1_APP_DATA5_ADDR=0x00000000 +BANK1_APP_DATA5_SIZE=0x00000000 +BANK1_APP_DATA6_ADDR=0x00000000 +BANK1_APP_DATA6_SIZE=0x00000000 +[OTAHeader] +OTA_BIN_VER1=1 +OTA_BIN_VER2=0 +OTA_BIN_VER3=0 +OTA_BIN_VER4=1 diff --git a/bin/default_bin/disable_bank_switch/flash_map.h b/bin/default_bin/disable_bank_switch/flash_map.h new file mode 100644 index 0000000..2eae3b4 --- /dev/null +++ b/bin/default_bin/disable_bank_switch/flash_map.h @@ -0,0 +1,133 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** +* @file flash_map.h +* @brief Flash Layout Configuration, and flash layout must be changed with config file! +* @note flash_map.h must be generated by FlashMapGenerateTool! +* ************************************************************************************* +*/ + +#ifndef _FLASH_MAP_H_ +#define _FLASH_MAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* +* Flash Layout +*============================================================================*/ +/* Flash total size 512KB +example: + 1) Reserved: 4K (0x00800000) + 2) OEM Header: 4K (0x00801000) + 3) OTA Bank0: 340K (0x00802000) + a) OTA Header 4K (0x00802000) + b) Secure boot loader 4K (0x0080D000) + c) Patch code 40K (0x00803000) + d) Upperstack Code 144K (0x0080E000) + e) APP code 148K (0x00832000) + f) APP data1 0K (0x00857000) + g) APP data2 0K (0x00857000) + h) APP data3 0K (0x00857000) + i) APP data4 0K (0x00857000) + j) APP data5 0K (0x00857000) + k) APP data6 0K (0x00857000) + 4) OTA Bank1: 0K (0x00857000) + a) OTA Header 0K (0x00000000) + b) Secure boot loader 0K (0x00000000) + c) Patch code 0K (0x00000000) + d) Upperstack Code 0K (0x00000000) + e) APP code 0K (0x00000000) + f) APP data1 0K (0x00000000) + g) APP data2 0K (0x00000000) + h) APP data3 0K (0x00000000) + i) APP data4 0K (0x00000000) + j) APP data5 0K (0x00000000) + k) APP data6 0K (0x00000000) + 5) FTL: 16K (0x00857000) + 6) OTA Tmp: 148K (0x0085B000) + 7) user data1: 0K (0x00880000) + 8) user data2: 0K (0x00880000) +*/ + +/*============================================================================* +* Flash Layout Configuration (Generated by FlashMapGenerateTool) +*============================================================================*/ + +#define FLASH_ADDR 0x00800000 //Fixed +#define FLASH_SIZE 0x00080000 //512K Bytes + +/* ========== High Level Flash Layout Configuration ========== */ +#define RESERVED_ADDR 0x00800000 +#define RESERVED_SIZE 0x00001000 //4K Bytes +#define OEM_CFG_ADDR 0x00801000 +#define OEM_CFG_SIZE 0x00001000 //4K Bytes +#define OTA_BANK0_ADDR 0x00802000 +#define OTA_BANK0_SIZE 0x00055000 //340K Bytes +#define OTA_BANK1_ADDR 0x00857000 +#define OTA_BANK1_SIZE 0x00000000 //0K Bytes +#define FTL_ADDR 0x00857000 +#define FTL_SIZE 0x00004000 //16K Bytes +#define OTA_TMP_ADDR 0x0085B000 +#define OTA_TMP_SIZE 0x00025000 //148K Bytes +#define USER_DATA1_ADDR 0x00880000 +#define USER_DATA1_SIZE 0x00000000 //0K Bytes +#define USER_DATA2_ADDR 0x00880000 +#define USER_DATA2_SIZE 0x00000000 //0K Bytes + +/* ========== OTA Bank0 Flash Layout Configuration ========== */ +#define BANK0_OTA_HEADER_ADDR 0x00802000 +#define BANK0_OTA_HEADER_SIZE 0x00001000 //4K Bytes +#define BANK0_SECURE_BOOT_ADDR 0x0080D000 +#define BANK0_SECURE_BOOT_SIZE 0x00001000 //4K Bytes +#define BANK0_ROM_PATCH_ADDR 0x00803000 +#define BANK0_ROM_PATCH_SIZE 0x0000A000 //40K Bytes +#define BANK0_UPPERSTACK_ADDR 0x0080E000 +#define BANK0_UPPERSTACK_SIZE 0x00024000 //144K Bytes +#define BANK0_APP_ADDR 0x00832000 +#define BANK0_APP_SIZE 0x00025000 //148K Bytes +#define BANK0_APP_DATA1_ADDR 0x00857000 +#define BANK0_APP_DATA1_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA2_ADDR 0x00857000 +#define BANK0_APP_DATA2_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA3_ADDR 0x00857000 +#define BANK0_APP_DATA3_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA4_ADDR 0x00857000 +#define BANK0_APP_DATA4_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA5_ADDR 0x00857000 +#define BANK0_APP_DATA5_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA6_ADDR 0x00857000 +#define BANK0_APP_DATA6_SIZE 0x00000000 //0K Bytes + +/* ========== OTA Bank1 Flash Layout Configuration ========== */ +#define BANK1_OTA_HEADER_ADDR 0x00000000 +#define BANK1_OTA_HEADER_SIZE 0x00000000 //0K Bytes +#define BANK1_SECURE_BOOT_ADDR 0x00000000 +#define BANK1_SECURE_BOOT_SIZE 0x00000000 //0K Bytes +#define BANK1_ROM_PATCH_ADDR 0x00000000 +#define BANK1_ROM_PATCH_SIZE 0x00000000 //0K Bytes +#define BANK1_UPPERSTACK_ADDR 0x00000000 +#define BANK1_UPPERSTACK_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_ADDR 0x00000000 +#define BANK1_APP_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA1_ADDR 0x00000000 +#define BANK1_APP_DATA1_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA2_ADDR 0x00000000 +#define BANK1_APP_DATA2_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA3_ADDR 0x00000000 +#define BANK1_APP_DATA3_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA4_ADDR 0x00000000 +#define BANK1_APP_DATA4_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA5_ADDR 0x00000000 +#define BANK1_APP_DATA5_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA6_ADDR 0x00000000 +#define BANK1_APP_DATA6_SIZE 0x00000000 //0K Bytes + + +#ifdef __cplusplus +} +#endif +/** @} */ /* _FLASH_MAP_H_ */ +#endif diff --git a/bin/gcc/adc.a b/bin/gcc/adc.a new file mode 100644 index 0000000..0b41d6c Binary files /dev/null and b/bin/gcc/adc.a differ diff --git a/bin/gcc/auto_k_rf.a b/bin/gcc/auto_k_rf.a new file mode 100644 index 0000000..9a6256f Binary files /dev/null and b/bin/gcc/auto_k_rf.a differ diff --git a/bin/gcc/bee3_sdk.a b/bin/gcc/bee3_sdk.a new file mode 100644 index 0000000..d7ad5e0 Binary files /dev/null and b/bin/gcc/bee3_sdk.a differ diff --git a/bin/gcc/gap_utils.a b/bin/gcc/gap_utils.a new file mode 100644 index 0000000..10558f6 Binary files /dev/null and b/bin/gcc/gap_utils.a differ diff --git a/bin/gcc/ima_adpcm_lib.a b/bin/gcc/ima_adpcm_lib.a new file mode 100644 index 0000000..2984af6 Binary files /dev/null and b/bin/gcc/ima_adpcm_lib.a differ diff --git a/bin/gcc/msbc_lib.a b/bin/gcc/msbc_lib.a new file mode 100644 index 0000000..81061cd Binary files /dev/null and b/bin/gcc/msbc_lib.a differ diff --git a/bin/gcc/rom_symbol_gcc.axf b/bin/gcc/rom_symbol_gcc.axf new file mode 100644 index 0000000..2b4f733 --- /dev/null +++ b/bin/gcc/rom_symbol_gcc.axf @@ -0,0 +1,427 @@ +vAssertHandler = 0x00000209 ; +ulSetInterruptMaskFromISR = 0x0000024d ; +vClearInterruptMaskFromISR = 0x00000255 ; +WDG_SystemReset = 0x0000029d ; +__aeabi_memcpy4 = 0x000002a9 ; +__aeabi_memcpy8 = 0x000002a9 ; +RamVectorTableInit = 0x000034d1 ; +RamVectorTableUpdate = 0x000034f7 ; +LOGUARTDriverInit = 0x000037ed ; +DumpRawMemory = 0x000043ab ; +dump_raw_memory_all = 0x00004519 ; +hardfault_print_buffered_log = 0x00004573 ; +ROM_Default_Handler = 0x000047e7 ; +SystemCall = 0x0000491b ; +SystemCall_Stack = 0x00004927 ; +update_ram_layout = 0x00004a79 ; +get_active_ota_bank_addr = 0x000053a5 ; +btxfcs = 0x000054ed ; +PPB_BufSwitch = 0x00005665 ; +PPB_Init = 0x00005689 ; +PPB_Uninit = 0x000056dd ; +PPB_Init_DLPS_Restore = 0x00005701 ; +PPB_Write = 0x00005709 ; +PPB_ClearOutputBuffer = 0x000057db ; +LogUartTxChar = 0x00005811 ; +log_timestamp_get = 0x00005853 ; +VSnprintf = 0x00005893 ; +log_direct = 0x00005a07 ; +log_buffer = 0x00005aa9 ; +log_index = 0x00005bcd ; +log_snoop = 0x00005cdf ; +trace_bdaddr = 0x00005ddf ; +trace_string = 0x00005e6b ; +trace_binary = 0x00005f07 ; +LogBufferLowerStack = 0x00005f9f ; +LogBufferLowerStackData = 0x000060c5 ; +log_module_trace_init = 0x000061a3 ; +log_module_trace_set = 0x000061d3 ; +log_module_bitmap_trace_set = 0x0000621f ; +LogUartDMAStart = 0x00006323 ; +LogDMA_SM_Dispatch = 0x00006335 ; +LogUartDMAInit = 0x000063bd ; +LogUartDMAIdleHook = 0x000064b1 ; +log_pm_check = 0x0000651f ; +hw_aes_encrypt128_use_dma = 0x0000675d ; +hw_aes_decrypt128_use_dma = 0x000067a1 ; +aes128_ecb_encrypt = 0x000067e5 ; +aes128_ecb_decrypt = 0x00006841 ; +aes128_ecb_encrypt_msb2lsb = 0x0000689b ; +aes128_ecb_decrypt_msb2lsb = 0x000068b3 ; +aes256_ecb_encrypt = 0x000068cb ; +aes256_ecb_decrypt = 0x00006927 ; +aes256_ecb_encrypt_msb2lsb = 0x00006981 ; +aes256_ecb_decrypt_msb2lsb = 0x00006999 ; +hw_aes_decrypt_16byte = 0x000069ed ; +ftl_ioctl = 0x000075d3 ; +ftl_load = 0x00007b1f ; +ftl_save = 0x00007b33 ; +ftl_init = 0x00007c45 ; +hardfault_dump = 0x00007df1 ; +flash_dump_flash_info = 0x0000805f ; +flash_get_flash_exist = 0x000080b3 ; +flash_get_bank_addr = 0x000080b9 ; +flash_get_bank_size = 0x0000813b ; +flash_erase_locked = 0x000081a1 ; +flash_ioctl = 0x000081f7 ; +flash_write_locked = 0x00008601 ; +flash_auto_write_locked = 0x00008629 ; +flash_auto_write_buffer_locked = 0x0000864b ; +flash_read_locked = 0x00008671 ; +flash_auto_read_locked = 0x00008699 ; +flash_split_read_locked = 0x000086b7 ; +flash_auto_dma_read_locked = 0x000086e1 ; +flash_auto_seq_trans_dma_read_locked = 0x00008709 ; +flash_try_high_speed = 0x00008731 ; +flash_get_block_protect_locked = 0x000088f1 ; +flash_set_block_protect_locked = 0x00008917 ; +flash_sw_protect_unlock_by_addr_locked = 0x0000893d ; +crc8EtsGen = 0x000089cd ; +crc8EtsCheck = 0x000089ed ; +set_hci_mode_flag = 0x00008a1d ; +check_hci_mode_flag = 0x00008a47 ; +check_image_chksum = 0x00008a5d ; +check_header_valid = 0x00008a83 ; +get_header_addr_by_img_id = 0x00008ae3 ; +get_active_bank_image_size_by_img_id = 0x00008b3f ; +is_ota_support_bank_switch = 0x00008b7b ; +get_temp_ota_bank_addr_by_img_id = 0x00008b95 ; +get_temp_ota_bank_size_by_img_id = 0x00008c07 ; +get_active_bank_image_version = 0x00008c73 ; +platform_random = 0x00008d3f ; +flash_erase = 0x00009fcf ; +flash_set_bit = 0x0000a559 ; +flash_get_bit = 0x0000a561 ; +flash_write = 0x0000a56d ; +flash_auto_write = 0x0000a875 ; +power_manager_get_unit_status = 0x0000d0c9 ; +power_manager_suspend_all = 0x0000d207 ; +power_manager_resume_all = 0x0000d211 ; +platform_pm_set_power_mode = 0x0000d755 ; +platform_pm_get_power_mode = 0x0000d769 ; +platform_pm_get_error_code = 0x0000d76f ; +platform_pm_get_refuse_reason = 0x0000d775 ; +platform_pm_get_statistics = 0x0000d78f ; +platform_pm_get_wakeup_reason = 0x0000d7b9 ; +platform_pm_register_callback_func = 0x0000d7c9 ; +platform_pm_stop_all_non_excluded_timer = 0x0000d8cb ; +platform_rtc_get_counter = 0x0000e81b ; +vListInitialise = 0x0000e885 ; +vListInitialiseItem = 0x0000e89b ; +vListInsertEnd = 0x0000e8a1 ; +vListInsert = 0x0000e8b9 ; +uxListRemove = 0x0000e8e9 ; +xQueueGenericReset = 0x0000e911 ; +xQueueGenericCreate = 0x0000e985 ; +xQueueGenericSend = 0x0000eab3 ; +xQueueCreateMutex = 0x0000ebed ; +xQueueGetMutexHolder = 0x0000ec11 ; +xQueueGetMutexHolderFromISR = 0x0000ec2d ; +xQueueGiveMutexRecursive = 0x0000ec4d ; +xQueueSemaphoreTake = 0x0000ec85 ; +xQueueTakeMutexRecursive = 0x0000edef ; +xQueueCreateCountingSemaphore = 0x0000ee29 ; +xQueueGenericSendFromISR = 0x0000ee5f ; +xQueueGiveFromISR = 0x0000eefd ; +xQueueReceive = 0x0000efaf ; +xQueuePeek = 0x0000f0c7 ; +xQueueReceiveFromISR = 0x0000f1f1 ; +xQueuePeekFromISR = 0x0000f26f ; +uxQueueMessagesWaiting = 0x0000f2d3 ; +uxQueueSpacesAvailable = 0x0000f2f3 ; +uxQueueMessagesWaitingFromISR = 0x0000f317 ; +vQueueDelete = 0x0000f32d ; +uxQueueGetQueueNumber = 0x0000f347 ; +vQueueSetQueueNumber = 0x0000f34b ; +ucQueueGetQueueType = 0x0000f34f ; +xQueueIsQueueEmptyFromISR = 0x0000f355 ; +xQueueIsQueueFullFromISR = 0x0000f375 ; +vQueueWaitForMessageRestricted = 0x0000f395 ; +xTaskCreate = 0x0000f51b ; +vTaskDelete = 0x0000f5dd ; +xTaskIncrementTick = 0x0000f683 ; +xTaskResumeAll = 0x0000f741 ; +vTaskSuspendAll = 0x0000f85b ; +vTaskDelayUntil = 0x0000f865 ; +vTaskDelay = 0x0000f8d3 ; +eTaskGetState = 0x0000f907 ; +uxTaskPriorityGet = 0x0000f96b ; +uxTaskPriorityGetFromISR = 0x0000f985 ; +vTaskPrioritySet = 0x0000f99f ; +vTaskSwitchContext = 0x0000fa33 ; +vTaskSuspend = 0x0000fadb ; +vTaskResume = 0x0000fb8f ; +xTaskResumeFromISR = 0x0000fc1d ; +vTaskStartScheduler = 0x0000fc87 ; +vTaskEndScheduler = 0x0000fce7 ; +xTaskGetTickCount2 = 0x0000fcf7 ; +xTaskGetTickCount = 0x0000fcfd ; +xTaskGetTickCountFromISR = 0x0000fd03 ; +uxTaskGetNumberOfTasks = 0x0000fd09 ; +pcTaskGetName = 0x0000fd0f ; +vTaskGetInfo = 0x0000fd33 ; +uxTaskGetSystemState = 0x0000fdfb ; +xTaskGetIdleTaskHandle = 0x0000fe85 ; +vTaskPlaceOnEventList = 0x0000fe9f ; +vTaskPlaceOnUnorderedEventList = 0x0000fec9 ; +vTaskPlaceOnEventListRestricted = 0x0000ff0f ; +xTaskRemoveFromEventList = 0x0000ff43 ; +vTaskRemoveFromUnorderedEventList = 0x0000ffa7 ; +vTaskSetTimeOutState = 0x0001003d ; +vTaskInternalSetTimeOutState = 0x0001005f ; +xTaskCheckForTimeOut = 0x0001006b ; +vTaskMissedYield = 0x000100d1 ; +uxTaskGetTaskNumber = 0x000100d9 ; +vTaskSetTaskNumber = 0x000100e1 ; +uxTaskGetStackHighWaterMark = 0x000100e9 ; +xTaskGetCurrentTaskHandle = 0x000100fb ; +xTaskGetSchedulerState = 0x00010101 ; +xTaskPriorityInherit = 0x0001011b ; +xTaskPriorityDisinherit = 0x0001018b ; +vTaskPriorityDisinheritAfterTimeout = 0x000101fb ; +uxTaskResetEventItemValue = 0x0001027b ; +pvTaskIncrementMutexHeldCount = 0x0001028f ; +ulTaskNotifyTake = 0x000102a3 ; +xTaskNotifyWait = 0x000102fd ; +xTaskGenericNotify = 0x00010371 ; +xTaskGenericNotifyFromISR = 0x00010441 ; +vTaskNotifyGiveFromISR = 0x00010511 ; +xTaskNotifyStateClear = 0x0001059f ; +vTaskStatusDump = 0x000105c9 ; +xTimerGenericCommand = 0x000108e1 ; +xTimerCreateTimerTask = 0x00010b15 ; +xTimerCreate = 0x00010b5d ; +xTimerGetTimerDaemonTaskHandle = 0x00010bd9 ; +xTimerGetPeriod = 0x00010bf1 ; +vTimerSetReloadMode = 0x00010c07 ; +xTimerGetExpiryTime = 0x00010c39 ; +pcTimerGetName = 0x00010c4f ; +vTimerGetNextTimeoutItem = 0x00010c65 ; +xTimerGetAutoReload = 0x00010ca1 ; +xTimerIsTimerActive = 0x00010cab ; +xTimerIsTimerActiveFromISR = 0x00010cd5 ; +pvTimerGetTimerID = 0x00010d01 ; +vTimerSetTimerID = 0x00010d1f ; +xTimerPendFunctionCallFromISR = 0x00010d3f ; +xTimerPendFunctionCall = 0x00010d5f ; +uxTimerGetTimerNumber = 0x00010d99 ; +vTimerSetTimerNumber = 0x00010d9d ; +dumpAllUsedTimer = 0x00010daf ; +pxPortInitialiseStack = 0x00010fb9 ; +xPortStartScheduler = 0x0001100b ; +vPortEndScheduler = 0x00011033 ; +vPortYield = 0x0001104d ; +vPortEnterCritical = 0x0001105f ; +vPortExitCritical = 0x00011081 ; +rtlEnterCritical = 0x000110c5 ; +rtlExitCritical = 0x000110e1 ; +vTimerCreateFailedHook = 0x000111a7 ; +pvPortMalloc = 0x000113a3 ; +pvPortMalloc_auto_type = 0x000114d3 ; +vPortFree = 0x00011505 ; +xPortGetFreeHeapSize = 0x00011585 ; +xPortGetMinimumEverFreeHeapSize = 0x000115c7 ; +vPortInitialiseBlocks = 0x000115d1 ; +hw_aes_init = 0x00011dff ; +hw_aes_cpu_operate = 0x00011f6d ; +hw_aes_set_dma_tx_done = 0x00011f79 ; +hw_aes_set_dma_rx_done = 0x00011f7f ; +hw_aes_dma_operate = 0x00011f85 ; +hw_aes_dma_interrupt_disable = 0x0001210b ; +hw_aes_is_dma_rx_done = 0x000121af ; +hw_aes_is_dma_tx_done = 0x000121b5 ; +hw_aes_dma_done = 0x000121bb ; +hw_aes_set_dma_move_src = 0x000121c5 ; +hw_aes_set_dma_move_dst = 0x000121e5 ; +hw_aes_set_dma_carry_size = 0x000121eb ; +aes_cmac_inverse = 0x0001235f ; +get_secure_reg_cfg_val = 0x00012417 ; +Pinmux_Deinit_rom = 0x0001254b ; +WDG_ClockEnable = 0x00012959 ; +WDG_Config = 0x00012977 ; +WDG_Enable = 0x000129bb ; +WDG_Disable = 0x000129d5 ; +WDG_Restart = 0x000129ef ; +reset_reason_get = 0x00012b71 ; +os_mem_alloc_intern = 0x00012c31 ; +os_mem_zalloc_intern = 0x00012c8b ; +os_mem_aligned_alloc_intern = 0x00012ced ; +os_mem_free = 0x00012d4d ; +os_mem_aligned_free = 0x00012d69 ; +os_mem_peek = 0x00012d85 ; +os_mem_check_heap_usage = 0x00012da7 ; +os_msg_queue_create_intern = 0x00012de1 ; +os_msg_queue_delete_intern = 0x00012e39 ; +os_msg_queue_peek_intern = 0x00012e83 ; +os_msg_send_intern = 0x00012ed7 ; +os_msg_recv_intern = 0x00012f33 ; +os_msg_peek_intern = 0x00012f91 ; +os_queue_init = 0x00013011 ; +os_queue_in = 0x0001301b ; +os_queue_out = 0x0001304b ; +os_queue_peek = 0x0001307f ; +os_queue_insert = 0x00013083 ; +os_queue_delete = 0x000130c3 ; +os_systick_handler = 0x00013131 ; +os_delay = 0x00013147 ; +os_sys_time_get = 0x00013163 ; +os_sys_tick_get = 0x00013181 ; +os_sys_tick_increase = 0x0001319f ; +os_sched_start = 0x000131c3 ; +os_sched_stop = 0x000131e1 ; +os_sched_suspend = 0x000131ff ; +os_sched_resume = 0x0001321d ; +os_sched_is_start = 0x0001323b ; +os_sched_state_get = 0x00013259 ; +os_vector_table_update = 0x00013277 ; +os_init = 0x0001328d ; +os_lock = 0x000132d9 ; +os_unlock = 0x000132f5 ; +os_sem_create = 0x00013311 ; +os_sem_delete = 0x0001333d ; +os_sem_take = 0x00013361 ; +os_sem_give = 0x00013389 ; +os_mutex_create = 0x000133ad ; +os_mutex_delete = 0x000133d1 ; +os_mutex_take = 0x000133f5 ; +os_mutex_give = 0x0001341d ; +os_task_create = 0x00013469 ; +os_task_delete = 0x000134a5 ; +os_task_suspend = 0x000134c9 ; +os_task_resume = 0x000134ed ; +os_task_yield = 0x00013511 ; +os_task_handle_get = 0x0001352f ; +os_task_priority_get = 0x00013553 ; +os_task_priority_set = 0x0001357b ; +os_task_status_dump = 0x000135a3 ; +os_task_dlps_return_idle_task = 0x000135b9 ; +os_timer_id_get = 0x000135f9 ; +os_timer_create = 0x00013635 ; +os_timer_start = 0x00013671 ; +os_timer_restart = 0x00013695 ; +os_timer_stop = 0x000136bd ; +os_timer_delete = 0x000136e1 ; +os_timer_dump = 0x00013705 ; +os_timer_state_get = 0x00013723 ; +os_timer_init = 0x0001375f ; +os_timer_number_get = 0x00013775 ; +os_timer_pendcall = 0x0001379d ; +os_timer_next_timeout_value_get = 0x000137cb ; +osif_timer_create = 0x00013f9f ; +BB_write_baseband_register = 0x00014901 ; +bzdma_ble_set_segment_valid_bitmap = 0x00014a91 ; +bzdma_send_packet_to_ble_data_ring_fifo = 0x00015369 ; +bzdma_update_fw_rptr_of_ble_data_ring_fifo = 0x0001544b ; +bzdma_wait_rxcmd_complete = 0x0001557d ; +bzdma_send_burst_rxcmd_and_wait_complete = 0x000155a3 ; +rtk_write_modem_radio_reg = 0x000184ad ; +rtk_read_modem_radio_reg = 0x00018515 ; +hci_handle_le_receiver_test = 0x0001a81b ; +hci_handle_le_test_end = 0x0001ac3b ; +btaon_fast_read = 0x00032f61 ; +btaon_fast_read_8b = 0x00032f75 ; +btaon_fast_read_safe = 0x00032f95 ; +btaon_fast_read_safe_8b = 0x00032fb1 ; +btaon_fast_write = 0x00032fdb ; +btaon_fast_write_8b = 0x00032ffb ; +btaon_fast_write_safe = 0x00033039 ; +btaon_fast_write_safe_8b = 0x00033063 ; +btaon_fast_update = 0x000330a9 ; +btaon_fast_update_8b = 0x000330c3 ; +btaon_fast_update_safe = 0x000330df ; +btaon_fast_update_safe_8b = 0x000330fb ; +init_dft = 0x0003d547 ; +modem_dft = 0x0003d66f ; +deinit_dft = 0x0003d751 ; +btmac_pm_check_active = 0x0003dee9 ; +btmac_pm_check_inactive = 0x0003defd ; +btmac_pm_initiate_wakeup = 0x0003df39 ; +btmac_pm_set_power_mode = 0x0003df43 ; +btmac_pm_get_error_code = 0x0003df4f ; +btmac_pm_get_wakeup_reason = 0x0003df55 ; +btmac_pm_get_statistics = 0x0003df5b ; +btmac_pm_check_rom = 0x0003e4a9 ; +dfu_dump_header = 0x0003ed01 ; +dfu_set_ready = 0x0003ed1b ; +dfu_set_obsolete = 0x0003ed25 ; +dfu_check_ota_mode_flag = 0x0003ed31 ; +dfu_reset = 0x0003ed45 ; +dfu_process_crc = 0x0003edc3 ; +dfu_process_sha256 = 0x0003ee99 ; +SHA256_Init = 0x0003f4ad ; +SHA256_Update = 0x0003f4d7 ; +SHA256_Final = 0x0003f517 ; +SHA256 = 0x0003f5d5 ; +setlocale = 0x0003f795 ; +memcmp = 0x0003f7a9 ; +strlen = 0x0003f805 ; +__aeabi_memcpy = 0x0003f849 ; +__rt_memcpy = 0x0003f849 ; +memcpy = 0x0003f849 ; +__aeabi_memset = 0x0003f8cb ; +_memset_w = 0x0003f8dd ; +_memset = 0x0003f8f7 ; +__aeabi_memclr = 0x0003f915 ; +__rt_memclr = 0x0003f915 ; +__aeabi_memclr4 = 0x0003f919 ; +__aeabi_memclr8 = 0x0003f919 ; +__rt_memclr_w = 0x0003f919 ; +exit = 0x000409b9 ; +pMCU_PPB = 0x00200104 ; +pLogDMA_SM = 0x00200108 ; +socv_ft_data = 0x00200110 ; +platform_delay_us = 0x0020011c ; +platform_delay_ms = 0x00200120 ; +otp = 0x00200164 ; +SystemCpuClock = 0x00200524 ; +init_true_random_generator = 0x00200854 ; +get_true_random_number = 0x00200858 ; +bzdma_supported_le_max_seg_num = 0x00200861 ; +BB_handle_psd_end_intr = 0x002008a0 ; +BB_handle_psd_end_intr_in_isr = 0x002008a8 ; +rtk_write_rfc_reg_pi = 0x002008b0 ; +rtk_read_modem_radio_reg_pi = 0x002008b4 ; +rtk_write_modem_radio_reg_pi = 0x002008b8 ; +rtk_ioq_read_rfc_reg = 0x002008e0 ; +rtk_update_rfc_reg_pi = 0x002008e4 ; +lc_calculate_log_from_rssi = 0x002008f4 ; +ll_hw_init = 0x00200b0c ; +phy_auto_gated_on = 0x00200ea0 ; +phy_auto_gated_off = 0x00200ea4 ; +le_tx_power_to_txgain_index = 0x00200ef0 ; +btmac_pm_system = 0x002010d4 ; +app_pre_main = 0x002011d0 ; +upperstack_entry = 0x002011d4 ; +app_main = 0x002011d8 ; +log_seq_num = 0x002011e8 ; +is_log_init = 0x002011ea ; +flash_sem = 0x00201228 ; +flash_device_info = 0x00201258 ; +pxCurrentTCB = 0x00201340 ; +xTickCount = 0x0020134c ; +uxPendedTicks = 0x00201358 ; +uxSchedulerSuspended = 0x00201370 ; +pTaskHandleList = 0x00201374 ; +uxTimerCreateCount = 0x00201474 ; +uxTimerDeleteCount = 0x00201476 ; +xTimerQueue = 0x00201478 ; +pxTimerPool = 0x00201488 ; +puxUsedTimerPoolMask = 0x0020148c ; +xFreeBytesRemaining = 0x002014d8 ; +xMinimumEverFreeBytesRemaining = 0x002014e0 ; +xHeapTotalSize = 0x002014e8 ; +xStart = 0x002014f0 ; +app_cb_wdg_reset = 0x00201514 ; +patch_osif_os_sys_time_get = 0x00201580 ; +patch_osif_os_msg_send_intern = 0x00201608 ; +patch_osif_os_timer_create = 0x00201644 ; +Patch_Dump_CPU_Register_and_Memory = 0x00201694 ; +patch_vTaskSwitchContext = 0x002016c0 ; +patch_traceTaskSwitchIn = 0x002016c4 ; +patch_HardFaultRecord_TryToSave = 0x0020182c ; +low_task_handle = 0x00201858 ; +Bzdma_Manager = 0x00201888 ; +g_modem_psd_report_entry_num = 0x002020de ; +g_modem_psd_report_array = 0x002020ec ; +g_efuse_modem_psd_setting_1 = 0x00202938 ; +rcp_BTMAC_Handler = 0x00202c94 ; diff --git a/bin/gcc/sbc_lib.a b/bin/gcc/sbc_lib.a new file mode 100644 index 0000000..3b8c690 Binary files /dev/null and b/bin/gcc/sbc_lib.a differ diff --git a/bin/gcc/system_trace.a b/bin/gcc/system_trace.a new file mode 100644 index 0000000..0f882f5 Binary files /dev/null and b/bin/gcc/system_trace.a differ diff --git a/bin/mdk/ROM.lib b/bin/mdk/ROM.lib new file mode 100644 index 0000000..f5a425f --- /dev/null +++ b/bin/mdk/ROM.lib @@ -0,0 +1,428 @@ +## ARM Linker, 5060750: Last Updated: Fri Jun 04 16:49:01 2021 +0x00000209 T vAssertHandler +0x0000024d T ulSetInterruptMaskFromISR +0x00000255 T vClearInterruptMaskFromISR +0x0000029d T WDG_SystemReset +0x000002a9 T __aeabi_memcpy4 +0x000002a9 T __aeabi_memcpy8 +0x000034d1 T RamVectorTableInit +0x000034f7 T RamVectorTableUpdate +0x000037ed T LOGUARTDriverInit +0x000043ab T DumpRawMemory +0x00004519 T dump_raw_memory_all +0x00004573 T hardfault_print_buffered_log +0x000047e7 T ROM_Default_Handler +0x0000491b T SystemCall +0x00004927 T SystemCall_Stack +0x00004a79 T update_ram_layout +0x000053a5 T get_active_ota_bank_addr +0x000054ed T btxfcs +0x00005665 T PPB_BufSwitch +0x00005689 T PPB_Init +0x000056dd T PPB_Uninit +0x00005701 T PPB_Init_DLPS_Restore +0x00005709 T PPB_Write +0x000057db T PPB_ClearOutputBuffer +0x00005811 T LogUartTxChar +0x00005853 T log_timestamp_get +0x00005893 T VSnprintf +0x00005a07 T log_direct +0x00005aa9 T log_buffer +0x00005bcd T log_index +0x00005cdf T log_snoop +0x00005ddf T trace_bdaddr +0x00005e6b T trace_string +0x00005f07 T trace_binary +0x00005f9f T LogBufferLowerStack +0x000060c5 T LogBufferLowerStackData +0x000061a3 T log_module_trace_init +0x000061d3 T log_module_trace_set +0x0000621f T log_module_bitmap_trace_set +0x00006323 T LogUartDMAStart +0x00006335 T LogDMA_SM_Dispatch +0x000063bd T LogUartDMAInit +0x000064b1 T LogUartDMAIdleHook +0x0000651f T log_pm_check +0x0000675d T hw_aes_encrypt128_use_dma +0x000067a1 T hw_aes_decrypt128_use_dma +0x000067e5 T aes128_ecb_encrypt +0x00006841 T aes128_ecb_decrypt +0x0000689b T aes128_ecb_encrypt_msb2lsb +0x000068b3 T aes128_ecb_decrypt_msb2lsb +0x000068cb T aes256_ecb_encrypt +0x00006927 T aes256_ecb_decrypt +0x00006981 T aes256_ecb_encrypt_msb2lsb +0x00006999 T aes256_ecb_decrypt_msb2lsb +0x000069ed T hw_aes_decrypt_16byte +0x000075d3 T ftl_ioctl +0x00007b1f T ftl_load +0x00007b33 T ftl_save +0x00007c45 T ftl_init +0x00007df1 T hardfault_dump +0x0000805f T flash_dump_flash_info +0x000080b3 T flash_get_flash_exist +0x000080b9 T flash_get_bank_addr +0x0000813b T flash_get_bank_size +0x000081a1 T flash_erase_locked +0x000081f7 T flash_ioctl +0x00008601 T flash_write_locked +0x00008629 T flash_auto_write_locked +0x0000864b T flash_auto_write_buffer_locked +0x00008671 T flash_read_locked +0x00008699 T flash_auto_read_locked +0x000086b7 T flash_split_read_locked +0x000086e1 T flash_auto_dma_read_locked +0x00008709 T flash_auto_seq_trans_dma_read_locked +0x00008731 T flash_try_high_speed +0x000088f1 T flash_get_block_protect_locked +0x00008917 T flash_set_block_protect_locked +0x0000893d T flash_sw_protect_unlock_by_addr_locked +0x000089cd T crc8EtsGen +0x000089ed T crc8EtsCheck +0x00008a1d T set_hci_mode_flag +0x00008a47 T check_hci_mode_flag +0x00008a5d T check_image_chksum +0x00008a83 T check_header_valid +0x00008ae3 T get_header_addr_by_img_id +0x00008b3f T get_active_bank_image_size_by_img_id +0x00008b7b T is_ota_support_bank_switch +0x00008b95 T get_temp_ota_bank_addr_by_img_id +0x00008c07 T get_temp_ota_bank_size_by_img_id +0x00008c73 T get_active_bank_image_version +0x00008d3f T platform_random +0x00009fcf T flash_erase +0x0000a559 T flash_set_bit +0x0000a561 T flash_get_bit +0x0000a56d T flash_write +0x0000a875 T flash_auto_write +0x0000d0c9 T power_manager_get_unit_status +0x0000d207 T power_manager_suspend_all +0x0000d211 T power_manager_resume_all +0x0000d755 T platform_pm_set_power_mode +0x0000d769 T platform_pm_get_power_mode +0x0000d76f T platform_pm_get_error_code +0x0000d775 T platform_pm_get_refuse_reason +0x0000d78f T platform_pm_get_statistics +0x0000d7b9 T platform_pm_get_wakeup_reason +0x0000d7c9 T platform_pm_register_callback_func +0x0000d8cb T platform_pm_stop_all_non_excluded_timer +0x0000e81b T platform_rtc_get_counter +0x0000e885 T vListInitialise +0x0000e89b T vListInitialiseItem +0x0000e8a1 T vListInsertEnd +0x0000e8b9 T vListInsert +0x0000e8e9 T uxListRemove +0x0000e911 T xQueueGenericReset +0x0000e985 T xQueueGenericCreate +0x0000eab3 T xQueueGenericSend +0x0000ebed T xQueueCreateMutex +0x0000ec11 T xQueueGetMutexHolder +0x0000ec2d T xQueueGetMutexHolderFromISR +0x0000ec4d T xQueueGiveMutexRecursive +0x0000ec85 T xQueueSemaphoreTake +0x0000edef T xQueueTakeMutexRecursive +0x0000ee29 T xQueueCreateCountingSemaphore +0x0000ee5f T xQueueGenericSendFromISR +0x0000eefd T xQueueGiveFromISR +0x0000efaf T xQueueReceive +0x0000f0c7 T xQueuePeek +0x0000f1f1 T xQueueReceiveFromISR +0x0000f26f T xQueuePeekFromISR +0x0000f2d3 T uxQueueMessagesWaiting +0x0000f2f3 T uxQueueSpacesAvailable +0x0000f317 T uxQueueMessagesWaitingFromISR +0x0000f32d T vQueueDelete +0x0000f347 T uxQueueGetQueueNumber +0x0000f34b T vQueueSetQueueNumber +0x0000f34f T ucQueueGetQueueType +0x0000f355 T xQueueIsQueueEmptyFromISR +0x0000f375 T xQueueIsQueueFullFromISR +0x0000f395 T vQueueWaitForMessageRestricted +0x0000f51b T xTaskCreate +0x0000f5dd T vTaskDelete +0x0000f683 T xTaskIncrementTick +0x0000f741 T xTaskResumeAll +0x0000f85b T vTaskSuspendAll +0x0000f865 T vTaskDelayUntil +0x0000f8d3 T vTaskDelay +0x0000f907 T eTaskGetState +0x0000f96b T uxTaskPriorityGet +0x0000f985 T uxTaskPriorityGetFromISR +0x0000f99f T vTaskPrioritySet +0x0000fa33 T vTaskSwitchContext +0x0000fadb T vTaskSuspend +0x0000fb8f T vTaskResume +0x0000fc1d T xTaskResumeFromISR +0x0000fc87 T vTaskStartScheduler +0x0000fce7 T vTaskEndScheduler +0x0000fcf7 T xTaskGetTickCount2 +0x0000fcfd T xTaskGetTickCount +0x0000fd03 T xTaskGetTickCountFromISR +0x0000fd09 T uxTaskGetNumberOfTasks +0x0000fd0f T pcTaskGetName +0x0000fd33 T vTaskGetInfo +0x0000fdfb T uxTaskGetSystemState +0x0000fe85 T xTaskGetIdleTaskHandle +0x0000fe9f T vTaskPlaceOnEventList +0x0000fec9 T vTaskPlaceOnUnorderedEventList +0x0000ff0f T vTaskPlaceOnEventListRestricted +0x0000ff43 T xTaskRemoveFromEventList +0x0000ffa7 T vTaskRemoveFromUnorderedEventList +0x0001003d T vTaskSetTimeOutState +0x0001005f T vTaskInternalSetTimeOutState +0x0001006b T xTaskCheckForTimeOut +0x000100d1 T vTaskMissedYield +0x000100d9 T uxTaskGetTaskNumber +0x000100e1 T vTaskSetTaskNumber +0x000100e9 T uxTaskGetStackHighWaterMark +0x000100fb T xTaskGetCurrentTaskHandle +0x00010101 T xTaskGetSchedulerState +0x0001011b T xTaskPriorityInherit +0x0001018b T xTaskPriorityDisinherit +0x000101fb T vTaskPriorityDisinheritAfterTimeout +0x0001027b T uxTaskResetEventItemValue +0x0001028f T pvTaskIncrementMutexHeldCount +0x000102a3 T ulTaskNotifyTake +0x000102fd T xTaskNotifyWait +0x00010371 T xTaskGenericNotify +0x00010441 T xTaskGenericNotifyFromISR +0x00010511 T vTaskNotifyGiveFromISR +0x0001059f T xTaskNotifyStateClear +0x000105c9 T vTaskStatusDump +0x000108e1 T xTimerGenericCommand +0x00010b15 T xTimerCreateTimerTask +0x00010b5d T xTimerCreate +0x00010bd9 T xTimerGetTimerDaemonTaskHandle +0x00010bf1 T xTimerGetPeriod +0x00010c07 T vTimerSetReloadMode +0x00010c39 T xTimerGetExpiryTime +0x00010c4f T pcTimerGetName +0x00010c65 T vTimerGetNextTimeoutItem +0x00010ca1 T xTimerGetAutoReload +0x00010cab T xTimerIsTimerActive +0x00010cd5 T xTimerIsTimerActiveFromISR +0x00010d01 T pvTimerGetTimerID +0x00010d1f T vTimerSetTimerID +0x00010d3f T xTimerPendFunctionCallFromISR +0x00010d5f T xTimerPendFunctionCall +0x00010d99 T uxTimerGetTimerNumber +0x00010d9d T vTimerSetTimerNumber +0x00010daf T dumpAllUsedTimer +0x00010fb9 T pxPortInitialiseStack +0x0001100b T xPortStartScheduler +0x00011033 T vPortEndScheduler +0x0001104d T vPortYield +0x0001105f T vPortEnterCritical +0x00011081 T vPortExitCritical +0x000110c5 T rtlEnterCritical +0x000110e1 T rtlExitCritical +0x000111a7 T vTimerCreateFailedHook +0x000113a3 T pvPortMalloc +0x000114d3 T pvPortMalloc_auto_type +0x00011505 T vPortFree +0x00011585 T xPortGetFreeHeapSize +0x000115c7 T xPortGetMinimumEverFreeHeapSize +0x000115d1 T vPortInitialiseBlocks +0x00011dff T hw_aes_init +0x00011f6d T hw_aes_cpu_operate +0x00011f79 T hw_aes_set_dma_tx_done +0x00011f7f T hw_aes_set_dma_rx_done +0x00011f85 T hw_aes_dma_operate +0x0001210b T hw_aes_dma_interrupt_disable +0x000121af T hw_aes_is_dma_rx_done +0x000121b5 T hw_aes_is_dma_tx_done +0x000121bb T hw_aes_dma_done +0x000121c5 T hw_aes_set_dma_move_src +0x000121e5 T hw_aes_set_dma_move_dst +0x000121eb T hw_aes_set_dma_carry_size +0x0001235f T aes_cmac_inverse +0x00012417 T get_secure_reg_cfg_val +0x0001254b T Pinmux_Deinit_rom +0x00012959 T WDG_ClockEnable +0x00012977 T WDG_Config +0x000129bb T WDG_Enable +0x000129d5 T WDG_Disable +0x000129ef T WDG_Restart +0x00012b71 T reset_reason_get +0x00012c31 T os_mem_alloc_intern +0x00012c8b T os_mem_zalloc_intern +0x00012ced T os_mem_aligned_alloc_intern +0x00012d4d T os_mem_free +0x00012d69 T os_mem_aligned_free +0x00012d85 T os_mem_peek +0x00012da7 T os_mem_check_heap_usage +0x00012de1 T os_msg_queue_create_intern +0x00012e39 T os_msg_queue_delete_intern +0x00012e83 T os_msg_queue_peek_intern +0x00012ed7 T os_msg_send_intern +0x00012f33 T os_msg_recv_intern +0x00012f91 T os_msg_peek_intern +0x00013011 T os_queue_init +0x0001301b T os_queue_in +0x0001304b T os_queue_out +0x0001307f T os_queue_peek +0x00013083 T os_queue_insert +0x000130c3 T os_queue_delete +0x00013131 T os_systick_handler +0x00013147 T os_delay +0x00013163 T os_sys_time_get +0x00013181 T os_sys_tick_get +0x0001319f T os_sys_tick_increase +0x000131c3 T os_sched_start +0x000131e1 T os_sched_stop +0x000131ff T os_sched_suspend +0x0001321d T os_sched_resume +0x0001323b T os_sched_is_start +0x00013259 T os_sched_state_get +0x00013277 T os_vector_table_update +0x0001328d T os_init +0x000132d9 T os_lock +0x000132f5 T os_unlock +0x00013311 T os_sem_create +0x0001333d T os_sem_delete +0x00013361 T os_sem_take +0x00013389 T os_sem_give +0x000133ad T os_mutex_create +0x000133d1 T os_mutex_delete +0x000133f5 T os_mutex_take +0x0001341d T os_mutex_give +0x00013469 T os_task_create +0x000134a5 T os_task_delete +0x000134c9 T os_task_suspend +0x000134ed T os_task_resume +0x00013511 T os_task_yield +0x0001352f T os_task_handle_get +0x00013553 T os_task_priority_get +0x0001357b T os_task_priority_set +0x000135a3 T os_task_status_dump +0x000135b9 T os_task_dlps_return_idle_task +0x000135f9 T os_timer_id_get +0x00013635 T os_timer_create +0x00013671 T os_timer_start +0x00013695 T os_timer_restart +0x000136bd T os_timer_stop +0x000136e1 T os_timer_delete +0x00013705 T os_timer_dump +0x00013723 T os_timer_state_get +0x0001375f T os_timer_init +0x00013775 T os_timer_number_get +0x0001379d T os_timer_pendcall +0x000137cb T os_timer_next_timeout_value_get +0x00013f9f T osif_timer_create +0x00014901 T BB_write_baseband_register +0x00014a91 T bzdma_ble_set_segment_valid_bitmap +0x00015369 T bzdma_send_packet_to_ble_data_ring_fifo +0x0001544b T bzdma_update_fw_rptr_of_ble_data_ring_fifo +0x0001557d T bzdma_wait_rxcmd_complete +0x000155a3 T bzdma_send_burst_rxcmd_and_wait_complete +0x000184ad T rtk_write_modem_radio_reg +0x00018515 T rtk_read_modem_radio_reg +0x0001a81b T hci_handle_le_receiver_test +0x0001ac3b T hci_handle_le_test_end +0x00032f61 T btaon_fast_read +0x00032f75 T btaon_fast_read_8b +0x00032f95 T btaon_fast_read_safe +0x00032fb1 T btaon_fast_read_safe_8b +0x00032fdb T btaon_fast_write +0x00032ffb T btaon_fast_write_8b +0x00033039 T btaon_fast_write_safe +0x00033063 T btaon_fast_write_safe_8b +0x000330a9 T btaon_fast_update +0x000330c3 T btaon_fast_update_8b +0x000330df T btaon_fast_update_safe +0x000330fb T btaon_fast_update_safe_8b +0x0003d547 T init_dft +0x0003d66f T modem_dft +0x0003d751 T deinit_dft +0x0003dee9 T btmac_pm_check_active +0x0003defd T btmac_pm_check_inactive +0x0003df39 T btmac_pm_initiate_wakeup +0x0003df43 T btmac_pm_set_power_mode +0x0003df4f T btmac_pm_get_error_code +0x0003df55 T btmac_pm_get_wakeup_reason +0x0003df5b T btmac_pm_get_statistics +0x0003e4a9 T btmac_pm_check_rom +0x0003ed01 T dfu_dump_header +0x0003ed1b T dfu_set_ready +0x0003ed25 T dfu_set_obsolete +0x0003ed31 T dfu_check_ota_mode_flag +0x0003ed45 T dfu_reset +0x0003edc3 T dfu_process_crc +0x0003ee99 T dfu_process_sha256 +0x0003f4ad T SHA256_Init +0x0003f4d7 T SHA256_Update +0x0003f517 T SHA256_Final +0x0003f5d5 T SHA256 +0x0003f795 T setlocale +0x0003f7a9 T memcmp +0x0003f805 T strlen +0x0003f849 T __aeabi_memcpy +0x0003f849 T __rt_memcpy +0x0003f849 T memcpy +0x0003f8cb T __aeabi_memset +0x0003f8dd T _memset_w +0x0003f8f7 T _memset +0x0003f915 T __aeabi_memclr +0x0003f915 T __rt_memclr +0x0003f919 T __aeabi_memclr4 +0x0003f919 T __aeabi_memclr8 +0x0003f919 T __rt_memclr_w +0x000409b9 T exit +0x00200104 D pMCU_PPB +0x00200108 D pLogDMA_SM +0x00200110 D socv_ft_data +0x0020011c D platform_delay_us +0x00200120 D platform_delay_ms +0x00200164 D otp +0x00200524 D SystemCpuClock +0x00200854 D init_true_random_generator +0x00200858 D get_true_random_number +0x00200861 D bzdma_supported_le_max_seg_num +0x002008a0 D BB_handle_psd_end_intr +0x002008a8 D BB_handle_psd_end_intr_in_isr +0x002008b0 D rtk_write_rfc_reg_pi +0x002008b4 D rtk_read_modem_radio_reg_pi +0x002008b8 D rtk_write_modem_radio_reg_pi +0x002008e0 D rtk_ioq_read_rfc_reg +0x002008e4 D rtk_update_rfc_reg_pi +0x002008f4 D lc_calculate_log_from_rssi +0x00200b0c D ll_hw_init +0x00200ea0 D phy_auto_gated_on +0x00200ea4 D phy_auto_gated_off +0x00200ef0 D le_tx_power_to_txgain_index +0x002010d4 D btmac_pm_system +0x002011d0 D app_pre_main +0x002011d4 D upperstack_entry +0x002011d8 D app_main +0x002011e8 D log_seq_num +0x002011ea D is_log_init +0x00201228 D flash_sem +0x00201258 D flash_device_info +0x00201340 D pxCurrentTCB +0x0020134c D xTickCount +0x00201358 D uxPendedTicks +0x00201370 D uxSchedulerSuspended +0x00201374 D pTaskHandleList +0x00201474 D uxTimerCreateCount +0x00201476 D uxTimerDeleteCount +0x00201478 D xTimerQueue +0x00201488 D pxTimerPool +0x0020148c D puxUsedTimerPoolMask +0x002014d8 D xFreeBytesRemaining +0x002014e0 D xMinimumEverFreeBytesRemaining +0x002014e8 D xHeapTotalSize +0x002014f0 D xStart +0x00201514 D app_cb_wdg_reset +0x00201580 D patch_osif_os_sys_time_get +0x00201608 D patch_osif_os_msg_send_intern +0x00201644 D patch_osif_os_timer_create +0x00201694 D Patch_Dump_CPU_Register_and_Memory +0x002016c0 D patch_vTaskSwitchContext +0x002016c4 D patch_traceTaskSwitchIn +0x0020182c D patch_HardFaultRecord_TryToSave +0x00201858 D low_task_handle +0x00201888 D Bzdma_Manager +0x002020de D g_modem_psd_report_entry_num +0x002020ec D g_modem_psd_report_array +0x00202938 D g_efuse_modem_psd_setting_1 +0x00202c94 D rcp_BTMAC_Handler diff --git a/bin/mdk/adc.lib b/bin/mdk/adc.lib new file mode 100644 index 0000000..0b41d6c Binary files /dev/null and b/bin/mdk/adc.lib differ diff --git a/bin/mdk/auto_k_rf.lib b/bin/mdk/auto_k_rf.lib new file mode 100644 index 0000000..55b3d31 Binary files /dev/null and b/bin/mdk/auto_k_rf.lib differ diff --git a/bin/mdk/auto_k_rf_bonding_lib_DUT.lib b/bin/mdk/auto_k_rf_bonding_lib_DUT.lib new file mode 100644 index 0000000..e6b1791 Binary files /dev/null and b/bin/mdk/auto_k_rf_bonding_lib_DUT.lib differ diff --git a/bin/mdk/bee2_adc_lib.lib b/bin/mdk/bee2_adc_lib.lib new file mode 100644 index 0000000..3a0fa8a Binary files /dev/null and b/bin/mdk/bee2_adc_lib.lib differ diff --git a/bin/mdk/bee3_sdk.lib b/bin/mdk/bee3_sdk.lib new file mode 100644 index 0000000..985a2bb Binary files /dev/null and b/bin/mdk/bee3_sdk.lib differ diff --git a/bin/mdk/gap_utils.lib b/bin/mdk/gap_utils.lib new file mode 100644 index 0000000..1ba9282 Binary files /dev/null and b/bin/mdk/gap_utils.lib differ diff --git a/bin/mdk/ima_adpcm_lib.lib b/bin/mdk/ima_adpcm_lib.lib new file mode 100644 index 0000000..2984af6 Binary files /dev/null and b/bin/mdk/ima_adpcm_lib.lib differ diff --git a/bin/mdk/key_crypto.lib b/bin/mdk/key_crypto.lib new file mode 100644 index 0000000..56a3eb3 Binary files /dev/null and b/bin/mdk/key_crypto.lib differ diff --git a/bin/mdk/leaudio.lib b/bin/mdk/leaudio.lib new file mode 100644 index 0000000..ca67273 Binary files /dev/null and b/bin/mdk/leaudio.lib differ diff --git a/bin/mdk/msbc_lib.lib b/bin/mdk/msbc_lib.lib new file mode 100644 index 0000000..42f8558 Binary files /dev/null and b/bin/mdk/msbc_lib.lib differ diff --git a/bin/mdk/sbc_lib.lib b/bin/mdk/sbc_lib.lib new file mode 100644 index 0000000..8958581 Binary files /dev/null and b/bin/mdk/sbc_lib.lib differ diff --git a/bin/mdk/system_trace.lib b/bin/mdk/system_trace.lib new file mode 100644 index 0000000..10eae97 Binary files /dev/null and b/bin/mdk/system_trace.lib differ diff --git a/bin/readme b/bin/readme new file mode 100644 index 0000000..e69de29 diff --git a/bin/upperstack_img/upperstack_0_0/gap_utils.lib b/bin/upperstack_img/upperstack_0_0/gap_utils.lib new file mode 100644 index 0000000..1ba9282 Binary files /dev/null and b/bin/upperstack_img/upperstack_0_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_0_0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin b/bin/upperstack_img/upperstack_0_0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin new file mode 100644 index 0000000..2d07506 Binary files /dev/null and b/bin/upperstack_img/upperstack_0_0/upperstack_MP_000_1.0.68.0_358ad01b-3805df99b8b7b1289866e3c8af16b615.bin differ diff --git a/bin/upperstack_img/upperstack_0_0/upperstack_config.h b/bin/upperstack_img/upperstack_0_0/upperstack_config.h new file mode 100644 index 0000000..96986aa --- /dev/null +++ b/bin/upperstack_img/upperstack_0_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.1 +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/bin/upperstack_img/upperstack_1_0/gap_utils.lib b/bin/upperstack_img/upperstack_1_0/gap_utils.lib new file mode 100644 index 0000000..0d1fa83 Binary files /dev/null and b/bin/upperstack_img/upperstack_1_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_1_0/upperstack_MP_100_1.0.67.0_d6aa7850-015cee738e9a6076255e6a640fd07161.bin b/bin/upperstack_img/upperstack_1_0/upperstack_MP_100_1.0.67.0_d6aa7850-015cee738e9a6076255e6a640fd07161.bin new file mode 100644 index 0000000..3f7b1b5 Binary files /dev/null and b/bin/upperstack_img/upperstack_1_0/upperstack_MP_100_1.0.67.0_d6aa7850-015cee738e9a6076255e6a640fd07161.bin differ diff --git a/bin/upperstack_img/upperstack_1_0/upperstack_config.h b/bin/upperstack_img/upperstack_1_0/upperstack_config.h new file mode 100644 index 0000000..9261584 --- /dev/null +++ b/bin/upperstack_img/upperstack_1_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.1 +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/bin/upperstack_img/upperstack_a_0/gap_utils.lib b/bin/upperstack_img/upperstack_a_0/gap_utils.lib new file mode 100644 index 0000000..ae291ad Binary files /dev/null and b/bin/upperstack_img/upperstack_a_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_a_0/upperstack_MP_a00_1.0.67.0_d6aa7850-649560260550beb325fd83550cce3c04.bin b/bin/upperstack_img/upperstack_a_0/upperstack_MP_a00_1.0.67.0_d6aa7850-649560260550beb325fd83550cce3c04.bin new file mode 100644 index 0000000..7348500 Binary files /dev/null and b/bin/upperstack_img/upperstack_a_0/upperstack_MP_a00_1.0.67.0_d6aa7850-649560260550beb325fd83550cce3c04.bin differ diff --git a/bin/upperstack_img/upperstack_a_0/upperstack_config.h b/bin/upperstack_img/upperstack_a_0/upperstack_config.h new file mode 100644 index 0000000..559e8f9 --- /dev/null +++ b/bin/upperstack_img/upperstack_a_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.1 +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 0) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 0) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/bin/upperstack_img/upperstack_b_0/gap_utils.lib b/bin/upperstack_img/upperstack_b_0/gap_utils.lib new file mode 100644 index 0000000..4a5e6be Binary files /dev/null and b/bin/upperstack_img/upperstack_b_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_b_0/upperstack_MP_b00_1.0.67.1_f8542fe7-9fe204db21c88e82332af43969011589.bin b/bin/upperstack_img/upperstack_b_0/upperstack_MP_b00_1.0.67.1_f8542fe7-9fe204db21c88e82332af43969011589.bin new file mode 100644 index 0000000..f2fe93d Binary files /dev/null and b/bin/upperstack_img/upperstack_b_0/upperstack_MP_b00_1.0.67.1_f8542fe7-9fe204db21c88e82332af43969011589.bin differ diff --git a/bin/upperstack_img/upperstack_b_0/upperstack_config.h b/bin/upperstack_img/upperstack_b_0/upperstack_config.h new file mode 100644 index 0000000..5a38c4e --- /dev/null +++ b/bin/upperstack_img/upperstack_b_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.1 +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 0) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/bin/upperstack_img/upperstack_findmy_0/gap_utils.lib b/bin/upperstack_img/upperstack_findmy_0/gap_utils.lib new file mode 100644 index 0000000..cbcbfd2 Binary files /dev/null and b/bin/upperstack_img/upperstack_findmy_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_findmy_0/upperstack_MP_findmy0_1.0.68.0_b3380dcc-189226228a0cfd23d423314e5cc03483.bin b/bin/upperstack_img/upperstack_findmy_0/upperstack_MP_findmy0_1.0.68.0_b3380dcc-189226228a0cfd23d423314e5cc03483.bin new file mode 100644 index 0000000..14b88f3 Binary files /dev/null and b/bin/upperstack_img/upperstack_findmy_0/upperstack_MP_findmy0_1.0.68.0_b3380dcc-189226228a0cfd23d423314e5cc03483.bin differ diff --git a/bin/upperstack_img/upperstack_findmy_0/upperstack_config.h b/bin/upperstack_img/upperstack_findmy_0/upperstack_config.h new file mode 100644 index 0000000..bb30ac9 --- /dev/null +++ b/bin/upperstack_img/upperstack_findmy_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 0) + +//BT 4.1 +#define F_BT_LE_4_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 0) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 0) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 0) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/bin/upperstack_img/upperstack_ring_0/gap_utils.lib b/bin/upperstack_img/upperstack_ring_0/gap_utils.lib new file mode 100644 index 0000000..319d79d Binary files /dev/null and b/bin/upperstack_img/upperstack_ring_0/gap_utils.lib differ diff --git a/bin/upperstack_img/upperstack_ring_0/upperstack_MP_ring0_1.0.67.0_185c70a2-f8e266a103b10e61e10f2f0f54a8b080.bin b/bin/upperstack_img/upperstack_ring_0/upperstack_MP_ring0_1.0.67.0_185c70a2-f8e266a103b10e61e10f2f0f54a8b080.bin new file mode 100644 index 0000000..af0c2e7 Binary files /dev/null and b/bin/upperstack_img/upperstack_ring_0/upperstack_MP_ring0_1.0.67.0_185c70a2-f8e266a103b10e61e10f2f0f54a8b080.bin differ diff --git a/bin/upperstack_img/upperstack_ring_0/upperstack_config.h b/bin/upperstack_img/upperstack_ring_0/upperstack_config.h new file mode 100644 index 0000000..249d378 --- /dev/null +++ b/bin/upperstack_img/upperstack_ring_0/upperstack_config.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _UPPERSTACK_CONFIG_H_ +#define _UPPERSTACK_CONFIG_H_ +#define F_BT_LE_SUPPORT 1 /* support BT Low Energy */ + +/*============================================================================* + * BLE Feature Flags + *============================================================================*/ +#define F_BT_LE_GAP_CENTRAL_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_GAP_SCAN_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GAP_SCAN_FILTER_SUPPORT (F_BT_LE_GAP_SCAN_SUPPORT && 0) +#define F_BT_LE_GAP_PERIPHERAL_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_CLIENT_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_GATT_SERVER_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_SMP_OOB_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_BOND_KEY_REQ_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.0 +#define F_BT_LE_READ_REMOTE_FEATS (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_ATT_SIGNED_WRITE_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_0_DTM_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_ADV_TX_POWRE_SUPPORT (F_BT_LE_GAP_PERIPHERAL_SUPPORT && 1) +#define F_BT_LE_READ_CHANN_MAP (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.1 +#define F_BT_LE_4_1_COC_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_4_1_WRITE_AUTHEN_PAYLOAD_TIMEOUT_SUPPORT (F_BT_LE_SUPPORT && 1) + +//BT 4.2 +#define F_BT_LE_4_2_SUPPORT (F_BT_LE_SUPPORT && 1) +#define F_BT_LE_4_2_SC_SUPPORT (F_BT_LE_4_2_SUPPORT && 0) +#define F_BT_LE_4_2_SC_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT && F_BT_LE_4_2_SC_SUPPORT && 1) +#define F_BT_LE_4_2_KEY_PRESS_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) +#define F_BT_LE_PRIVACY_SUPPORT (F_BT_LE_4_2_SUPPORT && 1) + +//BT 5 +#define F_BT_LE_5_0_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_0_AE_ADV_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_AE_SCAN_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_SUPPORT (F_BT_LE_5_0_SUPPORT && 0) +#define F_BT_LE_5_0_PA_ADV_SUPPORT (F_BT_LE_5_0_AE_ADV_SUPPORT && F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SUPPORT (F_BT_LE_5_0_PA_SUPPORT && 1) +#define F_BT_LE_5_0_PA_SYNC_SCAN_SUPPORT (F_BT_LE_5_0_AE_SCAN_SUPPORT && F_BT_LE_5_0_PA_SYNC_SUPPORT && 1) +#define F_BT_LE_5_0_DTM_SUPPORT (F_BT_LE_5_0_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 1) +#define F_BT_LE_5_0_SET_PHYS_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_READ_POWER_SUPPORT (F_BT_LE_5_0_SUPPORT && 1) +#define F_BT_LE_5_0_RF_PATH_SUPPORT ((F_BT_LE_5_0_AE_ADV_SUPPORT || F_BT_LE_5_2_POWER_CONTROL_SUPPORT) && 1) + +//BT 5.1 +#define F_BT_LE_5_1_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_1_PAST_SUPPORT ((F_BT_LE_5_0_PA_ADV_SUPPORT || F_BT_LE_5_0_PA_SYNC_SUPPORT) && F_BT_LE_5_1_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SUPPORT (F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_ADV_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_SENDER_SYNC_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SENDER_SUPPORT && 1) +#define F_BT_LE_5_1_PAST_RECIPIENT_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_PAST_SUPPORT && 1) +#define F_BT_LE_5_1_AOA_AOD_SUPPORT (F_BT_LE_5_1_SUPPORT && 0) +#define F_BT_LE_5_1_AOX_CONN_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_SUPPORT (F_BT_LE_5_1_AOA_AOD_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT (F_BT_LE_5_0_PA_ADV_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT (F_BT_LE_5_0_PA_SYNC_SUPPORT && F_BT_LE_5_1_AOX_CONNLESS_SUPPORT && 1) +#define F_BT_LE_5_1_DTM_SUPPORT (F_BT_LE_5_1_SUPPORT && F_BT_LE_4_0_DTM_SUPPORT && 0) + +//BT5.2 +#define F_BT_LE_5_2_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_5_2_POWER_CONTROL_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) +#define F_BT_LE_5_2_DTM_SUPPORT (F_BT_LE_5_2_SUPPORT && 1) + +#define F_BT_GATT_SERVER_CLEAR_SERVICE_SUPPORT (F_BT_LE_GATT_SERVER_SUPPORT && 1) + +/*============================================================================* + * Function Configuration Flags + *============================================================================*/ +#define F_BT_LE_FIX_CHANN_SUPPORT (F_BT_LE_SUPPORT && 0) +#define F_BT_LE_LOCAL_IRK_SETTING_SUPPORT (F_BT_LE_SUPPORT && 1) + +#define F_BT_LE_GAP_MSG_INFO_WAY 1 + +#define F_BT_OOB_SUPPORT (F_BT_LE_SMP_OOB_SUPPORT || F_BT_LE_4_2_SC_OOB_SUPPORT) + +#endif /* _UPPERSTACK_CONFIG_H_ */ diff --git a/board/evb/findmy/board.h b/board/evb/findmy/board.h new file mode 100644 index 0000000..aa36e18 --- /dev/null +++ b/board/evb/findmy/board.h @@ -0,0 +1,228 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file board.h +* @brief header file of FindMy demo +* @details +* @author Scarlett_liang +* @date 2023-4-17 +* @version v2.0.0 +* ********************************************************************************************************* +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define USE_UARP + +#define COMMON_FMNA 0 /* Common Demo FMNA */ +#define E_DEMO_FMNA 1 /* E Customer Demo FMNA */ + +#define FMNA_HD_PLATFORM_SEL E_DEMO_FMNA /* FMNA Hardware Platform selection */ + +/******************************************************* +* Feature Config +*******************************************************/ +#define APP_MAX_LINKS 2 /* Config APP LE link number */ + +#define DEBUG /* enable debug control point procedures */ + +#define FEAUTRE_SUPPORT_FLASH_2_BIT_MODE 1 /* set 1 to enable flash 2-bit mode */ + +/* Notice: This feature requires upperstack image at version 1.0.63.0 or higher! */ +#define SUPPORT_DYNAMIC_SERVICE 0 /* set 1 to support Service Availability feature */ + +/******************************************************* +* Custom APP Config +*******************************************************/ +#define SUPPORT_CUSTOMIZED_APP 1 /* set 1 to support customized app, not GFPS */ + +#define CUST_APP_ONLY_CONN 0 //Custom APP only connects but does not pair +#define CUST_APP_PAIRED 1 //Custom APP needs to be paired + +#if SUPPORT_CUSTOMIZED_APP +#define CUST_APP_TYPE CUST_APP_ONLY_CONN //Select one of the above custom APP types +/* If the custom APP needs HID service, set it to 1. + And CUST_APP_TYPE must be set to CUST_APP_PAIRED */ +#define CUST_HID_SERVICE 0 +#endif +#define ONE_SHOT_ADV_EN (1 && (SUPPORT_CUSTOMIZED_APP || GFPS_FEATURE_SUPPORT)) /* set 1 to support ONE SHOT ADV function */ + +/******************************************************* +* OTA Config +*******************************************************/ +//#define USE_UARP /* enable firmware update function */ +#define DFU_TEMP_BUFFER_SIZE 512 /* dfu max buffer size */ + +/******************************************************* +* Log Config +*******************************************************/ +#define IS_RELEASE_VERSION 0 /* 1: close all log 0: open log */ +#define FMNA_DISABLE_LOGS 0 /* 1: close fmna log 0: open fmna log */ +#define IS_PRINT_REMAINING_RAM_SIZE 0 /* 1: print 0: not print */ + +/******************************************************* +* KEY Config +*******************************************************/ +#if (FMNA_HD_PLATFORM_SEL == COMMON_FMNA) +#define TRIGGER_BUTTON P1_1 +#define GPIO_TRIG_PIN GPIO_GetPin(TRIGGER_BUTTON) +#define TRIG_BUTTON_IRQ GPIO9_IRQn +#define trig_button_handler GPIO9_Handler + +#elif (FMNA_HD_PLATFORM_SEL == E_DEMO_FMNA) +#define TRIGGER_BUTTON P1_1 +#define GPIO_TRIG_PIN GPIO_GetPin(TRIGGER_BUTTON) +#define TRIG_BUTTON_IRQ GPIO9_IRQn +#define trig_button_handler GPIO9_Handler +#endif + +/* customized adv trig pin define*/ +#if SUPPORT_CUSTOMIZED_APP +#define CUST_ADV_PIN P4_1 +#define GPIO_CUST_ADV_PIN GPIO_GetPin(CUST_ADV_PIN) +#define CUST_ADV_PIN_IRQ GPIO29_IRQn +#define cust_adv_pin_handler GPIO29_Handler +#endif + +/******************************************************* +* BUZZER Module Config +*******************************************************/ +#if (FMNA_HD_PLATFORM_SEL == COMMON_FMNA) +#define USE_ACTIVE_BUZZER 1 /* set 1 to use active buzzer function */ + +#elif (FMNA_HD_PLATFORM_SEL == E_DEMO_FMNA) +#define USE_PAM8904_BUZZER 1 /* set 1 to use PAM8904 & buzzer function */ +#endif + +#define SOUND_LED_EN 0 /* set 1 to enable LED to simulate SOUND feature */ + +#define PWM_FREQ 0 +#define PWM_DEFAULT_FREQ 4000 +#define PWM_LOW_FREQ 4000 +#define PWM_MEDIUM_FREQ PWM_DEFAULT_FREQ +#define PWM_HIGH_FREQ 4000 + +#if SOUND_LED_EN +#define SOUND_LED_PIN P0_1 + +#elif USE_ACTIVE_BUZZER +#define PWM_OUT_PIN P0_1 +#undef PWM_FREQ +#define PWM_FREQ PWM_DEFAULT_FREQ /* unit: Hz*/ + +#elif USE_PAM8904_BUZZER +#define PAM8904_DIN P4_0 +#define PAM8904_EN P2_7 +#define PWM_OUT_PIN PAM8904_DIN +#undef PWM_FREQ +#define PWM_FREQ PWM_DEFAULT_FREQ /* unit: Hz*/ +#endif + +/******************************************************* +* G-Sensor Module Config +*******************************************************/ +#if (FMNA_HD_PLATFORM_SEL == COMMON_FMNA) +#define USE_DA213B_SENSOR 1 /* set 1 to use DA213B to detect motion */ +#define ACTIVE_DUR 9 /* active duration time = (ACTIVE_DUR + 1)* 1ms */ +#define ACTIVE_TH 2 /* Threshold of active interrupt = ACTIVE_TH * 3.91mg (2g range) */ + +#elif (FMNA_HD_PLATFORM_SEL == E_DEMO_FMNA) +#define USE_DA213B_SENSOR 1 /* set 1 to use DA213B to detect motion */ +#define ACTIVE_DUR 99 /* active duration time = (ACTIVE_DUR + 1)* 1ms */ +#define ACTIVE_TH 60 /* Threshold of active interrupt = ACTIVE_TH * 3.91mg (2g range) */ +#endif + +#if USE_DA213B_SENSOR +#define I2C_DA213B_SCL_PIN P2_4 +#define I2C_DA213B_SDA_PIN P2_5 +#endif + +/******************************************************* +* Battery Module Config +*******************************************************/ +#define SUPPORT_BAT_DETECT_FEATURE 1 /* set 1 to enable battery detect feature */ + +#if SUPPORT_BAT_DETECT_FEATURE + +/* Note: make sure BAT_ENTER_NORMAL_MODE_THRESHOLD > BAT_ENTER_NORMAL_MODE_THRESHOLD */ +#define BAT_ENTER_LOW_POWER_THRESHOLD 2000 /* enter low power mode threshold, unit: mV */ +#define BAT_ENTER_NORMAL_MODE_THRESHOLD 2200 /* enter normal mode threshold, unit: mV */ +#define BAT_ENTER_OTA_MODE_THRESHOLD 2500 /* enter ota mode threshold, unit: mV */ + +#define SUPPORT_LITHIUM_BAT_DETECT_FEATURE 0 /* set 1 to detect the lithium battery power */ + +/* Change the ADC sampling pin here! */ +/** ADC sample channel config:P2_2,P2_3,P2_6,P2_7 and VBAT + * If ADC_PIN = P2_2, then ADC_CHANNEL = 0; + * If ADC_PIN = P2_3, then ADC_CHANNEL = 1; + * If ADC_PIN = P2_6, then ADC_CHANNEL = 2; + * If ADC_PIN = P2_7, then ADC_CHANNEL = 3; + */ +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE +#define ADC_PIN P2_6 +#define ADC_CHANNEL 2 +#define VOLTAGE_DIVIDER 4.0 /* Vbat:Vadc = 4:1 */ +#endif + +#endif + +/******************************************************* +* NFC Module Config +*******************************************************/ +/* This feature is not complete yet, it will be added in the future. */ +#define SUPPORT_NFC 0 /* set 1 to support NFC */ + +/******************************************************* +* DLPS Module Config +*******************************************************/ +/** @brief Config DLPS: 0-Disable DLPS, 1-Enable DLPS */ +#define DLPS_EN 1 + +/** @defgroup IO Driver Config + * @note user must config it firstly!! Do not change macro names!! + * @{ + */ +/* if use user define dlps enter/dlps exit callback function */ +#define USE_USER_DEFINE_DLPS_EXIT_CB 1 +#define USE_USER_DEFINE_DLPS_ENTER_CB 1 + +/* if use any peripherals below, #define it 1 */ +#define USE_I2C0_DLPS 1 +#define USE_I2C1_DLPS 0 +#define USE_TIM_DLPS 1 +#define USE_QDECODER_DLPS 0 +#define USE_IR_DLPS 0 +#define USE_ADC_DLPS 1 +#define USE_CTC_DLPS 0 +#define USE_SPI0_DLPS 0 +#define USE_SPI1_DLPS 0 +#define USE_SPI2W_DLPS 0 +#define USE_KEYSCAN_DLPS 0 +#define USE_GPIO_DLPS 1 +#define USE_CODEC_DLPS 0 +#define USE_I2S0_DLPS 0 +#define USE_ENHTIM_DLPS 0 +#define USE_UART0_DLPS 0 +#define USE_UART1_DLPS 0 + +/* do not modify USE_IO_DRIVER_DLPS macro */ +#define USE_IO_DRIVER_DLPS (USE_I2C0_DLPS | USE_I2C1_DLPS | USE_TIM_DLPS | USE_QDECODER_DLPS\ + | USE_IR_DLPS | USE_ADC_DLPS | USE_CTC_DLPS | USE_SPI0_DLPS\ + | USE_SPI1_DLPS | USE_SPI2W_DLPS | USE_KEYSCAN_DLPS\ + | USE_GPIO_DLPS | USE_CODEC_DLPS | USE_I2S0_DLPS\ + | USE_ENHTIM_DLPS | USE_UART0_DLPS | USE_UART1_DLPS\ + | USE_USER_DEFINE_DLPS_ENTER_CB\ + | USE_USER_DEFINE_DLPS_EXIT_CB) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/board/evb/findmy/flash map.ini b/board/evb/findmy/flash map.ini new file mode 100644 index 0000000..5720ceb --- /dev/null +++ b/board/evb/findmy/flash map.ini @@ -0,0 +1,70 @@ +[Property] +IC_TYPE=554542 +FLASH_SIZE=512 +OTA_SWITCH=Disable +IMG_HDR_SIZE=1024 +[OTAHeader] +OTA_BIN_VER1=1 +OTA_BIN_VER2=0 +OTA_BIN_VER3=0 +OTA_BIN_VER4=1 +[HighLevel] +OEM_CFG_ADDR=0x00801000 +OEM_CFG_SIZE=0x00001000 +OTA_BANK0_ADDR=0x00802000 +OTA_BANK0_SIZE=0x0004B000 +OTA_BANK1_ADDR=0x0084D000 +OTA_BANK1_SIZE=0x00000000 +FTL_ADDR=0x0084D000 +FTL_SIZE=0x00004000 +OTA_TMP_ADDR=0x00851000 +OTA_TMP_SIZE=0x0002D000 +USER_DATA1_ADDR=0x0087E000 +USER_DATA1_SIZE=0x00001000 +USER_DATA2_ADDR=0x0087F000 +USER_DATA2_SIZE=0x00001000 +[OTABank] +BANK0_OTA_HDR_ADDR=0x00802000 +BANK0_OTA_HDR_SIZE=0x00001000 +BANK0_FSBL_ADDR=0x0080D000 +BANK0_FSBL_SIZE=0x00001000 +BANK0_ROM_PATCH_ADDR=0x00803000 +BANK0_ROM_PATCH_SIZE=0x0000A000 +BANK0_UPPERSTACK_ADDR=0x0080E000 +BANK0_UPPERSTACK_SIZE=0x00017000 +BANK0_APP_ADDR=0x00825000 +BANK0_APP_SIZE=0x00028000 +BANK0_APP_DATA1_ADDR=0x0084D000 +BANK0_APP_DATA1_SIZE=0x00000000 +BANK0_APP_DATA2_ADDR=0x0084D000 +BANK0_APP_DATA2_SIZE=0x00000000 +BANK0_APP_DATA3_ADDR=0x0084D000 +BANK0_APP_DATA3_SIZE=0x00000000 +BANK0_APP_DATA4_ADDR=0x0084D000 +BANK0_APP_DATA4_SIZE=0x00000000 +BANK0_APP_DATA5_ADDR=0x0084D000 +BANK0_APP_DATA5_SIZE=0x00000000 +BANK0_APP_DATA6_ADDR=0x0084D000 +BANK0_APP_DATA6_SIZE=0x00000000 +BANK1_OTA_HDR_ADDR=0x00000000 +BANK1_OTA_HDR_SIZE=0x00000000 +BANK1_FSBL_ADDR=0x00000000 +BANK1_FSBL_SIZE=0x00000000 +BANK1_ROM_PATCH_ADDR=0x00000000 +BANK1_ROM_PATCH_SIZE=0x00000000 +BANK1_UPPERSTACK_ADDR=0x00000000 +BANK1_UPPERSTACK_SIZE=0x00000000 +BANK1_APP_ADDR=0x00000000 +BANK1_APP_SIZE=0x00000000 +BANK1_APP_DATA1_ADDR=0x00000000 +BANK1_APP_DATA1_SIZE=0x00000000 +BANK1_APP_DATA2_ADDR=0x00000000 +BANK1_APP_DATA2_SIZE=0x00000000 +BANK1_APP_DATA3_ADDR=0x00000000 +BANK1_APP_DATA3_SIZE=0x00000000 +BANK1_APP_DATA4_ADDR=0x00000000 +BANK1_APP_DATA4_SIZE=0x00000000 +BANK1_APP_DATA5_ADDR=0x00000000 +BANK1_APP_DATA5_SIZE=0x00000000 +BANK1_APP_DATA6_ADDR=0x00000000 +BANK1_APP_DATA6_SIZE=0x00000000 diff --git a/board/evb/findmy/flash_map.h b/board/evb/findmy/flash_map.h new file mode 100644 index 0000000..1f656c0 --- /dev/null +++ b/board/evb/findmy/flash_map.h @@ -0,0 +1,133 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** +* @file flash_map.h +* @brief Flash Layout Configuration, and flash layout must be changed with config file! +* @note flash_map.h must be generated by FlashMapGenerateTool! +* ************************************************************************************* +*/ + +#ifndef _FLASH_MAP_H_ +#define _FLASH_MAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* +* Flash Layout +*============================================================================*/ +/* Flash total size 512KB +example: + 1) Reserved: 4K (0x00800000) + 2) OEM Header: 4K (0x00801000) + 3) OTA Bank0: 300K (0x00802000) + a) OTA Header 4K (0x00802000) + b) Secure boot loader 4K (0x0080D000) + c) Patch code 40K (0x00803000) + d) Upperstack Code 92K (0x0080E000) + e) APP code 160K (0x00825000) + f) APP data1 0K (0x0084D000) + g) APP data2 0K (0x0084D000) + h) APP data3 0K (0x0084D000) + i) APP data4 0K (0x0084D000) + j) APP data5 0K (0x0084D000) + k) APP data6 0K (0x0084D000) + 4) OTA Bank1: 0K (0x0084D000) + a) OTA Header 0K (0x00000000) + b) Secure boot loader 0K (0x00000000) + c) Patch code 0K (0x00000000) + d) Upperstack Code 0K (0x00000000) + e) APP code 0K (0x00000000) + f) APP data1 0K (0x00000000) + g) APP data2 0K (0x00000000) + h) APP data3 0K (0x00000000) + i) APP data4 0K (0x00000000) + j) APP data5 0K (0x00000000) + k) APP data6 0K (0x00000000) + 5) FTL: 16K (0x0084D000) + 6) OTA Tmp: 180K (0x00851000) + 7) user data1: 4K (0x0087E000) + 8) user data2: 4K (0x0087F000) +*/ + +/*============================================================================* +* Flash Layout Configuration (Generated by FlashMapGenerateTool) +*============================================================================*/ + +#define FLASH_ADDR 0x00800000 //Fixed +#define FLASH_SIZE 0x00080000 //512K Bytes + +/* ========== High Level Flash Layout Configuration ========== */ +#define RESERVED_ADDR 0x00800000 +#define RESERVED_SIZE 0x00001000 //4K Bytes +#define OEM_CFG_ADDR 0x00801000 +#define OEM_CFG_SIZE 0x00001000 //4K Bytes +#define OTA_BANK0_ADDR 0x00802000 +#define OTA_BANK0_SIZE 0x0004B000 //300K Bytes +#define OTA_BANK1_ADDR 0x0084D000 +#define OTA_BANK1_SIZE 0x00000000 //0K Bytes +#define FTL_ADDR 0x0084D000 +#define FTL_SIZE 0x00004000 //16K Bytes +#define OTA_TMP_ADDR 0x00851000 +#define OTA_TMP_SIZE 0x0002D000 //180K Bytes +#define USER_DATA1_ADDR 0x0087E000 +#define USER_DATA1_SIZE 0x00001000 //4K Bytes +#define USER_DATA2_ADDR 0x0087F000 +#define USER_DATA2_SIZE 0x00001000 //4K Bytes + +/* ========== OTA Bank0 Flash Layout Configuration ========== */ +#define BANK0_OTA_HEADER_ADDR 0x00802000 +#define BANK0_OTA_HEADER_SIZE 0x00001000 //4K Bytes +#define BANK0_SECURE_BOOT_ADDR 0x0080D000 +#define BANK0_SECURE_BOOT_SIZE 0x00001000 //4K Bytes +#define BANK0_ROM_PATCH_ADDR 0x00803000 +#define BANK0_ROM_PATCH_SIZE 0x0000A000 //40K Bytes +#define BANK0_UPPERSTACK_ADDR 0x0080E000 +#define BANK0_UPPERSTACK_SIZE 0x00017000 //92K Bytes +#define BANK0_APP_ADDR 0x00825000 +#define BANK0_APP_SIZE 0x00028000 //160K Bytes +#define BANK0_APP_DATA1_ADDR 0x0084D000 +#define BANK0_APP_DATA1_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA2_ADDR 0x0084D000 +#define BANK0_APP_DATA2_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA3_ADDR 0x0084D000 +#define BANK0_APP_DATA3_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA4_ADDR 0x0084D000 +#define BANK0_APP_DATA4_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA5_ADDR 0x0084D000 +#define BANK0_APP_DATA5_SIZE 0x00000000 //0K Bytes +#define BANK0_APP_DATA6_ADDR 0x0084D000 +#define BANK0_APP_DATA6_SIZE 0x00000000 //0K Bytes + +/* ========== OTA Bank1 Flash Layout Configuration ========== */ +#define BANK1_OTA_HEADER_ADDR 0x00000000 +#define BANK1_OTA_HEADER_SIZE 0x00000000 //0K Bytes +#define BANK1_SECURE_BOOT_ADDR 0x00000000 +#define BANK1_SECURE_BOOT_SIZE 0x00000000 //0K Bytes +#define BANK1_ROM_PATCH_ADDR 0x00000000 +#define BANK1_ROM_PATCH_SIZE 0x00000000 //0K Bytes +#define BANK1_UPPERSTACK_ADDR 0x00000000 +#define BANK1_UPPERSTACK_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_ADDR 0x00000000 +#define BANK1_APP_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA1_ADDR 0x00000000 +#define BANK1_APP_DATA1_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA2_ADDR 0x00000000 +#define BANK1_APP_DATA2_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA3_ADDR 0x00000000 +#define BANK1_APP_DATA3_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA4_ADDR 0x00000000 +#define BANK1_APP_DATA4_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA5_ADDR 0x00000000 +#define BANK1_APP_DATA5_SIZE 0x00000000 //0K Bytes +#define BANK1_APP_DATA6_ADDR 0x00000000 +#define BANK1_APP_DATA6_SIZE 0x00000000 //0K Bytes + + +#ifdef __cplusplus +} +#endif +/** @} */ /* _FLASH_MAP_H_ */ +#endif diff --git a/board/evb/findmy/mdk/Listings/app.map b/board/evb/findmy/mdk/Listings/app.map new file mode 100644 index 0000000..e358872 --- /dev/null +++ b/board/evb/findmy/mdk/Listings/app.map @@ -0,0 +1,6429 @@ +Component: ARM Compiler 5.06 update 6 (build 750) Tool: armlink [4d35ed] + +============================================================================== + +Section Cross References + + startup_rtl876x.o(VECTOR) refers to startup_rtl876x.o(RESET) for Reset_Handler + startup_rtl876x.o(VECTOR) refers to startup_rtl876x.o(.text) for NMI_Handler + startup_rtl876x.o(VECTOR) refers to main.o(.text) for System_Handler + startup_rtl876x.o(VECTOR) refers to reset_watch_dog_timer.o(.app.data_ram.text) for Timer3_Handler + startup_rtl876x.o(VECTOR) refers to system_rtl876x.o(.app.data_ram.text) for GPIO_Group3_Handler + startup_rtl876x.o(VECTOR) refers to key_crypto.o(.text) for Timer4_Handler + startup_rtl876x.o(RESET) refers to system_rtl876x.o(.app.flash.text) for SystemInit + system_rtl876x.o(.app.data_ram.text) refers to startup_rtl876x.o(.text) for GPIO3_Handler + system_rtl876x.o(.app.data_ram.text) refers to key_handle.o(.text) for GPIO9_Handler + system_rtl876x.o(.app.flash.text) refers to overlay_mgr.o(.text) for load_overlay + system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.app.overlay_a) for AppUpdateVectorTable + system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.text) for log_direct_app + system_rtl876x.o(.app.flash.text) refers to main.o(.app.flash.text) for bt_stack_config_init + system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.bss) for user_wdg_cb + system_rtl876x.o(.app.flash.text) refers to system_rtl876x.o(.TRACE) for .TRACE + system_rtl876x.o(.app.overlay_a) refers to system_rtl876x.o(.constdata) for .constdata + system_rtl876x.o(.app.overlay_a) refers to startup_rtl876x.o(.text) for Default_Handler + system_rtl876x.o(.app.overlay_a) refers to system_rtl876x.o(.TRACE) for .TRACE + system_rtl876x.o(.text) refers to vsnprintf.o(.text) for vsnprintf + system_rtl876x.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + system_rtl876x.o(.text) refers to __main.o(!!!main) for __main + system_rtl876x.o(.text) refers to system_rtl876x.o(.bss) for .bss + system_rtl876x.o(.text) refers to system_rtl876x.o(.constdata) for .constdata + system_rtl876x.o(.app.flash.header) refers to system_rtl876x.o(.constdata) for app_cb_table + system_rtl876x.o(.constdata) refers to system_rtl876x.o(.conststring) for .conststring + rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_pinmux.o(.text) for Pad_Config + rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_io_dlps.o(.bss) for .bss + rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_nvic.o(.text) for NVIC_Init + rtl876x_io_dlps.o(.app.data_ram.text) refers to rtl876x_io_dlps.o(.TRACE) for .TRACE + rtl876x_io_dlps.o(.text) refers to rtl876x_io_dlps.o(.app.data_ram.text) for DLPS_IO_EnterDlpsCb + rtl876x_gpio.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + rtl876x_tim.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + rtl876x_tim.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + rtl876x_pinmux.o(.text) refers to rtl876x_pinmux.o(.constdata) for .constdata + rtl876x_adc.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + rtl876x_i2c.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + rtl876x_i2c.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + rtl876x_i2c.o(.text) refers to rtl876x_i2c.o(.data) for .data + rtl876x_aon_wdg.o(.text) refers to rtl876x_aon_wdg.o(.bss) for .bss + findmy_network_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + findmy_network_service.o(.text) refers to findmy_network_service.o(.TRACE) for .TRACE + findmy_network_service.o(.text) refers to findmy_network_service.o(.bss) for .bss + findmy_network_service.o(.text) refers to findmy_network_service.o(.constdata) for .constdata + findmy_network_service.o(.constdata) refers to findmy_network_service.o(.text) for fns_attr_write_cb + accessory_info_service.o(.text) refers to fmna_version.o(.text) for fmna_version_get_fw_version + accessory_info_service.o(.text) refers to fmna_battery_platform.o(.text) for fmna_battery_platform_get_battery_level + accessory_info_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + accessory_info_service.o(.text) refers to accessory_info_service.o(.TRACE) for .TRACE + accessory_info_service.o(.text) refers to accessory_info_service.o(.constdata) for .constdata + accessory_info_service.o(.text) refers to accessory_info_service.o(.bss) for .bss + accessory_info_service.o(.constdata) refers to accessory_info_service.o(.constdata) for GATT_UUID_ACC_INFO_SERVICE + accessory_info_service.o(.constdata) refers to accessory_info_service.o(.text) for ais_attr_read_cb + firmware_update_service.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + firmware_update_service.o(.text) refers to firmware_update_service.o(.TRACE) for .TRACE + firmware_update_service.o(.text) refers to firmware_update_service.o(.bss) for .bss + firmware_update_service.o(.text) refers to firmware_update_service.o(.constdata) for .constdata + firmware_update_service.o(.constdata) refers to firmware_update_service.o(.text) for fwus_attr_write_cb + tps.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + tps.o(.text) refers to tps.o(.TRACE) for .TRACE + tps.o(.text) refers to tps.o(.bss) for .bss + tps.o(.text) refers to tps.o(.data) for .data + tps.o(.text) refers to tps.o(.constdata) for .constdata + tps.o(.constdata) refers to tps.o(.conststring) for .conststring + tps.o(.constdata) refers to tps.o(.text) for tps_attr_read_cb + hids_kb.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data + hids_kb.o(.text) refers to hids_kb.o(.bss) for .bss + hids_kb.o(.text) refers to hids_kb.o(.data) for .data + hids_kb.o(.text) refers to hids_kb.o(.constdata) for .constdata + hids_kb.o(.text) refers to hids_kb.o(.TRACE) for .TRACE + hids_kb.o(.constdata) refers to hids_kb.o(.text) for hids_attr_read_cb + ias.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + ias.o(.text) refers to ias.o(.TRACE) for .TRACE + ias.o(.text) refers to ias.o(.bss) for .bss + ias.o(.text) refers to ias.o(.constdata) for .constdata + ias.o(.constdata) refers to ias.o(.text) for ias_attr_write_cb + sdd_service.o(.text) refers to gap_lib_system_call.o(.text) for server_send_data + sdd_service.o(.text) refers to sdd_service.o(.TRACE) for .TRACE + sdd_service.o(.text) refers to sdd_service.o(.bss) for .bss + sdd_service.o(.text) refers to sdd_service.o(.data) for .data + sdd_service.o(.text) refers to sdd_service.o(.constdata) for .constdata + sdd_service.o(.constdata) refers to sdd_service.o(.text) for sdd_attr_read_cb + dis.o(.text) refers to gap_lib_system_call.o(.text) for server_add_service + dis.o(.text) refers to dis.o(.data) for .data + dis.o(.text) refers to dis.o(.TRACE) for .TRACE + dis.o(.text) refers to dis.o(.bss) for .bss + dis.o(.text) refers to dis.o(.constdata) for .constdata + dis.o(.constdata) refers to dis.o(.text) for dis_attr_read_cb + main.o(.app.flash.text) refers to gap_config.o(.app.flash.text) for gap_config_max_le_paired_device + main.o(.text) refers to key_handle.o(.text) for gpio_board_init + main.o(.text) refers to fmna_motion_detection_platform.o(.text) for board_i2c_master_init + main.o(.text) refers to fmna_battery_platform.o(.text) for bat_init_driver + main.o(.text) refers to key_crypto.o(.text) for hw_timer_driver_init + main.o(.text) refers to rtl876x_io_dlps.o(.text) for DLPS_IORegister + main.o(.text) refers to app_task.o(.text) for app_task_init + main.o(.text) refers to rand.o(.text) for srand + main.o(.text) refers to findmy_app.o(.text) for app_global_data_init + main.o(.text) refers to fmna_connection.o(.text) for fmna_connection_pair_info_restore + main.o(.text) refers to fmna_gap_platform.o(.text) for one_shot_adv_init + main.o(.text) refers to fmna_version.o(.text) for fmna_version_init + main.o(.text) refers to fmna_adv_platform.o(.text) for fmna_ble_platform_init + main.o(.text) refers to fmna_gatt_platform.o(.text) for fmna_gatt_platform_init + main.o(.text) refers to fmna_sound_platform.o(.text) for fmna_sound_platform_init + main.o(.text) refers to fmna_motion_detection.o(.text) for fmna_motion_detection_init + main.o(.text) refers to serial_number_send.o(.text) for custom_new_adv_init + main.o(.text) refers to fmna_timer_platform.o(.text) for sw_timer_init + main.o(.text) refers to rtl876x_pinmux.o(.text) for System_WakeUpInterruptValue + main.o(.text) refers to fmna_sound_platform.o(.bss) for sound_en + main.o(.text) refers to rtl876x_io_dlps.o(.bss) for User_IO_EnterDlpsCB + main.o(.text) refers to system_rtl876x.o(.bss) for random_seed_value + main.o(.text) refers to main.o(.TRACE) for .TRACE + main.o(.text) refers to findmy_app.o(.bss) for app_global_data + main.o(.text) refers to key_handle.o(.bss) for gpio_key_debounce_timer + app_task.o(.text) refers to gap_lib_system_call.o(.text) for gap_start_bt_stack + app_task.o(.text) refers to main.o(.text) for driver_init + app_task.o(.text) refers to rtl876x_aon_wdg.o(.text) for AON_WDG_Config + app_task.o(.text) refers to findmy_app.o(.text) for app_handle_io_msg + app_task.o(.text) refers to app_task.o(.constdata) for .constdata + app_task.o(.text) refers to app_task.o(.bss) for .bss + app_task.o(.text) refers to app_task.o(.TRACE) for .TRACE + findmy_app.o(.text) refers to fmna_sound_platform.o(.text) for fmna_sound_is_playing + findmy_app.o(.text) refers to custom_app.o(.text) for cust_feature_enable + findmy_app.o(.text) refers to fmna_gatt_platform.o(.text) for fmna_gatt_platform_get_gatt_data + findmy_app.o(.text) refers to sdd_service.o(.text) for sdd_battery_level_value_notify + findmy_app.o(.text) refers to fmna_connection_platform.o(.text) for fmna_connection_platform_get_serial_number + findmy_app.o(.text) refers to serial_number_send.o(.text) for custom_new_adv_init + findmy_app.o(.text) refers to fmna_connection.o(.text) for fmna_connection_set_is_fmna_paired + findmy_app.o(.text) refers to system_rtl876x.o(.text) for log_direct_app + findmy_app.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_init + findmy_app.o(.text) refers to fmna_crypto.o(.text) for serial_number_read_state_init + findmy_app.o(.text) refers to gap_lib_system_call.o(.text) for le_find_key_entry_by_idx + findmy_app.o(.text) refers to findmy_app.o(.TRACE) for .TRACE + findmy_app.o(.text) refers to findmy_app.o(.bss) for .bss + findmy_app.o(.text) refers to custom_app.o(.bss) for custom_data + findmy_app.o(.text) refers to findmy_app.o(.data) for .data + findmy_app.o(.text) refers to fmna_timer_platform.o(.bss) for disconnection_click_timer + findmy_app.o(.text) refers to fmna_crypto.o(.bss) for serial_number_read_state + findmy_app.o(.text) refers to fmna_gap_platform.o(.text) for fmble_gap_adv_stop + findmy_app.o(.text) refers to fmna_battery_platform.o(.text) for bat_update_battery_info + findmy_app.o(.text) refers to key_crypto.o(.text) for crypto_enter_dlps_config + findmy_app.o(.text) refers to fmna_gatt.o(.data) for m_gatt_mtu + findmy_app.o(.text) refers to fmna_gap_platform.o(.bss) for one_shot_adv_data + findmy_app.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_stop_adv + findmy_app.o(.text) refers to rtl876x_aon_wdg.o(.text) for AON_WDG_Restart + findmy_app.o(.text) refers to tps.o(.text) for tps_set_parameter + findmy_app.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_idivmod + findmy_app.o(.text) refers to fmna_gatt_platform.o(.bss) for password_correct + findmy_app.o(.text) refers to sdd_service.o(.data) for sdd_rssi_level + custom_app.o(.text) refers to rand.o(.emb_text) for rand + custom_app.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + custom_app.o(.text) refers to custom_app.o(i.__ARM_common_memcpy1_6) for __ARM_common_memcpy1_6 + custom_app.o(.text) refers to gap_lib_system_call.o(.text) for le_gen_rand_addr + custom_app.o(.text) refers to fmna_gap_platform.o(.text) for one_shot_bt_addr_set + custom_app.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + custom_app.o(.text) refers to custom_app.o(i.__ARM_common_memcpy4_5) for __ARM_common_memcpy4_5 + custom_app.o(.text) refers to custom_app.o(.bss) for .bss + custom_app.o(.text) refers to custom_app.o(.data) for .data + custom_app.o(.text) refers to custom_app.o(.TRACE) for .TRACE + custom_app.o(.text) refers to custom_app.o(.constdata) for .constdata + custom_app.o(.text) refers to findmy_app.o(.bss) for find_my_loacl_apple_mac + dfu_flash.o(.text) refers to system_rtl876x.o(.text) for log_direct_app + dfu_flash.o(.text) refers to dfu_flash.o(.TRACE) for .TRACE + dfu_flash.o(.text) refers to dfu_flash.o(.data) for .data + overlay_mgr.o(.text) refers to overlay_mgr.o(i.__ARM_common_memcpy1_8) for __ARM_common_memcpy1_8 + overlay_mgr.o(.text) refers to overlay_mgr.o(.data) for .data + overlay_mgr.o(.text) refers to overlay_mgr.o(.bss) for .bss + overlay_mgr.o(.data) refers to overlay_mgr.o(.conststring) for .conststring + reset_watch_dog_timer.o(.app.data_ram.text) refers to rtl876x_tim.o(.text) for TIM_Cmd + reset_watch_dog_timer.o(.app.data_ram.text) refers to app_task.o(.text) for app_send_msg_to_apptask + reset_watch_dog_timer.o(.app.data_ram.text) refers to reset_watch_dog_timer.o(.TRACE) for .TRACE + reset_watch_dog_timer.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + reset_watch_dog_timer.o(.text) refers to rtl876x_tim.o(.text) for TIM_StructInit + reset_watch_dog_timer.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init + serial_number_send.o(.text) refers to fmna_connection_platform.o(.text) for fmna_connection_platform_get_serial_number + serial_number_send.o(.text) refers to fmna_gap_platform.o(.text) for fmble_gap_adv_data_set + serial_number_send.o(.text) refers to gap_lib_system_call.o(.text) for le_gen_rand_addr + serial_number_send.o(.text) refers to serial_number_send.o(.bss) for .bss + serial_number_send.o(.text) refers to serial_number_send.o(.TRACE) for .TRACE + serial_number_send.o(.text) refers to serial_number_send.o(.data) for .data + da213b.o(.text) refers to rtl876x_i2c.o(.text) for I2C_MasterWrite + da213b.o(.text) refers to fmna_sound_platform.o(.text) for fmna_sound_platform_stop + da213b.o(.text) refers to da213b.o(.TRACE) for .TRACE + da213b.o(.text) refers to fmna_sound_platform.o(.bss) for sound_en + key_handle.o(.text) refers to fmna_sound_platform.o(.text) for fmna_sound_platform_start + key_handle.o(.text) refers to findmy_app.o(.text) for fmna_factory_reset + key_handle.o(.text) refers to rtl876x_gpio.o(.text) for GPIO_GetPin + key_handle.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + key_handle.o(.text) refers to rtl876x_pinmux.o(.text) for Pinmux_Config + key_handle.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + key_handle.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init + key_handle.o(.text) refers to key_handle.o(.bss) for .bss + key_handle.o(.text) refers to key_handle.o(.TRACE) for .TRACE + fmna_adv.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_get_default_bt_addr + fmna_adv.o(.text) refers to overlay_mgr.o(i.__ARM_common_memcpy1_8) for __ARM_common_memcpy1_8 + fmna_adv.o(.text) refers to fmna_battery_platform.o(.text) for fmna_battery_platform_get_battery_level + fmna_adv.o(.text) refers to custom_app.o(i.__ARM_common_memcpy1_6) for __ARM_common_memcpy1_6 + fmna_adv.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_has_been_maintenanced + fmna_adv.o(.text) refers to fmna_adv.o(.bss) for .bss + fmna_adv.o(.text) refers to fmna_adv.o(.constdata) for .constdata + fmna_adv.o(.text) refers to fmna_adv.o(.TRACE) for .TRACE + fmna_config_control_point.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + fmna_config_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_verify_control_point_opcode_and_length + fmna_config_control_point.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_dispatch_event + fmna_config_control_point.o(.text) refers to fmna_adv.o(.text) for fmna_adv_init_nearby + fmna_config_control_point.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_start_slow_adv + fmna_config_control_point.o(.text) refers to custom_app.o(.text) for cust_feature_is_enabled + fmna_config_control_point.o(.text) refers to fmna_config_control_point.o(.data) for .data + fmna_config_control_point.o(.text) refers to fmna_config_control_point.o(.TRACE) for .TRACE + fmna_config_control_point.o(.text) refers to fmna_state_machine.o(.bss) for m_fmna_current_primary_key + fmna_config_control_point.o(.text) refers to fmna_timer_platform.o(.bss) for unpair_pending_timer + fmna_config_control_point.o(.text) refers to fmna_state_machine.o(.data) for m_fmna_key_rotation_timeout_ms + fmna_connection.o(.text) refers to fmna_connection_platform.o(.text) for fmna_connection_platform_disconnect + fmna_connection.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_get_most_recent_conn_handle + fmna_connection.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_stop_adv + fmna_connection.o(.text) refers to fmna_adv.o(.text) for fmna_adv_init_nearby + fmna_connection.o(.text) refers to fmna_state_machine.o(.text) for fmna_evt_handler + fmna_connection.o(.text) refers to fmna_connection.o(.bss) for .bss + fmna_connection.o(.text) refers to fmna_connection.o(.data) for .data + fmna_connection.o(.text) refers to fmna_connection.o(.TRACE) for .TRACE + fmna_connection.o(.text) refers to fmna_state_machine.o(.bss) for m_fmna_current_primary_key + fmna_connection.o(.text) refers to fmna_connection.o(.constdata) for .constdata + fmna_connection.o(.text) refers to gap_lib_system_call.o(.text) for le_find_key_entry_by_idx + fmna_connection.o(.text) refers to fmna_peer_manager.o(.text) for fmna_pm_delete_bonds + fmna_connection.o(.text) refers to fmna_crypto.o(.text) for fmna_crypto_unpair + fmna_connection.o(.text) refers to fmna_pairing_control_point.o(.text) for fmna_pairing_control_point_unpair + fmna_connection.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_connection.o(.text) refers to fmna_timer_platform.o(.bss) for unpair_pending_timer + fmna_connection.o(.text) refers to fmna_state_machine.o(.data) for m_fmna_key_rotation_timeout_ms + fmna_crypto.o(.text) refers to base64.o(.text) for mbedtls_base64_decode + fmna_crypto.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + fmna_crypto.o(.text) refers to fm-crypto.o(.text) for fm_crypto_ckg_init + fmna_crypto.o(.text) refers to fmna_connection_platform.o(.text) for fmna_connection_platform_get_serial_number + fmna_crypto.o(.text) refers to fmna_version.o(.text) for fmna_version_get_fw_version + fmna_crypto.o(.text) refers to fmna_malloc_platform.o(.text) for fmna_malloc + fmna_crypto.o(.text) refers to fmna_crypto.o(.bss) for .bss + fmna_crypto.o(.text) refers to fmna_crypto.o(.TRACE) for .TRACE + fmna_crypto.o(.text) refers to fmna_crypto.o(.constdata) for .constdata + fmna_crypto.o(.text) refers to fmna_state_machine.o(.bss) for m_fmna_temp_primary_key + fmna_crypto.o(.text) refers to key_crypto.o(.data) for is_key_rotated + fmna_crypto.o(.text) refers to fmna_timer_platform.o(.bss) for sn_lookup_timer + fmna_debug_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_verify_control_point_opcode_and_length + fmna_debug_control_point.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_set_key_rotation_timeout_ms + fmna_debug_control_point.o(.text) refers to fmna_motion_detection.o(.text) for fmna_motion_detection_set_separated_ut_backoff_timeout_seconds + fmna_debug_control_point.o(.text) refers to fmna_debug_control_point.o(.data) for .data + fmna_debug_control_point.o(.text) refers to fmna_debug_control_point.o(.TRACE) for .TRACE + fmna_debug_control_point.o(.text) refers to fmna_debug_control_point.o(.constdata) for .constdata + fmna_gatt.o(.text) refers to fmna_gatt_platform.o(.text) for fmna_gatt_platform_send_next_indication + fmna_gatt.o(.text) refers to app_task.o(.text) for app_sched_event_put + fmna_gatt.o(.text) refers to fmna_config_control_point.o(.text) for fmna_config_control_point_is_tx_allowed + fmna_gatt.o(.text) refers to fmna_connection.o(.text) for fmna_connection_get_num_connections + fmna_gatt.o(.text) refers to fmna_nonowner_control_point.o(.text) for fmna_nonowner_rx_handler + fmna_gatt.o(.text) refers to fmna_paired_owner_control_point.o(.text) for fmna_paired_owner_rx_handler + fmna_gatt.o(.text) refers to fmna_debug_control_point.o(.text) for fmna_debug_control_point_rx_handler + fmna_gatt.o(.text) refers to fmna_gatt.o(.TRACE) for .TRACE + fmna_gatt.o(.text) refers to fmna_gatt.o(.bss) for .bss + fmna_gatt.o(.text) refers to fmna_gatt.o(.data) for .data + fmna_gatt.o(.text) refers to fmna_pairing_control_point.o(.text) for fmna_pairing_control_point_append_to_rx_buffer + fmna_motion_detection.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + fmna_motion_detection.o(.text) refers to fmna_motion_detection_platform.o(.text) for fmna_motion_detection_platform_deinit + fmna_motion_detection.o(.text) refers to fmna_timer_platform.o(.text) for app_timer_stop + fmna_motion_detection.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_dispatch_event + fmna_motion_detection.o(.text) refers to fmna_motion_detection.o(.TRACE) for .TRACE + fmna_motion_detection.o(.text) refers to fmna_motion_detection.o(.bss) for .bss + fmna_motion_detection.o(.text) refers to fmna_motion_detection.o(.data) for .data + fmna_motion_detection.o(.text) refers to fmna_motion_detection.o(.constdata) for .constdata + fmna_nonowner_control_point.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_is_nearby + fmna_nonowner_control_point.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_status_bit_enabled + fmna_nonowner_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_verify_control_point_opcode_and_length + fmna_nonowner_control_point.o(.text) refers to fmna_nonowner_control_point.o(.TRACE) for .TRACE + fmna_nonowner_control_point.o(.text) refers to fmna_nonowner_control_point.o(.data) for .data + fmna_nonowner_control_point.o(.text) refers to fmna_nonowner_control_point.o(.bss) for .bss + fmna_paired_owner_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_verify_control_point_opcode_and_length + fmna_paired_owner_control_point.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + fmna_paired_owner_control_point.o(.text) refers to fmna_paired_owner_control_point.o(.data) for .data + fmna_paired_owner_control_point.o(.text) refers to fmna_paired_owner_control_point.o(.TRACE) for .TRACE + fmna_paired_owner_control_point.o(.text) refers to fmna_state_machine.o(.bss) for m_fmna_current_primary_key + fmna_paired_owner_control_point.o(.text) refers to fmna_paired_owner_control_point.o(.constdata) for .constdata + fmna_paired_owner_control_point.o(.text) refers to fmna_crypto.o(.bss) for serial_number_read_state + fmna_pairing_control_point.o(.text) refers to fmna_connection.o(.text) for fmna_connection_fmna_unpair + fmna_pairing_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_verify_control_point_opcode_and_length + fmna_pairing_control_point.o(.text) refers to fmna_malloc_platform.o(.text) for fmna_malloc + fmna_pairing_control_point.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_dispatch_event + fmna_pairing_control_point.o(.text) refers to fmna_pairing_control_point.o(.bss) for .bss + fmna_pairing_control_point.o(.text) refers to fmna_pairing_control_point.o(.TRACE) for .TRACE + fmna_pairing_control_point.o(.text) refers to fmna_pairing_control_point.o(.data) for .data + fmna_pairing_control_point.o(.text) refers to fmna_crypto.o(.bss) for p_fmna_initiate_pairing_data + fmna_state_machine.o(.text) refers to fmna_motion_detection.o(.text) for fmna_motion_detection_stop + fmna_state_machine.o(.text) refers to fmna_timer_platform.o(.text) for app_timer_stop + fmna_state_machine.o(.text) refers to fmna_adv.o(.text) for fmna_adv_init_pairing + fmna_state_machine.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_start_fast_adv + fmna_state_machine.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + fmna_state_machine.o(.text) refers to fmna_crypto.o(.text) for fmna_crypto_roll_secondary_key + fmna_state_machine.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_send_command_response + fmna_state_machine.o(.text) refers to app_task.o(.text) for app_sched_event_put + fmna_state_machine.o(.text) refers to key_crypto.o(.text) for fmna_rotate_key_internal + fmna_state_machine.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + fmna_state_machine.o(.text) refers to fmna_gatt_platform.o(.text) for fmna_gatt_platform_get_most_recent_conn_handle + fmna_state_machine.o(.text) refers to fmna_state_machine.o(.bss) for .bss + fmna_state_machine.o(.text) refers to fmna_state_machine.o(.TRACE) for .TRACE + fmna_state_machine.o(.text) refers to fmna_state_machine.o(.data) for .data + fmna_state_machine.o(.text) refers to fmna_state_machine.o(.constdata) for .constdata + fmna_state_machine.o(.text) refers to fmna_peer_manager.o(.text) for fmna_pm_delete_bonds + fmna_state_machine.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_state_machine.o(.text) refers to key_crypto.o(.data) for is_key_rotated + fmna_state_machine.o(.text) refers to fmna_sound_platform.o(.text) for fmna_sound_platform_start + fmna_state_machine.o(.text) refers to fmna_malloc_platform.o(.text) for fmna_malloc + fmna_state_machine.o(.text) refers to fmna_connection.o(.bss) for m_fmna_active_connections + fmna_state_machine.o(.text) refers to fmna_crypto.o(.bss) for p_fmna_send_pairing_data + fmna_state_machine.o(.text) refers to fmna_connection_platform.o(.text) for fmna_connection_mfi_token_stored + fmna_state_machine.o(.text) refers to custom_app.o(.text) for cust_adv_update_device_name + fmna_state_machine.o(.text) refers to fmna_nonowner_control_point.o(.bss) for m_aggressive_ut_adv_enabled + fmna_state_machine.o(.text) refers to fmna_adv.o(.constdata) for fmna_nearby_adv_fast_duration + fmna_state_machine.o(.text) refers to fmna_battery_platform.o(.text) for bat_update_battery_info + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_boot_evt_boot_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_pair_evt_bonded_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_separated_evt_key_rotate_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_nearby_evt_timeout_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_fmna_pair_evt_disconnected_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_fmna_pair_evt_fmna_pairing_finalize_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_generic_evt_bonded_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.text) for fmna_disconnecting_evt_nearby_handler + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_boot_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_pair_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_separated_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_nearby_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_connecting_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_fmna_pair_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_fmna_pair_complete_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_connected_evt_handlers + fmna_state_machine.o(.constdata) refers to fmna_state_machine.o(.constdata) for fmna_sm_disconnecting_evt_handlers + fmna_state_machine.o(.data) refers to fmna_state_machine.o(.conststring) for .conststring + fmna_uarp_control_point.o(.text) refers to fmnasampleuarp.o(.text) for FMNASampleSendMessageComplete + fmna_uarp_control_point.o(.text) refers to app_task.o(.text) for app_sched_event_put + fmna_uarp_control_point.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_send_indication + fmna_uarp_control_point.o(.text) refers to fmna_dfu_platform.o(.text) for dfu_buf_free + fmna_uarp_control_point.o(.text) refers to fmna_crypto.o(.text) for fmna_crypto_get_serial_number_raw + fmna_uarp_control_point.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_fmna_paired + fmna_uarp_control_point.o(.text) refers to fmna_uarp_control_point.o(.bss) for .bss + fmna_uarp_control_point.o(.text) refers to fmna_uarp_control_point.o(.constdata) for .constdata + fmna_uarp_control_point.o(.text) refers to fmna_uarp_control_point.o(.TRACE) for .TRACE + fmna_uarp_control_point.o(.text) refers to fmna_uarp_control_point.o(.data) for .data + fmna_version.o(.text) refers to fmna_version.o(.bss) for .bss + fmna_version.o(.text) refers to fmna_version.o(.TRACE) for .TRACE + fmnasampleuarp.o(.text) refers to coreuarpplatformaccessory.o(.text) for uarpPlatformAccessoryAssetRelease + fmnasampleuarp.o(.text) refers to fmnasampleuarp.o(.bss) for .bss + fmnasampleuarp.o(.text) refers to fmnasampleuarp.o(.constdata) for .constdata + fmnasampleuarp.o(.text) refers to fmnasampleuarp.o(.TRACE) for .TRACE + fmnasampleuarp.o(.text) refers to fmna_dfu_platform.o(.text) for dfu_service_handle_valid_fw + fmnasampleuarp.o(.text) refers to coreuarpaccessory.o(.text) for uarpAccessoryAssetCorrupt + fmnasampleuarp.o(.text) refers to coreuarputils.o(.text) for uarpPayloadTagPack + fmnasampleuarp.o(.text) refers to fmnasampleuarp.o(.data) for .data + fmnasampleuarp.o(.text) refers to coreuarpplatformrtk.o(.text) for uarpFree + fmnasampleuarp.o(.constdata) refers to fmnasampleuarp.o(.conststring) for .conststring + fmna_adv_platform.o(.text) refers to gap_lib_system_call.o(.text) for le_gen_rand_addr + fmna_adv_platform.o(.text) refers to fmna_gap_platform.o(.text) for one_shot_bt_addr_set + fmna_adv_platform.o(.text) refers to gap_lib.o(.text) for gap_lib_init + fmna_adv_platform.o(.text) refers to gap_config.o(.app.flash.text) for gap_config_le_key_storage_flag + fmna_adv_platform.o(.text) refers to fmna_adv_platform.o(.constdata) for .constdata + fmna_adv_platform.o(.text) refers to fmna_adv_platform.o(.TRACE) for .TRACE + fmna_adv_platform.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_adv_platform.o(.text) refers to fmna_adv_platform.o(.bss) for .bss + fmna_adv_platform.o(.text) refers to fmna_timer_platform.o(.bss) for adv_timer + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_pairing_adv_fast_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_pairing_adv_fast_intv + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_pairing_adv_slow_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_pairing_adv_slow_intv + fmna_adv_platform.o(.text) refers to fmna_adv_platform.o(.data) for .data + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_nearby_adv_fast_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_nearby_adv_fast_intv + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_nearby_adv_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_nearby_adv_intv + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_separated_adv_fast_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_separated_adv_fast_intv + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_separated_adv_slow_duration + fmna_adv_platform.o(.text) refers to fmna_adv.o(.constdata) for fmna_separated_adv_slow_intv + fmna_adv_platform.o(.text) refers to findmy_app.o(.text) for app_gap_callback + fmna_battery_platform.o(.text) refers to adc_lib.o(.text) for ADC_CalibrationInit + fmna_battery_platform.o(.text) refers to rtl876x_adc.o(.text) for ADC_DeInit + fmna_battery_platform.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + fmna_battery_platform.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_idivmod + fmna_battery_platform.o(.text) refers to dflti.o(.text) for __aeabi_i2d + fmna_battery_platform.o(.text) refers to daddsub.o(.text) for __aeabi_dsub + fmna_battery_platform.o(.text) refers to d2f.o(.text) for __aeabi_d2f + fmna_battery_platform.o(.text) refers to ffixui.o(.text) for __aeabi_f2uiz + fmna_battery_platform.o(.text) refers to fmna_adv_platform.o(.text) for fmna_adv_platform_stop_adv + fmna_battery_platform.o(.text) refers to fmna_battery_platform.o(.TRACE) for .TRACE + fmna_battery_platform.o(.text) refers to fmna_battery_platform.o(.bss) for .bss + fmna_battery_platform.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_connection_platform.o(.text) refers to gap_lib_system_call.o(.text) for le_disconnect + fmna_connection_platform.o(.text) refers to fmna_connection.o(.text) for fmna_connection_connected_handler + fmna_connection_platform.o(.text) refers to fmna_gatt_platform.o(.text) for on_connect + fmna_connection_platform.o(.text) refers to fmna_peer_manager.o(.text) for fmna_pm_conn_sec_handle + fmna_connection_platform.o(.text) refers to custom_app.o(.text) for cust_adv_update_device_name + fmna_connection_platform.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_dispatch_event + fmna_connection_platform.o(.text) refers to fmna_connection_platform.o(.TRACE) for .TRACE + fmna_connection_platform.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_connection_platform.o(.text) refers to fmna_connection_platform.o(.constdata) for .constdata + fmna_connection_platform.o(.text) refers to fmna_connection_platform.o(.bss) for .bss + fmna_dfu_platform.o(.text) refers to dfu_flash.o(.text) for dfu_update + fmna_dfu_platform.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + fmna_dfu_platform.o(.text) refers to system_rtl876x.o(.text) for log_direct_app + fmna_dfu_platform.o(.text) refers to fmna_dfu_platform.o(.bss) for .bss + fmna_dfu_platform.o(.text) refers to fmna_dfu_platform.o(.TRACE) for .TRACE + fmna_dfu_platform.o(.text) refers to fmna_dfu_platform.o(.constdata) for .constdata + fmna_gap_platform.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + fmna_gap_platform.o(.text) refers to rand.o(.emb_text) for rand + fmna_gap_platform.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + fmna_gap_platform.o(.text) refers to custom_app.o(i.__ARM_common_memcpy1_6) for __ARM_common_memcpy1_6 + fmna_gap_platform.o(.text) refers to gap_lib_system_call.o(.text) for le_adv_set_param + fmna_gap_platform.o(.text) refers to dflti.o(.text) for __aeabi_ui2d + fmna_gap_platform.o(.text) refers to dmul.o(.text) for __aeabi_dmul + fmna_gap_platform.o(.text) refers to dfixui.o(.text) for __aeabi_d2uiz + fmna_gap_platform.o(.text) refers to fmna_gap_platform.o(.TRACE) for .TRACE + fmna_gap_platform.o(.text) refers to fmna_gap_platform.o(.bss) for .bss + fmna_gap_platform.o(.text) refers to fmna_gap_platform.o(.constdata) for .constdata + fmna_gatt_platform.o(.text) refers to gap_lib_system_call.o(.text) for le_get_conn_id_by_handle + fmna_gatt_platform.o(.text) refers to fmna_connection.o(.text) for fmna_connection_is_valid_connection + fmna_gatt_platform.o(.text) refers to fmna_gatt.o(.text) for fmna_gatt_dispatch_send_packet_extension_indication + fmna_gatt_platform.o(.text) refers to sdd_service.o(.text) for sdd_battery_level_value_notify + fmna_gatt_platform.o(.text) refers to fmna_battery_platform.o(.text) for fmna_battery_platform_get_battery_level + fmna_gatt_platform.o(.text) refers to custom_app.o(.text) for cust_connection_disconnect_this + fmna_gatt_platform.o(.text) refers to fmna_sound_platform.o(.text) for play_beep_mode + fmna_gatt_platform.o(.text) refers to accessory_info_service.o(.text) for accessory_info_add_service + fmna_gatt_platform.o(.text) refers to findmy_network_service.o(.text) for findmy_network_add_service + fmna_gatt_platform.o(.text) refers to tps.o(.text) for tps_add_service + fmna_gatt_platform.o(.text) refers to ias.o(.text) for ias_add_service + fmna_gatt_platform.o(.text) refers to dis.o(.text) for dis_add_service + fmna_gatt_platform.o(.text) refers to fmna_gatt_platform.o(.bss) for .bss + fmna_gatt_platform.o(.text) refers to fmna_gatt_platform.o(.TRACE) for .TRACE + fmna_gatt_platform.o(.text) refers to fmna_gatt.o(.bss) for fmna_service_current_extended_packet_tx + fmna_gatt_platform.o(.text) refers to fmna_gatt_platform.o(.data) for .data + fmna_gatt_platform.o(.text) refers to custom_app.o(.bss) for custom_data + fmna_gatt_platform.o(.text) refers to sdd_service.o(.data) for sdd_rssi_level + fmna_gatt_platform.o(.text) refers to fmna_gatt_platform.o(.constdata) for .constdata + fmna_gatt_platform.o(.text) refers to app_task.o(.bss) for bt_indication_queue + fmna_gatt_platform.o(.text) refers to fmna_gatt.o(.bss) for m_command_response_index + fmna_malloc_platform.o(.text) refers to fmna_malloc_platform.o(.TRACE) for .TRACE + fmna_malloc_platform.o(.text) refers to fmna_malloc_platform.o(.bss) for .bss + fmna_malloc_platform.o(.text) refers to fmna_malloc_platform.o(.constdata) for .constdata + fmna_motion_detection_platform.o(.text) refers to rtl876x_pinmux.o(.text) for Pad_Config + fmna_motion_detection_platform.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + fmna_motion_detection_platform.o(.text) refers to rtl876x_i2c.o(.text) for I2C_Cmd + fmna_motion_detection_platform.o(.text) refers to da213b.o(.text) for da213b_init + fmna_motion_detection_platform.o(.text) refers to fmna_motion_detection_platform.o(.TRACE) for .TRACE + fmna_motion_detection_platform.o(.text) refers to fmna_motion_detection_platform.o(.bss) for .bss + fmna_peer_manager.o(.text) refers to gap_lib_system_call.o(.text) for le_get_bond_dev_num + fmna_peer_manager.o(.text) refers to fmna_connection.o(.text) for fmna_connection_update_connection_info + fmna_peer_manager.o(.text) refers to fmna_state_machine.o(.text) for fmna_evt_handler + fmna_peer_manager.o(.text) refers to fmna_peer_manager.o(.TRACE) for .TRACE + fmna_peer_manager.o(.text) refers to findmy_app.o(.bss) for app_global_data + fmna_sound_platform.o(.text) refers to rtl876x_pinmux.o(.text) for Pad_Config + fmna_sound_platform.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + fmna_sound_platform.o(.text) refers to rtl876x_tim.o(.text) for TIM_PWMChangeFreqAndDuty + fmna_sound_platform.o(.text) refers to fmna_timer_platform.o(.text) for app_timer_start + fmna_sound_platform.o(.text) refers to fmna_state_machine.o(.text) for fmna_state_machine_dispatch_event + fmna_sound_platform.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + fmna_sound_platform.o(.text) refers to fmna_sound_platform.o(.bss) for .bss + fmna_sound_platform.o(.text) refers to fmna_sound_platform.o(.TRACE) for .TRACE + fmna_sound_platform.o(.text) refers to fmna_sound_platform.o(.constdata) for .constdata + fmna_timer_platform.o(.app.data_ram.text) refers to app_task.o(.text) for app_send_msg_to_apptask + fmna_timer_platform.o(.app.data_ram.text) refers to fmna_timer_platform.o(.TRACE) for .TRACE + fmna_timer_platform.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + fmna_timer_platform.o(.text) refers to fmna_malloc_platform.o(.text) for fmna_free + fmna_timer_platform.o(.text) refers to fmna_connection.o(.text) for fmna_connection_get_unpair_pending + fmna_timer_platform.o(.text) refers to findmy_app.o(.text) for fmna_factory_reset + fmna_timer_platform.o(.text) refers to fmna_timer_platform.o(.TRACE) for .TRACE + fmna_timer_platform.o(.text) refers to fmna_crypto.o(.bss) for serial_number_read_state + fmna_timer_platform.o(.text) refers to fmna_timer_platform.o(.bss) for .bss + fmna_timer_platform.o(.text) refers to fmna_timer_platform.o(.app.data_ram.text) for aon_watch_dog_wake_up_dlps_callback + coreuarputils.o(.text) refers to coreuarpplatformrtk.o(.text) for uarpNtohl + coreuarpaccessory.o(.text) refers to coreuarpplatformrtk.o(.text) for uarpHtons + coreuarpaccessory.o(.text) refers to coreuarpaccessory.o(.bss) for .bss + coreuarpaccessory.o(.text) refers to coreuarpaccessory.o(.TRACE) for .TRACE + coreuarpaccessory.o(.text) refers to coreuarpaccessory.o(.constdata) for .constdata + coreuarpaccessory.o(.text) refers to coreuarputils.o(.text) for uarpVersionEndianSwap + coreuarpaccessory.o(.text) refers to fmna_dfu_platform.o(.text) for dfu_service_handle_active_image + coreuarpaccessory.o(.constdata) refers to coreuarpaccessory.o(.conststring) for .conststring + coreuarpplatformaccessory.o(.text) refers to coreuarpaccessory.o(.text) for uarpAccessoryAssetRequestData + coreuarpplatformaccessory.o(.text) refers to coreuarputils.o(.text) for uarpVersionCompare + coreuarpplatformaccessory.o(.text) refers to coreuarpplatformaccessory.o(.bss) for .bss + coreuarpplatformaccessory.o(.text) refers to coreuarpplatformaccessory.o(.TRACE) for .TRACE + coreuarpplatformaccessory.o(.text) refers to coreuarpplatformaccessory.o(.constdata) for .constdata + coreuarpplatformaccessory.o(.text) refers to coreuarpplatformrtk.o(.text) for uarpNtohl + coreuarpplatformaccessory.o(.text) refers to fmna_dfu_platform.o(.text) for dfu_handle_uarp_payload + coreuarpplatformaccessory.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + coreuarpplatformaccessory.o(.text) refers to fmnasampleuarp.o(.bss) for total_payload_index + coreuarpplatformaccessory.o(.constdata) refers to coreuarpplatformaccessory.o(.conststring) for .conststring + coreuarpplatformrtk.o(.text) refers to coreuarpplatformrtk.o(.constdata) for .constdata + coreuarpplatformrtk.o(.text) refers to coreuarpplatformrtk.o(.TRACE) for .TRACE + fm-crypto.o(.text) refers to sha256.o(.text) for mbedtls_sha256 + fm-crypto.o(.text) refers to ecp.o(.text) for mbedtls_ecp_point_init + fm-crypto.o(.text) refers to platform_util.o(.text) for mbedtls_platform_frng + fm-crypto.o(.text) refers to ecp_curves.o(.text) for mbedtls_ecp_group_load + fm-crypto.o(.text) refers to bignum.o(.text) for mbedtls_mpi_write_binary + fm-crypto.o(.text) refers to kdf963.o(.text) for mbed_KDF963 + fm-crypto.o(.text) refers to fm-crypto.o(.constdata) for .constdata + fm-crypto.o(.text) refers to gcm.o(.text) for mbedtls_gcm_init + fm-crypto.o(.text) refers to ecdsa.o(.text) for mbedtls_ecdsa_init + fm-crypto.o(.text) refers to md.o(.text) for mbedtls_md_init + fm-crypto.o(.text) refers to ecdh.o(.text) for mbedtls_ecdh_compute_shared + kdf963.o(.text) refers to sha256.o(.text) for mbedtls_sha256_init + aes.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + aes.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + aes.o(.text) refers to aes.o(.bss) for .bss + aes.o(.text) refers to aes.o(.constdata) for .constdata + asn1parse.o(.text) refers to bignum.o(.text) for mbedtls_mpi_read_binary + asn1parse.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + asn1parse.o(.text) refers to asn1parse.o(.constdata) for .constdata + asn1write.o(.text) refers to bignum.o(.text) for mbedtls_mpi_size + asn1write.o(.text) refers to asn1parse.o(.text) for mbedtls_asn1_find_named_data + asn1write.o(.text) refers to asn1write.o(.constdata) for .constdata + base64.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + base64.o(.text) refers to constant_time.o(.bss) for mbedtls_ct_zero + bignum.o(.app.data_ram.text) refers to bignum.o(.text) for mbedtls_mpi_copy + bignum.o(.app.data_ram.text) refers to bignum_core.o(.text) for mbedtls_mpi_core_add + bignum.o(.app.data_ram.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + bignum.o(.app.data_ram.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + bignum.o(.text) refers to bignum_core.o(.text) for mbedtls_mpi_core_lt_ct + bignum.o(.text) refers to platform_util.o(.text) for mbedtls_zeroize_and_free + bignum.o(.text) refers to constant_time.o(.bss) for mbedtls_ct_zero + bignum.o(.text) refers to bignum.o(.constdata) for .constdata + bignum.o(.text) refers to bignum.o(.app.data_ram.text) for mbedtls_mpi_mul_int + bignum.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + bignum.o(.text) refers to rt_memmove.o(.text) for __aeabi_memmove + bignum_core.o(.text) refers to bignum_core.o(.constdata) for .constdata + bignum_core.o(.text) refers to constant_time.o(.bss) for mbedtls_ct_zero + bignum_core.o(.text) refers to constant_time.o(.text) for mbedtls_ct_memcpy_if + bignum_core.o(.text) refers to bignum.o(.text) for mbedtls_mpi_lset + cipher.o(.text) refers to strcmpv6m.o(.text) for strcmp + cipher.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + cipher.o(.text) refers to gcm.o(.text) for mbedtls_gcm_starts + cipher.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + cipher.o(.text) refers to constant_time.o(.text) for mbedtls_ct_memcmp + cipher.o(.text) refers to cipher.o(.bss) for .bss + cipher.o(.text) refers to cipher_wrap.o(.constdata) for mbedtls_cipher_definitions + cipher.o(.text) refers to cipher_wrap.o(.bss) for mbedtls_cipher_supported + cipher.o(.text) refers to cipher_wrap.o(.data) for mbedtls_cipher_base_lookup_table + cipher_wrap.o(.text) refers to gcm.o(.text) for mbedtls_gcm_init + cipher_wrap.o(.text) refers to aes.o(.text) for mbedtls_aes_crypt_ecb + cipher_wrap.o(.text) refers to cipher_wrap.o(.constdata) for .constdata + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.text) for aes_crypt_ecb_wrap + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.text) for gcm_aes_setkey_wrap + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.conststring) for .conststring + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_128_ecb_info + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_192_ecb_info + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_256_ecb_info + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_128_gcm_info + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_192_gcm_info + cipher_wrap.o(.constdata) refers to cipher_wrap.o(.constdata) for aes_256_gcm_info + cipher_wrap.o(.data) refers to cipher_wrap.o(.constdata) for aes_info + cipher_wrap.o(.data) refers to cipher_wrap.o(.constdata) for gcm_aes_info + constant_time.o(.text) refers to constant_time.o(.bss) for .bss + ecdh.o(.text) refers to ecp.o(.text) for mbedtls_ecp_point_init + ecdh.o(.text) refers to bignum.o(.text) for mbedtls_mpi_copy + ecdh.o(.text) refers to ecp_curves.o(.text) for mbedtls_ecp_group_load + ecdsa.o(.text) refers to bignum.o(.text) for mbedtls_mpi_cmp_int + ecdsa.o(.text) refers to ecp.o(.text) for mbedtls_ecp_point_init + ecdsa.o(.text) refers to bignum.o(.app.data_ram.text) for mbedtls_mpi_sub_mpi + ecdsa.o(.text) refers to ecdsa.o(.constdata) for .constdata + ecdsa.o(.text) refers to asn1write.o(.text) for mbedtls_asn1_write_mpi + ecdsa.o(.text) refers to asn1parse.o(.text) for mbedtls_asn1_get_tag + ecdsa.o(.text) refers to ecp_curves.o(.text) for mbedtls_ecp_group_load + ecp.o(.text) refers to bignum.o(.text) for mbedtls_mpi_init + ecp.o(.text) refers to strcmpv6m.o(.text) for strcmp + ecp.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + ecp.o(.text) refers to ecp_curves.o(.text) for mbedtls_ecp_group_load + ecp.o(.text) refers to ecp.o(.bss) for .bss + ecp.o(.text) refers to ecp.o(.constdata) for .constdata + ecp.o(.text) refers to bignum.o(.app.data_ram.text) for mbedtls_mpi_mul_mpi + ecp.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_uidivmod + ecp.o(.constdata) refers to ecp.o(.conststring) for .conststring + ecp_curves.o(.text) refers to bignum.o(.text) for mbedtls_mpi_bitlen + ecp_curves.o(.text) refers to ecp_curves.o(.data) for .data + ecp_curves.o(.text) refers to ecp.o(.text) for mbedtls_ecp_group_free + ecp_curves.o(.text) refers to ecp_curves.o(.constdata) for .constdata + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_0_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_0_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.data) for mpi_one + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_1_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_1_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_2_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_2_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_3_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_3_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_4_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_4_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_5_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_5_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_6_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_6_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_7_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_7_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_8_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_8_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_9_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_9_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_10_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_10_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_11_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_11_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_12_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_12_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_13_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_13_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_14_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_14_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_15_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp224r1_T_15_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_0_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_0_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_1_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_1_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_2_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_2_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_3_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_3_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_4_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_4_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_5_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_5_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_6_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_6_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_7_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_7_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_8_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_8_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_9_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_9_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_10_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_10_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_11_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_11_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_12_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_12_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_13_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_13_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_14_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_14_Y + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_15_X + ecp_curves.o(.constdata) refers to ecp_curves.o(.constdata) for secp256r1_T_15_Y + gcm.o(.text) refers to cipher.o(.text) for mbedtls_cipher_info_from_values + gcm.o(.text) refers to btod.o(i.__ARM_common_ll_muluu) for __ARM_common_ll_muluu + gcm.o(.text) refers to gcm.o(.constdata) for .constdata + gcm.o(.text) refers to overlay_mgr.o(i.__ARM_common_memcpy1_8) for __ARM_common_memcpy1_8 + gcm.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + gcm.o(.text) refers to constant_time.o(.text) for mbedtls_ct_memcmp + md.o(.text) refers to sha256.o(.text) for mbedtls_sha256_free + md.o(.text) refers to platform_util.o(.text) for mbedtls_zeroize_and_free + md.o(.text) refers to strcmpv6m.o(.text) for strcmp + md.o(.text) refers to md.o(.constdata) for .constdata + md.o(.constdata) refers to md.o(.conststring) for .conststring + sha256.o(.text) refers to platform_util.o(.text) for mbedtls_platform_zeroize + platform_util.o(.text) refers to system_rtl876x.o(.text) for malloc + platform_util.o(.text) refers to rand.o(.emb_text) for rand + platform_util.o(.text) refers to platform_util.o(.data) for .data + platform_util.o(.data) refers to memset.o(.text) for memset + gap_config.o(.text) refers to gap_config.o(.TRACE) for .TRACE + gap_lib.o(.text) refers to gap_vendor_cmd.o(.text) for le_handle_vendor_cmd_rsp + gap_lib.o(.text) refers to gap_lib_system_call.o(.text) for gap_register_extend_cb + gap_lib.o(.text) refers to gap_lib.o(.TRACE) for .TRACE + gap_lib_system_call.o(.text) refers to gap_lib_system_call.o(.bss) for .bss + adc_lib.o(.text) refers to fflti.o(.text) for __aeabi_i2f + adc_lib.o(.text) refers to fdiv.o(.text) for __aeabi_fdiv + adc_lib.o(.text) refers to fmul.o(x$fpl$fmul) for __aeabi_fmul + adc_lib.o(.text) refers to faddsub.o(x$fpl$fadd) for __aeabi_fadd + adc_lib.o(.text) refers to adc_lib.o(.data) for .data + adc_lib.o(.text) refers to adc_lib.o(.bss) for .bss + key_crypto.o(.text) refers to rtl876x_tim.o(.text) for TIM_Cmd + key_crypto.o(.text) refers to app_task.o(.text) for app_send_msg_to_apptask + key_crypto.o(.text) refers to fmna_crypto.o(.text) for fmna_crypto_roll_primary_key + key_crypto.o(.text) refers to rtl876x_rcc.o(.text) for RCC_PeriphClockCmd + key_crypto.o(.text) refers to rtl876x_nvic.o(.text) for NVIC_Init + key_crypto.o(.text) refers to key_crypto.o(.TRACE) for .TRACE + key_crypto.o(.text) refers to key_crypto.o(.bss) for .bss + key_crypto.o(.text) refers to key_crypto.o(.data) for .data + gap_vendor_cmd.o(.text) refers to gap_lib_system_call.o(.text) for btif_vendor_cmd_req + gap_vendor_cmd.o(.text) refers to gap_vendor_cmd.o(i.__ARM_common_switch8) for __ARM_common_switch8 + gap_vendor_cmd.o(.text) refers to gap_vendor_cmd.o(.bss) for .bss + gap_vendor_cmd.o(.text) refers to gap_vendor_cmd.o(.constdata) for .constdata + gap_vendor_cmd.o(.text) refers to gap_lib_system_call.o(.bss) for gap_app_cb + vsnprintf.o(.text) refers (Special) to _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) for _printf_a + vsnprintf.o(.text) refers (Special) to _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) for _printf_c + vsnprintf.o(.text) refers (Special) to _printf_charcount.o(.text) for _printf_charcount + vsnprintf.o(.text) refers (Special) to _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) for _printf_d + vsnprintf.o(.text) refers (Special) to _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) for _printf_e + vsnprintf.o(.text) refers (Special) to _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) for _printf_f + vsnprintf.o(.text) refers (Special) to printf1.o(x$fpl$printf1) for _printf_fp_dec + vsnprintf.o(.text) refers (Special) to printf2.o(x$fpl$printf2) for _printf_fp_hex + vsnprintf.o(.text) refers (Special) to _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) for _printf_g + vsnprintf.o(.text) refers (Special) to _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) for _printf_i + vsnprintf.o(.text) refers (Special) to _printf_dec.o(.text) for _printf_int_dec + vsnprintf.o(.text) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l + vsnprintf.o(.text) refers (Special) to _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) for _printf_lc + vsnprintf.o(.text) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + vsnprintf.o(.text) refers (Special) to _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) for _printf_lld + vsnprintf.o(.text) refers (Special) to _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) for _printf_lli + vsnprintf.o(.text) refers (Special) to _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) for _printf_llo + vsnprintf.o(.text) refers (Special) to _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) for _printf_llu + vsnprintf.o(.text) refers (Special) to _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) for _printf_llx + vsnprintf.o(.text) refers (Special) to _printf_longlong_dec.o(.text) for _printf_longlong_dec + vsnprintf.o(.text) refers (Special) to _printf_hex_int_ll_ptr.o(.text) for _printf_longlong_hex + vsnprintf.o(.text) refers (Special) to _printf_oct_int_ll.o(.text) for _printf_longlong_oct + vsnprintf.o(.text) refers (Special) to _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) for _printf_ls + vsnprintf.o(.text) refers (Special) to _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) for _printf_n + vsnprintf.o(.text) refers (Special) to _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) for _printf_o + vsnprintf.o(.text) refers (Special) to _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) for _printf_p + vsnprintf.o(.text) refers (Special) to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + vsnprintf.o(.text) refers (Special) to _printf_pad.o(.text) for _printf_post_padding + vsnprintf.o(.text) refers (Special) to _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) for _printf_s + vsnprintf.o(.text) refers (Special) to _printf_str.o(.text) for _printf_str + vsnprintf.o(.text) refers (Special) to _printf_truncate.o(.text) for _printf_truncate_signed + vsnprintf.o(.text) refers (Special) to _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) for _printf_u + vsnprintf.o(.text) refers (Special) to _printf_wctomb.o(.text) for _printf_wctomb + vsnprintf.o(.text) refers (Special) to _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) for _printf_x + vsnprintf.o(.text) refers to _printf_char_common.o(.text) for _printf_char_common + vsnprintf.o(.text) refers to _sputc.o(.text) for _sputc + vsnprintf.o(.text) refers to _snputc.o(.text) for _snputc + rand.o(.emb_text) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2 + rand.o(.emb_text) refers to rand.o(.text) for _rand_init + rand.o(.emb_text) refers to rand.o(.bss) for _random_number_data + rand.o(.text) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2 + rand.o(.text) refers to rand.o(.bss) for .bss + rand.o(.bss) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000D) for __rt_lib_init_rand_2 + __main.o(!!!main) refers to __rtentry.o(.ARM.Collect$$rtentry$$00000000) for __rt_entry + d2f.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + daddsub.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dfixui.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dflti.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + dmul.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + faddsub.o(x$fpl$fadd) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + faddsub.o(x$fpl$fadd) refers to faddsub.o(x$fpl$fsub) for _fsub1 + faddsub.o(x$fpl$frsb) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + faddsub.o(x$fpl$frsb) refers to faddsub.o(x$fpl$fsub) for _fsub1 + faddsub.o(x$fpl$frsb) refers to faddsub.o(x$fpl$fadd) for _fadd1 + faddsub.o(x$fpl$fsub) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + faddsub.o(x$fpl$fsub) refers to faddsub.o(x$fpl$fadd) for _fadd1 + fdiv.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + fdiv.o(.text) refers to fdiv.o(.constdata) for .constdata + fdiv.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + ffixui.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + fflti.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + fmul.o(x$fpl$fmul) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) for __rt_entry_li + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for __rt_entry_main + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$0000000C) for __rt_entry_postli_1 + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000009) for __rt_entry_postsh_1 + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry2.o(.ARM.Collect$$rtentry$$00000002) for __rt_entry_presh_1 + __rtentry.o(.ARM.Collect$$rtentry$$00000000) refers (Special) to __rtentry5.o(.ARM.Collect$$rtentry$$00000005) for __rt_entry_sh + aeabi_idiv0_sigfpe.o(.text) refers to rt_div0.o(.text) for __rt_div0 + __printf.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + _printf_str.o(.text) refers (Special) to _printf_char.o(.text) for _printf_cs_common + _printf_str.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_str.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + _printf_dec.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_signed + _printf_dec.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_dec.o(.text) refers to rtudiv10.o(.text) for __rt_udiv10 + _printf_dec.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_char_common.o(.text) refers to __printf_flags_ss_wp.o(.text) for __printf + _printf_wctomb.o(.text) refers (Special) to _printf_wchar.o(.text) for _printf_lcs_common + _printf_wctomb.o(.text) refers to _wcrtomb.o(.text) for _wcrtomb + _printf_wctomb.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_wctomb.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + _printf_wctomb.o(.text) refers to _printf_wctomb.o(.constdata) for .constdata + _printf_wctomb.o(.constdata) refers (Special) to _printf_wchar.o(.text) for _printf_lcs_common + _printf_longlong_dec.o(.text) refers to lludiv10.o(.text) for _ll_udiv10 + _printf_longlong_dec.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_oct_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_oct_int.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_oct_int.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_oct_int_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_oct_int_ll.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_hex_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_ll.o(.text) refers to _printf_hex_ll.o(.constdata) for .constdata + _printf_hex_int.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_hex_int.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_int.o(.text) refers to _printf_hex_int.o(.constdata) for .constdata + _printf_hex_int_ll.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_int_ll.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_hex_int_ll.o(.text) refers to _printf_hex_int_ll.o(.constdata) for .constdata + _printf_hex_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_ptr.o(.text) refers to _printf_hex_ptr.o(.constdata) for .constdata + _printf_hex_int_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_int_ptr.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_hex_int_ptr.o(.text) refers to _printf_hex_int_ptr.o(.constdata) for .constdata + _printf_hex_ll_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_ll_ptr.o(.text) refers to _printf_hex_ll_ptr.o(.constdata) for .constdata + _printf_hex_int_ll_ptr.o(.text) refers to _printf_intcommon.o(.text) for _printf_int_common + _printf_hex_int_ll_ptr.o(.text) refers (Weak) to _printf_truncate.o(.text) for _printf_truncate_unsigned + _printf_hex_int_ll_ptr.o(.text) refers to _printf_hex_int_ll_ptr.o(.constdata) for .constdata + __printf_flags.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags.o(.text) refers to __printf_flags.o(.constdata) for .constdata + __printf_ss.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_ss.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_ss.o(.text) refers to __printf_flags_ss.o(.constdata) for .constdata + __printf_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit + __printf_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit + __printf_flags_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_wp.o(.text) refers to __printf_flags_wp.o(.constdata) for .constdata + __printf_ss_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit + __printf_ss_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_ss_wp.o(.text) refers to __printf_wp.o(i._is_digit) for _is_digit + __printf_flags_ss_wp.o(.text) refers to _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) for _printf_percent + __printf_flags_ss_wp.o(.text) refers to __printf_flags_ss_wp.o(.constdata) for .constdata + _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) refers (Weak) to _printf_char.o(.text) for _printf_char + _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) refers (Weak) to _printf_char.o(.text) for _printf_string + _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) refers (Weak) to _printf_charcount.o(.text) for _printf_charcount + _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_int_hex + _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_hex_ptr + _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) refers (Weak) to _printf_oct_int_ll.o(.text) for _printf_int_oct + _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec + _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec + _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) refers (Weak) to _printf_dec.o(.text) for _printf_int_dec + _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec + _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec + _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) refers (Weak) to printf1.o(x$fpl$printf1) for _printf_fp_dec + _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) refers (Weak) to printf2.o(x$fpl$printf2) for _printf_fp_hex + _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) refers (Special) to _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017) for _printf_percent_end + _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec + _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec + _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) refers (Weak) to _printf_longlong_dec.o(.text) for _printf_longlong_dec + _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l + _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) refers (Weak) to _printf_wchar.o(.text) for _printf_wchar + _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) refers (Special) to _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) for _printf_l + _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) refers (Weak) to _printf_wchar.o(.text) for _printf_wstring + _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) refers (Weak) to _printf_oct_int_ll.o(.text) for _printf_ll_oct + _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) refers (Special) to _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) for _printf_ll + _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) refers (Weak) to _printf_hex_int_ll_ptr.o(.text) for _printf_ll_hex + libinit2.o(.ARM.Collect$$libinit$$0000000D) refers (Weak) to rand.o(.text) for _rand_init + libinit2.o(.ARM.Collect$$libinit$$0000000F) refers (Weak) to rt_locale.o(.text) for __rt_locale + libinit2.o(.ARM.Collect$$libinit$$00000010) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F + libinit2.o(.ARM.Collect$$libinit$$00000012) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F + libinit2.o(.ARM.Collect$$libinit$$00000012) refers (Weak) to lc_ctype_c.o(locale$$code) for _get_lc_ctype + libinit2.o(.ARM.Collect$$libinit$$00000014) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F + libinit2.o(.ARM.Collect$$libinit$$00000016) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F + libinit2.o(.ARM.Collect$$libinit$$00000016) refers (Weak) to lc_numeric_c.o(locale$$code) for _get_lc_numeric + libinit2.o(.ARM.Collect$$libinit$$00000018) refers to libinit2.o(.ARM.Collect$$libinit$$0000000F) for .ARM.Collect$$libinit$$0000000F + libinit2.o(.ARM.Collect$$libinit$$00000026) refers to argv_veneer.o(.text) for __ARM_argv_veneer + libinit2.o(.ARM.Collect$$libinit$$00000027) refers to argv_veneer.o(.text) for __ARM_argv_veneer + printf1.o(x$fpl$printf1) refers to _printf_fp_dec.o(.text) for _printf_fp_dec_real + printf2.o(x$fpl$printf2) refers to _printf_fp_hex.o(.text) for _printf_fp_hex_real + printf2b.o(x$fpl$printf2) refers to _printf_fp_hex.o(.text) for _printf_fp_hex_real + __rtentry2.o(.ARM.Collect$$rtentry$$00000008) refers to boardinit2.o(.text) for _platform_post_stackheap_init + __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) refers to libinit.o(.ARM.Collect$$libinit$$00000000) for __rt_lib_init + __rtentry2.o(.ARM.Collect$$rtentry$$0000000B) refers to boardinit3.o(.text) for _platform_post_lib_init + __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) refers to main.o(.text) for main + __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$00000001) for .ARM.Collect$$rtentry$$00000001 + __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$00000008) for .ARM.Collect$$rtentry$$00000008 + __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) for .ARM.Collect$$rtentry$$0000000A + __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000B) for .ARM.Collect$$rtentry$$0000000B + __rtentry2.o(.ARM.exidx) refers to __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) for .ARM.Collect$$rtentry$$0000000D + __rtentry4.o(.ARM.Collect$$rtentry$$00000004) refers to startup_rtl876x.o(.text) for __user_setup_stackheap + __rtentry4.o(.ARM.exidx) refers to __rtentry4.o(.ARM.Collect$$rtentry$$00000004) for .ARM.Collect$$rtentry$$00000004 + __rtentry5.o(.ARM.Collect$$rtentry$$00000005) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00002716) for __lit__00000000 + __rtentry5.o(__vectab_stack_and_reset_sym_area) refers to __main.o(!!!main) for __main + __rtentry5.o(.ARM.exidx) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00000005) for .ARM.Collect$$rtentry$$00000005 + __rtentry5.o(.ARM.exidx) refers to __rtentry5.o(.ARM.Collect$$rtentry$$00002716) for .ARM.Collect$$rtentry$$00002716 + rt_div0.o(.text) refers to defsig_fpe_outer.o(.text) for __rt_SIGFPE + _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_intcommon.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + _printf_fp_dec.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + _printf_fp_dec.o(.text) refers (Special) to lc_numeric_c.o(locale$$code) for _get_lc_numeric + _printf_fp_dec.o(.text) refers to bigflt0.o(.text) for _btod_etento + _printf_fp_dec.o(.text) refers to btod.o(.text) for _btod_d2e + _printf_fp_dec.o(.text) refers to lludiv10.o(.text) for _ll_udiv10 + _printf_fp_dec.o(.text) refers to fpclassify.o(i.__ARM_fpclassify) for __ARM_fpclassify + _printf_fp_dec.o(.text) refers to _printf_fp_infnan.o(.text) for _printf_fp_infnan + _printf_fp_dec.o(.text) refers to rtudiv10.o(.text) for __rt_udiv10 + _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_fp_dec.o(.text) refers to rt_locale.o(.text) for __rt_locale + _printf_fp_dec.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + _printf_fp_hex.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + _printf_fp_hex.o(.text) refers to fpclassify.o(i.__ARM_fpclassify) for __ARM_fpclassify + _printf_fp_hex.o(.text) refers to _printf_fp_infnan.o(.text) for _printf_fp_infnan + _printf_fp_hex.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_idivmod + _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_fp_hex.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + _printf_fp_hex.o(.text) refers to _printf_fp_hex.o(.constdata) for .constdata + _printf_fp_hex.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + _printf_char.o(.text) refers (Weak) to _printf_str.o(.text) for _printf_str + _printf_wchar.o(.text) refers (Weak) to _printf_wctomb.o(.text) for _printf_wctomb + _wcrtomb.o(.text) refers to rt_ctype_table.o(.text) for __rt_ctype_table + rt_ctype_table.o(.text) refers to rt_locale.o(.text) for __rt_locale + rt_ctype_table.o(.text) refers to lc_ctype_c.o(locale$$code) for _get_lc_ctype + rt_locale.o(.text) refers to rt_locale.o(.bss) for __rt_locale_data + rt_locale_intlibspace.o(.text) refers to libspace.o(.bss) for __libspace_start + _printf_fp_infnan.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_pre_padding + _printf_fp_infnan.o(.text) refers (Weak) to _printf_pad.o(.text) for _printf_post_padding + bigflt0.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + bigflt0.o(.text) refers to aeabi_sdivfast.o(.text) for __aeabi_idivmod + bigflt0.o(.text) refers to btod.o(.text) for _btod_emul + bigflt0.o(.text) refers to bigflt0.o(.constdata) for .constdata + bigflt0.o(.constdata) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + btod.o(.text) refers to btod.o(i.__ARM_common_ll_muluu) for __ARM_common_ll_muluu + lc_numeric_c.o(locale$$data) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000016) for __rt_lib_init_lc_numeric_2 + lc_numeric_c.o(locale$$code) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000016) for __rt_lib_init_lc_numeric_2 + lc_numeric_c.o(locale$$code) refers to strcmpv6m.o(.text) for strcmp + lc_numeric_c.o(locale$$code) refers to lc_numeric_c.o(locale$$data) for __lcnum_c_name + defsig_fpe_outer.o(.text) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner + defsig_fpe_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit + defsig_fpe_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise + _get_argv_nomalloc.o(.text) refers (Special) to hrguard.o(.text) for __heap_region$guard + _get_argv_nomalloc.o(.text) refers to defsig_rtmem_outer.o(.text) for __rt_SIGRTMEM + _get_argv_nomalloc.o(.text) refers to sys_command.o(.text) for _sys_command_string + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002E) for __rt_lib_init_alloca_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000002C) for __rt_lib_init_argv_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001B) for __rt_lib_init_atexit_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000021) for __rt_lib_init_clock_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000032) for __rt_lib_init_cpp_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000030) for __rt_lib_init_exceptions_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000002) for __rt_lib_init_fp_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001F) for __rt_lib_init_fp_trap_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000023) for __rt_lib_init_getenv_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000A) for __rt_lib_init_heap_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000011) for __rt_lib_init_lc_collate_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000013) for __rt_lib_init_lc_ctype_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000015) for __rt_lib_init_lc_monetary_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000017) for __rt_lib_init_lc_numeric_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000019) for __rt_lib_init_lc_time_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000004) for __rt_lib_init_preinit_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000E) for __rt_lib_init_rand_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000033) for __rt_lib_init_return + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000001D) for __rt_lib_init_signal_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000025) for __rt_lib_init_stdio_1 + libinit.o(.ARM.Collect$$libinit$$00000000) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$0000000C) for __rt_lib_init_user_alloc_1 + ieee_status.o(.text) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + fpclassify.o(i.__ARM_fpclassify) refers (Special) to usenofp.o(x$fpl$usenofp) for __I$use$fp + sys_command.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting + sys_command.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function + libspace.o(.text) refers to libspace.o(.bss) for __libspace_start + rt_raise.o(.text) refers to __raise.o(.text) for __raise + rt_raise.o(.text) refers to sys_exit.o(.text) for _sys_exit + lc_ctype_c.o(locale$$data) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000012) for __rt_lib_init_lc_ctype_2 + lc_ctype_c.o(locale$$code) refers (Special) to libinit2.o(.ARM.Collect$$libinit$$00000012) for __rt_lib_init_lc_ctype_2 + lc_ctype_c.o(locale$$code) refers to strcmpv6m.o(.text) for strcmp + lc_ctype_c.o(locale$$code) refers to lc_ctype_c.o(locale$$data) for __lcctype_c_name + defsig_exit.o(.text) refers to sys_exit.o(.text) for _sys_exit + defsig_fpe_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_rtmem_outer.o(.text) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner + defsig_rtmem_outer.o(.text) refers to defsig_exit.o(.text) for __sig_exit + defsig_rtmem_formal.o(.text) refers to rt_raise.o(.text) for __rt_raise + sys_exit.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting + sys_exit.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function + __raise.o(.text) refers to defsig.o(CL$$defsig) for __default_signal_handler + defsig_general.o(.text) refers to sys_wrch.o(.text) for _ttywrch + defsig_rtmem_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + sys_wrch.o(.text) refers (Special) to use_no_semi.o(.text) for __I$use$semihosting + sys_wrch.o(.text) refers (Special) to indicate_semi.o(.text) for __semihosting_library_function + defsig.o(CL$$defsig) refers to defsig_fpe_inner.o(.text) for __rt_SIGFPE_inner + defsig.o(CL$$defsig) refers to defsig_rtmem_inner.o(.text) for __rt_SIGRTMEM_inner + defsig_abrt_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_rtred_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_stak_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_pvfn_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_cppl_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_segv_inner.o(.text) refers to defsig_general.o(.text) for __default_signal_display + defsig_other.o(.text) refers to defsig_general.o(.text) for __default_signal_display + platform_util.o(i.mbedtls_get_unaligned_uint64) refers to overlay_mgr.o(i.__ARM_common_memcpy1_8) for __ARM_common_memcpy1_8 + platform_util.o(i.mbedtls_put_unaligned_uint64) refers to overlay_mgr.o(i.__ARM_common_memcpy1_8) for __ARM_common_memcpy1_8 + + +============================================================================== + +Removing Unused input sections from the image. + + Removing system_rtl876x.o(.rev16_text), (4 bytes). + Removing system_rtl876x.o(.revsh_text), (4 bytes). + Removing rtl876x_io_dlps.o(.rev16_text), (4 bytes). + Removing rtl876x_io_dlps.o(.revsh_text), (4 bytes). + Removing rtl876x_gpio.o(.rev16_text), (4 bytes). + Removing rtl876x_gpio.o(.revsh_text), (4 bytes). + Removing rtl876x_rcc.o(.rev16_text), (4 bytes). + Removing rtl876x_rcc.o(.revsh_text), (4 bytes). + Removing rtl876x_tim.o(.rev16_text), (4 bytes). + Removing rtl876x_tim.o(.revsh_text), (4 bytes). + Removing rtl876x_pinmux.o(.rev16_text), (4 bytes). + Removing rtl876x_pinmux.o(.revsh_text), (4 bytes). + Removing rtl876x_nvic.o(.rev16_text), (4 bytes). + Removing rtl876x_nvic.o(.revsh_text), (4 bytes). + Removing rtl876x_adc.o(.rev16_text), (4 bytes). + Removing rtl876x_adc.o(.revsh_text), (4 bytes). + Removing rtl876x_i2c.o(.rev16_text), (4 bytes). + Removing rtl876x_i2c.o(.revsh_text), (4 bytes). + Removing rtl876x_aon_wdg.o(.rev16_text), (4 bytes). + Removing rtl876x_aon_wdg.o(.revsh_text), (4 bytes). + Removing findmy_network_service.o(.rev16_text), (4 bytes). + Removing findmy_network_service.o(.revsh_text), (4 bytes). + Removing accessory_info_service.o(.rev16_text), (4 bytes). + Removing accessory_info_service.o(.revsh_text), (4 bytes). + Removing firmware_update_service.o(.rev16_text), (4 bytes). + Removing firmware_update_service.o(.revsh_text), (4 bytes). + Removing firmware_update_service.o(.text), (292 bytes). + Removing firmware_update_service.o(.bss), (8 bytes). + Removing firmware_update_service.o(.constdata), (124 bytes). + Removing tps.o(.rev16_text), (4 bytes). + Removing tps.o(.revsh_text), (4 bytes). + Removing hids_kb.o(.text), (616 bytes). + Removing hids_kb.o(.bss), (8 bytes). + Removing hids_kb.o(.constdata), (972 bytes). + Removing hids_kb.o(.data), (6 bytes). + Removing ias.o(.constdata), (4 bytes). + Removing dis.o(.constdata), (2 bytes). + Removing main.o(.rev16_text), (4 bytes). + Removing main.o(.revsh_text), (4 bytes). + Removing app_task.o(.rev16_text), (4 bytes). + Removing app_task.o(.revsh_text), (4 bytes). + Removing findmy_app.o(.rev16_text), (4 bytes). + Removing findmy_app.o(.revsh_text), (4 bytes). + Removing custom_app.o(.rev16_text), (4 bytes). + Removing custom_app.o(.revsh_text), (4 bytes). + Removing dfu_flash.o(.rev16_text), (4 bytes). + Removing dfu_flash.o(.revsh_text), (4 bytes). + Removing dfu_flash.o(.text), (1672 bytes). + Removing dfu_flash.o(.data), (1 bytes). + Removing reset_watch_dog_timer.o(.rev16_text), (4 bytes). + Removing reset_watch_dog_timer.o(.revsh_text), (4 bytes). + Removing reset_watch_dog_timer.o(.text), (96 bytes). + Removing serial_number_send.o(.rev16_text), (4 bytes). + Removing serial_number_send.o(.revsh_text), (4 bytes). + Removing da213b.o(.rev16_text), (4 bytes). + Removing da213b.o(.revsh_text), (4 bytes). + Removing key_handle.o(.rev16_text), (4 bytes). + Removing key_handle.o(.revsh_text), (4 bytes). + Removing fmna_adv.o(.rev16_text), (4 bytes). + Removing fmna_adv.o(.revsh_text), (4 bytes). + Removing fmna_config_control_point.o(.rev16_text), (4 bytes). + Removing fmna_config_control_point.o(.revsh_text), (4 bytes). + Removing fmna_connection.o(.rev16_text), (4 bytes). + Removing fmna_connection.o(.revsh_text), (4 bytes). + Removing fmna_crypto.o(.rev16_text), (4 bytes). + Removing fmna_crypto.o(.revsh_text), (4 bytes). + Removing fmna_crypto.o(.bss), (1245 bytes). + Removing fmna_debug_control_point.o(.rev16_text), (4 bytes). + Removing fmna_debug_control_point.o(.revsh_text), (4 bytes). + Removing fmna_gatt.o(.rev16_text), (4 bytes). + Removing fmna_gatt.o(.revsh_text), (4 bytes). + Removing fmna_motion_detection.o(.rev16_text), (4 bytes). + Removing fmna_motion_detection.o(.revsh_text), (4 bytes). + Removing fmna_nfc.o(.rev16_text), (4 bytes). + Removing fmna_nfc.o(.revsh_text), (4 bytes). + Removing fmna_nonowner_control_point.o(.rev16_text), (4 bytes). + Removing fmna_nonowner_control_point.o(.revsh_text), (4 bytes). + Removing fmna_paired_owner_control_point.o(.rev16_text), (4 bytes). + Removing fmna_paired_owner_control_point.o(.revsh_text), (4 bytes). + Removing fmna_pairing_control_point.o(.rev16_text), (4 bytes). + Removing fmna_pairing_control_point.o(.revsh_text), (4 bytes). + Removing fmna_state_machine.o(.rev16_text), (4 bytes). + Removing fmna_state_machine.o(.revsh_text), (4 bytes). + Removing fmna_uarp_control_point.o(.rev16_text), (4 bytes). + Removing fmna_uarp_control_point.o(.revsh_text), (4 bytes). + Removing fmna_uarp_control_point.o(.text), (860 bytes). + Removing fmna_uarp_control_point.o(.bss), (1393 bytes). + Removing fmna_uarp_control_point.o(.constdata), (77 bytes). + Removing fmna_uarp_control_point.o(.data), (2 bytes). + Removing fmna_version.o(.rev16_text), (4 bytes). + Removing fmna_version.o(.revsh_text), (4 bytes). + Removing fmnasampleuarp.o(.rev16_text), (4 bytes). + Removing fmnasampleuarp.o(.revsh_text), (4 bytes). + Removing fmnasampleuarp.o(.text), (4280 bytes). + Removing fmnasampleuarp.o(.bss), (4 bytes). + Removing fmnasampleuarp.o(.constdata), (4 bytes). + Removing fmnasampleuarp.o(.conststring), (53 bytes). + Removing fmnasampleuarp.o(.data), (4 bytes). + Removing fmna_adv_platform.o(.rev16_text), (4 bytes). + Removing fmna_adv_platform.o(.revsh_text), (4 bytes). + Removing fmna_battery_platform.o(.rev16_text), (4 bytes). + Removing fmna_battery_platform.o(.revsh_text), (4 bytes). + Removing fmna_connection_platform.o(.rev16_text), (4 bytes). + Removing fmna_connection_platform.o(.revsh_text), (4 bytes). + Removing fmna_dfu_platform.o(.rev16_text), (4 bytes). + Removing fmna_dfu_platform.o(.revsh_text), (4 bytes). + Removing fmna_dfu_platform.o(.text), (1076 bytes). + Removing fmna_dfu_platform.o(.bss), (164 bytes). + Removing fmna_dfu_platform.o(.constdata), (14 bytes). + Removing fmna_gap_platform.o(.rev16_text), (4 bytes). + Removing fmna_gap_platform.o(.revsh_text), (4 bytes). + Removing fmna_gatt_platform.o(.rev16_text), (4 bytes). + Removing fmna_gatt_platform.o(.revsh_text), (4 bytes). + Removing fmna_gatt_platform.o(.bss), (1 bytes). + Removing fmna_motion_detection_platform.o(.rev16_text), (4 bytes). + Removing fmna_motion_detection_platform.o(.revsh_text), (4 bytes). + Removing fmna_peer_manager.o(.rev16_text), (4 bytes). + Removing fmna_peer_manager.o(.revsh_text), (4 bytes). + Removing fmna_sound_platform.o(.rev16_text), (4 bytes). + Removing fmna_sound_platform.o(.revsh_text), (4 bytes). + Removing fmna_timer_platform.o(.rev16_text), (4 bytes). + Removing fmna_timer_platform.o(.revsh_text), (4 bytes). + Removing coreuarputils.o(.rev16_text), (4 bytes). + Removing coreuarputils.o(.revsh_text), (4 bytes). + Removing coreuarputils.o(.text), (554 bytes). + Removing coreuarpaccessory.o(.rev16_text), (4 bytes). + Removing coreuarpaccessory.o(.revsh_text), (4 bytes). + Removing coreuarpaccessory.o(.text), (4296 bytes). + Removing coreuarpaccessory.o(.bss), (2 bytes). + Removing coreuarpaccessory.o(.constdata), (4 bytes). + Removing coreuarpaccessory.o(.conststring), (54 bytes). + Removing coreuarpplatformaccessory.o(.rev16_text), (4 bytes). + Removing coreuarpplatformaccessory.o(.revsh_text), (4 bytes). + Removing coreuarpplatformaccessory.o(.text), (7628 bytes). + Removing coreuarpplatformaccessory.o(.bss), (2 bytes). + Removing coreuarpplatformaccessory.o(.constdata), (4 bytes). + Removing coreuarpplatformaccessory.o(.conststring), (62 bytes). + Removing coreuarpplatformrtk.o(.rev16_text), (4 bytes). + Removing coreuarpplatformrtk.o(.revsh_text), (4 bytes). + Removing coreuarpplatformrtk.o(.text), (100 bytes). + Removing coreuarpplatformrtk.o(.constdata), (11 bytes). + Removing platform.o(.text), (6 bytes). + Removing gap_config.o(.text), (136 bytes). + Removing key_crypto.o(.rev16_text), (4 bytes). + Removing key_crypto.o(.revsh_text), (4 bytes). + Removing platform_util.o(i.mbedtls_get_unaligned_uint16), (26 bytes). + Removing platform_util.o(i.mbedtls_put_unaligned_uint16), (10 bytes). + Removing platform_util.o(i.mbedtls_get_unaligned_uint32), (46 bytes). + Removing platform_util.o(i.mbedtls_put_unaligned_uint32), (20 bytes). + Removing platform_util.o(i.mbedtls_get_unaligned_uint64), (20 bytes). + Removing platform_util.o(i.mbedtls_put_unaligned_uint64), (12 bytes). + Removing platform_util.o(i.mbedtls_xor), (26 bytes). + +152 unused section(s) (total 26421 bytes) removed from the image. + +============================================================================== + +Image Symbol Table + + Local Symbols + + Symbol Name Value Ov Type Size Object(Section) + + ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit1.o ABSOLUTE + ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit2.o ABSOLUTE + ../clib/angel/boardlib.s 0x00000000 Number 0 boardinit3.o ABSOLUTE + ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry5.o ABSOLUTE + ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry4.o ABSOLUTE + ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry2.o ABSOLUTE + ../clib/angel/kernel.s 0x00000000 Number 0 __rtentry.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 aeabi_idiv0.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_locale_intlibspace.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 aeabi_idiv0_sigfpe.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_raise.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_locale.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_ctype_table.o ABSOLUTE + ../clib/angel/rt.s 0x00000000 Number 0 rt_div0.o ABSOLUTE + ../clib/angel/startup.s 0x00000000 Number 0 __main.o ABSOLUTE + ../clib/angel/sys.s 0x00000000 Number 0 libspace.o ABSOLUTE + ../clib/angel/sys.s 0x00000000 Number 0 use_no_semi.o ABSOLUTE + ../clib/angel/sys.s 0x00000000 Number 0 indicate_semi.o ABSOLUTE + ../clib/angel/sysapp.c 0x00000000 Number 0 sys_wrch.o ABSOLUTE + ../clib/angel/sysapp.c 0x00000000 Number 0 sys_command.o ABSOLUTE + ../clib/angel/sysapp.c 0x00000000 Number 0 sys_exit.o ABSOLUTE + ../clib/armsys.c 0x00000000 Number 0 argv_veneer.o ABSOLUTE + ../clib/armsys.c 0x00000000 Number 0 _get_argv_nomalloc.o ABSOLUTE + ../clib/armsys.c 0x00000000 Number 0 no_argv.o ABSOLUTE + ../clib/bigflt.c 0x00000000 Number 0 bigflt0.o ABSOLUTE + ../clib/btod.c 0x00000000 Number 0 btod.o ABSOLUTE + ../clib/division.c 0x00000000 Number 0 lludiv10.o ABSOLUTE + ../clib/division.c 0x00000000 Number 0 rtudiv10.o ABSOLUTE + ../clib/division.s 0x00000000 Number 0 aeabi_sdivfast.o ABSOLUTE + ../clib/division.s 0x00000000 Number 0 aeabi_sdivfast_div0.o ABSOLUTE + ../clib/heapalloc.c 0x00000000 Number 0 hrguard.o ABSOLUTE + ../clib/libinit.s 0x00000000 Number 0 libinit2.o ABSOLUTE + ../clib/libinit.s 0x00000000 Number 0 libinit.o ABSOLUTE + ../clib/locale.c 0x00000000 Number 0 _wcrtomb.o ABSOLUTE + ../clib/locale.s 0x00000000 Number 0 lc_ctype_c.o ABSOLUTE + ../clib/locale.s 0x00000000 Number 0 lc_numeric_c.o ABSOLUTE + ../clib/memcpset.c 0x00000000 Number 0 rt_memmove.o ABSOLUTE + ../clib/memcpset.c 0x00000000 Number 0 memset.o ABSOLUTE + ../clib/memcpset.s 0x00000000 Number 0 strcmpv6m.o ABSOLUTE + ../clib/misc.s 0x00000000 Number 0 printf_stubs.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll_ptr.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_fp_hex.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_nopercent.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_char.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_wchar.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_charcount.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_char_common.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_intcommon.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ptr.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _sputc.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _snputc.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_fp_dec.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_int_ptr.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll_ptr.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_flags.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_ss.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_hex_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_flags_wp.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_wp.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_ss_wp.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf_flags_ss_wp.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 vsnprintf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_str.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_wctomb.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_longlong_dec.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_oct_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_oct_int.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_oct_int_ll.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_fp_infnan.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 __printf.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_pad.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_truncate.o ABSOLUTE + ../clib/printf.c 0x00000000 Number 0 _printf_dec.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent_end.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_l.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_ll.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_llu.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_lld.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_lli.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_percent.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_a.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_g.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_u.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_p.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_e.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_llo.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_s.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_lc.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_o.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_llx.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_f.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_c.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_i.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_d.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_n.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_x.o ABSOLUTE + ../clib/printf_percent.s 0x00000000 Number 0 _printf_ls.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 __raise.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_general.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_outer.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_exit.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtmem_formal.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_outer.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_fpe_formal.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_cppl_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_pvfn_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_stak_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_rtred_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_other.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_abrt_inner.o ABSOLUTE + ../clib/signal.c 0x00000000 Number 0 defsig_segv_inner.o ABSOLUTE + ../clib/signal.s 0x00000000 Number 0 defsig.o ABSOLUTE + ../clib/stdlib.c 0x00000000 Number 0 rand.o ABSOLUTE + ../clib/stdlib.c 0x00000000 Number 0 rand.o ABSOLUTE + ../fplib/cfplib/d2f.c 0x00000000 Number 0 d2f.o ABSOLUTE + ../fplib/cfplib/daddsub.c 0x00000000 Number 0 daddsub.o ABSOLUTE + ../fplib/cfplib/dmul.c 0x00000000 Number 0 dmul.o ABSOLUTE + ../fplib/cfplib/fdiv.c 0x00000000 Number 0 fdiv.o ABSOLUTE + ../fplib/cfplib/ffix.c 0x00000000 Number 0 ffixui.o ABSOLUTE + ../fplib/cfplib/ffix.c 0x00000000 Number 0 dfixui.o ABSOLUTE + ../fplib/cfplib/fflt.c 0x00000000 Number 0 fflti.o ABSOLUTE + ../fplib/cfplib/fflt.c 0x00000000 Number 0 dflti.o ABSOLUTE + ../fplib/cfplib/fpinit.c 0x00000000 Number 0 fpinit.o ABSOLUTE + ../fplib/cfplib/ieee_status.c 0x00000000 Number 0 ieee_status.o ABSOLUTE + ../fplib/faddsub6m.s 0x00000000 Number 0 faddsub.o ABSOLUTE + ../fplib/fmul6m.s 0x00000000 Number 0 fmul.o ABSOLUTE + ../fplib/printf1.s 0x00000000 Number 0 printf1.o ABSOLUTE + ../fplib/printf2.s 0x00000000 Number 0 printf2.o ABSOLUTE + ../fplib/printf2a.s 0x00000000 Number 0 printf2a.o ABSOLUTE + ../fplib/printf2b.s 0x00000000 Number 0 printf2b.o ABSOLUTE + ../fplib/usenofp.s 0x00000000 Number 0 usenofp.o ABSOLUTE + ../mathlib/fpclassify.c 0x00000000 Number 0 fpclassify.o ABSOLUTE + ..\..\..\..\src\app\adc_lib\adc_lib.c 0x00000000 Number 0 adc_lib.o ABSOLUTE + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c 0x00000000 Number 0 coreuarpaccessory.o ABSOLUTE + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c 0x00000000 Number 0 coreuarpplatformaccessory.o ABSOLUTE + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c 0x00000000 Number 0 coreuarpplatformrtk.o ABSOLUTE + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c 0x00000000 Number 0 coreuarputils.o ABSOLUTE + ..\..\..\..\src\app\findmy\app_task.c 0x00000000 Number 0 app_task.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\fm-crypto.c 0x00000000 Number 0 fm-crypto.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c 0x00000000 Number 0 aes.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c 0x00000000 Number 0 asn1parse.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c 0x00000000 Number 0 asn1write.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c 0x00000000 Number 0 base64.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c 0x00000000 Number 0 bignum.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c 0x00000000 Number 0 bignum_core.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c 0x00000000 Number 0 cipher.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c 0x00000000 Number 0 cipher_wrap.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c 0x00000000 Number 0 constant_time.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c 0x00000000 Number 0 ecdh.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c 0x00000000 Number 0 ecdsa.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c 0x00000000 Number 0 ecp.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c 0x00000000 Number 0 ecp_curves.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c 0x00000000 Number 0 gcm.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c 0x00000000 Number 0 kdf963.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c 0x00000000 Number 0 md.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c 0x00000000 Number 0 platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c 0x00000000 Number 0 platform_util.o ABSOLUTE + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c 0x00000000 Number 0 sha256.o ABSOLUTE + ..\..\..\..\src\app\findmy\custom_app.c 0x00000000 Number 0 custom_app.o ABSOLUTE + ..\..\..\..\src\app\findmy\findmy_app.c 0x00000000 Number 0 findmy_app.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c 0x00000000 Number 0 fmnasampleuarp.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c 0x00000000 Number 0 fmna_adv.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c 0x00000000 Number 0 fmna_config_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c 0x00000000 Number 0 fmna_connection.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c 0x00000000 Number 0 fmna_crypto.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c 0x00000000 Number 0 fmna_debug_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c 0x00000000 Number 0 fmna_gatt.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c 0x00000000 Number 0 fmna_motion_detection.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c 0x00000000 Number 0 fmna_nfc.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c 0x00000000 Number 0 fmna_nonowner_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c 0x00000000 Number 0 fmna_paired_owner_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c 0x00000000 Number 0 fmna_pairing_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c 0x00000000 Number 0 fmna_state_machine.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c 0x00000000 Number 0 fmna_uarp_control_point.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c 0x00000000 Number 0 fmna_version.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c 0x00000000 Number 0 da213b.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c 0x00000000 Number 0 key_handle.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c 0x00000000 Number 0 fmna_adv_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c 0x00000000 Number 0 fmna_battery_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c 0x00000000 Number 0 fmna_connection_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c 0x00000000 Number 0 fmna_dfu_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c 0x00000000 Number 0 fmna_gap_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c 0x00000000 Number 0 fmna_gatt_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c 0x00000000 Number 0 fmna_malloc_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c 0x00000000 Number 0 fmna_motion_detection_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c 0x00000000 Number 0 fmna_peer_manager.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c 0x00000000 Number 0 fmna_sound_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c 0x00000000 Number 0 fmna_timer_platform.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c 0x00000000 Number 0 accessory_info_service.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c 0x00000000 Number 0 findmy_network_service.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c 0x00000000 Number 0 firmware_update_service.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c 0x00000000 Number 0 hids_kb.o ABSOLUTE + ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c 0x00000000 Number 0 sdd_service.o ABSOLUTE + ..\..\..\..\src\app\findmy\main.c 0x00000000 Number 0 main.o ABSOLUTE + ..\..\..\..\src\app\findmy\reset_watch_dog_timer.c 0x00000000 Number 0 reset_watch_dog_timer.o ABSOLUTE + ..\..\..\..\src\app\findmy\serial_number_send.c 0x00000000 Number 0 serial_number_send.o ABSOLUTE + ..\..\..\..\src\app\findmy_lib\key_crypto.c 0x00000000 Number 0 key_crypto.o ABSOLUTE + ..\..\..\..\src\app\gap_lib\extension\gap_config.c 0x00000000 Number 0 gap_config.o ABSOLUTE + ..\..\..\..\src\app\gap_lib\extension\gap_vendor_cmd.c 0x00000000 Number 0 gap_vendor_cmd.o ABSOLUTE + ..\..\..\..\src\app\gap_lib\gap_lib\gap_lib.c 0x00000000 Number 0 gap_lib.o ABSOLUTE + ..\..\..\..\src\app\gap_lib\systemcall\gap_lib_system_call.c 0x00000000 Number 0 gap_lib_system_call.o ABSOLUTE + ..\..\..\..\src\ble\profile\server\dis.c 0x00000000 Number 0 dis.o ABSOLUTE + ..\..\..\..\src\ble\profile\server\ias.c 0x00000000 Number 0 ias.o ABSOLUTE + ..\..\..\..\src\ble\profile\server\tps.c 0x00000000 Number 0 tps.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c 0x00000000 Number 0 rtl876x_adc.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c 0x00000000 Number 0 rtl876x_aon_wdg.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c 0x00000000 Number 0 rtl876x_gpio.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c 0x00000000 Number 0 rtl876x_i2c.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c 0x00000000 Number 0 rtl876x_io_dlps.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c 0x00000000 Number 0 rtl876x_nvic.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c 0x00000000 Number 0 rtl876x_pinmux.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c 0x00000000 Number 0 rtl876x_rcc.o ABSOLUTE + ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c 0x00000000 Number 0 rtl876x_tim.o ABSOLUTE + ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c 0x00000000 Number 0 overlay_mgr.o ABSOLUTE + ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c 0x00000000 Number 0 system_rtl876x.o ABSOLUTE + ..\..\..\..\src\platform\dfu_flash.c 0x00000000 Number 0 dfu_flash.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\UARPDK\\CoreUARPAccessory.c 0x00000000 Number 0 coreuarpaccessory.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\UARPDK\\CoreUARPPlatformAccessory.c 0x00000000 Number 0 coreuarpplatformaccessory.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\UARPDK\\CoreUARPPlatformRTK.c 0x00000000 Number 0 coreuarpplatformrtk.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\UARPDK\\CoreUARPUtils.c 0x00000000 Number 0 coreuarputils.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\app_task.c 0x00000000 Number 0 app_task.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\custom_app.c 0x00000000 Number 0 custom_app.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\findmy_app.c 0x00000000 Number 0 findmy_app.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\FMNASampleUARP.c 0x00000000 Number 0 fmnasampleuarp.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_adv.c 0x00000000 Number 0 fmna_adv.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_config_control_point.c 0x00000000 Number 0 fmna_config_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_connection.c 0x00000000 Number 0 fmna_connection.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_crypto.c 0x00000000 Number 0 fmna_crypto.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_debug_control_point.c 0x00000000 Number 0 fmna_debug_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_gatt.c 0x00000000 Number 0 fmna_gatt.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_motion_detection.c 0x00000000 Number 0 fmna_motion_detection.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_nfc.c 0x00000000 Number 0 fmna_nfc.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_nonowner_control_point.c 0x00000000 Number 0 fmna_nonowner_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_paired_owner_control_point.c 0x00000000 Number 0 fmna_paired_owner_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_pairing_control_point.c 0x00000000 Number 0 fmna_pairing_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_state_machine.c 0x00000000 Number 0 fmna_state_machine.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_uarp_control_point.c 0x00000000 Number 0 fmna_uarp_control_point.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_adk\\fmna_version.c 0x00000000 Number 0 fmna_version.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_peripheral\\da213b.c 0x00000000 Number 0 da213b.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_peripheral\\key_handle.c 0x00000000 Number 0 key_handle.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_adv_platform.c 0x00000000 Number 0 fmna_adv_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_battery_platform.c 0x00000000 Number 0 fmna_battery_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_connection_platform.c 0x00000000 Number 0 fmna_connection_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_dfu_platform.c 0x00000000 Number 0 fmna_dfu_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_gap_platform.c 0x00000000 Number 0 fmna_gap_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_gatt_platform.c 0x00000000 Number 0 fmna_gatt_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_motion_detection_platform.c 0x00000000 Number 0 fmna_motion_detection_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_peer_manager.c 0x00000000 Number 0 fmna_peer_manager.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_sound_platform.c 0x00000000 Number 0 fmna_sound_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_platform\\fmna_timer_platform.c 0x00000000 Number 0 fmna_timer_platform.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_profile\\accessory_info_service.c 0x00000000 Number 0 accessory_info_service.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_profile\\findmy_network_service.c 0x00000000 Number 0 findmy_network_service.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\fmna_profile\\firmware_update_service.c 0x00000000 Number 0 firmware_update_service.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\main.c 0x00000000 Number 0 main.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\reset_watch_dog_timer.c 0x00000000 Number 0 reset_watch_dog_timer.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy\\serial_number_send.c 0x00000000 Number 0 serial_number_send.o ABSOLUTE + ..\\..\\..\\..\\src\\app\\findmy_lib\\key_crypto.c 0x00000000 Number 0 key_crypto.o ABSOLUTE + ..\\..\\..\\..\\src\\ble\\profile\\server\\tps.c 0x00000000 Number 0 tps.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_adc.c 0x00000000 Number 0 rtl876x_adc.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_aon_wdg.c 0x00000000 Number 0 rtl876x_aon_wdg.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_gpio.c 0x00000000 Number 0 rtl876x_gpio.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_i2c.c 0x00000000 Number 0 rtl876x_i2c.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_io_dlps.c 0x00000000 Number 0 rtl876x_io_dlps.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_nvic.c 0x00000000 Number 0 rtl876x_nvic.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_pinmux.c 0x00000000 Number 0 rtl876x_pinmux.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_rcc.c 0x00000000 Number 0 rtl876x_rcc.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\peripheral\\rtl876x_tim.c 0x00000000 Number 0 rtl876x_tim.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x.s 0x00000000 Number 0 startup_rtl876x.o ABSOLUTE + ..\\..\\..\\..\\src\\mcu\\rtl876x\\system_rtl876x.c 0x00000000 Number 0 system_rtl876x.o ABSOLUTE + ..\\..\\..\\..\\src\\platform\\dfu_flash.c 0x00000000 Number 0 dfu_flash.o ABSOLUTE + VECTOR 0x00200000 Section 232 startup_rtl876x.o(VECTOR) + .app.data_ram.text 0x00207c00 Section 0 system_rtl876x.o(.app.data_ram.text) + .app.data_ram.text 0x00207d14 Section 0 rtl876x_io_dlps.o(.app.data_ram.text) + .app.data_ram.text 0x00208334 Section 0 reset_watch_dog_timer.o(.app.data_ram.text) + .app.data_ram.text 0x0020837c Section 0 fmna_timer_platform.o(.app.data_ram.text) + aon_watch_dog_wake_up_dlps_callback 0x0020837d * Thumb Code 40 fmna_timer_platform.o(.app.data_ram.text) + .app.data_ram.text 0x002083ac Section 0 bignum.o(.app.data_ram.text) + .data 0x00208b00 Section 4 rtl876x_i2c.o(.data) + .data 0x00208b04 Section 20 tps.o(.data) + system_id_value 0x00208b04 Data 1 tps.o(.data) + firmware_version_str 0x00208b05 Data 3 tps.o(.data) + serial_number_value 0x00208b08 Data 16 tps.o(.data) + .data 0x00208b18 Section 1 sdd_service.o(.data) + .data 0x00208b19 Section 173 dis.o(.data) + dis_system_id_len 0x00208b19 Data 1 dis.o(.data) + dis_manufacturer_name_len 0x00208b1a Data 1 dis.o(.data) + dis_model_number_len 0x00208b1b Data 1 dis.o(.data) + dis_serial_number_len 0x00208b1c Data 1 dis.o(.data) + dis_hardware_rev_len 0x00208b1d Data 1 dis.o(.data) + dis_firmware_rev_len 0x00208b1e Data 1 dis.o(.data) + dis_software_rev_len 0x00208b1f Data 1 dis.o(.data) + dis_ieee_data_list_len 0x00208b20 Data 1 dis.o(.data) + dis_pnp_id 0x00208b21 Data 7 dis.o(.data) + dis_system_id 0x00208b28 Data 8 dis.o(.data) + dis_manufacturer_name 0x00208b30 Data 20 dis.o(.data) + dis_model_number 0x00208b44 Data 20 dis.o(.data) + dis_serial_number 0x00208b58 Data 20 dis.o(.data) + dis_hardware_rev 0x00208b6c Data 20 dis.o(.data) + dis_firmware_rev 0x00208b80 Data 20 dis.o(.data) + dis_software_rev 0x00208b94 Data 20 dis.o(.data) + dis_ieee_data_list 0x00208ba8 Data 30 dis.o(.data) + .data 0x00208bc6 Section 1 findmy_app.o(.data) + .data 0x00208bc7 Section 63 custom_app.o(.data) + cust_adv_data 0x00208bc8 Data 31 custom_app.o(.data) + cust_scan_rsp_data 0x00208be7 Data 31 custom_app.o(.data) + .data 0x00208c08 Section 108 overlay_mgr.o(.data) + overlay_sections 0x00208c08 Data 108 overlay_mgr.o(.data) + .data 0x00208c74 Section 62 serial_number_send.o(.data) + custom_new_adv_data 0x00208c74 Data 31 serial_number_send.o(.data) + custom_new_scan_rsp_data 0x00208c93 Data 31 serial_number_send.o(.data) + .data 0x00208cb2 Section 40 fmna_config_control_point.o(.data) + rx_length_check_managers 0x00208cb2 Data 40 fmna_config_control_point.o(.data) + .data 0x00208cda Section 1 fmna_connection.o(.data) + m_max_connections 0x00208cda Data 1 fmna_connection.o(.data) + .data 0x00208cdc Section 16 fmna_debug_control_point.o(.data) + rx_length_check_managers 0x00208cdc Data 16 fmna_debug_control_point.o(.data) + .data 0x00208cec Section 2 fmna_gatt.o(.data) + .data 0x00208cf0 Section 8 fmna_motion_detection.o(.data) + m_motion_check_poll_rate_ms 0x00208cf0 Data 2 fmna_motion_detection.o(.data) + m_motion_backoff_timeout_ms 0x00208cf4 Data 4 fmna_motion_detection.o(.data) + .data 0x00208cf8 Section 12 fmna_nonowner_control_point.o(.data) + rx_length_check_managers 0x00208cf8 Data 12 fmna_nonowner_control_point.o(.data) + .data 0x00208d04 Section 12 fmna_paired_owner_control_point.o(.data) + rx_length_check_managers 0x00208d04 Data 12 fmna_paired_owner_control_point.o(.data) + .data 0x00208d10 Section 12 fmna_pairing_control_point.o(.data) + rx_length_check_managers 0x00208d10 Data 12 fmna_pairing_control_point.o(.data) + .data 0x00208d1c Section 136 fmna_state_machine.o(.data) + nearby_disconnecting_conn_handle 0x00208d1c Data 2 fmna_state_machine.o(.data) + m_fmna_nearby_separated_timeout 0x00208d20 Data 4 fmna_state_machine.o(.data) + m_separated_ut_timeout_ms 0x00208d28 Data 4 fmna_state_machine.o(.data) + .data 0x00208da4 Section 91 fmna_adv_platform.o(.data) + pairing_adv_data 0x00208da4 Data 29 fmna_adv_platform.o(.data) + nearby_adv_data 0x00208dc1 Data 31 fmna_adv_platform.o(.data) + separate_adv_data 0x00208de0 Data 31 fmna_adv_platform.o(.data) + .data 0x00208dff Section 2 fmna_gatt_platform.o(.data) + recent_conn_handle 0x00208dff Data 1 fmna_gatt_platform.o(.data) + ind_complete_flag 0x00208e00 Data 1 fmna_gatt_platform.o(.data) + .data 0x00208e04 Section 8 cipher_wrap.o(.data) + .data 0x00208e0c Section 4 ecp_curves.o(.data) + mpi_one 0x00208e0c Data 4 ecp_curves.o(.data) + .data 0x00208e10 Section 4 platform_util.o(.data) + memset_func 0x00208e10 Data 4 platform_util.o(.data) + .data 0x00208e14 Section 50 adc_lib.o(.data) + .data 0x00208e46 Section 1 key_crypto.o(.data) + .bss 0x00208e48 Section 20 system_rtl876x.o(.bss) + .bss 0x00208e5c Section 392 rtl876x_io_dlps.o(.bss) + .bss 0x00208fe4 Section 1 rtl876x_aon_wdg.o(.bss) + is_called 0x00208fe4 Data 1 rtl876x_aon_wdg.o(.bss) + .bss 0x00208fe8 Section 8 findmy_network_service.o(.bss) + pfn_fns_data_cb 0x00208fec Data 4 findmy_network_service.o(.bss) + .bss 0x00208ff0 Section 12 accessory_info_service.o(.bss) + .bss 0x00208ffc Section 8 tps.o(.bss) + tx_power_value 0x00208ffc Data 1 tps.o(.bss) + pfn_tps_cb 0x00209000 Data 4 tps.o(.bss) + .bss 0x00209004 Section 4 ias.o(.bss) + pfn_ias_cb 0x00209004 Data 4 ias.o(.bss) + .bss 0x00209008 Section 8 sdd_service.o(.bss) + sdd_read_level_pending 0x00209008 Data 1 sdd_service.o(.bss) + pfn_sdd_cb 0x0020900c Data 4 sdd_service.o(.bss) + .bss 0x00209010 Section 4 dis.o(.bss) + pfn_dis_cb 0x00209010 Data 4 dis.o(.bss) + .bss 0x00209014 Section 16 app_task.o(.bss) + .bss 0x00209024 Section 57 findmy_app.o(.bss) + press_down 0x00209028 Data 4 findmy_app.o(.bss) + last_press_time 0x0020902c Data 4 findmy_app.o(.bss) + time_diff 0x00209030 Data 4 findmy_app.o(.bss) + m_serial_number 0x0020904d Data 16 findmy_app.o(.bss) + .bss 0x00209060 Section 56 custom_app.o(.bss) + .bss 0x00209098 Section 8 overlay_mgr.o(.bss) + .bss 0x002090a0 Section 48 serial_number_send.o(.bss) + serial_number_loaded 0x002090a0 Data 1 serial_number_send.o(.bss) + device_serial_number 0x002090a1 Data 16 serial_number_send.o(.bss) + .bss 0x002090d0 Section 28 key_handle.o(.bss) + time_flags 0x002090d0 Data 1 key_handle.o(.bss) + button_periodic_timer 0x002090d4 Data 4 key_handle.o(.bss) + trigger_button 0x002090dc Data 8 key_handle.o(.bss) + cust_button 0x002090e4 Data 8 key_handle.o(.bss) + .bss 0x002090ec Section 52 fmna_adv.o(.bss) + m_fmna_nearby_adv_packet 0x002090ec Data 4 fmna_adv.o(.bss) + m_fmna_separated_adv_packet 0x002090f0 Data 27 fmna_adv.o(.bss) + m_fmna_pairing_adv_payload 0x0020910b Data 21 fmna_adv.o(.bss) + .bss 0x00209120 Section 40 fmna_connection.o(.bss) + m_fmna_delayed_max_conn 0x00209120 Data 1 fmna_connection.o(.bss) + m_is_fmna_paired 0x00209121 Data 1 fmna_connection.o(.bss) + m_unpair_pending 0x00209122 Data 1 fmna_connection.o(.bss) + m_multi_status 0x00209124 Data 4 fmna_connection.o(.bss) + m_active_ltk 0x00209138 Data 16 fmna_connection.o(.bss) + .bss 0x00209148 Section 1933 fmna_crypto.o(.bss) + serial_number_query_count 0x00209160 Data 8 fmna_crypto.o(.bss) + m_serial_number 0x00209168 Data 16 fmna_crypto.o(.bss) + m_serial_number_hmac_payload 0x00209178 Data 28 fmna_crypto.o(.bss) + m_serial_number_payload 0x00209194 Data 60 fmna_crypto.o(.bss) + m_fm_crypto_ckg_ctx 0x002091d0 Data 196 fmna_crypto.o(.bss) + m_seedk1 0x00209294 Data 32 fmna_crypto.o(.bss) + m_p 0x002092b4 Data 57 fmna_crypto.o(.bss) + m_server_shared_secret 0x002092ed Data 32 fmna_crypto.o(.bss) + m_q_e 0x0020930d Data 65 fmna_crypto.o(.bss) + m_q_a 0x0020934e Data 65 fmna_crypto.o(.bss) + m_mfi_struct 0x00209390 Data 20 fmna_crypto.o(.bss) + m_key_verif_encr_msg 0x002093a4 Data 1265 fmna_crypto.o(.bss) + m_current_primary_sk 0x00209895 Data 32 fmna_crypto.o(.bss) + m_current_secondary_sk 0x002098b5 Data 32 fmna_crypto.o(.bss) + .bss 0x002098d8 Section 299 fmna_gatt.o(.bss) + .bss 0x00209a03 Section 1 fmna_gatt.o(.bss) + .bss 0x00209a04 Section 16 fmna_motion_detection.o(.bss) + m_motion_active_polling_enabled 0x00209a04 Data 1 fmna_motion_detection.o(.bss) + m_motion_active_polling_ended 0x00209a05 Data 1 fmna_motion_detection.o(.bss) + m_motion_sound_count 0x00209a06 Data 1 fmna_motion_detection.o(.bss) + m_motion_poll_timer_id 0x00209a08 Data 4 fmna_motion_detection.o(.bss) + m_motion_active_poll_duration_timer_id 0x00209a0c Data 4 fmna_motion_detection.o(.bss) + m_motion_backoff_timer_id 0x00209a10 Data 4 fmna_motion_detection.o(.bss) + .bss 0x00209a14 Section 1 fmna_nonowner_control_point.o(.bss) + .bss 0x00209a16 Section 1396 fmna_pairing_control_point.o(.bss) + pairing_rx_buffer 0x00209a16 Data 1396 fmna_pairing_control_point.o(.bss) + .bss 0x00209f8c Section 232 fmna_state_machine.o(.bss) + is_persistent_connection_disconnection 0x00209f8c Data 1 fmna_state_machine.o(.bss) + m_motion_detected_sound 0x00209f8d Data 1 fmna_state_machine.o(.bss) + m_is_nearby 0x00209f8e Data 1 fmna_state_machine.o(.bss) + has_been_maintenanced 0x00209f8f Data 1 fmna_state_machine.o(.bss) + nearby_separated_timeout_timer_is_on_work 0x00209f90 Data 1 fmna_state_machine.o(.bss) + m_fmna_nearby_separated_timeout_timer_id 0x00209f9c Data 4 fmna_state_machine.o(.bss) + m_fmna_key_rotation_timer_id 0x00209fa0 Data 4 fmna_state_machine.o(.bss) + m_fmna_one_time_key_rotation_timer_id 0x00209fa4 Data 4 fmna_state_machine.o(.bss) + m_fmna_non_owner_0_connection_timeout_timer_id 0x00209fa8 Data 4 fmna_state_machine.o(.bss) + m_fmna_non_owner_1_connection_timeout_timer_id 0x00209fac Data 4 fmna_state_machine.o(.bss) + m_fmna_pair_connection_timeout_timer_id 0x00209fb0 Data 4 fmna_state_machine.o(.bss) + m_separated_ut_timeout_timer_id 0x00209fb4 Data 4 fmna_state_machine.o(.bss) + m_fmna_persistent_connection_disconnection_timer_id 0x00209fb8 Data 4 fmna_state_machine.o(.bss) + next_secondary_key_rotation_index 0x00209fbc Data 4 fmna_state_machine.o(.bss) + cached_next_secondary_key_rotation_index 0x00209fc0 Data 4 fmna_state_machine.o(.bss) + .bss 0x0020a074 Section 4 fmna_version.o(.bss) + m_fw_version 0x0020a074 Data 4 fmna_version.o(.bss) + .bss 0x0020a078 Section 40 fmna_adv_platform.o(.bss) + fmna_fast_adv_interval 0x0020a078 Data 2 fmna_adv_platform.o(.bss) + fmna_slow_adv_interval 0x0020a07a Data 2 fmna_adv_platform.o(.bss) + fmna_fast_adv_duration 0x0020a07c Data 4 fmna_adv_platform.o(.bss) + fmna_slow_adv_duration 0x0020a080 Data 4 fmna_adv_platform.o(.bss) + fmna_adv 0x0020a084 Data 28 fmna_adv_platform.o(.bss) + .bss 0x0020a0a0 Section 2 fmna_battery_platform.o(.bss) + cur_bat_level 0x0020a0a0 Data 1 fmna_battery_platform.o(.bss) + is_adc_efuse_existed 0x0020a0a1 Data 1 fmna_battery_platform.o(.bss) + .bss 0x0020a0a2 Section 1 fmna_connection_platform.o(.bss) + m_new_token_stored 0x0020a0a2 Data 1 fmna_connection_platform.o(.bss) + .bss 0x0020a0a4 Section 108 fmna_gap_platform.o(.bss) + findmy_adv_timer 0x0020a0a4 Data 4 fmna_gap_platform.o(.bss) + customized_adv_timer 0x0020a0a8 Data 4 fmna_gap_platform.o(.bss) + custom_new_adv_timer 0x0020a0ac Data 4 fmna_gap_platform.o(.bss) + .bss 0x0020a110 Section 14 fmna_gatt_platform.o(.bss) + fmna_gatt_data 0x0020a111 Data 6 fmna_gatt_platform.o(.bss) + .bss 0x0020a120 Section 56 fmna_malloc_platform.o(.bss) + malloc_buf 0x0020a120 Data 56 fmna_malloc_platform.o(.bss) + .bss 0x0020a158 Section 1 fmna_motion_detection_platform.o(.bss) + .bss 0x0020a15c Section 44 fmna_sound_platform.o(.bss) + m_fmna_sound_timeout_timer_id 0x0020a160 Data 4 fmna_sound_platform.o(.bss) + m_beep_sequence_timer_id 0x0020a164 Data 4 fmna_sound_platform.o(.bss) + sound_context 0x0020a168 Data 16 fmna_sound_platform.o(.bss) + beep_sequence_context 0x0020a178 Data 16 fmna_sound_platform.o(.bss) + .bss 0x0020a188 Section 24 fmna_timer_platform.o(.bss) + .bss 0x0020a1a0 Section 2604 aes.o(.bss) + aes_init_done 0x0020a1a0 Data 4 aes.o(.bss) + FSb 0x0020a1a4 Data 256 aes.o(.bss) + FT0 0x0020a2a4 Data 1024 aes.o(.bss) + RSb 0x0020a6a4 Data 256 aes.o(.bss) + RT0 0x0020a7a4 Data 1024 aes.o(.bss) + RCON 0x0020aba4 Data 40 aes.o(.bss) + .bss 0x0020abcc Section 4 cipher.o(.bss) + supported_init 0x0020abcc Data 4 cipher.o(.bss) + .bss 0x0020abd0 Section 28 cipher_wrap.o(.bss) + .bss 0x0020abec Section 4 constant_time.o(.bss) + .bss 0x0020abf0 Section 12 ecp.o(.bss) + ecp_supported_grp_id 0x0020abf0 Data 3 ecp.o(.bss) + ecp_max_ops 0x0020abf4 Data 4 ecp.o(.bss) + init_done 0x0020abf8 Data 4 ecp.o(.bss) + .bss 0x0020abfc Section 8 gap_lib_system_call.o(.bss) + .bss 0x0020ac04 Section 84 adc_lib.o(.bss) + .bss 0x0020ac58 Section 8 key_crypto.o(.bss) + .bss 0x0020ac60 Section 4 gap_vendor_cmd.o(.bss) + .bss 0x0020ac64 Section 228 rand.o(.bss) + .bss 0x0020ad48 Section 20 rt_locale.o(.bss) + __rt_locale_data 0x0020ad48 Data 20 rt_locale.o(.bss) + .app.overlay_a 0x0020ad5c Section 0 system_rtl876x.o(.app.overlay_a) + .app.flash.header 0x00825000 Section 1024 system_rtl876x.o(.app.flash.header) + __tagsym$$used 0x00825000 Number 0 system_rtl876x.o(.app.flash.header) + __tagsym$$used 0x008251e0 Number 0 system_rtl876x.o(.app.flash.header) + RESET 0x00825400 Section 8 startup_rtl876x.o(RESET) + !!!main 0x00825408 Section 8 __main.o(!!!main) + .ARM.Collect$$_printf_percent$$00000000 0x00825410 Section 2 _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) + .ARM.Collect$$_printf_percent$$00000001 0x00825412 Section 10 _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) + .ARM.Collect$$_printf_percent$$00000002 0x0082541c Section 10 _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) + .ARM.Collect$$_printf_percent$$00000003 0x00825426 Section 10 _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) + .ARM.Collect$$_printf_percent$$00000004 0x00825430 Section 10 _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) + .ARM.Collect$$_printf_percent$$00000005 0x0082543a Section 10 _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) + .ARM.Collect$$_printf_percent$$00000006 0x00825444 Section 10 _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) + .ARM.Collect$$_printf_percent$$00000007 0x0082544e Section 10 _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) + .ARM.Collect$$_printf_percent$$00000008 0x00825458 Section 10 _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) + .ARM.Collect$$_printf_percent$$00000009 0x00825462 Section 10 _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) + .ARM.Collect$$_printf_percent$$0000000A 0x0082546c Section 10 _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) + .ARM.Collect$$_printf_percent$$0000000B 0x00825476 Section 10 _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) + .ARM.Collect$$_printf_percent$$0000000C 0x00825480 Section 10 _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) + .ARM.Collect$$_printf_percent$$0000000D 0x0082548a Section 10 _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) + .ARM.Collect$$_printf_percent$$0000000E 0x00825494 Section 10 _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) + .ARM.Collect$$_printf_percent$$0000000F 0x0082549e Section 10 _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) + .ARM.Collect$$_printf_percent$$00000010 0x008254a8 Section 10 _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) + .ARM.Collect$$_printf_percent$$00000011 0x008254b2 Section 10 _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) + .ARM.Collect$$_printf_percent$$00000012 0x008254bc Section 10 _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) + .ARM.Collect$$_printf_percent$$00000013 0x008254c6 Section 10 _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) + .ARM.Collect$$_printf_percent$$00000014 0x008254d0 Section 10 _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) + .ARM.Collect$$_printf_percent$$00000015 0x008254da Section 10 _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) + .ARM.Collect$$_printf_percent$$00000016 0x008254e4 Section 10 _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) + .ARM.Collect$$_printf_percent$$00000017 0x008254ee Section 4 _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017) + .ARM.Collect$$libinit$$00000000 0x008254f2 Section 2 libinit.o(.ARM.Collect$$libinit$$00000000) + .ARM.Collect$$libinit$$00000002 0x008254f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000002) + .ARM.Collect$$libinit$$00000004 0x008254f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000004) + .ARM.Collect$$libinit$$0000000A 0x008254f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000A) + .ARM.Collect$$libinit$$0000000C 0x008254f4 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000C) + .ARM.Collect$$libinit$$0000000D 0x008254f4 Section 4 libinit2.o(.ARM.Collect$$libinit$$0000000D) + .ARM.Collect$$libinit$$0000000E 0x008254f8 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000000E) + .ARM.Collect$$libinit$$0000000F 0x008254f8 Section 6 libinit2.o(.ARM.Collect$$libinit$$0000000F) + .ARM.Collect$$libinit$$00000011 0x008254fe Section 0 libinit2.o(.ARM.Collect$$libinit$$00000011) + .ARM.Collect$$libinit$$00000012 0x008254fe Section 12 libinit2.o(.ARM.Collect$$libinit$$00000012) + .ARM.Collect$$libinit$$00000013 0x0082550a Section 0 libinit2.o(.ARM.Collect$$libinit$$00000013) + .ARM.Collect$$libinit$$00000015 0x0082550a Section 0 libinit2.o(.ARM.Collect$$libinit$$00000015) + .ARM.Collect$$libinit$$00000016 0x0082550a Section 10 libinit2.o(.ARM.Collect$$libinit$$00000016) + .ARM.Collect$$libinit$$00000017 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000017) + .ARM.Collect$$libinit$$00000019 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000019) + .ARM.Collect$$libinit$$0000001B 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001B) + .ARM.Collect$$libinit$$0000001D 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001D) + .ARM.Collect$$libinit$$0000001F 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000001F) + .ARM.Collect$$libinit$$00000021 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000021) + .ARM.Collect$$libinit$$00000023 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000023) + .ARM.Collect$$libinit$$00000025 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000025) + .ARM.Collect$$libinit$$0000002C 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000002C) + .ARM.Collect$$libinit$$0000002E 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$0000002E) + .ARM.Collect$$libinit$$00000030 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000030) + .ARM.Collect$$libinit$$00000032 0x00825514 Section 0 libinit2.o(.ARM.Collect$$libinit$$00000032) + .ARM.Collect$$libinit$$00000033 0x00825514 Section 2 libinit2.o(.ARM.Collect$$libinit$$00000033) + .ARM.Collect$$rtentry$$00000000 0x00825516 Section 0 __rtentry.o(.ARM.Collect$$rtentry$$00000000) + .ARM.Collect$$rtentry$$00000002 0x00825516 Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000002) + .ARM.Collect$$rtentry$$00000005 0x00825516 Section 4 __rtentry5.o(.ARM.Collect$$rtentry$$00000005) + .ARM.Collect$$rtentry$$00000009 0x0082551a Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000009) + .ARM.Collect$$rtentry$$0000000A 0x0082551a Section 4 __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) + .ARM.Collect$$rtentry$$0000000C 0x0082551e Section 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000C) + .ARM.Collect$$rtentry$$0000000D 0x0082551e Section 8 __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) + .ARM.Collect$$rtentry$$00002716 0x00825528 Section 4 __rtentry5.o(.ARM.Collect$$rtentry$$00002716) + __lit__00000000 0x00825528 Data 4 __rtentry5.o(.ARM.Collect$$rtentry$$00002716) + .app.flash.text 0x0082552c Section 0 system_rtl876x.o(.app.flash.text) + .app.flash.text 0x008259d4 Section 0 main.o(.app.flash.text) + .app.flash.text 0x008259e4 Section 0 gap_config.o(.app.flash.text) + .emb_text 0x00825af4 Section 56 rand.o(.emb_text) + .text 0x00825b2c Section 84 startup_rtl876x.o(.text) + DEFAULT_HANDLER_TXT 0x00825b3c Data 0 startup_rtl876x.o(.text) + .text 0x00825b80 Section 0 system_rtl876x.o(.text) + .text 0x00825e28 Section 0 rtl876x_io_dlps.o(.text) + .text 0x00825e44 Section 0 rtl876x_gpio.o(.text) + .text 0x00825fec Section 0 rtl876x_rcc.o(.text) + .text 0x0082632c Section 0 rtl876x_tim.o(.text) + .text 0x0082651c Section 0 rtl876x_pinmux.o(.text) + .text 0x0082695c Section 0 rtl876x_nvic.o(.text) + .text 0x00826a2c Section 0 rtl876x_adc.o(.text) + .text 0x00826d50 Section 0 rtl876x_i2c.o(.text) + .text 0x008271f0 Section 0 rtl876x_aon_wdg.o(.text) + AON_WDG_WriteReg 0x00827431 Thumb Code 40 rtl876x_aon_wdg.o(.text) + .text 0x00827470 Section 0 findmy_network_service.o(.text) + .text 0x00827568 Section 0 accessory_info_service.o(.text) + .text 0x00827698 Section 0 tps.o(.text) + .text 0x0082786c Section 0 ias.o(.text) + .text 0x00827928 Section 0 sdd_service.o(.text) + .text 0x00827b48 Section 0 dis.o(.text) + .text 0x00827df0 Section 0 main.o(.text) + .text 0x00827f98 Section 0 app_task.o(.text) + .text 0x00828180 Section 0 findmy_app.o(.text) + handle_ten_click 0x00828fb9 Thumb Code 88 findmy_app.o(.text) + .text 0x0082902c Section 0 custom_app.o(.text) + cust_adv_update_timer_callback 0x00829145 Thumb Code 46 custom_app.o(.text) + .text 0x00829794 Section 0 overlay_mgr.o(.text) + .text 0x00829810 Section 0 serial_number_send.o(.text) + .text 0x00829990 Section 0 da213b.o(.text) + da213b_write_one_byte 0x00829991 Thumb Code 76 da213b.o(.text) + da213b_read_one_byte 0x008299dd Thumb Code 74 da213b.o(.text) + .text 0x00829bd8 Section 0 key_handle.o(.text) + button_periodic_timer_cb 0x00829bd9 Thumb Code 258 key_handle.o(.text) + cust_button_int_handler 0x00829cdb Thumb Code 158 key_handle.o(.text) + trig_button_int_handler 0x00829d79 Thumb Code 208 key_handle.o(.text) + gpio_key_debounce_timeout_cb 0x00829e49 Thumb Code 100 key_handle.o(.text) + .text 0x0082a1d4 Section 0 fmna_adv.o(.text) + .text 0x0082a374 Section 0 fmna_config_control_point.o(.text) + .text 0x0082a718 Section 0 fmna_connection.o(.text) + is_multi_status_bit_enabled 0x0082acc5 Thumb Code 34 fmna_connection.o(.text) + .text 0x0082ad2c Section 0 fmna_crypto.o(.text) + fmna_crypto_key_restore 0x0082b759 Thumb Code 476 fmna_crypto.o(.text) + .text 0x0082b9c4 Section 0 fmna_debug_control_point.o(.text) + .text 0x0082bb28 Section 0 fmna_gatt.o(.text) + fmna_gatt_dispatch_send_next_packet_handler 0x0082bb75 Thumb Code 8 fmna_gatt.o(.text) + fmna_gatt_dispatch_send_packet_extension_indication_handler 0x0082bfed Thumb Code 20 fmna_gatt.o(.text) + .text 0x0082c034 Section 0 fmna_motion_detection.o(.text) + motion_backoff_timeout_handler 0x0082c035 Thumb Code 48 fmna_motion_detection.o(.text) + motion_active_poll_duration_timeout_sched_handler 0x0082c065 Thumb Code 84 fmna_motion_detection.o(.text) + motion_active_poll_duration_timer_timeout_handler 0x0082c0b9 Thumb Code 24 fmna_motion_detection.o(.text) + motion_poll_timer_timeout_handler 0x0082c0d1 Thumb Code 48 fmna_motion_detection.o(.text) + .text 0x0082c3b8 Section 0 fmna_nonowner_control_point.o(.text) + .text 0x0082c510 Section 0 fmna_paired_owner_control_point.o(.text) + .text 0x0082c6c0 Section 0 fmna_pairing_control_point.o(.text) + .text 0x0082c7e0 Section 0 fmna_state_machine.o(.text) + set_is_nearby 0x0082c7e1 Thumb Code 128 fmna_state_machine.o(.text) + fmna_update_secondary_index 0x0082c92f Thumb Code 102 fmna_state_machine.o(.text) + dispatch_update_next_secondary_key_rotation_index 0x0082ca81 Thumb Code 18 fmna_state_machine.o(.text) + fmna_persistent_connection_disconnection_timeout_handler 0x0082cb21 Thumb Code 56 fmna_state_machine.o(.text) + separated_ut_timeout_handler 0x0082cb59 Thumb Code 48 fmna_state_machine.o(.text) + fmna_pair_connection_timeout_handler 0x0082cb89 Thumb Code 54 fmna_state_machine.o(.text) + fmna_non_owner_1_connection_timeout_handler 0x0082cbbf Thumb Code 232 fmna_state_machine.o(.text) + fmna_non_owner_0_connection_timeout_handler 0x0082cca7 Thumb Code 52 fmna_state_machine.o(.text) + fmna_one_time_key_rotation_handler 0x0082ccdb Thumb Code 96 fmna_state_machine.o(.text) + dispatch_fmna_sm_event_handler 0x0082ce97 Thumb Code 6 fmna_state_machine.o(.text) + fmna_nearby_separated_timeout_handler 0x0082ceab Thumb Code 26 fmna_state_machine.o(.text) + fmna_boot_evt_boot_handler 0x0082cf9d Thumb Code 168 fmna_state_machine.o(.text) + fmna_pair_evt_pair_handler 0x0082d045 Thumb Code 30 fmna_state_machine.o(.text) + fmna_pair_evt_disconnected_handler 0x0082d063 Thumb Code 294 fmna_state_machine.o(.text) + fmna_pair_evt_bonded_handler 0x0082d189 Thumb Code 6 fmna_state_machine.o(.text) + fmna_pair_evt_connected_handler 0x0082d18f Thumb Code 44 fmna_state_machine.o(.text) + fmna_separated_evt_connected_handler 0x0082d1bb Thumb Code 98 fmna_state_machine.o(.text) + fmna_separated_evt_key_rotate_handler 0x0082d21d Thumb Code 50 fmna_state_machine.o(.text) + fmna_separated_evt_unbonded_handler 0x0082d24f Thumb Code 16 fmna_state_machine.o(.text) + fmna_separated_evt_motion_detected_handler 0x0082d25f Thumb Code 24 fmna_state_machine.o(.text) + fmna_separated_evt_sound_start_handler 0x0082d277 Thumb Code 26 fmna_state_machine.o(.text) + fmna_generic_evt_sound_complete_handler 0x0082d291 Thumb Code 78 fmna_state_machine.o(.text) + fmna_separated_evt_sound_complete_handler 0x0082d2df Thumb Code 98 fmna_state_machine.o(.text) + fmna_nearby_evt_connected_handler 0x0082d341 Thumb Code 98 fmna_state_machine.o(.text) + fmna_nearby_evt_key_rotate_handler 0x0082d3a3 Thumb Code 18 fmna_state_machine.o(.text) + fmna_nearby_evt_timeout_handler 0x0082d3b5 Thumb Code 56 fmna_state_machine.o(.text) + fmna_connected_evt_key_rotate_handler 0x0082d3ed Thumb Code 76 fmna_state_machine.o(.text) + fmna_connected_evt_unbonded_handler 0x0082d439 Thumb Code 6 fmna_state_machine.o(.text) + fmna_connected_evt_disconnected_handler 0x0082d43f Thumb Code 110 fmna_state_machine.o(.text) + fmna_connected_evt_timeout_handler 0x0082d4ad Thumb Code 66 fmna_state_machine.o(.text) + fmna_generic_evt_sound_start_handler 0x0082d4ef Thumb Code 20 fmna_state_machine.o(.text) + fmna_connected_evt_sound_stop_handler 0x0082d503 Thumb Code 14 fmna_state_machine.o(.text) + fmna_connected_evt_debug_reset_handler 0x0082d511 Thumb Code 66 fmna_state_machine.o(.text) + fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler 0x0082d553 Thumb Code 228 fmna_state_machine.o(.text) + fmna_fmna_pair_evt_fmna_pairing_finalize_handler 0x0082d637 Thumb Code 62 fmna_state_machine.o(.text) + fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler 0x0082d675 Thumb Code 44 fmna_state_machine.o(.text) + fmna_generic_evt_bonded_handler 0x0082d6a1 Thumb Code 160 fmna_state_machine.o(.text) + fmna_fmna_pair_evt_disconnected_handler 0x0082d741 Thumb Code 20 fmna_state_machine.o(.text) + fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler 0x0082d755 Thumb Code 176 fmna_state_machine.o(.text) + fmna_disconnecting_evt_nearby_handler 0x0082d805 Thumb Code 104 fmna_state_machine.o(.text) + fmna_disconnecting_evt_separated_handler 0x0082d86d Thumb Code 72 fmna_state_machine.o(.text) + fmna_disconnecting_evt_pair_handler 0x0082d8b5 Thumb Code 16 fmna_state_machine.o(.text) + fmna_key_rotation_handler 0x0082db8d Thumb Code 38 fmna_state_machine.o(.text) + fmna_generic_evt_disconnected_handler 0x0082dbb3 Thumb Code 120 fmna_state_machine.o(.text) + .text 0x0082dc6c Section 0 fmna_version.o(.text) + .text 0x0082dcb8 Section 0 fmna_adv_platform.o(.text) + .text 0x0082e0c8 Section 0 fmna_battery_platform.o(.text) + .text 0x0082e2d4 Section 0 fmna_connection_platform.o(.text) + .text 0x0082e60c Section 0 fmna_gap_platform.o(.text) + findmy_adv_timer_callback 0x0082e60d Thumb Code 38 fmna_gap_platform.o(.text) + customized_adv_timer_callback 0x0082e633 Thumb Code 38 fmna_gap_platform.o(.text) + custom_new_adv_timer_callback 0x0082e659 Thumb Code 38 fmna_gap_platform.o(.text) + .text 0x0082ea90 Section 0 fmna_gatt_platform.o(.text) + app_bt_direct_callback 0x0082ea9d Thumb Code 54 fmna_gatt_platform.o(.text) + .text 0x0082f100 Section 0 fmna_malloc_platform.o(.text) + .text 0x0082f238 Section 0 fmna_motion_detection_platform.o(.text) + .text 0x0082f3c4 Section 0 fmna_peer_manager.o(.text) + .text 0x0082f434 Section 0 fmna_sound_platform.o(.text) + buzzer_init 0x0082f435 Thumb Code 152 fmna_sound_platform.o(.text) + beep_sequence_handler 0x0082f4cd Thumb Code 144 fmna_sound_platform.o(.text) + fmna_sound_timeout_handler 0x0082f55d Thumb Code 70 fmna_sound_platform.o(.text) + .text 0x0082f910 Section 0 fmna_timer_platform.o(.text) + sn_lookup_callback 0x0082f933 Thumb Code 26 fmna_timer_platform.o(.text) + unpair_pending_callback 0x0082f94d Thumb Code 16 fmna_timer_platform.o(.text) + .text 0x0082fbc4 Section 0 fm-crypto.o(.text) + _fm_crypto_scmult_reduce 0x008302a7 Thumb Code 134 fm-crypto.o(.text) + .text 0x00830334 Section 0 kdf963.o(.text) + .text 0x008303e8 Section 0 aes.o(.text) + .text 0x008314e8 Section 0 asn1parse.o(.text) + asn1_get_sequence_of_cb 0x00831705 Thumb Code 64 asn1parse.o(.text) + asn1_get_tagged_int 0x008318ad Thumb Code 124 asn1parse.o(.text) + .text 0x00831930 Section 0 asn1write.o(.text) + mbedtls_asn1_write_len_and_tag 0x0083198b Thumb Code 100 asn1write.o(.text) + asn1_write_tagged_int 0x00831d81 Thumb Code 68 asn1write.o(.text) + .text 0x00831dc8 Section 0 base64.o(.text) + mbedtls_ct_base64_enc_char 0x00831dc9 Thumb Code 90 base64.o(.text) + mbedtls_ct_uchar_in_range_if 0x0083214d Thumb Code 34 base64.o(.text) + .text 0x00832178 Section 0 bignum.o(.text) + mpi_select 0x00832c0f Thumb Code 172 bignum.o(.text) + mbedtls_mpi_resize_clear 0x00833675 Thumb Code 52 bignum.o(.text) + add_sub_mpi 0x008336a9 Thumb Code 96 bignum.o(.text) + mpi_montmul 0x00833709 Thumb Code 36 bignum.o(.text) + .text 0x0083372c Section 0 bignum_core.o(.text) + mbedtls_ct_uint_lt 0x00834607 Thumb Code 70 bignum_core.o(.text) + .text 0x00834650 Section 0 cipher.o(.text) + .text 0x00834b6c Section 0 cipher_wrap.o(.text) + gcm_ctx_alloc 0x00834b6d Thumb Code 28 cipher_wrap.o(.text) + gcm_ctx_free 0x00834b89 Thumb Code 16 cipher_wrap.o(.text) + aes_crypt_ecb_wrap 0x00834b99 Thumb Code 8 cipher_wrap.o(.text) + aes_setkey_dec_wrap 0x00834ba1 Thumb Code 8 cipher_wrap.o(.text) + aes_setkey_enc_wrap 0x00834ba9 Thumb Code 8 cipher_wrap.o(.text) + aes_ctx_alloc 0x00834bb1 Thumb Code 28 cipher_wrap.o(.text) + aes_ctx_free 0x00834bcd Thumb Code 16 cipher_wrap.o(.text) + gcm_aes_setkey_wrap 0x00834bdd Thumb Code 14 cipher_wrap.o(.text) + .text 0x00834bf4 Section 0 constant_time.o(.text) + .text 0x00834cac Section 0 ecdh.o(.text) + ecdh_gen_public_restartable 0x0083504d Thumb Code 72 ecdh.o(.text) + .text 0x0083509c Section 0 ecdsa.o(.text) + .text 0x00835888 Section 0 ecp.o(.text) + mbedtls_mpi_mul_mod 0x00835cd7 Thumb Code 168 ecp.o(.text) + ecp_normalize_jac 0x00836033 Thumb Code 134 ecp.o(.text) + ecp_normalize_jac_many 0x008360b9 Thumb Code 432 ecp.o(.text) + ecp_double_jac 0x00836269 Thumb Code 592 ecp.o(.text) + ecp_add_mixed 0x008364b9 Thumb Code 498 ecp.o(.text) + ecp_select_comb 0x008366ab Thumb Code 170 ecp.o(.text) + mbedtls_ecp_mul_shortcuts 0x0083687f Thumb Code 232 ecp.o(.text) + ecp_restart_rsm_free 0x00836d81 Thumb Code 98 ecp.o(.text) + mbedtls_mpi_add_mod 0x00836de3 Thumb Code 64 ecp.o(.text) + ecp_sw_rhs 0x00836e23 Thumb Code 130 ecp.o(.text) + mbedtls_mpi_sub_mod 0x00836ea5 Thumb Code 62 ecp.o(.text) + mbedtls_mpi_shift_l_mod 0x00836ee3 Thumb Code 60 ecp.o(.text) + ecp_mul_restartable_internal 0x00836f1f Thumb Code 148 ecp.o(.text) + ecp_mul_comb 0x00836fb3 Thumb Code 558 ecp.o(.text) + ecp_precompute_comb 0x008371e1 Thumb Code 624 ecp.o(.text) + ecp_mul_comb_after_precomp 0x00837451 Thumb Code 736 ecp.o(.text) + ecp_randomize_jac 0x00837731 Thumb Code 140 ecp.o(.text) + .text 0x008377c4 Section 0 ecp_curves.o(.text) + ecp_group_load 0x008377c5 Thumb Code 130 ecp_curves.o(.text) + ecp_mod_p256 0x00837847 Thumb Code 1044 ecp_curves.o(.text) + ecp_mod_p224 0x00837c5b Thumb Code 542 ecp_curves.o(.text) + mbedtls_ecp_fix_negative 0x00837f07 Thumb Code 64 ecp_curves.o(.text) + sub32 0x00837f47 Thumb Code 32 ecp_curves.o(.text) + add32 0x00837f67 Thumb Code 30 ecp_curves.o(.text) + .text 0x00837fc0 Section 0 gcm.o(.text) + gcm_mult 0x008382ef Thumb Code 394 gcm.o(.text) + gcm_mask 0x0083865b Thumb Code 162 gcm.o(.text) + .text 0x00838aec Section 0 md.o(.text) + .text 0x00838f1a Section 0 sha256.o(.text) + .text 0x00838f74 Section 0 platform_util.o(.text) + .text 0x00838fe8 Section 0 gap_lib.o(.text) + .text 0x00839034 Section 0 gap_lib_system_call.o(.text) + .text 0x00839acc Section 0 adc_lib.o(.text) + ADC_GetKValue 0x00839acd Thumb Code 66 adc_lib.o(.text) + ADC_GetKVoltage 0x00839b0f Thumb Code 82 adc_lib.o(.text) + .text 0x00839dd8 Section 0 key_crypto.o(.text) + .text 0x00839f70 Section 0 gap_vendor_cmd.o(.text) + .text 0x0083a530 Section 0 vsnprintf.o(.text) + .text 0x0083a568 Section 0 rand.o(.text) + .text 0x0083a5a4 Section 0 rt_memmove.o(.text) + .text 0x0083a63a Section 0 memset.o(.text) + .text 0x0083a658 Section 160 strcmpv6m.o(.text) + .text 0x0083a6f8 Section 488 aeabi_sdivfast.o(.text) + .text 0x0083a8e0 Section 0 d2f.o(.text) + .text 0x0083a95c Section 0 daddsub.o(.text) + _dadd1 0x0083a95d Thumb Code 290 daddsub.o(.text) + _dsub1 0x0083aa7f Thumb Code 470 daddsub.o(.text) + .text 0x0083acb4 Section 0 dfixui.o(.text) + .text 0x0083acfc Section 0 dflti.o(.text) + .text 0x0083ad54 Section 0 dmul.o(.text) + .text 0x0083af9c Section 0 fdiv.o(.text) + .text 0x0083b0fc Section 0 ffixui.o(.text) + .text 0x0083b12c Section 0 fflti.o(.text) + .text 0x0083b18a Section 0 _printf_pad.o(.text) + .text 0x0083b1d8 Section 0 _printf_truncate.o(.text) + .text 0x0083b1fc Section 0 _printf_str.o(.text) + .text 0x0083b250 Section 0 _printf_dec.o(.text) + .text 0x0083b2bc Section 0 _printf_charcount.o(.text) + .text 0x0083b2e4 Section 0 _printf_char_common.o(.text) + _printf_input_char 0x0083b2e5 Thumb Code 10 _printf_char_common.o(.text) + .text 0x0083b314 Section 0 _sputc.o(.text) + .text 0x0083b31e Section 0 _snputc.o(.text) + .text 0x0083b330 Section 0 _printf_wctomb.o(.text) + .text 0x0083b3ec Section 0 _printf_longlong_dec.o(.text) + .text 0x0083b45c Section 0 _printf_oct_int_ll.o(.text) + _printf_longlong_oct_internal 0x0083b45d Thumb Code 0 _printf_oct_int_ll.o(.text) + .text 0x0083b4cc Section 0 _printf_hex_int_ll_ptr.o(.text) + _printf_hex_common 0x0083b4cd Thumb Code 0 _printf_hex_int_ll_ptr.o(.text) + .text 0x0083b564 Section 0 __printf_flags_ss_wp.o(.text) + .text 0x0083b6ec Section 0 lludiv10.o(.text) + .text 0x0083b766 Section 0 _printf_intcommon.o(.text) + .text 0x0083b818 Section 0 _printf_fp_dec.o(.text) + _fp_digits 0x0083b81b Thumb Code 412 _printf_fp_dec.o(.text) + .text 0x0083bc30 Section 0 _printf_fp_hex.o(.text) + .text 0x0083bf08 Section 0 _printf_char.o(.text) + .text 0x0083bf36 Section 0 _printf_wchar.o(.text) + .text 0x0083bf64 Section 0 _wcrtomb.o(.text) + .text 0x0083bfa4 Section 0 rtudiv10.o(.text) + .text 0x0083bfcc Section 16 rt_ctype_table.o(.text) + .text 0x0083bfdc Section 8 rt_locale.o(.text) + .text 0x0083bfe4 Section 0 _printf_fp_infnan.o(.text) + .text 0x0083c06c Section 0 bigflt0.o(.text) + .text 0x0083c144 Section 0 btod.o(.text) + btod_internal_mul 0x0083c185 Thumb Code 492 btod.o(.text) + btod_internal_div 0x0083c371 Thumb Code 520 btod.o(.text) + i.__ARM_common_ll_muluu 0x0083c6c4 Section 0 btod.o(i.__ARM_common_ll_muluu) + i.__ARM_common_memcpy1_6 0x0083c6f4 Section 0 custom_app.o(i.__ARM_common_memcpy1_6) + i.__ARM_common_memcpy1_8 0x0083c70e Section 0 overlay_mgr.o(i.__ARM_common_memcpy1_8) + i.__ARM_common_memcpy4_5 0x0083c730 Section 0 custom_app.o(i.__ARM_common_memcpy4_5) + i.__ARM_common_switch8 0x0083c73a Section 0 gap_vendor_cmd.o(i.__ARM_common_switch8) + i.__ARM_fpclassify 0x0083c754 Section 0 fpclassify.o(i.__ARM_fpclassify) + i._is_digit 0x0083c780 Section 0 __printf_wp.o(i._is_digit) + locale$$code 0x0083c790 Section 44 lc_numeric_c.o(locale$$code) + locale$$code 0x0083c7bc Section 44 lc_ctype_c.o(locale$$code) + x$fpl$fadd 0x0083c7e8 Section 140 faddsub.o(x$fpl$fadd) + _fadd1 0x0083c7f5 Thumb Code 0 faddsub.o(x$fpl$fadd) + x$fpl$fmul 0x0083c874 Section 176 fmul.o(x$fpl$fmul) + x$fpl$fsub 0x0083c924 Section 208 faddsub.o(x$fpl$fsub) + _fsub1 0x0083c931 Thumb Code 0 faddsub.o(x$fpl$fsub) + x$fpl$printf1 0x0083c9f4 Section 16 printf1.o(x$fpl$printf1) + x$fpl$printf2 0x0083ca04 Section 16 printf2.o(x$fpl$printf2) + .constdata 0x0083ca14 Section 12 system_rtl876x.o(.constdata) + x$fpl$usenofp 0x0083ca14 Section 0 usenofp.o(x$fpl$usenofp) + .constdata 0x0083ca20 Section 256 system_rtl876x.o(.constdata) + __func__ 0x0083ca20 Data 7 system_rtl876x.o(.constdata) + __func__ 0x0083ca27 Data 7 system_rtl876x.o(.constdata) + __func__ 0x0083ca2e Data 8 system_rtl876x.o(.constdata) + .constdata 0x0083cb20 Section 156 rtl876x_pinmux.o(.constdata) + .constdata 0x0083cbbc Section 460 findmy_network_service.o(.constdata) + .constdata 0x0083cd88 Section 16 accessory_info_service.o(.constdata) + .constdata 0x0083cd98 Section 696 accessory_info_service.o(.constdata) + .constdata 0x0083d050 Section 264 tps.o(.constdata) + .constdata 0x0083d158 Section 96 ias.o(.constdata) + .constdata 0x0083d1b8 Section 124 sdd_service.o(.constdata) + sdd_attr_tbl 0x0083d1b8 Data 112 sdd_service.o(.constdata) + .constdata 0x0083d234 Section 544 dis.o(.constdata) + dis_attr_tbl 0x0083d234 Data 532 dis.o(.constdata) + .constdata 0x0083d454 Section 58 app_task.o(.constdata) + __func__ 0x0083d454 Data 24 app_task.o(.constdata) + __func__ 0x0083d46c Data 20 app_task.o(.constdata) + __func__ 0x0083d480 Data 14 app_task.o(.constdata) + .constdata 0x0083d48e Section 57 custom_app.o(.constdata) + __FUNCTION__ 0x0083d48e Data 28 custom_app.o(.constdata) + __FUNCTION__ 0x0083d4aa Data 15 custom_app.o(.constdata) + __FUNCTION__ 0x0083d4b9 Data 14 custom_app.o(.constdata) + .constdata 0x0083d4c8 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4cc Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4d0 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4d4 Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4d8 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4dc Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4e0 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4e4 Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4e8 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4ec Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4f0 Section 2 fmna_adv.o(.constdata) + .constdata 0x0083d4f4 Section 4 fmna_adv.o(.constdata) + .constdata 0x0083d4f8 Section 8 fmna_adv.o(.constdata) + .constdata 0x0083d500 Section 85 fmna_connection.o(.constdata) + __FUNCTION__ 0x0083d500 Data 21 fmna_connection.o(.constdata) + __FUNCTION__ 0x0083d515 Data 36 fmna_connection.o(.constdata) + __FUNCTION__ 0x0083d539 Data 28 fmna_connection.o(.constdata) + .constdata 0x0083d555 Section 259 fmna_crypto.o(.constdata) + server_key 0x0083d555 Data 88 fmna_crypto.o(.constdata) + sig_key 0x0083d5ad Data 88 fmna_crypto.o(.constdata) + __FUNCTION__ 0x0083d605 Data 29 fmna_crypto.o(.constdata) + __FUNCTION__ 0x0083d622 Data 24 fmna_crypto.o(.constdata) + __FUNCTION__ 0x0083d63a Data 30 fmna_crypto.o(.constdata) + .constdata 0x0083d658 Section 20 fmna_debug_control_point.o(.constdata) + .constdata 0x0083d66c Section 27 fmna_motion_detection.o(.constdata) + __FUNCTION__ 0x0083d66c Data 27 fmna_motion_detection.o(.constdata) + .constdata 0x0083d687 Section 29 fmna_paired_owner_control_point.o(.constdata) + __FUNCTION__ 0x0083d687 Data 29 fmna_paired_owner_control_point.o(.constdata) + .constdata 0x0083d6a4 Section 8 fmna_state_machine.o(.constdata) + fmna_sm_boot_evt_handlers 0x0083d6a4 Data 8 fmna_state_machine.o(.constdata) + .constdata 0x0083d6ac Section 40 fmna_state_machine.o(.constdata) + fmna_sm_pair_evt_handlers 0x0083d6ac Data 40 fmna_state_machine.o(.constdata) + .constdata 0x0083d6d4 Section 48 fmna_state_machine.o(.constdata) + fmna_sm_separated_evt_handlers 0x0083d6d4 Data 48 fmna_state_machine.o(.constdata) + .constdata 0x0083d704 Section 32 fmna_state_machine.o(.constdata) + fmna_sm_nearby_evt_handlers 0x0083d704 Data 32 fmna_state_machine.o(.constdata) + .constdata 0x0083d724 Section 16 fmna_state_machine.o(.constdata) + fmna_sm_connecting_evt_handlers 0x0083d724 Data 16 fmna_state_machine.o(.constdata) + .constdata 0x0083d734 Section 24 fmna_state_machine.o(.constdata) + fmna_sm_fmna_pair_evt_handlers 0x0083d734 Data 24 fmna_state_machine.o(.constdata) + .constdata 0x0083d74c Section 16 fmna_state_machine.o(.constdata) + fmna_sm_fmna_pair_complete_evt_handlers 0x0083d74c Data 16 fmna_state_machine.o(.constdata) + .constdata 0x0083d75c Section 80 fmna_state_machine.o(.constdata) + fmna_sm_connected_evt_handlers 0x0083d75c Data 80 fmna_state_machine.o(.constdata) + .constdata 0x0083d7ac Section 32 fmna_state_machine.o(.constdata) + fmna_sm_disconnecting_evt_handlers 0x0083d7ac Data 32 fmna_state_machine.o(.constdata) + .constdata 0x0083d7cc Section 500 fmna_state_machine.o(.constdata) + fmna_sm_handlers 0x0083d7cc Data 72 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d814 Data 14 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d822 Data 39 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d849 Data 28 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d865 Data 16 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d875 Data 31 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d894 Data 27 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d8af Data 58 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d8e9 Data 44 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d915 Data 35 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d938 Data 59 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d973 Data 47 fmna_state_machine.o(.constdata) + __FUNCTION__ 0x0083d9a2 Data 30 fmna_state_machine.o(.constdata) + .constdata 0x0083d9c0 Section 38 fmna_adv_platform.o(.constdata) + __FUNCTION__ 0x0083d9c0 Data 38 fmna_adv_platform.o(.constdata) + .constdata 0x0083d9e6 Section 41 fmna_connection_platform.o(.constdata) + __func__ 0x0083d9e6 Data 41 fmna_connection_platform.o(.constdata) + .constdata 0x0083da0f Section 23 fmna_gap_platform.o(.constdata) + __FUNCTION__ 0x0083da0f Data 23 fmna_gap_platform.o(.constdata) + .constdata 0x0083da26 Section 122 fmna_gatt_platform.o(.constdata) + __func__ 0x0083da26 Data 40 fmna_gatt_platform.o(.constdata) + __func__ 0x0083da4e Data 42 fmna_gatt_platform.o(.constdata) + __func__ 0x0083da78 Data 40 fmna_gatt_platform.o(.constdata) + .constdata 0x0083daa0 Section 12 fmna_malloc_platform.o(.constdata) + __func__ 0x0083daa0 Data 12 fmna_malloc_platform.o(.constdata) + .constdata 0x0083daac Section 76 fmna_sound_platform.o(.constdata) + __FUNCTION__ 0x0083daac Data 25 fmna_sound_platform.o(.constdata) + __FUNCTION__ 0x0083dac5 Data 26 fmna_sound_platform.o(.constdata) + __FUNCTION__ 0x0083dadf Data 25 fmna_sound_platform.o(.constdata) + .constdata 0x0083daf8 Section 114 fm-crypto.o(.constdata) + __func__ 0x0083db57 Data 19 fm-crypto.o(.constdata) + .constdata 0x0083db6a Section 2 aes.o(.constdata) + mbedtls_byte_order_detector 0x0083db6a Data 2 aes.o(.constdata) + .constdata 0x0083db6c Section 24 asn1parse.o(.constdata) + __func__ 0x0083db6c Data 24 asn1parse.o(.constdata) + .constdata 0x0083db84 Section 30 asn1write.o(.constdata) + __func__ 0x0083db84 Data 30 asn1write.o(.constdata) + .constdata 0x0083dba2 Section 36 bignum.o(.constdata) + __func__ 0x0083dba2 Data 17 bignum.o(.constdata) + __func__ 0x0083dbb3 Data 19 bignum.o(.constdata) + .constdata 0x0083dbc6 Section 2 bignum_core.o(.constdata) + mbedtls_byte_order_detector 0x0083dbc6 Data 2 bignum_core.o(.constdata) + .constdata 0x0083dbc8 Section 24 cipher_wrap.o(.constdata) + aes_info 0x0083dbc8 Data 24 cipher_wrap.o(.constdata) + .constdata 0x0083dbe0 Section 8 cipher_wrap.o(.constdata) + aes_128_ecb_info 0x0083dbe0 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dbe8 Section 8 cipher_wrap.o(.constdata) + aes_192_ecb_info 0x0083dbe8 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dbf0 Section 8 cipher_wrap.o(.constdata) + aes_256_ecb_info 0x0083dbf0 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dbf8 Section 24 cipher_wrap.o(.constdata) + gcm_aes_info 0x0083dbf8 Data 24 cipher_wrap.o(.constdata) + .constdata 0x0083dc10 Section 8 cipher_wrap.o(.constdata) + aes_128_gcm_info 0x0083dc10 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dc18 Section 8 cipher_wrap.o(.constdata) + aes_192_gcm_info 0x0083dc18 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dc20 Section 8 cipher_wrap.o(.constdata) + aes_256_gcm_info 0x0083dc20 Data 8 cipher_wrap.o(.constdata) + .constdata 0x0083dc28 Section 56 cipher_wrap.o(.constdata) + .constdata 0x0083dc60 Section 28 cipher_wrap.o(.constdata) + __func__ 0x0083dc60 Data 14 cipher_wrap.o(.constdata) + __func__ 0x0083dc6e Data 14 cipher_wrap.o(.constdata) + .constdata 0x0083dc7c Section 64 ecdsa.o(.constdata) + __func__ 0x0083dc7c Data 31 ecdsa.o(.constdata) + __func__ 0x0083dc9b Data 33 ecdsa.o(.constdata) + .constdata 0x0083dcbc Section 107 ecp.o(.constdata) + mbedtls_byte_order_detector 0x0083dcbc Data 2 ecp.o(.constdata) + ecp_supported_curves 0x0083dcc0 Data 36 ecp.o(.constdata) + __func__ 0x0083dce4 Data 23 ecp.o(.constdata) + __func__ 0x0083dcfb Data 13 ecp.o(.constdata) + __func__ 0x0083dd08 Data 31 ecp.o(.constdata) + .constdata 0x0083dd28 Section 1072 ecp_curves.o(.constdata) + secp224r1_p 0x0083dd28 Data 32 ecp_curves.o(.constdata) + secp224r1_b 0x0083dd48 Data 28 ecp_curves.o(.constdata) + secp224r1_gx 0x0083dd64 Data 28 ecp_curves.o(.constdata) + secp224r1_gy 0x0083dd80 Data 28 ecp_curves.o(.constdata) + secp224r1_n 0x0083dd9c Data 28 ecp_curves.o(.constdata) + secp224r1_T 0x0083ddb8 Data 384 ecp_curves.o(.constdata) + secp256r1_p 0x0083df38 Data 32 ecp_curves.o(.constdata) + secp256r1_b 0x0083df58 Data 32 ecp_curves.o(.constdata) + secp256r1_gx 0x0083df78 Data 32 ecp_curves.o(.constdata) + secp256r1_gy 0x0083df98 Data 32 ecp_curves.o(.constdata) + secp256r1_n 0x0083dfb8 Data 32 ecp_curves.o(.constdata) + secp256r1_T 0x0083dfd8 Data 384 ecp_curves.o(.constdata) + .constdata 0x0083e158 Section 32 ecp_curves.o(.constdata) + secp224r1_T_0_X 0x0083e158 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e178 Section 32 ecp_curves.o(.constdata) + secp224r1_T_0_Y 0x0083e178 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e198 Section 32 ecp_curves.o(.constdata) + secp224r1_T_1_X 0x0083e198 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e1b8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_1_Y 0x0083e1b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e1d8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_2_X 0x0083e1d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e1f8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_2_Y 0x0083e1f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e218 Section 32 ecp_curves.o(.constdata) + secp224r1_T_3_X 0x0083e218 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e238 Section 32 ecp_curves.o(.constdata) + secp224r1_T_3_Y 0x0083e238 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e258 Section 32 ecp_curves.o(.constdata) + secp224r1_T_4_X 0x0083e258 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e278 Section 32 ecp_curves.o(.constdata) + secp224r1_T_4_Y 0x0083e278 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e298 Section 32 ecp_curves.o(.constdata) + secp224r1_T_5_X 0x0083e298 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e2b8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_5_Y 0x0083e2b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e2d8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_6_X 0x0083e2d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e2f8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_6_Y 0x0083e2f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e318 Section 32 ecp_curves.o(.constdata) + secp224r1_T_7_X 0x0083e318 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e338 Section 32 ecp_curves.o(.constdata) + secp224r1_T_7_Y 0x0083e338 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e358 Section 32 ecp_curves.o(.constdata) + secp224r1_T_8_X 0x0083e358 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e378 Section 32 ecp_curves.o(.constdata) + secp224r1_T_8_Y 0x0083e378 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e398 Section 32 ecp_curves.o(.constdata) + secp224r1_T_9_X 0x0083e398 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e3b8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_9_Y 0x0083e3b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e3d8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_10_X 0x0083e3d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e3f8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_10_Y 0x0083e3f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e418 Section 32 ecp_curves.o(.constdata) + secp224r1_T_11_X 0x0083e418 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e438 Section 32 ecp_curves.o(.constdata) + secp224r1_T_11_Y 0x0083e438 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e458 Section 32 ecp_curves.o(.constdata) + secp224r1_T_12_X 0x0083e458 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e478 Section 32 ecp_curves.o(.constdata) + secp224r1_T_12_Y 0x0083e478 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e498 Section 32 ecp_curves.o(.constdata) + secp224r1_T_13_X 0x0083e498 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e4b8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_13_Y 0x0083e4b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e4d8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_14_X 0x0083e4d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e4f8 Section 32 ecp_curves.o(.constdata) + secp224r1_T_14_Y 0x0083e4f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e518 Section 32 ecp_curves.o(.constdata) + secp224r1_T_15_X 0x0083e518 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e538 Section 32 ecp_curves.o(.constdata) + secp224r1_T_15_Y 0x0083e538 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e558 Section 32 ecp_curves.o(.constdata) + secp256r1_T_0_X 0x0083e558 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e578 Section 32 ecp_curves.o(.constdata) + secp256r1_T_0_Y 0x0083e578 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e598 Section 32 ecp_curves.o(.constdata) + secp256r1_T_1_X 0x0083e598 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e5b8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_1_Y 0x0083e5b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e5d8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_2_X 0x0083e5d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e5f8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_2_Y 0x0083e5f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e618 Section 32 ecp_curves.o(.constdata) + secp256r1_T_3_X 0x0083e618 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e638 Section 32 ecp_curves.o(.constdata) + secp256r1_T_3_Y 0x0083e638 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e658 Section 32 ecp_curves.o(.constdata) + secp256r1_T_4_X 0x0083e658 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e678 Section 32 ecp_curves.o(.constdata) + secp256r1_T_4_Y 0x0083e678 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e698 Section 32 ecp_curves.o(.constdata) + secp256r1_T_5_X 0x0083e698 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e6b8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_5_Y 0x0083e6b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e6d8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_6_X 0x0083e6d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e6f8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_6_Y 0x0083e6f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e718 Section 32 ecp_curves.o(.constdata) + secp256r1_T_7_X 0x0083e718 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e738 Section 32 ecp_curves.o(.constdata) + secp256r1_T_7_Y 0x0083e738 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e758 Section 32 ecp_curves.o(.constdata) + secp256r1_T_8_X 0x0083e758 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e778 Section 32 ecp_curves.o(.constdata) + secp256r1_T_8_Y 0x0083e778 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e798 Section 32 ecp_curves.o(.constdata) + secp256r1_T_9_X 0x0083e798 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e7b8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_9_Y 0x0083e7b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e7d8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_10_X 0x0083e7d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e7f8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_10_Y 0x0083e7f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e818 Section 32 ecp_curves.o(.constdata) + secp256r1_T_11_X 0x0083e818 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e838 Section 32 ecp_curves.o(.constdata) + secp256r1_T_11_Y 0x0083e838 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e858 Section 32 ecp_curves.o(.constdata) + secp256r1_T_12_X 0x0083e858 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e878 Section 32 ecp_curves.o(.constdata) + secp256r1_T_12_Y 0x0083e878 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e898 Section 32 ecp_curves.o(.constdata) + secp256r1_T_13_X 0x0083e898 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e8b8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_13_Y 0x0083e8b8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e8d8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_14_X 0x0083e8d8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e8f8 Section 32 ecp_curves.o(.constdata) + secp256r1_T_14_Y 0x0083e8f8 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e918 Section 32 ecp_curves.o(.constdata) + secp256r1_T_15_X 0x0083e918 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e938 Section 32 ecp_curves.o(.constdata) + secp256r1_T_15_Y 0x0083e938 Data 32 ecp_curves.o(.constdata) + .constdata 0x0083e958 Section 34 gcm.o(.constdata) + mbedtls_byte_order_detector 0x0083e958 Data 2 gcm.o(.constdata) + last4 0x0083e95a Data 32 gcm.o(.constdata) + .constdata 0x0083e97c Section 61 md.o(.constdata) + mbedtls_sha224_info 0x0083e97c Data 3 md.o(.constdata) + mbedtls_sha256_info 0x0083e97f Data 3 md.o(.constdata) + supported_digests 0x0083e984 Data 12 md.o(.constdata) + md_names 0x0083e990 Data 24 md.o(.constdata) + __func__ 0x0083e9a8 Data 17 md.o(.constdata) + .constdata 0x0083e9b9 Section 75 gap_vendor_cmd.o(.constdata) + __func__ 0x0083e9b9 Data 24 gap_vendor_cmd.o(.constdata) + __func__ 0x0083e9d1 Data 28 gap_vendor_cmd.o(.constdata) + __func__ 0x0083e9ed Data 23 gap_vendor_cmd.o(.constdata) + .constdata 0x0083ea04 Section 64 fdiv.o(.constdata) + fdiv_tab 0x0083ea04 Data 64 fdiv.o(.constdata) + .constdata 0x0083ea44 Section 8 _printf_wctomb.o(.constdata) + initial_mbstate 0x0083ea44 Data 8 _printf_wctomb.o(.constdata) + .constdata 0x0083ea4c Section 40 _printf_hex_int_ll_ptr.o(.constdata) + uc_hextab 0x0083ea4c Data 20 _printf_hex_int_ll_ptr.o(.constdata) + lc_hextab 0x0083ea60 Data 20 _printf_hex_int_ll_ptr.o(.constdata) + .constdata 0x0083ea74 Section 17 __printf_flags_ss_wp.o(.constdata) + maptable 0x0083ea74 Data 17 __printf_flags_ss_wp.o(.constdata) + .constdata 0x0083ea85 Section 38 _printf_fp_hex.o(.constdata) + lc_hextab 0x0083ea85 Data 19 _printf_fp_hex.o(.constdata) + uc_hextab 0x0083ea98 Data 19 _printf_fp_hex.o(.constdata) + .constdata 0x0083eaac Section 148 bigflt0.o(.constdata) + tenpwrs_x 0x0083eaac Data 60 bigflt0.o(.constdata) + tenpwrs_i 0x0083eae8 Data 64 bigflt0.o(.constdata) + .conststring 0x0083eb40 Section 508 system_rtl876x.o(.conststring) + .conststring 0x0083ed3c Section 33 tps.o(.conststring) + .conststring 0x0083ed60 Section 25 overlay_mgr.o(.conststring) + .conststring 0x0083ed7c Section 797 fmna_state_machine.o(.conststring) + .conststring 0x0083f09c Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0a8 Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0b4 Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0c0 Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0cc Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0d8 Section 12 cipher_wrap.o(.conststring) + .conststring 0x0083f0e4 Section 22 ecp.o(.conststring) + .conststring 0x0083f0fc Section 15 md.o(.conststring) + locale$$data 0x0083f10c Section 28 lc_numeric_c.o(locale$$data) + __lcnum_c_name 0x0083f110 Data 2 lc_numeric_c.o(locale$$data) + __lcnum_c_start 0x0083f118 Data 0 lc_numeric_c.o(locale$$data) + __lcnum_c_point 0x0083f124 Data 0 lc_numeric_c.o(locale$$data) + __lcnum_c_thousands 0x0083f126 Data 0 lc_numeric_c.o(locale$$data) + __lcnum_c_grouping 0x0083f127 Data 0 lc_numeric_c.o(locale$$data) + locale$$data 0x0083f128 Section 272 lc_ctype_c.o(locale$$data) + __lcnum_c_end 0x0083f128 Data 0 lc_numeric_c.o(locale$$data) + __lcctype_c_name 0x0083f12c Data 2 lc_ctype_c.o(locale$$data) + __lcctype_c_start 0x0083f134 Data 0 lc_ctype_c.o(locale$$data) + __lcctype_c_end 0x0083f238 Data 0 lc_ctype_c.o(locale$$data) + .TRACE 0x08800000 Section 326 system_rtl876x.o(.TRACE) + __tagsym$$used 0x08800000 Number 0 system_rtl876x.o(.TRACE) + format 0x08800000 Data 51 system_rtl876x.o(.TRACE) + __tagsym$$used 0x08800034 Number 0 system_rtl876x.o(.TRACE) + format 0x08800034 Data 32 system_rtl876x.o(.TRACE) + __tagsym$$used 0x08800054 Number 0 system_rtl876x.o(.TRACE) + format 0x08800054 Data 43 system_rtl876x.o(.TRACE) + __tagsym$$used 0x08800080 Number 0 system_rtl876x.o(.TRACE) + format 0x08800080 Data 41 system_rtl876x.o(.TRACE) + __tagsym$$used 0x088000ac Number 0 system_rtl876x.o(.TRACE) + format 0x088000ac Data 45 system_rtl876x.o(.TRACE) + __tagsym$$used 0x088000dc Number 0 system_rtl876x.o(.TRACE) + format 0x088000dc Data 31 system_rtl876x.o(.TRACE) + __tagsym$$used 0x088000fc Number 0 system_rtl876x.o(.TRACE) + format 0x088000fc Data 34 system_rtl876x.o(.TRACE) + __tagsym$$used 0x08800120 Number 0 system_rtl876x.o(.TRACE) + format 0x08800120 Data 38 system_rtl876x.o(.TRACE) + .TRACE 0x08800148 Section 42 rtl876x_io_dlps.o(.TRACE) + __tagsym$$used 0x08800148 Number 0 rtl876x_io_dlps.o(.TRACE) + format 0x08800148 Data 42 rtl876x_io_dlps.o(.TRACE) + .TRACE 0x08800174 Section 252 findmy_network_service.o(.TRACE) + __tagsym$$used 0x08800174 Number 0 findmy_network_service.o(.TRACE) + format 0x08800174 Data 84 findmy_network_service.o(.TRACE) + __tagsym$$used 0x088001c8 Number 0 findmy_network_service.o(.TRACE) + format 0x088001c8 Data 39 findmy_network_service.o(.TRACE) + __tagsym$$used 0x088001f0 Number 0 findmy_network_service.o(.TRACE) + format 0x088001f0 Data 39 findmy_network_service.o(.TRACE) + __tagsym$$used 0x08800218 Number 0 findmy_network_service.o(.TRACE) + format 0x08800218 Data 49 findmy_network_service.o(.TRACE) + __tagsym$$used 0x0880024c Number 0 findmy_network_service.o(.TRACE) + format 0x0880024c Data 36 findmy_network_service.o(.TRACE) + .TRACE 0x08800270 Section 128 accessory_info_service.o(.TRACE) + __tagsym$$used 0x08800270 Number 0 accessory_info_service.o(.TRACE) + format 0x08800270 Data 42 accessory_info_service.o(.TRACE) + __tagsym$$used 0x0880029c Number 0 accessory_info_service.o(.TRACE) + format 0x0880029c Data 46 accessory_info_service.o(.TRACE) + __tagsym$$used 0x088002cc Number 0 accessory_info_service.o(.TRACE) + format 0x088002cc Data 36 accessory_info_service.o(.TRACE) + .TRACE 0x088002f0 Section 297 firmware_update_service.o(.TRACE) + __tagsym$$used 0x088002f0 Number 0 firmware_update_service.o(.TRACE) + format 0x088002f0 Data 85 firmware_update_service.o(.TRACE) + __tagsym$$used 0x08800348 Number 0 firmware_update_service.o(.TRACE) + format 0x08800348 Data 40 firmware_update_service.o(.TRACE) + __tagsym$$used 0x08800370 Number 0 firmware_update_service.o(.TRACE) + format 0x08800370 Data 40 firmware_update_service.o(.TRACE) + __tagsym$$used 0x08800398 Number 0 firmware_update_service.o(.TRACE) + format 0x08800398 Data 49 firmware_update_service.o(.TRACE) + __tagsym$$used 0x088003cc Number 0 firmware_update_service.o(.TRACE) + format 0x088003cc Data 40 firmware_update_service.o(.TRACE) + __tagsym$$used 0x088003f4 Number 0 firmware_update_service.o(.TRACE) + format 0x088003f4 Data 37 firmware_update_service.o(.TRACE) + .TRACE 0x0880041c Section 358 tps.o(.TRACE) + __tagsym$$used 0x0880041c Number 0 tps.o(.TRACE) + format 0x0880041c Data 47 tps.o(.TRACE) + __tagsym$$used 0x0880044c Number 0 tps.o(.TRACE) + format 0x0880044c Data 45 tps.o(.TRACE) + __tagsym$$used 0x0880047c Number 0 tps.o(.TRACE) + format 0x0880047c Data 37 tps.o(.TRACE) + __tagsym$$used 0x088004a4 Number 0 tps.o(.TRACE) + format 0x088004a4 Data 47 tps.o(.TRACE) + __tagsym$$used 0x088004d4 Number 0 tps.o(.TRACE) + format 0x088004d4 Data 40 tps.o(.TRACE) + __tagsym$$used 0x088004fc Number 0 tps.o(.TRACE) + format 0x088004fc Data 44 tps.o(.TRACE) + __tagsym$$used 0x08800528 Number 0 tps.o(.TRACE) + format 0x08800528 Data 53 tps.o(.TRACE) + __tagsym$$used 0x08800560 Number 0 tps.o(.TRACE) + format 0x08800560 Data 34 tps.o(.TRACE) + .TRACE 0x08800584 Section 114 hids_kb.o(.TRACE) + __tagsym$$used 0x08800584 Number 0 hids_kb.o(.TRACE) + format 0x08800584 Data 46 hids_kb.o(.TRACE) + __tagsym$$used 0x088005b4 Number 0 hids_kb.o(.TRACE) + format 0x088005b4 Data 32 hids_kb.o(.TRACE) + __tagsym$$used 0x088005d4 Number 0 hids_kb.o(.TRACE) + format 0x088005d4 Data 34 hids_kb.o(.TRACE) + .TRACE 0x088005f8 Section 82 ias.o(.TRACE) + __tagsym$$used 0x088005f8 Number 0 ias.o(.TRACE) + format 0x088005f8 Data 46 ias.o(.TRACE) + __tagsym$$used 0x08800628 Number 0 ias.o(.TRACE) + format 0x08800628 Data 34 ias.o(.TRACE) + .TRACE 0x0880064c Section 298 sdd_service.o(.TRACE) + __tagsym$$used 0x0880064c Number 0 sdd_service.o(.TRACE) + format 0x0880064c Data 48 sdd_service.o(.TRACE) + __tagsym$$used 0x0880067c Number 0 sdd_service.o(.TRACE) + format 0x0880067c Data 47 sdd_service.o(.TRACE) + __tagsym$$used 0x088006ac Number 0 sdd_service.o(.TRACE) + format 0x088006ac Data 42 sdd_service.o(.TRACE) + __tagsym$$used 0x088006d8 Number 0 sdd_service.o(.TRACE) + format 0x088006d8 Data 48 sdd_service.o(.TRACE) + __tagsym$$used 0x08800708 Number 0 sdd_service.o(.TRACE) + format 0x08800708 Data 28 sdd_service.o(.TRACE) + __tagsym$$used 0x08800724 Number 0 sdd_service.o(.TRACE) + format 0x08800724 Data 46 sdd_service.o(.TRACE) + __tagsym$$used 0x08800754 Number 0 sdd_service.o(.TRACE) + format 0x08800754 Data 34 sdd_service.o(.TRACE) + .TRACE 0x08800778 Section 174 dis.o(.TRACE) + __tagsym$$used 0x08800778 Number 0 dis.o(.TRACE) + format 0x08800778 Data 43 dis.o(.TRACE) + __tagsym$$used 0x088007a4 Number 0 dis.o(.TRACE) + format 0x088007a4 Data 37 dis.o(.TRACE) + __tagsym$$used 0x088007cc Number 0 dis.o(.TRACE) + format 0x088007cc Data 53 dis.o(.TRACE) + __tagsym$$used 0x08800804 Number 0 dis.o(.TRACE) + format 0x08800804 Data 34 dis.o(.TRACE) + .TRACE 0x08800828 Section 152 main.o(.TRACE) + __tagsym$$used 0x08800828 Number 0 main.o(.TRACE) + format 0x08800828 Data 55 main.o(.TRACE) + __tagsym$$used 0x08800860 Number 0 main.o(.TRACE) + format 0x08800860 Data 30 main.o(.TRACE) + __tagsym$$used 0x08800880 Number 0 main.o(.TRACE) + format 0x08800880 Data 22 main.o(.TRACE) + __tagsym$$used 0x08800898 Number 0 main.o(.TRACE) + format 0x08800898 Data 40 main.o(.TRACE) + .TRACE 0x088008c0 Section 184 app_task.o(.TRACE) + __tagsym$$used 0x088008c0 Number 0 app_task.o(.TRACE) + format 0x088008c0 Data 63 app_task.o(.TRACE) + __tagsym$$used 0x08800900 Number 0 app_task.o(.TRACE) + format 0x08800900 Data 64 app_task.o(.TRACE) + __tagsym$$used 0x08800940 Number 0 app_task.o(.TRACE) + format 0x08800940 Data 27 app_task.o(.TRACE) + __tagsym$$used 0x0880095c Number 0 app_task.o(.TRACE) + format 0x0880095c Data 28 app_task.o(.TRACE) + .TRACE 0x08800978 Section 4576 findmy_app.o(.TRACE) + __tagsym$$used 0x08800978 Number 0 findmy_app.o(.TRACE) + format 0x08800978 Data 25 findmy_app.o(.TRACE) + __tagsym$$used 0x08800994 Number 0 findmy_app.o(.TRACE) + format 0x08800994 Data 48 findmy_app.o(.TRACE) + __tagsym$$used 0x088009c4 Number 0 findmy_app.o(.TRACE) + format 0x088009c4 Data 36 findmy_app.o(.TRACE) + __tagsym$$used 0x088009e8 Number 0 findmy_app.o(.TRACE) + format 0x088009e8 Data 112 findmy_app.o(.TRACE) + __tagsym$$used 0x08800a58 Number 0 findmy_app.o(.TRACE) + format 0x08800a58 Data 25 findmy_app.o(.TRACE) + __tagsym$$used 0x08800a74 Number 0 findmy_app.o(.TRACE) + format 0x08800a74 Data 48 findmy_app.o(.TRACE) + __tagsym$$used 0x08800aa4 Number 0 findmy_app.o(.TRACE) + format 0x08800aa4 Data 24 findmy_app.o(.TRACE) + __tagsym$$used 0x08800abc Number 0 findmy_app.o(.TRACE) + format 0x08800abc Data 48 findmy_app.o(.TRACE) + __tagsym$$used 0x08800aec Number 0 findmy_app.o(.TRACE) + format 0x08800aec Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08800b20 Number 0 findmy_app.o(.TRACE) + format 0x08800b20 Data 57 findmy_app.o(.TRACE) + __tagsym$$used 0x08800b5c Number 0 findmy_app.o(.TRACE) + format 0x08800b5c Data 23 findmy_app.o(.TRACE) + __tagsym$$used 0x08800b74 Number 0 findmy_app.o(.TRACE) + format 0x08800b74 Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08800ba8 Number 0 findmy_app.o(.TRACE) + format 0x08800ba8 Data 48 findmy_app.o(.TRACE) + __tagsym$$used 0x08800bd8 Number 0 findmy_app.o(.TRACE) + format 0x08800bd8 Data 50 findmy_app.o(.TRACE) + __tagsym$$used 0x08800c0c Number 0 findmy_app.o(.TRACE) + format 0x08800c0c Data 107 findmy_app.o(.TRACE) + __tagsym$$used 0x08800c78 Number 0 findmy_app.o(.TRACE) + format 0x08800c78 Data 35 findmy_app.o(.TRACE) + __tagsym$$used 0x08800c9c Number 0 findmy_app.o(.TRACE) + format 0x08800c9c Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08800cd0 Number 0 findmy_app.o(.TRACE) + format 0x08800cd0 Data 25 findmy_app.o(.TRACE) + __tagsym$$used 0x08800cec Number 0 findmy_app.o(.TRACE) + format 0x08800cec Data 29 findmy_app.o(.TRACE) + __tagsym$$used 0x08800d0c Number 0 findmy_app.o(.TRACE) + format 0x08800d0c Data 34 findmy_app.o(.TRACE) + __tagsym$$used 0x08800d30 Number 0 findmy_app.o(.TRACE) + format 0x08800d30 Data 40 findmy_app.o(.TRACE) + __tagsym$$used 0x08800d58 Number 0 findmy_app.o(.TRACE) + format 0x08800d58 Data 69 findmy_app.o(.TRACE) + __tagsym$$used 0x08800da0 Number 0 findmy_app.o(.TRACE) + format 0x08800da0 Data 19 findmy_app.o(.TRACE) + __tagsym$$used 0x08800db4 Number 0 findmy_app.o(.TRACE) + format 0x08800db4 Data 21 findmy_app.o(.TRACE) + __tagsym$$used 0x08800dcc Number 0 findmy_app.o(.TRACE) + format 0x08800dcc Data 106 findmy_app.o(.TRACE) + __tagsym$$used 0x08800e38 Number 0 findmy_app.o(.TRACE) + format 0x08800e38 Data 30 findmy_app.o(.TRACE) + __tagsym$$used 0x08800e58 Number 0 findmy_app.o(.TRACE) + format 0x08800e58 Data 46 findmy_app.o(.TRACE) + __tagsym$$used 0x08800e88 Number 0 findmy_app.o(.TRACE) + format 0x08800e88 Data 84 findmy_app.o(.TRACE) + __tagsym$$used 0x08800edc Number 0 findmy_app.o(.TRACE) + format 0x08800edc Data 57 findmy_app.o(.TRACE) + __tagsym$$used 0x08800f18 Number 0 findmy_app.o(.TRACE) + format 0x08800f18 Data 60 findmy_app.o(.TRACE) + __tagsym$$used 0x08800f54 Number 0 findmy_app.o(.TRACE) + format 0x08800f54 Data 133 findmy_app.o(.TRACE) + __tagsym$$used 0x08800fdc Number 0 findmy_app.o(.TRACE) + format 0x08800fdc Data 73 findmy_app.o(.TRACE) + __tagsym$$used 0x08801028 Number 0 findmy_app.o(.TRACE) + format 0x08801028 Data 70 findmy_app.o(.TRACE) + __tagsym$$used 0x08801070 Number 0 findmy_app.o(.TRACE) + format 0x08801070 Data 34 findmy_app.o(.TRACE) + __tagsym$$used 0x08801094 Number 0 findmy_app.o(.TRACE) + format 0x08801094 Data 79 findmy_app.o(.TRACE) + __tagsym$$used 0x088010e4 Number 0 findmy_app.o(.TRACE) + format 0x088010e4 Data 54 findmy_app.o(.TRACE) + __tagsym$$used 0x0880111c Number 0 findmy_app.o(.TRACE) + format 0x0880111c Data 57 findmy_app.o(.TRACE) + __tagsym$$used 0x08801158 Number 0 findmy_app.o(.TRACE) + format 0x08801158 Data 71 findmy_app.o(.TRACE) + __tagsym$$used 0x088011a0 Number 0 findmy_app.o(.TRACE) + format 0x088011a0 Data 70 findmy_app.o(.TRACE) + __tagsym$$used 0x088011e8 Number 0 findmy_app.o(.TRACE) + format 0x088011e8 Data 52 findmy_app.o(.TRACE) + __tagsym$$used 0x0880121c Number 0 findmy_app.o(.TRACE) + format 0x0880121c Data 57 findmy_app.o(.TRACE) + __tagsym$$used 0x08801258 Number 0 findmy_app.o(.TRACE) + format 0x08801258 Data 126 findmy_app.o(.TRACE) + __tagsym$$used 0x088012d8 Number 0 findmy_app.o(.TRACE) + format 0x088012d8 Data 62 findmy_app.o(.TRACE) + __tagsym$$used 0x08801318 Number 0 findmy_app.o(.TRACE) + format 0x08801318 Data 52 findmy_app.o(.TRACE) + __tagsym$$used 0x0880134c Number 0 findmy_app.o(.TRACE) + format 0x0880134c Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08801380 Number 0 findmy_app.o(.TRACE) + format 0x08801380 Data 54 findmy_app.o(.TRACE) + __tagsym$$used 0x088013b8 Number 0 findmy_app.o(.TRACE) + format 0x088013b8 Data 58 findmy_app.o(.TRACE) + __tagsym$$used 0x088013f4 Number 0 findmy_app.o(.TRACE) + format 0x088013f4 Data 32 findmy_app.o(.TRACE) + __tagsym$$used 0x08801414 Number 0 findmy_app.o(.TRACE) + format 0x08801414 Data 37 findmy_app.o(.TRACE) + __tagsym$$used 0x0880143c Number 0 findmy_app.o(.TRACE) + format 0x0880143c Data 120 findmy_app.o(.TRACE) + __tagsym$$used 0x088014b4 Number 0 findmy_app.o(.TRACE) + format 0x088014b4 Data 65 findmy_app.o(.TRACE) + __tagsym$$used 0x088014f8 Number 0 findmy_app.o(.TRACE) + format 0x088014f8 Data 55 findmy_app.o(.TRACE) + __tagsym$$used 0x08801530 Number 0 findmy_app.o(.TRACE) + format 0x08801530 Data 56 findmy_app.o(.TRACE) + __tagsym$$used 0x08801568 Number 0 findmy_app.o(.TRACE) + format 0x08801568 Data 52 findmy_app.o(.TRACE) + __tagsym$$used 0x0880159c Number 0 findmy_app.o(.TRACE) + format 0x0880159c Data 38 findmy_app.o(.TRACE) + __tagsym$$used 0x088015c4 Number 0 findmy_app.o(.TRACE) + format 0x088015c4 Data 37 findmy_app.o(.TRACE) + __tagsym$$used 0x088015ec Number 0 findmy_app.o(.TRACE) + format 0x088015ec Data 43 findmy_app.o(.TRACE) + __tagsym$$used 0x08801618 Number 0 findmy_app.o(.TRACE) + format 0x08801618 Data 40 findmy_app.o(.TRACE) + __tagsym$$used 0x08801640 Number 0 findmy_app.o(.TRACE) + format 0x08801640 Data 43 findmy_app.o(.TRACE) + __tagsym$$used 0x0880166c Number 0 findmy_app.o(.TRACE) + format 0x0880166c Data 29 findmy_app.o(.TRACE) + __tagsym$$used 0x0880168c Number 0 findmy_app.o(.TRACE) + format 0x0880168c Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x088016c0 Number 0 findmy_app.o(.TRACE) + format 0x088016c0 Data 46 findmy_app.o(.TRACE) + __tagsym$$used 0x088016f0 Number 0 findmy_app.o(.TRACE) + format 0x088016f0 Data 45 findmy_app.o(.TRACE) + __tagsym$$used 0x08801720 Number 0 findmy_app.o(.TRACE) + format 0x08801720 Data 42 findmy_app.o(.TRACE) + __tagsym$$used 0x0880174c Number 0 findmy_app.o(.TRACE) + format 0x0880174c Data 40 findmy_app.o(.TRACE) + __tagsym$$used 0x08801774 Number 0 findmy_app.o(.TRACE) + format 0x08801774 Data 43 findmy_app.o(.TRACE) + __tagsym$$used 0x088017a0 Number 0 findmy_app.o(.TRACE) + format 0x088017a0 Data 26 findmy_app.o(.TRACE) + __tagsym$$used 0x088017bc Number 0 findmy_app.o(.TRACE) + format 0x088017bc Data 35 findmy_app.o(.TRACE) + __tagsym$$used 0x088017e0 Number 0 findmy_app.o(.TRACE) + format 0x088017e0 Data 17 findmy_app.o(.TRACE) + __tagsym$$used 0x088017f4 Number 0 findmy_app.o(.TRACE) + format 0x088017f4 Data 16 findmy_app.o(.TRACE) + __tagsym$$used 0x08801804 Number 0 findmy_app.o(.TRACE) + format 0x08801804 Data 58 findmy_app.o(.TRACE) + __tagsym$$used 0x08801840 Number 0 findmy_app.o(.TRACE) + format 0x08801840 Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08801874 Number 0 findmy_app.o(.TRACE) + format 0x08801874 Data 51 findmy_app.o(.TRACE) + __tagsym$$used 0x088018a8 Number 0 findmy_app.o(.TRACE) + format 0x088018a8 Data 81 findmy_app.o(.TRACE) + __tagsym$$used 0x088018fc Number 0 findmy_app.o(.TRACE) + format 0x088018fc Data 58 findmy_app.o(.TRACE) + __tagsym$$used 0x08801938 Number 0 findmy_app.o(.TRACE) + format 0x08801938 Data 65 findmy_app.o(.TRACE) + __tagsym$$used 0x0880197c Number 0 findmy_app.o(.TRACE) + format 0x0880197c Data 42 findmy_app.o(.TRACE) + __tagsym$$used 0x088019a8 Number 0 findmy_app.o(.TRACE) + format 0x088019a8 Data 89 findmy_app.o(.TRACE) + __tagsym$$used 0x08801a04 Number 0 findmy_app.o(.TRACE) + format 0x08801a04 Data 51 findmy_app.o(.TRACE) + __tagsym$$used 0x08801a38 Number 0 findmy_app.o(.TRACE) + format 0x08801a38 Data 85 findmy_app.o(.TRACE) + __tagsym$$used 0x08801a90 Number 0 findmy_app.o(.TRACE) + format 0x08801a90 Data 43 findmy_app.o(.TRACE) + __tagsym$$used 0x08801abc Number 0 findmy_app.o(.TRACE) + format 0x08801abc Data 57 findmy_app.o(.TRACE) + __tagsym$$used 0x08801af8 Number 0 findmy_app.o(.TRACE) + format 0x08801af8 Data 49 findmy_app.o(.TRACE) + __tagsym$$used 0x08801b2c Number 0 findmy_app.o(.TRACE) + format 0x08801b2c Data 44 findmy_app.o(.TRACE) + .TRACE 0x08801b58 Section 1125 custom_app.o(.TRACE) + __tagsym$$used 0x08801b58 Number 0 custom_app.o(.TRACE) + format 0x08801b58 Data 62 custom_app.o(.TRACE) + __tagsym$$used 0x08801b98 Number 0 custom_app.o(.TRACE) + format 0x08801b98 Data 73 custom_app.o(.TRACE) + __tagsym$$used 0x08801be4 Number 0 custom_app.o(.TRACE) + format 0x08801be4 Data 67 custom_app.o(.TRACE) + __tagsym$$used 0x08801c28 Number 0 custom_app.o(.TRACE) + format 0x08801c28 Data 24 custom_app.o(.TRACE) + __tagsym$$used 0x08801c40 Number 0 custom_app.o(.TRACE) + format 0x08801c40 Data 43 custom_app.o(.TRACE) + __tagsym$$used 0x08801c6c Number 0 custom_app.o(.TRACE) + format 0x08801c6c Data 25 custom_app.o(.TRACE) + __tagsym$$used 0x08801c88 Number 0 custom_app.o(.TRACE) + format 0x08801c88 Data 42 custom_app.o(.TRACE) + __tagsym$$used 0x08801cb4 Number 0 custom_app.o(.TRACE) + format 0x08801cb4 Data 24 custom_app.o(.TRACE) + __tagsym$$used 0x08801ccc Number 0 custom_app.o(.TRACE) + format 0x08801ccc Data 54 custom_app.o(.TRACE) + __tagsym$$used 0x08801d04 Number 0 custom_app.o(.TRACE) + format 0x08801d04 Data 33 custom_app.o(.TRACE) + __tagsym$$used 0x08801d28 Number 0 custom_app.o(.TRACE) + format 0x08801d28 Data 22 custom_app.o(.TRACE) + __tagsym$$used 0x08801d40 Number 0 custom_app.o(.TRACE) + format 0x08801d40 Data 35 custom_app.o(.TRACE) + __tagsym$$used 0x08801d64 Number 0 custom_app.o(.TRACE) + format 0x08801d64 Data 38 custom_app.o(.TRACE) + __tagsym$$used 0x08801d8c Number 0 custom_app.o(.TRACE) + format 0x08801d8c Data 27 custom_app.o(.TRACE) + __tagsym$$used 0x08801da8 Number 0 custom_app.o(.TRACE) + format 0x08801da8 Data 58 custom_app.o(.TRACE) + __tagsym$$used 0x08801de4 Number 0 custom_app.o(.TRACE) + format 0x08801de4 Data 42 custom_app.o(.TRACE) + __tagsym$$used 0x08801e10 Number 0 custom_app.o(.TRACE) + format 0x08801e10 Data 28 custom_app.o(.TRACE) + __tagsym$$used 0x08801e2c Number 0 custom_app.o(.TRACE) + format 0x08801e2c Data 42 custom_app.o(.TRACE) + __tagsym$$used 0x08801e58 Number 0 custom_app.o(.TRACE) + format 0x08801e58 Data 41 custom_app.o(.TRACE) + __tagsym$$used 0x08801e84 Number 0 custom_app.o(.TRACE) + format 0x08801e84 Data 59 custom_app.o(.TRACE) + __tagsym$$used 0x08801ec0 Number 0 custom_app.o(.TRACE) + format 0x08801ec0 Data 43 custom_app.o(.TRACE) + __tagsym$$used 0x08801eec Number 0 custom_app.o(.TRACE) + format 0x08801eec Data 43 custom_app.o(.TRACE) + __tagsym$$used 0x08801f18 Number 0 custom_app.o(.TRACE) + format 0x08801f18 Data 43 custom_app.o(.TRACE) + __tagsym$$used 0x08801f44 Number 0 custom_app.o(.TRACE) + format 0x08801f44 Data 37 custom_app.o(.TRACE) + __tagsym$$used 0x08801f6c Number 0 custom_app.o(.TRACE) + format 0x08801f6c Data 44 custom_app.o(.TRACE) + __tagsym$$used 0x08801f98 Number 0 custom_app.o(.TRACE) + format 0x08801f98 Data 37 custom_app.o(.TRACE) + .TRACE 0x08801fc0 Section 888 dfu_flash.o(.TRACE) + __tagsym$$used 0x08801fc0 Number 0 dfu_flash.o(.TRACE) + format 0x08801fc0 Data 60 dfu_flash.o(.TRACE) + __tagsym$$used 0x08801ffc Number 0 dfu_flash.o(.TRACE) + format 0x08801ffc Data 72 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802044 Number 0 dfu_flash.o(.TRACE) + format 0x08802044 Data 78 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802094 Number 0 dfu_flash.o(.TRACE) + format 0x08802094 Data 41 dfu_flash.o(.TRACE) + __tagsym$$used 0x088020c0 Number 0 dfu_flash.o(.TRACE) + format 0x088020c0 Data 33 dfu_flash.o(.TRACE) + __tagsym$$used 0x088020e4 Number 0 dfu_flash.o(.TRACE) + format 0x088020e4 Data 30 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802104 Number 0 dfu_flash.o(.TRACE) + format 0x08802104 Data 34 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802128 Number 0 dfu_flash.o(.TRACE) + format 0x08802128 Data 43 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802154 Number 0 dfu_flash.o(.TRACE) + format 0x08802154 Data 43 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802180 Number 0 dfu_flash.o(.TRACE) + format 0x08802180 Data 77 dfu_flash.o(.TRACE) + __tagsym$$used 0x088021d0 Number 0 dfu_flash.o(.TRACE) + format 0x088021d0 Data 37 dfu_flash.o(.TRACE) + __tagsym$$used 0x088021f8 Number 0 dfu_flash.o(.TRACE) + format 0x088021f8 Data 45 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802228 Number 0 dfu_flash.o(.TRACE) + format 0x08802228 Data 49 dfu_flash.o(.TRACE) + __tagsym$$used 0x0880225c Number 0 dfu_flash.o(.TRACE) + format 0x0880225c Data 41 dfu_flash.o(.TRACE) + __tagsym$$used 0x08802288 Number 0 dfu_flash.o(.TRACE) + format 0x08802288 Data 72 dfu_flash.o(.TRACE) + __tagsym$$used 0x088022d0 Number 0 dfu_flash.o(.TRACE) + format 0x088022d0 Data 28 dfu_flash.o(.TRACE) + __tagsym$$used 0x088022ec Number 0 dfu_flash.o(.TRACE) + format 0x088022ec Data 76 dfu_flash.o(.TRACE) + .TRACE 0x08802338 Section 58 reset_watch_dog_timer.o(.TRACE) + __tagsym$$used 0x08802338 Number 0 reset_watch_dog_timer.o(.TRACE) + format 0x08802338 Data 58 reset_watch_dog_timer.o(.TRACE) + .TRACE 0x08802374 Section 264 serial_number_send.o(.TRACE) + __tagsym$$used 0x08802374 Number 0 serial_number_send.o(.TRACE) + format 0x08802374 Data 50 serial_number_send.o(.TRACE) + __tagsym$$used 0x088023a8 Number 0 serial_number_send.o(.TRACE) + format 0x088023a8 Data 26 serial_number_send.o(.TRACE) + __tagsym$$used 0x088023c4 Number 0 serial_number_send.o(.TRACE) + format 0x088023c4 Data 47 serial_number_send.o(.TRACE) + __tagsym$$used 0x088023f4 Number 0 serial_number_send.o(.TRACE) + format 0x088023f4 Data 41 serial_number_send.o(.TRACE) + __tagsym$$used 0x08802420 Number 0 serial_number_send.o(.TRACE) + format 0x08802420 Data 51 serial_number_send.o(.TRACE) + __tagsym$$used 0x08802454 Number 0 serial_number_send.o(.TRACE) + format 0x08802454 Data 40 serial_number_send.o(.TRACE) + .TRACE 0x0880247c Section 318 da213b.o(.TRACE) + __tagsym$$used 0x0880247c Number 0 da213b.o(.TRACE) + format 0x0880247c Data 45 da213b.o(.TRACE) + __tagsym$$used 0x088024ac Number 0 da213b.o(.TRACE) + format 0x088024ac Data 44 da213b.o(.TRACE) + __tagsym$$used 0x088024d8 Number 0 da213b.o(.TRACE) + format 0x088024d8 Data 24 da213b.o(.TRACE) + __tagsym$$used 0x088024f0 Number 0 da213b.o(.TRACE) + format 0x088024f0 Data 41 da213b.o(.TRACE) + __tagsym$$used 0x0880251c Number 0 da213b.o(.TRACE) + format 0x0880251c Data 35 da213b.o(.TRACE) + __tagsym$$used 0x08802540 Number 0 da213b.o(.TRACE) + format 0x08802540 Data 40 da213b.o(.TRACE) + __tagsym$$used 0x08802568 Number 0 da213b.o(.TRACE) + format 0x08802568 Data 40 da213b.o(.TRACE) + __tagsym$$used 0x08802590 Number 0 da213b.o(.TRACE) + format 0x08802590 Data 42 da213b.o(.TRACE) + .TRACE 0x088025bc Section 890 key_handle.o(.TRACE) + __tagsym$$used 0x088025bc Number 0 key_handle.o(.TRACE) + format 0x088025bc Data 90 key_handle.o(.TRACE) + __tagsym$$used 0x08802618 Number 0 key_handle.o(.TRACE) + format 0x08802618 Data 90 key_handle.o(.TRACE) + __tagsym$$used 0x08802674 Number 0 key_handle.o(.TRACE) + format 0x08802674 Data 91 key_handle.o(.TRACE) + __tagsym$$used 0x088026d0 Number 0 key_handle.o(.TRACE) + format 0x088026d0 Data 51 key_handle.o(.TRACE) + __tagsym$$used 0x08802704 Number 0 key_handle.o(.TRACE) + format 0x08802704 Data 67 key_handle.o(.TRACE) + __tagsym$$used 0x08802748 Number 0 key_handle.o(.TRACE) + format 0x08802748 Data 54 key_handle.o(.TRACE) + __tagsym$$used 0x08802780 Number 0 key_handle.o(.TRACE) + format 0x08802780 Data 59 key_handle.o(.TRACE) + __tagsym$$used 0x088027bc Number 0 key_handle.o(.TRACE) + format 0x088027bc Data 67 key_handle.o(.TRACE) + __tagsym$$used 0x08802800 Number 0 key_handle.o(.TRACE) + format 0x08802800 Data 54 key_handle.o(.TRACE) + __tagsym$$used 0x08802838 Number 0 key_handle.o(.TRACE) + format 0x08802838 Data 71 key_handle.o(.TRACE) + __tagsym$$used 0x08802880 Number 0 key_handle.o(.TRACE) + format 0x08802880 Data 71 key_handle.o(.TRACE) + __tagsym$$used 0x088028c8 Number 0 key_handle.o(.TRACE) + format 0x088028c8 Data 53 key_handle.o(.TRACE) + __tagsym$$used 0x08802900 Number 0 key_handle.o(.TRACE) + format 0x08802900 Data 54 key_handle.o(.TRACE) + .TRACE 0x08802938 Section 90 fmna_adv.o(.TRACE) + __tagsym$$used 0x08802938 Number 0 fmna_adv.o(.TRACE) + format 0x08802938 Data 35 fmna_adv.o(.TRACE) + __tagsym$$used 0x0880295c Number 0 fmna_adv.o(.TRACE) + format 0x0880295c Data 6 fmna_adv.o(.TRACE) + __tagsym$$used 0x08802964 Number 0 fmna_adv.o(.TRACE) + format 0x08802964 Data 38 fmna_adv.o(.TRACE) + __tagsym$$used 0x0880298c Number 0 fmna_adv.o(.TRACE) + format 0x0880298c Data 6 fmna_adv.o(.TRACE) + .TRACE 0x08802994 Section 851 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802994 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802994 Data 53 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x088029cc Number 0 fmna_config_control_point.o(.TRACE) + format 0x088029cc Data 43 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x088029f8 Number 0 fmna_config_control_point.o(.TRACE) + format 0x088029f8 Data 51 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802a2c Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802a2c Data 53 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802a64 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802a64 Data 18 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802a78 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802a78 Data 37 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802aa0 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802aa0 Data 17 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802ab4 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802ab4 Data 32 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802ad4 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802ad4 Data 38 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802afc Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802afc Data 38 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802b24 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802b24 Data 26 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802b40 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802b40 Data 53 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802b78 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802b78 Data 32 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802b98 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802b98 Data 13 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802ba8 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802ba8 Data 32 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802bc8 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802bc8 Data 44 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802bf4 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802bf4 Data 53 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802c2c Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802c2c Data 28 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802c48 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802c48 Data 23 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802c60 Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802c60 Data 59 fmna_config_control_point.o(.TRACE) + __tagsym$$used 0x08802c9c Number 0 fmna_config_control_point.o(.TRACE) + format 0x08802c9c Data 75 fmna_config_control_point.o(.TRACE) + .TRACE 0x08802ce8 Section 722 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802ce8 Number 0 fmna_connection.o(.TRACE) + format 0x08802ce8 Data 51 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802d1c Number 0 fmna_connection.o(.TRACE) + format 0x08802d1c Data 30 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802d3c Number 0 fmna_connection.o(.TRACE) + format 0x08802d3c Data 43 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802d68 Number 0 fmna_connection.o(.TRACE) + format 0x08802d68 Data 48 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802d98 Number 0 fmna_connection.o(.TRACE) + format 0x08802d98 Data 48 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802dc8 Number 0 fmna_connection.o(.TRACE) + format 0x08802dc8 Data 65 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802e0c Number 0 fmna_connection.o(.TRACE) + format 0x08802e0c Data 36 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802e30 Number 0 fmna_connection.o(.TRACE) + format 0x08802e30 Data 106 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802e9c Number 0 fmna_connection.o(.TRACE) + format 0x08802e9c Data 30 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802ebc Number 0 fmna_connection.o(.TRACE) + format 0x08802ebc Data 31 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802edc Number 0 fmna_connection.o(.TRACE) + format 0x08802edc Data 51 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f10 Number 0 fmna_connection.o(.TRACE) + format 0x08802f10 Data 34 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f34 Number 0 fmna_connection.o(.TRACE) + format 0x08802f34 Data 23 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f4c Number 0 fmna_connection.o(.TRACE) + format 0x08802f4c Data 22 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f64 Number 0 fmna_connection.o(.TRACE) + format 0x08802f64 Data 40 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f8c Number 0 fmna_connection.o(.TRACE) + format 0x08802f8c Data 15 fmna_connection.o(.TRACE) + __tagsym$$used 0x08802f9c Number 0 fmna_connection.o(.TRACE) + format 0x08802f9c Data 30 fmna_connection.o(.TRACE) + .TRACE 0x08802fbc Section 1929 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08802fbc Number 0 fmna_crypto.o(.TRACE) + format 0x08802fbc Data 30 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08802fdc Number 0 fmna_crypto.o(.TRACE) + format 0x08802fdc Data 18 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08802ff0 Number 0 fmna_crypto.o(.TRACE) + format 0x08802ff0 Data 44 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880301c Number 0 fmna_crypto.o(.TRACE) + format 0x0880301c Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803024 Number 0 fmna_crypto.o(.TRACE) + format 0x08803024 Data 21 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880303c Number 0 fmna_crypto.o(.TRACE) + format 0x0880303c Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803044 Number 0 fmna_crypto.o(.TRACE) + format 0x08803044 Data 46 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803074 Number 0 fmna_crypto.o(.TRACE) + format 0x08803074 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880307c Number 0 fmna_crypto.o(.TRACE) + format 0x0880307c Data 54 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088030b4 Number 0 fmna_crypto.o(.TRACE) + format 0x088030b4 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088030bc Number 0 fmna_crypto.o(.TRACE) + format 0x088030bc Data 42 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088030e8 Number 0 fmna_crypto.o(.TRACE) + format 0x088030e8 Data 48 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803118 Number 0 fmna_crypto.o(.TRACE) + format 0x08803118 Data 44 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803144 Number 0 fmna_crypto.o(.TRACE) + format 0x08803144 Data 20 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803158 Number 0 fmna_crypto.o(.TRACE) + format 0x08803158 Data 30 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803178 Number 0 fmna_crypto.o(.TRACE) + format 0x08803178 Data 37 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088031a0 Number 0 fmna_crypto.o(.TRACE) + format 0x088031a0 Data 28 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088031bc Number 0 fmna_crypto.o(.TRACE) + format 0x088031bc Data 29 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088031dc Number 0 fmna_crypto.o(.TRACE) + format 0x088031dc Data 31 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088031fc Number 0 fmna_crypto.o(.TRACE) + format 0x088031fc Data 36 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803220 Number 0 fmna_crypto.o(.TRACE) + format 0x08803220 Data 40 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803248 Number 0 fmna_crypto.o(.TRACE) + format 0x08803248 Data 41 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803274 Number 0 fmna_crypto.o(.TRACE) + format 0x08803274 Data 14 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803284 Number 0 fmna_crypto.o(.TRACE) + format 0x08803284 Data 48 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088032b4 Number 0 fmna_crypto.o(.TRACE) + format 0x088032b4 Data 30 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088032d4 Number 0 fmna_crypto.o(.TRACE) + format 0x088032d4 Data 30 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088032f4 Number 0 fmna_crypto.o(.TRACE) + format 0x088032f4 Data 40 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880331c Number 0 fmna_crypto.o(.TRACE) + format 0x0880331c Data 31 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880333c Number 0 fmna_crypto.o(.TRACE) + format 0x0880333c Data 29 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880335c Number 0 fmna_crypto.o(.TRACE) + format 0x0880335c Data 31 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880337c Number 0 fmna_crypto.o(.TRACE) + format 0x0880337c Data 40 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088033a4 Number 0 fmna_crypto.o(.TRACE) + format 0x088033a4 Data 41 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088033d0 Number 0 fmna_crypto.o(.TRACE) + format 0x088033d0 Data 14 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088033e0 Number 0 fmna_crypto.o(.TRACE) + format 0x088033e0 Data 31 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803400 Number 0 fmna_crypto.o(.TRACE) + format 0x08803400 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803408 Number 0 fmna_crypto.o(.TRACE) + format 0x08803408 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803410 Number 0 fmna_crypto.o(.TRACE) + format 0x08803410 Data 16 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803420 Number 0 fmna_crypto.o(.TRACE) + format 0x08803420 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803428 Number 0 fmna_crypto.o(.TRACE) + format 0x08803428 Data 18 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880343c Number 0 fmna_crypto.o(.TRACE) + format 0x0880343c Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803444 Number 0 fmna_crypto.o(.TRACE) + format 0x08803444 Data 18 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803458 Number 0 fmna_crypto.o(.TRACE) + format 0x08803458 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803460 Number 0 fmna_crypto.o(.TRACE) + format 0x08803460 Data 50 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803494 Number 0 fmna_crypto.o(.TRACE) + format 0x08803494 Data 31 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088034b4 Number 0 fmna_crypto.o(.TRACE) + format 0x088034b4 Data 47 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088034e4 Number 0 fmna_crypto.o(.TRACE) + format 0x088034e4 Data 36 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803508 Number 0 fmna_crypto.o(.TRACE) + format 0x08803508 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803510 Number 0 fmna_crypto.o(.TRACE) + format 0x08803510 Data 41 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880353c Number 0 fmna_crypto.o(.TRACE) + format 0x0880353c Data 13 fmna_crypto.o(.TRACE) + __tagsym$$used 0x0880354c Number 0 fmna_crypto.o(.TRACE) + format 0x0880354c Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803554 Number 0 fmna_crypto.o(.TRACE) + format 0x08803554 Data 41 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803580 Number 0 fmna_crypto.o(.TRACE) + format 0x08803580 Data 38 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088035a8 Number 0 fmna_crypto.o(.TRACE) + format 0x088035a8 Data 6 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088035b0 Number 0 fmna_crypto.o(.TRACE) + format 0x088035b0 Data 30 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088035d0 Number 0 fmna_crypto.o(.TRACE) + format 0x088035d0 Data 33 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088035f4 Number 0 fmna_crypto.o(.TRACE) + format 0x088035f4 Data 57 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803630 Number 0 fmna_crypto.o(.TRACE) + format 0x08803630 Data 36 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803654 Number 0 fmna_crypto.o(.TRACE) + format 0x08803654 Data 42 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803680 Number 0 fmna_crypto.o(.TRACE) + format 0x08803680 Data 47 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088036b0 Number 0 fmna_crypto.o(.TRACE) + format 0x088036b0 Data 22 fmna_crypto.o(.TRACE) + __tagsym$$used 0x088036c8 Number 0 fmna_crypto.o(.TRACE) + format 0x088036c8 Data 71 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803710 Number 0 fmna_crypto.o(.TRACE) + format 0x08803710 Data 29 fmna_crypto.o(.TRACE) + __tagsym$$used 0x08803730 Number 0 fmna_crypto.o(.TRACE) + format 0x08803730 Data 21 fmna_crypto.o(.TRACE) + .TRACE 0x08803748 Section 239 fmna_debug_control_point.o(.TRACE) + __tagsym$$used 0x08803748 Number 0 fmna_debug_control_point.o(.TRACE) + format 0x08803748 Data 51 fmna_debug_control_point.o(.TRACE) + __tagsym$$used 0x0880377c Number 0 fmna_debug_control_point.o(.TRACE) + format 0x0880377c Data 48 fmna_debug_control_point.o(.TRACE) + __tagsym$$used 0x088037ac Number 0 fmna_debug_control_point.o(.TRACE) + format 0x088037ac Data 20 fmna_debug_control_point.o(.TRACE) + __tagsym$$used 0x088037c0 Number 0 fmna_debug_control_point.o(.TRACE) + format 0x088037c0 Data 68 fmna_debug_control_point.o(.TRACE) + __tagsym$$used 0x08803804 Number 0 fmna_debug_control_point.o(.TRACE) + format 0x08803804 Data 51 fmna_debug_control_point.o(.TRACE) + .TRACE 0x08803838 Section 855 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803838 Number 0 fmna_gatt.o(.TRACE) + format 0x08803838 Data 40 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803860 Number 0 fmna_gatt.o(.TRACE) + format 0x08803860 Data 35 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803884 Number 0 fmna_gatt.o(.TRACE) + format 0x08803884 Data 44 fmna_gatt.o(.TRACE) + __tagsym$$used 0x088038b0 Number 0 fmna_gatt.o(.TRACE) + format 0x088038b0 Data 32 fmna_gatt.o(.TRACE) + __tagsym$$used 0x088038d0 Number 0 fmna_gatt.o(.TRACE) + format 0x088038d0 Data 51 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803904 Number 0 fmna_gatt.o(.TRACE) + format 0x08803904 Data 40 fmna_gatt.o(.TRACE) + __tagsym$$used 0x0880392c Number 0 fmna_gatt.o(.TRACE) + format 0x0880392c Data 32 fmna_gatt.o(.TRACE) + __tagsym$$used 0x0880394c Number 0 fmna_gatt.o(.TRACE) + format 0x0880394c Data 47 fmna_gatt.o(.TRACE) + __tagsym$$used 0x0880397c Number 0 fmna_gatt.o(.TRACE) + format 0x0880397c Data 43 fmna_gatt.o(.TRACE) + __tagsym$$used 0x088039a8 Number 0 fmna_gatt.o(.TRACE) + format 0x088039a8 Data 32 fmna_gatt.o(.TRACE) + __tagsym$$used 0x088039c8 Number 0 fmna_gatt.o(.TRACE) + format 0x088039c8 Data 50 fmna_gatt.o(.TRACE) + __tagsym$$used 0x088039fc Number 0 fmna_gatt.o(.TRACE) + format 0x088039fc Data 36 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803a20 Number 0 fmna_gatt.o(.TRACE) + format 0x08803a20 Data 32 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803a40 Number 0 fmna_gatt.o(.TRACE) + format 0x08803a40 Data 43 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803a6c Number 0 fmna_gatt.o(.TRACE) + format 0x08803a6c Data 43 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803a98 Number 0 fmna_gatt.o(.TRACE) + format 0x08803a98 Data 43 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803ac4 Number 0 fmna_gatt.o(.TRACE) + format 0x08803ac4 Data 51 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803af8 Number 0 fmna_gatt.o(.TRACE) + format 0x08803af8 Data 38 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803b20 Number 0 fmna_gatt.o(.TRACE) + format 0x08803b20 Data 65 fmna_gatt.o(.TRACE) + __tagsym$$used 0x08803b64 Number 0 fmna_gatt.o(.TRACE) + format 0x08803b64 Data 43 fmna_gatt.o(.TRACE) + .TRACE 0x08803b90 Section 938 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803b90 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803b90 Data 30 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803bb0 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803bb0 Data 30 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803bd0 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803bd0 Data 30 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803bf0 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803bf0 Data 44 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803c1c Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803c1c Data 60 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803c58 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803c58 Data 47 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803c88 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803c88 Data 53 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803cc0 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803cc0 Data 8 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803cc8 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803cc8 Data 8 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803cd0 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803cd0 Data 75 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803d1c Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803d1c Data 51 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803d50 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803d50 Data 36 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803d74 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803d74 Data 39 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803d9c Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803d9c Data 55 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803dd4 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803dd4 Data 37 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803dfc Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803dfc Data 55 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803e34 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803e34 Data 34 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803e58 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803e58 Data 59 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803e94 Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803e94 Data 53 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803ecc Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803ecc Data 30 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803eec Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803eec Data 31 fmna_motion_detection.o(.TRACE) + __tagsym$$used 0x08803f0c Number 0 fmna_motion_detection.o(.TRACE) + format 0x08803f0c Data 46 fmna_motion_detection.o(.TRACE) + .TRACE 0x08803f3c Section 351 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08803f3c Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08803f3c Data 38 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08803f64 Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08803f64 Data 51 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08803f98 Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08803f98 Data 49 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08803fcc Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08803fcc Data 28 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08803fe8 Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08803fe8 Data 37 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08804010 Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08804010 Data 27 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x0880402c Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x0880402c Data 32 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x0880404c Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x0880404c Data 24 fmna_nonowner_control_point.o(.TRACE) + __tagsym$$used 0x08804064 Number 0 fmna_nonowner_control_point.o(.TRACE) + format 0x08804064 Data 55 fmna_nonowner_control_point.o(.TRACE) + .TRACE 0x0880409c Section 346 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x0880409c Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x0880409c Data 51 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x088040d0 Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x088040d0 Data 34 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x088040f4 Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x088040f4 Data 57 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x08804130 Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x08804130 Data 55 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x08804168 Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x08804168 Data 30 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x08804188 Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x08804188 Data 51 fmna_paired_owner_control_point.o(.TRACE) + __tagsym$$used 0x088041bc Number 0 fmna_paired_owner_control_point.o(.TRACE) + format 0x088041bc Data 58 fmna_paired_owner_control_point.o(.TRACE) + .TRACE 0x088041f8 Section 73 fmna_pairing_control_point.o(.TRACE) + __tagsym$$used 0x088041f8 Number 0 fmna_pairing_control_point.o(.TRACE) + format 0x088041f8 Data 19 fmna_pairing_control_point.o(.TRACE) + __tagsym$$used 0x0880420c Number 0 fmna_pairing_control_point.o(.TRACE) + format 0x0880420c Data 31 fmna_pairing_control_point.o(.TRACE) + __tagsym$$used 0x0880422c Number 0 fmna_pairing_control_point.o(.TRACE) + format 0x0880422c Data 21 fmna_pairing_control_point.o(.TRACE) + .TRACE 0x08804244 Section 3327 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804244 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804244 Data 66 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804288 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804288 Data 67 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088042cc Number 0 fmna_state_machine.o(.TRACE) + format 0x088042cc Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088042ec Number 0 fmna_state_machine.o(.TRACE) + format 0x088042ec Data 44 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804318 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804318 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804338 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804338 Data 63 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804378 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804378 Data 88 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088043d0 Number 0 fmna_state_machine.o(.TRACE) + format 0x088043d0 Data 43 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088043fc Number 0 fmna_state_machine.o(.TRACE) + format 0x088043fc Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880441c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880441c Data 57 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804458 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804458 Data 57 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804494 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804494 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088044b4 Number 0 fmna_state_machine.o(.TRACE) + format 0x088044b4 Data 36 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088044d8 Number 0 fmna_state_machine.o(.TRACE) + format 0x088044d8 Data 44 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804504 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804504 Data 68 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804548 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804548 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804568 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804568 Data 31 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804588 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804588 Data 66 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088045cc Number 0 fmna_state_machine.o(.TRACE) + format 0x088045cc Data 55 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804604 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804604 Data 71 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880464c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880464c Data 52 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804680 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804680 Data 71 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088046c8 Number 0 fmna_state_machine.o(.TRACE) + format 0x088046c8 Data 58 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804704 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804704 Data 65 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804748 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804748 Data 39 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804770 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804770 Data 42 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880479c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880479c Data 43 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088047c8 Number 0 fmna_state_machine.o(.TRACE) + format 0x088047c8 Data 45 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088047f8 Number 0 fmna_state_machine.o(.TRACE) + format 0x088047f8 Data 66 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880483c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880483c Data 50 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804870 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804870 Data 70 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088048b8 Number 0 fmna_state_machine.o(.TRACE) + format 0x088048b8 Data 44 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088048e4 Number 0 fmna_state_machine.o(.TRACE) + format 0x088048e4 Data 65 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804928 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804928 Data 67 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880496c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880496c Data 48 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x0880499c Number 0 fmna_state_machine.o(.TRACE) + format 0x0880499c Data 56 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x088049d4 Number 0 fmna_state_machine.o(.TRACE) + format 0x088049d4 Data 50 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804a08 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804a08 Data 72 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804a50 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804a50 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804a70 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804a70 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804a90 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804a90 Data 57 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804acc Number 0 fmna_state_machine.o(.TRACE) + format 0x08804acc Data 25 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804ae8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804ae8 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804b08 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804b08 Data 32 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804b28 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804b28 Data 72 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804b70 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804b70 Data 32 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804b90 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804b90 Data 72 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804bd8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804bd8 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804bf8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804bf8 Data 67 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804c3c Number 0 fmna_state_machine.o(.TRACE) + format 0x08804c3c Data 34 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804c60 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804c60 Data 65 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804ca4 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804ca4 Data 32 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804cc4 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804cc4 Data 59 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804d00 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804d00 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804d20 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804d20 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804d40 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804d40 Data 47 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804d70 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804d70 Data 87 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804dc8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804dc8 Data 40 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804df0 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804df0 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804e10 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804e10 Data 45 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804e40 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804e40 Data 48 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804e70 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804e70 Data 56 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804ea8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804ea8 Data 30 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804ec8 Number 0 fmna_state_machine.o(.TRACE) + format 0x08804ec8 Data 68 fmna_state_machine.o(.TRACE) + __tagsym$$used 0x08804f0c Number 0 fmna_state_machine.o(.TRACE) + format 0x08804f0c Data 55 fmna_state_machine.o(.TRACE) + .TRACE 0x08804f44 Section 746 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804f44 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804f44 Data 30 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804f64 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804f64 Data 41 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804f90 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804f90 Data 27 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804fac Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804fac Data 30 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804fcc Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804fcc Data 21 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08804fe4 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08804fe4 Data 70 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x0880502c Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x0880502c Data 37 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08805054 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08805054 Data 75 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x088050a0 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x088050a0 Data 32 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x088050c0 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x088050c0 Data 30 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x088050e0 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x088050e0 Data 47 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08805110 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08805110 Data 32 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08805130 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08805130 Data 49 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x08805164 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x08805164 Data 39 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x0880518c Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x0880518c Data 37 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x088051b4 Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x088051b4 Data 56 fmna_uarp_control_point.o(.TRACE) + __tagsym$$used 0x088051ec Number 0 fmna_uarp_control_point.o(.TRACE) + format 0x088051ec Data 66 fmna_uarp_control_point.o(.TRACE) + .TRACE 0x08805230 Section 53 fmna_version.o(.TRACE) + __tagsym$$used 0x08805230 Number 0 fmna_version.o(.TRACE) + format 0x08805230 Data 22 fmna_version.o(.TRACE) + __tagsym$$used 0x08805248 Number 0 fmna_version.o(.TRACE) + format 0x08805248 Data 29 fmna_version.o(.TRACE) + .TRACE 0x08805268 Section 1815 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805268 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805268 Data 34 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880528c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880528c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088052b0 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088052b0 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088052d4 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088052d4 Data 34 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088052f8 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088052f8 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880531c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880531c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805340 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805340 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805364 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805364 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805388 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805388 Data 34 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088053ac Number 0 fmnasampleuarp.o(.TRACE) + format 0x088053ac Data 22 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088053c4 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088053c4 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088053e8 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088053e8 Data 28 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805404 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805404 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805428 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805428 Data 46 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805458 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805458 Data 47 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805488 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805488 Data 46 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088054b8 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088054b8 Data 27 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088054d4 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088054d4 Data 56 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880550c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880550c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805530 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805530 Data 41 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880555c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880555c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805580 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805580 Data 39 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088055a8 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088055a8 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088055cc Number 0 fmnasampleuarp.o(.TRACE) + format 0x088055cc Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088055f0 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088055f0 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805614 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805614 Data 53 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880564c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880564c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805670 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805670 Data 43 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880569c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880569c Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088056c0 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088056c0 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088056e4 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088056e4 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805708 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805708 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880572c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880572c Data 49 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805760 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805760 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805784 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805784 Data 25 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088057a0 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088057a0 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088057c4 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088057c4 Data 39 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088057ec Number 0 fmnasampleuarp.o(.TRACE) + format 0x088057ec Data 44 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805818 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805818 Data 72 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805860 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805860 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805884 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805884 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088058a8 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088058a8 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088058cc Number 0 fmnasampleuarp.o(.TRACE) + format 0x088058cc Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x088058f0 Number 0 fmnasampleuarp.o(.TRACE) + format 0x088058f0 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805914 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805914 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x08805938 Number 0 fmnasampleuarp.o(.TRACE) + format 0x08805938 Data 35 fmnasampleuarp.o(.TRACE) + __tagsym$$used 0x0880595c Number 0 fmnasampleuarp.o(.TRACE) + format 0x0880595c Data 35 fmnasampleuarp.o(.TRACE) + .TRACE 0x08805980 Section 285 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x08805980 Number 0 fmna_adv_platform.o(.TRACE) + format 0x08805980 Data 43 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x088059ac Number 0 fmna_adv_platform.o(.TRACE) + format 0x088059ac Data 51 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x088059e0 Number 0 fmna_adv_platform.o(.TRACE) + format 0x088059e0 Data 61 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x08805a20 Number 0 fmna_adv_platform.o(.TRACE) + format 0x08805a20 Data 61 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x08805a60 Number 0 fmna_adv_platform.o(.TRACE) + format 0x08805a60 Data 19 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x08805a74 Number 0 fmna_adv_platform.o(.TRACE) + format 0x08805a74 Data 18 fmna_adv_platform.o(.TRACE) + __tagsym$$used 0x08805a88 Number 0 fmna_adv_platform.o(.TRACE) + format 0x08805a88 Data 21 fmna_adv_platform.o(.TRACE) + .TRACE 0x08805aa0 Section 366 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805aa0 Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805aa0 Data 41 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805acc Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805acc Data 29 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805aec Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805aec Data 46 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805b1c Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805b1c Data 67 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805b60 Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805b60 Data 50 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805b94 Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805b94 Data 53 fmna_battery_platform.o(.TRACE) + __tagsym$$used 0x08805bcc Number 0 fmna_battery_platform.o(.TRACE) + format 0x08805bcc Data 66 fmna_battery_platform.o(.TRACE) + .TRACE 0x08805c10 Section 566 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805c10 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805c10 Data 50 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805c44 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805c44 Data 53 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805c7c Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805c7c Data 58 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805cb8 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805cb8 Data 55 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805cf0 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805cf0 Data 45 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d20 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d20 Data 26 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d3c Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d3c Data 21 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d54 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d54 Data 14 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d64 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d64 Data 6 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d6c Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d6c Data 14 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d7c Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d7c Data 14 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805d8c Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805d8c Data 31 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805dac Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805dac Data 31 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805dcc Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805dcc Data 16 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805ddc Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805ddc Data 16 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805dec Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805dec Data 35 fmna_connection_platform.o(.TRACE) + __tagsym$$used 0x08805e10 Number 0 fmna_connection_platform.o(.TRACE) + format 0x08805e10 Data 54 fmna_connection_platform.o(.TRACE) + .TRACE 0x08805e48 Section 919 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805e48 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805e48 Data 126 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805ec8 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805ec8 Data 92 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805f24 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805f24 Data 48 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805f54 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805f54 Data 47 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805f84 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805f84 Data 40 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805fac Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805fac Data 52 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805fe0 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805fe0 Data 18 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08805ff4 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08805ff4 Data 56 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x0880602c Number 0 fmna_dfu_platform.o(.TRACE) + format 0x0880602c Data 53 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08806064 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08806064 Data 85 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x088060bc Number 0 fmna_dfu_platform.o(.TRACE) + format 0x088060bc Data 62 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x088060fc Number 0 fmna_dfu_platform.o(.TRACE) + format 0x088060fc Data 51 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08806130 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08806130 Data 52 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x08806164 Number 0 fmna_dfu_platform.o(.TRACE) + format 0x08806164 Data 70 fmna_dfu_platform.o(.TRACE) + __tagsym$$used 0x088061ac Number 0 fmna_dfu_platform.o(.TRACE) + format 0x088061ac Data 51 fmna_dfu_platform.o(.TRACE) + .TRACE 0x088061e0 Section 800 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088061e0 Number 0 fmna_gap_platform.o(.TRACE) + format 0x088061e0 Data 57 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x0880621c Number 0 fmna_gap_platform.o(.TRACE) + format 0x0880621c Data 61 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x0880625c Number 0 fmna_gap_platform.o(.TRACE) + format 0x0880625c Data 61 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x0880629c Number 0 fmna_gap_platform.o(.TRACE) + format 0x0880629c Data 54 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088062d4 Number 0 fmna_gap_platform.o(.TRACE) + format 0x088062d4 Data 58 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x08806310 Number 0 fmna_gap_platform.o(.TRACE) + format 0x08806310 Data 58 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x0880634c Number 0 fmna_gap_platform.o(.TRACE) + format 0x0880634c Data 42 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x08806378 Number 0 fmna_gap_platform.o(.TRACE) + format 0x08806378 Data 43 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088063a4 Number 0 fmna_gap_platform.o(.TRACE) + format 0x088063a4 Data 45 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088063d4 Number 0 fmna_gap_platform.o(.TRACE) + format 0x088063d4 Data 52 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x08806408 Number 0 fmna_gap_platform.o(.TRACE) + format 0x08806408 Data 43 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x08806434 Number 0 fmna_gap_platform.o(.TRACE) + format 0x08806434 Data 53 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x0880646c Number 0 fmna_gap_platform.o(.TRACE) + format 0x0880646c Data 53 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088064a4 Number 0 fmna_gap_platform.o(.TRACE) + format 0x088064a4 Data 53 fmna_gap_platform.o(.TRACE) + __tagsym$$used 0x088064dc Number 0 fmna_gap_platform.o(.TRACE) + format 0x088064dc Data 36 fmna_gap_platform.o(.TRACE) + .TRACE 0x08806500 Section 1430 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806500 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806500 Data 43 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x0880652c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x0880652c Data 102 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806594 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806594 Data 42 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088065c0 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088065c0 Data 39 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088065e8 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088065e8 Data 39 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806610 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806610 Data 41 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x0880663c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x0880663c Data 67 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806680 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806680 Data 70 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088066c8 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088066c8 Data 98 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x0880672c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x0880672c Data 62 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x0880676c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x0880676c Data 24 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806784 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806784 Data 55 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088067bc Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088067bc Data 36 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088067e0 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088067e0 Data 34 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806804 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806804 Data 46 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806834 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806834 Data 35 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806858 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806858 Data 36 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x0880687c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x0880687c Data 84 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088068d0 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088068d0 Data 19 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088068e4 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088068e4 Data 33 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806908 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806908 Data 92 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806964 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806964 Data 93 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088069c4 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088069c4 Data 17 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x088069d8 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x088069d8 Data 49 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806a0c Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806a0c Data 51 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806a40 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806a40 Data 53 fmna_gatt_platform.o(.TRACE) + __tagsym$$used 0x08806a78 Number 0 fmna_gatt_platform.o(.TRACE) + format 0x08806a78 Data 30 fmna_gatt_platform.o(.TRACE) + .TRACE 0x08806a98 Section 292 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806a98 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806a98 Data 24 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806ab0 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806ab0 Data 49 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806ae4 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806ae4 Data 23 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806afc Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806afc Data 36 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806b20 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806b20 Data 24 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806b38 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806b38 Data 36 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806b5c Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806b5c Data 27 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806b78 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806b78 Data 27 fmna_malloc_platform.o(.TRACE) + __tagsym$$used 0x08806b94 Number 0 fmna_malloc_platform.o(.TRACE) + format 0x08806b94 Data 40 fmna_malloc_platform.o(.TRACE) + .TRACE 0x08806bbc Section 133 fmna_motion_detection_platform.o(.TRACE) + __tagsym$$used 0x08806bbc Number 0 fmna_motion_detection_platform.o(.TRACE) + format 0x08806bbc Data 39 fmna_motion_detection_platform.o(.TRACE) + __tagsym$$used 0x08806be4 Number 0 fmna_motion_detection_platform.o(.TRACE) + format 0x08806be4 Data 23 fmna_motion_detection_platform.o(.TRACE) + __tagsym$$used 0x08806bfc Number 0 fmna_motion_detection_platform.o(.TRACE) + format 0x08806bfc Data 41 fmna_motion_detection_platform.o(.TRACE) + __tagsym$$used 0x08806c28 Number 0 fmna_motion_detection_platform.o(.TRACE) + format 0x08806c28 Data 25 fmna_motion_detection_platform.o(.TRACE) + .TRACE 0x08806c44 Section 103 fmna_peer_manager.o(.TRACE) + __tagsym$$used 0x08806c44 Number 0 fmna_peer_manager.o(.TRACE) + format 0x08806c44 Data 37 fmna_peer_manager.o(.TRACE) + __tagsym$$used 0x08806c6c Number 0 fmna_peer_manager.o(.TRACE) + format 0x08806c6c Data 22 fmna_peer_manager.o(.TRACE) + __tagsym$$used 0x08806c84 Number 0 fmna_peer_manager.o(.TRACE) + format 0x08806c84 Data 39 fmna_peer_manager.o(.TRACE) + .TRACE 0x08806cac Section 798 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806cac Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806cac Data 37 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806cd4 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806cd4 Data 24 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806cec Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806cec Data 27 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806d08 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806d08 Data 35 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806d2c Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806d2c Data 43 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806d58 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806d58 Data 47 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806d88 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806d88 Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806da8 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806da8 Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806dc8 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806dc8 Data 56 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806e00 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806e00 Data 21 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806e18 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806e18 Data 39 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806e40 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806e40 Data 42 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806e6c Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806e6c Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806e8c Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806e8c Data 47 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806ebc Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806ebc Data 48 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806eec Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806eec Data 25 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806f08 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806f08 Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806f28 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806f28 Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806f48 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806f48 Data 30 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806f68 Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806f68 Data 52 fmna_sound_platform.o(.TRACE) + __tagsym$$used 0x08806f9c Number 0 fmna_sound_platform.o(.TRACE) + format 0x08806f9c Data 46 fmna_sound_platform.o(.TRACE) + .TRACE 0x08806fcc Section 555 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08806fcc Number 0 fmna_timer_platform.o(.TRACE) + format 0x08806fcc Data 59 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08807008 Number 0 fmna_timer_platform.o(.TRACE) + format 0x08807008 Data 57 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08807044 Number 0 fmna_timer_platform.o(.TRACE) + format 0x08807044 Data 62 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08807084 Number 0 fmna_timer_platform.o(.TRACE) + format 0x08807084 Data 41 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x088070b0 Number 0 fmna_timer_platform.o(.TRACE) + format 0x088070b0 Data 47 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x088070e0 Number 0 fmna_timer_platform.o(.TRACE) + format 0x088070e0 Data 51 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08807114 Number 0 fmna_timer_platform.o(.TRACE) + format 0x08807114 Data 57 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x08807150 Number 0 fmna_timer_platform.o(.TRACE) + format 0x08807150 Data 57 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x0880718c Number 0 fmna_timer_platform.o(.TRACE) + format 0x0880718c Data 64 fmna_timer_platform.o(.TRACE) + __tagsym$$used 0x088071cc Number 0 fmna_timer_platform.o(.TRACE) + format 0x088071cc Data 43 fmna_timer_platform.o(.TRACE) + .TRACE 0x088071f8 Section 1675 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088071f8 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088071f8 Data 26 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807214 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807214 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807238 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807238 Data 27 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807254 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807254 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807278 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807278 Data 29 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807298 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807298 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088072bc Number 0 coreuarpaccessory.o(.TRACE) + format 0x088072bc Data 30 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088072dc Number 0 coreuarpaccessory.o(.TRACE) + format 0x088072dc Data 44 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807308 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807308 Data 47 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807338 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807338 Data 41 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807364 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807364 Data 13 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807374 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807374 Data 34 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807398 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807398 Data 37 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088073c0 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088073c0 Data 37 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088073e8 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088073e8 Data 28 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807404 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807404 Data 43 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807430 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807430 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807454 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807454 Data 38 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x0880747c Number 0 coreuarpaccessory.o(.TRACE) + format 0x0880747c Data 42 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088074a8 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088074a8 Data 22 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088074c0 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088074c0 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088074e4 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088074e4 Data 32 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807504 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807504 Data 37 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x0880752c Number 0 coreuarpaccessory.o(.TRACE) + format 0x0880752c Data 38 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807554 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807554 Data 32 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807574 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807574 Data 17 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807588 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807588 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088075ac Number 0 coreuarpaccessory.o(.TRACE) + format 0x088075ac Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088075d0 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088075d0 Data 45 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807600 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807600 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807624 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807624 Data 46 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807654 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807654 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807678 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807678 Data 38 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088076a0 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088076a0 Data 39 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088076c8 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088076c8 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088076ec Number 0 coreuarpaccessory.o(.TRACE) + format 0x088076ec Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807710 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807710 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807734 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807734 Data 62 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807774 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807774 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807798 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807798 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088077bc Number 0 coreuarpaccessory.o(.TRACE) + format 0x088077bc Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x088077e0 Number 0 coreuarpaccessory.o(.TRACE) + format 0x088077e0 Data 35 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807804 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807804 Data 19 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807818 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807818 Data 22 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807830 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807830 Data 22 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807848 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807848 Data 21 coreuarpaccessory.o(.TRACE) + __tagsym$$used 0x08807860 Number 0 coreuarpaccessory.o(.TRACE) + format 0x08807860 Data 35 coreuarpaccessory.o(.TRACE) + .TRACE 0x08807884 Section 3374 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807884 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807884 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088078a8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088078a8 Data 33 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088078cc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088078cc Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088078f0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088078f0 Data 36 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807914 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807914 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807938 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807938 Data 45 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807968 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807968 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880798c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880798c Data 59 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088079c8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088079c8 Data 59 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807a04 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807a04 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807a28 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807a28 Data 22 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807a40 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807a40 Data 37 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807a68 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807a68 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807a8c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807a8c Data 39 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ab4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ab4 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ad8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ad8 Data 33 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807afc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807afc Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807b20 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807b20 Data 34 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807b44 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807b44 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807b68 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807b68 Data 59 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ba4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ba4 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807bc8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807bc8 Data 60 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807c04 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807c04 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807c28 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807c28 Data 41 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807c54 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807c54 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807c78 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807c78 Data 31 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807c98 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807c98 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807cbc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807cbc Data 36 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ce0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ce0 Data 54 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807d18 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807d18 Data 79 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807d68 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807d68 Data 54 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807da0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807da0 Data 17 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807db4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807db4 Data 61 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807df4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807df4 Data 48 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807e24 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807e24 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807e48 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807e48 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807e6c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807e6c Data 42 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807e98 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807e98 Data 31 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807eb8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807eb8 Data 25 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ed4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ed4 Data 22 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807eec Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807eec Data 15 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807efc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807efc Data 27 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807f18 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807f18 Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807f30 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807f30 Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807f48 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807f48 Data 31 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807f68 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807f68 Data 31 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807f88 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807f88 Data 43 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807fb4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807fb4 Data 22 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807fcc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807fcc Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08807ff0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08807ff0 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808014 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808014 Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880802c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880802c Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808044 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808044 Data 23 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880805c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880805c Data 23 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808074 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808074 Data 58 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088080b0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088080b0 Data 66 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088080f4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088080f4 Data 88 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880814c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880814c Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808170 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808170 Data 34 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808194 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808194 Data 52 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088081c8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088081c8 Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088081e0 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088081e0 Data 17 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088081f4 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088081f4 Data 15 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808204 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808204 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808228 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808228 Data 58 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808264 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808264 Data 66 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088082a8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088082a8 Data 94 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808308 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808308 Data 66 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880834c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880834c Data 90 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088083a8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088083a8 Data 89 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808404 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808404 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808428 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808428 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880844c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880844c Data 43 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808478 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808478 Data 46 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088084a8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088084a8 Data 47 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088084d8 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088084d8 Data 34 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x088084fc Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x088084fc Data 48 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880852c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880852c Data 18 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808540 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808540 Data 24 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x08808558 Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x08808558 Data 35 coreuarpplatformaccessory.o(.TRACE) + __tagsym$$used 0x0880857c Number 0 coreuarpplatformaccessory.o(.TRACE) + format 0x0880857c Data 54 coreuarpplatformaccessory.o(.TRACE) + .TRACE 0x088085b4 Section 44 coreuarpplatformrtk.o(.TRACE) + __tagsym$$used 0x088085b4 Number 0 coreuarpplatformrtk.o(.TRACE) + format 0x088085b4 Data 25 coreuarpplatformrtk.o(.TRACE) + __tagsym$$used 0x088085d0 Number 0 coreuarpplatformrtk.o(.TRACE) + format 0x088085d0 Data 16 coreuarpplatformrtk.o(.TRACE) + .TRACE 0x088085e0 Section 403 gap_config.o(.TRACE) + __tagsym$$used 0x088085e0 Number 0 gap_config.o(.TRACE) + format 0x088085e0 Data 250 gap_config.o(.TRACE) + __tagsym$$used 0x088086dc Number 0 gap_config.o(.TRACE) + format 0x088086dc Data 102 gap_config.o(.TRACE) + __tagsym$$used 0x08808744 Number 0 gap_config.o(.TRACE) + format 0x08808744 Data 47 gap_config.o(.TRACE) + .TRACE 0x08808774 Section 24 gap_lib.o(.TRACE) + __tagsym$$used 0x08808774 Number 0 gap_lib.o(.TRACE) + format 0x08808774 Data 24 gap_lib.o(.TRACE) + .TRACE 0x0880878c Section 206 key_crypto.o(.TRACE) + __tagsym$$used 0x0880878c Number 0 key_crypto.o(.TRACE) + format 0x0880878c Data 46 key_crypto.o(.TRACE) + __tagsym$$used 0x088087bc Number 0 key_crypto.o(.TRACE) + format 0x088087bc Data 33 key_crypto.o(.TRACE) + __tagsym$$used 0x088087e0 Number 0 key_crypto.o(.TRACE) + format 0x088087e0 Data 29 key_crypto.o(.TRACE) + __tagsym$$used 0x08808800 Number 0 key_crypto.o(.TRACE) + format 0x08808800 Data 28 key_crypto.o(.TRACE) + __tagsym$$used 0x0880881c Number 0 key_crypto.o(.TRACE) + format 0x0880881c Data 29 key_crypto.o(.TRACE) + __tagsym$$used 0x0880883c Number 0 key_crypto.o(.TRACE) + format 0x0880883c Data 30 key_crypto.o(.TRACE) + + Global Symbols + + Symbol Name Value Ov Type Size Object(Section) + + BuildAttributes$$THM_ISAv3M$S$PE$A:L22$X:L11$S22$IEEE1$IW$USESV6$~STKCKD$USESV7$~SHL$OTIME$ROPI$IEEEJ$EBA8$UX$STANDARDLIB$REQ8$PRES8$EABIv2 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_A$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_A$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$RO$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$RW$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$ZI$$Length 0x00000000 Number 0 anon$$obj.o ABSOLUTE + __ARM_use_no_argv 0x00000000 Number 0 main.o ABSOLUTE + _printf_flags 0x00000000 Number 0 printf_stubs.o ABSOLUTE + _printf_return_value 0x00000000 Number 0 printf_stubs.o ABSOLUTE + _printf_sizespec 0x00000000 Number 0 printf_stubs.o ABSOLUTE + _printf_widthprec 0x00000000 Number 0 printf_stubs.o ABSOLUTE + __ARM_exceptions_init - Undefined Weak Reference + __alloca_initialize - Undefined Weak Reference + __arm_preinit_ - Undefined Weak Reference + __cpp_initialize__aeabi_ - Undefined Weak Reference + __scatterload - Undefined Weak Reference + __sigvec_lookup - Undefined Weak Reference + _atexit_init - Undefined Weak Reference + _clock_init - Undefined Weak Reference + _fp_trap_init - Undefined Weak Reference + _get_lc_collate - Undefined Weak Reference + _get_lc_monetary - Undefined Weak Reference + _get_lc_time - Undefined Weak Reference + _getenv_init - Undefined Weak Reference + _handle_redirection - Undefined Weak Reference + _init_alloc - Undefined Weak Reference + _init_user_alloc - Undefined Weak Reference + _initio - Undefined Weak Reference + _printf_mbtowc - Undefined Weak Reference + _printf_wc - Undefined Weak Reference + _signal_init - Undefined Weak Reference + Image$$OVERLAY_A$$RO$$Length 0x000000d8 Number 0 anon$$obj.o ABSOLUTE + Image$$RAM_VECTOR_TABLE$$RO$$Length 0x000000e8 Number 0 anon$$obj.o ABSOLUTE + __Vectors_Size 0x000000e8 Number 0 startup_rtl876x.o ABSOLUTE + vAssertHandler 0x00000209 Thumb Code 0 ROM.lib ABSOLUTE + ulSetInterruptMaskFromISR 0x0000024d Thumb Code 0 ROM.lib ABSOLUTE + vClearInterruptMaskFromISR 0x00000255 Thumb Code 0 ROM.lib ABSOLUTE + WDG_SystemReset 0x0000029d Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memcpy4 0x000002a9 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memcpy8 0x000002a9 Thumb Code 0 ROM.lib ABSOLUTE + Image$$RAM_DATA_ON$$RW$$Length 0x00000348 Number 0 anon$$obj.o ABSOLUTE + Image$$RAM_DATA_ON$$RO$$Length 0x00000f00 Number 0 anon$$obj.o ABSOLUTE + Image$$RAM_DATA_ON$$ZI$$Length 0x00001f14 Number 0 anon$$obj.o ABSOLUTE + RamVectorTableInit 0x000034d1 Thumb Code 0 ROM.lib ABSOLUTE + RamVectorTableUpdate 0x000034f7 Thumb Code 0 ROM.lib ABSOLUTE + LOGUARTDriverInit 0x000037ed Thumb Code 0 ROM.lib ABSOLUTE + DumpRawMemory 0x000043ab Thumb Code 0 ROM.lib ABSOLUTE + dump_raw_memory_all 0x00004519 Thumb Code 0 ROM.lib ABSOLUTE + hardfault_print_buffered_log 0x00004573 Thumb Code 0 ROM.lib ABSOLUTE + ROM_Default_Handler 0x000047e7 Thumb Code 0 ROM.lib ABSOLUTE + SystemCall 0x0000491b Thumb Code 0 ROM.lib ABSOLUTE + SystemCall_Stack 0x00004927 Thumb Code 0 ROM.lib ABSOLUTE + update_ram_layout 0x00004a79 Thumb Code 0 ROM.lib ABSOLUTE + get_active_ota_bank_addr 0x000053a5 Thumb Code 0 ROM.lib ABSOLUTE + btxfcs 0x000054ed Thumb Code 0 ROM.lib ABSOLUTE + PPB_BufSwitch 0x00005665 Thumb Code 0 ROM.lib ABSOLUTE + PPB_Init 0x00005689 Thumb Code 0 ROM.lib ABSOLUTE + PPB_Uninit 0x000056dd Thumb Code 0 ROM.lib ABSOLUTE + PPB_Init_DLPS_Restore 0x00005701 Thumb Code 0 ROM.lib ABSOLUTE + PPB_Write 0x00005709 Thumb Code 0 ROM.lib ABSOLUTE + PPB_ClearOutputBuffer 0x000057db Thumb Code 0 ROM.lib ABSOLUTE + LogUartTxChar 0x00005811 Thumb Code 0 ROM.lib ABSOLUTE + log_timestamp_get 0x00005853 Thumb Code 0 ROM.lib ABSOLUTE + VSnprintf 0x00005893 Thumb Code 0 ROM.lib ABSOLUTE + log_direct 0x00005a07 Thumb Code 0 ROM.lib ABSOLUTE + log_buffer 0x00005aa9 Thumb Code 0 ROM.lib ABSOLUTE + log_index 0x00005bcd Thumb Code 0 ROM.lib ABSOLUTE + log_snoop 0x00005cdf Thumb Code 0 ROM.lib ABSOLUTE + trace_bdaddr 0x00005ddf Thumb Code 0 ROM.lib ABSOLUTE + trace_string 0x00005e6b Thumb Code 0 ROM.lib ABSOLUTE + trace_binary 0x00005f07 Thumb Code 0 ROM.lib ABSOLUTE + LogBufferLowerStack 0x00005f9f Thumb Code 0 ROM.lib ABSOLUTE + LogBufferLowerStackData 0x000060c5 Thumb Code 0 ROM.lib ABSOLUTE + log_module_trace_init 0x000061a3 Thumb Code 0 ROM.lib ABSOLUTE + log_module_trace_set 0x000061d3 Thumb Code 0 ROM.lib ABSOLUTE + log_module_bitmap_trace_set 0x0000621f Thumb Code 0 ROM.lib ABSOLUTE + LogUartDMAStart 0x00006323 Thumb Code 0 ROM.lib ABSOLUTE + LogDMA_SM_Dispatch 0x00006335 Thumb Code 0 ROM.lib ABSOLUTE + LogUartDMAInit 0x000063bd Thumb Code 0 ROM.lib ABSOLUTE + LogUartDMAIdleHook 0x000064b1 Thumb Code 0 ROM.lib ABSOLUTE + log_pm_check 0x0000651f Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_encrypt128_use_dma 0x0000675d Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_decrypt128_use_dma 0x000067a1 Thumb Code 0 ROM.lib ABSOLUTE + aes128_ecb_encrypt 0x000067e5 Thumb Code 0 ROM.lib ABSOLUTE + aes128_ecb_decrypt 0x00006841 Thumb Code 0 ROM.lib ABSOLUTE + aes128_ecb_encrypt_msb2lsb 0x0000689b Thumb Code 0 ROM.lib ABSOLUTE + aes128_ecb_decrypt_msb2lsb 0x000068b3 Thumb Code 0 ROM.lib ABSOLUTE + aes256_ecb_encrypt 0x000068cb Thumb Code 0 ROM.lib ABSOLUTE + aes256_ecb_decrypt 0x00006927 Thumb Code 0 ROM.lib ABSOLUTE + aes256_ecb_encrypt_msb2lsb 0x00006981 Thumb Code 0 ROM.lib ABSOLUTE + aes256_ecb_decrypt_msb2lsb 0x00006999 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_decrypt_16byte 0x000069ed Thumb Code 0 ROM.lib ABSOLUTE + ftl_ioctl 0x000075d3 Thumb Code 0 ROM.lib ABSOLUTE + ftl_load 0x00007b1f Thumb Code 0 ROM.lib ABSOLUTE + ftl_save 0x00007b33 Thumb Code 0 ROM.lib ABSOLUTE + ftl_init 0x00007c45 Thumb Code 0 ROM.lib ABSOLUTE + hardfault_dump 0x00007df1 Thumb Code 0 ROM.lib ABSOLUTE + flash_dump_flash_info 0x0000805f Thumb Code 0 ROM.lib ABSOLUTE + flash_get_flash_exist 0x000080b3 Thumb Code 0 ROM.lib ABSOLUTE + flash_get_bank_addr 0x000080b9 Thumb Code 0 ROM.lib ABSOLUTE + flash_get_bank_size 0x0000813b Thumb Code 0 ROM.lib ABSOLUTE + flash_erase_locked 0x000081a1 Thumb Code 0 ROM.lib ABSOLUTE + flash_ioctl 0x000081f7 Thumb Code 0 ROM.lib ABSOLUTE + flash_write_locked 0x00008601 Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_write_locked 0x00008629 Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_write_buffer_locked 0x0000864b Thumb Code 0 ROM.lib ABSOLUTE + flash_read_locked 0x00008671 Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_read_locked 0x00008699 Thumb Code 0 ROM.lib ABSOLUTE + flash_split_read_locked 0x000086b7 Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_dma_read_locked 0x000086e1 Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_seq_trans_dma_read_locked 0x00008709 Thumb Code 0 ROM.lib ABSOLUTE + flash_try_high_speed 0x00008731 Thumb Code 0 ROM.lib ABSOLUTE + flash_get_block_protect_locked 0x000088f1 Thumb Code 0 ROM.lib ABSOLUTE + flash_set_block_protect_locked 0x00008917 Thumb Code 0 ROM.lib ABSOLUTE + flash_sw_protect_unlock_by_addr_locked 0x0000893d Thumb Code 0 ROM.lib ABSOLUTE + crc8EtsGen 0x000089cd Thumb Code 0 ROM.lib ABSOLUTE + crc8EtsCheck 0x000089ed Thumb Code 0 ROM.lib ABSOLUTE + set_hci_mode_flag 0x00008a1d Thumb Code 0 ROM.lib ABSOLUTE + check_hci_mode_flag 0x00008a47 Thumb Code 0 ROM.lib ABSOLUTE + check_image_chksum 0x00008a5d Thumb Code 0 ROM.lib ABSOLUTE + check_header_valid 0x00008a83 Thumb Code 0 ROM.lib ABSOLUTE + get_header_addr_by_img_id 0x00008ae3 Thumb Code 0 ROM.lib ABSOLUTE + get_active_bank_image_size_by_img_id 0x00008b3f Thumb Code 0 ROM.lib ABSOLUTE + is_ota_support_bank_switch 0x00008b7b Thumb Code 0 ROM.lib ABSOLUTE + get_temp_ota_bank_addr_by_img_id 0x00008b95 Thumb Code 0 ROM.lib ABSOLUTE + get_temp_ota_bank_size_by_img_id 0x00008c07 Thumb Code 0 ROM.lib ABSOLUTE + get_active_bank_image_version 0x00008c73 Thumb Code 0 ROM.lib ABSOLUTE + platform_random 0x00008d3f Thumb Code 0 ROM.lib ABSOLUTE + flash_erase 0x00009fcf Thumb Code 0 ROM.lib ABSOLUTE + flash_set_bit 0x0000a559 Thumb Code 0 ROM.lib ABSOLUTE + flash_get_bit 0x0000a561 Thumb Code 0 ROM.lib ABSOLUTE + flash_write 0x0000a56d Thumb Code 0 ROM.lib ABSOLUTE + flash_auto_write 0x0000a875 Thumb Code 0 ROM.lib ABSOLUTE + power_manager_get_unit_status 0x0000d0c9 Thumb Code 0 ROM.lib ABSOLUTE + power_manager_suspend_all 0x0000d207 Thumb Code 0 ROM.lib ABSOLUTE + power_manager_resume_all 0x0000d211 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_set_power_mode 0x0000d755 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_get_power_mode 0x0000d769 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_get_error_code 0x0000d76f Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_get_refuse_reason 0x0000d775 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_get_statistics 0x0000d78f Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_get_wakeup_reason 0x0000d7b9 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_register_callback_func 0x0000d7c9 Thumb Code 0 ROM.lib ABSOLUTE + platform_pm_stop_all_non_excluded_timer 0x0000d8cb Thumb Code 0 ROM.lib ABSOLUTE + platform_rtc_get_counter 0x0000e81b Thumb Code 0 ROM.lib ABSOLUTE + vListInitialise 0x0000e885 Thumb Code 0 ROM.lib ABSOLUTE + vListInitialiseItem 0x0000e89b Thumb Code 0 ROM.lib ABSOLUTE + vListInsertEnd 0x0000e8a1 Thumb Code 0 ROM.lib ABSOLUTE + vListInsert 0x0000e8b9 Thumb Code 0 ROM.lib ABSOLUTE + uxListRemove 0x0000e8e9 Thumb Code 0 ROM.lib ABSOLUTE + xQueueGenericReset 0x0000e911 Thumb Code 0 ROM.lib ABSOLUTE + xQueueGenericCreate 0x0000e985 Thumb Code 0 ROM.lib ABSOLUTE + xQueueGenericSend 0x0000eab3 Thumb Code 0 ROM.lib ABSOLUTE + xQueueCreateMutex 0x0000ebed Thumb Code 0 ROM.lib ABSOLUTE + xQueueGetMutexHolder 0x0000ec11 Thumb Code 0 ROM.lib ABSOLUTE + xQueueGetMutexHolderFromISR 0x0000ec2d Thumb Code 0 ROM.lib ABSOLUTE + xQueueGiveMutexRecursive 0x0000ec4d Thumb Code 0 ROM.lib ABSOLUTE + xQueueSemaphoreTake 0x0000ec85 Thumb Code 0 ROM.lib ABSOLUTE + xQueueTakeMutexRecursive 0x0000edef Thumb Code 0 ROM.lib ABSOLUTE + xQueueCreateCountingSemaphore 0x0000ee29 Thumb Code 0 ROM.lib ABSOLUTE + xQueueGenericSendFromISR 0x0000ee5f Thumb Code 0 ROM.lib ABSOLUTE + xQueueGiveFromISR 0x0000eefd Thumb Code 0 ROM.lib ABSOLUTE + xQueueReceive 0x0000efaf Thumb Code 0 ROM.lib ABSOLUTE + xQueuePeek 0x0000f0c7 Thumb Code 0 ROM.lib ABSOLUTE + xQueueReceiveFromISR 0x0000f1f1 Thumb Code 0 ROM.lib ABSOLUTE + xQueuePeekFromISR 0x0000f26f Thumb Code 0 ROM.lib ABSOLUTE + uxQueueMessagesWaiting 0x0000f2d3 Thumb Code 0 ROM.lib ABSOLUTE + uxQueueSpacesAvailable 0x0000f2f3 Thumb Code 0 ROM.lib ABSOLUTE + uxQueueMessagesWaitingFromISR 0x0000f317 Thumb Code 0 ROM.lib ABSOLUTE + vQueueDelete 0x0000f32d Thumb Code 0 ROM.lib ABSOLUTE + uxQueueGetQueueNumber 0x0000f347 Thumb Code 0 ROM.lib ABSOLUTE + vQueueSetQueueNumber 0x0000f34b Thumb Code 0 ROM.lib ABSOLUTE + ucQueueGetQueueType 0x0000f34f Thumb Code 0 ROM.lib ABSOLUTE + xQueueIsQueueEmptyFromISR 0x0000f355 Thumb Code 0 ROM.lib ABSOLUTE + xQueueIsQueueFullFromISR 0x0000f375 Thumb Code 0 ROM.lib ABSOLUTE + vQueueWaitForMessageRestricted 0x0000f395 Thumb Code 0 ROM.lib ABSOLUTE + xTaskCreate 0x0000f51b Thumb Code 0 ROM.lib ABSOLUTE + vTaskDelete 0x0000f5dd Thumb Code 0 ROM.lib ABSOLUTE + xTaskIncrementTick 0x0000f683 Thumb Code 0 ROM.lib ABSOLUTE + xTaskResumeAll 0x0000f741 Thumb Code 0 ROM.lib ABSOLUTE + vTaskSuspendAll 0x0000f85b Thumb Code 0 ROM.lib ABSOLUTE + vTaskDelayUntil 0x0000f865 Thumb Code 0 ROM.lib ABSOLUTE + vTaskDelay 0x0000f8d3 Thumb Code 0 ROM.lib ABSOLUTE + eTaskGetState 0x0000f907 Thumb Code 0 ROM.lib ABSOLUTE + uxTaskPriorityGet 0x0000f96b Thumb Code 0 ROM.lib ABSOLUTE + uxTaskPriorityGetFromISR 0x0000f985 Thumb Code 0 ROM.lib ABSOLUTE + vTaskPrioritySet 0x0000f99f Thumb Code 0 ROM.lib ABSOLUTE + vTaskSwitchContext 0x0000fa33 Thumb Code 0 ROM.lib ABSOLUTE + vTaskSuspend 0x0000fadb Thumb Code 0 ROM.lib ABSOLUTE + vTaskResume 0x0000fb8f Thumb Code 0 ROM.lib ABSOLUTE + xTaskResumeFromISR 0x0000fc1d Thumb Code 0 ROM.lib ABSOLUTE + vTaskStartScheduler 0x0000fc87 Thumb Code 0 ROM.lib ABSOLUTE + vTaskEndScheduler 0x0000fce7 Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetTickCount2 0x0000fcf7 Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetTickCount 0x0000fcfd Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetTickCountFromISR 0x0000fd03 Thumb Code 0 ROM.lib ABSOLUTE + uxTaskGetNumberOfTasks 0x0000fd09 Thumb Code 0 ROM.lib ABSOLUTE + pcTaskGetName 0x0000fd0f Thumb Code 0 ROM.lib ABSOLUTE + vTaskGetInfo 0x0000fd33 Thumb Code 0 ROM.lib ABSOLUTE + uxTaskGetSystemState 0x0000fdfb Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetIdleTaskHandle 0x0000fe85 Thumb Code 0 ROM.lib ABSOLUTE + vTaskPlaceOnEventList 0x0000fe9f Thumb Code 0 ROM.lib ABSOLUTE + vTaskPlaceOnUnorderedEventList 0x0000fec9 Thumb Code 0 ROM.lib ABSOLUTE + vTaskPlaceOnEventListRestricted 0x0000ff0f Thumb Code 0 ROM.lib ABSOLUTE + xTaskRemoveFromEventList 0x0000ff43 Thumb Code 0 ROM.lib ABSOLUTE + vTaskRemoveFromUnorderedEventList 0x0000ffa7 Thumb Code 0 ROM.lib ABSOLUTE + vTaskSetTimeOutState 0x0001003d Thumb Code 0 ROM.lib ABSOLUTE + vTaskInternalSetTimeOutState 0x0001005f Thumb Code 0 ROM.lib ABSOLUTE + xTaskCheckForTimeOut 0x0001006b Thumb Code 0 ROM.lib ABSOLUTE + vTaskMissedYield 0x000100d1 Thumb Code 0 ROM.lib ABSOLUTE + uxTaskGetTaskNumber 0x000100d9 Thumb Code 0 ROM.lib ABSOLUTE + vTaskSetTaskNumber 0x000100e1 Thumb Code 0 ROM.lib ABSOLUTE + uxTaskGetStackHighWaterMark 0x000100e9 Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetCurrentTaskHandle 0x000100fb Thumb Code 0 ROM.lib ABSOLUTE + xTaskGetSchedulerState 0x00010101 Thumb Code 0 ROM.lib ABSOLUTE + xTaskPriorityInherit 0x0001011b Thumb Code 0 ROM.lib ABSOLUTE + xTaskPriorityDisinherit 0x0001018b Thumb Code 0 ROM.lib ABSOLUTE + vTaskPriorityDisinheritAfterTimeout 0x000101fb Thumb Code 0 ROM.lib ABSOLUTE + uxTaskResetEventItemValue 0x0001027b Thumb Code 0 ROM.lib ABSOLUTE + pvTaskIncrementMutexHeldCount 0x0001028f Thumb Code 0 ROM.lib ABSOLUTE + ulTaskNotifyTake 0x000102a3 Thumb Code 0 ROM.lib ABSOLUTE + xTaskNotifyWait 0x000102fd Thumb Code 0 ROM.lib ABSOLUTE + xTaskGenericNotify 0x00010371 Thumb Code 0 ROM.lib ABSOLUTE + xTaskGenericNotifyFromISR 0x00010441 Thumb Code 0 ROM.lib ABSOLUTE + vTaskNotifyGiveFromISR 0x00010511 Thumb Code 0 ROM.lib ABSOLUTE + xTaskNotifyStateClear 0x0001059f Thumb Code 0 ROM.lib ABSOLUTE + vTaskStatusDump 0x000105c9 Thumb Code 0 ROM.lib ABSOLUTE + xTimerGenericCommand 0x000108e1 Thumb Code 0 ROM.lib ABSOLUTE + xTimerCreateTimerTask 0x00010b15 Thumb Code 0 ROM.lib ABSOLUTE + xTimerCreate 0x00010b5d Thumb Code 0 ROM.lib ABSOLUTE + xTimerGetTimerDaemonTaskHandle 0x00010bd9 Thumb Code 0 ROM.lib ABSOLUTE + xTimerGetPeriod 0x00010bf1 Thumb Code 0 ROM.lib ABSOLUTE + vTimerSetReloadMode 0x00010c07 Thumb Code 0 ROM.lib ABSOLUTE + xTimerGetExpiryTime 0x00010c39 Thumb Code 0 ROM.lib ABSOLUTE + pcTimerGetName 0x00010c4f Thumb Code 0 ROM.lib ABSOLUTE + vTimerGetNextTimeoutItem 0x00010c65 Thumb Code 0 ROM.lib ABSOLUTE + xTimerGetAutoReload 0x00010ca1 Thumb Code 0 ROM.lib ABSOLUTE + xTimerIsTimerActive 0x00010cab Thumb Code 0 ROM.lib ABSOLUTE + xTimerIsTimerActiveFromISR 0x00010cd5 Thumb Code 0 ROM.lib ABSOLUTE + pvTimerGetTimerID 0x00010d01 Thumb Code 0 ROM.lib ABSOLUTE + vTimerSetTimerID 0x00010d1f Thumb Code 0 ROM.lib ABSOLUTE + xTimerPendFunctionCallFromISR 0x00010d3f Thumb Code 0 ROM.lib ABSOLUTE + xTimerPendFunctionCall 0x00010d5f Thumb Code 0 ROM.lib ABSOLUTE + uxTimerGetTimerNumber 0x00010d99 Thumb Code 0 ROM.lib ABSOLUTE + vTimerSetTimerNumber 0x00010d9d Thumb Code 0 ROM.lib ABSOLUTE + dumpAllUsedTimer 0x00010daf Thumb Code 0 ROM.lib ABSOLUTE + pxPortInitialiseStack 0x00010fb9 Thumb Code 0 ROM.lib ABSOLUTE + xPortStartScheduler 0x0001100b Thumb Code 0 ROM.lib ABSOLUTE + vPortEndScheduler 0x00011033 Thumb Code 0 ROM.lib ABSOLUTE + vPortYield 0x0001104d Thumb Code 0 ROM.lib ABSOLUTE + vPortEnterCritical 0x0001105f Thumb Code 0 ROM.lib ABSOLUTE + vPortExitCritical 0x00011081 Thumb Code 0 ROM.lib ABSOLUTE + rtlEnterCritical 0x000110c5 Thumb Code 0 ROM.lib ABSOLUTE + rtlExitCritical 0x000110e1 Thumb Code 0 ROM.lib ABSOLUTE + vTimerCreateFailedHook 0x000111a7 Thumb Code 0 ROM.lib ABSOLUTE + pvPortMalloc 0x000113a3 Thumb Code 0 ROM.lib ABSOLUTE + pvPortMalloc_auto_type 0x000114d3 Thumb Code 0 ROM.lib ABSOLUTE + vPortFree 0x00011505 Thumb Code 0 ROM.lib ABSOLUTE + xPortGetFreeHeapSize 0x00011585 Thumb Code 0 ROM.lib ABSOLUTE + xPortGetMinimumEverFreeHeapSize 0x000115c7 Thumb Code 0 ROM.lib ABSOLUTE + vPortInitialiseBlocks 0x000115d1 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_init 0x00011dff Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_cpu_operate 0x00011f6d Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_set_dma_tx_done 0x00011f79 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_set_dma_rx_done 0x00011f7f Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_dma_operate 0x00011f85 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_dma_interrupt_disable 0x0001210b Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_is_dma_rx_done 0x000121af Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_is_dma_tx_done 0x000121b5 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_dma_done 0x000121bb Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_set_dma_move_src 0x000121c5 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_set_dma_move_dst 0x000121e5 Thumb Code 0 ROM.lib ABSOLUTE + hw_aes_set_dma_carry_size 0x000121eb Thumb Code 0 ROM.lib ABSOLUTE + aes_cmac_inverse 0x0001235f Thumb Code 0 ROM.lib ABSOLUTE + get_secure_reg_cfg_val 0x00012417 Thumb Code 0 ROM.lib ABSOLUTE + Pinmux_Deinit_rom 0x0001254b Thumb Code 0 ROM.lib ABSOLUTE + WDG_ClockEnable 0x00012959 Thumb Code 0 ROM.lib ABSOLUTE + WDG_Config 0x00012977 Thumb Code 0 ROM.lib ABSOLUTE + WDG_Enable 0x000129bb Thumb Code 0 ROM.lib ABSOLUTE + WDG_Disable 0x000129d5 Thumb Code 0 ROM.lib ABSOLUTE + WDG_Restart 0x000129ef Thumb Code 0 ROM.lib ABSOLUTE + reset_reason_get 0x00012b71 Thumb Code 0 ROM.lib ABSOLUTE + os_mem_alloc_intern 0x00012c31 Thumb Code 0 ROM.lib ABSOLUTE + os_mem_zalloc_intern 0x00012c8b Thumb Code 0 ROM.lib ABSOLUTE + os_mem_aligned_alloc_intern 0x00012ced Thumb Code 0 ROM.lib ABSOLUTE + os_mem_free 0x00012d4d Thumb Code 0 ROM.lib ABSOLUTE + os_mem_aligned_free 0x00012d69 Thumb Code 0 ROM.lib ABSOLUTE + os_mem_peek 0x00012d85 Thumb Code 0 ROM.lib ABSOLUTE + os_mem_check_heap_usage 0x00012da7 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_queue_create_intern 0x00012de1 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_queue_delete_intern 0x00012e39 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_queue_peek_intern 0x00012e83 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_send_intern 0x00012ed7 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_recv_intern 0x00012f33 Thumb Code 0 ROM.lib ABSOLUTE + os_msg_peek_intern 0x00012f91 Thumb Code 0 ROM.lib ABSOLUTE + os_queue_init 0x00013011 Thumb Code 0 ROM.lib ABSOLUTE + os_queue_in 0x0001301b Thumb Code 0 ROM.lib ABSOLUTE + os_queue_out 0x0001304b Thumb Code 0 ROM.lib ABSOLUTE + os_queue_peek 0x0001307f Thumb Code 0 ROM.lib ABSOLUTE + os_queue_insert 0x00013083 Thumb Code 0 ROM.lib ABSOLUTE + os_queue_delete 0x000130c3 Thumb Code 0 ROM.lib ABSOLUTE + os_systick_handler 0x00013131 Thumb Code 0 ROM.lib ABSOLUTE + os_delay 0x00013147 Thumb Code 0 ROM.lib ABSOLUTE + os_sys_time_get 0x00013163 Thumb Code 0 ROM.lib ABSOLUTE + os_sys_tick_get 0x00013181 Thumb Code 0 ROM.lib ABSOLUTE + os_sys_tick_increase 0x0001319f Thumb Code 0 ROM.lib ABSOLUTE + os_sched_start 0x000131c3 Thumb Code 0 ROM.lib ABSOLUTE + os_sched_stop 0x000131e1 Thumb Code 0 ROM.lib ABSOLUTE + os_sched_suspend 0x000131ff Thumb Code 0 ROM.lib ABSOLUTE + os_sched_resume 0x0001321d Thumb Code 0 ROM.lib ABSOLUTE + os_sched_is_start 0x0001323b Thumb Code 0 ROM.lib ABSOLUTE + os_sched_state_get 0x00013259 Thumb Code 0 ROM.lib ABSOLUTE + os_vector_table_update 0x00013277 Thumb Code 0 ROM.lib ABSOLUTE + os_init 0x0001328d Thumb Code 0 ROM.lib ABSOLUTE + os_lock 0x000132d9 Thumb Code 0 ROM.lib ABSOLUTE + os_unlock 0x000132f5 Thumb Code 0 ROM.lib ABSOLUTE + os_sem_create 0x00013311 Thumb Code 0 ROM.lib ABSOLUTE + os_sem_delete 0x0001333d Thumb Code 0 ROM.lib ABSOLUTE + os_sem_take 0x00013361 Thumb Code 0 ROM.lib ABSOLUTE + os_sem_give 0x00013389 Thumb Code 0 ROM.lib ABSOLUTE + os_mutex_create 0x000133ad Thumb Code 0 ROM.lib ABSOLUTE + os_mutex_delete 0x000133d1 Thumb Code 0 ROM.lib ABSOLUTE + os_mutex_take 0x000133f5 Thumb Code 0 ROM.lib ABSOLUTE + os_mutex_give 0x0001341d Thumb Code 0 ROM.lib ABSOLUTE + os_task_create 0x00013469 Thumb Code 0 ROM.lib ABSOLUTE + os_task_delete 0x000134a5 Thumb Code 0 ROM.lib ABSOLUTE + os_task_suspend 0x000134c9 Thumb Code 0 ROM.lib ABSOLUTE + os_task_resume 0x000134ed Thumb Code 0 ROM.lib ABSOLUTE + os_task_yield 0x00013511 Thumb Code 0 ROM.lib ABSOLUTE + os_task_handle_get 0x0001352f Thumb Code 0 ROM.lib ABSOLUTE + os_task_priority_get 0x00013553 Thumb Code 0 ROM.lib ABSOLUTE + os_task_priority_set 0x0001357b Thumb Code 0 ROM.lib ABSOLUTE + os_task_status_dump 0x000135a3 Thumb Code 0 ROM.lib ABSOLUTE + os_task_dlps_return_idle_task 0x000135b9 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_id_get 0x000135f9 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_create 0x00013635 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_start 0x00013671 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_restart 0x00013695 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_stop 0x000136bd Thumb Code 0 ROM.lib ABSOLUTE + os_timer_delete 0x000136e1 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_dump 0x00013705 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_state_get 0x00013723 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_init 0x0001375f Thumb Code 0 ROM.lib ABSOLUTE + os_timer_number_get 0x00013775 Thumb Code 0 ROM.lib ABSOLUTE + os_timer_pendcall 0x0001379d Thumb Code 0 ROM.lib ABSOLUTE + os_timer_next_timeout_value_get 0x000137cb Thumb Code 0 ROM.lib ABSOLUTE + osif_timer_create 0x00013f9f Thumb Code 0 ROM.lib ABSOLUTE + BB_write_baseband_register 0x00014901 Thumb Code 0 ROM.lib ABSOLUTE + bzdma_ble_set_segment_valid_bitmap 0x00014a91 Thumb Code 0 ROM.lib ABSOLUTE + bzdma_send_packet_to_ble_data_ring_fifo 0x00015369 Thumb Code 0 ROM.lib ABSOLUTE + bzdma_update_fw_rptr_of_ble_data_ring_fifo 0x0001544b Thumb Code 0 ROM.lib ABSOLUTE + bzdma_wait_rxcmd_complete 0x0001557d Thumb Code 0 ROM.lib ABSOLUTE + bzdma_send_burst_rxcmd_and_wait_complete 0x000155a3 Thumb Code 0 ROM.lib ABSOLUTE + rtk_write_modem_radio_reg 0x000184ad Thumb Code 0 ROM.lib ABSOLUTE + rtk_read_modem_radio_reg 0x00018515 Thumb Code 0 ROM.lib ABSOLUTE + hci_handle_le_receiver_test 0x0001a81b Thumb Code 0 ROM.lib ABSOLUTE + hci_handle_le_test_end 0x0001ac3b Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_read 0x00032f61 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_read_8b 0x00032f75 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_read_safe 0x00032f95 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_read_safe_8b 0x00032fb1 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_write 0x00032fdb Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_write_8b 0x00032ffb Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_write_safe 0x00033039 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_write_safe_8b 0x00033063 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_update 0x000330a9 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_update_8b 0x000330c3 Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_update_safe 0x000330df Thumb Code 0 ROM.lib ABSOLUTE + btaon_fast_update_safe_8b 0x000330fb Thumb Code 0 ROM.lib ABSOLUTE + init_dft 0x0003d547 Thumb Code 0 ROM.lib ABSOLUTE + modem_dft 0x0003d66f Thumb Code 0 ROM.lib ABSOLUTE + deinit_dft 0x0003d751 Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_check_active 0x0003dee9 Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_check_inactive 0x0003defd Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_initiate_wakeup 0x0003df39 Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_set_power_mode 0x0003df43 Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_get_error_code 0x0003df4f Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_get_wakeup_reason 0x0003df55 Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_get_statistics 0x0003df5b Thumb Code 0 ROM.lib ABSOLUTE + btmac_pm_check_rom 0x0003e4a9 Thumb Code 0 ROM.lib ABSOLUTE + dfu_dump_header 0x0003ed01 Thumb Code 0 ROM.lib ABSOLUTE + dfu_set_ready 0x0003ed1b Thumb Code 0 ROM.lib ABSOLUTE + dfu_set_obsolete 0x0003ed25 Thumb Code 0 ROM.lib ABSOLUTE + dfu_check_ota_mode_flag 0x0003ed31 Thumb Code 0 ROM.lib ABSOLUTE + dfu_reset 0x0003ed45 Thumb Code 0 ROM.lib ABSOLUTE + dfu_process_crc 0x0003edc3 Thumb Code 0 ROM.lib ABSOLUTE + dfu_process_sha256 0x0003ee99 Thumb Code 0 ROM.lib ABSOLUTE + SHA256_Init 0x0003f4ad Thumb Code 0 ROM.lib ABSOLUTE + SHA256_Update 0x0003f4d7 Thumb Code 0 ROM.lib ABSOLUTE + SHA256_Final 0x0003f517 Thumb Code 0 ROM.lib ABSOLUTE + SHA256 0x0003f5d5 Thumb Code 0 ROM.lib ABSOLUTE + setlocale 0x0003f795 Thumb Code 0 ROM.lib ABSOLUTE + memcmp 0x0003f7a9 Thumb Code 0 ROM.lib ABSOLUTE + strlen 0x0003f805 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memcpy 0x0003f849 Thumb Code 0 ROM.lib ABSOLUTE + __rt_memcpy 0x0003f849 Thumb Code 0 ROM.lib ABSOLUTE + memcpy 0x0003f849 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memset 0x0003f8cb Thumb Code 0 ROM.lib ABSOLUTE + _memset_w 0x0003f8dd Thumb Code 0 ROM.lib ABSOLUTE + _memset 0x0003f8f7 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memclr 0x0003f915 Thumb Code 0 ROM.lib ABSOLUTE + __rt_memclr 0x0003f915 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memclr4 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE + __aeabi_memclr8 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE + __rt_memclr_w 0x0003f919 Thumb Code 0 ROM.lib ABSOLUTE + exit 0x000409b9 Thumb Code 0 ROM.lib ABSOLUTE + __Vectors 0x00200000 Data 4 startup_rtl876x.o(VECTOR) + __Vectors_End 0x002000e8 Data 0 startup_rtl876x.o(VECTOR) + pMCU_PPB 0x00200104 Data 0 ROM.lib ABSOLUTE + pLogDMA_SM 0x00200108 Data 0 ROM.lib ABSOLUTE + socv_ft_data 0x00200110 Data 0 ROM.lib ABSOLUTE + platform_delay_us 0x0020011c Data 0 ROM.lib ABSOLUTE + platform_delay_ms 0x00200120 Data 0 ROM.lib ABSOLUTE + otp 0x00200164 Data 0 ROM.lib ABSOLUTE + SystemCpuClock 0x00200524 Data 0 ROM.lib ABSOLUTE + init_true_random_generator 0x00200854 Data 0 ROM.lib ABSOLUTE + get_true_random_number 0x00200858 Data 0 ROM.lib ABSOLUTE + bzdma_supported_le_max_seg_num 0x00200861 Data 0 ROM.lib ABSOLUTE + BB_handle_psd_end_intr 0x002008a0 Data 0 ROM.lib ABSOLUTE + BB_handle_psd_end_intr_in_isr 0x002008a8 Data 0 ROM.lib ABSOLUTE + rtk_write_rfc_reg_pi 0x002008b0 Data 0 ROM.lib ABSOLUTE + rtk_read_modem_radio_reg_pi 0x002008b4 Data 0 ROM.lib ABSOLUTE + rtk_write_modem_radio_reg_pi 0x002008b8 Data 0 ROM.lib ABSOLUTE + rtk_ioq_read_rfc_reg 0x002008e0 Data 0 ROM.lib ABSOLUTE + rtk_update_rfc_reg_pi 0x002008e4 Data 0 ROM.lib ABSOLUTE + lc_calculate_log_from_rssi 0x002008f4 Data 0 ROM.lib ABSOLUTE + ll_hw_init 0x00200b0c Data 0 ROM.lib ABSOLUTE + phy_auto_gated_on 0x00200ea0 Data 0 ROM.lib ABSOLUTE + phy_auto_gated_off 0x00200ea4 Data 0 ROM.lib ABSOLUTE + le_tx_power_to_txgain_index 0x00200ef0 Data 0 ROM.lib ABSOLUTE + btmac_pm_system 0x002010d4 Data 0 ROM.lib ABSOLUTE + app_pre_main 0x002011d0 Data 0 ROM.lib ABSOLUTE + upperstack_entry 0x002011d4 Data 0 ROM.lib ABSOLUTE + app_main 0x002011d8 Data 0 ROM.lib ABSOLUTE + log_seq_num 0x002011e8 Data 0 ROM.lib ABSOLUTE + is_log_init 0x002011ea Data 0 ROM.lib ABSOLUTE + flash_sem 0x00201228 Data 0 ROM.lib ABSOLUTE + flash_device_info 0x00201258 Data 0 ROM.lib ABSOLUTE + pxCurrentTCB 0x00201340 Data 0 ROM.lib ABSOLUTE + xTickCount 0x0020134c Data 0 ROM.lib ABSOLUTE + uxPendedTicks 0x00201358 Data 0 ROM.lib ABSOLUTE + uxSchedulerSuspended 0x00201370 Data 0 ROM.lib ABSOLUTE + pTaskHandleList 0x00201374 Data 0 ROM.lib ABSOLUTE + uxTimerCreateCount 0x00201474 Data 0 ROM.lib ABSOLUTE + uxTimerDeleteCount 0x00201476 Data 0 ROM.lib ABSOLUTE + xTimerQueue 0x00201478 Data 0 ROM.lib ABSOLUTE + pxTimerPool 0x00201488 Data 0 ROM.lib ABSOLUTE + puxUsedTimerPoolMask 0x0020148c Data 0 ROM.lib ABSOLUTE + xFreeBytesRemaining 0x002014d8 Data 0 ROM.lib ABSOLUTE + xMinimumEverFreeBytesRemaining 0x002014e0 Data 0 ROM.lib ABSOLUTE + xHeapTotalSize 0x002014e8 Data 0 ROM.lib ABSOLUTE + xStart 0x002014f0 Data 0 ROM.lib ABSOLUTE + app_cb_wdg_reset 0x00201514 Data 0 ROM.lib ABSOLUTE + patch_osif_os_sys_time_get 0x00201580 Data 0 ROM.lib ABSOLUTE + patch_osif_os_msg_send_intern 0x00201608 Data 0 ROM.lib ABSOLUTE + patch_osif_os_timer_create 0x00201644 Data 0 ROM.lib ABSOLUTE + Patch_Dump_CPU_Register_and_Memory 0x00201694 Data 0 ROM.lib ABSOLUTE + patch_vTaskSwitchContext 0x002016c0 Data 0 ROM.lib ABSOLUTE + patch_traceTaskSwitchIn 0x002016c4 Data 0 ROM.lib ABSOLUTE + patch_HardFaultRecord_TryToSave 0x0020182c Data 0 ROM.lib ABSOLUTE + low_task_handle 0x00201858 Data 0 ROM.lib ABSOLUTE + Bzdma_Manager 0x00201888 Data 0 ROM.lib ABSOLUTE + g_modem_psd_report_entry_num 0x002020de Data 0 ROM.lib ABSOLUTE + g_modem_psd_report_array 0x002020ec Data 0 ROM.lib ABSOLUTE + g_efuse_modem_psd_setting_1 0x00202938 Data 0 ROM.lib ABSOLUTE + rcp_BTMAC_Handler 0x00202c94 Data 0 ROM.lib ABSOLUTE + __initial_sp 0x00203800 Number 0 startup_rtl876x.o ABSOLUTE + GPIO_Group3_Handler 0x00207c01 * Thumb Code 72 system_rtl876x.o(.app.data_ram.text) + Image$$RAM_DATA_ON$$RO$$Base 0x00207c00 Number 0 anon$$obj.o ABSOLUTE + GPIO_Group2_Handler 0x00207c49 * Thumb Code 72 system_rtl876x.o(.app.data_ram.text) + GPIO_Group1_Handler 0x00207c91 * Thumb Code 64 system_rtl876x.o(.app.data_ram.text) + GPIO_Group0_Handler 0x00207cd1 * Thumb Code 64 system_rtl876x.o(.app.data_ram.text) + DLPS_IO_EnterDlpsCb 0x00207d15 * Thumb Code 642 rtl876x_io_dlps.o(.app.data_ram.text) + DLPS_IO_ExitDlpsCb 0x00207f97 * Thumb Code 848 rtl876x_io_dlps.o(.app.data_ram.text) + Timer3_Handler 0x00208335 * Thumb Code 60 reset_watch_dog_timer.o(.app.data_ram.text) + mbedtls_mpi_add_abs 0x002083ad * Thumb Code 158 bignum.o(.app.data_ram.text) + mbedtls_mpi_sub_abs 0x0020844b * Thumb Code 152 bignum.o(.app.data_ram.text) + mbedtls_mpi_add_mpi 0x002084e3 * Thumb Code 10 bignum.o(.app.data_ram.text) + mbedtls_mpi_mul_int 0x002084ed * Thumb Code 104 bignum.o(.app.data_ram.text) + mbedtls_mpi_sub_mpi 0x00208555 * Thumb Code 12 bignum.o(.app.data_ram.text) + mbedtls_mpi_div_mpi 0x00208561 * Thumb Code 1016 bignum.o(.app.data_ram.text) + mbedtls_mpi_div_int 0x00208959 Thumb Code 46 bignum.o(.app.data_ram.text) + mbedtls_mpi_mod_int 0x00208987 Thumb Code 156 bignum.o(.app.data_ram.text) + mbedtls_mpi_mul_mpi 0x00208a23 * Thumb Code 222 bignum.o(.app.data_ram.text) + I2C_TimeOut 0x00208b00 Data 4 rtl876x_i2c.o(.data) + Image$$RAM_DATA_ON$$RW$$Base 0x00208b00 Number 0 anon$$obj.o ABSOLUTE + sdd_rssi_level 0x00208b18 Data 1 sdd_service.o(.data) + broadcast_stop 0x00208bc6 Data 1 findmy_app.o(.data) + mac_is_same 0x00208bc7 Data 1 custom_app.o(.data) + m_gatt_mtu 0x00208cec Data 2 fmna_gatt.o(.data) + m_fmna_key_rotation_timeout_ms 0x00208d24 Data 4 fmna_state_machine.o(.data) + fmna_sm_state_strings 0x00208d2c Data 40 fmna_state_machine.o(.data) + fmna_sm_event_strings 0x00208d54 Data 80 fmna_state_machine.o(.data) + mbedtls_cipher_base_lookup_table 0x00208e04 Data 8 cipher_wrap.o(.data) + SOC_Version 0x00208e14 Data 1 adc_lib.o(.data) + ADC_K_Version 0x00208e15 Data 1 adc_lib.o(.data) + SOC_Version_Table 0x00208e16 Data 48 adc_lib.o(.data) + is_key_rotated 0x00208e46 Data 1 key_crypto.o(.data) + Image$$RAM_DATA_ON$$ZI$$Base 0x00208e48 Number 0 anon$$obj.o ABSOLUTE + user_wdg_cb 0x00208e48 Data 4 system_rtl876x.o(.bss) + app_pre_main_cb 0x00208e4c Data 4 system_rtl876x.o(.bss) + os_patch 0x00208e50 Data 4 system_rtl876x.o(.bss) + random_seed_value 0x00208e54 Data 4 system_rtl876x.o(.bss) + active_timer_handle 0x00208e58 Data 4 system_rtl876x.o(.bss) + User_IO_EnterDlpsCB 0x00208e5c Data 4 rtl876x_io_dlps.o(.bss) + User_IO_ExitDlpsCB 0x00208e60 Data 4 rtl876x_io_dlps.o(.bss) + PeriIntStoreReg 0x00208e64 Data 4 rtl876x_io_dlps.o(.bss) + PWM2_StoreReg 0x00208e68 Data 4 rtl876x_io_dlps.o(.bss) + Pinmux_StoreReg 0x00208e6c Data 40 rtl876x_io_dlps.o(.bss) + ADC_StoreReg 0x00208e94 Data 60 rtl876x_io_dlps.o(.bss) + GPIO_StoreReg 0x00208ed0 Data 40 rtl876x_io_dlps.o(.bss) + I2C0_StoreReg 0x00208ef8 Data 80 rtl876x_io_dlps.o(.bss) + TIM_StoreReg 0x00208f48 Data 112 rtl876x_io_dlps.o(.bss) + CPU_StoreReg 0x00208fb8 Data 12 rtl876x_io_dlps.o(.bss) + CPU_StoreReg_IP 0x00208fc4 Data 32 rtl876x_io_dlps.o(.bss) + fns_id 0x00208fe8 Data 1 findmy_network_service.o(.bss) + ais_id 0x00208ff0 Data 1 accessory_info_service.o(.bss) + bat_level 0x00208ff1 Data 1 accessory_info_service.o(.bss) + acc_capability 0x00208ff4 Data 4 accessory_info_service.o(.bss) + fw_vers 0x00208ff8 Data 4 accessory_info_service.o(.bss) + app_task_handle 0x00209014 Data 4 app_task.o(.bss) + evt_queue_handle 0x00209018 Data 4 app_task.o(.bss) + io_queue_handle 0x0020901c Data 4 app_task.o(.bss) + bt_indication_queue 0x00209020 Data 4 app_task.o(.bss) + is_enable 0x00209024 Data 1 findmy_app.o(.bss) + find_my_in_local_apple 0x00209025 Data 1 findmy_app.o(.bss) + find_my_in_sdd_apple 0x00209026 Data 1 findmy_app.o(.bss) + password_received 0x00209027 Data 1 findmy_app.o(.bss) + find_my_loacl_apple_mac 0x00209034 Data 6 findmy_app.o(.bss) + find_my_sdd_apple_mac 0x0020903a Data 6 findmy_app.o(.bss) + app_global_data 0x00209040 Data 13 findmy_app.o(.bss) + SINGLE_ID 0x00209060 Data 6 custom_app.o(.bss) + READ_SINGLE_ID 0x00209066 Data 6 custom_app.o(.bss) + custom_data 0x0020906c Data 44 custom_app.o(.bss) + scenario_name 0x00209098 Data 8 overlay_mgr.o(.bss) + custom_new_adv 0x002090b4 Data 28 serial_number_send.o(.bss) + gpio_key_debounce_timer 0x002090d8 Data 4 key_handle.o(.bss) + m_fmna_active_connections 0x00209128 Data 16 fmna_connection.o(.bss) + serial_number_read_state 0x00209148 Data 1 fmna_crypto.o(.bss) + p_fmna_send_pairing_data 0x0020914c Data 4 fmna_crypto.o(.bss) + p_fmna_initiate_pairing_data 0x00209150 Data 4 fmna_crypto.o(.bss) + p_fmna_finalize_pairing_data 0x00209154 Data 4 fmna_crypto.o(.bss) + p_fmna_send_pairing_status 0x00209158 Data 4 fmna_crypto.o(.bss) + p_fmna_encrypted_serial_number_payload 0x0020915c Data 4 fmna_crypto.o(.bss) + fmna_service_current_extended_packet_tx 0x002098d8 Data 12 fmna_gatt.o(.bss) + tx_buffer 0x002098e4 Data 247 fmna_gatt.o(.bss) + m_command_response_data 0x002099db Data 40 fmna_gatt.o(.bss) + m_command_response_index 0x00209a03 Data 1 fmna_gatt.o(.bss) + m_aggressive_ut_adv_enabled 0x00209a14 Data 1 fmna_nonowner_control_point.o(.bss) + m_fmna_state 0x00209f91 Data 1 fmna_state_machine.o(.bss) + m_fmna_secondary_keys_info 0x00209f94 Data 4 fmna_state_machine.o(.bss) + m_current_separated_primary_key_index 0x00209f98 Data 4 fmna_state_machine.o(.bss) + m_fmna_temp_primary_key 0x00209fc4 Data 48 fmna_state_machine.o(.bss) + m_fmna_current_primary_key 0x00209ff4 Data 48 fmna_state_machine.o(.bss) + m_fmna_current_separated_primary_key 0x0020a024 Data 48 fmna_state_machine.o(.bss) + m_fmna_current_secondary_key 0x0020a054 Data 32 fmna_state_machine.o(.bss) + one_shot_adv_data 0x0020a0b0 Data 96 fmna_gap_platform.o(.bss) + password_correct 0x0020a110 Data 1 fmna_gatt_platform.o(.bss) + password 0x0020a117 Data 7 fmna_gatt_platform.o(.bss) + is_motion_detection_start 0x0020a158 Data 1 fmna_motion_detection_platform.o(.bss) + sound_en 0x0020a15c Data 1 fmna_sound_platform.o(.bss) + adv_timer 0x0020a188 Data 4 fmna_timer_platform.o(.bss) + sn_lookup_timer 0x0020a18c Data 4 fmna_timer_platform.o(.bss) + aon_watch_dog_wake_up_dlps_timer 0x0020a190 Data 4 fmna_timer_platform.o(.bss) + unpair_pending_timer 0x0020a194 Data 4 fmna_timer_platform.o(.bss) + double_click_detect_timer 0x0020a198 Data 4 fmna_timer_platform.o(.bss) + disconnection_click_timer 0x0020a19c Data 4 fmna_timer_platform.o(.bss) + mbedtls_cipher_supported 0x0020abd0 Data 28 cipher_wrap.o(.bss) + mbedtls_ct_zero 0x0020abec Data 4 constant_time.o(.bss) + gap_app_cb 0x0020abfc Data 4 gap_lib_system_call.o(.bss) + gap_common_app_cb 0x0020ac00 Data 4 gap_lib_system_call.o(.bss) + ADC_Resistance_Value 0x0020ac04 Data 2 adc_lib.o(.bss) + EFUSE_ADC_Read_Value 0x0020ac06 Data 33 adc_lib.o(.bss) + ADC_Divide_Single_Value 0x0020ac28 Data 12 adc_lib.o(.bss) + ADC_Bypass_Single_Value 0x0020ac34 Data 12 adc_lib.o(.bss) + ADC_Divide_Diff_Value 0x0020ac40 Data 12 adc_lib.o(.bss) + ADC_Bypass_Diff_Value 0x0020ac4c Data 12 adc_lib.o(.bss) + fmna_task_handle 0x0020ac58 Data 4 key_crypto.o(.bss) + fmna_sem 0x0020ac5c Data 4 key_crypto.o(.bss) + gap_common_vendor_cb 0x0020ac60 Data 4 gap_vendor_cmd.o(.bss) + _random_number_data 0x0020ac64 Data 228 rand.o(.bss) + AppUpdateVectorTable 0x0020ad5d * Thumb Code 174 system_rtl876x.o(.app.overlay_a) + Image$$OVERLAY_A$$RO$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$RO$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$RW$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_B$$ZI$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$RO$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$RW$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_C$$ZI$$Base 0x0020ad5c Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_A$$RW$$Base 0x0020ae34 Number 0 anon$$obj.o ABSOLUTE + Image$$OVERLAY_A$$ZI$$Base 0x0020ae34 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$RO$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$RW$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE + Image$$CACHE_DATA_ON$$ZI$$Base 0x00216000 Number 0 anon$$obj.o ABSOLUTE + img_header 0x00825000 Data 480 system_rtl876x.o(.app.flash.header) + auth_header 0x008251e0 Data 544 system_rtl876x.o(.app.flash.header) + Image$$FLASH_START_ADDR$$RO$$Base 0x00825400 Number 0 anon$$obj.o ABSOLUTE + Load$$FLASH_START_ADDR$$RO$$Base 0x00825400 Number 0 anon$$obj.o ABSOLUTE + Reset_Handler 0x00825401 Thumb Code 4 startup_rtl876x.o(RESET) + __main 0x00825409 Thumb Code 8 __main.o(!!!main) + _printf_percent 0x00825411 Thumb Code 0 _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000) + _printf_n 0x00825413 Thumb Code 0 _printf_n.o(.ARM.Collect$$_printf_percent$$00000001) + _printf_p 0x0082541d Thumb Code 0 _printf_p.o(.ARM.Collect$$_printf_percent$$00000002) + _printf_f 0x00825427 Thumb Code 0 _printf_f.o(.ARM.Collect$$_printf_percent$$00000003) + _printf_e 0x00825431 Thumb Code 0 _printf_e.o(.ARM.Collect$$_printf_percent$$00000004) + _printf_g 0x0082543b Thumb Code 0 _printf_g.o(.ARM.Collect$$_printf_percent$$00000005) + _printf_a 0x00825445 Thumb Code 0 _printf_a.o(.ARM.Collect$$_printf_percent$$00000006) + _printf_ll 0x0082544f Thumb Code 0 _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007) + _printf_i 0x00825459 Thumb Code 0 _printf_i.o(.ARM.Collect$$_printf_percent$$00000008) + _printf_d 0x00825463 Thumb Code 0 _printf_d.o(.ARM.Collect$$_printf_percent$$00000009) + _printf_u 0x0082546d Thumb Code 0 _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A) + _printf_o 0x00825477 Thumb Code 0 _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B) + _printf_x 0x00825481 Thumb Code 0 _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C) + _printf_lli 0x0082548b Thumb Code 0 _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D) + _printf_lld 0x00825495 Thumb Code 0 _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E) + _printf_llu 0x0082549f Thumb Code 0 _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F) + _printf_llo 0x008254a9 Thumb Code 0 _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010) + _printf_llx 0x008254b3 Thumb Code 0 _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011) + _printf_l 0x008254bd Thumb Code 0 _printf_l.o(.ARM.Collect$$_printf_percent$$00000012) + _printf_c 0x008254c7 Thumb Code 0 _printf_c.o(.ARM.Collect$$_printf_percent$$00000013) + _printf_s 0x008254d1 Thumb Code 0 _printf_s.o(.ARM.Collect$$_printf_percent$$00000014) + _printf_lc 0x008254db Thumb Code 0 _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015) + _printf_ls 0x008254e5 Thumb Code 0 _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016) + _printf_percent_end 0x008254ef Thumb Code 0 _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017) + __rt_lib_init 0x008254f3 Thumb Code 0 libinit.o(.ARM.Collect$$libinit$$00000000) + __rt_lib_init_fp_1 0x008254f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000002) + __rt_lib_init_heap_1 0x008254f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000A) + __rt_lib_init_preinit_1 0x008254f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000004) + __rt_lib_init_rand_2 0x008254f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000D) + __rt_lib_init_user_alloc_1 0x008254f5 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000C) + __rt_lib_init_lc_common 0x008254f9 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000F) + __rt_lib_init_rand_1 0x008254f9 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000000E) + __rt_lib_init_lc_collate_1 0x008254ff Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000011) + __rt_lib_init_lc_ctype_2 0x008254ff Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000012) + __rt_lib_init_lc_ctype_1 0x0082550b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000013) + __rt_lib_init_lc_monetary_1 0x0082550b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000015) + __rt_lib_init_lc_numeric_2 0x0082550b Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000016) + __rt_lib_init_alloca_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000002E) + __rt_lib_init_argv_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000002C) + __rt_lib_init_atexit_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001B) + __rt_lib_init_clock_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000021) + __rt_lib_init_cpp_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000032) + __rt_lib_init_exceptions_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000030) + __rt_lib_init_fp_trap_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001F) + __rt_lib_init_getenv_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000023) + __rt_lib_init_lc_numeric_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000017) + __rt_lib_init_lc_time_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000019) + __rt_lib_init_return 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000033) + __rt_lib_init_signal_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$0000001D) + __rt_lib_init_stdio_1 0x00825515 Thumb Code 0 libinit2.o(.ARM.Collect$$libinit$$00000025) + __rt_entry 0x00825517 Thumb Code 0 __rtentry.o(.ARM.Collect$$rtentry$$00000000) + __rt_entry_presh_1 0x00825517 Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000002) + __rt_entry_sh 0x00825517 Thumb Code 0 __rtentry5.o(.ARM.Collect$$rtentry$$00000005) + __rt_entry_li 0x0082551b Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000A) + __rt_entry_postsh_1 0x0082551b Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$00000009) + __rt_entry_main 0x0082551f Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000D) + __rt_entry_postli_1 0x0082551f Thumb Code 0 __rtentry2.o(.ARM.Collect$$rtentry$$0000000C) + ram_init 0x0082552d Thumb Code 32 system_rtl876x.o(.app.flash.text) + ram_cache_init 0x0082554d Thumb Code 32 system_rtl876x.o(.app.flash.text) + get_image_entry_addr 0x0082556d Thumb Code 76 system_rtl876x.o(.app.flash.text) + set_os_clock 0x008255b9 Thumb Code 40 system_rtl876x.o(.app.flash.text) + wdg_system_reset_app_cb 0x008255e1 Thumb Code 12 system_rtl876x.o(.app.flash.text) + print_reset_reason 0x008255ed Thumb Code 272 system_rtl876x.o(.app.flash.text) + pre_main 0x008256fd Thumb Code 102 system_rtl876x.o(.app.flash.text) + SystemInit 0x00825763 Thumb Code 328 system_rtl876x.o(.app.flash.text) + bt_stack_config_init 0x008259d5 Thumb Code 16 main.o(.app.flash.text) + gap_config_le_link_number 0x008259e5 Thumb Code 30 gap_config.o(.app.flash.text) + gap_config_bt_bd_addr 0x00825a03 Thumb Code 28 gap_config.o(.app.flash.text) + gap_config_cccd_not_check 0x00825a1f Thumb Code 20 gap_config.o(.app.flash.text) + gap_config_le_min_rem_sca 0x00825a33 Thumb Code 34 gap_config.o(.app.flash.text) + gap_config_bte_pool_size 0x00825a55 Thumb Code 20 gap_config.o(.app.flash.text) + gap_config_bt_report_buf_num 0x00825a69 Thumb Code 6 gap_config.o(.app.flash.text) + gap_config_ccc_bits_count 0x00825a6f Thumb Code 14 gap_config.o(.app.flash.text) + gap_config_max_attribute_table_count 0x00825a7d Thumb Code 8 gap_config.o(.app.flash.text) + gap_config_max_mtu_size 0x00825a85 Thumb Code 8 gap_config.o(.app.flash.text) + gap_config_le_key_storage_flag 0x00825a8d Thumb Code 8 gap_config.o(.app.flash.text) + gap_config_max_le_paired_device 0x00825a95 Thumb Code 8 gap_config.o(.app.flash.text) + gap_config_pa_parameter 0x00825a9d Thumb Code 12 gap_config.o(.app.flash.text) + gap_config_local_addr_storage 0x00825aa9 Thumb Code 28 gap_config.o(.app.flash.text) + gap_config_bqb_en 0x00825ac5 Thumb Code 20 gap_config.o(.app.flash.text) + gap_config_l2c_param 0x00825ad9 Thumb Code 18 gap_config.o(.app.flash.text) + rand 0x00825af5 Thumb Code 52 rand.o(.emb_text) + ADC_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + BTMAC_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + BusFault_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + CAP_Touch_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Default_Handler 0x00825b2d Thumb Code 14 startup_rtl876x.o(.text) + Enhanced_Timer0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Enhanced_Timer1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GDMA0_Channel0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GDMA0_Channel1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GDMA0_Channel2_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GDMA0_Channel3_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO10_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO11_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO12_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO13_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO14_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO15_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO16_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO17_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO18_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO19_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO20_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO21_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO22_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO23_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO24_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO25_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO26_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO27_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO28_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO2_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO30_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO31_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO3_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO4_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO5_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO6_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO7_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + GPIO8_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + HardFault_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + I2C0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + I2C1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + I2S0_RX_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + I2S0_TX_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + IR_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Keyscan_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + LPCOMP_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + MemManage_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + NMI_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + PTA_Mailbox_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + PendSV_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Peripheral_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Qdecode_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + RTC_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SPI0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SPI1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SPI2W_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SPI_Flash_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SVC_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + SysTick_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + TRNG_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Timer2_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Timer4_5_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + Timer5_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + UART0_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + UART1_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + UsageFault_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + WDG_Handler 0x00825b2d Thumb Code 0 startup_rtl876x.o(.text) + __user_setup_stackheap 0x00825b3b Thumb Code 2 startup_rtl876x.o(.text) + random_seed_init 0x00825b81 Thumb Code 16 system_rtl876x.o(.text) + show_sdk_lib_version 0x00825b91 Thumb Code 2 system_rtl876x.o(.text) + log_direct_app 0x00825b93 Thumb Code 150 system_rtl876x.o(.text) + common_main 0x00825c29 Thumb Code 94 system_rtl876x.o(.text) + __2printf 0x00825c87 Thumb Code 4 system_rtl876x.o(.text) + malloc 0x00825c8b Thumb Code 16 system_rtl876x.o(.text) + calloc 0x00825c9b Thumb Code 16 system_rtl876x.o(.text) + realloc 0x00825cab Thumb Code 128 system_rtl876x.o(.text) + free 0x00825d2b Thumb Code 8 system_rtl876x.o(.text) + get_cpu_clock 0x00825d33 Thumb Code 6 system_rtl876x.o(.text) + get_ic_type 0x00825d39 Thumb Code 6 system_rtl876x.o(.text) + set_active_timer_callback 0x00825d3f Thumb Code 26 system_rtl876x.o(.text) + set_boot_active_time 0x00825d59 Thumb Code 62 system_rtl876x.o(.text) + DLPS_IORegister 0x00825e29 Thumb Code 20 rtl876x_io_dlps.o(.text) + GPIO_DeInit 0x00825e45 Thumb Code 16 rtl876x_gpio.o(.text) + GPIO_Init 0x00825e55 Thumb Code 200 rtl876x_gpio.o(.text) + GPIO_StructInit 0x00825f1d Thumb Code 26 rtl876x_gpio.o(.text) + GPIO_INTConfig 0x00825f37 Thumb Code 18 rtl876x_gpio.o(.text) + GPIO_ClearINTPendingBit 0x00825f49 Thumb Code 6 rtl876x_gpio.o(.text) + GPIO_MaskINTConfig 0x00825f4f Thumb Code 18 rtl876x_gpio.o(.text) + GPIO_GetPin 0x00825f61 Thumb Code 58 rtl876x_gpio.o(.text) + GPIO_GetNum 0x00825f9b Thumb Code 42 rtl876x_gpio.o(.text) + GPIO_DBClkCmd 0x00825fc5 Thumb Code 20 rtl876x_gpio.o(.text) + RCC_PeriphClockCmd 0x00825fed Thumb Code 262 rtl876x_rcc.o(.text) + RCC_PeriFunctionConfig 0x008260f3 Thumb Code 88 rtl876x_rcc.o(.text) + RCC_PeriClockConfig 0x0082614b Thumb Code 104 rtl876x_rcc.o(.text) + RCC_I2CClkDivConfig 0x008261b3 Thumb Code 92 rtl876x_rcc.o(.text) + RCC_SPIClkDivConfig 0x0082620f Thumb Code 92 rtl876x_rcc.o(.text) + RCC_TIMClkDivConfig 0x0082626b Thumb Code 48 rtl876x_rcc.o(.text) + RCC_UARTClkDivConfig 0x0082629b Thumb Code 92 rtl876x_rcc.o(.text) + TIM_DeInit 0x0082632d Thumb Code 16 rtl876x_tim.o(.text) + TIM_TimeBaseInit 0x0082633d Thumb Code 234 rtl876x_tim.o(.text) + TIM_StructInit 0x00826427 Thumb Code 26 rtl876x_tim.o(.text) + TIM_Cmd 0x00826441 Thumb Code 20 rtl876x_tim.o(.text) + TIM_CmdSafe 0x00826455 Thumb Code 64 rtl876x_tim.o(.text) + TIM_ChangePeriod 0x00826495 Thumb Code 4 rtl876x_tim.o(.text) + TIM_INTConfig 0x00826499 Thumb Code 18 rtl876x_tim.o(.text) + TIM_PWMChangeFreqAndDuty 0x008264ab Thumb Code 30 rtl876x_tim.o(.text) + TIM_PWMComplOutputEMCmd 0x008264c9 Thumb Code 20 rtl876x_tim.o(.text) + TIM_PWMDZBypassCmd 0x008264dd Thumb Code 20 rtl876x_tim.o(.text) + TIM_PWMChangeDZClockSrc 0x008264f1 Thumb Code 20 rtl876x_tim.o(.text) + Pinmux_Reset 0x0082651d Thumb Code 22 rtl876x_pinmux.o(.text) + Pinmux_Deinit 0x00826533 Thumb Code 24 rtl876x_pinmux.o(.text) + Pinmux_Config 0x0082654b Thumb Code 32 rtl876x_pinmux.o(.text) + Pad_Config 0x0082656b Thumb Code 100 rtl876x_pinmux.o(.text) + Pad_WakeupEnableValue 0x008265cf Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_WKDebounceConfig 0x008265f5 Thumb Code 40 rtl876x_pinmux.o(.text) + Pad_WakeupPolarityValue 0x0082661d Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_DebounceWakeupStatus 0x00826643 Thumb Code 32 rtl876x_pinmux.o(.text) + System_DebounceWakeupStatus 0x00826663 Thumb Code 32 rtl876x_pinmux.o(.text) + System_WakeUpPinDisable 0x00826683 Thumb Code 28 rtl876x_pinmux.o(.text) + System_WakeUpPinEnable 0x0082669f Thumb Code 178 rtl876x_pinmux.o(.text) + Pad_WakeupInterruptValue 0x00826751 Thumb Code 36 rtl876x_pinmux.o(.text) + System_WakeUpInterruptValue 0x00826775 Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_OutputControlValue 0x0082679b Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_OutputEnableValue 0x008267c1 Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_PullEnableValue 0x008267e7 Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_PullUpOrDownValue 0x0082680d Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_PullConfigValue 0x00826833 Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_PowerOrShutDownValue 0x00826859 Thumb Code 40 rtl876x_pinmux.o(.text) + Pad_ControlSelectValue 0x00826881 Thumb Code 40 rtl876x_pinmux.o(.text) + Pad_ClearWakeupINTPendingBit 0x008268a9 Thumb Code 38 rtl876x_pinmux.o(.text) + Pad_ClearAllWakeupINT 0x008268cf Thumb Code 94 rtl876x_pinmux.o(.text) + Spic0_control 0x0082692d Thumb Code 22 rtl876x_pinmux.o(.text) + Spic1_control 0x00826943 Thumb Code 20 rtl876x_pinmux.o(.text) + NVIC_Init 0x0082695d Thumb Code 182 rtl876x_nvic.o(.text) + ADC_DeInit 0x00826a2d Thumb Code 16 rtl876x_adc.o(.text) + ADC_Init 0x00826a3d Thumb Code 276 rtl876x_adc.o(.text) + ADC_StructInit 0x00826b51 Thumb Code 82 rtl876x_adc.o(.text) + ADC_Cmd 0x00826ba3 Thumb Code 144 rtl876x_adc.o(.text) + ADC_INTConfig 0x00826c33 Thumb Code 16 rtl876x_adc.o(.text) + ADC_ReadRawData 0x00826c43 Thumb Code 22 rtl876x_adc.o(.text) + ADC_ReadAvgRawData 0x00826c59 Thumb Code 6 rtl876x_adc.o(.text) + ADC_ReadFIFO 0x00826c5f Thumb Code 8 rtl876x_adc.o(.text) + ADC_ReadFIFOData 0x00826c67 Thumb Code 26 rtl876x_adc.o(.text) + ADC_GetFIFODataLen 0x00826c81 Thumb Code 8 rtl876x_adc.o(.text) + ADC_SchIndexConfig 0x00826c89 Thumb Code 28 rtl876x_adc.o(.text) + ADC_SchTableConfig 0x00826ca5 Thumb Code 28 rtl876x_adc.o(.text) + ADC_BitMapConfig 0x00826cc1 Thumb Code 16 rtl876x_adc.o(.text) + ADC_ManualPowerOnCmd 0x00826cd1 Thumb Code 20 rtl876x_adc.o(.text) + ADC_WriteFIFOCmd 0x00826ce5 Thumb Code 20 rtl876x_adc.o(.text) + ADC_BypassCmd 0x00826cf9 Thumb Code 54 rtl876x_adc.o(.text) + ADC_GetINTStatus 0x00826d2f Thumb Code 16 rtl876x_adc.o(.text) + ADC_ClearINTPendingBit 0x00826d3f Thumb Code 10 rtl876x_adc.o(.text) + I2C_Init 0x00826d51 Thumb Code 392 rtl876x_i2c.o(.text) + I2C_DeInit 0x00826ed9 Thumb Code 34 rtl876x_i2c.o(.text) + I2C_StructInit 0x00826efb Thumb Code 38 rtl876x_i2c.o(.text) + I2C_Cmd 0x00826f21 Thumb Code 20 rtl876x_i2c.o(.text) + I2C_CheckAbortStatus 0x00826f35 Thumb Code 64 rtl876x_i2c.o(.text) + I2C_MasterWrite 0x00826f75 Thumb Code 96 rtl876x_i2c.o(.text) + I2C_MasterRead 0x00826fd5 Thumb Code 144 rtl876x_i2c.o(.text) + I2C_RepeatRead 0x00827065 Thumb Code 210 rtl876x_i2c.o(.text) + I2C_INTConfig 0x00827137 Thumb Code 20 rtl876x_i2c.o(.text) + I2C_ClearINTPendingBit 0x0082714b Thumb Code 166 rtl876x_i2c.o(.text) + AON_WDG_Config 0x008271f1 Thumb Code 94 rtl876x_aon_wdg.o(.text) + AON_WDG_ConfigResetLevel 0x0082724f Thumb Code 64 rtl876x_aon_wdg.o(.text) + AON_WDG_ConfigComp 0x0082728f Thumb Code 64 rtl876x_aon_wdg.o(.text) + AON_WDG_ConfigCntCtl 0x008272cf Thumb Code 64 rtl876x_aon_wdg.o(.text) + AON_WDG_ConfigCntReload 0x0082730f Thumb Code 64 rtl876x_aon_wdg.o(.text) + AON_WDG_Enable 0x0082734f Thumb Code 60 rtl876x_aon_wdg.o(.text) + AON_WDG_Disable 0x0082738b Thumb Code 60 rtl876x_aon_wdg.o(.text) + AON_WDG_Restart 0x008273c7 Thumb Code 22 rtl876x_aon_wdg.o(.text) + AON_WDG_SystemReset 0x008273dd Thumb Code 68 rtl876x_aon_wdg.o(.text) + AON_WDG_IsEnable 0x00827421 Thumb Code 16 rtl876x_aon_wdg.o(.text) + fns_write_post_callback 0x00827471 Thumb Code 26 findmy_network_service.o(.text) + fns_attr_write_cb 0x0082748b Thumb Code 90 findmy_network_service.o(.text) + fns_cccd_update_cb 0x008274e5 Thumb Code 18 findmy_network_service.o(.text) + findmy_network_add_service 0x008274f7 Thumb Code 64 findmy_network_service.o(.text) + ais_attr_read_cb 0x00827569 Thumb Code 176 accessory_info_service.o(.text) + accessory_info_add_service 0x00827619 Thumb Code 60 accessory_info_service.o(.text) + tps_set_parameter 0x00827699 Thumb Code 90 tps.o(.text) + tps_attr_read_cb 0x008276f3 Thumb Code 238 tps.o(.text) + tps_add_service 0x008277e1 Thumb Code 66 tps.o(.text) + ias_attr_write_cb 0x0082786d Thumb Code 88 ias.o(.text) + ias_add_service 0x008278c5 Thumb Code 66 ias.o(.text) + sdd_set_parameter 0x00827929 Thumb Code 34 sdd_service.o(.text) + sdd_battery_level_value_notify 0x0082794b Thumb Code 24 sdd_service.o(.text) + sdd_send_array_value 0x00827963 Thumb Code 22 sdd_service.o(.text) + sdd_battery_level_value_read_confirm 0x00827979 Thumb Code 40 sdd_service.o(.text) + sdd_attr_read_cb 0x008279a1 Thumb Code 88 sdd_service.o(.text) + sdd_cccd_update_cb 0x008279f9 Thumb Code 78 sdd_service.o(.text) + sdd_attr_write_cb 0x00827a47 Thumb Code 126 sdd_service.o(.text) + sdd_add_service 0x00827ac5 Thumb Code 66 sdd_service.o(.text) + dis_set_parameter 0x00827b49 Thumb Code 200 dis.o(.text) + dis_attr_read_cb 0x00827c11 Thumb Code 330 dis.o(.text) + dis_add_service 0x00827d5b Thumb Code 68 dis.o(.text) + board_init 0x00827df1 Thumb Code 12 main.o(.text) + driver_init 0x00827dfd Thumb Code 16 main.o(.text) + io_dlps_enter_cb 0x00827e0d Thumb Code 16 main.o(.text) + io_dlps_exit_cb 0x00827e1d Thumb Code 20 main.o(.text) + app_dlps_check_cb 0x00827e31 Thumb Code 10 main.o(.text) + pwr_mgr_init 0x00827e3b Thumb Code 42 main.o(.text) + task_init 0x00827e65 Thumb Code 12 main.o(.text) + main 0x00827e71 Thumb Code 166 main.o(.text) + System_Handler 0x00827f17 Thumb Code 68 main.o(.text) + app_main_task 0x00827f99 Thumb Code 156 app_task.o(.text) + app_task_init 0x00828035 Thumb Code 30 app_task.o(.text) + app_send_msg_to_apptask 0x00828053 Thumb Code 92 app_task.o(.text) + app_sched_event_put 0x008280af Thumb Code 154 app_task.o(.text) + double_click_detect_timer_cb 0x00828181 Thumb Code 342 findmy_app.o(.text) + fmna_factory_reset 0x008282d7 Thumb Code 44 findmy_app.o(.text) + app_bond_info_restore 0x00828303 Thumb Code 56 findmy_app.o(.text) + app_handle_gpio_msg 0x0082833b Thumb Code 398 findmy_app.o(.text) + app_handle_authen_state_evt 0x008284c9 Thumb Code 110 findmy_app.o(.text) + app_handle_conn_param_update_evt 0x00828537 Thumb Code 360 findmy_app.o(.text) + app_handle_conn_mtu_info_evt 0x0082869f Thumb Code 38 findmy_app.o(.text) + app_handle_conn_state_evt 0x008286c5 Thumb Code 414 findmy_app.o(.text) + app_handle_dev_state_evt 0x00828863 Thumb Code 204 findmy_app.o(.text) + app_handle_gap_msg 0x0082892f Thumb Code 238 findmy_app.o(.text) + app_handle_io_msg 0x00828a1d Thumb Code 372 findmy_app.o(.text) + app_global_data_init 0x00828b91 Thumb Code 64 findmy_app.o(.text) + password_verification_timeout 0x00828bd1 Thumb Code 66 findmy_app.o(.text) + app_handle_bond_modify_msg 0x00828c13 Thumb Code 234 findmy_app.o(.text) + app_gap_callback 0x00828cfd Thumb Code 700 findmy_app.o(.text) + generate_random_id 0x0082902d Thumb Code 62 custom_app.o(.text) + update_single_id 0x0082906b Thumb Code 58 custom_app.o(.text) + save_single_id_to_flash 0x008290a5 Thumb Code 56 custom_app.o(.text) + read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data 0x008290dd Thumb Code 90 custom_app.o(.text) + reset_data_copy_flag 0x00829137 Thumb Code 14 custom_app.o(.text) + cust_adv_init 0x00829173 Thumb Code 116 custom_app.o(.text) + cust_data_init 0x008291e7 Thumb Code 110 custom_app.o(.text) + cust_adv_stop 0x00829255 Thumb Code 56 custom_app.o(.text) + cust_feature_disable 0x0082928d Thumb Code 100 custom_app.o(.text) + cust_factory_reset 0x008292f1 Thumb Code 30 custom_app.o(.text) + cust_adv_update_device_name 0x0082930f Thumb Code 572 custom_app.o(.text) + cust_handle_connected_evt 0x0082954b Thumb Code 108 custom_app.o(.text) + cust_adv_start 0x008295b7 Thumb Code 56 custom_app.o(.text) + cust_handle_disconnected_evt 0x008295ef Thumb Code 62 custom_app.o(.text) + cust_feature_is_enabled 0x0082962d Thumb Code 6 custom_app.o(.text) + cust_feature_enable 0x00829633 Thumb Code 128 custom_app.o(.text) + cust_connection_disconnect_this 0x008296b3 Thumb Code 30 custom_app.o(.text) + cust_adv_is_enabled 0x008296d1 Thumb Code 6 custom_app.o(.text) + cust_get_conn_id 0x008296d7 Thumb Code 6 custom_app.o(.text) + cust_ble_set_to_idle 0x008296dd Thumb Code 62 custom_app.o(.text) + cust_resume_pending_ble_oprations 0x0082971b Thumb Code 30 custom_app.o(.text) + load_overlay 0x00829795 Thumb Code 76 overlay_mgr.o(.text) + get_current_scenario_index 0x008297e1 Thumb Code 40 overlay_mgr.o(.text) + load_serial_number_from_flash 0x00829811 Thumb Code 60 serial_number_send.o(.text) + update_serial_number_in_adv 0x0082984d Thumb Code 58 serial_number_send.o(.text) + set_serial_number_to_adv 0x00829887 Thumb Code 50 serial_number_send.o(.text) + get_serial_number 0x008298b9 Thumb Code 30 serial_number_send.o(.text) + custom_new_adv_init 0x008298d7 Thumb Code 56 serial_number_send.o(.text) + custom_new_adv_start 0x0082990f Thumb Code 42 serial_number_send.o(.text) + custom_new_adv_stop 0x00829939 Thumb Code 26 serial_number_send.o(.text) + da213b_check_motion_flag 0x00829a27 Thumb Code 164 da213b.o(.text) + da213b_init 0x00829acb Thumb Code 132 da213b.o(.text) + da213b_deinit 0x00829b4f Thumb Code 90 da213b.o(.text) + gpio_board_init 0x00829ead Thumb Code 60 key_handle.o(.text) + gpio_driver_init 0x00829ee9 Thumb Code 372 key_handle.o(.text) + GPIO9_Handler 0x0082a05d Thumb Code 98 key_handle.o(.text) + GPIO29_Handler 0x0082a0bf Thumb Code 98 key_handle.o(.text) + gpio_key_enter_dlps_config 0x0082a121 Thumb Code 112 key_handle.o(.text) + gpio_key_exit_dlps_config 0x0082a191 Thumb Code 44 key_handle.o(.text) + fmna_adv_reset_bd_addr 0x0082a1d5 Thumb Code 32 fmna_adv.o(.text) + fmna_adv_init_pairing 0x0082a1f5 Thumb Code 64 fmna_adv.o(.text) + fmna_adv_init_separated 0x0082a235 Thumb Code 132 fmna_adv.o(.text) + fmna_adv_init_nearby 0x0082a2b9 Thumb Code 134 fmna_adv.o(.text) + fmna_config_control_point_rx_handler 0x0082a375 Thumb Code 738 fmna_config_control_point.o(.text) + fmna_config_control_point_is_tx_allowed 0x0082a657 Thumb Code 70 fmna_config_control_point.o(.text) + fmna_connection_is_valid_connection 0x0082a719 Thumb Code 24 fmna_connection.o(.text) + fmna_connection_is_status_bit_enabled 0x0082a731 Thumb Code 62 fmna_connection.o(.text) + fmna_connection_init 0x0082a76f Thumb Code 22 fmna_connection.o(.text) + fmna_connection_get_conn_handle_with_multi_status_enabled 0x0082a785 Thumb Code 52 fmna_connection.o(.text) + fmna_connection_disconnect_all 0x0082a7b9 Thumb Code 48 fmna_connection.o(.text) + fmna_connection_disconnect_this 0x0082a7e9 Thumb Code 26 fmna_connection.o(.text) + fmna_connection_send_multi_status 0x0082a803 Thumb Code 144 fmna_connection.o(.text) + fmna_connection_update_connection_info 0x0082a893 Thumb Code 52 fmna_connection.o(.text) + fmna_connection_update_connection_info_all 0x0082a8c7 Thumb Code 64 fmna_connection.o(.text) + fmna_connection_get_num_connections 0x0082a907 Thumb Code 30 fmna_connection.o(.text) + fmna_connection_set_max_connections 0x0082a925 Thumb Code 176 fmna_connection.o(.text) + fmna_connection_connected_handler 0x0082a9d5 Thumb Code 124 fmna_connection.o(.text) + fmna_connection_conn_param_update_handler 0x0082aa51 Thumb Code 28 fmna_connection.o(.text) + fmna_connection_is_fmna_paired 0x0082aa6d Thumb Code 6 fmna_connection.o(.text) + fmna_connection_disconnected_handler 0x0082aa73 Thumb Code 290 fmna_connection.o(.text) + fmna_connection_set_active_ltk 0x0082ab95 Thumb Code 52 fmna_connection.o(.text) + fmna_connection_get_active_ltk 0x0082abc9 Thumb Code 4 fmna_connection.o(.text) + fmna_connection_set_is_fmna_paired 0x0082abcd Thumb Code 20 fmna_connection.o(.text) + fmna_connection_pair_info_restore 0x0082abe1 Thumb Code 50 fmna_connection.o(.text) + fmna_connection_fmna_unpair 0x0082ac13 Thumb Code 160 fmna_connection.o(.text) + fmna_connection_get_max_connections 0x0082acb3 Thumb Code 6 fmna_connection.o(.text) + fmna_connection_set_unpair_pending 0x0082acb9 Thumb Code 6 fmna_connection.o(.text) + fmna_connection_get_unpair_pending 0x0082acbf Thumb Code 6 fmna_connection.o(.text) + fmna_crypto_get_serial_number_raw 0x0082ad2d Thumb Code 4 fmna_crypto.o(.text) + fmna_crypto_init 0x0082ad31 Thumb Code 174 fmna_crypto.o(.text) + fmna_crypto_generate_send_pairing_data_params 0x0082addf Thumb Code 234 fmna_crypto.o(.text) + fmna_log_mfi_token 0x0082aec9 Thumb Code 16 fmna_crypto.o(.text) + fmna_crypto_finalize_pairing 0x0082aed9 Thumb Code 490 fmna_crypto.o(.text) + fmna_crypto_pairing_complete 0x0082b0c3 Thumb Code 504 fmna_crypto.o(.text) + fmna_crypto_roll_primary_sk 0x0082b2bb Thumb Code 52 fmna_crypto.o(.text) + fmna_crypto_roll_secondary_sk 0x0082b2ef Thumb Code 52 fmna_crypto.o(.text) + fmna_crypto_roll_primary_key 0x0082b323 Thumb Code 122 fmna_crypto.o(.text) + fmna_primary_key_update 0x0082b39d Thumb Code 164 fmna_crypto.o(.text) + fmna_crypto_roll_secondary_key 0x0082b441 Thumb Code 152 fmna_crypto.o(.text) + fmna_crypto_generate_serial_number_response 0x0082b4d9 Thumb Code 272 fmna_crypto.o(.text) + serial_number_read_state_init 0x0082b5e9 Thumb Code 268 fmna_crypto.o(.text) + fmna_crypto_unpair 0x0082b6f5 Thumb Code 56 fmna_crypto.o(.text) + fmna_log_mfi_token_help 0x0082b72d Thumb Code 18 fmna_crypto.o(.text) + fmna_log_serial_number 0x0082b73f Thumb Code 26 fmna_crypto.o(.text) + fmna_debug_control_point_rx_handler 0x0082b9c5 Thumb Code 308 fmna_debug_control_point.o(.text) + fmna_gatt_verify_control_point_opcode_and_length 0x0082bb29 Thumb Code 76 fmna_gatt.o(.text) + fmna_gatt_dispatch_send_next_packet 0x0082bb7d Thumb Code 14 fmna_gatt.o(.text) + fmna_gatt_send_indication_internal 0x0082bb8b Thumb Code 282 fmna_gatt.o(.text) + fmna_gatt_send_indication 0x0082bca5 Thumb Code 68 fmna_gatt.o(.text) + fmna_gatt_send_command_response 0x0082bce9 Thumb Code 94 fmna_gatt.o(.text) + fmna_gatt_config_char_write_handler 0x0082bd47 Thumb Code 112 fmna_gatt.o(.text) + fmna_gatt_nonown_char_write_handler 0x0082bdb7 Thumb Code 112 fmna_gatt.o(.text) + fmna_gatt_paired_owner_char_write_handler 0x0082be27 Thumb Code 112 fmna_gatt.o(.text) + fmna_gatt_debug_char_write_handler 0x0082be97 Thumb Code 112 fmna_gatt.o(.text) + fmna_gatt_pairing_char_authorized_write_handler 0x0082bf07 Thumb Code 222 fmna_gatt.o(.text) + fmna_gatt_get_most_recent_conn_handle 0x0082bfe5 Thumb Code 8 fmna_gatt.o(.text) + fmna_gatt_dispatch_send_packet_extension_indication 0x0082c001 Thumb Code 14 fmna_gatt.o(.text) + fmna_gatt_init 0x0082c00f Thumb Code 8 fmna_gatt.o(.text) + fmna_gatt_services_init 0x0082c017 Thumb Code 8 fmna_gatt.o(.text) + fmna_gatt_reset_queues 0x0082c01f Thumb Code 8 fmna_gatt.o(.text) + fmna_motion_detection_init 0x0082c101 Thumb Code 132 fmna_motion_detection.o(.text) + fmna_motion_detection_start_active_polling 0x0082c185 Thumb Code 140 fmna_motion_detection.o(.text) + motion_detected_handler 0x0082c211 Thumb Code 26 fmna_motion_detection.o(.text) + fmna_motion_detection_stop 0x0082c22b Thumb Code 88 fmna_motion_detection.o(.text) + fmna_motion_detection_start 0x0082c283 Thumb Code 60 fmna_motion_detection.o(.text) + fmna_motion_detection_set_separated_ut_backoff_timeout_seconds 0x0082c2bf Thumb Code 12 fmna_motion_detection.o(.text) + fmna_nonowner_rx_handler 0x0082c3b9 Thumb Code 284 fmna_nonowner_control_point.o(.text) + fmna_paired_owner_rx_handler 0x0082c511 Thumb Code 350 fmna_paired_owner_control_point.o(.text) + fmna_pairing_control_point_unpair 0x0082c6c1 Thumb Code 12 fmna_pairing_control_point.o(.text) + fmna_pairing_control_point_append_to_rx_buffer 0x0082c6cd Thumb Code 58 fmna_pairing_control_point.o(.text) + fmna_pairing_control_point_handle_rx 0x0082c707 Thumb Code 164 fmna_pairing_control_point.o(.text) + fmna_state_machine_is_nearby 0x0082c861 Thumb Code 16 fmna_state_machine.o(.text) + start_pair_adv 0x0082c871 Thumb Code 12 fmna_state_machine.o(.text) + fmna_state_machine_set_nearby_timeout_seconds 0x0082c87d Thumb Code 26 fmna_state_machine.o(.text) + fmna_state_machine_stop_key_rotation_timers 0x0082c897 Thumb Code 86 fmna_state_machine.o(.text) + fmna_state_machine_set_next_keyroll_ms 0x0082c8ed Thumb Code 66 fmna_state_machine.o(.text) + dispatch_set_next_secondary_key_rotation_index_handler 0x0082c995 Thumb Code 138 fmna_state_machine.o(.text) + fmna_state_machine_set_next_secondary_key_rotation_index 0x0082ca1f Thumb Code 20 fmna_state_machine.o(.text) + fmna_state_machine_latch_current_separated_key 0x0082ca33 Thumb Code 78 fmna_state_machine.o(.text) + fmna_rotate_key 0x0082ca93 Thumb Code 142 fmna_state_machine.o(.text) + fmna_evt_handler 0x0082cd3b Thumb Code 348 fmna_state_machine.o(.text) + fmna_state_machine_dispatch_event 0x0082ce9d Thumb Code 14 fmna_state_machine.o(.text) + fmna_state_machine_init 0x0082cec5 Thumb Code 216 fmna_state_machine.o(.text) + fmna_state_machine_has_been_maintenanced 0x0082d8c5 Thumb Code 6 fmna_state_machine.o(.text) + fmna_state_machine_set_persistent_connection_disconnection 0x0082d8cb Thumb Code 100 fmna_state_machine.o(.text) + fmna_state_machine_is_persistent_connection_disconnection 0x0082d92f Thumb Code 6 fmna_state_machine.o(.text) + get_next_secondary_key_rotation_index 0x0082d935 Thumb Code 6 fmna_state_machine.o(.text) + fmna_state_machine_get_non_owner_connection_timeout 0x0082d93b Thumb Code 4 fmna_state_machine.o(.text) + fmna_state_machine_set_key_rotation_timeout_ms 0x0082d93f Thumb Code 74 fmna_state_machine.o(.text) + fmna_state_machine_set_separated_ut_timeout_seconds 0x0082d989 Thumb Code 12 fmna_state_machine.o(.text) + fmna_state_machine_clear_keys 0x0082d995 Thumb Code 280 fmna_state_machine.o(.text) + fmna_state_machine_handle_msg 0x0082daad Thumb Code 224 fmna_state_machine.o(.text) + fmna_version_init 0x0082dc6d Thumb Code 24 fmna_version.o(.text) + fmna_version_get_fw_version 0x0082dc85 Thumb Code 30 fmna_version.o(.text) + fmna_adv_platform_get_default_bt_addr 0x0082dcb9 Thumb Code 78 fmna_adv_platform.o(.text) + fmna_adv_platform_set_random_static_bt_addr 0x0082dd07 Thumb Code 60 fmna_adv_platform.o(.text) + fmna_adv_platform_start_fast_adv 0x0082dd43 Thumb Code 86 fmna_adv_platform.o(.text) + fmna_adv_platform_start_slow_adv 0x0082dd99 Thumb Code 86 fmna_adv_platform.o(.text) + fmna_adv_platform_stop_adv 0x0082ddef Thumb Code 36 fmna_adv_platform.o(.text) + fmna_adv_platform_init_pairing 0x0082de13 Thumb Code 74 fmna_adv_platform.o(.text) + fmna_adv_platform_init_nearby 0x0082de5d Thumb Code 78 fmna_adv_platform.o(.text) + fmna_adv_platform_init_separated 0x0082deab Thumb Code 78 fmna_adv_platform.o(.text) + fmna_ble_platform_init 0x0082def9 Thumb Code 272 fmna_adv_platform.o(.text) + bat_init_data 0x0082e0c9 Thumb Code 36 fmna_battery_platform.o(.text) + bat_enter_dlps_config 0x0082e0ed Thumb Code 2 fmna_battery_platform.o(.text) + bat_exit_dlps_config 0x0082e0ef Thumb Code 2 fmna_battery_platform.o(.text) + bat_init_driver 0x0082e0f1 Thumb Code 70 fmna_battery_platform.o(.text) + bat_update_battery_info 0x0082e137 Thumb Code 318 fmna_battery_platform.o(.text) + fmna_battery_platform_get_battery_level 0x0082e275 Thumb Code 6 fmna_battery_platform.o(.text) + fmna_connection_platform_disconnect 0x0082e2d5 Thumb Code 10 fmna_connection_platform.o(.text) + fmna_handle_ble_evt 0x0082e2df Thumb Code 204 fmna_connection_platform.o(.text) + fmna_connection_platform_fmna_unpair 0x0082e3ab Thumb Code 14 fmna_connection_platform.o(.text) + fmna_connection_platform_log_token_help 0x0082e3b9 Thumb Code 44 fmna_connection_platform.o(.text) + fmna_connection_platform_log_token 0x0082e3e5 Thumb Code 66 fmna_connection_platform.o(.text) + num_to_char 0x0082e427 Thumb Code 14 fmna_connection_platform.o(.text) + fmna_connection_platform_get_serial_number 0x0082e435 Thumb Code 104 fmna_connection_platform.o(.text) + fmna_connection_update_mfi_token_storage 0x0082e49d Thumb Code 256 fmna_connection_platform.o(.text) + fmna_connection_mfi_token_stored 0x0082e59d Thumb Code 6 fmna_connection_platform.o(.text) + gap_sched_adv_random_delay 0x0082e67f Thumb Code 62 fmna_gap_platform.o(.text) + one_shot_bt_addr_set 0x0082e6bd Thumb Code 30 fmna_gap_platform.o(.text) + one_shot_adv_init 0x0082e6db Thumb Code 122 fmna_gap_platform.o(.text) + one_shot_adv_set_param 0x0082e755 Thumb Code 326 fmna_gap_platform.o(.text) + one_shot_handle_pending_adv 0x0082e89b Thumb Code 44 fmna_gap_platform.o(.text) + one_shot_adv_set_addr 0x0082e8c7 Thumb Code 22 fmna_gap_platform.o(.text) + fmble_gap_adv_start 0x0082e8dd Thumb Code 90 fmna_gap_platform.o(.text) + fmble_gap_adv_data_set 0x0082e937 Thumb Code 104 fmna_gap_platform.o(.text) + fmble_gap_adv_stop 0x0082e99f Thumb Code 54 fmna_gap_platform.o(.text) + fmna_gatt_platform_get_gatt_data 0x0082ea91 Thumb Code 12 fmna_gatt_platform.o(.text) + app_profile_callback 0x0082ead3 Thumb Code 822 fmna_gatt_platform.o(.text) + fmna_gatt_platform_services_init 0x0082ee09 Thumb Code 84 fmna_gatt_platform.o(.text) + fmna_gatt_platform_init 0x0082ee5d Thumb Code 2 fmna_gatt_platform.o(.text) + fmna_gatt_platform_get_most_recent_conn_handle 0x0082ee5f Thumb Code 6 fmna_gatt_platform.o(.text) + fmna_gatt_platform_send_indication 0x0082ee65 Thumb Code 290 fmna_gatt_platform.o(.text) + fmna_gatt_platform_send_indication_busy 0x0082ef87 Thumb Code 126 fmna_gatt_platform.o(.text) + fmna_gatt_platform_reset_indication_queue 0x0082f005 Thumb Code 72 fmna_gatt_platform.o(.text) + fmna_gatt_platform_get_next_command_response_index 0x0082f04d Thumb Code 32 fmna_gatt_platform.o(.text) + fmna_gatt_platform_send_next_indication 0x0082f06d Thumb Code 62 fmna_gatt_platform.o(.text) + on_connect 0x0082f0ab Thumb Code 6 fmna_gatt_platform.o(.text) + on_disconnect 0x0082f0b1 Thumb Code 14 fmna_gatt_platform.o(.text) + fmna_malloc 0x0082f101 Thumb Code 122 fmna_malloc_platform.o(.text) + fmna_free 0x0082f17b Thumb Code 72 fmna_malloc_platform.o(.text) + fmna_all_pairing_buf_free 0x0082f1c3 Thumb Code 62 fmna_malloc_platform.o(.text) + board_i2c_master_init 0x0082f239 Thumb Code 58 fmna_motion_detection_platform.o(.text) + board_i2c_master_deinit 0x0082f273 Thumb Code 44 fmna_motion_detection_platform.o(.text) + fmna_motion_detection_platform_init 0x0082f29f Thumb Code 152 fmna_motion_detection_platform.o(.text) + fmna_motion_detection_platform_deinit 0x0082f337 Thumb Code 90 fmna_motion_detection_platform.o(.text) + fmna_motion_detection_platform_is_motion_detected 0x0082f391 Thumb Code 8 fmna_motion_detection_platform.o(.text) + fmna_pm_peer_count 0x0082f3c5 Thumb Code 24 fmna_peer_manager.o(.text) + fmna_pm_delete_bonds 0x0082f3dd Thumb Code 28 fmna_peer_manager.o(.text) + fmna_pm_conn_sec_handle 0x0082f3f9 Thumb Code 38 fmna_peer_manager.o(.text) + fmna_sound_is_playing 0x0082f5a3 Thumb Code 20 fmna_sound_platform.o(.text) + fmna_sound_get_current_event 0x0082f5b7 Thumb Code 6 fmna_sound_platform.o(.text) + fmna_sound_get_remaining_time 0x0082f5bd Thumb Code 38 fmna_sound_platform.o(.text) + fmna_sound_platform_init 0x0082f5e3 Thumb Code 202 fmna_sound_platform.o(.text) + fmna_sound_platform_start 0x0082f6ad Thumb Code 164 fmna_sound_platform.o(.text) + fmna_sound_platform_stop 0x0082f751 Thumb Code 164 fmna_sound_platform.o(.text) + play_beep_mode 0x0082f7f5 Thumb Code 268 fmna_sound_platform.o(.text) + beep_stop 0x0082f901 Thumb Code 12 fmna_sound_platform.o(.text) + adv_timer_callback 0x0082f911 Thumb Code 34 fmna_timer_platform.o(.text) + sw_timer_init 0x0082f95d Thumb Code 232 fmna_timer_platform.o(.text) + app_timer_create 0x0082fa45 Thumb Code 56 fmna_timer_platform.o(.text) + app_timer_start 0x0082fa7d Thumb Code 32 fmna_timer_platform.o(.text) + app_timer_stop 0x0082fa9d Thumb Code 44 fmna_timer_platform.o(.text) + fm_crypto_sha256 0x0082fbc5 Thumb Code 16 fm-crypto.o(.text) + fm_crypto_ckg_init 0x0082fbd5 Thumb Code 108 fm-crypto.o(.text) + fm_crypto_ckg_free 0x0082fc41 Thumb Code 38 fm-crypto.o(.text) + fm_crypto_ckg_gen_c1 0x0082fc67 Thumb Code 56 fm-crypto.o(.text) + fm_crypto_ckg_gen_c3 0x0082fc9f Thumb Code 188 fm-crypto.o(.text) + fm_crypto_ckg_finish 0x0082fd5b Thumb Code 148 fm-crypto.o(.text) + fm_crypto_roll_sk 0x0082fdef Thumb Code 28 fm-crypto.o(.text) + fm_crypto_derive_ltk 0x0082fe0b Thumb Code 60 fm-crypto.o(.text) + fm_crypto_derive_primary_or_secondary_x 0x0082fe47 Thumb Code 286 fm-crypto.o(.text) + fm_crypto_derive_server_shared_secret 0x0082ff65 Thumb Code 54 fm-crypto.o(.text) + fm_crypto_decrypt_e3 0x0082ff9b Thumb Code 182 fm-crypto.o(.text) + fm_crypto_verify_s2 0x00830051 Thumb Code 102 fm-crypto.o(.text) + fm_crypto_authenticate_with_ksn 0x008300b7 Thumb Code 116 fm-crypto.o(.text) + fm_crypto_generate_seedk1 0x0083012b Thumb Code 14 fm-crypto.o(.text) + fm_crypto_encrypt_to_server 0x00830139 Thumb Code 366 fm-crypto.o(.text) + mbed_KDF963 0x00830335 Thumb Code 180 kdf963.o(.text) + mbedtls_aes_init 0x008303e9 Thumb Code 12 aes.o(.text) + mbedtls_aes_free 0x008303f5 Thumb Code 18 aes.o(.text) + mbedtls_aes_setkey_enc 0x00830407 Thumb Code 870 aes.o(.text) + mbedtls_aes_setkey_dec 0x0083076d Thumb Code 248 aes.o(.text) + mbedtls_internal_aes_encrypt 0x00830865 Thumb Code 1580 aes.o(.text) + mbedtls_internal_aes_decrypt 0x00830e91 Thumb Code 1576 aes.o(.text) + mbedtls_aes_crypt_ecb 0x008314b9 Thumb Code 38 aes.o(.text) + mbedtls_asn1_get_len 0x008314e9 Thumb Code 108 asn1parse.o(.text) + mbedtls_asn1_get_tag 0x00831555 Thumb Code 40 asn1parse.o(.text) + mbedtls_asn1_get_bool 0x0083157d Thumb Code 52 asn1parse.o(.text) + mbedtls_asn1_get_int 0x008315b1 Thumb Code 12 asn1parse.o(.text) + mbedtls_asn1_get_enum 0x008315bd Thumb Code 12 asn1parse.o(.text) + mbedtls_asn1_get_mpi 0x008315c9 Thumb Code 38 asn1parse.o(.text) + mbedtls_asn1_get_bitstring 0x008315ef Thumb Code 80 asn1parse.o(.text) + mbedtls_asn1_traverse_sequence_of 0x0083163f Thumb Code 128 asn1parse.o(.text) + mbedtls_asn1_get_bitstring_null 0x008316bf Thumb Code 50 asn1parse.o(.text) + mbedtls_asn1_sequence_free 0x008316f1 Thumb Code 20 asn1parse.o(.text) + mbedtls_asn1_get_sequence_of 0x00831745 Thumb Code 42 asn1parse.o(.text) + mbedtls_asn1_get_alg 0x0083176f Thumb Code 140 asn1parse.o(.text) + mbedtls_asn1_get_alg_null 0x008317fb Thumb Code 46 asn1parse.o(.text) + mbedtls_asn1_free_named_data 0x00831829 Thumb Code 32 asn1parse.o(.text) + mbedtls_asn1_free_named_data_list 0x00831849 Thumb Code 40 asn1parse.o(.text) + mbedtls_asn1_free_named_data_list_shallow 0x00831871 Thumb Code 20 asn1parse.o(.text) + mbedtls_asn1_find_named_data 0x00831885 Thumb Code 40 asn1parse.o(.text) + mbedtls_asn1_write_len 0x00831931 Thumb Code 66 asn1write.o(.text) + mbedtls_asn1_write_tag 0x00831973 Thumb Code 24 asn1write.o(.text) + mbedtls_asn1_write_raw_buffer 0x008319ef Thumb Code 44 asn1write.o(.text) + mbedtls_asn1_write_mpi 0x00831a1b Thumb Code 98 asn1write.o(.text) + mbedtls_asn1_write_null 0x00831a7d Thumb Code 6 asn1write.o(.text) + mbedtls_asn1_write_oid 0x00831a83 Thumb Code 58 asn1write.o(.text) + mbedtls_asn1_write_algorithm_identifier_ext 0x00831abd Thumb Code 116 asn1write.o(.text) + mbedtls_asn1_write_algorithm_identifier 0x00831b31 Thumb Code 20 asn1write.o(.text) + mbedtls_asn1_write_bool 0x00831b45 Thumb Code 38 asn1write.o(.text) + mbedtls_asn1_write_int 0x00831b6b Thumb Code 10 asn1write.o(.text) + mbedtls_asn1_write_enum 0x00831b75 Thumb Code 10 asn1write.o(.text) + mbedtls_asn1_write_tagged_string 0x00831b7f Thumb Code 60 asn1write.o(.text) + mbedtls_asn1_write_utf8_string 0x00831bbb Thumb Code 14 asn1write.o(.text) + mbedtls_asn1_write_printable_string 0x00831bc9 Thumb Code 14 asn1write.o(.text) + mbedtls_asn1_write_ia5_string 0x00831bd7 Thumb Code 14 asn1write.o(.text) + mbedtls_asn1_write_bitstring 0x00831be5 Thumb Code 96 asn1write.o(.text) + mbedtls_asn1_write_named_bitstring 0x00831c45 Thumb Code 50 asn1write.o(.text) + mbedtls_asn1_write_octet_string 0x00831c77 Thumb Code 58 asn1write.o(.text) + mbedtls_asn1_store_named_data 0x00831cb1 Thumb Code 208 asn1write.o(.text) + mbedtls_base64_encode 0x00831e23 Thumb Code 274 base64.o(.text) + mbedtls_base64_decode 0x00831f35 Thumb Code 536 base64.o(.text) + mbedtls_mpi_lt_mpi_ct 0x00832179 Thumb Code 128 bignum.o(.text) + mbedtls_mpi_grow 0x008321f9 Thumb Code 76 bignum.o(.text) + mbedtls_mpi_safe_cond_assign 0x00832245 Thumb Code 100 bignum.o(.text) + mbedtls_mpi_safe_cond_swap 0x008322a9 Thumb Code 110 bignum.o(.text) + mbedtls_mpi_init 0x00832317 Thumb Code 12 bignum.o(.text) + mbedtls_mpi_free 0x00832323 Thumb Code 36 bignum.o(.text) + mbedtls_mpi_shrink 0x00832347 Thumb Code 106 bignum.o(.text) + mbedtls_mpi_copy 0x008323b1 Thumb Code 116 bignum.o(.text) + mbedtls_mpi_swap 0x00832425 Thumb Code 22 bignum.o(.text) + mbedtls_mpi_lset 0x0083243b Thumb Code 54 bignum.o(.text) + mbedtls_mpi_get_bit 0x00832471 Thumb Code 32 bignum.o(.text) + mbedtls_mpi_set_bit 0x00832491 Thumb Code 86 bignum.o(.text) + mbedtls_mpi_lsb 0x008324e7 Thumb Code 50 bignum.o(.text) + mbedtls_mpi_bitlen 0x00832519 Thumb Code 12 bignum.o(.text) + mbedtls_mpi_size 0x00832525 Thumb Code 16 bignum.o(.text) + mbedtls_mpi_cmp_abs 0x00832535 Thumb Code 116 bignum.o(.text) + mbedtls_mpi_add_int 0x008325a9 Thumb Code 48 bignum.o(.text) + mbedtls_mpi_read_string 0x008325d9 Thumb Code 426 bignum.o(.text) + mbedtls_mpi_cmp_mpi 0x00832783 Thumb Code 168 bignum.o(.text) + mbedtls_mpi_cmp_int 0x0083282b Thumb Code 46 bignum.o(.text) + mbedtls_mpi_shift_r 0x00832859 Thumb Code 20 bignum.o(.text) + mbedtls_mpi_shift_l 0x0083286d Thumb Code 60 bignum.o(.text) + mbedtls_mpi_write_string 0x008328a9 Thumb Code 570 bignum.o(.text) + mbedtls_mpi_read_binary_le 0x00832ae3 Thumb Code 42 bignum.o(.text) + mbedtls_mpi_read_binary 0x00832b0d Thumb Code 42 bignum.o(.text) + mbedtls_mpi_write_binary_le 0x00832b37 Thumb Code 18 bignum.o(.text) + mbedtls_mpi_write_binary 0x00832b49 Thumb Code 18 bignum.o(.text) + mbedtls_mpi_sub_int 0x00832b5b Thumb Code 50 bignum.o(.text) + mbedtls_mpi_mod_mpi 0x00832b8d Thumb Code 130 bignum.o(.text) + mbedtls_mpi_exp_mod 0x00832cbb Thumb Code 1272 bignum.o(.text) + mbedtls_mpi_gcd 0x008331b3 Thumb Code 362 bignum.o(.text) + mbedtls_mpi_fill_random 0x0083331d Thumb Code 54 bignum.o(.text) + mbedtls_mpi_random 0x00833353 Thumb Code 70 bignum.o(.text) + mbedtls_mpi_inv_mod 0x00833399 Thumb Code 732 bignum.o(.text) + mbedtls_mpi_core_clz 0x0083372d Thumb Code 22 bignum_core.o(.text) + mbedtls_mpi_core_bitlen 0x00833743 Thumb Code 58 bignum_core.o(.text) + mbedtls_mpi_core_bigendian_to_host 0x0083377d Thumb Code 54 bignum_core.o(.text) + mbedtls_mpi_core_uint_le_mpi 0x008337b3 Thumb Code 60 bignum_core.o(.text) + mbedtls_mpi_core_lt_ct 0x008337ef Thumb Code 184 bignum_core.o(.text) + mbedtls_mpi_core_cond_assign 0x008338a7 Thumb Code 52 bignum_core.o(.text) + mbedtls_mpi_core_cond_swap 0x008338db Thumb Code 72 bignum_core.o(.text) + mbedtls_mpi_core_read_le 0x00833923 Thumb Code 74 bignum_core.o(.text) + mbedtls_mpi_core_read_be 0x0083396d Thumb Code 82 bignum_core.o(.text) + mbedtls_mpi_core_write_le 0x008339bf Thumb Code 92 bignum_core.o(.text) + mbedtls_mpi_core_write_be 0x00833a1b Thumb Code 100 bignum_core.o(.text) + mbedtls_mpi_core_shift_r 0x00833a7f Thumb Code 112 bignum_core.o(.text) + mbedtls_mpi_core_shift_l 0x00833aef Thumb Code 104 bignum_core.o(.text) + mbedtls_mpi_core_add 0x00833b57 Thumb Code 72 bignum_core.o(.text) + mbedtls_mpi_core_add_if 0x00833b9f Thumb Code 84 bignum_core.o(.text) + mbedtls_mpi_core_sub 0x00833bf3 Thumb Code 62 bignum_core.o(.text) + mbedtls_mpi_core_mla 0x00833c31 Thumb Code 1032 bignum_core.o(.text) + mbedtls_mpi_core_mul 0x00834039 Thumb Code 56 bignum_core.o(.text) + mbedtls_mpi_core_montmul_init 0x00834071 Thumb Code 40 bignum_core.o(.text) + mbedtls_mpi_core_montmul 0x00834099 Thumb Code 186 bignum_core.o(.text) + mbedtls_mpi_core_get_mont_r2_unsafe 0x00834153 Thumb Code 54 bignum_core.o(.text) + mbedtls_mpi_core_fill_random 0x00834189 Thumb Code 90 bignum_core.o(.text) + mbedtls_mpi_core_random 0x008341e3 Thumb Code 412 bignum_core.o(.text) + mbedtls_mpi_core_exp_mod_working_limbs 0x0083437f Thumb Code 28 bignum_core.o(.text) + mbedtls_mpi_core_exp_mod 0x0083439b Thumb Code 492 bignum_core.o(.text) + mbedtls_mpi_core_sub_int 0x00834587 Thumb Code 40 bignum_core.o(.text) + mbedtls_mpi_core_check_zero_ct 0x008345af Thumb Code 28 bignum_core.o(.text) + mbedtls_mpi_core_to_mont_rep 0x008345cb Thumb Code 28 bignum_core.o(.text) + mbedtls_mpi_core_from_mont_rep 0x008345e7 Thumb Code 32 bignum_core.o(.text) + mbedtls_cipher_list 0x00834651 Thumb Code 42 cipher.o(.text) + mbedtls_cipher_info_from_type 0x0083467b Thumb Code 30 cipher.o(.text) + mbedtls_cipher_info_from_string 0x00834699 Thumb Code 46 cipher.o(.text) + mbedtls_cipher_info_from_values 0x008346c7 Thumb Code 72 cipher.o(.text) + mbedtls_cipher_init 0x0083470f Thumb Code 10 cipher.o(.text) + mbedtls_cipher_free 0x00834719 Thumb Code 44 cipher.o(.text) + mbedtls_cipher_setup 0x00834745 Thumb Code 52 cipher.o(.text) + mbedtls_cipher_setkey 0x00834779 Thumb Code 116 cipher.o(.text) + mbedtls_cipher_set_iv 0x008347ed Thumb Code 92 cipher.o(.text) + mbedtls_cipher_reset 0x00834849 Thumb Code 18 cipher.o(.text) + mbedtls_cipher_update_ad 0x0083485b Thumb Code 34 cipher.o(.text) + mbedtls_cipher_update 0x0083487d Thumb Code 152 cipher.o(.text) + mbedtls_cipher_finish 0x00834915 Thumb Code 84 cipher.o(.text) + mbedtls_cipher_write_tag 0x00834969 Thumb Code 60 cipher.o(.text) + mbedtls_cipher_check_tag 0x008349a5 Thumb Code 96 cipher.o(.text) + mbedtls_cipher_crypt 0x00834a05 Thumb Code 128 cipher.o(.text) + mbedtls_cipher_auth_encrypt_ext 0x00834a85 Thumb Code 114 cipher.o(.text) + mbedtls_cipher_auth_decrypt_ext 0x00834af7 Thumb Code 106 cipher.o(.text) + mbedtls_ct_memcmp 0x00834bf5 Thumb Code 34 constant_time.o(.text) + mbedtls_ct_memcpy_if 0x00834c17 Thumb Code 50 constant_time.o(.text) + mbedtls_ct_memcpy_offset 0x00834c49 Thumb Code 96 constant_time.o(.text) + mbedtls_ecdh_can_do 0x00834cad Thumb Code 4 ecdh.o(.text) + mbedtls_ecdh_gen_public 0x00834cb1 Thumb Code 20 ecdh.o(.text) + mbedtls_ecdh_compute_shared 0x00834cc5 Thumb Code 82 ecdh.o(.text) + mbedtls_ecdh_init 0x00834d17 Thumb Code 82 ecdh.o(.text) + mbedtls_ecdh_setup 0x00834d69 Thumb Code 14 ecdh.o(.text) + mbedtls_ecdh_enable_restart 0x00834d77 Thumb Code 8 ecdh.o(.text) + mbedtls_ecdh_free 0x00834d7f Thumb Code 80 ecdh.o(.text) + mbedtls_ecdh_make_params 0x00834dcf Thumb Code 128 ecdh.o(.text) + mbedtls_ecdh_read_params 0x00834e4f Thumb Code 60 ecdh.o(.text) + mbedtls_ecdh_get_params 0x00834e8b Thumb Code 116 ecdh.o(.text) + mbedtls_ecdh_make_public 0x00834eff Thumb Code 94 ecdh.o(.text) + mbedtls_ecdh_read_public 0x00834f5d Thumb Code 40 ecdh.o(.text) + mbedtls_ecdh_calc_secret 0x00834f85 Thumb Code 200 ecdh.o(.text) + mbedtls_ecdsa_can_do 0x0083509d Thumb Code 4 ecdsa.o(.text) + mbedtls_ecdsa_sign_restartable 0x008350a1 Thumb Code 712 ecdsa.o(.text) + mbedtls_ecdsa_sign 0x00835369 Thumb Code 36 ecdsa.o(.text) + mbedtls_ecdsa_verify_restartable 0x0083538d Thumb Code 606 ecdsa.o(.text) + mbedtls_ecdsa_verify 0x008355eb Thumb Code 24 ecdsa.o(.text) + mbedtls_ecdsa_write_signature_restartable 0x00835603 Thumb Code 200 ecdsa.o(.text) + mbedtls_ecdsa_write_signature 0x008356cb Thumb Code 34 ecdsa.o(.text) + mbedtls_ecdsa_read_signature_restartable 0x008356ed Thumb Code 146 ecdsa.o(.text) + mbedtls_ecdsa_read_signature 0x0083577f Thumb Code 20 ecdsa.o(.text) + mbedtls_ecdsa_genkey 0x00835793 Thumb Code 36 ecdsa.o(.text) + mbedtls_ecdsa_free 0x008357b7 Thumb Code 14 ecdsa.o(.text) + mbedtls_ecdsa_from_keypair 0x008357c5 Thumb Code 58 ecdsa.o(.text) + mbedtls_ecdsa_init 0x008357ff Thumb Code 8 ecdsa.o(.text) + mbedtls_ecdsa_restart_init 0x00835807 Thumb Code 16 ecdsa.o(.text) + mbedtls_ecdsa_restart_free 0x00835817 Thumb Code 92 ecdsa.o(.text) + mbedtls_ecp_set_max_ops 0x00835889 Thumb Code 6 ecp.o(.text) + mbedtls_ecp_restart_is_enabled 0x0083588f Thumb Code 12 ecp.o(.text) + mbedtls_ecp_point_init 0x0083589b Thumb Code 26 ecp.o(.text) + mbedtls_ecp_point_free 0x008358b5 Thumb Code 32 ecp.o(.text) + mbedtls_ecp_restart_init 0x008358d5 Thumb Code 12 ecp.o(.text) + mbedtls_ecp_restart_free 0x008358e1 Thumb Code 78 ecp.o(.text) + mbedtls_ecp_check_budget 0x0083592f Thumb Code 70 ecp.o(.text) + mbedtls_ecp_curve_list 0x00835975 Thumb Code 4 ecp.o(.text) + mbedtls_ecp_grp_id_list 0x00835979 Thumb Code 48 ecp.o(.text) + mbedtls_ecp_curve_info_from_grp_id 0x008359a9 Thumb Code 28 ecp.o(.text) + mbedtls_ecp_curve_info_from_tls_id 0x008359c5 Thumb Code 28 ecp.o(.text) + mbedtls_ecp_curve_info_from_name 0x008359e1 Thumb Code 46 ecp.o(.text) + mbedtls_ecp_get_type 0x00835a0f Thumb Code 24 ecp.o(.text) + mbedtls_ecp_group_init 0x00835a27 Thumb Code 66 ecp.o(.text) + mbedtls_ecp_keypair_init 0x00835a69 Thumb Code 26 ecp.o(.text) + mbedtls_ecp_group_free 0x00835a83 Thumb Code 134 ecp.o(.text) + mbedtls_ecp_keypair_free 0x00835b09 Thumb Code 32 ecp.o(.text) + mbedtls_ecp_copy 0x00835b29 Thumb Code 44 ecp.o(.text) + mbedtls_ecp_group_copy 0x00835b55 Thumb Code 10 ecp.o(.text) + mbedtls_ecp_set_zero 0x00835b5f Thumb Code 40 ecp.o(.text) + mbedtls_ecp_is_zero 0x00835b87 Thumb Code 22 ecp.o(.text) + mbedtls_ecp_point_cmp 0x00835b9d Thumb Code 50 ecp.o(.text) + mbedtls_ecp_point_read_string 0x00835bcf Thumb Code 44 ecp.o(.text) + mbedtls_ecp_point_write_binary 0x00835bfb Thumb Code 220 ecp.o(.text) + mbedtls_ecp_point_read_binary 0x00835d7f Thumb Code 334 ecp.o(.text) + mbedtls_ecp_tls_read_point 0x00835ecd Thumb Code 44 ecp.o(.text) + mbedtls_ecp_tls_write_point 0x00835ef9 Thumb Code 64 ecp.o(.text) + mbedtls_ecp_tls_read_group_id 0x00835f39 Thumb Code 132 ecp.o(.text) + mbedtls_ecp_tls_read_group 0x00835fbd Thumb Code 26 ecp.o(.text) + mbedtls_ecp_tls_write_group 0x00835fd7 Thumb Code 92 ecp.o(.text) + mbedtls_ecp_check_pubkey 0x00836755 Thumb Code 174 ecp.o(.text) + mbedtls_ecp_check_privkey 0x00836803 Thumb Code 56 ecp.o(.text) + mbedtls_ecp_mul_restartable 0x0083683b Thumb Code 34 ecp.o(.text) + mbedtls_ecp_mul 0x0083685d Thumb Code 34 ecp.o(.text) + mbedtls_ecp_muladd_restartable 0x00836967 Thumb Code 436 ecp.o(.text) + mbedtls_ecp_muladd 0x00836b1b Thumb Code 24 ecp.o(.text) + mbedtls_ecp_gen_privkey 0x00836b33 Thumb Code 78 ecp.o(.text) + mbedtls_ecp_gen_keypair_base 0x00836b81 Thumb Code 90 ecp.o(.text) + mbedtls_ecp_gen_keypair 0x00836bdb Thumb Code 28 ecp.o(.text) + mbedtls_ecp_gen_key 0x00836bf7 Thumb Code 48 ecp.o(.text) + mbedtls_ecp_read_key 0x00836c27 Thumb Code 72 ecp.o(.text) + mbedtls_ecp_write_key 0x00836c6f Thumb Code 28 ecp.o(.text) + mbedtls_ecp_check_pub_priv 0x00836c8b Thumb Code 200 ecp.o(.text) + mbedtls_ecp_export 0x00836d53 Thumb Code 46 ecp.o(.text) + mbedtls_ecp_group_load 0x00837e79 Thumb Code 142 ecp_curves.o(.text) + mbedtls_gcm_init 0x00837fc1 Thumb Code 12 gcm.o(.text) + mbedtls_gcm_setkey 0x00837fcd Thumb Code 802 gcm.o(.text) + mbedtls_gcm_starts 0x00838479 Thumb Code 270 gcm.o(.text) + mbedtls_gcm_update_ad 0x00838587 Thumb Code 212 gcm.o(.text) + mbedtls_gcm_update 0x008386fd Thumb Code 400 gcm.o(.text) + mbedtls_gcm_finish 0x0083888d Thumb Code 412 gcm.o(.text) + mbedtls_gcm_crypt_and_tag 0x00838a29 Thumb Code 84 gcm.o(.text) + mbedtls_gcm_auth_decrypt 0x00838a7d Thumb Code 82 gcm.o(.text) + mbedtls_gcm_free 0x00838acf Thumb Code 26 gcm.o(.text) + mbedtls_md_info_from_type 0x00838aed Thumb Code 20 md.o(.text) + mbedtls_md_init 0x00838b01 Thumb Code 10 md.o(.text) + mbedtls_md_free 0x00838b0b Thumb Code 70 md.o(.text) + mbedtls_md_clone 0x00838b51 Thumb Code 54 md.o(.text) + mbedtls_md_setup 0x00838b87 Thumb Code 130 md.o(.text) + mbedtls_md_starts 0x00838c09 Thumb Code 44 md.o(.text) + mbedtls_md_update 0x00838c35 Thumb Code 36 md.o(.text) + mbedtls_md_finish 0x00838c59 Thumb Code 36 md.o(.text) + mbedtls_md 0x00838c7d Thumb Code 56 md.o(.text) + mbedtls_md_get_size 0x00838cb5 Thumb Code 8 md.o(.text) + mbedtls_md_get_type 0x00838cbd Thumb Code 8 md.o(.text) + mbedtls_md_list 0x00838cc5 Thumb Code 4 md.o(.text) + mbedtls_md_info_from_string 0x00838cc9 Thumb Code 54 md.o(.text) + mbedtls_md_get_name 0x00838cff Thumb Code 26 md.o(.text) + mbedtls_md_info_from_ctx 0x00838d19 Thumb Code 8 md.o(.text) + mbedtls_md_hmac_starts 0x00838d21 Thumb Code 200 md.o(.text) + mbedtls_md_hmac_update 0x00838de9 Thumb Code 22 md.o(.text) + mbedtls_md_hmac_finish 0x00838dff Thumb Code 98 md.o(.text) + mbedtls_md_hmac_reset 0x00838e61 Thumb Code 46 md.o(.text) + mbedtls_md_hmac 0x00838e8f Thumb Code 140 md.o(.text) + mbedtls_sha256_init 0x00838f1b Thumb Code 10 sha256.o(.text) + mbedtls_sha256_free 0x00838f25 Thumb Code 16 sha256.o(.text) + mbedtls_sha256_clone 0x00838f35 Thumb Code 10 sha256.o(.text) + mbedtls_sha256_starts 0x00838f3f Thumb Code 10 sha256.o(.text) + mbedtls_internal_sha256_process 0x00838f49 Thumb Code 12 sha256.o(.text) + mbedtls_sha256_update 0x00838f55 Thumb Code 10 sha256.o(.text) + mbedtls_sha256_finish 0x00838f5f Thumb Code 10 sha256.o(.text) + mbedtls_sha256 0x00838f69 Thumb Code 10 sha256.o(.text) + mbedtls_platform_zeroize 0x00838f75 Thumb Code 16 platform_util.o(.text) + mbedtls_zeroize_and_free 0x00838f85 Thumb Code 28 platform_util.o(.text) + mbedtls_platform_frng 0x00838fa1 Thumb Code 68 platform_util.o(.text) + gap_lib_handle_btif_msg 0x00838fe9 Thumb Code 40 gap_lib.o(.text) + gap_lib_init 0x00839011 Thumb Code 22 gap_lib.o(.text) + btif_vendor_cmd_req 0x00839035 Thumb Code 26 gap_lib_system_call.o(.text) + btif_sw_reset_req 0x0083904f Thumb Code 18 gap_lib_system_call.o(.text) + BTIF_VendorGetResponse 0x00839061 Thumb Code 20 gap_lib_system_call.o(.text) + btif_send_event 0x00839075 Thumb Code 20 gap_lib_system_call.o(.text) + hci_if_open 0x00839089 Thumb Code 18 gap_lib_system_call.o(.text) + hci_if_close 0x0083909b Thumb Code 16 gap_lib_system_call.o(.text) + hci_if_write 0x008390ab Thumb Code 20 gap_lib_system_call.o(.text) + hci_if_confirm 0x008390bf Thumb Code 18 gap_lib_system_call.o(.text) + gap_start_bt_stack 0x008390d1 Thumb Code 28 gap_lib_system_call.o(.text) + gap_register_app_cb 0x008390ed Thumb Code 18 gap_lib_system_call.o(.text) + gap_set_param 0x008390ff Thumb Code 28 gap_lib_system_call.o(.text) + gap_get_param 0x0083911b Thumb Code 22 gap_lib_system_call.o(.text) + gap_set_pairable_mode 0x00839131 Thumb Code 18 gap_lib_system_call.o(.text) + gap_write_airplan_mode 0x00839143 Thumb Code 20 gap_lib_system_call.o(.text) + gap_read_airplan_mode 0x00839157 Thumb Code 18 gap_lib_system_call.o(.text) + gap_handle_msg 0x00839169 Thumb Code 14 gap_lib_system_call.o(.text) + gap_buffer_free 0x00839177 Thumb Code 20 gap_lib_system_call.o(.text) + gap_register_extend_cb 0x0083918b Thumb Code 14 gap_lib_system_call.o(.text) + gap_register_direct_cb 0x00839199 Thumb Code 14 gap_lib_system_call.o(.text) + gap_send_dev_state 0x008391a7 Thumb Code 14 gap_lib_system_call.o(.text) + le_gap_init 0x008391b5 Thumb Code 18 gap_lib_system_call.o(.text) + le_gap_msg_info_way 0x008391c7 Thumb Code 14 gap_lib_system_call.o(.text) + le_get_max_link_num 0x008391d5 Thumb Code 18 gap_lib_system_call.o(.text) + le_register_app_cb 0x008391e7 Thumb Code 18 gap_lib_system_call.o(.text) + le_set_gap_param 0x008391f9 Thumb Code 28 gap_lib_system_call.o(.text) + le_get_gap_param 0x00839215 Thumb Code 22 gap_lib_system_call.o(.text) + le_modify_white_list 0x0083922b Thumb Code 28 gap_lib_system_call.o(.text) + le_gen_rand_addr 0x00839247 Thumb Code 22 gap_lib_system_call.o(.text) + le_set_rand_addr 0x0083925d Thumb Code 20 gap_lib_system_call.o(.text) + le_cfg_local_identity_address 0x00839271 Thumb Code 22 gap_lib_system_call.o(.text) + le_set_host_chann_classif 0x00839287 Thumb Code 20 gap_lib_system_call.o(.text) + le_write_default_data_len 0x0083929b Thumb Code 22 gap_lib_system_call.o(.text) + le_vendor_set_rem_min_sca 0x008392b1 Thumb Code 20 gap_lib_system_call.o(.text) + server_init 0x008392c5 Thumb Code 14 gap_lib_system_call.o(.text) + server_builtin_service_reg 0x008392d3 Thumb Code 12 gap_lib_system_call.o(.text) + server_add_service 0x008392df Thumb Code 44 gap_lib_system_call.o(.text) + server_add_service_by_start_handle 0x0083930b Thumb Code 44 gap_lib_system_call.o(.text) + server_register_app_cb 0x00839337 Thumb Code 14 gap_lib_system_call.o(.text) + server_attr_read_confirm 0x00839345 Thumb Code 42 gap_lib_system_call.o(.text) + server_exec_write_confirm 0x0083936f Thumb Code 28 gap_lib_system_call.o(.text) + server_attr_write_confirm 0x0083938b Thumb Code 30 gap_lib_system_call.o(.text) + server_send_data 0x008393a9 Thumb Code 42 gap_lib_system_call.o(.text) + server_get_write_cmd_data_buffer 0x008393d3 Thumb Code 28 gap_lib_system_call.o(.text) + server_get_start_handle 0x008393ef Thumb Code 20 gap_lib_system_call.o(.text) + server_clear_service 0x00839403 Thumb Code 18 gap_lib_system_call.o(.text) + server_set_service_reg_mode 0x00839415 Thumb Code 22 gap_lib_system_call.o(.text) + le_adv_set_param 0x0083942b Thumb Code 28 gap_lib_system_call.o(.text) + le_adv_get_param 0x00839447 Thumb Code 20 gap_lib_system_call.o(.text) + le_adv_start 0x0083945b Thumb Code 18 gap_lib_system_call.o(.text) + le_adv_stop 0x0083946d Thumb Code 18 gap_lib_system_call.o(.text) + le_adv_update_param 0x0083947f Thumb Code 18 gap_lib_system_call.o(.text) + le_adv_read_tx_power 0x00839491 Thumb Code 18 gap_lib_system_call.o(.text) + le_adv_set_tx_power 0x008394a3 Thumb Code 22 gap_lib_system_call.o(.text) + le_vendor_one_shot_adv 0x008394b9 Thumb Code 44 gap_lib_system_call.o(.text) + le_get_conn_param 0x008394e5 Thumb Code 28 gap_lib_system_call.o(.text) + le_get_conn_info 0x00839501 Thumb Code 26 gap_lib_system_call.o(.text) + le_get_conn_addr 0x0083951b Thumb Code 28 gap_lib_system_call.o(.text) + le_get_conn_id 0x00839537 Thumb Code 28 gap_lib_system_call.o(.text) + le_get_active_link_num 0x00839553 Thumb Code 18 gap_lib_system_call.o(.text) + le_get_idle_link_num 0x00839565 Thumb Code 18 gap_lib_system_call.o(.text) + le_disconnect 0x00839577 Thumb Code 20 gap_lib_system_call.o(.text) + le_read_rssi 0x0083958b Thumb Code 20 gap_lib_system_call.o(.text) + le_set_data_len 0x0083959f Thumb Code 28 gap_lib_system_call.o(.text) + le_disable_slave_latency 0x008395bb Thumb Code 22 gap_lib_system_call.o(.text) + le_update_passed_chann_map 0x008395d1 Thumb Code 20 gap_lib_system_call.o(.text) + le_update_conn_param 0x008395e5 Thumb Code 42 gap_lib_system_call.o(.text) + le_set_conn_tx_power 0x0083960f Thumb Code 28 gap_lib_system_call.o(.text) + le_get_conn_local_addr 0x0083962b Thumb Code 28 gap_lib_system_call.o(.text) + le_bond_set_param 0x00839647 Thumb Code 28 gap_lib_system_call.o(.text) + le_bond_get_param 0x00839663 Thumb Code 20 gap_lib_system_call.o(.text) + le_bond_pair 0x00839677 Thumb Code 20 gap_lib_system_call.o(.text) + le_bond_get_display_key 0x0083968b Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_passkey_input_confirm 0x008396a1 Thumb Code 28 gap_lib_system_call.o(.text) + le_bond_just_work_confirm 0x008396bd Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_passkey_display_confirm 0x008396d3 Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_user_confirm 0x008396e9 Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_cfg_local_key_distribute 0x008396ff Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_clear_all_keys 0x00839715 Thumb Code 12 gap_lib_system_call.o(.text) + le_bond_delete_by_idx 0x00839721 Thumb Code 20 gap_lib_system_call.o(.text) + le_bond_delete_by_bd 0x00839735 Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_get_sec_level 0x0083974b Thumb Code 22 gap_lib_system_call.o(.text) + le_bond_get_pair_procedure_type 0x00839761 Thumb Code 22 gap_lib_system_call.o(.text) + le_link_check_conn_id_internal 0x00839777 Thumb Code 22 gap_lib_system_call.o(.text) + le_get_conn_id_by_handle 0x0083978d Thumb Code 22 gap_lib_system_call.o(.text) + le_get_conn_handle 0x008397a3 Thumb Code 20 gap_lib_system_call.o(.text) + flash_save_local_name 0x008397b7 Thumb Code 18 gap_lib_system_call.o(.text) + flash_load_local_name 0x008397c9 Thumb Code 16 gap_lib_system_call.o(.text) + flash_save_local_appearance 0x008397d9 Thumb Code 18 gap_lib_system_call.o(.text) + flash_load_local_appearance 0x008397eb Thumb Code 18 gap_lib_system_call.o(.text) + flash_save_local_irk 0x008397fd Thumb Code 18 gap_lib_system_call.o(.text) + flash_load_local_irk 0x0083980f Thumb Code 18 gap_lib_system_call.o(.text) + le_find_key_entry 0x00839821 Thumb Code 20 gap_lib_system_call.o(.text) + le_find_key_entry_by_idx 0x00839835 Thumb Code 18 gap_lib_system_call.o(.text) + le_get_bond_dev_num 0x00839847 Thumb Code 18 gap_lib_system_call.o(.text) + le_get_low_priority_bond 0x00839859 Thumb Code 16 gap_lib_system_call.o(.text) + le_get_high_priority_bond 0x00839869 Thumb Code 16 gap_lib_system_call.o(.text) + le_set_high_priority_bond 0x00839879 Thumb Code 22 gap_lib_system_call.o(.text) + le_resolve_random_address 0x0083988f Thumb Code 28 gap_lib_system_call.o(.text) + le_get_cccd_data 0x008398ab Thumb Code 22 gap_lib_system_call.o(.text) + le_find_key_entry_v2 0x008398c1 Thumb Code 28 gap_lib_system_call.o(.text) + le_set_high_priority_bond_v2 0x008398dd Thumb Code 32 gap_lib_system_call.o(.text) + le_gen_bond_dev 0x008398fd Thumb Code 40 gap_lib_system_call.o(.text) + le_gen_bond_dev_v2 0x00839925 Thumb Code 46 gap_lib_system_call.o(.text) + le_clear_cccd_data 0x00839953 Thumb Code 22 gap_lib_system_call.o(.text) + le_get_dev_irk 0x00839969 Thumb Code 28 gap_lib_system_call.o(.text) + le_get_max_le_paired_device_num 0x00839985 Thumb Code 18 gap_lib_system_call.o(.text) + le_get_dev_bond_info_len 0x00839997 Thumb Code 18 gap_lib_system_call.o(.text) + le_get_dev_bond_info 0x008399a9 Thumb Code 22 gap_lib_system_call.o(.text) + le_set_dev_bond_info 0x008399bf Thumb Code 26 gap_lib_system_call.o(.text) + le_get_dev_info 0x008399d9 Thumb Code 26 gap_lib_system_call.o(.text) + le_set_local_ltk 0x008399f3 Thumb Code 32 gap_lib_system_call.o(.text) + le_privacy_check_resolvable_private_address 0x00839a13 Thumb Code 22 gap_lib_system_call.o(.text) + le_dtm_receiver_test 0x00839a29 Thumb Code 20 gap_lib_system_call.o(.text) + le_dtm_transmitter_test 0x00839a3d Thumb Code 26 gap_lib_system_call.o(.text) + le_dtm_test_end 0x00839a57 Thumb Code 18 gap_lib_system_call.o(.text) + gatt_register_callback 0x00839a69 Thumb Code 12 gap_lib_system_call.o(.text) + gaps_set_parameter 0x00839a75 Thumb Code 28 gap_lib_system_call.o(.text) + gaps_set_peripheral_preferred_conn_param 0x00839a91 Thumb Code 20 gap_lib_system_call.o(.text) + gatts_service_changed_indicate 0x00839aa5 Thumb Code 28 gap_lib_system_call.o(.text) + ADC_CalibrationInit 0x00839b61 Thumb Code 456 adc_lib.o(.text) + ADC_GetVoltage 0x00839d29 Thumb Code 132 adc_lib.o(.text) + ADC_GetResistance 0x00839dad Thumb Code 20 adc_lib.o(.text) + Timer4_Handler 0x00839dd9 Thumb Code 40 key_crypto.o(.text) + fmna_main_task 0x00839e01 Thumb Code 84 key_crypto.o(.text) + fmna_task_init 0x00839e55 Thumb Code 26 key_crypto.o(.text) + hw_timer_driver_init 0x00839e6f Thumb Code 76 key_crypto.o(.text) + crypto_exit_dlps_config 0x00839ebb Thumb Code 46 key_crypto.o(.text) + crypto_enter_dlps_config 0x00839ee9 Thumb Code 30 key_crypto.o(.text) + fmna_rotate_key_internal 0x00839f07 Thumb Code 66 key_crypto.o(.text) + gap_register_vendor_cb 0x00839f71 Thumb Code 6 gap_vendor_cmd.o(.text) + gap_set_lps_bootup_active_time 0x00839f77 Thumb Code 42 gap_vendor_cmd.o(.text) + lps_get_wakeup_time 0x00839fa1 Thumb Code 14 gap_vendor_cmd.o(.text) + le_vendor_adv_3_data_enable 0x00839faf Thumb Code 36 gap_vendor_cmd.o(.text) + le_vendor_adv_3_data_set 0x00839fd3 Thumb Code 98 gap_vendor_cmd.o(.text) + le_vendor_drop_acl_data 0x0083a035 Thumb Code 92 gap_vendor_cmd.o(.text) + le_vendor_update_conn_param 0x0083a091 Thumb Code 102 gap_vendor_cmd.o(.text) + le_vendor_trigger_internal_32k_calibration 0x0083a0f7 Thumb Code 30 gap_vendor_cmd.o(.text) + le_handle_vendor_cmd_rsp 0x0083a115 Thumb Code 370 gap_vendor_cmd.o(.text) + gap_vendor_cmd_req 0x0083a287 Thumb Code 18 gap_vendor_cmd.o(.text) + le_handle_vendor_evt_info 0x0083a299 Thumb Code 22 gap_vendor_cmd.o(.text) + le_vendor_modify_bt_le_fw_policy 0x0083a2af Thumb Code 58 gap_vendor_cmd.o(.text) + le_vendor_check_priority_level 0x0083a2e9 Thumb Code 12 gap_vendor_cmd.o(.text) + le_vendor_set_priority 0x0083a2f5 Thumb Code 378 gap_vendor_cmd.o(.text) + le_vendor_more_precise_32k_option 0x0083a46f Thumb Code 42 gap_vendor_cmd.o(.text) + le_vendor_measure_master_clk_freq_mode 0x0083a499 Thumb Code 42 gap_vendor_cmd.o(.text) + gap_vendor_set_ant_ctrl 0x0083a4c3 Thumb Code 68 gap_vendor_cmd.o(.text) + gap_vendor_read_thermal_meter_data 0x0083a507 Thumb Code 24 gap_vendor_cmd.o(.text) + vsnprintf 0x0083a531 Thumb Code 50 vsnprintf.o(.text) + srand 0x0083a569 Thumb Code 44 rand.o(.text) + _rand_init 0x0083a595 Thumb Code 4 rand.o(.text) + __aeabi_memmove4 0x0083a5a5 Thumb Code 70 rt_memmove.o(.text) + __aeabi_memmove8 0x0083a5a5 Thumb Code 0 rt_memmove.o(.text) + __aeabi_memmove 0x0083a5eb Thumb Code 80 rt_memmove.o(.text) + __rt_memmove 0x0083a5eb Thumb Code 0 rt_memmove.o(.text) + memset 0x0083a63b Thumb Code 28 memset.o(.text) + strcmp 0x0083a659 Thumb Code 160 strcmpv6m.o(.text) + __aeabi_uidiv 0x0083a6f9 Thumb Code 0 aeabi_sdivfast.o(.text) + __aeabi_uidivmod 0x0083a6f9 Thumb Code 28 aeabi_sdivfast.o(.text) + __aeabi_idiv 0x0083a715 Thumb Code 0 aeabi_sdivfast.o(.text) + __aeabi_idivmod 0x0083a715 Thumb Code 460 aeabi_sdivfast.o(.text) + __aeabi_d2f 0x0083a8e1 Thumb Code 0 d2f.o(.text) + _d2f 0x0083a8e1 Thumb Code 120 d2f.o(.text) + __aeabi_dadd 0x0083ac55 Thumb Code 0 daddsub.o(.text) + _dadd 0x0083ac55 Thumb Code 26 daddsub.o(.text) + __aeabi_dsub 0x0083ac6f Thumb Code 0 daddsub.o(.text) + _dsub 0x0083ac6f Thumb Code 22 daddsub.o(.text) + __aeabi_drsub 0x0083ac85 Thumb Code 0 daddsub.o(.text) + _drsb 0x0083ac85 Thumb Code 28 daddsub.o(.text) + __aeabi_d2uiz 0x0083acb5 Thumb Code 0 dfixui.o(.text) + _dfixu 0x0083acb5 Thumb Code 68 dfixui.o(.text) + __aeabi_i2d_normalise 0x0083acfd Thumb Code 66 dflti.o(.text) + __aeabi_i2d 0x0083ad3f Thumb Code 16 dflti.o(.text) + _dflt 0x0083ad3f Thumb Code 0 dflti.o(.text) + __aeabi_ui2d 0x0083ad4f Thumb Code 6 dflti.o(.text) + _dfltu 0x0083ad4f Thumb Code 0 dflti.o(.text) + __aeabi_dmul 0x0083ad55 Thumb Code 0 dmul.o(.text) + _dmul 0x0083ad55 Thumb Code 558 dmul.o(.text) + __aeabi_fdiv 0x0083af9d Thumb Code 0 fdiv.o(.text) + _fdiv 0x0083af9d Thumb Code 334 fdiv.o(.text) + _frdiv 0x0083b0eb Thumb Code 8 fdiv.o(.text) + __aeabi_f2uiz 0x0083b0fd Thumb Code 0 ffixui.o(.text) + _ffixu 0x0083b0fd Thumb Code 48 ffixui.o(.text) + __aeabi_i2f_normalise 0x0083b12d Thumb Code 72 fflti.o(.text) + __aeabi_i2f 0x0083b175 Thumb Code 16 fflti.o(.text) + _fflt 0x0083b175 Thumb Code 0 fflti.o(.text) + __aeabi_ui2f 0x0083b185 Thumb Code 6 fflti.o(.text) + _ffltu 0x0083b185 Thumb Code 0 fflti.o(.text) + _printf_pre_padding 0x0083b18b Thumb Code 44 _printf_pad.o(.text) + _printf_post_padding 0x0083b1b7 Thumb Code 34 _printf_pad.o(.text) + _printf_truncate_signed 0x0083b1d9 Thumb Code 18 _printf_truncate.o(.text) + _printf_truncate_unsigned 0x0083b1eb Thumb Code 18 _printf_truncate.o(.text) + _printf_str 0x0083b1fd Thumb Code 82 _printf_str.o(.text) + _printf_int_dec 0x0083b251 Thumb Code 90 _printf_dec.o(.text) + _printf_charcount 0x0083b2bd Thumb Code 38 _printf_charcount.o(.text) + _printf_char_common 0x0083b2ef Thumb Code 32 _printf_char_common.o(.text) + _sputc 0x0083b315 Thumb Code 10 _sputc.o(.text) + _snputc 0x0083b31f Thumb Code 16 _snputc.o(.text) + _printf_wctomb 0x0083b331 Thumb Code 182 _printf_wctomb.o(.text) + _printf_longlong_dec 0x0083b3ed Thumb Code 94 _printf_longlong_dec.o(.text) + _printf_longlong_oct 0x0083b45d Thumb Code 68 _printf_oct_int_ll.o(.text) + _printf_int_oct 0x0083b4a1 Thumb Code 24 _printf_oct_int_ll.o(.text) + _printf_ll_oct 0x0083b4b9 Thumb Code 10 _printf_oct_int_ll.o(.text) + _printf_longlong_hex 0x0083b4cd Thumb Code 88 _printf_hex_int_ll_ptr.o(.text) + _printf_int_hex 0x0083b525 Thumb Code 28 _printf_hex_int_ll_ptr.o(.text) + _printf_ll_hex 0x0083b541 Thumb Code 10 _printf_hex_int_ll_ptr.o(.text) + _printf_hex_ptr 0x0083b54b Thumb Code 22 _printf_hex_int_ll_ptr.o(.text) + __printf 0x0083b565 Thumb Code 386 __printf_flags_ss_wp.o(.text) + _ll_udiv10 0x0083b6ed Thumb Code 122 lludiv10.o(.text) + _printf_int_common 0x0083b767 Thumb Code 176 _printf_intcommon.o(.text) + __lib_sel_fp_printf 0x0083b819 Thumb Code 2 _printf_fp_dec.o(.text) + _printf_fp_dec_real 0x0083b9b7 Thumb Code 620 _printf_fp_dec.o(.text) + _printf_fp_hex_real 0x0083bc31 Thumb Code 718 _printf_fp_hex.o(.text) + _printf_cs_common 0x0083bf09 Thumb Code 22 _printf_char.o(.text) + _printf_char 0x0083bf1f Thumb Code 16 _printf_char.o(.text) + _printf_string 0x0083bf2f Thumb Code 8 _printf_char.o(.text) + _printf_lcs_common 0x0083bf37 Thumb Code 22 _printf_wchar.o(.text) + _printf_wchar 0x0083bf4d Thumb Code 16 _printf_wchar.o(.text) + _printf_wstring 0x0083bf5d Thumb Code 8 _printf_wchar.o(.text) + _wcrtomb 0x0083bf65 Thumb Code 64 _wcrtomb.o(.text) + __rt_udiv10 0x0083bfa5 Thumb Code 40 rtudiv10.o(.text) + __rt_ctype_table 0x0083bfcd Thumb Code 16 rt_ctype_table.o(.text) + __rt_locale 0x0083bfdd Thumb Code 8 rt_locale.o(.text) + _printf_fp_infnan 0x0083bfe5 Thumb Code 120 _printf_fp_infnan.o(.text) + _btod_etento 0x0083c06d Thumb Code 210 bigflt0.o(.text) + _btod_d2e 0x0083c145 Thumb Code 64 btod.o(.text) + _btod_emul 0x0083c579 Thumb Code 28 btod.o(.text) + _btod_emuld 0x0083c595 Thumb Code 144 btod.o(.text) + _btod_ediv 0x0083c625 Thumb Code 26 btod.o(.text) + _btod_edivd 0x0083c63f Thumb Code 124 btod.o(.text) + __ARM_common_ll_muluu 0x0083c6c5 Thumb Code 48 btod.o(i.__ARM_common_ll_muluu) + __ARM_common_memcpy1_6 0x0083c6f5 Thumb Code 26 custom_app.o(i.__ARM_common_memcpy1_6) + __ARM_common_memcpy1_8 0x0083c70f Thumb Code 34 overlay_mgr.o(i.__ARM_common_memcpy1_8) + __ARM_common_memcpy4_5 0x0083c731 Thumb Code 10 custom_app.o(i.__ARM_common_memcpy4_5) + __ARM_common_switch8 0x0083c73b Thumb Code 26 gap_vendor_cmd.o(i.__ARM_common_switch8) + __ARM_fpclassify 0x0083c755 Thumb Code 40 fpclassify.o(i.__ARM_fpclassify) + _is_digit 0x0083c781 Thumb Code 14 __printf_wp.o(i._is_digit) + _get_lc_numeric 0x0083c791 Thumb Code 44 lc_numeric_c.o(locale$$code) + _get_lc_ctype 0x0083c7bd Thumb Code 44 lc_ctype_c.o(locale$$code) + __aeabi_fadd 0x0083c7e9 Thumb Code 0 faddsub.o(x$fpl$fadd) + _fadd 0x0083c7e9 Thumb Code 134 faddsub.o(x$fpl$fadd) + __aeabi_fmul 0x0083c875 Thumb Code 0 fmul.o(x$fpl$fmul) + _fmul 0x0083c875 Thumb Code 172 fmul.o(x$fpl$fmul) + __aeabi_fsub 0x0083c925 Thumb Code 0 faddsub.o(x$fpl$fsub) + _fsub 0x0083c925 Thumb Code 204 faddsub.o(x$fpl$fsub) + _printf_fp_dec 0x0083c9f5 Thumb Code 16 printf1.o(x$fpl$printf1) + _printf_fp_hex 0x0083ca05 Thumb Code 16 printf2.o(x$fpl$printf2) + __I$use$fp 0x0083ca14 Number 0 usenofp.o(x$fpl$usenofp) + app_cb_table 0x0083ca14 Data 12 system_rtl876x.o(.constdata) + PINADDR_TABLE 0x0083cb20 Data 78 rtl876x_pinmux.o(.constdata) + WKSTATUS_TABLE 0x0083cb6e Data 78 rtl876x_pinmux.o(.constdata) + fns_attr_tbl 0x0083cbbc Data 448 findmy_network_service.o(.constdata) + fns_ble_cbs 0x0083cd7c Data 12 findmy_network_service.o(.constdata) + GATT_UUID_ACC_INFO_SERVICE 0x0083cd88 Data 16 accessory_info_service.o(.constdata) + bat_type 0x0083cd98 Data 1 accessory_info_service.o(.constdata) + findmy_vers 0x0083cd9c Data 4 accessory_info_service.o(.constdata) + product_data 0x0083cda0 Data 8 accessory_info_service.o(.constdata) + accessory_category 0x0083cda8 Data 8 accessory_info_service.o(.constdata) + manu_name 0x0083cdb0 Data 64 accessory_info_service.o(.constdata) + model_name 0x0083cdf0 Data 64 accessory_info_service.o(.constdata) + ais_attr_tbl 0x0083ce30 Data 532 accessory_info_service.o(.constdata) + ais_ble_cbs 0x0083d044 Data 12 accessory_info_service.o(.constdata) + tps_attr_tbl 0x0083d050 Data 252 tps.o(.constdata) + tps_cbs 0x0083d14c Data 12 tps.o(.constdata) + ias_attr_tbl 0x0083d158 Data 84 ias.o(.constdata) + ias_cbs 0x0083d1ac Data 12 ias.o(.constdata) + sdd_cbs 0x0083d228 Data 12 sdd_service.o(.constdata) + dis_cbs 0x0083d448 Data 12 dis.o(.constdata) + fmna_separated_adv_fast_intv 0x0083d4c8 Data 2 fmna_adv.o(.constdata) + fmna_separated_adv_fast_duration 0x0083d4cc Data 4 fmna_adv.o(.constdata) + fmna_separated_adv_slow_intv 0x0083d4d0 Data 2 fmna_adv.o(.constdata) + fmna_separated_adv_slow_duration 0x0083d4d4 Data 4 fmna_adv.o(.constdata) + fmna_nearby_adv_fast_intv 0x0083d4d8 Data 2 fmna_adv.o(.constdata) + fmna_nearby_adv_fast_duration 0x0083d4dc Data 4 fmna_adv.o(.constdata) + fmna_nearby_adv_intv 0x0083d4e0 Data 2 fmna_adv.o(.constdata) + fmna_nearby_adv_duration 0x0083d4e4 Data 4 fmna_adv.o(.constdata) + fmna_pairing_adv_fast_intv 0x0083d4e8 Data 2 fmna_adv.o(.constdata) + fmna_pairing_adv_fast_duration 0x0083d4ec Data 4 fmna_adv.o(.constdata) + fmna_pairing_adv_slow_intv 0x0083d4f0 Data 2 fmna_adv.o(.constdata) + fmna_pairing_adv_slow_duration 0x0083d4f4 Data 4 fmna_adv.o(.constdata) + m_log_chunk 0x0083d658 Data 20 fmna_debug_control_point.o(.constdata) + KDF_LABEL_UPDATE 0x0083daf8 Data 7 fm-crypto.o(.constdata) + KDF_LABEL_CONNECT 0x0083daff Data 8 fm-crypto.o(.constdata) + KDF_LABEL_DIVERSIFY 0x0083db07 Data 10 fm-crypto.o(.constdata) + KDF_LABEL_INTERMEDIATE 0x0083db11 Data 13 fm-crypto.o(.constdata) + KDF_LABEL_SERVERSS 0x0083db1e Data 19 fm-crypto.o(.constdata) + KDF_LABEL_PAIRINGSESS 0x0083db31 Data 15 fm-crypto.o(.constdata) + KDF_LABEL_SNPROTECTION 0x0083db40 Data 23 fm-crypto.o(.constdata) + mbedtls_cipher_definitions 0x0083dc28 Data 56 cipher_wrap.o(.constdata) + __ctype 0x0083f135 Data 0 lc_ctype_c.o(locale$$data) + Load$$RAM_VECTOR_TABLE$$RO$$Base 0x0083f238 Number 0 anon$$obj.o ABSOLUTE + Load$$RAM_DATA_ON$$RO$$Base 0x0083f320 Number 0 anon$$obj.o ABSOLUTE + Load$$RAM_DATA_ON$$RW$$Base 0x00840220 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_A$$RO$$Base 0x00840568 Number 0 anon$$obj.o ABSOLUTE + Load$$CACHE_DATA_ON$$RO$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$CACHE_DATA_ON$$RW$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_A$$RW$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_B$$RO$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_B$$RW$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_C$$RO$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + Load$$OVERLAY_C$$RW$$Base 0x00840640 Number 0 anon$$obj.o ABSOLUTE + + + +============================================================================== + +Memory Map of the image + + Image Entry point : 0x00825409 + + Load Region LOAD_FLASH (Base: 0x00825000, Size: 0x0001b640, Max: 0x00028000, ABSOLUTE) + + Execution Region RAM_VECTOR_TABLE (Exec base: 0x00200000, Load base: 0x0083f238, Size: 0x000000e8, Max: 0x000000e8, OVERLAY) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x00200000 0x0083f238 0x000000e8 Data RO 1 VECTOR startup_rtl876x.o + + + Execution Region RAM_DATA_ON (Exec base: 0x00207c00, Load base: 0x0083f320, Size: 0x0000315c, Max: 0x00004800, OVERLAY) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x00207c00 0x0083f320 0x00000114 Code RO 14 .app.data_ram.text system_rtl876x.o + 0x00207d14 0x0083f434 0x00000620 Code RO 203 .app.data_ram.text rtl876x_io_dlps.o + 0x00208334 0x0083fa54 0x00000048 Code RO 1123 .app.data_ram.text reset_watch_dog_timer.o + 0x0020837c 0x0083fa9c 0x00000030 Code RO 2281 .app.data_ram.text fmna_timer_platform.o + 0x002083ac 0x0083facc 0x00000754 Code RO 2634 .app.data_ram.text bignum.o + 0x00208b00 0x00840220 0x00000004 Data RW 407 .data rtl876x_i2c.o + 0x00208b04 0x00840224 0x00000014 Data RW 594 .data tps.o + 0x00208b18 0x00840238 0x00000001 Data RW 671 .data sdd_service.o + 0x00208b19 0x00840239 0x000000ad Data RW 693 .data dis.o + 0x00208bc6 0x008402e6 0x00000001 Data RW 883 .data findmy_app.o + 0x00208bc7 0x008402e7 0x0000003f Data RW 1035 .data custom_app.o + 0x00208c06 0x00840326 0x00000002 PAD + 0x00208c08 0x00840328 0x0000006c Data RW 1104 .data overlay_mgr.o + 0x00208c74 0x00840394 0x0000003e Data RW 1156 .data serial_number_send.o + 0x00208cb2 0x008403d2 0x00000028 Data RW 1311 .data fmna_config_control_point.o + 0x00208cda 0x008403fa 0x00000001 Data RW 1352 .data fmna_connection.o + 0x00208cdb 0x008403fb 0x00000001 PAD + 0x00208cdc 0x008403fc 0x00000010 Data RW 1574 .data fmna_debug_control_point.o + 0x00208cec 0x0084040c 0x00000002 Data RW 1607 .data fmna_gatt.o + 0x00208cee 0x0084040e 0x00000002 PAD + 0x00208cf0 0x00840410 0x00000008 Data RW 1652 .data fmna_motion_detection.o + 0x00208cf8 0x00840418 0x0000000c Data RW 1715 .data fmna_nonowner_control_point.o + 0x00208d04 0x00840424 0x0000000c Data RW 1747 .data fmna_paired_owner_control_point.o + 0x00208d10 0x00840430 0x0000000c Data RW 1775 .data fmna_pairing_control_point.o + 0x00208d1c 0x0084043c 0x00000088 Data RW 1817 .data fmna_state_machine.o + 0x00208da4 0x008404c4 0x0000005b Data RW 1983 .data fmna_adv_platform.o + 0x00208dff 0x0084051f 0x00000002 Data RW 2153 .data fmna_gatt_platform.o + 0x00208e01 0x00840521 0x00000003 PAD + 0x00208e04 0x00840524 0x00000008 Data RW 2758 .data cipher_wrap.o + 0x00208e0c 0x0084052c 0x00000004 Data RW 2961 .data ecp_curves.o + 0x00208e10 0x00840530 0x00000004 Data RW 3088 .data platform_util.o + 0x00208e14 0x00840534 0x00000032 Data RW 3170 .data adc.lib(adc_lib.o) + 0x00208e46 0x00840566 0x00000001 Data RW 3202 .data key_crypto.lib(key_crypto.o) + 0x00208e47 0x00840567 0x00000001 PAD + 0x00208e48 - 0x00000014 Zero RW 20 .bss system_rtl876x.o + 0x00208e5c - 0x00000188 Zero RW 206 .bss rtl876x_io_dlps.o + 0x00208fe4 - 0x00000001 Zero RW 433 .bss rtl876x_aon_wdg.o + 0x00208fe5 0x00840567 0x00000003 PAD + 0x00208fe8 - 0x00000008 Zero RW 459 .bss findmy_network_service.o + 0x00208ff0 - 0x0000000c Zero RW 531 .bss accessory_info_service.o + 0x00208ffc - 0x00000008 Zero RW 591 .bss tps.o + 0x00209004 - 0x00000004 Zero RW 648 .bss ias.o + 0x00209008 - 0x00000008 Zero RW 669 .bss sdd_service.o + 0x00209010 - 0x00000004 Zero RW 690 .bss dis.o + 0x00209014 - 0x00000010 Zero RW 841 .bss app_task.o + 0x00209024 - 0x00000039 Zero RW 882 .bss findmy_app.o + 0x0020905d 0x00840567 0x00000003 PAD + 0x00209060 - 0x00000038 Zero RW 1033 .bss custom_app.o + 0x00209098 - 0x00000008 Zero RW 1102 .bss overlay_mgr.o + 0x002090a0 - 0x00000030 Zero RW 1155 .bss serial_number_send.o + 0x002090d0 - 0x0000001c Zero RW 1219 .bss key_handle.o + 0x002090ec - 0x00000034 Zero RW 1253 .bss fmna_adv.o + 0x00209120 - 0x00000028 Zero RW 1350 .bss fmna_connection.o + 0x00209148 - 0x0000078d Zero RW 1393 .bss fmna_crypto.o + 0x002098d5 0x00840567 0x00000003 PAD + 0x002098d8 - 0x0000012b Zero RW 1605 .bss fmna_gatt.o + 0x00209a03 - 0x00000001 Zero RW 1606 .bss fmna_gatt.o + 0x00209a04 - 0x00000010 Zero RW 1650 .bss fmna_motion_detection.o + 0x00209a14 - 0x00000001 Zero RW 1714 .bss fmna_nonowner_control_point.o + 0x00209a15 0x00840567 0x00000001 PAD + 0x00209a16 - 0x00000574 Zero RW 1774 .bss fmna_pairing_control_point.o + 0x00209f8a 0x00840567 0x00000002 PAD + 0x00209f8c - 0x000000e8 Zero RW 1805 .bss fmna_state_machine.o + 0x0020a074 - 0x00000004 Zero RW 1911 .bss fmna_version.o + 0x0020a078 - 0x00000028 Zero RW 1981 .bss fmna_adv_platform.o + 0x0020a0a0 - 0x00000002 Zero RW 2031 .bss fmna_battery_platform.o + 0x0020a0a2 - 0x00000001 Zero RW 2058 .bss fmna_connection_platform.o + 0x0020a0a3 0x00840567 0x00000001 PAD + 0x0020a0a4 - 0x0000006c Zero RW 2118 .bss fmna_gap_platform.o + 0x0020a110 - 0x0000000e Zero RW 2150 .bss fmna_gatt_platform.o + 0x0020a11e 0x00840567 0x00000002 PAD + 0x0020a120 - 0x00000038 Zero RW 2186 .bss fmna_malloc_platform.o + 0x0020a158 - 0x00000001 Zero RW 2204 .bss fmna_motion_detection_platform.o + 0x0020a159 0x00840567 0x00000003 PAD + 0x0020a15c - 0x0000002c Zero RW 2254 .bss fmna_sound_platform.o + 0x0020a188 - 0x00000018 Zero RW 2284 .bss fmna_timer_platform.o + 0x0020a1a0 - 0x00000a2c Zero RW 2501 .bss aes.o + 0x0020abcc - 0x00000004 Zero RW 2702 .bss cipher.o + 0x0020abd0 - 0x0000001c Zero RW 2741 .bss cipher_wrap.o + 0x0020abec - 0x00000004 Zero RW 2785 .bss constant_time.o + 0x0020abf0 - 0x0000000c Zero RW 2853 .bss ecp.o + 0x0020abfc - 0x00000008 Zero RW 3166 .bss gap_utils.lib(gap_lib_system_call.o) + 0x0020ac04 - 0x00000054 Zero RW 3169 .bss adc.lib(adc_lib.o) + 0x0020ac58 - 0x00000008 Zero RW 3201 .bss key_crypto.lib(key_crypto.o) + 0x0020ac60 - 0x00000004 Zero RW 3310 .bss gap_utils.lib(gap_vendor_cmd.o) + 0x0020ac64 - 0x000000e4 Zero RW 3319 .bss c_p.l(rand.o) + 0x0020ad48 - 0x00000014 Zero RW 3560 .bss c_p.l(rt_locale.o) + + + Execution Region OVERLAY_A (Exec base: 0x0020ad5c, Load base: 0x00840568, Size: 0x000000d8, Max: 0xffffffff, OVERLAY) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x0020ad5c 0x00840568 0x000000d8 Code RO 16 .app.overlay_a system_rtl876x.o + + + Execution Region OVERLAY_B (Exec base: 0x0020ad5c, Load base: 0x00840640, Size: 0x00000000, Max: 0xffffffff, OVERLAY) + + **** No section assigned to this execution region **** + + + Execution Region OVERLAY_C (Exec base: 0x0020ad5c, Load base: 0x00840640, Size: 0x00000000, Max: 0xffffffff, OVERLAY) + + **** No section assigned to this execution region **** + + + Execution Region CACHE_DATA_ON (Exec base: 0x00216000, Load base: 0x00840640, Size: 0x00000000, Max: 0x00000000, OVERLAY) + + **** No section assigned to this execution region **** + + + Execution Region app.bin (Exec base: 0x00825000, Load base: 0x00825000, Size: 0x00000400, Max: 0xffffffff, ABSOLUTE) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x00825000 0x00825000 0x00000400 Data RO 19 .app.flash.header system_rtl876x.o + + + Execution Region APP_FLASH_HEADER_EXT (Exec base: 0x00825400, Load base: 0x00825400, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE) + + **** No section assigned to this execution region **** + + + Execution Region FLASH_START_ADDR (Exec base: 0x00825400, Load base: 0x00825400, Size: 0x00000008, Max: 0xffffffff, ABSOLUTE) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x00825400 0x00825400 0x00000008 Code RO 2 RESET startup_rtl876x.o + + + Execution Region FLASH_TEXT (Exec base: 0x00825408, Load base: 0x00825408, Size: 0x00019e30, Max: 0xffffffff, ABSOLUTE) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x00825408 0x00825408 0x00000008 Code RO 3332 * !!!main c_p.l(__main.o) + 0x00825410 0x00825410 0x00000002 Code RO 3447 .ARM.Collect$$_printf_percent$$00000000 c_p.l(_printf_percent.o) + 0x00825412 0x00825412 0x0000000a Code RO 3436 .ARM.Collect$$_printf_percent$$00000001 c_p.l(_printf_n.o) + 0x0082541c 0x0082541c 0x0000000a Code RO 3438 .ARM.Collect$$_printf_percent$$00000002 c_p.l(_printf_p.o) + 0x00825426 0x00825426 0x0000000a Code RO 3443 .ARM.Collect$$_printf_percent$$00000003 c_p.l(_printf_f.o) + 0x00825430 0x00825430 0x0000000a Code RO 3444 .ARM.Collect$$_printf_percent$$00000004 c_p.l(_printf_e.o) + 0x0082543a 0x0082543a 0x0000000a Code RO 3445 .ARM.Collect$$_printf_percent$$00000005 c_p.l(_printf_g.o) + 0x00825444 0x00825444 0x0000000a Code RO 3446 .ARM.Collect$$_printf_percent$$00000006 c_p.l(_printf_a.o) + 0x0082544e 0x0082544e 0x0000000a Code RO 3451 .ARM.Collect$$_printf_percent$$00000007 c_p.l(_printf_ll.o) + 0x00825458 0x00825458 0x0000000a Code RO 3440 .ARM.Collect$$_printf_percent$$00000008 c_p.l(_printf_i.o) + 0x00825462 0x00825462 0x0000000a Code RO 3441 .ARM.Collect$$_printf_percent$$00000009 c_p.l(_printf_d.o) + 0x0082546c 0x0082546c 0x0000000a Code RO 3442 .ARM.Collect$$_printf_percent$$0000000A c_p.l(_printf_u.o) + 0x00825476 0x00825476 0x0000000a Code RO 3439 .ARM.Collect$$_printf_percent$$0000000B c_p.l(_printf_o.o) + 0x00825480 0x00825480 0x0000000a Code RO 3437 .ARM.Collect$$_printf_percent$$0000000C c_p.l(_printf_x.o) + 0x0082548a 0x0082548a 0x0000000a Code RO 3448 .ARM.Collect$$_printf_percent$$0000000D c_p.l(_printf_lli.o) + 0x00825494 0x00825494 0x0000000a Code RO 3449 .ARM.Collect$$_printf_percent$$0000000E c_p.l(_printf_lld.o) + 0x0082549e 0x0082549e 0x0000000a Code RO 3450 .ARM.Collect$$_printf_percent$$0000000F c_p.l(_printf_llu.o) + 0x008254a8 0x008254a8 0x0000000a Code RO 3455 .ARM.Collect$$_printf_percent$$00000010 c_p.l(_printf_llo.o) + 0x008254b2 0x008254b2 0x0000000a Code RO 3456 .ARM.Collect$$_printf_percent$$00000011 c_p.l(_printf_llx.o) + 0x008254bc 0x008254bc 0x0000000a Code RO 3452 .ARM.Collect$$_printf_percent$$00000012 c_p.l(_printf_l.o) + 0x008254c6 0x008254c6 0x0000000a Code RO 3434 .ARM.Collect$$_printf_percent$$00000013 c_p.l(_printf_c.o) + 0x008254d0 0x008254d0 0x0000000a Code RO 3435 .ARM.Collect$$_printf_percent$$00000014 c_p.l(_printf_s.o) + 0x008254da 0x008254da 0x0000000a Code RO 3453 .ARM.Collect$$_printf_percent$$00000015 c_p.l(_printf_lc.o) + 0x008254e4 0x008254e4 0x0000000a Code RO 3454 .ARM.Collect$$_printf_percent$$00000016 c_p.l(_printf_ls.o) + 0x008254ee 0x008254ee 0x00000004 Code RO 3548 .ARM.Collect$$_printf_percent$$00000017 c_p.l(_printf_percent_end.o) + 0x008254f2 0x008254f2 0x00000002 Code RO 3590 .ARM.Collect$$libinit$$00000000 c_p.l(libinit.o) + 0x008254f4 0x008254f4 0x00000000 Code RO 3458 .ARM.Collect$$libinit$$00000002 c_p.l(libinit2.o) + 0x008254f4 0x008254f4 0x00000000 Code RO 3460 .ARM.Collect$$libinit$$00000004 c_p.l(libinit2.o) + 0x008254f4 0x008254f4 0x00000000 Code RO 3463 .ARM.Collect$$libinit$$0000000A c_p.l(libinit2.o) + 0x008254f4 0x008254f4 0x00000000 Code RO 3465 .ARM.Collect$$libinit$$0000000C c_p.l(libinit2.o) + 0x008254f4 0x008254f4 0x00000004 Code RO 3466 .ARM.Collect$$libinit$$0000000D c_p.l(libinit2.o) + 0x008254f8 0x008254f8 0x00000000 Code RO 3467 .ARM.Collect$$libinit$$0000000E c_p.l(libinit2.o) + 0x008254f8 0x008254f8 0x00000006 Code RO 3468 .ARM.Collect$$libinit$$0000000F c_p.l(libinit2.o) + 0x008254fe 0x008254fe 0x00000000 Code RO 3470 .ARM.Collect$$libinit$$00000011 c_p.l(libinit2.o) + 0x008254fe 0x008254fe 0x0000000c Code RO 3471 .ARM.Collect$$libinit$$00000012 c_p.l(libinit2.o) + 0x0082550a 0x0082550a 0x00000000 Code RO 3472 .ARM.Collect$$libinit$$00000013 c_p.l(libinit2.o) + 0x0082550a 0x0082550a 0x00000000 Code RO 3474 .ARM.Collect$$libinit$$00000015 c_p.l(libinit2.o) + 0x0082550a 0x0082550a 0x0000000a Code RO 3475 .ARM.Collect$$libinit$$00000016 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3476 .ARM.Collect$$libinit$$00000017 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3478 .ARM.Collect$$libinit$$00000019 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3480 .ARM.Collect$$libinit$$0000001B c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3482 .ARM.Collect$$libinit$$0000001D c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3484 .ARM.Collect$$libinit$$0000001F c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3486 .ARM.Collect$$libinit$$00000021 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3488 .ARM.Collect$$libinit$$00000023 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3490 .ARM.Collect$$libinit$$00000025 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3494 .ARM.Collect$$libinit$$0000002C c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3496 .ARM.Collect$$libinit$$0000002E c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3498 .ARM.Collect$$libinit$$00000030 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000000 Code RO 3500 .ARM.Collect$$libinit$$00000032 c_p.l(libinit2.o) + 0x00825514 0x00825514 0x00000002 Code RO 3501 .ARM.Collect$$libinit$$00000033 c_p.l(libinit2.o) + 0x00825516 0x00825516 0x00000000 Code RO 3359 .ARM.Collect$$rtentry$$00000000 c_p.l(__rtentry.o) + 0x00825516 0x00825516 0x00000000 Code RO 3512 .ARM.Collect$$rtentry$$00000002 c_p.l(__rtentry2.o) + 0x00825516 0x00825516 0x00000004 Code RO 3526 .ARM.Collect$$rtentry$$00000005 c_p.l(__rtentry5.o) + 0x0082551a 0x0082551a 0x00000000 Code RO 3514 .ARM.Collect$$rtentry$$00000009 c_p.l(__rtentry2.o) + 0x0082551a 0x0082551a 0x00000004 Code RO 3515 .ARM.Collect$$rtentry$$0000000A c_p.l(__rtentry2.o) + 0x0082551e 0x0082551e 0x00000000 Code RO 3517 .ARM.Collect$$rtentry$$0000000C c_p.l(__rtentry2.o) + 0x0082551e 0x0082551e 0x00000008 Code RO 3518 .ARM.Collect$$rtentry$$0000000D c_p.l(__rtentry2.o) + 0x00825526 0x00825526 0x00000002 PAD + 0x00825528 0x00825528 0x00000004 Code RO 3527 .ARM.Collect$$rtentry$$00002716 c_p.l(__rtentry5.o) + 0x0082552c 0x0082552c 0x000004a8 Code RO 15 .app.flash.text system_rtl876x.o + 0x008259d4 0x008259d4 0x00000010 Code RO 715 .app.flash.text main.o + 0x008259e4 0x008259e4 0x00000110 Code RO 3157 .app.flash.text gap_utils.lib(gap_config.o) + 0x00825af4 0x00825af4 0x00000038 Code RO 3317 .emb_text c_p.l(rand.o) + 0x00825b2c 0x00825b2c 0x00000054 Code RO 3 .text startup_rtl876x.o + 0x00825b80 0x00825b80 0x000002a8 Code RO 17 .text system_rtl876x.o + 0x00825e28 0x00825e28 0x0000001c Code RO 204 .text rtl876x_io_dlps.o + 0x00825e44 0x00825e44 0x000001a8 Code RO 265 .text rtl876x_gpio.o + 0x00825fec 0x00825fec 0x00000340 Code RO 288 .text rtl876x_rcc.o + 0x0082632c 0x0082632c 0x000001f0 Code RO 308 .text rtl876x_tim.o + 0x0082651c 0x0082651c 0x00000440 Code RO 329 .text rtl876x_pinmux.o + 0x0082695c 0x0082695c 0x000000d0 Code RO 353 .text rtl876x_nvic.o + 0x00826a2c 0x00826a2c 0x00000324 Code RO 376 .text rtl876x_adc.o + 0x00826d50 0x00826d50 0x000004a0 Code RO 406 .text rtl876x_i2c.o + 0x008271f0 0x008271f0 0x00000280 Code RO 432 .text rtl876x_aon_wdg.o + 0x00827470 0x00827470 0x000000f8 Code RO 457 .text findmy_network_service.o + 0x00827568 0x00827568 0x00000130 Code RO 529 .text accessory_info_service.o + 0x00827698 0x00827698 0x000001d4 Code RO 589 .text tps.o + 0x0082786c 0x0082786c 0x000000bc Code RO 646 .text ias.o + 0x00827928 0x00827928 0x00000220 Code RO 667 .text sdd_service.o + 0x00827b48 0x00827b48 0x000002a8 Code RO 688 .text dis.o + 0x00827df0 0x00827df0 0x000001a8 Code RO 716 .text main.o + 0x00827f98 0x00827f98 0x000001e8 Code RO 839 .text app_task.o + 0x00828180 0x00828180 0x00000eac Code RO 880 .text findmy_app.o + 0x0082902c 0x0082902c 0x00000768 Code RO 1031 .text custom_app.o + 0x00829794 0x00829794 0x0000007c Code RO 1101 .text overlay_mgr.o + 0x00829810 0x00829810 0x00000180 Code RO 1153 .text serial_number_send.o + 0x00829990 0x00829990 0x00000248 Code RO 1190 .text da213b.o + 0x00829bd8 0x00829bd8 0x000005fc Code RO 1217 .text key_handle.o + 0x0082a1d4 0x0082a1d4 0x000001a0 Code RO 1251 .text fmna_adv.o + 0x0082a374 0x0082a374 0x000003a4 Code RO 1309 .text fmna_config_control_point.o + 0x0082a718 0x0082a718 0x00000614 Code RO 1348 .text fmna_connection.o + 0x0082ad2c 0x0082ad2c 0x00000c98 Code RO 1391 .text fmna_crypto.o + 0x0082b9c4 0x0082b9c4 0x00000164 Code RO 1571 .text fmna_debug_control_point.o + 0x0082bb28 0x0082bb28 0x0000050c Code RO 1603 .text fmna_gatt.o + 0x0082c034 0x0082c034 0x00000384 Code RO 1648 .text fmna_motion_detection.o + 0x0082c3b8 0x0082c3b8 0x00000158 Code RO 1712 .text fmna_nonowner_control_point.o + 0x0082c510 0x0082c510 0x000001b0 Code RO 1744 .text fmna_paired_owner_control_point.o + 0x0082c6c0 0x0082c6c0 0x00000120 Code RO 1772 .text fmna_pairing_control_point.o + 0x0082c7e0 0x0082c7e0 0x0000148c Code RO 1803 .text fmna_state_machine.o + 0x0082dc6c 0x0082dc6c 0x0000004c Code RO 1909 .text fmna_version.o + 0x0082dcb8 0x0082dcb8 0x00000410 Code RO 1979 .text fmna_adv_platform.o + 0x0082e0c8 0x0082e0c8 0x0000020c Code RO 2029 .text fmna_battery_platform.o + 0x0082e2d4 0x0082e2d4 0x00000338 Code RO 2056 .text fmna_connection_platform.o + 0x0082e60c 0x0082e60c 0x00000484 Code RO 2116 .text fmna_gap_platform.o + 0x0082ea90 0x0082ea90 0x00000670 Code RO 2148 .text fmna_gatt_platform.o + 0x0082f100 0x0082f100 0x00000138 Code RO 2184 .text fmna_malloc_platform.o + 0x0082f238 0x0082f238 0x0000018c Code RO 2202 .text fmna_motion_detection_platform.o + 0x0082f3c4 0x0082f3c4 0x00000070 Code RO 2227 .text fmna_peer_manager.o + 0x0082f434 0x0082f434 0x000004dc Code RO 2252 .text fmna_sound_platform.o + 0x0082f910 0x0082f910 0x000002b4 Code RO 2282 .text fmna_timer_platform.o + 0x0082fbc4 0x0082fbc4 0x00000770 Code RO 2427 .text fm-crypto.o + 0x00830334 0x00830334 0x000000b4 Code RO 2478 .text kdf963.o + 0x008303e8 0x008303e8 0x00001100 Code RO 2500 .text aes.o + 0x008314e8 0x008314e8 0x00000448 Code RO 2561 .text asn1parse.o + 0x00831930 0x00831930 0x00000498 Code RO 2585 .text asn1write.o + 0x00831dc8 0x00831dc8 0x000003b0 Code RO 2606 .text base64.o + 0x00832178 0x00832178 0x000015b4 Code RO 2635 .text bignum.o + 0x0083372c 0x0083372c 0x00000f24 Code RO 2668 .text bignum_core.o + 0x00834650 0x00834650 0x0000051c Code RO 2701 .text cipher.o + 0x00834b6c 0x00834b6c 0x00000088 Code RO 2740 .text cipher_wrap.o + 0x00834bf4 0x00834bf4 0x000000b8 Code RO 2784 .text constant_time.o + 0x00834cac 0x00834cac 0x000003f0 Code RO 2803 .text ecdh.o + 0x0083509c 0x0083509c 0x000007ec Code RO 2819 .text ecdsa.o + 0x00835888 0x00835888 0x00001f3c Code RO 2852 .text ecp.o + 0x008377c4 0x008377c4 0x000007fc Code RO 2895 .text ecp_curves.o + 0x00837fc0 0x00837fc0 0x00000b2c Code RO 2977 .text gcm.o + 0x00838aec 0x00838aec 0x0000042e Code RO 3017 .text md.o + 0x00838f1a 0x00838f1a 0x00000058 Code RO 3052 .text sha256.o + 0x00838f72 0x00838f72 0x00000002 PAD + 0x00838f74 0x00838f74 0x00000074 Code RO 3087 .text platform_util.o + 0x00838fe8 0x00838fe8 0x0000004c Code RO 3162 .text gap_utils.lib(gap_lib.o) + 0x00839034 0x00839034 0x00000a98 Code RO 3165 .text gap_utils.lib(gap_lib_system_call.o) + 0x00839acc 0x00839acc 0x0000030c Code RO 3168 .text adc.lib(adc_lib.o) + 0x00839dd8 0x00839dd8 0x00000198 Code RO 3199 .text key_crypto.lib(key_crypto.o) + 0x00839f70 0x00839f70 0x000005c0 Code RO 3309 .text gap_utils.lib(gap_vendor_cmd.o) + 0x0083a530 0x0083a530 0x00000038 Code RO 3315 .text c_p.l(vsnprintf.o) + 0x0083a568 0x0083a568 0x0000003c Code RO 3318 .text c_p.l(rand.o) + 0x0083a5a4 0x0083a5a4 0x00000096 Code RO 3322 .text c_p.l(rt_memmove.o) + 0x0083a63a 0x0083a63a 0x0000001c Code RO 3324 .text c_p.l(memset.o) + 0x0083a656 0x0083a656 0x00000002 PAD + 0x0083a658 0x0083a658 0x000000a0 Code RO 3326 .text c_p.l(strcmpv6m.o) + 0x0083a6f8 0x0083a6f8 0x000001e8 Code RO 3328 .text c_p.l(aeabi_sdivfast.o) + 0x0083a8e0 0x0083a8e0 0x0000007c Code RO 3334 .text fz_ps.l(d2f.o) + 0x0083a95c 0x0083a95c 0x00000358 Code RO 3336 .text fz_ps.l(daddsub.o) + 0x0083acb4 0x0083acb4 0x00000048 Code RO 3338 .text fz_ps.l(dfixui.o) + 0x0083acfc 0x0083acfc 0x00000058 Code RO 3340 .text fz_ps.l(dflti.o) + 0x0083ad54 0x0083ad54 0x00000248 Code RO 3342 .text fz_ps.l(dmul.o) + 0x0083af9c 0x0083af9c 0x00000160 Code RO 3350 .text fz_ps.l(fdiv.o) + 0x0083b0fc 0x0083b0fc 0x00000030 Code RO 3353 .text fz_ps.l(ffixui.o) + 0x0083b12c 0x0083b12c 0x0000005e Code RO 3355 .text fz_ps.l(fflti.o) + 0x0083b18a 0x0083b18a 0x0000004e Code RO 3366 .text c_p.l(_printf_pad.o) + 0x0083b1d8 0x0083b1d8 0x00000024 Code RO 3368 .text c_p.l(_printf_truncate.o) + 0x0083b1fc 0x0083b1fc 0x00000052 Code RO 3370 .text c_p.l(_printf_str.o) + 0x0083b24e 0x0083b24e 0x00000002 PAD + 0x0083b250 0x0083b250 0x0000006c Code RO 3372 .text c_p.l(_printf_dec.o) + 0x0083b2bc 0x0083b2bc 0x00000026 Code RO 3374 .text c_p.l(_printf_charcount.o) + 0x0083b2e2 0x0083b2e2 0x00000002 PAD + 0x0083b2e4 0x0083b2e4 0x00000030 Code RO 3376 .text c_p.l(_printf_char_common.o) + 0x0083b314 0x0083b314 0x0000000a Code RO 3378 .text c_p.l(_sputc.o) + 0x0083b31e 0x0083b31e 0x00000010 Code RO 3380 .text c_p.l(_snputc.o) + 0x0083b32e 0x0083b32e 0x00000002 PAD + 0x0083b330 0x0083b330 0x000000bc Code RO 3382 .text c_p.l(_printf_wctomb.o) + 0x0083b3ec 0x0083b3ec 0x00000070 Code RO 3385 .text c_p.l(_printf_longlong_dec.o) + 0x0083b45c 0x0083b45c 0x00000070 Code RO 3391 .text c_p.l(_printf_oct_int_ll.o) + 0x0083b4cc 0x0083b4cc 0x00000098 Code RO 3411 .text c_p.l(_printf_hex_int_ll_ptr.o) + 0x0083b564 0x0083b564 0x00000188 Code RO 3431 .text c_p.l(__printf_flags_ss_wp.o) + 0x0083b6ec 0x0083b6ec 0x0000007a Code RO 3533 .text c_p.l(lludiv10.o) + 0x0083b766 0x0083b766 0x000000b0 Code RO 3535 .text c_p.l(_printf_intcommon.o) + 0x0083b816 0x0083b816 0x00000002 PAD + 0x0083b818 0x0083b818 0x00000418 Code RO 3537 .text c_p.l(_printf_fp_dec.o) + 0x0083bc30 0x0083bc30 0x000002d8 Code RO 3539 .text c_p.l(_printf_fp_hex.o) + 0x0083bf08 0x0083bf08 0x0000002e Code RO 3544 .text c_p.l(_printf_char.o) + 0x0083bf36 0x0083bf36 0x0000002e Code RO 3546 .text c_p.l(_printf_wchar.o) + 0x0083bf64 0x0083bf64 0x00000040 Code RO 3549 .text c_p.l(_wcrtomb.o) + 0x0083bfa4 0x0083bfa4 0x00000028 Code RO 3551 .text c_p.l(rtudiv10.o) + 0x0083bfcc 0x0083bfcc 0x00000010 Code RO 3557 .text c_p.l(rt_ctype_table.o) + 0x0083bfdc 0x0083bfdc 0x00000008 Code RO 3559 .text c_p.l(rt_locale.o) + 0x0083bfe4 0x0083bfe4 0x00000088 Code RO 3564 .text c_p.l(_printf_fp_infnan.o) + 0x0083c06c 0x0083c06c 0x000000d8 Code RO 3566 .text c_p.l(bigflt0.o) + 0x0083c144 0x0083c144 0x00000580 Code RO 3569 .text c_p.l(btod.o) + 0x0083c6c4 0x0083c6c4 0x00000030 Code RO 3572 i.__ARM_common_ll_muluu c_p.l(btod.o) + 0x0083c6f4 0x0083c6f4 0x0000001a Code RO 1054 i.__ARM_common_memcpy1_6 custom_app.o + 0x0083c70e 0x0083c70e 0x00000022 Code RO 1115 i.__ARM_common_memcpy1_8 overlay_mgr.o + 0x0083c730 0x0083c730 0x0000000a Code RO 1052 i.__ARM_common_memcpy4_5 custom_app.o + 0x0083c73a 0x0083c73a 0x0000001a Code RO 3313 i.__ARM_common_switch8 gap_utils.lib(gap_vendor_cmd.o) + 0x0083c754 0x0083c754 0x0000002c Code RO 3593 i.__ARM_fpclassify m_ps.l(fpclassify.o) + 0x0083c780 0x0083c780 0x0000000e Code RO 3424 i._is_digit c_p.l(__printf_wp.o) + 0x0083c78e 0x0083c78e 0x00000002 PAD + 0x0083c790 0x0083c790 0x0000002c Code RO 3575 locale$$code c_p.l(lc_numeric_c.o) + 0x0083c7bc 0x0083c7bc 0x0000002c Code RO 3605 locale$$code c_p.l(lc_ctype_c.o) + 0x0083c7e8 0x0083c7e8 0x0000008c Code RO 3344 x$fpl$fadd fz_ps.l(faddsub.o) + 0x0083c874 0x0083c874 0x000000b0 Code RO 3357 x$fpl$fmul fz_ps.l(fmul.o) + 0x0083c924 0x0083c924 0x000000d0 Code RO 3346 x$fpl$fsub fz_ps.l(faddsub.o) + 0x0083c9f4 0x0083c9f4 0x00000010 Code RO 3502 x$fpl$printf1 fz_ps.l(printf1.o) + 0x0083ca04 0x0083ca04 0x00000010 Code RO 3504 x$fpl$printf2 fz_ps.l(printf2.o) + 0x0083ca14 0x0083ca14 0x00000000 Code RO 3510 x$fpl$usenofp fz_ps.l(usenofp.o) + 0x0083ca14 0x0083ca14 0x0000000c Data RO 21 .constdata system_rtl876x.o + 0x0083ca20 0x0083ca20 0x00000100 Data RO 22 .constdata system_rtl876x.o + 0x0083cb20 0x0083cb20 0x0000009c Data RO 330 .constdata rtl876x_pinmux.o + 0x0083cbbc 0x0083cbbc 0x000001cc Data RO 460 .constdata findmy_network_service.o + 0x0083cd88 0x0083cd88 0x00000010 Data RO 532 .constdata accessory_info_service.o + 0x0083cd98 0x0083cd98 0x000002b8 Data RO 533 .constdata accessory_info_service.o + 0x0083d050 0x0083d050 0x00000108 Data RO 592 .constdata tps.o + 0x0083d158 0x0083d158 0x00000060 Data RO 649 .constdata ias.o + 0x0083d1b8 0x0083d1b8 0x0000007c Data RO 670 .constdata sdd_service.o + 0x0083d234 0x0083d234 0x00000220 Data RO 691 .constdata dis.o + 0x0083d454 0x0083d454 0x0000003a Data RO 842 .constdata app_task.o + 0x0083d48e 0x0083d48e 0x00000039 Data RO 1034 .constdata custom_app.o + 0x0083d4c7 0x0083d4c7 0x00000001 PAD + 0x0083d4c8 0x0083d4c8 0x00000002 Data RO 1254 .constdata fmna_adv.o + 0x0083d4ca 0x0083d4ca 0x00000002 PAD + 0x0083d4cc 0x0083d4cc 0x00000004 Data RO 1255 .constdata fmna_adv.o + 0x0083d4d0 0x0083d4d0 0x00000002 Data RO 1256 .constdata fmna_adv.o + 0x0083d4d2 0x0083d4d2 0x00000002 PAD + 0x0083d4d4 0x0083d4d4 0x00000004 Data RO 1257 .constdata fmna_adv.o + 0x0083d4d8 0x0083d4d8 0x00000002 Data RO 1258 .constdata fmna_adv.o + 0x0083d4da 0x0083d4da 0x00000002 PAD + 0x0083d4dc 0x0083d4dc 0x00000004 Data RO 1259 .constdata fmna_adv.o + 0x0083d4e0 0x0083d4e0 0x00000002 Data RO 1260 .constdata fmna_adv.o + 0x0083d4e2 0x0083d4e2 0x00000002 PAD + 0x0083d4e4 0x0083d4e4 0x00000004 Data RO 1261 .constdata fmna_adv.o + 0x0083d4e8 0x0083d4e8 0x00000002 Data RO 1262 .constdata fmna_adv.o + 0x0083d4ea 0x0083d4ea 0x00000002 PAD + 0x0083d4ec 0x0083d4ec 0x00000004 Data RO 1263 .constdata fmna_adv.o + 0x0083d4f0 0x0083d4f0 0x00000002 Data RO 1264 .constdata fmna_adv.o + 0x0083d4f2 0x0083d4f2 0x00000002 PAD + 0x0083d4f4 0x0083d4f4 0x00000004 Data RO 1265 .constdata fmna_adv.o + 0x0083d4f8 0x0083d4f8 0x00000008 Data RO 1266 .constdata fmna_adv.o + 0x0083d500 0x0083d500 0x00000055 Data RO 1351 .constdata fmna_connection.o + 0x0083d555 0x0083d555 0x00000103 Data RO 1395 .constdata fmna_crypto.o + 0x0083d658 0x0083d658 0x00000014 Data RO 1573 .constdata fmna_debug_control_point.o + 0x0083d66c 0x0083d66c 0x0000001b Data RO 1651 .constdata fmna_motion_detection.o + 0x0083d687 0x0083d687 0x0000001d Data RO 1746 .constdata fmna_paired_owner_control_point.o + 0x0083d6a4 0x0083d6a4 0x00000008 Data RO 1806 .constdata fmna_state_machine.o + 0x0083d6ac 0x0083d6ac 0x00000028 Data RO 1807 .constdata fmna_state_machine.o + 0x0083d6d4 0x0083d6d4 0x00000030 Data RO 1808 .constdata fmna_state_machine.o + 0x0083d704 0x0083d704 0x00000020 Data RO 1809 .constdata fmna_state_machine.o + 0x0083d724 0x0083d724 0x00000010 Data RO 1810 .constdata fmna_state_machine.o + 0x0083d734 0x0083d734 0x00000018 Data RO 1811 .constdata fmna_state_machine.o + 0x0083d74c 0x0083d74c 0x00000010 Data RO 1812 .constdata fmna_state_machine.o + 0x0083d75c 0x0083d75c 0x00000050 Data RO 1813 .constdata fmna_state_machine.o + 0x0083d7ac 0x0083d7ac 0x00000020 Data RO 1814 .constdata fmna_state_machine.o + 0x0083d7cc 0x0083d7cc 0x000001f4 Data RO 1815 .constdata fmna_state_machine.o + 0x0083d9c0 0x0083d9c0 0x00000026 Data RO 1982 .constdata fmna_adv_platform.o + 0x0083d9e6 0x0083d9e6 0x00000029 Data RO 2059 .constdata fmna_connection_platform.o + 0x0083da0f 0x0083da0f 0x00000017 Data RO 2119 .constdata fmna_gap_platform.o + 0x0083da26 0x0083da26 0x0000007a Data RO 2152 .constdata fmna_gatt_platform.o + 0x0083daa0 0x0083daa0 0x0000000c Data RO 2187 .constdata fmna_malloc_platform.o + 0x0083daac 0x0083daac 0x0000004c Data RO 2255 .constdata fmna_sound_platform.o + 0x0083daf8 0x0083daf8 0x00000072 Data RO 2428 .constdata fm-crypto.o + 0x0083db6a 0x0083db6a 0x00000002 Data RO 2502 .constdata aes.o + 0x0083db6c 0x0083db6c 0x00000018 Data RO 2562 .constdata asn1parse.o + 0x0083db84 0x0083db84 0x0000001e Data RO 2586 .constdata asn1write.o + 0x0083dba2 0x0083dba2 0x00000024 Data RO 2636 .constdata bignum.o + 0x0083dbc6 0x0083dbc6 0x00000002 Data RO 2669 .constdata bignum_core.o + 0x0083dbc8 0x0083dbc8 0x00000018 Data RO 2742 .constdata cipher_wrap.o + 0x0083dbe0 0x0083dbe0 0x00000008 Data RO 2743 .constdata cipher_wrap.o + 0x0083dbe8 0x0083dbe8 0x00000008 Data RO 2744 .constdata cipher_wrap.o + 0x0083dbf0 0x0083dbf0 0x00000008 Data RO 2745 .constdata cipher_wrap.o + 0x0083dbf8 0x0083dbf8 0x00000018 Data RO 2746 .constdata cipher_wrap.o + 0x0083dc10 0x0083dc10 0x00000008 Data RO 2747 .constdata cipher_wrap.o + 0x0083dc18 0x0083dc18 0x00000008 Data RO 2748 .constdata cipher_wrap.o + 0x0083dc20 0x0083dc20 0x00000008 Data RO 2749 .constdata cipher_wrap.o + 0x0083dc28 0x0083dc28 0x00000038 Data RO 2750 .constdata cipher_wrap.o + 0x0083dc60 0x0083dc60 0x0000001c Data RO 2751 .constdata cipher_wrap.o + 0x0083dc7c 0x0083dc7c 0x00000040 Data RO 2820 .constdata ecdsa.o + 0x0083dcbc 0x0083dcbc 0x0000006b Data RO 2854 .constdata ecp.o + 0x0083dd27 0x0083dd27 0x00000001 PAD + 0x0083dd28 0x0083dd28 0x00000430 Data RO 2896 .constdata ecp_curves.o + 0x0083e158 0x0083e158 0x00000020 Data RO 2897 .constdata ecp_curves.o + 0x0083e178 0x0083e178 0x00000020 Data RO 2898 .constdata ecp_curves.o + 0x0083e198 0x0083e198 0x00000020 Data RO 2899 .constdata ecp_curves.o + 0x0083e1b8 0x0083e1b8 0x00000020 Data RO 2900 .constdata ecp_curves.o + 0x0083e1d8 0x0083e1d8 0x00000020 Data RO 2901 .constdata ecp_curves.o + 0x0083e1f8 0x0083e1f8 0x00000020 Data RO 2902 .constdata ecp_curves.o + 0x0083e218 0x0083e218 0x00000020 Data RO 2903 .constdata ecp_curves.o + 0x0083e238 0x0083e238 0x00000020 Data RO 2904 .constdata ecp_curves.o + 0x0083e258 0x0083e258 0x00000020 Data RO 2905 .constdata ecp_curves.o + 0x0083e278 0x0083e278 0x00000020 Data RO 2906 .constdata ecp_curves.o + 0x0083e298 0x0083e298 0x00000020 Data RO 2907 .constdata ecp_curves.o + 0x0083e2b8 0x0083e2b8 0x00000020 Data RO 2908 .constdata ecp_curves.o + 0x0083e2d8 0x0083e2d8 0x00000020 Data RO 2909 .constdata ecp_curves.o + 0x0083e2f8 0x0083e2f8 0x00000020 Data RO 2910 .constdata ecp_curves.o + 0x0083e318 0x0083e318 0x00000020 Data RO 2911 .constdata ecp_curves.o + 0x0083e338 0x0083e338 0x00000020 Data RO 2912 .constdata ecp_curves.o + 0x0083e358 0x0083e358 0x00000020 Data RO 2913 .constdata ecp_curves.o + 0x0083e378 0x0083e378 0x00000020 Data RO 2914 .constdata ecp_curves.o + 0x0083e398 0x0083e398 0x00000020 Data RO 2915 .constdata ecp_curves.o + 0x0083e3b8 0x0083e3b8 0x00000020 Data RO 2916 .constdata ecp_curves.o + 0x0083e3d8 0x0083e3d8 0x00000020 Data RO 2917 .constdata ecp_curves.o + 0x0083e3f8 0x0083e3f8 0x00000020 Data RO 2918 .constdata ecp_curves.o + 0x0083e418 0x0083e418 0x00000020 Data RO 2919 .constdata ecp_curves.o + 0x0083e438 0x0083e438 0x00000020 Data RO 2920 .constdata ecp_curves.o + 0x0083e458 0x0083e458 0x00000020 Data RO 2921 .constdata ecp_curves.o + 0x0083e478 0x0083e478 0x00000020 Data RO 2922 .constdata ecp_curves.o + 0x0083e498 0x0083e498 0x00000020 Data RO 2923 .constdata ecp_curves.o + 0x0083e4b8 0x0083e4b8 0x00000020 Data RO 2924 .constdata ecp_curves.o + 0x0083e4d8 0x0083e4d8 0x00000020 Data RO 2925 .constdata ecp_curves.o + 0x0083e4f8 0x0083e4f8 0x00000020 Data RO 2926 .constdata ecp_curves.o + 0x0083e518 0x0083e518 0x00000020 Data RO 2927 .constdata ecp_curves.o + 0x0083e538 0x0083e538 0x00000020 Data RO 2928 .constdata ecp_curves.o + 0x0083e558 0x0083e558 0x00000020 Data RO 2929 .constdata ecp_curves.o + 0x0083e578 0x0083e578 0x00000020 Data RO 2930 .constdata ecp_curves.o + 0x0083e598 0x0083e598 0x00000020 Data RO 2931 .constdata ecp_curves.o + 0x0083e5b8 0x0083e5b8 0x00000020 Data RO 2932 .constdata ecp_curves.o + 0x0083e5d8 0x0083e5d8 0x00000020 Data RO 2933 .constdata ecp_curves.o + 0x0083e5f8 0x0083e5f8 0x00000020 Data RO 2934 .constdata ecp_curves.o + 0x0083e618 0x0083e618 0x00000020 Data RO 2935 .constdata ecp_curves.o + 0x0083e638 0x0083e638 0x00000020 Data RO 2936 .constdata ecp_curves.o + 0x0083e658 0x0083e658 0x00000020 Data RO 2937 .constdata ecp_curves.o + 0x0083e678 0x0083e678 0x00000020 Data RO 2938 .constdata ecp_curves.o + 0x0083e698 0x0083e698 0x00000020 Data RO 2939 .constdata ecp_curves.o + 0x0083e6b8 0x0083e6b8 0x00000020 Data RO 2940 .constdata ecp_curves.o + 0x0083e6d8 0x0083e6d8 0x00000020 Data RO 2941 .constdata ecp_curves.o + 0x0083e6f8 0x0083e6f8 0x00000020 Data RO 2942 .constdata ecp_curves.o + 0x0083e718 0x0083e718 0x00000020 Data RO 2943 .constdata ecp_curves.o + 0x0083e738 0x0083e738 0x00000020 Data RO 2944 .constdata ecp_curves.o + 0x0083e758 0x0083e758 0x00000020 Data RO 2945 .constdata ecp_curves.o + 0x0083e778 0x0083e778 0x00000020 Data RO 2946 .constdata ecp_curves.o + 0x0083e798 0x0083e798 0x00000020 Data RO 2947 .constdata ecp_curves.o + 0x0083e7b8 0x0083e7b8 0x00000020 Data RO 2948 .constdata ecp_curves.o + 0x0083e7d8 0x0083e7d8 0x00000020 Data RO 2949 .constdata ecp_curves.o + 0x0083e7f8 0x0083e7f8 0x00000020 Data RO 2950 .constdata ecp_curves.o + 0x0083e818 0x0083e818 0x00000020 Data RO 2951 .constdata ecp_curves.o + 0x0083e838 0x0083e838 0x00000020 Data RO 2952 .constdata ecp_curves.o + 0x0083e858 0x0083e858 0x00000020 Data RO 2953 .constdata ecp_curves.o + 0x0083e878 0x0083e878 0x00000020 Data RO 2954 .constdata ecp_curves.o + 0x0083e898 0x0083e898 0x00000020 Data RO 2955 .constdata ecp_curves.o + 0x0083e8b8 0x0083e8b8 0x00000020 Data RO 2956 .constdata ecp_curves.o + 0x0083e8d8 0x0083e8d8 0x00000020 Data RO 2957 .constdata ecp_curves.o + 0x0083e8f8 0x0083e8f8 0x00000020 Data RO 2958 .constdata ecp_curves.o + 0x0083e918 0x0083e918 0x00000020 Data RO 2959 .constdata ecp_curves.o + 0x0083e938 0x0083e938 0x00000020 Data RO 2960 .constdata ecp_curves.o + 0x0083e958 0x0083e958 0x00000022 Data RO 2978 .constdata gcm.o + 0x0083e97a 0x0083e97a 0x00000002 PAD + 0x0083e97c 0x0083e97c 0x0000003d Data RO 3018 .constdata md.o + 0x0083e9b9 0x0083e9b9 0x0000004b Data RO 3311 .constdata gap_utils.lib(gap_vendor_cmd.o) + 0x0083ea04 0x0083ea04 0x00000040 Data RO 3351 .constdata fz_ps.l(fdiv.o) + 0x0083ea44 0x0083ea44 0x00000008 Data RO 3383 .constdata c_p.l(_printf_wctomb.o) + 0x0083ea4c 0x0083ea4c 0x00000028 Data RO 3412 .constdata c_p.l(_printf_hex_int_ll_ptr.o) + 0x0083ea74 0x0083ea74 0x00000011 Data RO 3432 .constdata c_p.l(__printf_flags_ss_wp.o) + 0x0083ea85 0x0083ea85 0x00000026 Data RO 3540 .constdata c_p.l(_printf_fp_hex.o) + 0x0083eaab 0x0083eaab 0x00000001 PAD + 0x0083eaac 0x0083eaac 0x00000094 Data RO 3567 .constdata c_p.l(bigflt0.o) + 0x0083eb40 0x0083eb40 0x000001fc Data RO 23 .conststring system_rtl876x.o + 0x0083ed3c 0x0083ed3c 0x00000021 Data RO 593 .conststring tps.o + 0x0083ed5d 0x0083ed5d 0x00000003 PAD + 0x0083ed60 0x0083ed60 0x00000019 Data RO 1103 .conststring overlay_mgr.o + 0x0083ed79 0x0083ed79 0x00000003 PAD + 0x0083ed7c 0x0083ed7c 0x0000031d Data RO 1816 .conststring fmna_state_machine.o + 0x0083f099 0x0083f099 0x00000003 PAD + 0x0083f09c 0x0083f09c 0x0000000c Data RO 2752 .conststring cipher_wrap.o + 0x0083f0a8 0x0083f0a8 0x0000000c Data RO 2753 .conststring cipher_wrap.o + 0x0083f0b4 0x0083f0b4 0x0000000c Data RO 2754 .conststring cipher_wrap.o + 0x0083f0c0 0x0083f0c0 0x0000000c Data RO 2755 .conststring cipher_wrap.o + 0x0083f0cc 0x0083f0cc 0x0000000c Data RO 2756 .conststring cipher_wrap.o + 0x0083f0d8 0x0083f0d8 0x0000000c Data RO 2757 .conststring cipher_wrap.o + 0x0083f0e4 0x0083f0e4 0x00000016 Data RO 2855 .conststring ecp.o + 0x0083f0fa 0x0083f0fa 0x00000002 PAD + 0x0083f0fc 0x0083f0fc 0x0000000f Data RO 3019 .conststring md.o + 0x0083f10b 0x0083f10b 0x00000001 PAD + 0x0083f10c 0x0083f10c 0x00000000 Data RO 3644 Region$$Table anon$$obj.o + 0x0083f10c 0x0083f10c 0x0000001c Data RO 3574 locale$$data c_p.l(lc_numeric_c.o) + 0x0083f128 0x0083f128 0x00000110 Data RO 3604 locale$$data c_p.l(lc_ctype_c.o) + + + + Load Region LOAD_APP_TRACE (Base: 0x08800000, Size: 0x0000885c, Max: 0x00400000, ABSOLUTE) + + Execution Region App.trace (Exec base: 0x08800000, Load base: 0x08800000, Size: 0x0000885c, Max: 0x00400000, ABSOLUTE) + + Exec Addr Load Addr Size Type Attr Idx E Section Name Object + + 0x08800000 0x08800000 0x00000146 Data RO 18 .TRACE system_rtl876x.o + 0x08800146 0x08800146 0x00000002 PAD + 0x08800148 0x08800148 0x0000002a Data RO 205 .TRACE rtl876x_io_dlps.o + 0x08800172 0x08800172 0x00000002 PAD + 0x08800174 0x08800174 0x000000fc Data RO 458 .TRACE findmy_network_service.o + 0x08800270 0x08800270 0x00000080 Data RO 530 .TRACE accessory_info_service.o + 0x088002f0 0x088002f0 0x00000129 Data RO 562 .TRACE firmware_update_service.o + 0x08800419 0x08800419 0x00000003 PAD + 0x0880041c 0x0880041c 0x00000166 Data RO 590 .TRACE tps.o + 0x08800582 0x08800582 0x00000002 PAD + 0x08800584 0x08800584 0x00000072 Data RO 625 .TRACE hids_kb.o + 0x088005f6 0x088005f6 0x00000002 PAD + 0x088005f8 0x088005f8 0x00000052 Data RO 647 .TRACE ias.o + 0x0880064a 0x0880064a 0x00000002 PAD + 0x0880064c 0x0880064c 0x0000012a Data RO 668 .TRACE sdd_service.o + 0x08800776 0x08800776 0x00000002 PAD + 0x08800778 0x08800778 0x000000ae Data RO 689 .TRACE dis.o + 0x08800826 0x08800826 0x00000002 PAD + 0x08800828 0x08800828 0x00000098 Data RO 717 .TRACE main.o + 0x088008c0 0x088008c0 0x000000b8 Data RO 840 .TRACE app_task.o + 0x08800978 0x08800978 0x000011e0 Data RO 881 .TRACE findmy_app.o + 0x08801b58 0x08801b58 0x00000465 Data RO 1032 .TRACE custom_app.o + 0x08801fbd 0x08801fbd 0x00000003 PAD + 0x08801fc0 0x08801fc0 0x00000378 Data RO 1070 .TRACE dfu_flash.o + 0x08802338 0x08802338 0x0000003a Data RO 1125 .TRACE reset_watch_dog_timer.o + 0x08802372 0x08802372 0x00000002 PAD + 0x08802374 0x08802374 0x00000108 Data RO 1154 .TRACE serial_number_send.o + 0x0880247c 0x0880247c 0x0000013e Data RO 1191 .TRACE da213b.o + 0x088025ba 0x088025ba 0x00000002 PAD + 0x088025bc 0x088025bc 0x0000037a Data RO 1218 .TRACE key_handle.o + 0x08802936 0x08802936 0x00000002 PAD + 0x08802938 0x08802938 0x0000005a Data RO 1252 .TRACE fmna_adv.o + 0x08802992 0x08802992 0x00000002 PAD + 0x08802994 0x08802994 0x00000353 Data RO 1310 .TRACE fmna_config_control_point.o + 0x08802ce7 0x08802ce7 0x00000001 PAD + 0x08802ce8 0x08802ce8 0x000002d2 Data RO 1349 .TRACE fmna_connection.o + 0x08802fba 0x08802fba 0x00000002 PAD + 0x08802fbc 0x08802fbc 0x00000789 Data RO 1392 .TRACE fmna_crypto.o + 0x08803745 0x08803745 0x00000003 PAD + 0x08803748 0x08803748 0x000000ef Data RO 1572 .TRACE fmna_debug_control_point.o + 0x08803837 0x08803837 0x00000001 PAD + 0x08803838 0x08803838 0x00000357 Data RO 1604 .TRACE fmna_gatt.o + 0x08803b8f 0x08803b8f 0x00000001 PAD + 0x08803b90 0x08803b90 0x000003aa Data RO 1649 .TRACE fmna_motion_detection.o + 0x08803f3a 0x08803f3a 0x00000002 PAD + 0x08803f3c 0x08803f3c 0x0000015f Data RO 1713 .TRACE fmna_nonowner_control_point.o + 0x0880409b 0x0880409b 0x00000001 PAD + 0x0880409c 0x0880409c 0x0000015a Data RO 1745 .TRACE fmna_paired_owner_control_point.o + 0x088041f6 0x088041f6 0x00000002 PAD + 0x088041f8 0x088041f8 0x00000049 Data RO 1773 .TRACE fmna_pairing_control_point.o + 0x08804241 0x08804241 0x00000003 PAD + 0x08804244 0x08804244 0x00000cff Data RO 1804 .TRACE fmna_state_machine.o + 0x08804f43 0x08804f43 0x00000001 PAD + 0x08804f44 0x08804f44 0x000002ea Data RO 1851 .TRACE fmna_uarp_control_point.o + 0x0880522e 0x0880522e 0x00000002 PAD + 0x08805230 0x08805230 0x00000035 Data RO 1910 .TRACE fmna_version.o + 0x08805265 0x08805265 0x00000003 PAD + 0x08805268 0x08805268 0x00000717 Data RO 1940 .TRACE fmnasampleuarp.o + 0x0880597f 0x0880597f 0x00000001 PAD + 0x08805980 0x08805980 0x0000011d Data RO 1980 .TRACE fmna_adv_platform.o + 0x08805a9d 0x08805a9d 0x00000003 PAD + 0x08805aa0 0x08805aa0 0x0000016e Data RO 2030 .TRACE fmna_battery_platform.o + 0x08805c0e 0x08805c0e 0x00000002 PAD + 0x08805c10 0x08805c10 0x00000236 Data RO 2057 .TRACE fmna_connection_platform.o + 0x08805e46 0x08805e46 0x00000002 PAD + 0x08805e48 0x08805e48 0x00000397 Data RO 2085 .TRACE fmna_dfu_platform.o + 0x088061df 0x088061df 0x00000001 PAD + 0x088061e0 0x088061e0 0x00000320 Data RO 2117 .TRACE fmna_gap_platform.o + 0x08806500 0x08806500 0x00000596 Data RO 2149 .TRACE fmna_gatt_platform.o + 0x08806a96 0x08806a96 0x00000002 PAD + 0x08806a98 0x08806a98 0x00000124 Data RO 2185 .TRACE fmna_malloc_platform.o + 0x08806bbc 0x08806bbc 0x00000085 Data RO 2203 .TRACE fmna_motion_detection_platform.o + 0x08806c41 0x08806c41 0x00000003 PAD + 0x08806c44 0x08806c44 0x00000067 Data RO 2228 .TRACE fmna_peer_manager.o + 0x08806cab 0x08806cab 0x00000001 PAD + 0x08806cac 0x08806cac 0x0000031e Data RO 2253 .TRACE fmna_sound_platform.o + 0x08806fca 0x08806fca 0x00000002 PAD + 0x08806fcc 0x08806fcc 0x0000022b Data RO 2283 .TRACE fmna_timer_platform.o + 0x088071f7 0x088071f7 0x00000001 PAD + 0x088071f8 0x088071f8 0x0000068b Data RO 2345 .TRACE coreuarpaccessory.o + 0x08807883 0x08807883 0x00000001 PAD + 0x08807884 0x08807884 0x00000d2e Data RO 2374 .TRACE coreuarpplatformaccessory.o + 0x088085b2 0x088085b2 0x00000002 PAD + 0x088085b4 0x088085b4 0x0000002c Data RO 2404 .TRACE coreuarpplatformrtk.o + 0x088085e0 0x088085e0 0x00000193 Data RO 3159 .TRACE gap_utils.lib(gap_config.o) + 0x08808773 0x08808773 0x00000001 PAD + 0x08808774 0x08808774 0x00000018 Data RO 3163 .TRACE gap_utils.lib(gap_lib.o) + 0x0880878c 0x0880878c 0x000000ce Data RO 3200 .TRACE key_crypto.lib(key_crypto.o) + + +============================================================================== + +Image component sizes + + + Code (inc. data) RO Data RW Data ZI Data Debug Object Name + + 304 86 840 0 12 4154 accessory_info_service.o + 4352 62 2 0 2604 17696 aes.o + 488 56 242 0 16 5129 app_task.o + 1096 8 24 0 0 12218 asn1parse.o + 1176 4 30 0 0 12045 asn1write.o + 944 10 0 0 0 9928 base64.o + 7432 50 36 0 0 41823 bignum.o + 3876 22 2 0 0 34926 bignum_core.o + 1308 52 0 0 4 19179 cipher.o + 136 10 252 8 28 11411 cipher_wrap.o + 184 4 0 0 4 6738 constant_time.o + 0 0 1675 0 0 16144 coreuarpaccessory.o + 0 0 3374 0 0 28906 coreuarpplatformaccessory.o + 0 0 44 0 0 3914 coreuarpplatformrtk.o + 1932 330 1182 63 56 10339 custom_app.o + 584 48 318 0 0 8785 da213b.o + 0 0 888 0 0 9745 dfu_flash.o + 680 110 718 173 4 5625 dis.o + 1008 8 0 0 0 11008 ecdh.o + 2028 46 64 0 0 14235 ecdsa.o + 7996 142 129 0 12 52608 ecp.o + 2044 64 3120 4 0 13617 ecp_curves.o + 3756 604 4576 1 57 29800 findmy_app.o + 248 50 712 0 8 33025 findmy_network_service.o + 0 0 297 0 0 3190 firmware_update_service.o + 1904 40 114 0 0 22494 fm-crypto.o + 416 54 134 0 52 10858 fmna_adv.o + 1040 192 323 91 40 13478 fmna_adv_platform.o + 524 90 366 0 2 3879 fmna_battery_platform.o + 932 134 851 40 0 5023 fmna_config_control_point.o + 1556 158 807 1 40 12729 fmna_connection.o + 824 106 607 0 1 5767 fmna_connection_platform.o + 3224 624 2188 0 1933 23923 fmna_crypto.o + 356 48 259 16 0 2900 fmna_debug_control_point.o + 0 0 919 0 0 5295 fmna_dfu_platform.o + 1156 188 823 0 108 7977 fmna_gap_platform.o + 1292 148 855 2 300 14467 fmna_gatt.o + 1648 202 1552 2 14 12288 fmna_gatt_platform.o + 312 56 304 0 56 2718 fmna_malloc_platform.o + 900 238 965 8 16 5486 fmna_motion_detection.o + 396 44 133 0 1 3214 fmna_motion_detection_platform.o + 344 60 351 12 1 3117 fmna_nonowner_control_point.o + 432 82 375 12 0 3407 fmna_paired_owner_control_point.o + 288 54 73 12 1396 3164 fmna_pairing_control_point.o + 112 22 103 0 0 1034 fmna_peer_manager.o + 1244 162 874 0 44 7405 fmna_sound_platform.o + 5260 778 4920 136 232 32862 fmna_state_machine.o + 740 260 555 0 24 5073 fmna_timer_platform.o + 0 0 746 0 0 18666 fmna_uarp_control_point.o + 76 22 53 0 4 1080 fmna_version.o + 0 0 1815 0 0 19736 fmnasampleuarp.o + 2860 18 34 0 0 27033 gcm.o + 0 0 114 0 0 6753 hids_kb.o + 188 34 178 0 4 3153 ias.o + 180 0 0 0 0 3038 kdf963.o + 1532 184 890 0 28 11471 key_handle.o + 440 62 152 0 0 28691 main.o + 1070 28 76 0 0 11653 md.o + 158 8 25 108 8 3624 overlay_mgr.o + 116 4 0 4 0 2796 platform_util.o + 72 12 58 0 0 3933 reset_watch_dog_timer.o + 804 8 0 0 0 12727 rtl876x_adc.o + 640 24 0 0 1 4560 rtl876x_aon_wdg.o + 424 20 0 0 0 8000 rtl876x_gpio.o + 1184 70 0 4 0 10715 rtl876x_i2c.o + 1596 210 42 0 392 34476 rtl876x_io_dlps.o + 208 26 0 0 0 11952 rtl876x_nvic.o + 1088 32 156 0 0 9417 rtl876x_pinmux.o + 832 54 0 0 0 3837 rtl876x_rcc.o + 496 24 0 0 0 4114 rtl876x_tim.o + 544 66 422 1 8 6280 sdd_service.o + 384 62 264 62 48 3975 serial_number_send.o + 88 0 0 0 0 3828 sha256.o + 92 72 232 0 0 968 startup_rtl876x.o + 2364 490 2126 0 20 79706 system_rtl876x.o + 468 74 655 20 8 4780 tps.o + + ---------------------------------------------------------------------- + 84378 7110 45113 788 7604 965708 Object Totals + 0 0 0 0 0 0 (incl. Generated) + 2 0 99 8 18 0 (incl. Padding) + + ---------------------------------------------------------------------- + + Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name + + 780 24 0 50 84 8547 adc_lib.o + 8 0 0 0 0 68 __main.o + 392 6 17 0 0 76 __printf_flags_ss_wp.o + 14 0 0 0 0 60 __printf_wp.o + 0 0 0 0 0 0 __rtentry.o + 12 0 0 0 0 0 __rtentry2.o + 8 4 0 0 0 0 __rtentry5.o + 10 0 0 0 0 0 _printf_a.o + 10 0 0 0 0 0 _printf_c.o + 46 0 0 0 0 100 _printf_char.o + 48 6 0 0 0 88 _printf_char_common.o + 38 0 0 0 0 60 _printf_charcount.o + 10 0 0 0 0 0 _printf_d.o + 108 18 0 0 0 76 _printf_dec.o + 10 0 0 0 0 0 _printf_e.o + 10 0 0 0 0 0 _printf_f.o + 1048 14 0 0 0 176 _printf_fp_dec.o + 728 10 38 0 0 84 _printf_fp_hex.o + 136 16 0 0 0 76 _printf_fp_infnan.o + 10 0 0 0 0 0 _printf_g.o + 152 4 40 0 0 148 _printf_hex_int_ll_ptr.o + 10 0 0 0 0 0 _printf_i.o + 176 0 0 0 0 84 _printf_intcommon.o + 10 0 0 0 0 0 _printf_l.o + 10 0 0 0 0 0 _printf_lc.o + 10 0 0 0 0 0 _printf_ll.o + 10 0 0 0 0 0 _printf_lld.o + 10 0 0 0 0 0 _printf_lli.o + 10 0 0 0 0 0 _printf_llo.o + 10 0 0 0 0 0 _printf_llu.o + 10 0 0 0 0 0 _printf_llx.o + 112 18 0 0 0 76 _printf_longlong_dec.o + 10 0 0 0 0 0 _printf_ls.o + 10 0 0 0 0 0 _printf_n.o + 10 0 0 0 0 0 _printf_o.o + 112 10 0 0 0 112 _printf_oct_int_ll.o + 10 0 0 0 0 0 _printf_p.o + 78 0 0 0 0 100 _printf_pad.o + 2 0 0 0 0 0 _printf_percent.o + 4 0 0 0 0 0 _printf_percent_end.o + 10 0 0 0 0 0 _printf_s.o + 82 0 0 0 0 72 _printf_str.o + 36 0 0 0 0 76 _printf_truncate.o + 10 0 0 0 0 0 _printf_u.o + 46 0 0 0 0 100 _printf_wchar.o + 188 6 8 0 0 80 _printf_wctomb.o + 10 0 0 0 0 0 _printf_x.o + 16 0 0 0 0 60 _snputc.o + 10 0 0 0 0 60 _sputc.o + 64 0 0 0 0 72 _wcrtomb.o + 488 0 0 0 0 92 aeabi_sdivfast.o + 216 6 148 0 0 80 bigflt0.o + 1456 30 0 0 0 336 btod.o + 44 10 272 0 0 76 lc_ctype_c.o + 44 10 28 0 0 76 lc_numeric_c.o + 2 0 0 0 0 0 libinit.o + 34 0 0 0 0 0 libinit2.o + 122 0 0 0 0 72 lludiv10.o + 28 0 0 0 0 68 memset.o + 116 16 0 0 228 156 rand.o + 16 4 0 0 0 76 rt_ctype_table.o + 8 4 0 0 20 68 rt_locale.o + 150 0 0 0 0 104 rt_memmove.o + 40 0 0 0 0 60 rtudiv10.o + 160 4 0 0 0 80 strcmpv6m.o + 56 6 0 0 0 72 vsnprintf.o + 124 4 0 0 0 72 d2f.o + 856 20 0 0 0 208 daddsub.o + 72 4 0 0 0 68 dfixui.o + 88 0 0 0 0 92 dflti.o + 584 26 0 0 0 84 dmul.o + 348 8 0 0 0 160 faddsub.o + 352 10 64 0 0 92 fdiv.o + 48 0 0 0 0 60 ffixui.o + 94 0 0 0 0 92 fflti.o + 176 4 0 0 0 80 fmul.o + 16 4 0 0 0 76 printf1.o + 16 4 0 0 0 76 printf2.o + 0 0 0 0 0 0 usenofp.o + 272 10 403 0 0 380 gap_config.o + 76 14 24 0 0 92 gap_lib.o + 2712 40 0 0 8 2976 gap_lib_system_call.o + 1498 62 75 0 4 736 gap_vendor_cmd.o + 408 40 206 1 8 54625 key_crypto.o + 44 4 0 0 0 60 fpclassify.o + + ---------------------------------------------------------------------- + 15442 480 1327 52 352 71896 Library Totals + 14 0 4 1 0 0 (incl. Padding) + + ---------------------------------------------------------------------- + + Code (inc. data) RO Data RW Data ZI Data Debug Library Name + + 780 24 0 50 84 8547 adc.lib + 6864 202 551 0 248 3320 c_p.l + 2774 84 64 0 0 1160 fz_ps.l + 4558 126 502 0 12 4184 gap_utils.lib + 408 40 206 1 8 54625 key_crypto.lib + 44 4 0 0 0 60 m_ps.l + + ---------------------------------------------------------------------- + 15442 480 1327 52 352 71896 Library Totals + + ---------------------------------------------------------------------- + +============================================================================== + + + Code (inc. data) RO Data RW Data ZI Data Debug + + 99820 7590 46440 840 7956 1029088 Grand Totals + 99820 7590 46440 840 7956 1029088 ELF Image Totals + 99820 7590 46440 840 0 0 ROM Totals + +============================================================================== + + Total RO Size (Code + RO Data) 146260 ( 142.83kB) + Total RW Size (RW Data + ZI Data) 8796 ( 8.59kB) + Total ROM Size (Code + RO Data + RW Data) 147100 ( 143.65kB) + +============================================================================== + diff --git a/board/evb/findmy/mdk/Listings/startup_rtl876x.lst b/board/evb/findmy/mdk/Listings/startup_rtl876x.lst new file mode 100644 index 0000000..b0ead1c --- /dev/null +++ b/board/evb/findmy/mdk/Listings/startup_rtl876x.lst @@ -0,0 +1,1641 @@ + + + +ARM Macro Assembler Page 1 + + + 1 00000000 #line 1 "..\\..\\..\\..\\src\\mcu\\rtl8 +76x\\arm\\startup_rtl876x.s" + 1 00000000 + 2 00000000 EXPORT __initial_sp + 3 00000000 00203800 + __initial_sp + EQU (0x200000 + 14 * 1024) + 4 00000000 + 5 00000000 PRESERVE8 + 6 00000000 THUMB + 7 00000000 + 8 00000000 ; Vector Table Mapped to Address 0 at Reset + 9 00000000 + 10 00000000 AREA VECTOR, DATA, READONLY + 11 00000000 EXPORT __Vectors + 12 00000000 EXPORT __Vectors_End + 13 00000000 EXPORT __Vectors_Size + 14 00000000 + 15 00000000 00203800 + __Vectors + DCD __initial_sp ; Top of Stack + 16 00000004 00000000 DCD Reset_Handler ; Reset Handler + 17 00000008 00000000 DCD NMI_Handler ; NMI Handler + 18 0000000C 00000000 DCD HardFault_Handler ; Hard Fault + Handler + 19 00000010 00000000 DCD MemManage_Handler + ; MPU Fault Handler + + 20 00000014 00000000 DCD BusFault_Handler + ; Bus Fault Handler + + 21 00000018 00000000 DCD UsageFault_Handler ; Usage Faul + t Handler + 22 0000001C 00000000 DCD 0 ; Reserved + 23 00000020 00000000 DCD 0 ; Reserved + 24 00000024 00000000 DCD 0 ; Reserved + 25 00000028 00000000 DCD 0 ; Reserved + 26 0000002C 00000000 DCD SVC_Handler ; SVCall Handler + 27 00000030 00000000 DCD 0 ; Reserved + 28 00000034 00000000 DCD 0 ; Reserved + 29 00000038 00000000 DCD PendSV_Handler ; PendSV Handler + + 30 0000003C 00000000 DCD SysTick_Handler + ; SysTick Handler + 31 00000040 + 32 00000040 ; External Interrupts + 33 00000040 00000000 DCD System_Handler ;[0] System On + interrupt + 34 00000044 00000000 DCD WDG_Handler ;[1] Watch dog glo + bal insterrupt + 35 00000048 00000000 DCD BTMAC_Handler ;[2] See Below T + able ( an Extension + of interrupt ) + 36 0000004C 00000000 DCD Timer3_Handler ;[3] Timer3 glo + bal interrupt + 37 00000050 00000000 DCD Timer2_Handler ;[4] Timer2 glo + bal interrupt + 38 00000054 00000000 DCD HardFault_Handler ;[5] Platfor + m interrupt (platfr + + + +ARM Macro Assembler Page 2 + + + om error interrupt) + + 39 00000058 00000000 DCD I2S0_RX_Handler ;[6] I2S0 RX i + nterrupt + 40 0000005C 00000000 DCD I2S0_TX_Handler ;[7] I2S0 TX i + nterrupt + 41 00000060 00000000 DCD Timer4_5_Handler ;[8] Timer[4: + 7] global interrupt + + 42 00000064 00000000 DCD GPIO4_Handler ;[9] GPIO 4 inte + rrupt + 43 00000068 00000000 DCD GPIO5_Handler ;[10] GPIO 5 inte + rrupt + 44 0000006C 00000000 DCD UART1_Handler ;[11] Uart1 inter + rupt (default for + log) + 45 00000070 00000000 DCD UART0_Handler ;[12] Uart0 inter + rupt + 46 00000074 00000000 DCD RTC_Handler ;[13] Realtime coun + ter interrupt + 47 00000078 00000000 DCD SPI0_Handler ;[14] SPI0 interru + pt + 48 0000007C 00000000 DCD SPI1_Handler ;[15] SPI1 interru + pt + 49 00000080 00000000 DCD I2C0_Handler ;[16] I2C0 interru + pt + 50 00000084 00000000 DCD I2C1_Handler ;[17] I2C1 interru + pt + 51 00000088 00000000 DCD ADC_Handler ;[18] ADC global in + terrupt + 52 0000008C 00000000 DCD Peripheral_Handler ;[19] See Be + low Table ( an Exte + nsion of interrupt + ) + 53 00000090 00000000 DCD GDMA0_Channel0_Handler ;[20] RT + K-DMA0 channel 0 gl + obal interrupt + 54 00000094 00000000 DCD GDMA0_Channel1_Handler ;[21] RT + K-DMA0 channel 1 gl + obal interrupt + 55 00000098 00000000 DCD GDMA0_Channel2_Handler ;[22] RT + K-DMA0 channel 2 gl + obal interrupt + 56 0000009C 00000000 DCD GDMA0_Channel3_Handler ;[23] RT + K-DMA0 channel 3 gl + obal interrupt + 57 000000A0 00000000 DCD Enhanced_Timer0_Handler ;[24] E + nhanced Timer0 + 58 000000A4 00000000 DCD Enhanced_Timer1_Handler ;[25] E + nhanced Timer1 + 59 000000A8 00000000 DCD GPIO_Group3_Handler ;[26] GPIO( + n*4)+3,n={0:7} glob + al interrupt + 60 000000AC 00000000 DCD GPIO_Group2_Handler ;[27] GPIO( + n*4)+2,n={0:7} glob + al interrupt + 61 000000B0 00000000 DCD IR_Handler ;[28] IR module glo + bal interrupt + 62 000000B4 00000000 DCD GPIO_Group1_Handler ;[29] GPIO( + + + +ARM Macro Assembler Page 3 + + + n*4)+1,n={0:7}-{1} + global interrupt + 63 000000B8 00000000 DCD GPIO_Group0_Handler ;[30] GPIO( + n*4)+0,n={0:7}-{1} + global interrupt + 64 000000BC 00000000 DCD 0 ;[31] Reserved + 65 000000C0 + 66 000000C0 ;Timer[4:5] interrupt + 67 000000C0 00000000 DCD Timer4_Handler ;8, 0, 48 + 68 000000C4 00000000 DCD Timer5_Handler ;8, 1, 49 + 69 000000C8 + 70 000000C8 ;Peripheral Interrupts not special interrupt + 71 000000C8 ;Interrupt name, Interrupt status bit, Offset in vector + 72 000000C8 00000000 DCD SPI_Flash_Handler ;19, 0, 50 + 73 000000CC 00000000 DCD Qdecode_Handler ;19, 1, 51 + 74 000000D0 00000000 DCD Keyscan_Handler ;19, 2, 52 + 75 000000D4 00000000 DCD SPI2W_Handler ;19, 3, 53 + 76 000000D8 00000000 DCD LPCOMP_Handler ;19, 4, 54 + 77 000000DC 00000000 DCD PTA_Mailbox_Handler ;19, 5, 55 + 78 000000E0 00000000 DCD CAP_Touch_Handler ;19, 6, 56 + 79 000000E4 00000000 DCD TRNG_Handler ;19, 9, 57 + 80 000000E8 __Vectors_End + 81 000000E8 + 82 000000E8 000000E8 + __Vectors_Size + EQU __Vectors_End - __Vectors + 83 000000E8 + 84 000000E8 AREA RESET, CODE, READONLY + 85 00000000 + 86 00000000 ; Reset Handler + 87 00000000 Reset_Handler + PROC + 88 00000000 EXPORT Reset_Handler [WE +AK] + 89 00000000 IMPORT SystemInit + 90 00000000 4800 LDR R0, =SystemInit + 91 00000002 4700 BX R0 + 92 00000004 + 93 00000004 ENDP ; end of Reset_Hand + ler + 94 00000004 + 95 00000004 + 96 00000004 00000000 AREA |.text|, CODE, READONLY + 97 00000000 Default_Handler + PROC + 98 00000000 EXPORT Default_Handler + [WEAK] + 99 00000000 EXPORT NMI_Handler + [WEAK] + 100 00000000 EXPORT HardFault_Handler + [WEAK] + 101 00000000 EXPORT MemManage_Handler + [WEAK] + 102 00000000 EXPORT BusFault_Handler + [WEAK] + 103 00000000 EXPORT UsageFault_Handler + [WEAK] + 104 00000000 EXPORT SVC_Handler + [WEAK] + + + +ARM Macro Assembler Page 4 + + + 105 00000000 EXPORT PendSV_Handler + [WEAK] + 106 00000000 EXPORT SysTick_Handler + [WEAK] + 107 00000000 EXPORT System_Handler + [WEAK] + 108 00000000 EXPORT WDG_Handler + [WEAK] + 109 00000000 EXPORT BTMAC_Handler + [WEAK] + 110 00000000 EXPORT Timer3_Handler + [WEAK] + 111 00000000 EXPORT Timer2_Handler + [WEAK] + 112 00000000 EXPORT I2S0_TX_Handler + [WEAK] + 113 00000000 EXPORT I2S0_RX_Handler + [WEAK] + 114 00000000 EXPORT Timer4_5_Handler + [WEAK] + 115 00000000 EXPORT GPIO4_Handler + [WEAK] + 116 00000000 EXPORT GPIO5_Handler + [WEAK] + 117 00000000 EXPORT UART1_Handler + [WEAK] + 118 00000000 EXPORT UART0_Handler + [WEAK] + 119 00000000 EXPORT RTC_Handler + [WEAK] + 120 00000000 EXPORT SPI0_Handler + [WEAK] + 121 00000000 EXPORT SPI1_Handler + [WEAK] + 122 00000000 EXPORT I2C0_Handler + [WEAK] + 123 00000000 EXPORT I2C1_Handler + [WEAK] + 124 00000000 EXPORT ADC_Handler + [WEAK] + 125 00000000 EXPORT Peripheral_Handler + [WEAK] + 126 00000000 EXPORT GDMA0_Channel0_Handler + [WEAK] + 127 00000000 EXPORT GDMA0_Channel1_Handler + [WEAK] + 128 00000000 EXPORT GDMA0_Channel2_Handler + [WEAK] + 129 00000000 EXPORT GDMA0_Channel3_Handler + [WEAK] + 130 00000000 EXPORT Enhanced_Timer0_Handler + [WEAK] + 131 00000000 EXPORT Enhanced_Timer1_Handler + [WEAK] + 132 00000000 EXPORT GPIO_Group3_Handler + [WEAK] + 133 00000000 EXPORT GPIO_Group2_Handler + [WEAK] + 134 00000000 EXPORT IR_Handler + + + +ARM Macro Assembler Page 5 + + + [WEAK] + 135 00000000 EXPORT GPIO_Group1_Handler + [WEAK] + 136 00000000 EXPORT GPIO_Group0_Handler + [WEAK] + 137 00000000 + 138 00000000 ;Extension Interrupts + 139 00000000 EXPORT Timer4_Handler + [WEAK] + 140 00000000 EXPORT Timer5_Handler + [WEAK] + 141 00000000 EXPORT SPI_Flash_Handler + [WEAK] + 142 00000000 EXPORT Qdecode_Handler + [WEAK] + 143 00000000 EXPORT Keyscan_Handler + [WEAK] + 144 00000000 EXPORT SPI2W_Handler + [WEAK] + 145 00000000 EXPORT LPCOMP_Handler + [WEAK] + 146 00000000 EXPORT PTA_Mailbox_Handler + [WEAK] + 147 00000000 EXPORT CAP_Touch_Handler + [WEAK] + 148 00000000 EXPORT TRNG_Handler + [WEAK] + 149 00000000 EXPORT GPIO0_Handler + [WEAK] + 150 00000000 EXPORT GPIO1_Handler + [WEAK] + 151 00000000 EXPORT GPIO2_Handler + [WEAK] + 152 00000000 EXPORT GPIO3_Handler + [WEAK] + 153 00000000 EXPORT GPIO6_Handler + [WEAK] + 154 00000000 EXPORT GPIO7_Handler + [WEAK] + 155 00000000 EXPORT GPIO8_Handler + [WEAK] + 156 00000000 EXPORT GPIO9_Handler + [WEAK] + 157 00000000 EXPORT GPIO10_Handler + [WEAK] + 158 00000000 EXPORT GPIO11_Handler + [WEAK] + 159 00000000 EXPORT GPIO12_Handler + [WEAK] + 160 00000000 EXPORT GPIO13_Handler + [WEAK] + 161 00000000 EXPORT GPIO14_Handler + [WEAK] + 162 00000000 EXPORT GPIO15_Handler + [WEAK] + 163 00000000 EXPORT GPIO16_Handler + [WEAK] + 164 00000000 EXPORT GPIO17_Handler + [WEAK] + + + +ARM Macro Assembler Page 6 + + + 165 00000000 EXPORT GPIO18_Handler + [WEAK] + 166 00000000 EXPORT GPIO19_Handler + [WEAK] + 167 00000000 EXPORT GPIO20_Handler + [WEAK] + 168 00000000 EXPORT GPIO21_Handler + [WEAK] + 169 00000000 EXPORT GPIO22_Handler + [WEAK] + 170 00000000 EXPORT GPIO23_Handler + [WEAK] + 171 00000000 EXPORT GPIO24_Handler + [WEAK] + 172 00000000 EXPORT GPIO25_Handler + [WEAK] + 173 00000000 EXPORT GPIO26_Handler + [WEAK] + 174 00000000 EXPORT GPIO27_Handler + [WEAK] + 175 00000000 EXPORT GPIO28_Handler + [WEAK] + 176 00000000 EXPORT GPIO29_Handler + [WEAK] + 177 00000000 EXPORT GPIO30_Handler + [WEAK] + 178 00000000 EXPORT GPIO31_Handler + [WEAK] + 179 00000000 NMI_Handler + 180 00000000 HardFault_Handler + 181 00000000 MemManage_Handler + 182 00000000 BusFault_Handler + 183 00000000 UsageFault_Handler + 184 00000000 SVC_Handler + 185 00000000 PendSV_Handler + 186 00000000 SysTick_Handler + 187 00000000 System_Handler + 188 00000000 WDG_Handler + 189 00000000 BTMAC_Handler + 190 00000000 Timer3_Handler + 191 00000000 Timer2_Handler + 192 00000000 I2S0_RX_Handler + 193 00000000 I2S0_TX_Handler + 194 00000000 Timer4_5_Handler + 195 00000000 GPIO4_Handler + 196 00000000 GPIO5_Handler + 197 00000000 UART1_Handler + 198 00000000 UART0_Handler + 199 00000000 RTC_Handler + 200 00000000 SPI0_Handler + 201 00000000 SPI1_Handler + 202 00000000 I2C0_Handler + 203 00000000 I2C1_Handler + 204 00000000 ADC_Handler + 205 00000000 Peripheral_Handler + 206 00000000 GDMA0_Channel0_Handler + 207 00000000 GDMA0_Channel1_Handler + 208 00000000 GDMA0_Channel2_Handler + 209 00000000 GDMA0_Channel3_Handler + + + +ARM Macro Assembler Page 7 + + + 210 00000000 Enhanced_Timer0_Handler + 211 00000000 Enhanced_Timer1_Handler + 212 00000000 GPIO_Group3_Handler + 213 00000000 GPIO_Group2_Handler + 214 00000000 IR_Handler + 215 00000000 GPIO_Group1_Handler + 216 00000000 GPIO_Group0_Handler + 217 00000000 + 218 00000000 ;Extension Interrupts + 219 00000000 Timer4_Handler + 220 00000000 Timer5_Handler + 221 00000000 SPI_Flash_Handler + 222 00000000 Qdecode_Handler + 223 00000000 Keyscan_Handler + 224 00000000 SPI2W_Handler + 225 00000000 LPCOMP_Handler + 226 00000000 PTA_Mailbox_Handler + 227 00000000 CAP_Touch_Handler + 228 00000000 TRNG_Handler + 229 00000000 GPIO0_Handler + 230 00000000 GPIO1_Handler + 231 00000000 GPIO2_Handler + 232 00000000 GPIO3_Handler + 233 00000000 GPIO6_Handler + 234 00000000 GPIO7_Handler + 235 00000000 GPIO8_Handler + 236 00000000 GPIO9_Handler + 237 00000000 GPIO10_Handler + 238 00000000 GPIO11_Handler + 239 00000000 GPIO12_Handler + 240 00000000 GPIO13_Handler + 241 00000000 GPIO14_Handler + 242 00000000 GPIO15_Handler + 243 00000000 GPIO16_Handler + 244 00000000 GPIO17_Handler + 245 00000000 GPIO18_Handler + 246 00000000 GPIO19_Handler + 247 00000000 GPIO20_Handler + 248 00000000 GPIO21_Handler + 249 00000000 GPIO22_Handler + 250 00000000 GPIO23_Handler + 251 00000000 GPIO24_Handler + 252 00000000 GPIO25_Handler + 253 00000000 GPIO26_Handler + 254 00000000 GPIO27_Handler + 255 00000000 GPIO28_Handler + 256 00000000 GPIO29_Handler + 257 00000000 GPIO30_Handler + 258 00000000 GPIO31_Handler + 259 00000000 IMPORT log_direct + 260 00000000 4811 LDR R0, =0x20000000 + 261 00000002 4912 LDR R1, =DEFAULT_HANDLER_TXT + 262 00000004 F3EF 8205 MRS R2, IPSR + 263 00000008 4B11 LDR R3, =log_direct + 264 0000000A 4798 BLX R3 + 265 0000000C E7FE B . + 266 0000000E + 267 0000000E ENDP + 268 0000000E + + + +ARM Macro Assembler Page 8 + + + 269 0000000E + 270 0000000E ; User Initial Stack + 271 0000000E EXPORT __user_setup_stackheap + 272 0000000E __user_setup_stackheap + PROC + 273 0000000E 4770 BX LR + 274 00000010 ENDP + 275 00000010 + 276 00000010 DEFAULT_HANDLER_TXT + 277 00000010 45 72 72 + 6F 72 21 + 20 50 6C + 65 61 73 + 65 20 69 + 6D 70 6C + 65 6D 65 + 6E 74 20 + 79 6F 75 + 72 20 49 + 53 52 20 + 48 61 6E + 64 6C 65 + 72 20 66 + 6F 72 20 + 49 52 51 + 20 25 64 + 21 0A 00 DCB "Error! Please implement your I +SR Handler for IRQ %d!\n", 0 + ; Null terminated s + tring + 278 00000046 00 00 ALIGN + 279 00000048 + 280 00000048 END + 20000000 + 00000000 + 00000000 +Command Line: --16 --debug --xref --cpreproc --diag_suppress=9931 --cpu=Cortex- +M0+ --apcs=interwork --depend=.\objects\startup_rtl876x.d -o.\objects\startup_r +tl876x.o -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include --predefine +="__UVISION_VERSION SETA 535" --predefine="ARMCM0P_MPU SETA 1" --list=.\listing +s\startup_rtl876x.lst ..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +VECTOR 00000000 + +Symbol: VECTOR + Definitions + At line 10 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + None +Comment: VECTOR unused +__Vectors 00000000 + +Symbol: __Vectors + Definitions + At line 15 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 11 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + +__Vectors_End 000000E8 + +Symbol: __Vectors_End + Definitions + At line 80 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 12 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + +3 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +RESET 00000000 + +Symbol: RESET + Definitions + At line 84 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + None +Comment: RESET unused +Reset_Handler 00000000 + +Symbol: Reset_Handler + Definitions + At line 87 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 16 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 88 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + +2 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +.text 00000000 + +Symbol: .text + Definitions + At line 96 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + None +Comment: .text unused +ADC_Handler 00000000 + +Symbol: ADC_Handler + Definitions + At line 204 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 51 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 124 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +BTMAC_Handler 00000000 + +Symbol: BTMAC_Handler + Definitions + At line 189 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 35 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 109 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +BusFault_Handler 00000000 + +Symbol: BusFault_Handler + Definitions + At line 182 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 20 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 102 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +CAP_Touch_Handler 00000000 + +Symbol: CAP_Touch_Handler + Definitions + At line 227 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 78 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 147 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +DEFAULT_HANDLER_TXT 00000010 + + + + +ARM Macro Assembler Page 2 Alphabetic symbol ordering +Relocatable symbols + +Symbol: DEFAULT_HANDLER_TXT + Definitions + At line 276 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 261 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: DEFAULT_HANDLER_TXT used once +Default_Handler 00000000 + +Symbol: Default_Handler + Definitions + At line 97 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 98 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s +Comment: Default_Handler used once +Enhanced_Timer0_Handler 00000000 + +Symbol: Enhanced_Timer0_Handler + Definitions + At line 210 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 57 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 130 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Enhanced_Timer1_Handler 00000000 + +Symbol: Enhanced_Timer1_Handler + Definitions + At line 211 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 58 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 131 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GDMA0_Channel0_Handler 00000000 + +Symbol: GDMA0_Channel0_Handler + Definitions + At line 206 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 53 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 126 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GDMA0_Channel1_Handler 00000000 + +Symbol: GDMA0_Channel1_Handler + Definitions + At line 207 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 + + + +ARM Macro Assembler Page 3 Alphabetic symbol ordering +Relocatable symbols + +6x.s + Uses + At line 54 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 127 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GDMA0_Channel2_Handler 00000000 + +Symbol: GDMA0_Channel2_Handler + Definitions + At line 208 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 55 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 128 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GDMA0_Channel3_Handler 00000000 + +Symbol: GDMA0_Channel3_Handler + Definitions + At line 209 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 56 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 129 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO0_Handler 00000000 + +Symbol: GPIO0_Handler + Definitions + At line 229 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 149 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO0_Handler used once +GPIO10_Handler 00000000 + +Symbol: GPIO10_Handler + Definitions + At line 237 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 157 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO10_Handler used once +GPIO11_Handler 00000000 + +Symbol: GPIO11_Handler + Definitions + At line 238 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 158 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 + + + +ARM Macro Assembler Page 4 Alphabetic symbol ordering +Relocatable symbols + +6x.s +Comment: GPIO11_Handler used once +GPIO12_Handler 00000000 + +Symbol: GPIO12_Handler + Definitions + At line 239 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 159 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO12_Handler used once +GPIO13_Handler 00000000 + +Symbol: GPIO13_Handler + Definitions + At line 240 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 160 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO13_Handler used once +GPIO14_Handler 00000000 + +Symbol: GPIO14_Handler + Definitions + At line 241 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 161 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO14_Handler used once +GPIO15_Handler 00000000 + +Symbol: GPIO15_Handler + Definitions + At line 242 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 162 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO15_Handler used once +GPIO16_Handler 00000000 + +Symbol: GPIO16_Handler + Definitions + At line 243 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 163 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO16_Handler used once +GPIO17_Handler 00000000 + +Symbol: GPIO17_Handler + Definitions + At line 244 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + + + +ARM Macro Assembler Page 5 Alphabetic symbol ordering +Relocatable symbols + + At line 164 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO17_Handler used once +GPIO18_Handler 00000000 + +Symbol: GPIO18_Handler + Definitions + At line 245 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 165 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO18_Handler used once +GPIO19_Handler 00000000 + +Symbol: GPIO19_Handler + Definitions + At line 246 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 166 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO19_Handler used once +GPIO1_Handler 00000000 + +Symbol: GPIO1_Handler + Definitions + At line 230 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 150 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO1_Handler used once +GPIO20_Handler 00000000 + +Symbol: GPIO20_Handler + Definitions + At line 247 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 167 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO20_Handler used once +GPIO21_Handler 00000000 + +Symbol: GPIO21_Handler + Definitions + At line 248 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 168 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO21_Handler used once +GPIO22_Handler 00000000 + +Symbol: GPIO22_Handler + Definitions + At line 249 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + + + +ARM Macro Assembler Page 6 Alphabetic symbol ordering +Relocatable symbols + + Uses + At line 169 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO22_Handler used once +GPIO23_Handler 00000000 + +Symbol: GPIO23_Handler + Definitions + At line 250 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 170 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO23_Handler used once +GPIO24_Handler 00000000 + +Symbol: GPIO24_Handler + Definitions + At line 251 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 171 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO24_Handler used once +GPIO25_Handler 00000000 + +Symbol: GPIO25_Handler + Definitions + At line 252 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 172 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO25_Handler used once +GPIO26_Handler 00000000 + +Symbol: GPIO26_Handler + Definitions + At line 253 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 173 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO26_Handler used once +GPIO27_Handler 00000000 + +Symbol: GPIO27_Handler + Definitions + At line 254 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 174 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO27_Handler used once +GPIO28_Handler 00000000 + +Symbol: GPIO28_Handler + Definitions + At line 255 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 + + + +ARM Macro Assembler Page 7 Alphabetic symbol ordering +Relocatable symbols + +6x.s + Uses + At line 175 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO28_Handler used once +GPIO29_Handler 00000000 + +Symbol: GPIO29_Handler + Definitions + At line 256 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 176 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO29_Handler used once +GPIO2_Handler 00000000 + +Symbol: GPIO2_Handler + Definitions + At line 231 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 151 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO2_Handler used once +GPIO30_Handler 00000000 + +Symbol: GPIO30_Handler + Definitions + At line 257 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 177 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO30_Handler used once +GPIO31_Handler 00000000 + +Symbol: GPIO31_Handler + Definitions + At line 258 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 178 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO31_Handler used once +GPIO3_Handler 00000000 + +Symbol: GPIO3_Handler + Definitions + At line 232 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 152 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO3_Handler used once +GPIO4_Handler 00000000 + +Symbol: GPIO4_Handler + Definitions + + + +ARM Macro Assembler Page 8 Alphabetic symbol ordering +Relocatable symbols + + At line 195 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 42 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 115 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO5_Handler 00000000 + +Symbol: GPIO5_Handler + Definitions + At line 196 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 43 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 116 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO6_Handler 00000000 + +Symbol: GPIO6_Handler + Definitions + At line 233 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 153 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO6_Handler used once +GPIO7_Handler 00000000 + +Symbol: GPIO7_Handler + Definitions + At line 234 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 154 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO7_Handler used once +GPIO8_Handler 00000000 + +Symbol: GPIO8_Handler + Definitions + At line 235 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 155 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: GPIO8_Handler used once +GPIO9_Handler 00000000 + +Symbol: GPIO9_Handler + Definitions + At line 236 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 156 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + + + +ARM Macro Assembler Page 9 Alphabetic symbol ordering +Relocatable symbols + +Comment: GPIO9_Handler used once +GPIO_Group0_Handler 00000000 + +Symbol: GPIO_Group0_Handler + Definitions + At line 216 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 63 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 136 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO_Group1_Handler 00000000 + +Symbol: GPIO_Group1_Handler + Definitions + At line 215 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 62 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 135 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO_Group2_Handler 00000000 + +Symbol: GPIO_Group2_Handler + Definitions + At line 213 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 60 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 133 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +GPIO_Group3_Handler 00000000 + +Symbol: GPIO_Group3_Handler + Definitions + At line 212 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 59 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 132 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +HardFault_Handler 00000000 + +Symbol: HardFault_Handler + Definitions + At line 180 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 18 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 38 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 + + + +ARM Macro Assembler Page 10 Alphabetic symbol ordering +Relocatable symbols + +x.s + At line 100 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +I2C0_Handler 00000000 + +Symbol: I2C0_Handler + Definitions + At line 202 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 49 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 122 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +I2C1_Handler 00000000 + +Symbol: I2C1_Handler + Definitions + At line 203 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 50 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 123 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +I2S0_RX_Handler 00000000 + +Symbol: I2S0_RX_Handler + Definitions + At line 192 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 39 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 113 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +I2S0_TX_Handler 00000000 + +Symbol: I2S0_TX_Handler + Definitions + At line 193 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 40 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 112 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +IR_Handler 00000000 + +Symbol: IR_Handler + Definitions + At line 214 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + + + +ARM Macro Assembler Page 11 Alphabetic symbol ordering +Relocatable symbols + + At line 61 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 134 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Keyscan_Handler 00000000 + +Symbol: Keyscan_Handler + Definitions + At line 223 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 74 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 143 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +LPCOMP_Handler 00000000 + +Symbol: LPCOMP_Handler + Definitions + At line 225 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 76 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 145 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +MemManage_Handler 00000000 + +Symbol: MemManage_Handler + Definitions + At line 181 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 19 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 101 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +NMI_Handler 00000000 + +Symbol: NMI_Handler + Definitions + At line 179 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 17 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 99 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + +PTA_Mailbox_Handler 00000000 + +Symbol: PTA_Mailbox_Handler + Definitions + At line 226 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + + + +ARM Macro Assembler Page 12 Alphabetic symbol ordering +Relocatable symbols + + Uses + At line 77 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 146 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +PendSV_Handler 00000000 + +Symbol: PendSV_Handler + Definitions + At line 185 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 29 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 105 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Peripheral_Handler 00000000 + +Symbol: Peripheral_Handler + Definitions + At line 205 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 52 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 125 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Qdecode_Handler 00000000 + +Symbol: Qdecode_Handler + Definitions + At line 222 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 73 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 142 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +RTC_Handler 00000000 + +Symbol: RTC_Handler + Definitions + At line 199 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 46 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 119 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SPI0_Handler 00000000 + +Symbol: SPI0_Handler + Definitions + At line 200 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 + + + +ARM Macro Assembler Page 13 Alphabetic symbol ordering +Relocatable symbols + +6x.s + Uses + At line 47 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 120 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SPI1_Handler 00000000 + +Symbol: SPI1_Handler + Definitions + At line 201 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 48 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 121 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SPI2W_Handler 00000000 + +Symbol: SPI2W_Handler + Definitions + At line 224 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 75 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 144 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SPI_Flash_Handler 00000000 + +Symbol: SPI_Flash_Handler + Definitions + At line 221 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 72 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 141 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SVC_Handler 00000000 + +Symbol: SVC_Handler + Definitions + At line 184 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 26 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 104 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +SysTick_Handler 00000000 + +Symbol: SysTick_Handler + Definitions + + + +ARM Macro Assembler Page 14 Alphabetic symbol ordering +Relocatable symbols + + At line 186 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 30 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 106 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +System_Handler 00000000 + +Symbol: System_Handler + Definitions + At line 187 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 33 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 107 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +TRNG_Handler 00000000 + +Symbol: TRNG_Handler + Definitions + At line 228 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 79 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 148 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Timer2_Handler 00000000 + +Symbol: Timer2_Handler + Definitions + At line 191 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 37 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 111 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Timer3_Handler 00000000 + +Symbol: Timer3_Handler + Definitions + At line 190 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 36 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 110 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Timer4_5_Handler 00000000 + +Symbol: Timer4_5_Handler + + + +ARM Macro Assembler Page 15 Alphabetic symbol ordering +Relocatable symbols + + Definitions + At line 194 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 41 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 114 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Timer4_Handler 00000000 + +Symbol: Timer4_Handler + Definitions + At line 219 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 67 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 139 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +Timer5_Handler 00000000 + +Symbol: Timer5_Handler + Definitions + At line 220 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 68 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 140 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +UART0_Handler 00000000 + +Symbol: UART0_Handler + Definitions + At line 198 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 45 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 118 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +UART1_Handler 00000000 + +Symbol: UART1_Handler + Definitions + At line 197 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 44 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 117 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +UsageFault_Handler 00000000 + + + + +ARM Macro Assembler Page 16 Alphabetic symbol ordering +Relocatable symbols + +Symbol: UsageFault_Handler + Definitions + At line 183 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 21 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 103 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +WDG_Handler 00000000 + +Symbol: WDG_Handler + Definitions + At line 188 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 34 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + At line 108 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + +__user_setup_stackheap 0000000E + +Symbol: __user_setup_stackheap + Definitions + At line 272 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 271 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: __user_setup_stackheap used once +82 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Absolute symbols + +__Vectors_Size 000000E8 + +Symbol: __Vectors_Size + Definitions + At line 82 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 13 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s +Comment: __Vectors_Size used once +__initial_sp 00203800 + +Symbol: __initial_sp + Definitions + At line 3 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x +.s + Uses + At line 2 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876x +.s + At line 15 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + +2 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +External symbols + +SystemInit 00000000 + +Symbol: SystemInit + Definitions + At line 89 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s + Uses + At line 90 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl876 +x.s +Comment: SystemInit used once +log_direct 00000000 + +Symbol: log_direct + Definitions + At line 259 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s + Uses + At line 263 in file ..\\..\\..\\..\\src\\mcu\\rtl876x\\arm\\startup_rtl87 +6x.s +Comment: log_direct used once +2 symbols +427 symbols in table diff --git a/board/evb/findmy/mdk/Objects/accessory_info_service.crf b/board/evb/findmy/mdk/Objects/accessory_info_service.crf new file mode 100644 index 0000000..31310fd Binary files /dev/null and b/board/evb/findmy/mdk/Objects/accessory_info_service.crf differ diff --git a/board/evb/findmy/mdk/Objects/accessory_info_service.d b/board/evb/findmy/mdk/Objects/accessory_info_service.d new file mode 100644 index 0000000..3e8712d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/accessory_info_service.d @@ -0,0 +1,32 @@ +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c +.\objects\accessory_info_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\accessory_info_service.o: ..\..\findmy\flash_map.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\trace.h +.\objects\accessory_info_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\accessory_info_service.o: ..\..\findmy\platform_autoconf.h +.\objects\accessory_info_service.o: ..\..\findmy\board.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\accessory_info_service.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\otp.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\accessory_info_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\accessory_info_service.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\accessory_info_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h diff --git a/board/evb/findmy/mdk/Objects/accessory_info_service.o b/board/evb/findmy/mdk/Objects/accessory_info_service.o new file mode 100644 index 0000000..b6f3eba Binary files /dev/null and b/board/evb/findmy/mdk/Objects/accessory_info_service.o differ diff --git a/board/evb/findmy/mdk/Objects/aes.crf b/board/evb/findmy/mdk/Objects/aes.crf new file mode 100644 index 0000000..d743099 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/aes.crf differ diff --git a/board/evb/findmy/mdk/Objects/aes.d b/board/evb/findmy/mdk/Objects/aes.d new file mode 100644 index 0000000..5cf7769 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/aes.d @@ -0,0 +1,29 @@ +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\aes.o: ..\..\findmy\flash_map.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\aes.o: ..\..\..\..\inc\os\os_mem.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\aes.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\aes.o: ..\..\..\..\inc\platform\trace.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\aes.o: ..\..\findmy\platform_autoconf.h +.\objects\aes.o: ..\..\findmy\board.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\aes.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\aes.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h diff --git a/board/evb/findmy/mdk/Objects/aes.o b/board/evb/findmy/mdk/Objects/aes.o new file mode 100644 index 0000000..561b67c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/aes.o differ diff --git a/board/evb/findmy/mdk/Objects/app.axf b/board/evb/findmy/mdk/Objects/app.axf new file mode 100644 index 0000000..480039c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/app.axf differ diff --git a/board/evb/findmy/mdk/Objects/app.build_log.htm b/board/evb/findmy/mdk/Objects/app.build_log.htm new file mode 100644 index 0000000..28ed53b --- /dev/null +++ b/board/evb/findmy/mdk/Objects/app.build_log.htm @@ -0,0 +1,151 @@ + + +
+

Vision Build Log

+

Tool Versions:

+IDE-Version: Vision V5.35.0.0 +Copyright (C) 2021 ARM Ltd and ARM Germany GmbH. All rights reserved. +License Information: yushanhe Administrator, ond, LIC=14HV2-9HAXY-WF1I7-EPPEH-WNZ0J-NQA6U + +Tool Versions: +Toolchain: MDK-ARM Plus Version: 5.35.0.2 +Toolchain Path: E:\Keil_V5\ARM\ARMCC\Bin +C Compiler: Armcc.exe V5.06 update 6 (build 750) +Assembler: Armasm.exe V5.06 update 6 (build 750) +Linker/Locator: ArmLink.exe V5.06 update 6 (build 750) +Library Manager: ArmAr.exe V5.06 update 6 (build 750) +Hex Converter: FromElf.exe V5.06 update 6 (build 750) +CPU DLL: SARMCM3.DLL V5.35.0.2 +Dialog DLL: DARMCM1.DLL V1.19.4.0 +Target DLL: Segger\JL2CM3.dll V2.99.40.0 +Dialog DLL: TARMCM1.DLL V1.14.4.0 + +

Project:

+C:\Users\Administrator\Desktop\Realtek_findmy_final_pakege_3\board\evb\findmy\mdk\findmy.uvprojx +Project File Date: 11/06/2025 + +

Output:

+*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'E:\Keil_V5\ARM\ARMCC\Bin' +Rebuild target 'findmy' +Before Build - User command #1: ..\..\..\..\tool\before_build_common.bat E:\Keil_V5\ +Before Build - User command #2: before_build_special.bat +build_before_special bat +assembling startup_rtl876x.s... +compiling rtl876x_nvic.c... +compiling rtl876x_rcc.c... +compiling rtl876x_tim.c... +compiling rtl876x_i2c.c... +compiling rtl876x_aon_wdg.c... +compiling rtl876x_adc.c... +compiling rtl876x_gpio.c... +compiling rtl876x_pinmux.c... +compiling system_rtl876x.c... +compiling rtl876x_io_dlps.c... +compiling findmy_network_service.c... +compiling ias.c... +compiling hids_kb.c... +compiling sdd_service.c... +compiling dis.c... +compiling firmware_update_service.c... +compiling accessory_info_service.c... +compiling tps.c... +compiling overlay_mgr.c... +compiling app_task.c... +compiling reset_watch_dog_timer.c... +compiling main.c... +compiling da213b.c... +compiling dfu_flash.c... +compiling custom_app.c... +compiling serial_number_send.c... +compiling findmy_app.c... +compiling key_handle.c... +compiling fmna_adv.c... +compiling fmna_config_control_point.c... +compiling fmna_debug_control_point.c... +compiling fmna_connection.c... +compiling fmna_gatt.c... +compiling fmna_motion_detection.c... +compiling fmna_nfc.c... +compiling fmna_nonowner_control_point.c... +compiling fmna_paired_owner_control_point.c... +compiling fmna_pairing_control_point.c... +compiling fmna_crypto.c... +compiling fmna_uarp_control_point.c... +compiling fmna_malloc_platform.c... +compiling fmna_version.c... +compiling fmna_state_machine.c... +compiling FMNASampleUARP.c... +compiling fmna_battery_platform.c... +compiling fmna_adv_platform.c... +compiling fmna_connection_platform.c... +compiling fmna_motion_detection_platform.c... +compiling fmna_gap_platform.c... +compiling fmna_dfu_platform.c... +compiling fmna_gatt_platform.c... +..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c(805): warning: #177-D: variable "p_sdd_cb_data" was declared but never referenced + T_SDD_CALLBACK_DATA *p_sdd_cb_data = (T_SDD_CALLBACK_DATA *)p_data; +..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c: 1 warning, 0 errors +compiling fmna_sound_platform.c... +compiling CoreUARPUtils.c... +compiling fmna_peer_manager.c... +compiling kdf963.c... +compiling CoreUARPPlatformRTK.c... +compiling fm-crypto.c... +compiling fmna_timer_platform.c... +compiling asn1parse.c... +compiling CoreUARPAccessory.c... +compiling asn1write.c... +compiling base64.c... +compiling aes.c... +compiling cipher.c... +compiling cipher_wrap.c... +compiling constant_time.c... +compiling CoreUARPPlatformAccessory.c... +compiling ecdh.c... +compiling bignum_core.c... +compiling platform.c... +compiling sha256.c... +compiling ecdsa.c... +compiling ecp_curves.c... +compiling md.c... +compiling platform_util.c... +compiling bignum.c... +compiling gcm.c... +compiling ecp.c... +linking... +Program Size: Code=99820 RO-data=46440 RW-data=840 ZI-data=7956 +After Build - User command #1: ..\..\..\..\tool\after_build_common.bat E:\Keil_V5\ARM\ARMCC\include C:\Users\Administrator\Desktop\Realtek_findmy_final_pakege_3\board\evb\findmy\mdk\Objects\app.axf app +go encrypt. +Plain text image. +Generating SHA256... +SHA256 = 423B45C7E5EAEA9E3A0E3835B3F83CF3FCB445A18EA7BCAFFA038E5254590ECF +MP header appending... +ini file path: ..\mp.ini +No BinDependence +No Comment +No Author +No Date +MP header appending OK! +MD5 v1.0.4 +Output Image: bin\app-a67926a7362b2dc4aab66cce8253a76a.bin +MD5 v1.0.4 +Output Image: bin\app_MP_findmy_1.1.1.0_8ab6d92f-b9f6e12ba9a77d357b7841f0adb5b519.bin +After Build - User command #2: after_build_special.bat +build_after_special bat +".\Objects\app.axf" - 0 Error(s), 1 Warning(s). + +

Software Packages used:

+ +Package Vendor: ARM + http://www.keil.com/pack/ARM.CMSIS.5.4.0.pack + ARM.CMSIS.5.4.0 + CMSIS (Cortex Microcontroller Software Interface Standard) + +

Collection of Component include folders:

+ E:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include + +

Collection of Component Files used:

+Build Time Elapsed: 00:00:03 +
+ + diff --git a/board/evb/findmy/mdk/Objects/app.htm b/board/evb/findmy/mdk/Objects/app.htm new file mode 100644 index 0000000..73fbfd9 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/app.htm @@ -0,0 +1,10343 @@ + + +Static Call Graph - [.\Objects\app.axf] +
+

Static Call Graph for image .\Objects\app.axf


+

#<CALLGRAPH># ARM Linker, 5060750: Last Updated: Tue Nov 25 08:50:59 2025 +

+

Maximum Stack Usage = 1944 bytes + Unknown(Cycles, Untraceable Function Pointers)

+Call chain for Maximum Stack Depth:

+app_main_task ⇒ app_handle_io_msg ⇒ app_handle_gpio_msg ⇒ serial_number_read_state_init ⇒ fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +

+

+Mutually Recursive functions +

  • gcm_mask   ⇒   mbedtls_cipher_update
    + +

    +

    +Function Pointers +

    +

    +

    +Global Symbols +

    +

    vAssertHandler (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_state_machine_init +
    • >>   fmna_crypto_key_restore +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    WDG_SystemReset (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   app_handle_gpio_msg +
    • >>   fmna_factory_reset +
    + +

    __aeabi_memcpy4 (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   AppUpdateVectorTable +
    • >>   mbedtls_mpi_core_exp_mod +
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_copy +
    • >>   __aeabi_memmove4 +
    • >>   mbedtls_sha256_clone +
    + +

    RamVectorTableInit (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   AppUpdateVectorTable +
    + +

    ROM_Default_Handler (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +
    [Address Reference Count : 1]

    • system_rtl876x.o(.app.overlay_a) +
    +

    SystemCall_Stack (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   server_attr_read_confirm +
    • >>   server_send_data +
    • >>   server_add_service +
    • >>   le_set_gap_param +
    • >>   le_privacy_check_resolvable_private_address +
    • >>   le_get_dev_irk +
    • >>   le_gen_rand_addr +
    • >>   le_disconnect +
    • >>   le_vendor_one_shot_adv +
    • >>   le_set_high_priority_bond_v2 +
    • >>   le_read_rssi +
    • >>   le_get_dev_info +
    • >>   le_get_conn_param +
    • >>   le_get_conn_local_addr +
    • >>   le_get_conn_handle +
    • >>   le_get_conn_addr +
    • >>   le_find_key_entry_by_idx +
    • >>   le_bond_passkey_input_confirm +
    • >>   le_bond_passkey_display_confirm +
    • >>   le_bond_just_work_confirm +
    • >>   le_bond_get_display_key +
    • >>   le_adv_read_tx_power +
    • >>   gap_get_param +
    • >>   gap_start_bt_stack +
    • >>   gap_handle_msg +
    • >>   le_set_local_ltk +
    • >>   le_register_app_cb +
    • >>   le_gap_init +
    • >>   le_bond_set_param +
    • >>   le_adv_set_param +
    • >>   gap_set_param +
    • >>   le_get_bond_dev_num +
    • >>   le_bond_delete_by_idx +
    • >>   server_register_app_cb +
    • >>   server_init +
    • >>   le_get_gap_param +
    • >>   le_get_conn_id_by_handle +
    • >>   gap_register_direct_cb +
    • >>   le_set_rand_addr +
    • >>   le_adv_update_param +
    • >>   gatts_service_changed_indicate +
    • >>   gaps_set_peripheral_preferred_conn_param +
    • >>   gaps_set_parameter +
    • >>   gatt_register_callback +
    • >>   le_dtm_test_end +
    • >>   le_dtm_transmitter_test +
    • >>   le_dtm_receiver_test +
    • >>   le_set_dev_bond_info +
    • >>   le_get_dev_bond_info +
    • >>   le_get_dev_bond_info_len +
    • >>   le_get_max_le_paired_device_num +
    • >>   le_clear_cccd_data +
    • >>   le_gen_bond_dev_v2 +
    • >>   le_gen_bond_dev +
    • >>   le_find_key_entry_v2 +
    • >>   le_get_cccd_data +
    • >>   le_resolve_random_address +
    • >>   le_set_high_priority_bond +
    • >>   le_get_high_priority_bond +
    • >>   le_get_low_priority_bond +
    • >>   le_find_key_entry +
    • >>   flash_load_local_irk +
    • >>   flash_save_local_irk +
    • >>   flash_load_local_appearance +
    • >>   flash_save_local_appearance +
    • >>   flash_load_local_name +
    • >>   flash_save_local_name +
    • >>   le_link_check_conn_id_internal +
    • >>   le_bond_get_pair_procedure_type +
    • >>   le_bond_get_sec_level +
    • >>   le_bond_delete_by_bd +
    • >>   le_bond_clear_all_keys +
    • >>   le_bond_cfg_local_key_distribute +
    • >>   le_bond_user_confirm +
    • >>   le_bond_pair +
    • >>   le_bond_get_param +
    • >>   le_set_conn_tx_power +
    • >>   le_update_conn_param +
    • >>   le_update_passed_chann_map +
    • >>   le_disable_slave_latency +
    • >>   le_set_data_len +
    • >>   le_get_idle_link_num +
    • >>   le_get_active_link_num +
    • >>   le_get_conn_id +
    • >>   le_get_conn_info +
    • >>   le_adv_set_tx_power +
    • >>   le_adv_stop +
    • >>   le_adv_start +
    • >>   le_adv_get_param +
    • >>   server_set_service_reg_mode +
    • >>   server_clear_service +
    • >>   server_get_start_handle +
    • >>   server_get_write_cmd_data_buffer +
    • >>   server_attr_write_confirm +
    • >>   server_exec_write_confirm +
    • >>   server_add_service_by_start_handle +
    • >>   server_builtin_service_reg +
    • >>   le_vendor_set_rem_min_sca +
    • >>   le_write_default_data_len +
    • >>   le_set_host_chann_classif +
    • >>   le_cfg_local_identity_address +
    • >>   le_modify_white_list +
    • >>   le_get_max_link_num +
    • >>   le_gap_msg_info_way +
    • >>   gap_send_dev_state +
    • >>   gap_buffer_free +
    • >>   gap_read_airplan_mode +
    • >>   gap_write_airplan_mode +
    • >>   gap_set_pairable_mode +
    • >>   gap_register_app_cb +
    • >>   hci_if_confirm +
    • >>   hci_if_write +
    • >>   hci_if_close +
    • >>   hci_if_open +
    • >>   btif_send_event +
    • >>   BTIF_VendorGetResponse +
    • >>   btif_sw_reset_req +
    • >>   btif_vendor_cmd_req +
    • >>   gap_register_extend_cb +
    + +

    update_ram_layout (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   SystemInit +
    + +

    get_active_ota_bank_addr (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   get_image_entry_addr +
    • >>   SystemInit +
    + +

    LogUartTxChar (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   log_direct_app +
    + +

    log_timestamp_get (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   log_direct_app +
    + +

    log_direct (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(.text) +
    +

    log_buffer (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   DLPS_IO_ExitDlpsCb +
    • >>   AppUpdateVectorTable +
    • >>   pre_main +
    • >>   print_reset_reason +
    • >>   sw_timer_init +
    • >>   one_shot_adv_init +
    • >>   fmna_version_init +
    • >>   fmna_sound_platform_init +
    • >>   fmna_motion_detection_init +
    • >>   fmna_connection_pair_info_restore +
    • >>   crypto_exit_dlps_config +
    • >>   bat_init_data +
    • >>   app_global_data_init +
    • >>   app_bond_info_restore +
    • >>   System_Handler +
    • >>   main +
    • >>   dis_add_service +
    • >>   dis_attr_read_cb +
    • >>   dis_set_parameter +
    • >>   sdd_add_service +
    • >>   sdd_attr_write_cb +
    • >>   sdd_cccd_update_cb +
    • >>   sdd_attr_read_cb +
    • >>   sdd_set_parameter +
    • >>   ias_add_service +
    • >>   ias_attr_write_cb +
    • >>   tps_add_service +
    • >>   tps_attr_read_cb +
    • >>   tps_set_parameter +
    • >>   fmna_version_get_fw_version +
    • >>   accessory_info_add_service +
    • >>   ais_attr_read_cb +
    • >>   findmy_network_add_service +
    • >>   fns_cccd_update_cb +
    • >>   fns_attr_write_cb +
    • >>   fns_write_post_callback +
    • >>   GPIO29_Handler +
    • >>   GPIO9_Handler +
    • >>   gpio_key_debounce_timeout_cb +
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    • >>   button_periodic_timer_cb +
    • >>   da213b_deinit +
    • >>   da213b_init +
    • >>   da213b_check_motion_flag +
    • >>   da213b_read_one_byte +
    • >>   da213b_write_one_byte +
    • >>   update_serial_number_in_adv +
    • >>   load_serial_number_from_flash +
    • >>   Timer3_Handler +
    • >>   fmna_connection_set_max_connections +
    • >>   fmble_gap_adv_start +
    • >>   fmble_gap_adv_data_set +
    • >>   cust_resume_pending_ble_oprations +
    • >>   cust_ble_set_to_idle +
    • >>   cust_adv_start +
    • >>   cust_adv_update_device_name +
    • >>   cust_feature_disable +
    • >>   cust_adv_stop +
    • >>   reset_data_copy_flag +
    • >>   read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data +
    • >>   cust_adv_update_timer_callback +
    • >>   serial_number_read_state_init +
    • >>   play_beep_mode +
    • >>   one_shot_handle_pending_adv +
    • >>   one_shot_adv_set_param +
    • >>   fmna_state_machine_init +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_sound_platform_stop +
    • >>   fmna_sound_platform_start +
    • >>   fmna_handle_ble_evt +
    • >>   fmna_connection_platform_get_serial_number +
    • >>   fmble_gap_adv_stop +
    • >>   custom_new_adv_stop +
    • >>   custom_new_adv_start +
    • >>   cust_handle_disconnected_evt +
    • >>   cust_handle_connected_evt +
    • >>   cust_feature_enable +
    • >>   cust_factory_reset +
    • >>   cust_data_init +
    • >>   cust_adv_init +
    • >>   crypto_enter_dlps_config +
    • >>   bat_update_battery_info +
    • >>   app_gap_callback +
    • >>   app_handle_bond_modify_msg +
    • >>   password_verification_timeout +
    • >>   app_handle_gap_msg +
    • >>   app_handle_dev_state_evt +
    • >>   app_handle_conn_state_evt +
    • >>   app_handle_conn_mtu_info_evt +
    • >>   app_handle_conn_param_update_evt +
    • >>   app_handle_authen_state_evt +
    • >>   app_handle_gpio_msg +
    • >>   fmna_factory_reset +
    • >>   double_click_detect_timer_cb +
    • >>   handle_ten_click +
    • >>   app_handle_io_msg +
    • >>   app_sched_event_put +
    • >>   app_send_msg_to_apptask +
    • >>   motion_poll_timer_timeout_handler +
    • >>   motion_active_poll_duration_timer_timeout_handler +
    • >>   motion_active_poll_duration_timeout_sched_handler +
    • >>   motion_backoff_timeout_handler +
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_pairing_control_point_append_to_rx_buffer +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_gatt_platform_services_init +
    • >>   fmna_gatt_platform_send_next_indication +
    • >>   fmna_gatt_platform_send_indication_busy +
    • >>   fmna_gatt_platform_send_indication +
    • >>   fmna_gatt_platform_reset_indication_queue +
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    • >>   fmna_gatt_debug_char_write_handler +
    • >>   fmna_gatt_paired_owner_char_write_handler +
    • >>   fmna_gatt_nonown_char_write_handler +
    • >>   fmna_gatt_config_char_write_handler +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fmna_state_machine_set_key_rotation_timeout_ms +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_malloc +
    • >>   fmna_free +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fmna_connection_platform_log_token_help +
    • >>   fmna_connection_platform_log_token +
    • >>   fmna_log_serial_number +
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_primary_key_update +
    • >>   fmna_crypto_roll_primary_key +
    • >>   fmna_crypto_roll_secondary_sk +
    • >>   fmna_crypto_roll_primary_sk +
    • >>   fmna_crypto_pairing_complete +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    • >>   fmna_crypto_init +
    • >>   fmna_crypto_key_restore +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   fmna_pm_delete_bonds +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_evt_handler +
    • >>   fmna_crypto_unpair +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_connection_set_active_ltk +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_connection_conn_param_update_handler +
    • >>   fmna_connection_connected_handler +
    • >>   fmna_connection_update_connection_info_all +
    • >>   fmna_connection_disconnect_this +
    • >>   fmna_connection_disconnect_all +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_state_machine_set_next_keyroll_ms +
    • >>   fmna_state_machine_set_nearby_timeout_seconds +
    • >>   fmna_state_machine_latch_current_separated_key +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_connection_update_connection_info +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_config_control_point_is_tx_allowed +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    • >>   fmna_adv_platform_init_separated +
    • >>   fmna_adv_platform_init_pairing +
    • >>   fmna_adv_platform_init_nearby +
    • >>   fmna_adv_platform_get_default_bt_addr +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    • >>   gap_lib_init +
    • >>   fmna_rotate_key_internal +
    • >>   fmna_pm_peer_count +
    • >>   fmna_all_pairing_buf_free +
    • >>   fmna_rotate_key +
    • >>   dispatch_set_next_secondary_key_rotation_index_handler +
    • >>   fmna_key_rotation_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_fmna_pair_evt_fmna_pairing_finalize_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    • >>   fmna_connected_evt_debug_reset_handler +
    • >>   fmna_connected_evt_disconnected_handler +
    • >>   fmna_nearby_evt_connected_handler +
    • >>   fmna_separated_evt_sound_complete_handler +
    • >>   fmna_generic_evt_sound_complete_handler +
    • >>   fmna_separated_evt_connected_handler +
    • >>   fmna_pair_evt_connected_handler +
    • >>   fmna_pair_evt_disconnected_handler +
    • >>   fmna_pair_evt_pair_handler +
    • >>   fmna_boot_evt_boot_handler +
    • >>   fmna_one_time_key_rotation_handler +
    • >>   fmna_non_owner_0_connection_timeout_handler +
    • >>   fmna_non_owner_1_connection_timeout_handler +
    • >>   fmna_pair_connection_timeout_handler +
    • >>   separated_ut_timeout_handler +
    • >>   fmna_persistent_connection_disconnection_timeout_handler +
    • >>   fmna_update_secondary_index +
    • >>   set_is_nearby +
    • >>   fmna_motion_detection_platform_init +
    • >>   fmna_motion_detection_platform_deinit +
    • >>   fmna_motion_detection_start +
    • >>   fmna_motion_detection_stop +
    • >>   fmna_motion_detection_start_active_polling +
    • >>   adv_timer_callback +
    • >>   sn_lookup_callback +
    • >>   aon_watch_dog_wake_up_dlps_callback +
    • >>   fmna_sound_timeout_handler +
    • >>   beep_sequence_handler +
    • >>   app_profile_callback +
    • >>   app_bt_direct_callback +
    • >>   custom_new_adv_timer_callback +
    • >>   customized_adv_timer_callback +
    • >>   findmy_adv_timer_callback +
    • >>   fmna_pm_conn_sec_handle +
    • >>   fmna_main_task +
    • >>   Timer4_Handler +
    + +

    trace_bdaddr (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   app_global_data_init +
    • >>   cust_adv_update_timer_callback +
    • >>   cust_adv_init +
    • >>   app_gap_callback +
    • >>   app_handle_bond_modify_msg +
    • >>   app_handle_conn_state_evt +
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    + +

    trace_string (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   AppUpdateVectorTable +
    • >>   pre_main +
    • >>   fmna_sound_platform_init +
    • >>   fmna_motion_detection_init +
    • >>   fmna_connection_set_max_connections +
    • >>   cust_adv_start +
    • >>   cust_adv_update_device_name +
    • >>   cust_adv_stop +
    • >>   serial_number_read_state_init +
    • >>   one_shot_adv_set_param +
    • >>   fmna_state_machine_init +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_sound_platform_stop +
    • >>   fmna_sound_platform_start +
    • >>   double_click_detect_timer_cb +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_state_machine_set_key_rotation_timeout_ms +
    • >>   fmna_log_serial_number +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_crypto_key_restore +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   fmna_evt_handler +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_connection_connected_handler +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_state_machine_set_next_keyroll_ms +
    • >>   fmna_adv_platform_get_default_bt_addr +
    • >>   fmna_rotate_key +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_boot_evt_boot_handler +
    • >>   fmna_one_time_key_rotation_handler +
    • >>   fmna_update_secondary_index +
    • >>   set_is_nearby +
    + +

    trace_binary (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   load_serial_number_from_flash +
    • >>   app_gap_callback +
    • >>   fmna_connection_platform_log_token_help +
    • >>   fmna_connection_platform_log_token +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_primary_key_update +
    • >>   fmna_crypto_pairing_complete +
    • >>   fmna_crypto_init +
    • >>   fmna_crypto_key_restore +
    • >>   fmna_adv_platform_init_separated +
    • >>   fmna_adv_platform_init_pairing +
    • >>   fmna_adv_platform_init_nearby +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    + +

    ftl_load (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_connection_pair_info_restore +
    • >>   app_bond_info_restore +
    • >>   read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data +
    • >>   cust_data_init +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_crypto_key_restore +
    + +

    ftl_save (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   cust_adv_update_device_name +
    • >>   save_single_id_to_flash +
    • >>   fmna_connection_set_is_fmna_paired +
    • >>   app_handle_bond_modify_msg +
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_primary_key_update +
    • >>   fmna_crypto_pairing_complete +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_state_machine_latch_current_separated_key +
    • >>   fmna_rotate_key +
    • >>   dispatch_set_next_secondary_key_rotation_index_handler +
    • >>   fmna_connected_evt_debug_reset_handler +
    • >>   app_profile_callback +
    + +

    ftl_init (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    + +

    flash_get_bank_addr (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    + +

    flash_get_bank_size (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    + +

    flash_erase_locked (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_connection_update_mfi_token_storage +
    + +

    flash_write_locked (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_connection_update_mfi_token_storage +
    + +

    flash_read_locked (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_connection_platform_get_serial_number +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    • >>   fmna_crypto_init +
    • >>   ADC_CalibrationInit +
    + +

    flash_try_high_speed (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   main +
    + +

    check_hci_mode_flag (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   SystemInit +
    + +

    check_header_valid (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   get_image_entry_addr +
    • >>   SystemInit +
    + +

    get_header_addr_by_img_id (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   get_image_entry_addr +
    • >>   SystemInit +
    + +

    platform_random (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    • >>   random_seed_init +
    + +

    power_manager_suspend_all (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +

    [Called By]

    • >>   set_boot_active_time +
    + +

    power_manager_resume_all (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_active_timer_callback +
    + +

    platform_pm_set_power_mode (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   main +
    • >>   pwr_mgr_init +
    + +

    platform_pm_get_power_mode (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   DLPS_IO_EnterDlpsCb +
    + +

    platform_pm_register_callback_func (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   DLPS_IORegister +
    • >>   main +
    • >>   pwr_mgr_init +
    + +

    Pinmux_Deinit_rom (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   SystemInit +
    + +

    WDG_ClockEnable (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   print_reset_reason +
    + +

    WDG_Config (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   print_reset_reason +
    + +

    WDG_Enable (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   print_reset_reason +
    + +

    WDG_Disable (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    • >>   print_reset_reason +
    + +

    reset_reason_get (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   print_reset_reason +
    • >>   main +
    + +

    os_mem_alloc_intern (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   realloc +
    • >>   malloc +
    • >>   app_sched_event_put +
    • >>   fmna_gatt_platform_send_indication_busy +
    + +

    os_mem_zalloc_intern (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   calloc +
    • >>   fmna_malloc +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fm_crypto_ckg_init +
    • >>   ecp_mul_comb +
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   aes_ctx_alloc +
    • >>   gcm_ctx_alloc +
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_asn1_store_named_data +
    • >>   asn1_get_sequence_of_cb +
    • >>   mbedtls_md_setup +
    + +

    os_mem_free (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   free +
    • >>   realloc +
    • >>   app_handle_io_msg +
    • >>   fmna_gatt_platform_send_next_indication +
    • >>   fmna_free +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fm_crypto_ckg_free +
    • >>   fmna_all_pairing_buf_free +
    • >>   ecp_mul_comb +
    • >>   ecp_restart_rsm_free +
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_restart_free +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_restart_free +
    • >>   aes_ctx_free +
    • >>   gcm_ctx_free +
    • >>   mbedtls_zeroize_and_free +
    • >>   mbedtls_asn1_store_named_data +
    • >>   mbedtls_asn1_free_named_data_list_shallow +
    • >>   mbedtls_asn1_free_named_data_list +
    • >>   mbedtls_asn1_free_named_data +
    • >>   mbedtls_asn1_sequence_free +
    • >>   mbedtls_md_free +
    • >>   mbedtls_ecp_group_free +
    + +

    os_msg_queue_create_intern (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   app_main_task +
    + +

    os_msg_send_intern (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   app_sched_event_put +
    • >>   app_send_msg_to_apptask +
    • >>   fmna_gatt_platform_send_indication_busy +
    + +

    os_msg_recv_intern (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   app_main_task +
    • >>   fmna_gatt_platform_send_next_indication +
    • >>   fmna_gatt_platform_reset_indication_queue +
    + +

    os_delay (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   button_periodic_timer_cb +
    • >>   da213b_deinit +
    • >>   da213b_init +
    • >>   da213b_check_motion_flag +
    • >>   app_handle_gpio_msg +
    • >>   fmna_factory_reset +
    • >>   fmna_connected_evt_debug_reset_handler +
    • >>   beep_sequence_handler +
    + +

    os_sys_time_get (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_sound_platform_start +
    • >>   app_handle_gpio_msg +
    • >>   fmna_sound_get_remaining_time +
    + +

    os_sched_start (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   common_main +
    • >>   main +
    + +

    os_sched_suspend (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +

    [Called By]

    • >>   realloc +
    + +

    os_sched_resume (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +

    [Called By]

    • >>   realloc +
    + +

    os_lock (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   log_direct_app +
    • >>   fmna_gatt_platform_get_next_command_response_index +
    + +

    os_unlock (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   log_direct_app +
    • >>   fmna_gatt_platform_get_next_command_response_index +
    + +

    os_sem_create (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_main_task +
    + +

    os_sem_take (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_rotate_key_internal +
    + +

    os_sem_give (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_main_task +
    + +

    os_task_create (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_task_init +
    • >>   app_task_init +
    + +

    os_task_suspend (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   crypto_enter_dlps_config +
    • >>   fmna_rotate_key_internal +
    • >>   fmna_main_task +
    + +

    os_task_resume (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   crypto_exit_dlps_config +
    • >>   fmna_rotate_key_internal +
    + +

    os_timer_create (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_boot_active_time +
    • >>   sw_timer_init +
    • >>   one_shot_adv_init +
    • >>   gpio_driver_init +
    • >>   cust_adv_init +
    • >>   app_timer_create +
    + +

    os_timer_start (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_boot_active_time +
    • >>   sw_timer_init +
    • >>   System_Handler +
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    • >>   serial_number_read_state_init +
    • >>   cust_feature_enable +
    • >>   app_handle_dev_state_evt +
    • >>   app_handle_gpio_msg +
    • >>   double_click_detect_timer_cb +
    • >>   fmna_config_control_point_rx_handler +
    + +

    os_timer_restart (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_boot_active_time +
    • >>   fmble_gap_adv_start +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   app_timer_start +
    + +

    os_timer_stop (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_active_timer_callback +
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    • >>   cust_feature_disable +
    • >>   fmna_adv_platform_stop_adv +
    • >>   fmble_gap_adv_stop +
    • >>   password_verification_timeout +
    • >>   app_handle_gpio_msg +
    • >>   fmna_connection_fmna_unpair +
    • >>   app_timer_stop +
    + +

    os_timer_delete (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   set_active_timer_callback +
    + +

    os_timer_state_get (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   fmna_adv_platform_stop_adv +
    • >>   app_timer_stop +
    + +

    btaon_fast_read_safe (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   Pad_Config +
    • >>   DLPS_IO_ExitDlpsCb +
    • >>   DLPS_IO_EnterDlpsCb +
    • >>   print_reset_reason +
    • >>   ADC_BypassCmd +
    • >>   ADC_Cmd +
    • >>   ADC_Init +
    • >>   Pad_ClearAllWakeupINT +
    • >>   Pad_ClearWakeupINTPendingBit +
    • >>   Pad_ControlSelectValue +
    • >>   Pad_PowerOrShutDownValue +
    • >>   Pad_PullConfigValue +
    • >>   Pad_PullUpOrDownValue +
    • >>   Pad_PullEnableValue +
    • >>   Pad_OutputEnableValue +
    • >>   Pad_OutputControlValue +
    • >>   System_WakeUpInterruptValue +
    • >>   Pad_WakeupInterruptValue +
    • >>   System_WakeUpPinEnable +
    • >>   System_WakeUpPinDisable +
    • >>   System_DebounceWakeupStatus +
    • >>   Pad_DebounceWakeupStatus +
    • >>   Pad_WakeupPolarityValue +
    • >>   Pad_WKDebounceConfig +
    • >>   Pad_WakeupEnableValue +
    + +

    btaon_fast_write_safe (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   Pad_Config +
    • >>   DLPS_IO_ExitDlpsCb +
    • >>   DLPS_IO_EnterDlpsCb +
    • >>   ADC_BypassCmd +
    • >>   ADC_Cmd +
    • >>   ADC_Init +
    • >>   Pad_ClearAllWakeupINT +
    • >>   Pad_ClearWakeupINTPendingBit +
    • >>   Pad_ControlSelectValue +
    • >>   Pad_PowerOrShutDownValue +
    • >>   Pad_PullConfigValue +
    • >>   Pad_PullUpOrDownValue +
    • >>   Pad_PullEnableValue +
    • >>   Pad_OutputEnableValue +
    • >>   Pad_OutputControlValue +
    • >>   System_WakeUpPinEnable +
    • >>   System_WakeUpPinDisable +
    • >>   System_DebounceWakeupStatus +
    • >>   Pad_DebounceWakeupStatus +
    • >>   Pad_WakeupPolarityValue +
    • >>   Pad_WKDebounceConfig +
    • >>   Pad_WakeupEnableValue +
    + +

    btmac_pm_set_power_mode (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   main +
    • >>   pwr_mgr_init +
    + +

    SHA256_Init (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   mbedtls_sha256_starts +
    + +

    SHA256_Update (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   mbedtls_sha256_update +
    • >>   mbedtls_internal_sha256_process +
    + +

    SHA256_Final (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   mbedtls_sha256_finish +
    + +

    SHA256 (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   mbedtls_sha256 +
    + +

    setlocale (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   pre_main +
    + +

    memcmp (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   load_overlay +
    • >>   get_current_scenario_index +
    • >>   app_handle_conn_state_evt +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   mbedtls_asn1_find_named_data +
    + +

    strlen (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE), UNUSED) +

    [Called By]

    • >>   mbedtls_mpi_read_string +
    + +

    __aeabi_memcpy (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   load_overlay +
    • >>   realloc +
    • >>   pre_main +
    • >>   ram_cache_init +
    • >>   ram_init +
    • >>   SystemInit +
    • >>   dis_set_parameter +
    • >>   sdd_attr_write_cb +
    • >>   tps_set_parameter +
    • >>   get_serial_number +
    • >>   update_serial_number_in_adv +
    • >>   cust_adv_update_device_name +
    • >>   set_serial_number_to_adv +
    • >>   fmna_gatt_platform_get_gatt_data +
    • >>   app_gap_callback +
    • >>   app_sched_event_put +
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_pairing_control_point_append_to_rx_buffer +
    • >>   fmna_gatt_platform_send_indication_busy +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_server_shared_secret +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   fm_crypto_ckg_finish +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_crypto_roll_primary_key +
    • >>   fmna_crypto_roll_secondary_sk +
    • >>   fmna_crypto_roll_primary_sk +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    • >>   fmna_connection_set_active_ltk +
    • >>   fmna_adv_platform_init_separated +
    • >>   fmna_adv_platform_init_pairing +
    • >>   fmna_adv_platform_init_nearby +
    • >>   fmna_adv_init_separated +
    • >>   mbedtls_ecdsa_write_signature_restartable +
    • >>   mbedtls_gcm_starts +
    • >>   mbedtls_gcm_finish +
    • >>   mbedtls_cipher_set_iv +
    • >>   mbedtls_mpi_core_read_be +
    • >>   mbedtls_asn1_store_named_data +
    • >>   mbedtls_asn1_write_octet_string +
    • >>   mbedtls_asn1_write_bitstring +
    • >>   mbedtls_asn1_write_tagged_string +
    • >>   mbedtls_asn1_write_algorithm_identifier_ext +
    • >>   mbedtls_asn1_write_oid +
    • >>   mbedtls_asn1_write_raw_buffer +
    • >>   mbedtls_platform_frng +
    • >>   mbed_KDF963 +
    • >>   __aeabi_memmove +
    • >>   gap_vendor_set_ant_ctrl +
    • >>   le_vendor_adv_3_data_set +
    + +

    __aeabi_memset (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   mbedtls_md_hmac_starts +
    + +

    _memset (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   memset +
    + +

    __aeabi_memclr (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   load_overlay +
    • >>   pre_main +
    • >>   ram_cache_init +
    • >>   ram_init +
    • >>   SystemInit +
    • >>   set_serial_number_to_adv +
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_pairing_control_point_unpair +
    • >>   ecp_mul_comb_after_precomp +
    • >>   mbedtls_mpi_core_write_le +
    • >>   mbedtls_mpi_core_write_be +
    • >>   mbedtls_platform_frng +
    + +

    __aeabi_memclr4 (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   one_shot_adv_init +
    • >>   app_global_data_init +
    • >>   app_gap_callback +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fm_crypto_ckg_init +
    • >>   fm_crypto_ckg_free +
    • >>   mbedtls_ecdsa_write_signature_restartable +
    • >>   mbedtls_cipher_setup +
    • >>   mbedtls_cipher_init +
    • >>   mbedtls_mpi_core_exp_mod +
    • >>   mbedtls_mpi_core_shift_r +
    • >>   mbedtls_mpi_core_read_le +
    • >>   mbedtls_mpi_core_read_be +
    • >>   mbedtls_mpi_core_random +
    • >>   mbedtls_mpi_core_mul +
    • >>   mbedtls_mpi_core_montmul +
    • >>   mbedtls_mpi_core_fill_random +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_resize_clear +
    • >>   mbedtls_aes_setkey_dec +
    • >>   mbedtls_aes_init +
    • >>   mbedtls_sha256_init +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_gcm_init +
    • >>   le_vendor_set_priority +
    + +

    exit (Thumb, 0 bytes, Stack size 0 bytes, ROM.lib(ABSOLUTE)) +

    [Called By]

    • >>   __rt_entry_main +
    + +

    GPIO_Group3_Handler (Thumb, 72 bytes, Stack size 8 bytes, system_rtl876x.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = GPIO_Group3_Handler +
    +
    [Calls]
    • >>   GPIO7_Handler +
    • >>   GPIO3_Handler +
    • >>   GPIO31_Handler +
    • >>   GPIO27_Handler +
    • >>   GPIO23_Handler +
    • >>   GPIO19_Handler +
    • >>   GPIO15_Handler +
    • >>   GPIO11_Handler +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    GPIO_Group2_Handler (Thumb, 72 bytes, Stack size 8 bytes, system_rtl876x.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = GPIO_Group2_Handler +
    +
    [Calls]
    • >>   GPIO6_Handler +
    • >>   GPIO30_Handler +
    • >>   GPIO2_Handler +
    • >>   GPIO26_Handler +
    • >>   GPIO22_Handler +
    • >>   GPIO18_Handler +
    • >>   GPIO14_Handler +
    • >>   GPIO10_Handler +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    GPIO_Group1_Handler (Thumb, 64 bytes, Stack size 8 bytes, system_rtl876x.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = GPIO_Group1_Handler ⇒ GPIO29_Handler ⇒ cust_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO25_Handler +
    • >>   GPIO21_Handler +
    • >>   GPIO1_Handler +
    • >>   GPIO17_Handler +
    • >>   GPIO13_Handler +
    • >>   GPIO29_Handler +
    • >>   GPIO9_Handler +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    GPIO_Group0_Handler (Thumb, 64 bytes, Stack size 8 bytes, system_rtl876x.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = GPIO_Group0_Handler +
    +
    [Calls]
    • >>   GPIO8_Handler +
    • >>   GPIO28_Handler +
    • >>   GPIO24_Handler +
    • >>   GPIO20_Handler +
    • >>   GPIO16_Handler +
    • >>   GPIO12_Handler +
    • >>   GPIO0_Handler +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    DLPS_IO_EnterDlpsCb (Thumb, 642 bytes, Stack size 32 bytes, rtl876x_io_dlps.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = DLPS_IO_EnterDlpsCb ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    • >>   platform_pm_get_power_mode +
    +
    [Address Reference Count : 1]
    • rtl876x_io_dlps.o(.text) +
    +

    DLPS_IO_ExitDlpsCb (Thumb, 848 bytes, Stack size 40 bytes, rtl876x_io_dlps.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = DLPS_IO_ExitDlpsCb ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   NVIC_Init +
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • rtl876x_io_dlps.o(.text) +
    +

    Timer3_Handler (Thumb, 60 bytes, Stack size 16 bytes, reset_watch_dog_timer.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = Timer3_Handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   TIM_Cmd +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    mbedtls_mpi_add_abs (Thumb, 158 bytes, Stack size 24 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_add +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   add_sub_mpi +
    + +

    mbedtls_mpi_sub_abs (Thumb, 152 bytes, Stack size 24 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_mpi_sub_abs ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy4 +
    • >>   mbedtls_mpi_core_sub_int +
    • >>   mbedtls_mpi_core_sub +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   mbedtls_mpi_shift_l_mod +
    • >>   mbedtls_mpi_add_mod +
    • >>   ecp_double_jac +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_gcd +
    • >>   add_sub_mpi +
    + +

    mbedtls_mpi_add_mpi (Thumb, 10 bytes, Stack size 8 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = mbedtls_mpi_add_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   add_sub_mpi +
    +
    [Called By]
    • >>   mbedtls_mpi_sub_mod +
    • >>   ecp_sw_rhs +
    • >>   mbedtls_mpi_add_mod +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    mbedtls_mpi_mul_int (Thumb, 104 bytes, Stack size 32 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = mbedtls_mpi_mul_int ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_mla +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_double_jac +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_div_mpi +
    + +

    mbedtls_mpi_sub_mpi (Thumb, 12 bytes, Stack size 8 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = mbedtls_mpi_sub_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   add_sub_mpi +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   mbedtls_mpi_sub_mod +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_div_mpi (Thumb, 1016 bytes, Stack size 136 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 240
    • Call Chain = mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_clz +
    • >>   mbedtls_mpi_core_bitlen +
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_shift_r +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_cmp_abs +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_mul_int +
    • >>   add_sub_mpi +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_div_int +
    • >>   mbedtls_mpi_mod_mpi +
    + +

    mbedtls_mpi_div_int (Thumb, 46 bytes, Stack size 24 bytes, bignum.o(.app.data_ram.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_div_mpi +
    + +

    mbedtls_mpi_mod_int (Thumb, 156 bytes, Stack size 40 bytes, bignum.o(.app.data_ram.text), UNUSED) +

    [Calls]

    • >>   __aeabi_uidivmod +
    + +

    mbedtls_mpi_mul_mpi (Thumb, 222 bytes, Stack size 64 bytes, bignum.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 148
    • Call Chain = mbedtls_mpi_mul_mpi ⇒ mbedtls_mpi_core_mul ⇒ mbedtls_mpi_core_mla +
    +
    [Calls]
    • >>   mbedtls_mpi_core_mul +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    AppUpdateVectorTable (Thumb, 174 bytes, Stack size 264 bytes, system_rtl876x.o(.app.overlay_a)) +

    [Stack]

    • Max Depth = 264
    • Call Chain = AppUpdateVectorTable +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   RamVectorTableInit +
    • >>   __aeabi_memcpy4 +
    +
    [Called By]
    • >>   pre_main +
    + +

    Reset_Handler (Thumb, 4 bytes, Stack size 0 bytes, startup_rtl876x.o(RESET)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    __main (Thumb, 8 bytes, Stack size 0 bytes, __main.o(!!!main)) +

    [Calls]

    • >>   __rt_entry +
    • >>   __scatterload (Weak Reference) +
    +
    [Called By]
    • >>   common_main +
    + +

    _printf_percent (Thumb, 0 bytes, Stack size unknown bytes, _printf_percent.o(.ARM.Collect$$_printf_percent$$00000000)) +

    [Called By]

    • >>   __printf +
    + +

    _printf_n (Thumb, 0 bytes, Stack size unknown bytes, _printf_n.o(.ARM.Collect$$_printf_percent$$00000001)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_n ⇒ _printf_p ⇒ _printf_f ⇒ _printf_e ⇒ _printf_g ⇒ _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_charcount +
    • >>   _printf_p +
    + +

    _printf_p (Thumb, 0 bytes, Stack size unknown bytes, _printf_p.o(.ARM.Collect$$_printf_percent$$00000002)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_p ⇒ _printf_f ⇒ _printf_e ⇒ _printf_g ⇒ _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_f +
    • >>   _printf_hex_ptr +
    +
    [Called By]
    • >>   _printf_n +
    + +

    _printf_f (Thumb, 0 bytes, Stack size unknown bytes, _printf_f.o(.ARM.Collect$$_printf_percent$$00000003)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_f ⇒ _printf_e ⇒ _printf_g ⇒ _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_fp_dec +
    • >>   _printf_e +
    +
    [Called By]
    • >>   _printf_p +
    + +

    _printf_e (Thumb, 0 bytes, Stack size unknown bytes, _printf_e.o(.ARM.Collect$$_printf_percent$$00000004)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_e ⇒ _printf_g ⇒ _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_fp_dec +
    • >>   _printf_g +
    +
    [Called By]
    • >>   _printf_f +
    + +

    _printf_g (Thumb, 0 bytes, Stack size unknown bytes, _printf_g.o(.ARM.Collect$$_printf_percent$$00000005)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_g ⇒ _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_fp_dec +
    • >>   _printf_a +
    +
    [Called By]
    • >>   _printf_e +
    + +

    _printf_a (Thumb, 0 bytes, Stack size unknown bytes, _printf_a.o(.ARM.Collect$$_printf_percent$$00000006)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_a ⇒ _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_fp_hex +
    • >>   _printf_ll +
    +
    [Called By]
    • >>   _printf_g +
    + +

    _printf_ll (Thumb, 0 bytes, Stack size unknown bytes, _printf_ll.o(.ARM.Collect$$_printf_percent$$00000007)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_ll ⇒ _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_i +
    +
    [Called By]
    • >>   _printf_a +
    + +

    _printf_i (Thumb, 0 bytes, Stack size unknown bytes, _printf_i.o(.ARM.Collect$$_printf_percent$$00000008)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_i ⇒ _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_dec +
    • >>   _printf_d +
    +
    [Called By]
    • >>   _printf_ll +
    + +

    _printf_d (Thumb, 0 bytes, Stack size unknown bytes, _printf_d.o(.ARM.Collect$$_printf_percent$$00000009)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_d ⇒ _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_dec +
    • >>   _printf_u +
    +
    [Called By]
    • >>   _printf_i +
    + +

    _printf_u (Thumb, 0 bytes, Stack size unknown bytes, _printf_u.o(.ARM.Collect$$_printf_percent$$0000000A)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_u ⇒ _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_dec +
    • >>   _printf_o +
    +
    [Called By]
    • >>   _printf_d +
    + +

    _printf_o (Thumb, 0 bytes, Stack size unknown bytes, _printf_o.o(.ARM.Collect$$_printf_percent$$0000000B)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_o ⇒ _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_x +
    • >>   _printf_int_oct +
    +
    [Called By]
    • >>   _printf_u +
    + +

    _printf_x (Thumb, 0 bytes, Stack size unknown bytes, _printf_x.o(.ARM.Collect$$_printf_percent$$0000000C)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_x ⇒ _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_lli +
    • >>   _printf_int_hex +
    +
    [Called By]
    • >>   _printf_o +
    + +

    _printf_lli (Thumb, 0 bytes, Stack size unknown bytes, _printf_lli.o(.ARM.Collect$$_printf_percent$$0000000D)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_lli ⇒ _printf_lld ⇒ _printf_llu ⇒ _printf_llo ⇒ _printf_llx ⇒ _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_lld +
    • >>   _printf_longlong_dec +
    +
    [Called By]
    • >>   _printf_x +
    + +

    _printf_lld (Thumb, 0 bytes, Stack size unknown bytes, _printf_lld.o(.ARM.Collect$$_printf_percent$$0000000E)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_lld ⇒ _printf_llu ⇒ _printf_llo ⇒ _printf_llx ⇒ _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_llu +
    • >>   _printf_longlong_dec +
    +
    [Called By]
    • >>   _printf_lli +
    + +

    _printf_llu (Thumb, 0 bytes, Stack size unknown bytes, _printf_llu.o(.ARM.Collect$$_printf_percent$$0000000F)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_llu ⇒ _printf_llo ⇒ _printf_llx ⇒ _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_llo +
    • >>   _printf_longlong_dec +
    +
    [Called By]
    • >>   _printf_lld +
    + +

    _printf_llo (Thumb, 0 bytes, Stack size unknown bytes, _printf_llo.o(.ARM.Collect$$_printf_percent$$00000010)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_llo ⇒ _printf_llx ⇒ _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_llx +
    • >>   _printf_ll_oct +
    +
    [Called By]
    • >>   _printf_llu +
    + +

    _printf_llx (Thumb, 0 bytes, Stack size unknown bytes, _printf_llx.o(.ARM.Collect$$_printf_percent$$00000011)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_llx ⇒ _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_l +
    • >>   _printf_ll_hex +
    +
    [Called By]
    • >>   _printf_llo +
    + +

    _printf_l (Thumb, 0 bytes, Stack size unknown bytes, _printf_l.o(.ARM.Collect$$_printf_percent$$00000012)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_l ⇒ _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_c +
    +
    [Called By]
    • >>   _printf_llx +
    + +

    _printf_c (Thumb, 0 bytes, Stack size unknown bytes, _printf_c.o(.ARM.Collect$$_printf_percent$$00000013)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_c ⇒ _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_char +
    • >>   _printf_s +
    +
    [Called By]
    • >>   _printf_l +
    + +

    _printf_s (Thumb, 0 bytes, Stack size unknown bytes, _printf_s.o(.ARM.Collect$$_printf_percent$$00000014)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_s ⇒ _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_string +
    • >>   _printf_lc +
    +
    [Called By]
    • >>   _printf_c +
    + +

    _printf_lc (Thumb, 0 bytes, Stack size unknown bytes, _printf_lc.o(.ARM.Collect$$_printf_percent$$00000015)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_lc ⇒ _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_wchar +
    • >>   _printf_ls +
    +
    [Called By]
    • >>   _printf_s +
    + +

    _printf_ls (Thumb, 0 bytes, Stack size unknown bytes, _printf_ls.o(.ARM.Collect$$_printf_percent$$00000016)) +

    [Stack]

    • Max Depth = 88 + Unknown Stack Size +
    • Call Chain = _printf_ls ⇒ _printf_wstring ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_percent_end +
    • >>   _printf_wstring +
    +
    [Called By]
    • >>   _printf_lc +
    + +

    _printf_percent_end (Thumb, 0 bytes, Stack size unknown bytes, _printf_percent_end.o(.ARM.Collect$$_printf_percent$$00000017)) +

    [Called By]

    • >>   _printf_ls +
    + +

    __rt_lib_init (Thumb, 0 bytes, Stack size unknown bytes, libinit.o(.ARM.Collect$$libinit$$00000000)) +

    [Called By]

    • >>   __rt_entry_li +
    + +

    __rt_lib_init_fp_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000002)) + +

    __rt_lib_init_heap_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000000A)) + +

    __rt_lib_init_preinit_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000004)) + +

    __rt_lib_init_rand_2 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000000D)) +

    [Stack]

    • Max Depth = 12 + Unknown Stack Size +
    • Call Chain = __rt_lib_init_rand_2 ⇒ _rand_init ⇒ srand +
    +
    [Calls]
    • >>   _rand_init +
    + +

    __rt_lib_init_user_alloc_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000000C)) + +

    __rt_lib_init_lc_common (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000000F)) +

    [Calls]

    • >>   __rt_locale +
    + +

    __rt_lib_init_rand_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000000E)) + +

    __rt_lib_init_lc_collate_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000011)) + +

    __rt_lib_init_lc_ctype_2 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000012)) +

    [Stack]

    • Max Depth = 24 + Unknown Stack Size +
    • Call Chain = __rt_lib_init_lc_ctype_2 ⇒ _get_lc_ctype ⇒ strcmp +
    +
    [Calls]
    • >>   _get_lc_ctype +
    + +

    __rt_lib_init_lc_ctype_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000013)) + +

    __rt_lib_init_lc_monetary_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000015)) + +

    __rt_lib_init_lc_numeric_2 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000016)) +

    [Stack]

    • Max Depth = 24 + Unknown Stack Size +
    • Call Chain = __rt_lib_init_lc_numeric_2 ⇒ _get_lc_numeric ⇒ strcmp +
    +
    [Calls]
    • >>   _get_lc_numeric +
    + +

    __rt_lib_init_alloca_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000002E)) + +

    __rt_lib_init_argv_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000002C)) + +

    __rt_lib_init_atexit_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000001B)) + +

    __rt_lib_init_clock_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000021)) + +

    __rt_lib_init_cpp_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000032)) + +

    __rt_lib_init_exceptions_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000030)) + +

    __rt_lib_init_fp_trap_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000001F)) + +

    __rt_lib_init_getenv_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000023)) + +

    __rt_lib_init_lc_numeric_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000017)) + +

    __rt_lib_init_lc_time_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000019)) + +

    __rt_lib_init_return (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000033)) + +

    __rt_lib_init_signal_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$0000001D)) + +

    __rt_lib_init_stdio_1 (Thumb, 0 bytes, Stack size unknown bytes, libinit2.o(.ARM.Collect$$libinit$$00000025)) + +

    __rt_entry (Thumb, 0 bytes, Stack size unknown bytes, __rtentry.o(.ARM.Collect$$rtentry$$00000000)) +

    [Called By]

    • >>   __main +
    + +

    __rt_entry_presh_1 (Thumb, 0 bytes, Stack size unknown bytes, __rtentry2.o(.ARM.Collect$$rtentry$$00000002)) + +

    __rt_entry_sh (Thumb, 0 bytes, Stack size unknown bytes, __rtentry5.o(.ARM.Collect$$rtentry$$00000005)) + +

    __rt_entry_li (Thumb, 0 bytes, Stack size unknown bytes, __rtentry2.o(.ARM.Collect$$rtentry$$0000000A)) +

    [Calls]

    • >>   __rt_lib_init +
    + +

    __rt_entry_postsh_1 (Thumb, 0 bytes, Stack size unknown bytes, __rtentry2.o(.ARM.Collect$$rtentry$$00000009)) + +

    __rt_entry_main (Thumb, 0 bytes, Stack size unknown bytes, __rtentry2.o(.ARM.Collect$$rtentry$$0000000D)) +

    [Stack]

    • Max Depth = 120 + Unknown Stack Size +
    • Call Chain = __rt_entry_main ⇒ main ⇒ fmna_sound_platform_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   exit +
    • >>   main +
    + +

    __rt_entry_postli_1 (Thumb, 0 bytes, Stack size unknown bytes, __rtentry2.o(.ARM.Collect$$rtentry$$0000000C)) + +

    ram_init (Thumb, 32 bytes, Stack size 8 bytes, system_rtl876x.o(.app.flash.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    + +

    ram_cache_init (Thumb, 32 bytes, Stack size 8 bytes, system_rtl876x.o(.app.flash.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    + +

    get_image_entry_addr (Thumb, 76 bytes, Stack size 16 bytes, system_rtl876x.o(.app.flash.text), UNUSED) +

    [Calls]

    • >>   get_header_addr_by_img_id +
    • >>   check_header_valid +
    • >>   get_active_ota_bank_addr +
    + +

    set_os_clock (Thumb, 40 bytes, Stack size 0 bytes, system_rtl876x.o(.app.flash.text), UNUSED) + +

    wdg_system_reset_app_cb (Thumb, 12 bytes, Stack size 0 bytes, system_rtl876x.o(.app.flash.text)) +
    [Address Reference Count : 1]

    • system_rtl876x.o(.app.flash.text) +
    +

    print_reset_reason (Thumb, 272 bytes, Stack size 40 bytes, system_rtl876x.o(.app.flash.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = print_reset_reason +
    +
    [Calls]
    • >>   btaon_fast_read_safe +
    • >>   reset_reason_get +
    • >>   WDG_Disable +
    • >>   WDG_Enable +
    • >>   WDG_Config +
    • >>   WDG_ClockEnable +
    • >>   log_buffer +
    +
    [Called By]
    • >>   pre_main +
    + +

    pre_main (Thumb, 102 bytes, Stack size 16 bytes, system_rtl876x.o(.app.flash.text)) +

    [Stack]

    • Max Depth = 280
    • Call Chain = pre_main ⇒ AppUpdateVectorTable +
    +
    [Calls]
    • >>   load_overlay +
    • >>   AppUpdateVectorTable +
    • >>   print_reset_reason +
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   setlocale +
    • >>   trace_string +
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • system_rtl876x.o(.app.flash.text) +
    +

    SystemInit (Thumb, 328 bytes, Stack size 16 bytes, system_rtl876x.o(.app.flash.text)) +

    [Stack]

    • Max Depth = 296 + Unknown Stack Size +
    • Call Chain = SystemInit ⇒ log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   bt_stack_config_init +
    • >>   log_direct_app +
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   Pinmux_Deinit_rom +
    • >>   get_header_addr_by_img_id +
    • >>   check_header_valid +
    • >>   check_hci_mode_flag +
    • >>   get_active_ota_bank_addr +
    • >>   update_ram_layout +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(RESET) +
    +

    bt_stack_config_init (Thumb, 16 bytes, Stack size 8 bytes, main.o(.app.flash.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = bt_stack_config_init +
    +
    [Calls]
    • >>   gap_config_max_le_paired_device +
    • >>   gap_config_local_addr_storage +
    +
    [Called By]
    • >>   SystemInit +
    + +

    gap_config_le_link_number (Thumb, 30 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_bt_bd_addr (Thumb, 28 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_cccd_not_check (Thumb, 20 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_le_min_rem_sca (Thumb, 34 bytes, Stack size 8 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_bte_pool_size (Thumb, 20 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_bt_report_buf_num (Thumb, 6 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_ccc_bits_count (Thumb, 14 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_max_attribute_table_count (Thumb, 8 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_max_mtu_size (Thumb, 8 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_le_key_storage_flag (Thumb, 8 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text)) +

    [Called By]

    • >>   fmna_ble_platform_init +
    + +

    gap_config_max_le_paired_device (Thumb, 8 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text)) +

    [Called By]

    • >>   bt_stack_config_init +
    + +

    gap_config_pa_parameter (Thumb, 12 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_local_addr_storage (Thumb, 28 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text)) +

    [Called By]

    • >>   bt_stack_config_init +
    + +

    gap_config_bqb_en (Thumb, 20 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    gap_config_l2c_param (Thumb, 18 bytes, Stack size 0 bytes, gap_config.o(.app.flash.text), UNUSED) + +

    rand (Thumb, 52 bytes, Stack size 0 bytes, rand.o(.emb_text)) +

    [Called By]

    • >>   cust_adv_update_device_name +
    • >>   update_single_id +
    • >>   generate_random_id +
    • >>   one_shot_adv_set_param +
    • >>   gap_sched_adv_random_delay +
    • >>   mbedtls_platform_frng +
    + +

    ADC_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    BTMAC_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    BusFault_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    CAP_Touch_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Default_Handler (Thumb, 14 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • system_rtl876x.o(.app.overlay_a) +
    +

    Enhanced_Timer0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Enhanced_Timer1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GDMA0_Channel0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GDMA0_Channel1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GDMA0_Channel2_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GDMA0_Channel3_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GPIO0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO10_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO11_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO12_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO13_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group1_Handler +
    + +

    GPIO14_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO15_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO16_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO17_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group1_Handler +
    + +

    GPIO18_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO19_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group1_Handler +
    + +

    GPIO20_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO21_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group1_Handler +
    + +

    GPIO22_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO23_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO24_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO25_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group1_Handler +
    + +

    GPIO26_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO27_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO28_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    GPIO2_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO30_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO31_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO3_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO4_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GPIO5_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    GPIO6_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group2_Handler +
    + +

    GPIO7_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group3_Handler +
    + +

    GPIO8_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +

    [Called By]

    • >>   GPIO_Group0_Handler +
    + +

    HardFault_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    I2C0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    I2C1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    I2S0_RX_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    I2S0_TX_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    IR_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Keyscan_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    LPCOMP_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    MemManage_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    NMI_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    PTA_Mailbox_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    PendSV_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Peripheral_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Qdecode_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    RTC_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SPI0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SPI1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SPI2W_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SPI_Flash_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SVC_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    SysTick_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    TRNG_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Timer2_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Timer4_5_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    Timer5_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    UART0_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    UART1_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    UsageFault_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    WDG_Handler (Thumb, 0 bytes, Stack size 0 bytes, startup_rtl876x.o(.text)) +
    [Address Reference Count : 1]

    • startup_rtl876x.o(VECTOR) +
    +

    __user_setup_stackheap (Thumb, 2 bytes, Stack size 0 bytes, startup_rtl876x.o(.text), UNUSED) + +

    random_seed_init (Thumb, 16 bytes, Stack size 8 bytes, system_rtl876x.o(.text), UNUSED) +

    [Calls]

    • >>   platform_random +
    + +

    show_sdk_lib_version (Thumb, 2 bytes, Stack size 0 bytes, system_rtl876x.o(.text)) +

    [Called By]

    • >>   common_main +
    + +

    log_direct_app (Thumb, 150 bytes, Stack size 160 bytes, system_rtl876x.o(.text)) +

    [Stack]

    • Max Depth = 280 + Unknown Stack Size +
    • Call Chain = log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   os_unlock +
    • >>   os_lock +
    • >>   log_timestamp_get +
    • >>   LogUartTxChar +
    • >>   vsnprintf +
    +
    [Called By]
    • >>   common_main +
    • >>   SystemInit +
    • >>   app_handle_gpio_msg +
    • >>   fmna_factory_reset +
    + +

    common_main (Thumb, 94 bytes, Stack size 8 bytes, system_rtl876x.o(.text)) +

    [Stack]

    • Max Depth = 288 + Unknown Stack Size +
    • Call Chain = common_main ⇒ log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   show_sdk_lib_version +
    • >>   log_direct_app +
    • >>   os_sched_start +
    • >>   WDG_Disable +
    • >>   platform_random +
    • >>   flash_get_bank_size +
    • >>   flash_get_bank_addr +
    • >>   ftl_init +
    • >>   __main +
    • >>   __aeabi_uidivmod +
    +
    [Address Reference Count : 1]
    • system_rtl876x.o(.app.flash.text) +
    +

    __2printf (Thumb, 4 bytes, Stack size 0 bytes, system_rtl876x.o(.text), UNUSED) + +

    malloc (Thumb, 16 bytes, Stack size 8 bytes, system_rtl876x.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = malloc +
    +
    [Calls]
    • >>   os_mem_alloc_intern +
    +
    [Called By]
    • >>   mbedtls_platform_frng +
    + +

    calloc (Thumb, 16 bytes, Stack size 8 bytes, system_rtl876x.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_zalloc_intern +
    + +

    realloc (Thumb, 128 bytes, Stack size 16 bytes, system_rtl876x.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   os_sched_resume +
    • >>   os_sched_suspend +
    • >>   os_mem_free +
    • >>   os_mem_alloc_intern +
    + +

    free (Thumb, 8 bytes, Stack size 8 bytes, system_rtl876x.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = free +
    +
    [Calls]
    • >>   os_mem_free +
    +
    [Called By]
    • >>   mbedtls_platform_frng +
    + +

    get_cpu_clock (Thumb, 6 bytes, Stack size 0 bytes, system_rtl876x.o(.text), UNUSED) + +

    get_ic_type (Thumb, 6 bytes, Stack size 0 bytes, system_rtl876x.o(.text), UNUSED) + +

    set_active_timer_callback (Thumb, 26 bytes, Stack size 8 bytes, system_rtl876x.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = set_active_timer_callback +
    +
    [Calls]
    • >>   os_timer_delete +
    • >>   os_timer_stop +
    • >>   power_manager_resume_all +
    +
    [Address Reference Count : 1]
    • system_rtl876x.o(.text) +
    +

    set_boot_active_time (Thumb, 62 bytes, Stack size 24 bytes, system_rtl876x.o(.text), UNUSED) +

    [Calls]

    • >>   os_timer_restart +
    • >>   os_timer_start +
    • >>   os_timer_create +
    • >>   power_manager_suspend_all +
    + +

    DLPS_IORegister (Thumb, 20 bytes, Stack size 8 bytes, rtl876x_io_dlps.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = DLPS_IORegister +
    +
    [Calls]
    • >>   platform_pm_register_callback_func +
    +
    [Called By]
    • >>   main +
    • >>   pwr_mgr_init +
    + +

    GPIO_DeInit (Thumb, 16 bytes, Stack size 8 bytes, rtl876x_gpio.o(.text), UNUSED) +

    [Calls]

    • >>   RCC_PeriphClockCmd +
    + +

    GPIO_Init (Thumb, 200 bytes, Stack size 4 bytes, rtl876x_gpio.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = GPIO_Init +
    +
    [Called By]
    • >>   gpio_driver_init +
    + +

    GPIO_StructInit (Thumb, 26 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text)) +

    [Called By]

    • >>   gpio_driver_init +
    + +

    GPIO_INTConfig (Thumb, 18 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text)) +

    [Called By]

    • >>   gpio_driver_init +
    + +

    GPIO_ClearINTPendingBit (Thumb, 6 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text)) +

    [Called By]

    • >>   gpio_driver_init +
    • >>   GPIO29_Handler +
    • >>   GPIO9_Handler +
    + +

    GPIO_MaskINTConfig (Thumb, 18 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text)) +

    [Called By]

    • >>   gpio_driver_init +
    • >>   GPIO29_Handler +
    • >>   GPIO9_Handler +
    + +

    GPIO_GetPin (Thumb, 58 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text)) +

    [Called By]

    • >>   gpio_driver_init +
    • >>   GPIO29_Handler +
    • >>   GPIO9_Handler +
    • >>   gpio_key_debounce_timeout_cb +
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    + +

    GPIO_GetNum (Thumb, 42 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text), UNUSED) + +

    GPIO_DBClkCmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_gpio.o(.text), UNUSED) + +

    RCC_PeriphClockCmd (Thumb, 262 bytes, Stack size 16 bytes, rtl876x_rcc.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = RCC_PeriphClockCmd +
    +
    [Called By]
    • >>   GPIO_DeInit +
    • >>   hw_timer_driver_init +
    • >>   gpio_driver_init +
    • >>   fmna_sound_platform_init +
    • >>   bat_init_driver +
    • >>   I2C_DeInit +
    • >>   ADC_DeInit +
    • >>   TIM_DeInit +
    • >>   fmna_motion_detection_platform_init +
    + +

    RCC_PeriFunctionConfig (Thumb, 88 bytes, Stack size 4 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    RCC_PeriClockConfig (Thumb, 104 bytes, Stack size 8 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    RCC_I2CClkDivConfig (Thumb, 92 bytes, Stack size 8 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    RCC_SPIClkDivConfig (Thumb, 92 bytes, Stack size 8 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    RCC_TIMClkDivConfig (Thumb, 48 bytes, Stack size 12 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    RCC_UARTClkDivConfig (Thumb, 92 bytes, Stack size 8 bytes, rtl876x_rcc.o(.text), UNUSED) + +

    TIM_DeInit (Thumb, 16 bytes, Stack size 8 bytes, rtl876x_tim.o(.text), UNUSED) +

    [Calls]

    • >>   RCC_PeriphClockCmd +
    + +

    TIM_TimeBaseInit (Thumb, 234 bytes, Stack size 16 bytes, rtl876x_tim.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = TIM_TimeBaseInit +
    +
    [Calls]
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   hw_timer_driver_init +
    • >>   fmna_sound_platform_init +
    + +

    TIM_StructInit (Thumb, 26 bytes, Stack size 0 bytes, rtl876x_tim.o(.text)) +

    [Called By]

    • >>   hw_timer_driver_init +
    • >>   fmna_sound_platform_init +
    + +

    TIM_Cmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_tim.o(.text)) +

    [Called By]

    • >>   crypto_exit_dlps_config +
    • >>   Timer3_Handler +
    • >>   buzzer_init +
    • >>   Timer4_Handler +
    + +

    TIM_CmdSafe (Thumb, 64 bytes, Stack size 16 bytes, rtl876x_tim.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_uidivmod +
    + +

    TIM_ChangePeriod (Thumb, 4 bytes, Stack size 0 bytes, rtl876x_tim.o(.text), UNUSED) + +

    TIM_INTConfig (Thumb, 18 bytes, Stack size 0 bytes, rtl876x_tim.o(.text)) +

    [Called By]

    • >>   hw_timer_driver_init +
    + +

    TIM_PWMChangeFreqAndDuty (Thumb, 30 bytes, Stack size 16 bytes, rtl876x_tim.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = TIM_PWMChangeFreqAndDuty +
    +
    [Calls]
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   buzzer_init +
    + +

    TIM_PWMComplOutputEMCmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_tim.o(.text), UNUSED) + +

    TIM_PWMDZBypassCmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_tim.o(.text), UNUSED) + +

    TIM_PWMChangeDZClockSrc (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_tim.o(.text), UNUSED) + +

    Pinmux_Reset (Thumb, 22 bytes, Stack size 0 bytes, rtl876x_pinmux.o(.text), UNUSED) + +

    Pinmux_Deinit (Thumb, 24 bytes, Stack size 0 bytes, rtl876x_pinmux.o(.text), UNUSED) + +

    Pinmux_Config (Thumb, 32 bytes, Stack size 4 bytes, rtl876x_pinmux.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = Pinmux_Config +
    +
    [Called By]
    • >>   gpio_board_init +
    • >>   board_i2c_master_init +
    • >>   fmna_motion_detection_platform_init +
    • >>   buzzer_init +
    + +

    Pad_Config (Thumb, 100 bytes, Stack size 40 bytes, rtl876x_pinmux.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = Pad_Config +
    +
    [Calls]
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   DLPS_IO_ExitDlpsCb +
    • >>   DLPS_IO_EnterDlpsCb +
    • >>   gpio_key_exit_dlps_config +
    • >>   gpio_key_enter_dlps_config +
    • >>   gpio_board_init +
    • >>   fmna_sound_platform_init +
    • >>   board_i2c_master_init +
    • >>   board_i2c_master_deinit +
    • >>   fmna_motion_detection_platform_init +
    • >>   fmna_motion_detection_platform_deinit +
    • >>   buzzer_init +
    + +

    Pad_WakeupEnableValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_WKDebounceConfig (Thumb, 40 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_WakeupPolarityValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_DebounceWakeupStatus (Thumb, 32 bytes, Stack size 8 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    System_DebounceWakeupStatus (Thumb, 32 bytes, Stack size 8 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    System_WakeUpPinDisable (Thumb, 28 bytes, Stack size 8 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    System_WakeUpPinEnable (Thumb, 178 bytes, Stack size 40 bytes, rtl876x_pinmux.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = System_WakeUpPinEnable +
    +
    [Calls]
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   gpio_key_enter_dlps_config +
    + +

    Pad_WakeupInterruptValue (Thumb, 36 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_read_safe +
    + +

    System_WakeUpInterruptValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = System_WakeUpInterruptValue +
    +
    [Calls]
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   System_Handler +
    + +

    Pad_OutputControlValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_OutputEnableValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_PullEnableValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_PullUpOrDownValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_PullConfigValue (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_PowerOrShutDownValue (Thumb, 40 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_ControlSelectValue (Thumb, 40 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Pad_ClearWakeupINTPendingBit (Thumb, 38 bytes, Stack size 16 bytes, rtl876x_pinmux.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = Pad_ClearWakeupINTPendingBit +
    +
    [Calls]
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   System_Handler +
    + +

    Pad_ClearAllWakeupINT (Thumb, 94 bytes, Stack size 8 bytes, rtl876x_pinmux.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    Spic0_control (Thumb, 22 bytes, Stack size 0 bytes, rtl876x_pinmux.o(.text), UNUSED) + +

    Spic1_control (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_pinmux.o(.text), UNUSED) + +

    NVIC_Init (Thumb, 182 bytes, Stack size 12 bytes, rtl876x_nvic.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = NVIC_Init +
    +
    [Called By]
    • >>   DLPS_IO_ExitDlpsCb +
    • >>   hw_timer_driver_init +
    • >>   gpio_driver_init +
    + +

    ADC_DeInit (Thumb, 16 bytes, Stack size 8 bytes, rtl876x_adc.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = ADC_DeInit ⇒ RCC_PeriphClockCmd +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    +
    [Called By]
    • >>   bat_init_driver +
    + +

    ADC_Init (Thumb, 276 bytes, Stack size 16 bytes, rtl876x_adc.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = ADC_Init +
    +
    [Calls]
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   bat_init_driver +
    + +

    ADC_StructInit (Thumb, 82 bytes, Stack size 0 bytes, rtl876x_adc.o(.text)) +

    [Called By]

    • >>   bat_init_driver +
    + +

    ADC_Cmd (Thumb, 144 bytes, Stack size 16 bytes, rtl876x_adc.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = ADC_Cmd +
    +
    [Calls]
    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    +
    [Called By]
    • >>   bat_update_battery_info +
    + +

    ADC_INTConfig (Thumb, 16 bytes, Stack size 0 bytes, rtl876x_adc.o(.text)) +

    [Called By]

    • >>   bat_update_battery_info +
    + +

    ADC_ReadRawData (Thumb, 22 bytes, Stack size 0 bytes, rtl876x_adc.o(.text)) +

    [Called By]

    • >>   bat_update_battery_info +
    + +

    ADC_ReadAvgRawData (Thumb, 6 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_ReadFIFO (Thumb, 8 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_ReadFIFOData (Thumb, 26 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_GetFIFODataLen (Thumb, 8 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_SchIndexConfig (Thumb, 28 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_SchTableConfig (Thumb, 28 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_BitMapConfig (Thumb, 16 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_ManualPowerOnCmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_WriteFIFOCmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_adc.o(.text), UNUSED) + +

    ADC_BypassCmd (Thumb, 54 bytes, Stack size 16 bytes, rtl876x_adc.o(.text), UNUSED) +

    [Calls]

    • >>   btaon_fast_write_safe +
    • >>   btaon_fast_read_safe +
    + +

    ADC_GetINTStatus (Thumb, 16 bytes, Stack size 0 bytes, rtl876x_adc.o(.text)) +

    [Called By]

    • >>   bat_update_battery_info +
    + +

    ADC_ClearINTPendingBit (Thumb, 10 bytes, Stack size 0 bytes, rtl876x_adc.o(.text)) +

    [Called By]

    • >>   bat_update_battery_info +
    + +

    I2C_Init (Thumb, 392 bytes, Stack size 24 bytes, rtl876x_i2c.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = I2C_Init +
    +
    [Calls]
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   fmna_motion_detection_platform_init +
    + +

    I2C_DeInit (Thumb, 34 bytes, Stack size 8 bytes, rtl876x_i2c.o(.text), UNUSED) +

    [Calls]

    • >>   RCC_PeriphClockCmd +
    + +

    I2C_StructInit (Thumb, 38 bytes, Stack size 0 bytes, rtl876x_i2c.o(.text)) +

    [Called By]

    • >>   fmna_motion_detection_platform_init +
    + +

    I2C_Cmd (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_i2c.o(.text)) +

    [Called By]

    • >>   fmna_motion_detection_platform_init +
    • >>   fmna_motion_detection_platform_deinit +
    + +

    I2C_CheckAbortStatus (Thumb, 64 bytes, Stack size 0 bytes, rtl876x_i2c.o(.text)) +

    [Called By]

    • >>   I2C_RepeatRead +
    • >>   I2C_MasterRead +
    • >>   I2C_MasterWrite +
    + +

    I2C_MasterWrite (Thumb, 96 bytes, Stack size 20 bytes, rtl876x_i2c.o(.text)) +

    [Stack]

    • Max Depth = 20
    • Call Chain = I2C_MasterWrite +
    +
    [Calls]
    • >>   I2C_CheckAbortStatus +
    +
    [Called By]
    • >>   da213b_write_one_byte +
    + +

    I2C_MasterRead (Thumb, 144 bytes, Stack size 28 bytes, rtl876x_i2c.o(.text), UNUSED) +

    [Calls]

    • >>   I2C_CheckAbortStatus +
    + +

    I2C_RepeatRead (Thumb, 210 bytes, Stack size 28 bytes, rtl876x_i2c.o(.text)) +

    [Stack]

    • Max Depth = 28
    • Call Chain = I2C_RepeatRead +
    +
    [Calls]
    • >>   I2C_CheckAbortStatus +
    +
    [Called By]
    • >>   da213b_read_one_byte +
    + +

    I2C_INTConfig (Thumb, 20 bytes, Stack size 0 bytes, rtl876x_i2c.o(.text), UNUSED) + +

    I2C_ClearINTPendingBit (Thumb, 166 bytes, Stack size 0 bytes, rtl876x_i2c.o(.text), UNUSED) + +

    AON_WDG_Config (Thumb, 94 bytes, Stack size 32 bytes, rtl876x_aon_wdg.o(.text)) +

    [Stack]

    • Max Depth = 44
    • Call Chain = AON_WDG_Config ⇒ AON_WDG_WriteReg +
    +
    [Calls]
    • >>   AON_WDG_WriteReg +
    +
    [Called By]
    • >>   AON_WDG_SystemReset +
    • >>   app_main_task +
    + +

    AON_WDG_ConfigResetLevel (Thumb, 64 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_ConfigComp (Thumb, 64 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_ConfigCntCtl (Thumb, 64 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_ConfigCntReload (Thumb, 64 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_Enable (Thumb, 60 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text)) +

    [Stack]

    • Max Depth = 36
    • Call Chain = AON_WDG_Enable ⇒ AON_WDG_WriteReg +
    +
    [Calls]
    • >>   AON_WDG_WriteReg +
    +
    [Called By]
    • >>   app_main_task +
    + +

    AON_WDG_Disable (Thumb, 60 bytes, Stack size 24 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_Restart (Thumb, 22 bytes, Stack size 8 bytes, rtl876x_aon_wdg.o(.text)) +

    [Stack]

    • Max Depth = 20
    • Call Chain = AON_WDG_Restart ⇒ AON_WDG_WriteReg +
    +
    [Calls]
    • >>   AON_WDG_WriteReg +
    +
    [Called By]
    • >>   app_handle_io_msg +
    • >>   app_main_task +
    + +

    AON_WDG_SystemReset (Thumb, 68 bytes, Stack size 16 bytes, rtl876x_aon_wdg.o(.text), UNUSED) +

    [Calls]

    • >>   AON_WDG_Config +
    • >>   AON_WDG_WriteReg +
    + +

    AON_WDG_IsEnable (Thumb, 16 bytes, Stack size 0 bytes, rtl876x_aon_wdg.o(.text), UNUSED) + +

    fns_write_post_callback (Thumb, 26 bytes, Stack size 16 bytes, findmy_network_service.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fns_write_post_callback +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • findmy_network_service.o(.text) +
    +

    fns_attr_write_cb (Thumb, 90 bytes, Stack size 48 bytes, findmy_network_service.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fns_attr_write_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • findmy_network_service.o(.constdata) +
    +

    fns_cccd_update_cb (Thumb, 18 bytes, Stack size 8 bytes, findmy_network_service.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fns_cccd_update_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • findmy_network_service.o(.constdata) +
    +

    findmy_network_add_service (Thumb, 64 bytes, Stack size 24 bytes, findmy_network_service.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = findmy_network_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    ais_attr_read_cb (Thumb, 176 bytes, Stack size 24 bytes, accessory_info_service.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = ais_attr_read_cb ⇒ fmna_version_get_fw_version +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_version_get_fw_version +
    • >>   fmna_battery_platform_get_battery_level +
    +
    [Address Reference Count : 1]
    • accessory_info_service.o(.constdata) +
    +

    accessory_info_add_service (Thumb, 60 bytes, Stack size 16 bytes, accessory_info_service.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = accessory_info_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    tps_set_parameter (Thumb, 90 bytes, Stack size 8 bytes, tps.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = tps_set_parameter +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    +
    [Called By]
    • >>   app_gap_callback +
    + +

    tps_attr_read_cb (Thumb, 238 bytes, Stack size 48 bytes, tps.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = tps_attr_read_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • tps.o(.constdata) +
    +

    tps_add_service (Thumb, 66 bytes, Stack size 24 bytes, tps.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = tps_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    ias_attr_write_cb (Thumb, 88 bytes, Stack size 24 bytes, ias.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = ias_attr_write_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • ias.o(.constdata) +
    +

    ias_add_service (Thumb, 66 bytes, Stack size 24 bytes, ias.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = ias_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    sdd_set_parameter (Thumb, 34 bytes, Stack size 8 bytes, sdd_service.o(.text), UNUSED) +

    [Calls]

    • >>   log_buffer +
    + +

    sdd_battery_level_value_notify (Thumb, 24 bytes, Stack size 24 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = sdd_battery_level_value_notify ⇒ server_send_data +
    +
    [Calls]
    • >>   server_send_data +
    +
    [Called By]
    • >>   app_gap_callback +
    • >>   double_click_detect_timer_cb +
    • >>   handle_ten_click +
    • >>   app_profile_callback +
    + +

    sdd_send_array_value (Thumb, 22 bytes, Stack size 16 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = sdd_send_array_value ⇒ server_send_data +
    +
    [Calls]
    • >>   server_send_data +
    +
    [Called By]
    • >>   double_click_detect_timer_cb +
    + +

    sdd_battery_level_value_read_confirm (Thumb, 40 bytes, Stack size 24 bytes, sdd_service.o(.text), UNUSED) +

    [Calls]

    • >>   server_attr_read_confirm +
    + +

    sdd_attr_read_cb (Thumb, 88 bytes, Stack size 48 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = sdd_attr_read_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • sdd_service.o(.constdata) +
    +

    sdd_cccd_update_cb (Thumb, 78 bytes, Stack size 56 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = sdd_cccd_update_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • sdd_service.o(.constdata) +
    +

    sdd_attr_write_cb (Thumb, 126 bytes, Stack size 56 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = sdd_attr_write_cb +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • sdd_service.o(.constdata) +
    +

    sdd_add_service (Thumb, 66 bytes, Stack size 24 bytes, sdd_service.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = sdd_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    dis_set_parameter (Thumb, 200 bytes, Stack size 16 bytes, dis.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    + +

    dis_attr_read_cb (Thumb, 330 bytes, Stack size 32 bytes, dis.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = dis_attr_read_cb +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Address Reference Count : 1]
    • dis.o(.constdata) +
    +

    dis_add_service (Thumb, 68 bytes, Stack size 24 bytes, dis.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = dis_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_add_service +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    board_init (Thumb, 12 bytes, Stack size 8 bytes, main.o(.text), UNUSED) +

    [Calls]

    • >>   gpio_board_init +
    • >>   board_i2c_master_init +
    + +

    driver_init (Thumb, 16 bytes, Stack size 8 bytes, main.o(.text)) +

    [Stack]

    • Max Depth = 152
    • Call Chain = driver_init ⇒ bat_init_driver ⇒ ADC_DeInit ⇒ RCC_PeriphClockCmd +
    +
    [Calls]
    • >>   hw_timer_driver_init +
    • >>   gpio_driver_init +
    • >>   bat_init_driver +
    +
    [Called By]
    • >>   app_main_task +
    + +

    io_dlps_enter_cb (Thumb, 16 bytes, Stack size 8 bytes, main.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = io_dlps_enter_cb ⇒ gpio_key_enter_dlps_config ⇒ Pad_Config +
    +
    [Calls]
    • >>   gpio_key_enter_dlps_config +
    • >>   board_i2c_master_deinit +
    • >>   bat_enter_dlps_config +
    +
    [Address Reference Count : 1]
    • main.o(.text) +
    +

    io_dlps_exit_cb (Thumb, 20 bytes, Stack size 8 bytes, main.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = io_dlps_exit_cb ⇒ gpio_key_exit_dlps_config ⇒ Pad_Config +
    +
    [Calls]
    • >>   gpio_key_exit_dlps_config +
    • >>   crypto_exit_dlps_config +
    • >>   board_i2c_master_init +
    • >>   bat_exit_dlps_config +
    +
    [Address Reference Count : 1]
    • main.o(.text) +
    +

    app_dlps_check_cb (Thumb, 10 bytes, Stack size 0 bytes, main.o(.text)) +
    [Address Reference Count : 1]

    • main.o(.text) +
    +

    pwr_mgr_init (Thumb, 42 bytes, Stack size 8 bytes, main.o(.text), UNUSED) +

    [Calls]

    • >>   DLPS_IORegister +
    • >>   btmac_pm_set_power_mode +
    • >>   platform_pm_register_callback_func +
    • >>   platform_pm_set_power_mode +
    + +

    task_init (Thumb, 12 bytes, Stack size 8 bytes, main.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_task_init +
    • >>   app_task_init +
    + +

    main (Thumb, 166 bytes, Stack size 8 bytes, main.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = main ⇒ fmna_sound_platform_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   DLPS_IORegister +
    • >>   btmac_pm_set_power_mode +
    • >>   os_sched_start +
    • >>   reset_reason_get +
    • >>   platform_pm_register_callback_func +
    • >>   platform_pm_set_power_mode +
    • >>   flash_try_high_speed +
    • >>   log_buffer +
    • >>   sw_timer_init +
    • >>   one_shot_adv_init +
    • >>   gpio_board_init +
    • >>   fmna_version_init +
    • >>   fmna_task_init +
    • >>   fmna_sound_platform_init +
    • >>   fmna_motion_detection_init +
    • >>   fmna_gatt_platform_init +
    • >>   fmna_connection_pair_info_restore +
    • >>   fmna_connection_init +
    • >>   fmna_ble_platform_init +
    • >>   custom_new_adv_init +
    • >>   board_i2c_master_init +
    • >>   bat_init_data +
    • >>   app_task_init +
    • >>   app_global_data_init +
    • >>   app_bond_info_restore +
    • >>   srand +
    +
    [Called By]
    • >>   __rt_entry_main +
    + +

    System_Handler (Thumb, 68 bytes, Stack size 8 bytes, main.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = System_Handler ⇒ Pad_ClearWakeupINTPendingBit +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   Pad_ClearWakeupINTPendingBit +
    • >>   System_WakeUpInterruptValue +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    app_main_task (Thumb, 156 bytes, Stack size 16 bytes, app_task.o(.text)) +

    [Stack]

    • Max Depth = 1944 + Unknown Stack Size +
    • Call Chain = app_main_task ⇒ app_handle_io_msg ⇒ app_handle_gpio_msg ⇒ serial_number_read_state_init ⇒ fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_msg_recv_intern +
    • >>   os_msg_queue_create_intern +
    • >>   driver_init +
    • >>   AON_WDG_Restart +
    • >>   AON_WDG_Enable +
    • >>   AON_WDG_Config +
    • >>   gap_start_bt_stack +
    • >>   gap_handle_msg +
    • >>   app_handle_io_msg +
    +
    [Address Reference Count : 1]
    • app_task.o(.text) +
    +

    app_task_init (Thumb, 30 bytes, Stack size 16 bytes, app_task.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = app_task_init +
    +
    [Calls]
    • >>   os_task_create +
    +
    [Called By]
    • >>   main +
    • >>   task_init +
    + +

    app_send_msg_to_apptask (Thumb, 92 bytes, Stack size 24 bytes, app_task.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = app_send_msg_to_apptask +
    +
    [Calls]
    • >>   os_msg_send_intern +
    • >>   log_buffer +
    +
    [Called By]
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    • >>   Timer3_Handler +
    • >>   motion_poll_timer_timeout_handler +
    • >>   motion_backoff_timeout_handler +
    • >>   fmna_key_rotation_handler +
    • >>   fmna_one_time_key_rotation_handler +
    • >>   fmna_non_owner_0_connection_timeout_handler +
    • >>   fmna_non_owner_1_connection_timeout_handler +
    • >>   fmna_pair_connection_timeout_handler +
    • >>   separated_ut_timeout_handler +
    • >>   fmna_persistent_connection_disconnection_timeout_handler +
    • >>   adv_timer_callback +
    • >>   aon_watch_dog_wake_up_dlps_callback +
    • >>   custom_new_adv_timer_callback +
    • >>   customized_adv_timer_callback +
    • >>   findmy_adv_timer_callback +
    • >>   Timer4_Handler +
    + +

    app_sched_event_put (Thumb, 154 bytes, Stack size 40 bytes, app_task.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = app_sched_event_put +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   os_msg_send_intern +
    • >>   os_mem_alloc_intern +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_state_machine_dispatch_event +
    • >>   motion_active_poll_duration_timer_timeout_handler +
    • >>   fmna_gatt_dispatch_send_packet_extension_indication +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fmna_gatt_dispatch_send_next_packet +
    • >>   fmna_state_machine_set_next_secondary_key_rotation_index +
    • >>   fmna_rotate_key +
    • >>   fmna_generic_evt_disconnected_handler +
    • >>   fmna_separated_evt_motion_detected_handler +
    • >>   fmna_nearby_separated_timeout_handler +
    • >>   fmna_motion_detection_start_active_polling +
    + +

    double_click_detect_timer_cb (Thumb, 342 bytes, Stack size 32 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 272
    • Call Chain = double_click_detect_timer_cb ⇒ handle_ten_click ⇒ cust_factory_reset ⇒ cust_feature_disable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   custom_new_adv_init +
    • >>   sdd_send_array_value +
    • >>   sdd_battery_level_value_notify +
    • >>   set_serial_number_to_adv +
    • >>   play_beep_mode +
    • >>   fmna_sound_is_playing +
    • >>   fmna_gatt_platform_get_gatt_data +
    • >>   fmna_connection_platform_get_serial_number +
    • >>   custom_new_adv_start +
    • >>   cust_get_conn_id +
    • >>   cust_feature_enable +
    • >>   cust_adv_init +
    • >>   handle_ten_click +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    fmna_factory_reset (Thumb, 44 bytes, Stack size 8 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 288 + Unknown Stack Size +
    • Call Chain = fmna_factory_reset ⇒ log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   log_direct_app +
    • >>   os_delay +
    • >>   log_buffer +
    • >>   WDG_SystemReset +
    • >>   fmna_connection_set_is_fmna_paired +
    +
    [Called By]
    • >>   button_periodic_timer_cb +
    • >>   unpair_pending_callback +
    + +

    app_bond_info_restore (Thumb, 56 bytes, Stack size 8 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = app_bond_info_restore +
    +
    [Calls]
    • >>   ftl_load +
    • >>   log_buffer +
    +
    [Called By]
    • >>   main +
    + +

    app_handle_gpio_msg (Thumb, 398 bytes, Stack size 24 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 1896 + Unknown Stack Size +
    • Call Chain = app_handle_gpio_msg ⇒ serial_number_read_state_init ⇒ fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_direct_app +
    • >>   os_timer_stop +
    • >>   os_timer_start +
    • >>   os_sys_time_get +
    • >>   os_delay +
    • >>   log_buffer +
    • >>   WDG_SystemReset +
    • >>   serial_number_read_state_init +
    • >>   fmna_state_machine_init +
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_sound_platform_stop +
    • >>   fmna_sound_platform_start +
    • >>   fmna_connection_is_fmna_paired +
    • >>   handle_ten_click +
    +
    [Called By]
    • >>   app_handle_io_msg +
    + +

    app_handle_authen_state_evt (Thumb, 110 bytes, Stack size 24 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 240
    • Call Chain = app_handle_authen_state_evt ⇒ fmna_handle_ble_evt ⇒ fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_set_high_priority_bond_v2 +
    • >>   le_find_key_entry_by_idx +
    • >>   fmna_handle_ble_evt +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    app_handle_conn_param_update_evt (Thumb, 360 bytes, Stack size 32 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 248
    • Call Chain = app_handle_conn_param_update_evt ⇒ fmna_handle_ble_evt ⇒ fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_get_conn_param +
    • >>   fmna_handle_ble_evt +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    app_handle_conn_mtu_info_evt (Thumb, 38 bytes, Stack size 16 bytes, findmy_app.o(.text), UNUSED) +

    [Calls]

    • >>   log_buffer +
    • >>   fmna_connection_is_valid_connection +
    + +

    app_handle_conn_state_evt (Thumb, 414 bytes, Stack size 72 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 288
    • Call Chain = app_handle_conn_state_evt ⇒ fmna_handle_ble_evt ⇒ fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   memcmp +
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   le_get_conn_param +
    • >>   le_get_conn_local_addr +
    • >>   le_get_conn_handle +
    • >>   le_get_conn_addr +
    • >>   fmna_handle_ble_evt +
    • >>   fmble_gap_adv_stop +
    • >>   cust_handle_disconnected_evt +
    • >>   cust_handle_connected_evt +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    app_handle_dev_state_evt (Thumb, 204 bytes, Stack size 32 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = app_handle_dev_state_evt ⇒ cust_feature_enable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   le_adv_read_tx_power +
    • >>   fmna_state_machine_init +
    • >>   fmna_connection_is_fmna_paired +
    • >>   cust_feature_enable +
    • >>   cust_adv_init +
    • >>   bat_update_battery_info +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    app_handle_gap_msg (Thumb, 238 bytes, Stack size 16 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 304
    • Call Chain = app_handle_gap_msg ⇒ app_handle_conn_state_evt ⇒ fmna_handle_ble_evt ⇒ fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_bond_passkey_input_confirm +
    • >>   le_bond_passkey_display_confirm +
    • >>   le_bond_just_work_confirm +
    • >>   le_bond_get_display_key +
    • >>   fmna_connection_is_valid_connection +
    • >>   app_handle_dev_state_evt +
    • >>   app_handle_conn_state_evt +
    • >>   app_handle_conn_param_update_evt +
    • >>   app_handle_authen_state_evt +
    +
    [Called By]
    • >>   app_handle_io_msg +
    + +

    app_handle_io_msg (Thumb, 372 bytes, Stack size 32 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 1928 + Unknown Stack Size +
    • Call Chain = app_handle_io_msg ⇒ app_handle_gpio_msg ⇒ serial_number_read_state_init ⇒ fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   log_buffer +
    • >>   AON_WDG_Restart +
    • >>   one_shot_adv_set_param +
    • >>   le_read_rssi +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_gatt_platform_get_gatt_data +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_adv_platform_stop_adv +
    • >>   cust_get_conn_id +
    • >>   crypto_enter_dlps_config +
    • >>   app_handle_gap_msg +
    • >>   app_handle_gpio_msg +
    +
    [Called By]
    • >>   app_main_task +
    + +

    app_global_data_init (Thumb, 64 bytes, Stack size 8 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = app_global_data_init ⇒ gap_get_param +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   gap_get_param +
    • >>   cust_data_init +
    +
    [Called By]
    • >>   main +
    + +

    password_verification_timeout (Thumb, 66 bytes, Stack size 16 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 136
    • Call Chain = password_verification_timeout ⇒ cust_connection_disconnect_this ⇒ cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   os_timer_stop +
    • >>   log_buffer +
    • >>   cust_connection_disconnect_this +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    app_handle_bond_modify_msg (Thumb, 234 bytes, Stack size 32 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = app_handle_bond_modify_msg ⇒ le_set_high_priority_bond_v2 +
    +
    [Calls]
    • >>   ftl_save +
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   le_set_high_priority_bond_v2 +
    • >>   le_find_key_entry_by_idx +
    +
    [Called By]
    • >>   app_gap_callback +
    + +

    app_gap_callback (Thumb, 700 bytes, Stack size 136 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = app_gap_callback ⇒ sdd_battery_level_value_notify ⇒ server_send_data +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy +
    • >>   trace_binary +
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   sdd_battery_level_value_notify +
    • >>   tps_set_parameter +
    • >>   one_shot_handle_pending_adv +
    • >>   one_shot_adv_set_addr +
    • >>   le_vendor_one_shot_adv +
    • >>   le_get_dev_info +
    • >>   le_find_key_entry_by_idx +
    • >>   fmna_gatt_platform_get_gatt_data +
    • >>   cust_get_conn_id +
    • >>   app_handle_bond_modify_msg +
    • >>   __aeabi_idivmod +
    +
    [Address Reference Count : 1]
    • fmna_adv_platform.o(.text) +
    +

    generate_random_id (Thumb, 62 bytes, Stack size 64 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_uidivmod +
    • >>   rand +
    + +

    update_single_id (Thumb, 58 bytes, Stack size 64 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_uidivmod +
    • >>   rand +
    + +

    save_single_id_to_flash (Thumb, 56 bytes, Stack size 8 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   ftl_save +
    + +

    read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data (Thumb, 90 bytes, Stack size 16 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data +
    +
    [Calls]
    • >>   ftl_load +
    • >>   log_buffer +
    • >>   __ARM_common_memcpy1_6 +
    +
    [Called By]
    • >>   cust_adv_update_device_name +
    + +

    reset_data_copy_flag (Thumb, 14 bytes, Stack size 8 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   log_buffer +
    + +

    cust_adv_init (Thumb, 116 bytes, Stack size 24 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = cust_adv_init ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   os_timer_create +
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   one_shot_bt_addr_set +
    • >>   le_gen_rand_addr +
    +
    [Called By]
    • >>   cust_feature_enable +
    • >>   app_handle_dev_state_evt +
    • >>   double_click_detect_timer_cb +
    + +

    cust_data_init (Thumb, 110 bytes, Stack size 8 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = cust_data_init +
    +
    [Calls]
    • >>   ftl_load +
    • >>   log_buffer +
    +
    [Called By]
    • >>   app_global_data_init +
    + +

    cust_adv_stop (Thumb, 56 bytes, Stack size 24 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = cust_adv_stop ⇒ fmble_gap_adv_stop +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmble_gap_adv_stop +
    +
    [Called By]
    • >>   cust_ble_set_to_idle +
    • >>   cust_feature_disable +
    • >>   cust_handle_connected_evt +
    + +

    cust_feature_disable (Thumb, 100 bytes, Stack size 16 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 216
    • Call Chain = cust_feature_disable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_timer_stop +
    • >>   log_buffer +
    • >>   le_disconnect +
    • >>   fmna_connection_set_max_connections +
    • >>   cust_adv_stop +
    • >>   fmna_connection_is_valid_connection +
    • >>   fmna_connection_is_fmna_paired +
    +
    [Called By]
    • >>   cust_factory_reset +
    + +

    cust_factory_reset (Thumb, 30 bytes, Stack size 8 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 224
    • Call Chain = cust_factory_reset ⇒ cust_feature_disable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   cust_feature_disable +
    +
    [Called By]
    • >>   handle_ten_click +
    + +

    cust_adv_update_device_name (Thumb, 572 bytes, Stack size 80 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   ftl_save +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   le_set_gap_param +
    • >>   fmble_gap_adv_data_set +
    • >>   __ARM_common_memcpy4_5 +
    • >>   read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data +
    • >>   __aeabi_uidivmod +
    • >>   rand +
    +
    [Called By]
    • >>   cust_handle_disconnected_evt +
    • >>   cust_handle_connected_evt +
    • >>   cust_feature_enable +
    • >>   cust_connection_disconnect_this +
    • >>   fmna_connection_platform_fmna_unpair +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    cust_handle_connected_evt (Thumb, 108 bytes, Stack size 32 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 144
    • Call Chain = cust_handle_connected_evt ⇒ cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_privacy_check_resolvable_private_address +
    • >>   le_get_dev_irk +
    • >>   cust_adv_update_device_name +
    • >>   cust_adv_stop +
    • >>   le_find_key_entry_by_idx +
    • >>   fmna_connection_is_fmna_paired +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    + +

    cust_adv_start (Thumb, 56 bytes, Stack size 24 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = cust_adv_start ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmble_gap_adv_start +
    +
    [Called By]
    • >>   cust_resume_pending_ble_oprations +
    • >>   cust_handle_disconnected_evt +
    • >>   cust_feature_enable +
    • >>   cust_connection_disconnect_this +
    + +

    cust_handle_disconnected_evt (Thumb, 62 bytes, Stack size 16 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 128
    • Call Chain = cust_handle_disconnected_evt ⇒ cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   log_buffer +
    • >>   cust_adv_start +
    • >>   cust_adv_update_device_name +
    • >>   fmna_connection_is_fmna_paired +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    + +

    cust_feature_is_enabled (Thumb, 6 bytes, Stack size 0 bytes, custom_app.o(.text)) +

    [Called By]

    • >>   fmna_config_control_point_rx_handler +
    + +

    cust_feature_enable (Thumb, 128 bytes, Stack size 24 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 224
    • Call Chain = cust_feature_enable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   fmna_connection_set_max_connections +
    • >>   cust_adv_start +
    • >>   cust_adv_update_device_name +
    • >>   fmna_connection_is_valid_connection +
    • >>   fmna_connection_is_fmna_paired +
    • >>   cust_adv_init +
    +
    [Called By]
    • >>   app_handle_dev_state_evt +
    • >>   double_click_detect_timer_cb +
    + +

    cust_connection_disconnect_this (Thumb, 30 bytes, Stack size 8 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = cust_connection_disconnect_this ⇒ cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   le_disconnect +
    • >>   cust_adv_start +
    • >>   cust_adv_update_device_name +
    +
    [Called By]
    • >>   password_verification_timeout +
    • >>   app_profile_callback +
    + +

    cust_adv_is_enabled (Thumb, 6 bytes, Stack size 0 bytes, custom_app.o(.text), UNUSED) + +

    cust_get_conn_id (Thumb, 6 bytes, Stack size 0 bytes, custom_app.o(.text)) +

    [Called By]

    • >>   app_gap_callback +
    • >>   double_click_detect_timer_cb +
    • >>   handle_ten_click +
    • >>   app_handle_io_msg +
    + +

    cust_ble_set_to_idle (Thumb, 62 bytes, Stack size 24 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   log_buffer +
    • >>   le_disconnect +
    • >>   cust_adv_stop +
    + +

    cust_resume_pending_ble_oprations (Thumb, 30 bytes, Stack size 8 bytes, custom_app.o(.text), UNUSED) +

    [Calls]

    • >>   log_buffer +
    • >>   cust_adv_start +
    + +

    load_overlay (Thumb, 76 bytes, Stack size 8 bytes, overlay_mgr.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = load_overlay +
    +
    [Calls]
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   memcmp +
    • >>   __ARM_common_memcpy1_8 +
    +
    [Called By]
    • >>   pre_main +
    + +

    get_current_scenario_index (Thumb, 40 bytes, Stack size 16 bytes, overlay_mgr.o(.text), UNUSED) +

    [Calls]

    • >>   memcmp +
    + +

    load_serial_number_from_flash (Thumb, 60 bytes, Stack size 16 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = load_serial_number_from_flash ⇒ fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fmna_connection_platform_get_serial_number +
    +
    [Called By]
    • >>   get_serial_number +
    • >>   update_serial_number_in_adv +
    + +

    update_serial_number_in_adv (Thumb, 58 bytes, Stack size 24 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = update_serial_number_in_adv ⇒ load_serial_number_from_flash ⇒ fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   load_serial_number_from_flash +
    • >>   fmble_gap_adv_data_set +
    +
    [Called By]
    • >>   custom_new_adv_init +
    • >>   set_serial_number_to_adv +
    • >>   custom_new_adv_start +
    + +

    set_serial_number_to_adv (Thumb, 50 bytes, Stack size 8 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = set_serial_number_to_adv ⇒ update_serial_number_in_adv ⇒ load_serial_number_from_flash ⇒ fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   update_serial_number_in_adv +
    +
    [Called By]
    • >>   double_click_detect_timer_cb +
    + +

    get_serial_number (Thumb, 30 bytes, Stack size 16 bytes, serial_number_send.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   load_serial_number_from_flash +
    + +

    custom_new_adv_init (Thumb, 56 bytes, Stack size 16 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 96
    • Call Chain = custom_new_adv_init ⇒ update_serial_number_in_adv ⇒ load_serial_number_from_flash ⇒ fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   update_serial_number_in_adv +
    • >>   one_shot_bt_addr_set +
    • >>   le_gen_rand_addr +
    +
    [Called By]
    • >>   main +
    • >>   double_click_detect_timer_cb +
    + +

    custom_new_adv_start (Thumb, 42 bytes, Stack size 8 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = custom_new_adv_start ⇒ update_serial_number_in_adv ⇒ load_serial_number_from_flash ⇒ fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   log_buffer +
    • >>   update_serial_number_in_adv +
    • >>   fmble_gap_adv_start +
    +
    [Called By]
    • >>   double_click_detect_timer_cb +
    + +

    custom_new_adv_stop (Thumb, 26 bytes, Stack size 8 bytes, serial_number_send.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = custom_new_adv_stop ⇒ fmble_gap_adv_stop +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmble_gap_adv_stop +
    +
    [Called By]
    • >>   handle_ten_click +
    + +

    da213b_check_motion_flag (Thumb, 164 bytes, Stack size 16 bytes, da213b.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = da213b_check_motion_flag ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   os_delay +
    • >>   log_buffer +
    • >>   da213b_read_one_byte +
    • >>   da213b_write_one_byte +
    • >>   fmna_sound_platform_stop +
    +
    [Called By]
    • >>   fmna_motion_detection_platform_is_motion_detected +
    + +

    da213b_init (Thumb, 132 bytes, Stack size 8 bytes, da213b.o(.text)) +

    [Stack]

    • Max Depth = 60
    • Call Chain = da213b_init ⇒ da213b_read_one_byte ⇒ I2C_RepeatRead +
    +
    [Calls]
    • >>   os_delay +
    • >>   log_buffer +
    • >>   da213b_read_one_byte +
    • >>   da213b_write_one_byte +
    +
    [Called By]
    • >>   fmna_motion_detection_platform_init +
    + +

    da213b_deinit (Thumb, 90 bytes, Stack size 8 bytes, da213b.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   os_delay +
    • >>   log_buffer +
    • >>   da213b_read_one_byte +
    • >>   da213b_write_one_byte +
    • >>   fmna_sound_platform_stop +
    +
    [Called By]
    • >>   fmna_motion_detection_platform_deinit +
    + +

    gpio_board_init (Thumb, 60 bytes, Stack size 24 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = gpio_board_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   Pinmux_Config +
    +
    [Called By]
    • >>   main +
    • >>   board_init +
    + +

    gpio_driver_init (Thumb, 372 bytes, Stack size 48 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = gpio_driver_init ⇒ RCC_PeriphClockCmd +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    • >>   GPIO_GetPin +
    • >>   GPIO_MaskINTConfig +
    • >>   GPIO_ClearINTPendingBit +
    • >>   GPIO_INTConfig +
    • >>   GPIO_StructInit +
    • >>   GPIO_Init +
    • >>   NVIC_Init +
    • >>   os_timer_create +
    +
    [Called By]
    • >>   driver_init +
    + +

    GPIO9_Handler (Thumb, 98 bytes, Stack size 16 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = GPIO9_Handler ⇒ trig_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO_GetPin +
    • >>   GPIO_MaskINTConfig +
    • >>   GPIO_ClearINTPendingBit +
    • >>   log_buffer +
    • >>   trig_button_int_handler +
    +
    [Called By]
    • >>   GPIO_Group1_Handler +
    + +

    GPIO29_Handler (Thumb, 98 bytes, Stack size 16 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = GPIO29_Handler ⇒ cust_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO_GetPin +
    • >>   GPIO_MaskINTConfig +
    • >>   GPIO_ClearINTPendingBit +
    • >>   log_buffer +
    • >>   cust_button_int_handler +
    +
    [Called By]
    • >>   GPIO_Group1_Handler +
    + +

    gpio_key_enter_dlps_config (Thumb, 112 bytes, Stack size 24 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = gpio_key_enter_dlps_config ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   System_WakeUpPinEnable +
    +
    [Called By]
    • >>   io_dlps_enter_cb +
    + +

    gpio_key_exit_dlps_config (Thumb, 44 bytes, Stack size 24 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = gpio_key_exit_dlps_config ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    +
    [Called By]
    • >>   io_dlps_exit_cb +
    + +

    fmna_adv_reset_bd_addr (Thumb, 32 bytes, Stack size 16 bytes, fmna_adv.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_adv_reset_bd_addr ⇒ fmna_adv_platform_set_random_static_bt_addr ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    • >>   fmna_adv_platform_get_default_bt_addr +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_pair_evt_pair_handler +
    + +

    fmna_adv_init_pairing (Thumb, 64 bytes, Stack size 24 bytes, fmna_adv.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_adv_init_pairing ⇒ fmna_adv_platform_stop_adv ⇒ fmble_gap_adv_stop +
    +
    [Calls]
    • >>   fmna_battery_platform_get_battery_level +
    • >>   __ARM_common_memcpy1_8 +
    • >>   fmna_adv_platform_stop_adv +
    • >>   fmna_adv_platform_init_pairing +
    +
    [Called By]
    • >>   start_pair_adv +
    • >>   fmna_disconnecting_evt_pair_handler +
    • >>   fmna_separated_evt_unbonded_handler +
    • >>   fmna_pair_evt_disconnected_handler +
    • >>   fmna_pair_evt_pair_handler +
    + +

    fmna_adv_init_separated (Thumb, 132 bytes, Stack size 32 bytes, fmna_adv.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = fmna_adv_init_separated ⇒ fmna_adv_platform_set_random_static_bt_addr ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fmna_battery_platform_get_battery_level +
    • >>   __ARM_common_memcpy1_6 +
    • >>   fmna_adv_platform_stop_adv +
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    • >>   fmna_adv_platform_init_separated +
    +
    [Called By]
    • >>   fmna_disconnecting_evt_separated_handler +
    • >>   fmna_nearby_evt_timeout_handler +
    • >>   fmna_separated_evt_key_rotate_handler +
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_adv_init_nearby (Thumb, 134 bytes, Stack size 24 bytes, fmna_adv.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = fmna_adv_init_nearby ⇒ fmna_adv_platform_set_random_static_bt_addr ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fmna_battery_platform_get_battery_level +
    • >>   __ARM_common_memcpy1_6 +
    • >>   fmna_adv_platform_stop_adv +
    • >>   fmna_state_machine_has_been_maintenanced +
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    • >>   fmna_adv_platform_init_nearby +
    +
    [Called By]
    • >>   fmna_connection_set_max_connections +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_connected_evt_key_rotate_handler +
    • >>   fmna_nearby_evt_key_rotate_handler +
    + +

    fmna_config_control_point_rx_handler (Thumb, 738 bytes, Stack size 32 bytes, fmna_config_control_point.o(.text)) +

    [Stack]

    • Max Depth = 232
    • Call Chain = fmna_config_control_point_rx_handler ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   fmna_connection_set_max_connections +
    • >>   cust_feature_is_enabled +
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_state_machine_set_next_secondary_key_rotation_index +
    • >>   fmna_state_machine_set_next_keyroll_ms +
    • >>   fmna_state_machine_set_nearby_timeout_seconds +
    • >>   fmna_state_machine_latch_current_separated_key +
    • >>   fmna_state_machine_is_persistent_connection_disconnection +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_connection_update_connection_info +
    • >>   fmna_connection_set_unpair_pending +
    • >>   fmna_connection_send_multi_status +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_connection_get_max_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    +
    [Called By]
    • >>   fmna_gatt_config_char_write_handler +
    + +

    fmna_config_control_point_is_tx_allowed (Thumb, 70 bytes, Stack size 32 bytes, fmna_config_control_point.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_config_control_point_is_tx_allowed ⇒ fmna_connection_is_status_bit_enabled +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_connection_is_status_bit_enabled +
    +
    [Called By]
    • >>   fmna_gatt_send_indication_internal +
    + +

    fmna_connection_is_valid_connection (Thumb, 24 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   cust_feature_disable +
    • >>   fmna_handle_ble_evt +
    • >>   cust_feature_enable +
    • >>   app_handle_gap_msg +
    • >>   app_handle_conn_mtu_info_evt +
    • >>   app_profile_callback +
    + +

    fmna_connection_is_status_bit_enabled (Thumb, 62 bytes, Stack size 8 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_connection_is_status_bit_enabled +
    +
    [Calls]
    • >>   is_multi_status_bit_enabled +
    +
    [Called By]
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_config_control_point_is_tx_allowed +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_connected_evt_timeout_handler +
    • >>   fmna_connected_evt_disconnected_handler +
    • >>   fmna_separated_evt_sound_complete_handler +
    • >>   fmna_generic_evt_sound_complete_handler +
    + +

    fmna_connection_init (Thumb, 22 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   main +
    + +

    fmna_connection_get_conn_handle_with_multi_status_enabled (Thumb, 52 bytes, Stack size 4 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = fmna_connection_get_conn_handle_with_multi_status_enabled +
    +
    [Called By]
    • >>   fmna_separated_evt_sound_complete_handler +
    • >>   fmna_generic_evt_sound_complete_handler +
    + +

    fmna_connection_disconnect_all (Thumb, 48 bytes, Stack size 16 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_connection_disconnect_all ⇒ fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_platform_disconnect +
    +
    [Called By]
    • >>   fmna_connected_evt_debug_reset_handler +
    + +

    fmna_connection_disconnect_this (Thumb, 26 bytes, Stack size 8 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_connection_disconnect_this ⇒ fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_get_most_recent_conn_handle +
    • >>   fmna_connection_platform_disconnect +
    +
    [Called By]
    • >>   fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler +
    • >>   fmna_fmna_pair_evt_fmna_pairing_finalize_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    • >>   fmna_nearby_evt_connected_handler +
    • >>   fmna_separated_evt_connected_handler +
    • >>   fmna_pair_evt_connected_handler +
    + +

    fmna_connection_send_multi_status (Thumb, 144 bytes, Stack size 24 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 192
    • Call Chain = fmna_connection_send_multi_status ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   fmna_gatt_send_indication +
    • >>   is_multi_status_bit_enabled +
    +
    [Called By]
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_connection_update_connection_info (Thumb, 52 bytes, Stack size 16 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_connection_update_connection_info +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_pm_conn_sec_handle +
    + +

    fmna_connection_update_connection_info_all (Thumb, 64 bytes, Stack size 24 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_connection_update_connection_info_all +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_separated_evt_sound_complete_handler +
    • >>   fmna_generic_evt_sound_complete_handler +
    + +

    fmna_connection_get_num_connections (Thumb, 30 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   fmna_connection_set_max_connections +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_connected_evt_key_rotate_handler +
    + +

    fmna_connection_set_max_connections (Thumb, 176 bytes, Stack size 32 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_adv_platform_stop_adv +
    • >>   fmna_connection_platform_disconnect +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    +
    [Called By]
    • >>   cust_feature_disable +
    • >>   cust_feature_enable +
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_connection_connected_handler (Thumb, 124 bytes, Stack size 32 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = fmna_connection_connected_handler ⇒ fmna_evt_handler +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_evt_handler +
    • >>   fmna_connection_platform_disconnect +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    + +

    fmna_connection_conn_param_update_handler (Thumb, 28 bytes, Stack size 16 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_connection_conn_param_update_handler +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    + +

    fmna_connection_is_fmna_paired (Thumb, 6 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   cust_feature_disable +
    • >>   cust_handle_disconnected_evt +
    • >>   cust_handle_connected_evt +
    • >>   cust_feature_enable +
    • >>   app_handle_dev_state_evt +
    • >>   app_handle_gpio_msg +
    • >>   app_handle_io_msg +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    • >>   fmna_crypto_init +
    • >>   fmna_crypto_unpair +
    • >>   fmna_config_control_point_is_tx_allowed +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_generic_evt_disconnected_handler +
    • >>   fmna_boot_evt_boot_handler +
    • >>   fmna_persistent_connection_disconnection_timeout_handler +
    + +

    fmna_connection_disconnected_handler (Thumb, 290 bytes, Stack size 24 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 192
    • Call Chain = fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_evt_handler +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    + +

    fmna_connection_set_active_ltk (Thumb, 52 bytes, Stack size 8 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_connection_set_active_ltk ⇒ le_set_local_ltk +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   le_find_key_entry_by_idx +
    • >>   le_set_local_ltk +
    +
    [Called By]
    • >>   fmna_primary_key_update +
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_connection_get_active_ltk (Thumb, 4 bytes, Stack size 0 bytes, fmna_connection.o(.text), UNUSED) + +

    fmna_connection_set_is_fmna_paired (Thumb, 20 bytes, Stack size 8 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_connection_set_is_fmna_paired +
    +
    [Calls]
    • >>   ftl_save +
    +
    [Called By]
    • >>   fmna_factory_reset +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    fmna_connection_pair_info_restore (Thumb, 50 bytes, Stack size 16 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_connection_pair_info_restore +
    +
    [Calls]
    • >>   ftl_load +
    • >>   log_buffer +
    +
    [Called By]
    • >>   main +
    + +

    fmna_connection_fmna_unpair (Thumb, 160 bytes, Stack size 32 bytes, fmna_connection.o(.text)) +

    [Stack]

    • Max Depth = 920
    • Call Chain = fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_timer_stop +
    • >>   ftl_save +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   fmna_state_machine_clear_keys +
    • >>   fmna_pm_delete_bonds +
    • >>   fmna_pairing_control_point_unpair +
    • >>   fmna_gatt_reset_queues +
    • >>   fmna_crypto_unpair +
    • >>   fmna_connection_platform_fmna_unpair +
    • >>   fmna_connection_platform_disconnect +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_adv_reset_bd_addr +
    +
    [Called By]
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_pairing_control_point_append_to_rx_buffer +
    • >>   fmna_generic_evt_disconnected_handler +
    • >>   app_profile_callback +
    + +

    fmna_connection_get_max_connections (Thumb, 6 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_connected_evt_key_rotate_handler +
    + +

    fmna_connection_set_unpair_pending (Thumb, 6 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_generic_evt_disconnected_handler +
    + +

    fmna_connection_get_unpair_pending (Thumb, 6 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   fmna_generic_evt_disconnected_handler +
    • >>   unpair_pending_callback +
    + +

    fmna_crypto_get_serial_number_raw (Thumb, 4 bytes, Stack size 0 bytes, fmna_crypto.o(.text), UNUSED) + +

    fmna_crypto_init (Thumb, 174 bytes, Stack size 40 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 920
    • Call Chain = fmna_crypto_init ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   flash_read_locked +
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fmna_connection_platform_get_serial_number +
    • >>   fmna_connection_is_fmna_paired +
    • >>   mbedtls_base64_decode +
    • >>   fm_crypto_ckg_init +
    • >>   fmna_crypto_key_restore +
    +
    [Called By]
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_crypto_generate_send_pairing_data_params (Thumb, 234 bytes, Stack size 32 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1864
    • Call Chain = fmna_crypto_generate_send_pairing_data_params ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   flash_read_locked +
    • >>   log_buffer +
    • >>   fmna_version_get_fw_version +
    • >>   fm_crypto_generate_seedk1 +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_ckg_gen_c1 +
    +
    [Called By]
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    + +

    fmna_log_mfi_token (Thumb, 16 bytes, Stack size 8 bytes, fmna_crypto.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_connection_platform_log_token +
    + +

    fmna_crypto_finalize_pairing (Thumb, 490 bytes, Stack size 40 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1872
    • Call Chain = fmna_crypto_finalize_pairing ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   ftl_save +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_malloc +
    • >>   fmna_free +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fmna_connection_platform_log_token +
    • >>   fm_crypto_verify_s2 +
    • >>   fm_crypto_sha256 +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_server_shared_secret +
    • >>   fm_crypto_decrypt_e3 +
    • >>   fm_crypto_ckg_gen_c3 +
    +
    [Called By]
    • >>   fmna_fmna_pair_evt_fmna_pairing_finalize_handler +
    + +

    fmna_crypto_pairing_complete (Thumb, 504 bytes, Stack size 16 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 408
    • Call Chain = fmna_crypto_pairing_complete ⇒ fm_crypto_ckg_finish ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   ftl_save +
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fm_crypto_ckg_free +
    • >>   fm_crypto_ckg_finish +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    fmna_crypto_roll_primary_sk (Thumb, 52 bytes, Stack size 40 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = fmna_crypto_roll_primary_sk ⇒ fm_crypto_roll_sk ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   fm_crypto_roll_sk +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    fmna_crypto_roll_secondary_sk (Thumb, 52 bytes, Stack size 40 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = fmna_crypto_roll_secondary_sk ⇒ fm_crypto_roll_sk ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   fm_crypto_roll_sk +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    fmna_crypto_roll_primary_key (Thumb, 122 bytes, Stack size 48 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1392
    • Call Chain = fmna_crypto_roll_primary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   fm_crypto_roll_sk +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_derive_ltk +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_main_task +
    + +

    fmna_primary_key_update (Thumb, 164 bytes, Stack size 24 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_primary_key_update ⇒ fmna_connection_set_active_ltk ⇒ le_set_local_ltk +
    +
    [Calls]
    • >>   ftl_save +
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fmna_connection_set_active_ltk +
    +
    [Called By]
    • >>   fmna_rotate_key +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    + +

    fmna_crypto_roll_secondary_key (Thumb, 152 bytes, Stack size 48 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1392
    • Call Chain = fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   ftl_save +
    • >>   trace_binary +
    • >>   log_buffer +
    • >>   fm_crypto_roll_sk +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_update_secondary_index +
    + +

    fmna_crypto_generate_serial_number_response (Thumb, 272 bytes, Stack size 24 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1856
    • Call Chain = fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr +
    • >>   ftl_save +
    • >>   log_buffer +
    • >>   fmna_malloc +
    • >>   fmna_free +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_authenticate_with_ksn +
    +
    [Called By]
    • >>   serial_number_read_state_init +
    + +

    serial_number_read_state_init (Thumb, 268 bytes, Stack size 16 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1872
    • Call Chain = serial_number_read_state_init ⇒ fmna_crypto_generate_serial_number_response ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_crypto_generate_serial_number_response +
    +
    [Called By]
    • >>   app_handle_gpio_msg +
    + +

    fmna_crypto_unpair (Thumb, 56 bytes, Stack size 8 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 888
    • Call Chain = fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fm_crypto_ckg_init +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    + +

    fmna_log_mfi_token_help (Thumb, 18 bytes, Stack size 8 bytes, fmna_crypto.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_connection_platform_log_token_help +
    + +

    fmna_log_serial_number (Thumb, 26 bytes, Stack size 8 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_log_serial_number +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_debug_control_point_rx_handler (Thumb, 308 bytes, Stack size 32 bytes, fmna_debug_control_point.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_debug_control_point_rx_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_state_machine_set_separated_ut_timeout_seconds +
    • >>   fmna_state_machine_set_key_rotation_timeout_ms +
    • >>   fmna_motion_detection_set_separated_ut_backoff_timeout_seconds +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    • >>   fmna_gatt_send_command_response +
    +
    [Called By]
    • >>   fmna_gatt_debug_char_write_handler +
    + +

    fmna_gatt_verify_control_point_opcode_and_length (Thumb, 76 bytes, Stack size 24 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_gatt_verify_control_point_opcode_and_length +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_gatt_dispatch_send_next_packet (Thumb, 14 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_gatt_dispatch_send_next_packet ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_send_indication_internal (Thumb, 282 bytes, Stack size 48 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 136
    • Call Chain = fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   app_sched_event_put +
    • >>   fmna_gatt_platform_send_indication +
    • >>   fmna_config_control_point_is_tx_allowed +
    +
    [Called By]
    • >>   fmna_gatt_dispatch_send_packet_extension_indication_handler +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_send_command_response +
    + +

    fmna_gatt_send_indication (Thumb, 68 bytes, Stack size 32 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 168
    • Call Chain = fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_platform_send_indication_busy +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fmna_connection_get_num_connections +
    +
    [Called By]
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_gatt_platform_send_next_indication +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_state_machine_latch_current_separated_key +
    • >>   fmna_connection_send_multi_status +
    • >>   fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    • >>   fmna_connected_evt_key_rotate_handler +
    • >>   fmna_separated_evt_sound_complete_handler +
    • >>   fmna_generic_evt_sound_complete_handler +
    + +

    fmna_gatt_send_command_response (Thumb, 94 bytes, Stack size 32 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 168
    • Call Chain = fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_platform_send_indication_busy +
    • >>   fmna_gatt_platform_get_next_command_response_index +
    • >>   fmna_gatt_send_indication_internal +
    • >>   fmna_connection_get_num_connections +
    +
    [Called By]
    • >>   fmna_connection_set_max_connections +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_gatt_debug_char_write_handler +
    • >>   fmna_gatt_paired_owner_char_write_handler +
    • >>   fmna_gatt_nonown_char_write_handler +
    • >>   fmna_gatt_config_char_write_handler +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_config_control_point_rx_handler +
    • >>   dispatch_set_next_secondary_key_rotation_index_handler +
    + +

    fmna_gatt_config_char_write_handler (Thumb, 112 bytes, Stack size 24 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = fmna_gatt_config_char_write_handler ⇒ fmna_config_control_point_rx_handler ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_config_control_point_rx_handler +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_nonown_char_write_handler (Thumb, 112 bytes, Stack size 24 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 224
    • Call Chain = fmna_gatt_nonown_char_write_handler ⇒ fmna_nonowner_rx_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_gatt_send_command_response +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_paired_owner_char_write_handler (Thumb, 112 bytes, Stack size 24 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 280
    • Call Chain = fmna_gatt_paired_owner_char_write_handler ⇒ fmna_paired_owner_rx_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_paired_owner_rx_handler +
    • >>   fmna_gatt_send_command_response +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_debug_char_write_handler (Thumb, 112 bytes, Stack size 24 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 224
    • Call Chain = fmna_gatt_debug_char_write_handler ⇒ fmna_debug_control_point_rx_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_gatt_send_command_response +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_pairing_char_authorized_write_handler (Thumb, 222 bytes, Stack size 16 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 952
    • Call Chain = fmna_gatt_pairing_char_authorized_write_handler ⇒ fmna_pairing_control_point_handle_rx ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_pairing_control_point_append_to_rx_buffer +
    • >>   fmna_pairing_control_point_unpair +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_get_most_recent_conn_handle (Thumb, 8 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_gatt_get_most_recent_conn_handle +
    +
    [Calls]
    • >>   fmna_gatt_platform_get_most_recent_conn_handle +
    +
    [Called By]
    • >>   fmna_connection_disconnect_this +
    • >>   fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    + +

    fmna_gatt_dispatch_send_packet_extension_indication (Thumb, 14 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_gatt_dispatch_send_packet_extension_indication ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Called By]
    • >>   app_profile_callback +
    + +

    fmna_gatt_init (Thumb, 8 bytes, Stack size 8 bytes, fmna_gatt.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_gatt_platform_init +
    + +

    fmna_gatt_services_init (Thumb, 8 bytes, Stack size 8 bytes, fmna_gatt.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_gatt_platform_services_init +
    + +

    fmna_gatt_reset_queues (Thumb, 8 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_gatt_reset_queues ⇒ fmna_gatt_platform_reset_indication_queue +
    +
    [Calls]
    • >>   fmna_gatt_platform_reset_indication_queue +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_disconnecting_evt_separated_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    + +

    fmna_motion_detection_init (Thumb, 132 bytes, Stack size 24 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_motion_detection_init ⇒ app_timer_create +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_create +
    +
    [Called By]
    • >>   main +
    + +

    fmna_motion_detection_start_active_polling (Thumb, 140 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = fmna_motion_detection_start_active_polling ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_sched_event_put +
    • >>   app_timer_stop +
    • >>   app_timer_start +
    +
    [Called By]
    • >>   fmna_separated_evt_sound_complete_handler +
    + +

    motion_detected_handler (Thumb, 26 bytes, Stack size 8 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 136
    • Call Chain = motion_detected_handler ⇒ fmna_motion_detection_platform_is_motion_detected ⇒ da213b_check_motion_flag ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_motion_detection_platform_is_motion_detected +
    +
    [Called By]
    • >>   fmna_state_machine_handle_msg +
    + +

    fmna_motion_detection_stop (Thumb, 88 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 152
    • Call Chain = fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_motion_detection_platform_deinit +
    • >>   app_timer_stop +
    +
    [Called By]
    • >>   set_is_nearby +
    + +

    fmna_motion_detection_start (Thumb, 60 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 124
    • Call Chain = fmna_motion_detection_start ⇒ fmna_motion_detection_platform_init ⇒ da213b_init ⇒ da213b_read_one_byte ⇒ I2C_RepeatRead +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_motion_detection_platform_init +
    • >>   app_timer_start +
    +
    [Called By]
    • >>   fmna_state_machine_handle_msg +
    + +

    fmna_motion_detection_set_separated_ut_backoff_timeout_seconds (Thumb, 12 bytes, Stack size 0 bytes, fmna_motion_detection.o(.text)) +

    [Called By]

    • >>   fmna_debug_control_point_rx_handler +
    + +

    fmna_nonowner_rx_handler (Thumb, 284 bytes, Stack size 32 bytes, fmna_nonowner_control_point.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_nonowner_rx_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_connection_update_connection_info +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_state_machine_is_nearby +
    +
    [Called By]
    • >>   fmna_gatt_nonown_char_write_handler +
    + +

    fmna_paired_owner_rx_handler (Thumb, 350 bytes, Stack size 88 bytes, fmna_paired_owner_control_point.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = fmna_paired_owner_rx_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   ftl_load +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    • >>   fmna_gatt_send_command_response +
    +
    [Called By]
    • >>   fmna_gatt_paired_owner_char_write_handler +
    + +

    fmna_pairing_control_point_unpair (Thumb, 12 bytes, Stack size 8 bytes, fmna_pairing_control_point.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_pairing_control_point_unpair +
    +
    [Calls]
    • >>   __aeabi_memclr +
    +
    [Called By]
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    • >>   fmna_connection_fmna_unpair +
    + +

    fmna_pairing_control_point_append_to_rx_buffer (Thumb, 58 bytes, Stack size 16 bytes, fmna_pairing_control_point.o(.text)) +

    [Stack]

    • Max Depth = 936
    • Call Chain = fmna_pairing_control_point_append_to_rx_buffer ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   fmna_connection_fmna_unpair +
    +
    [Called By]
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    + +

    fmna_pairing_control_point_handle_rx (Thumb, 164 bytes, Stack size 16 bytes, fmna_pairing_control_point.o(.text)) +

    [Stack]

    • Max Depth = 936
    • Call Chain = fmna_pairing_control_point_handle_rx ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   log_buffer +
    • >>   fmna_state_machine_dispatch_event +
    • >>   fmna_malloc +
    • >>   fmna_free +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_gatt_verify_control_point_opcode_and_length +
    +
    [Called By]
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    + +

    fmna_state_machine_is_nearby (Thumb, 16 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +

    [Called By]

    • >>   fmna_nonowner_rx_handler +
    + +

    start_pair_adv (Thumb, 12 bytes, Stack size 8 bytes, fmna_state_machine.o(.text), UNUSED) +

    [Calls]

    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_init_pairing +
    + +

    fmna_state_machine_set_nearby_timeout_seconds (Thumb, 26 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_state_machine_set_nearby_timeout_seconds +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_state_machine_stop_key_rotation_timers (Thumb, 86 bytes, Stack size 32 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_state_machine_stop_key_rotation_timers ⇒ app_timer_stop +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_stop +
    +
    [Called By]
    • >>   fmna_state_machine_set_key_rotation_timeout_ms +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_state_machine_set_next_keyroll_ms +
    + +

    fmna_state_machine_set_next_keyroll_ms (Thumb, 66 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = fmna_state_machine_set_next_keyroll_ms ⇒ fmna_state_machine_stop_key_rotation_timers ⇒ app_timer_stop +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   app_timer_start +
    +
    [Called By]
    • >>   fmna_config_control_point_rx_handler +
    + +

    dispatch_set_next_secondary_key_rotation_index_handler (Thumb, 138 bytes, Stack size 32 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1456
    • Call Chain = dispatch_set_next_secondary_key_rotation_index_handler ⇒ fmna_update_secondary_index ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ftl_save +
    • >>   log_buffer +
    • >>   fmna_gatt_send_command_response +
    • >>   fmna_update_secondary_index +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_state_machine_set_next_secondary_key_rotation_index (Thumb, 20 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = fmna_state_machine_set_next_secondary_key_rotation_index ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Called By]
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_state_machine_latch_current_separated_key (Thumb, 78 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 192
    • Call Chain = fmna_state_machine_latch_current_separated_key ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   ftl_save +
    • >>   log_buffer +
    • >>   fmna_gatt_send_indication +
    +
    [Called By]
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_rotate_key (Thumb, 142 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1448
    • Call Chain = fmna_rotate_key ⇒ fmna_update_secondary_index ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ftl_save +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_sched_event_put +
    • >>   fmna_primary_key_update +
    • >>   fmna_rotate_key_internal +
    • >>   fmna_update_secondary_index +
    +
    [Called By]
    • >>   fmna_state_machine_handle_msg +
    + +

    fmna_evt_handler (Thumb, 348 bytes, Stack size 40 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_evt_handler +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_state_machine_init +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_connection_connected_handler +
    • >>   dispatch_fmna_sm_event_handler +
    • >>   fmna_pm_conn_sec_handle +
    + +

    fmna_state_machine_dispatch_event (Thumb, 14 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_state_machine_dispatch_event ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Called By]
    • >>   app_handle_gpio_msg +
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_nonowner_rx_handler +
    • >>   fmna_debug_control_point_rx_handler +
    • >>   fmna_connection_update_mfi_token_storage +
    • >>   fmna_config_control_point_rx_handler +
    • >>   motion_detected_handler +
    • >>   fmna_sound_timeout_handler +
    + +

    fmna_state_machine_init (Thumb, 216 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = fmna_state_machine_init ⇒ fmna_evt_handler +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   vAssertHandler +
    • >>   fmna_evt_handler +
    • >>   app_timer_create +
    +
    [Called By]
    • >>   app_handle_dev_state_evt +
    • >>   app_handle_gpio_msg +
    + +

    fmna_state_machine_has_been_maintenanced (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +

    [Called By]

    • >>   fmna_adv_init_nearby +
    + +

    fmna_state_machine_set_persistent_connection_disconnection (Thumb, 100 bytes, Stack size 32 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_state_machine_set_persistent_connection_disconnection ⇒ app_timer_stop +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_stop +
    • >>   app_timer_start +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_config_control_point_rx_handler +
    + +

    fmna_state_machine_is_persistent_connection_disconnection (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +

    [Called By]

    • >>   fmna_config_control_point_rx_handler +
    + +

    get_next_secondary_key_rotation_index (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text), UNUSED) + +

    fmna_state_machine_get_non_owner_connection_timeout (Thumb, 4 bytes, Stack size 0 bytes, fmna_state_machine.o(.text), UNUSED) + +

    fmna_state_machine_set_key_rotation_timeout_ms (Thumb, 74 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = fmna_state_machine_set_key_rotation_timeout_ms ⇒ fmna_state_machine_stop_key_rotation_timers ⇒ app_timer_stop +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   app_timer_start +
    +
    [Called By]
    • >>   fmna_debug_control_point_rx_handler +
    + +

    fmna_state_machine_set_separated_ut_timeout_seconds (Thumb, 12 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +

    [Called By]

    • >>   fmna_debug_control_point_rx_handler +
    + +

    fmna_state_machine_clear_keys (Thumb, 280 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_state_machine_clear_keys ⇒ fmna_rotate_key_internal +
    +
    [Calls]
    • >>   fmna_rotate_key_internal +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    + +

    fmna_state_machine_handle_msg (Thumb, 224 bytes, Stack size 32 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1480
    • Call Chain = fmna_state_machine_handle_msg ⇒ fmna_rotate_key ⇒ fmna_update_secondary_index ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   bat_update_battery_info +
    • >>   fmna_evt_handler +
    • >>   fmna_connection_platform_disconnect +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_connection_get_max_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_rotate_key +
    • >>   fmna_motion_detection_start +
    • >>   motion_detected_handler +
    +
    [Called By]
    • >>   app_handle_io_msg +
    + +

    fmna_version_init (Thumb, 24 bytes, Stack size 8 bytes, fmna_version.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_version_init +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   main +
    + +

    fmna_version_get_fw_version (Thumb, 30 bytes, Stack size 16 bytes, fmna_version.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_version_get_fw_version +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   ais_attr_read_cb +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    + +

    fmna_adv_platform_get_default_bt_addr (Thumb, 78 bytes, Stack size 24 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_adv_platform_get_default_bt_addr ⇒ le_gen_rand_addr +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   le_gen_rand_addr +
    +
    [Called By]
    • >>   fmna_adv_reset_bd_addr +
    + +

    fmna_adv_platform_set_random_static_bt_addr (Thumb, 60 bytes, Stack size 16 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_adv_platform_set_random_static_bt_addr ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   one_shot_bt_addr_set +
    +
    [Called By]
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    • >>   fmna_adv_reset_bd_addr +
    + +

    fmna_adv_platform_start_fast_adv (Thumb, 86 bytes, Stack size 24 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   os_timer_restart +
    • >>   log_buffer +
    • >>   fmble_gap_adv_start +
    • >>   fmble_gap_adv_data_set +
    +
    [Called By]
    • >>   fmna_connection_disconnected_handler +
    • >>   start_pair_adv +
    • >>   fmna_disconnecting_evt_pair_handler +
    • >>   fmna_disconnecting_evt_separated_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_separated_evt_unbonded_handler +
    • >>   fmna_pair_evt_disconnected_handler +
    • >>   fmna_pair_evt_pair_handler +
    + +

    fmna_adv_platform_start_slow_adv (Thumb, 86 bytes, Stack size 24 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = fmna_adv_platform_start_slow_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   os_timer_restart +
    • >>   log_buffer +
    • >>   fmble_gap_adv_start +
    • >>   fmble_gap_adv_data_set +
    +
    [Called By]
    • >>   fmna_connection_set_max_connections +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_config_control_point_rx_handler +
    • >>   fmna_disconnecting_evt_separated_handler +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_connected_evt_key_rotate_handler +
    • >>   fmna_nearby_evt_timeout_handler +
    • >>   fmna_nearby_evt_key_rotate_handler +
    • >>   fmna_separated_evt_key_rotate_handler +
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_adv_platform_stop_adv (Thumb, 36 bytes, Stack size 8 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_adv_platform_stop_adv ⇒ fmble_gap_adv_stop +
    +
    [Calls]
    • >>   os_timer_state_get +
    • >>   os_timer_stop +
    • >>   fmble_gap_adv_stop +
    +
    [Called By]
    • >>   fmna_connection_set_max_connections +
    • >>   bat_update_battery_info +
    • >>   app_handle_io_msg +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    • >>   fmna_adv_init_pairing +
    + +

    fmna_adv_platform_init_pairing (Thumb, 74 bytes, Stack size 16 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_adv_platform_init_pairing +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   trace_binary +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_adv_init_pairing +
    + +

    fmna_adv_platform_init_nearby (Thumb, 78 bytes, Stack size 16 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_adv_platform_init_nearby +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   trace_binary +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_adv_init_nearby +
    + +

    fmna_adv_platform_init_separated (Thumb, 78 bytes, Stack size 16 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_adv_platform_init_separated +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   trace_binary +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_adv_init_separated +
    + +

    fmna_ble_platform_init (Thumb, 272 bytes, Stack size 88 bytes, fmna_adv_platform.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_ble_platform_init ⇒ one_shot_adv_init +
    +
    [Calls]
    • >>   one_shot_adv_init +
    • >>   le_set_gap_param +
    • >>   le_register_app_cb +
    • >>   le_gap_init +
    • >>   le_bond_set_param +
    • >>   le_adv_set_param +
    • >>   gap_set_param +
    • >>   gap_lib_init +
    • >>   gap_config_le_key_storage_flag +
    +
    [Called By]
    • >>   main +
    + +

    bat_init_data (Thumb, 36 bytes, Stack size 8 bytes, fmna_battery_platform.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = bat_init_data ⇒ ADC_CalibrationInit ⇒ ADC_GetKValue +
    +
    [Calls]
    • >>   log_buffer +
    • >>   ADC_CalibrationInit +
    +
    [Called By]
    • >>   main +
    + +

    bat_enter_dlps_config (Thumb, 2 bytes, Stack size 0 bytes, fmna_battery_platform.o(.text)) +

    [Called By]

    • >>   io_dlps_enter_cb +
    + +

    bat_exit_dlps_config (Thumb, 2 bytes, Stack size 0 bytes, fmna_battery_platform.o(.text)) +

    [Called By]

    • >>   io_dlps_exit_cb +
    + +

    bat_init_driver (Thumb, 70 bytes, Stack size 120 bytes, fmna_battery_platform.o(.text)) +

    [Stack]

    • Max Depth = 144
    • Call Chain = bat_init_driver ⇒ ADC_DeInit ⇒ RCC_PeriphClockCmd +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    • >>   ADC_StructInit +
    • >>   ADC_Init +
    • >>   ADC_DeInit +
    +
    [Called By]
    • >>   driver_init +
    + +

    bat_update_battery_info (Thumb, 318 bytes, Stack size 40 bytes, fmna_battery_platform.o(.text)) +

    [Stack]

    • Max Depth = 92
    • Call Chain = bat_update_battery_info ⇒ ADC_GetVoltage ⇒ ADC_GetKVoltage ⇒ __aeabi_fdiv +
    +
    [Calls]
    • >>   log_buffer +
    • >>   ADC_ClearINTPendingBit +
    • >>   ADC_GetINTStatus +
    • >>   ADC_ReadRawData +
    • >>   ADC_INTConfig +
    • >>   ADC_Cmd +
    • >>   fmna_adv_platform_stop_adv +
    • >>   ADC_GetVoltage +
    • >>   __aeabi_f2uiz +
    • >>   __aeabi_i2d +
    • >>   __aeabi_dsub +
    • >>   __aeabi_d2f +
    • >>   __aeabi_idivmod +
    +
    [Called By]
    • >>   fmna_state_machine_handle_msg +
    • >>   app_handle_dev_state_evt +
    + +

    fmna_battery_platform_get_battery_level (Thumb, 6 bytes, Stack size 0 bytes, fmna_battery_platform.o(.text)) +

    [Called By]

    • >>   ais_attr_read_cb +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    • >>   fmna_adv_init_pairing +
    • >>   app_profile_callback +
    + +

    fmna_connection_platform_disconnect (Thumb, 10 bytes, Stack size 8 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   le_disconnect +
    +
    [Called By]
    • >>   fmna_connection_set_max_connections +
    • >>   fmna_state_machine_handle_msg +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_connection_connected_handler +
    • >>   fmna_connection_disconnect_this +
    • >>   fmna_connection_disconnect_all +
    + +

    fmna_handle_ble_evt (Thumb, 204 bytes, Stack size 24 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 216
    • Call Chain = fmna_handle_ble_evt ⇒ fmna_connection_disconnected_handler ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_get_conn_param +
    • >>   fmna_connection_is_valid_connection +
    • >>   fmna_connection_disconnected_handler +
    • >>   fmna_connection_conn_param_update_handler +
    • >>   fmna_connection_connected_handler +
    • >>   fmna_connection_update_connection_info +
    • >>   on_disconnect +
    • >>   on_connect +
    • >>   fmna_pm_conn_sec_handle +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    • >>   app_handle_conn_param_update_evt +
    • >>   app_handle_authen_state_evt +
    + +

    fmna_connection_platform_fmna_unpair (Thumb, 14 bytes, Stack size 8 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = fmna_connection_platform_fmna_unpair ⇒ cust_adv_update_device_name ⇒ fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   cust_adv_update_device_name +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    + +

    fmna_connection_platform_log_token_help (Thumb, 44 bytes, Stack size 16 bytes, fmna_connection_platform.o(.text), UNUSED) +

    [Calls]

    • >>   trace_binary +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_log_mfi_token_help +
    + +

    fmna_connection_platform_log_token (Thumb, 66 bytes, Stack size 24 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_connection_platform_log_token +
    +
    [Calls]
    • >>   trace_binary +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_log_mfi_token +
    + +

    num_to_char (Thumb, 14 bytes, Stack size 0 bytes, fmna_connection_platform.o(.text), UNUSED) + +

    fmna_connection_platform_get_serial_number (Thumb, 104 bytes, Stack size 40 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_connection_platform_get_serial_number +
    +
    [Calls]
    • >>   flash_read_locked +
    • >>   log_buffer +
    +
    [Called By]
    • >>   load_serial_number_from_flash +
    • >>   double_click_detect_timer_cb +
    • >>   fmna_crypto_init +
    + +

    fmna_connection_update_mfi_token_storage (Thumb, 256 bytes, Stack size 24 bytes, fmna_connection_platform.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = fmna_connection_update_mfi_token_storage ⇒ fmna_state_machine_dispatch_event ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   memcmp +
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   flash_read_locked +
    • >>   flash_write_locked +
    • >>   flash_erase_locked +
    • >>   log_buffer +
    • >>   fmna_state_machine_dispatch_event +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fmna_connection_mfi_token_stored (Thumb, 6 bytes, Stack size 0 bytes, fmna_connection_platform.o(.text)) +

    [Called By]

    • >>   fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler +
    + +

    gap_sched_adv_random_delay (Thumb, 62 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_uidivmod +
    • >>   rand +
    + +

    one_shot_bt_addr_set (Thumb, 30 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = one_shot_bt_addr_set +
    +
    [Calls]
    • >>   __ARM_common_memcpy1_6 +
    +
    [Called By]
    • >>   custom_new_adv_init +
    • >>   cust_adv_update_timer_callback +
    • >>   cust_adv_init +
    • >>   fmna_adv_platform_set_random_static_bt_addr +
    + +

    one_shot_adv_init (Thumb, 122 bytes, Stack size 24 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = one_shot_adv_init +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   os_timer_create +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    • >>   main +
    + +

    one_shot_adv_set_param (Thumb, 326 bytes, Stack size 32 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = one_shot_adv_set_param ⇒ le_vendor_one_shot_adv +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   le_vendor_one_shot_adv +
    • >>   le_adv_set_param +
    • >>   le_adv_update_param +
    • >>   __aeabi_uidivmod +
    • >>   rand +
    +
    [Called By]
    • >>   one_shot_handle_pending_adv +
    • >>   app_handle_io_msg +
    + +

    one_shot_handle_pending_adv (Thumb, 44 bytes, Stack size 8 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = one_shot_handle_pending_adv ⇒ one_shot_adv_set_param ⇒ le_vendor_one_shot_adv +
    +
    [Calls]
    • >>   log_buffer +
    • >>   one_shot_adv_set_param +
    +
    [Called By]
    • >>   app_gap_callback +
    + +

    one_shot_adv_set_addr (Thumb, 22 bytes, Stack size 8 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = one_shot_adv_set_addr ⇒ le_set_rand_addr +
    +
    [Calls]
    • >>   le_set_rand_addr +
    +
    [Called By]
    • >>   app_gap_callback +
    + +

    fmble_gap_adv_start (Thumb, 90 bytes, Stack size 24 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   os_timer_restart +
    • >>   log_buffer +
    • >>   __aeabi_dmul +
    • >>   __aeabi_ui2d +
    • >>   __aeabi_d2uiz +
    +
    [Called By]
    • >>   cust_adv_start +
    • >>   custom_new_adv_start +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_platform_start_slow_adv +
    + +

    fmble_gap_adv_data_set (Thumb, 104 bytes, Stack size 32 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmble_gap_adv_data_set +
    +
    [Calls]
    • >>   log_buffer +
    +
    [Called By]
    • >>   update_serial_number_in_adv +
    • >>   cust_adv_update_device_name +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_platform_start_slow_adv +
    + +

    fmble_gap_adv_stop (Thumb, 54 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmble_gap_adv_stop +
    +
    [Calls]
    • >>   os_timer_stop +
    • >>   log_buffer +
    +
    [Called By]
    • >>   cust_adv_stop +
    • >>   fmna_adv_platform_stop_adv +
    • >>   custom_new_adv_stop +
    • >>   app_handle_conn_state_evt +
    + +

    fmna_gatt_platform_get_gatt_data (Thumb, 12 bytes, Stack size 8 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_gatt_platform_get_gatt_data +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    +
    [Called By]
    • >>   app_gap_callback +
    • >>   double_click_detect_timer_cb +
    • >>   handle_ten_click +
    • >>   app_handle_io_msg +
    + +

    app_profile_callback (Thumb, 822 bytes, Stack size 48 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 1000
    • Call Chain = app_profile_callback ⇒ fmna_gatt_pairing_char_authorized_write_handler ⇒ fmna_pairing_control_point_handle_rx ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ftl_save +
    • >>   log_buffer +
    • >>   sdd_battery_level_value_notify +
    • >>   fmna_battery_platform_get_battery_level +
    • >>   play_beep_mode +
    • >>   le_read_rssi +
    • >>   fmna_connection_is_valid_connection +
    • >>   cust_connection_disconnect_this +
    • >>   fmna_gatt_dispatch_send_packet_extension_indication +
    • >>   fmna_gatt_pairing_char_authorized_write_handler +
    • >>   fmna_gatt_debug_char_write_handler +
    • >>   fmna_gatt_paired_owner_char_write_handler +
    • >>   fmna_gatt_nonown_char_write_handler +
    • >>   fmna_gatt_config_char_write_handler +
    • >>   fmna_gatt_dispatch_send_next_packet +
    • >>   fmna_connection_fmna_unpair +
    +
    [Address Reference Count : 1]
    • fmna_gatt_platform.o(.text) +
    +

    fmna_gatt_platform_services_init (Thumb, 84 bytes, Stack size 8 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = fmna_gatt_platform_services_init ⇒ dis_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   log_buffer +
    • >>   dis_add_service +
    • >>   sdd_add_service +
    • >>   ias_add_service +
    • >>   tps_add_service +
    • >>   accessory_info_add_service +
    • >>   findmy_network_add_service +
    • >>   server_register_app_cb +
    • >>   server_init +
    • >>   gap_register_direct_cb +
    +
    [Called By]
    • >>   fmna_gatt_platform_init +
    • >>   fmna_gatt_services_init +
    + +

    fmna_gatt_platform_init (Thumb, 2 bytes, Stack size 0 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = fmna_gatt_platform_init ⇒ fmna_gatt_platform_services_init ⇒ dis_add_service ⇒ server_add_service +
    +
    [Calls]
    • >>   fmna_gatt_platform_services_init +
    +
    [Called By]
    • >>   main +
    • >>   fmna_gatt_init +
    + +

    fmna_gatt_platform_get_most_recent_conn_handle (Thumb, 6 bytes, Stack size 0 bytes, fmna_gatt_platform.o(.text)) +

    [Called By]

    • >>   fmna_gatt_dispatch_send_packet_extension_indication_handler +
    • >>   fmna_gatt_get_most_recent_conn_handle +
    • >>   fmna_pair_connection_timeout_handler +
    + +

    fmna_gatt_platform_send_indication (Thumb, 290 bytes, Stack size 48 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   server_send_data +
    +
    [Called By]
    • >>   fmna_gatt_send_indication_internal +
    + +

    fmna_gatt_platform_send_indication_busy (Thumb, 126 bytes, Stack size 56 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = fmna_gatt_platform_send_indication_busy ⇒ le_get_gap_param +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   os_msg_send_intern +
    • >>   os_mem_alloc_intern +
    • >>   log_buffer +
    • >>   le_get_gap_param +
    +
    [Called By]
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_send_command_response +
    + +

    fmna_gatt_platform_reset_indication_queue (Thumb, 72 bytes, Stack size 32 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_gatt_platform_reset_indication_queue +
    +
    [Calls]
    • >>   os_msg_recv_intern +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_gatt_reset_queues +
    + +

    fmna_gatt_platform_get_next_command_response_index (Thumb, 32 bytes, Stack size 8 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_gatt_platform_get_next_command_response_index +
    +
    [Calls]
    • >>   os_unlock +
    • >>   os_lock +
    +
    [Called By]
    • >>   fmna_gatt_send_command_response +
    + +

    fmna_gatt_platform_send_next_indication (Thumb, 62 bytes, Stack size 24 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 192
    • Call Chain = fmna_gatt_platform_send_next_indication ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   os_msg_recv_intern +
    • >>   os_mem_free +
    • >>   log_buffer +
    • >>   fmna_gatt_send_indication +
    +
    [Called By]
    • >>   fmna_gatt_dispatch_send_next_packet_handler +
    + +

    on_connect (Thumb, 6 bytes, Stack size 0 bytes, fmna_gatt_platform.o(.text)) +

    [Called By]

    • >>   fmna_handle_ble_evt +
    + +

    on_disconnect (Thumb, 14 bytes, Stack size 0 bytes, fmna_gatt_platform.o(.text)) +

    [Called By]

    • >>   fmna_handle_ble_evt +
    + +

    fmna_malloc (Thumb, 122 bytes, Stack size 32 bytes, fmna_malloc_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_malloc +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_fmna_pair_evt_fmna_pairing_finalize_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    + +

    fmna_free (Thumb, 72 bytes, Stack size 24 bytes, fmna_malloc_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_pairing_control_point_handle_rx +
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_fmna_pair_evt_fmna_pairing_finalize_handler +
    • >>   sn_lookup_callback +
    + +

    fmna_all_pairing_buf_free (Thumb, 62 bytes, Stack size 24 bytes, fmna_malloc_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = fmna_all_pairing_buf_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_fmna_pair_evt_disconnected_handler +
    + +

    board_i2c_master_init (Thumb, 58 bytes, Stack size 16 bytes, fmna_motion_detection_platform.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = board_i2c_master_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   Pinmux_Config +
    +
    [Called By]
    • >>   main +
    • >>   io_dlps_exit_cb +
    • >>   board_init +
    + +

    board_i2c_master_deinit (Thumb, 44 bytes, Stack size 24 bytes, fmna_motion_detection_platform.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = board_i2c_master_deinit ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    +
    [Called By]
    • >>   io_dlps_enter_cb +
    + +

    fmna_motion_detection_platform_init (Thumb, 152 bytes, Stack size 48 bytes, fmna_motion_detection_platform.o(.text)) +

    [Stack]

    • Max Depth = 108
    • Call Chain = fmna_motion_detection_platform_init ⇒ da213b_init ⇒ da213b_read_one_byte ⇒ I2C_RepeatRead +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    • >>   Pad_Config +
    • >>   log_buffer +
    • >>   I2C_Cmd +
    • >>   I2C_StructInit +
    • >>   I2C_Init +
    • >>   Pinmux_Config +
    • >>   da213b_init +
    +
    [Called By]
    • >>   fmna_motion_detection_start +
    + +

    fmna_motion_detection_platform_deinit (Thumb, 90 bytes, Stack size 24 bytes, fmna_motion_detection_platform.o(.text)) +

    [Stack]

    • Max Depth = 136
    • Call Chain = fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   log_buffer +
    • >>   I2C_Cmd +
    • >>   da213b_deinit +
    +
    [Called By]
    • >>   motion_active_poll_duration_timeout_sched_handler +
    • >>   fmna_motion_detection_stop +
    + +

    fmna_motion_detection_platform_is_motion_detected (Thumb, 8 bytes, Stack size 8 bytes, fmna_motion_detection_platform.o(.text)) +

    [Stack]

    • Max Depth = 128
    • Call Chain = fmna_motion_detection_platform_is_motion_detected ⇒ da213b_check_motion_flag ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   da213b_check_motion_flag +
    +
    [Called By]
    • >>   motion_detected_handler +
    + +

    fmna_pm_peer_count (Thumb, 24 bytes, Stack size 8 bytes, fmna_peer_manager.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_pm_peer_count ⇒ le_get_bond_dev_num +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_get_bond_dev_num +
    +
    [Called By]
    • >>   fmna_generic_evt_disconnected_handler +
    + +

    fmna_pm_delete_bonds (Thumb, 28 bytes, Stack size 8 bytes, fmna_peer_manager.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_pm_delete_bonds ⇒ le_bond_delete_by_idx +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_bond_delete_by_idx +
    +
    [Called By]
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_pm_conn_sec_handle (Thumb, 38 bytes, Stack size 8 bytes, fmna_peer_manager.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_pm_conn_sec_handle ⇒ fmna_evt_handler +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_evt_handler +
    • >>   fmna_connection_update_connection_info +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    + +

    fmna_sound_is_playing (Thumb, 20 bytes, Stack size 0 bytes, fmna_sound_platform.o(.text)) +

    [Called By]

    • >>   double_click_detect_timer_cb +
    + +

    fmna_sound_get_current_event (Thumb, 6 bytes, Stack size 0 bytes, fmna_sound_platform.o(.text), UNUSED) + +

    fmna_sound_get_remaining_time (Thumb, 38 bytes, Stack size 8 bytes, fmna_sound_platform.o(.text), UNUSED) +

    [Calls]

    • >>   os_sys_time_get +
    + +

    fmna_sound_platform_init (Thumb, 202 bytes, Stack size 72 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_sound_platform_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    • >>   Pad_Config +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   TIM_StructInit +
    • >>   TIM_TimeBaseInit +
    • >>   app_timer_create +
    +
    [Called By]
    • >>   main +
    + +

    fmna_sound_platform_start (Thumb, 164 bytes, Stack size 32 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = fmna_sound_platform_start ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   os_sys_time_get +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_start +
    • >>   buzzer_init +
    +
    [Called By]
    • >>   button_periodic_timer_cb +
    • >>   app_handle_gpio_msg +
    • >>   fmna_generic_evt_sound_start_handler +
    • >>   fmna_separated_evt_sound_start_handler +
    + +

    fmna_sound_platform_stop (Thumb, 164 bytes, Stack size 32 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_stop +
    • >>   buzzer_init +
    +
    [Called By]
    • >>   button_periodic_timer_cb +
    • >>   da213b_deinit +
    • >>   da213b_check_motion_flag +
    • >>   app_handle_gpio_msg +
    • >>   fmna_connected_evt_sound_stop_handler +
    + +

    play_beep_mode (Thumb, 268 bytes, Stack size 16 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = play_beep_mode ⇒ beep_sequence_handler ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   log_buffer +
    • >>   beep_sequence_handler +
    +
    [Called By]
    • >>   double_click_detect_timer_cb +
    • >>   handle_ten_click +
    • >>   app_profile_callback +
    + +

    beep_stop (Thumb, 12 bytes, Stack size 8 bytes, fmna_sound_platform.o(.text), UNUSED) +

    [Calls]

    • >>   buzzer_init +
    + +

    adv_timer_callback (Thumb, 34 bytes, Stack size 16 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = adv_timer_callback ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    sw_timer_init (Thumb, 232 bytes, Stack size 24 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = sw_timer_init +
    +
    [Calls]
    • >>   os_timer_start +
    • >>   os_timer_create +
    • >>   log_buffer +
    +
    [Called By]
    • >>   main +
    + +

    app_timer_create (Thumb, 56 bytes, Stack size 16 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = app_timer_create +
    +
    [Calls]
    • >>   os_timer_create +
    +
    [Called By]
    • >>   fmna_sound_platform_init +
    • >>   fmna_motion_detection_init +
    • >>   fmna_state_machine_init +
    + +

    app_timer_start (Thumb, 32 bytes, Stack size 16 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = app_timer_start +
    +
    [Calls]
    • >>   os_timer_restart +
    +
    [Called By]
    • >>   fmna_sound_platform_start +
    • >>   motion_active_poll_duration_timeout_sched_handler +
    • >>   fmna_state_machine_set_key_rotation_timeout_ms +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_state_machine_set_next_keyroll_ms +
    • >>   fmna_disconnecting_evt_nearby_handler +
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_nearby_evt_connected_handler +
    • >>   fmna_separated_evt_connected_handler +
    • >>   fmna_pair_evt_connected_handler +
    • >>   fmna_boot_evt_boot_handler +
    • >>   fmna_one_time_key_rotation_handler +
    • >>   set_is_nearby +
    • >>   fmna_motion_detection_start +
    • >>   fmna_motion_detection_start_active_polling +
    • >>   beep_sequence_handler +
    + +

    app_timer_stop (Thumb, 44 bytes, Stack size 16 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = app_timer_stop +
    +
    [Calls]
    • >>   os_timer_state_get +
    • >>   os_timer_stop +
    +
    [Called By]
    • >>   fmna_sound_platform_stop +
    • >>   motion_active_poll_duration_timeout_sched_handler +
    • >>   fmna_state_machine_stop_key_rotation_timers +
    • >>   fmna_state_machine_set_persistent_connection_disconnection +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler +
    • >>   fmna_connected_evt_disconnected_handler +
    • >>   fmna_pair_evt_disconnected_handler +
    • >>   set_is_nearby +
    • >>   fmna_motion_detection_stop +
    • >>   fmna_motion_detection_start_active_polling +
    + +

    fm_crypto_sha256 (Thumb, 16 bytes, Stack size 8 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fm_crypto_sha256 ⇒ mbedtls_sha256 +
    +
    [Calls]
    • >>   mbedtls_sha256 +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fm_crypto_ckg_init (Thumb, 108 bytes, Stack size 16 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 880
    • Call Chain = fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_platform_frng +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_gen_keypair +
    +
    [Called By]
    • >>   fmna_crypto_init +
    • >>   fmna_crypto_unpair +
    + +

    fm_crypto_ckg_free (Thumb, 38 bytes, Stack size 16 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = fm_crypto_ckg_free ⇒ mbedtls_ecp_keypair_free ⇒ mbedtls_ecp_group_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   os_mem_free +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_keypair_free +
    +
    [Called By]
    • >>   fmna_crypto_pairing_complete +
    + +

    fm_crypto_ckg_gen_c1 (Thumb, 56 bytes, Stack size 80 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = fm_crypto_ckg_gen_c1 ⇒ mbedtls_mpi_write_binary ⇒ mbedtls_mpi_core_write_be +
    +
    [Calls]
    • >>   mbedtls_sha256 +
    • >>   mbedtls_mpi_write_binary +
    +
    [Called By]
    • >>   fmna_crypto_generate_send_pairing_data_params +
    + +

    fm_crypto_ckg_gen_c3 (Thumb, 188 bytes, Stack size 176 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 1176
    • Call Chain = fm_crypto_ckg_gen_c3 ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   mbedtls_mpi_write_binary +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_muladd +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_group_init +
    • >>   mbedtls_ecp_group_free +
    • >>   mbedtls_ecp_check_pubkey +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fm_crypto_ckg_finish (Thumb, 148 bytes, Stack size 192 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 392
    • Call Chain = fm_crypto_ckg_finish ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   mbedtls_mpi_write_binary +
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_pairing_complete +
    + +

    fm_crypto_roll_sk (Thumb, 28 bytes, Stack size 16 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 216
    • Call Chain = fm_crypto_roll_sk ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_crypto_roll_primary_key +
    • >>   fmna_crypto_roll_secondary_sk +
    • >>   fmna_crypto_roll_primary_sk +
    + +

    fm_crypto_derive_ltk (Thumb, 60 bytes, Stack size 56 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 256
    • Call Chain = fm_crypto_derive_ltk ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_roll_primary_key +
    + +

    fm_crypto_derive_primary_or_secondary_x (Thumb, 286 bytes, Stack size 344 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 1344
    • Call Chain = fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_write_binary +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_muladd +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_keypair_free +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   mbed_KDF963 +
    • >>   _fm_crypto_scmult_reduce +
    +
    [Called By]
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_crypto_roll_primary_key +
    + +

    fm_crypto_derive_server_shared_secret (Thumb, 54 bytes, Stack size 96 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 296
    • Call Chain = fm_crypto_derive_server_shared_secret ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fm_crypto_decrypt_e3 (Thumb, 182 bytes, Stack size 472 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 808
    • Call Chain = fm_crypto_decrypt_e3 ⇒ mbedtls_gcm_auth_decrypt ⇒ mbedtls_gcm_crypt_and_tag ⇒ mbedtls_gcm_starts ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_gcm_setkey +
    • >>   mbedtls_gcm_init +
    • >>   mbedtls_gcm_free +
    • >>   mbedtls_gcm_auth_decrypt +
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fm_crypto_verify_s2 (Thumb, 102 bytes, Stack size 208 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 1392
    • Call Chain = fm_crypto_verify_s2 ⇒ mbedtls_ecdsa_read_signature ⇒ mbedtls_ecdsa_read_signature_restartable ⇒ mbedtls_ecdsa_verify_restartable ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_sha256 +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   mbedtls_ecdsa_read_signature +
    • >>   mbedtls_ecdsa_init +
    • >>   mbedtls_ecdsa_free +
    +
    [Called By]
    • >>   fmna_crypto_finalize_pairing +
    + +

    fm_crypto_authenticate_with_ksn (Thumb, 116 bytes, Stack size 80 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 280
    • Call Chain = fm_crypto_authenticate_with_ksn ⇒ mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   mbedtls_md_setup +
    • >>   mbedtls_md_init +
    • >>   mbedtls_md_info_from_type +
    • >>   mbedtls_md_hmac_update +
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_hmac_finish +
    • >>   mbedtls_md_free +
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_generate_serial_number_response +
    + +

    fm_crypto_generate_seedk1 (Thumb, 14 bytes, Stack size 8 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fm_crypto_generate_seedk1 ⇒ mbedtls_platform_frng ⇒ free +
    +
    [Calls]
    • >>   mbedtls_platform_frng +
    +
    [Called By]
    • >>   fmna_crypto_generate_send_pairing_data_params +
    + +

    fm_crypto_encrypt_to_server (Thumb, 366 bytes, Stack size 928 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 1832
    • Call Chain = fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   mbedtls_mpi_write_binary +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_gcm_setkey +
    • >>   mbedtls_gcm_init +
    • >>   mbedtls_gcm_free +
    • >>   mbedtls_gcm_crypt_and_tag +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_keypair_free +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_gen_keypair +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   mbedtls_ecdh_compute_shared +
    • >>   mbed_KDF963 +
    +
    [Called By]
    • >>   fmna_crypto_generate_serial_number_response +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    + +

    mbed_KDF963 (Thumb, 180 bytes, Stack size 192 bytes, kdf963.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = mbed_KDF963 ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   mbedtls_sha256_update +
    • >>   mbedtls_sha256_starts +
    • >>   mbedtls_sha256_init +
    • >>   mbedtls_sha256_free +
    • >>   mbedtls_sha256_finish +
    +
    [Called By]
    • >>   fm_crypto_roll_sk +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_server_shared_secret +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_derive_ltk +
    • >>   fm_crypto_decrypt_e3 +
    • >>   fm_crypto_ckg_finish +
    • >>   fm_crypto_authenticate_with_ksn +
    + +

    mbedtls_aes_init (Thumb, 12 bytes, Stack size 8 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_aes_init +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   aes_ctx_alloc +
    + +

    mbedtls_aes_free (Thumb, 18 bytes, Stack size 8 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_aes_free +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   aes_ctx_free +
    + +

    mbedtls_aes_setkey_enc (Thumb, 870 bytes, Stack size 568 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 568
    • Call Chain = mbedtls_aes_setkey_enc +
    +
    [Calls]
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   aes_setkey_enc_wrap +
    • >>   mbedtls_aes_setkey_dec +
    + +

    mbedtls_aes_setkey_dec (Thumb, 248 bytes, Stack size 312 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 880
    • Call Chain = mbedtls_aes_setkey_dec ⇒ mbedtls_aes_setkey_enc +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_aes_setkey_enc +
    +
    [Called By]
    • >>   aes_setkey_dec_wrap +
    + +

    mbedtls_internal_aes_encrypt (Thumb, 1580 bytes, Stack size 56 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_internal_aes_encrypt +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_aes_crypt_ecb +
    + +

    mbedtls_internal_aes_decrypt (Thumb, 1576 bytes, Stack size 56 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_internal_aes_decrypt +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_aes_crypt_ecb +
    + +

    mbedtls_aes_crypt_ecb (Thumb, 38 bytes, Stack size 8 bytes, aes.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = mbedtls_aes_crypt_ecb ⇒ mbedtls_internal_aes_decrypt +
    +
    [Calls]
    • >>   mbedtls_internal_aes_decrypt +
    • >>   mbedtls_internal_aes_encrypt +
    +
    [Called By]
    • >>   aes_crypt_ecb_wrap +
    + +

    mbedtls_asn1_get_len (Thumb, 108 bytes, Stack size 16 bytes, asn1parse.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_asn1_get_len +
    +
    [Called By]
    • >>   mbedtls_asn1_get_alg +
    • >>   mbedtls_asn1_traverse_sequence_of +
    • >>   mbedtls_asn1_get_tag +
    + +

    mbedtls_asn1_get_tag (Thumb, 40 bytes, Stack size 8 bytes, asn1parse.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_asn1_get_tag ⇒ mbedtls_asn1_get_len +
    +
    [Calls]
    • >>   mbedtls_asn1_get_len +
    +
    [Called By]
    • >>   mbedtls_ecdsa_read_signature_restartable +
    • >>   mbedtls_asn1_get_alg +
    • >>   mbedtls_asn1_get_bitstring_null +
    • >>   mbedtls_asn1_traverse_sequence_of +
    • >>   mbedtls_asn1_get_bitstring +
    • >>   mbedtls_asn1_get_mpi +
    • >>   mbedtls_asn1_get_bool +
    • >>   asn1_get_tagged_int +
    + +

    mbedtls_asn1_get_bool (Thumb, 52 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    + +

    mbedtls_asn1_get_int (Thumb, 12 bytes, Stack size 8 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   asn1_get_tagged_int +
    + +

    mbedtls_asn1_get_enum (Thumb, 12 bytes, Stack size 8 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   asn1_get_tagged_int +
    + +

    mbedtls_asn1_get_mpi (Thumb, 38 bytes, Stack size 16 bytes, asn1parse.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = mbedtls_asn1_get_mpi ⇒ mbedtls_mpi_read_binary ⇒ mbedtls_mpi_core_read_be ⇒ mbedtls_mpi_core_bigendian_to_host +
    +
    [Calls]
    • >>   mbedtls_asn1_get_tag +
    • >>   mbedtls_mpi_read_binary +
    +
    [Called By]
    • >>   mbedtls_ecdsa_read_signature_restartable +
    + +

    mbedtls_asn1_get_bitstring (Thumb, 80 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    + +

    mbedtls_asn1_traverse_sequence_of (Thumb, 128 bytes, Stack size 40 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    • >>   mbedtls_asn1_get_len +
    +
    [Called By]
    • >>   mbedtls_asn1_get_sequence_of +
    + +

    mbedtls_asn1_get_bitstring_null (Thumb, 50 bytes, Stack size 12 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    + +

    mbedtls_asn1_sequence_free (Thumb, 20 bytes, Stack size 8 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    + +

    mbedtls_asn1_get_sequence_of (Thumb, 42 bytes, Stack size 40 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_traverse_sequence_of +
    + +

    mbedtls_asn1_get_alg (Thumb, 140 bytes, Stack size 24 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    • >>   mbedtls_asn1_get_len +
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_asn1_get_alg_null +
    + +

    mbedtls_asn1_get_alg_null (Thumb, 46 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_alg +
    + +

    mbedtls_asn1_free_named_data (Thumb, 32 bytes, Stack size 8 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    • >>   mbedtls_platform_zeroize +
    + +

    mbedtls_asn1_free_named_data_list (Thumb, 40 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    + +

    mbedtls_asn1_free_named_data_list_shallow (Thumb, 20 bytes, Stack size 8 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    + +

    mbedtls_asn1_find_named_data (Thumb, 40 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   memcmp +
    +
    [Called By]
    • >>   mbedtls_asn1_store_named_data +
    + +

    mbedtls_asn1_write_len (Thumb, 66 bytes, Stack size 4 bytes, asn1write.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecdsa_write_signature_restartable +
    + +

    mbedtls_asn1_write_tag (Thumb, 24 bytes, Stack size 0 bytes, asn1write.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecdsa_write_signature_restartable +
    + +

    mbedtls_asn1_write_raw_buffer (Thumb, 44 bytes, Stack size 16 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    + +

    mbedtls_asn1_write_mpi (Thumb, 98 bytes, Stack size 24 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_size +
    • >>   mbedtls_asn1_write_len_and_tag +
    • >>   mbedtls_mpi_write_binary +
    +
    [Called By]
    • >>   mbedtls_ecdsa_write_signature_restartable +
    + +

    mbedtls_asn1_write_null (Thumb, 6 bytes, Stack size 0 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_len_and_tag +
    + +

    mbedtls_asn1_write_oid (Thumb, 58 bytes, Stack size 16 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_asn1_write_len_and_tag +
    + +

    mbedtls_asn1_write_algorithm_identifier_ext (Thumb, 116 bytes, Stack size 40 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_asn1_write_len_and_tag +
    +
    [Called By]
    • >>   mbedtls_asn1_write_algorithm_identifier +
    + +

    mbedtls_asn1_write_algorithm_identifier (Thumb, 20 bytes, Stack size 24 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_algorithm_identifier_ext +
    + +

    mbedtls_asn1_write_bool (Thumb, 38 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_len_and_tag +
    + +

    mbedtls_asn1_write_int (Thumb, 10 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   asn1_write_tagged_int +
    + +

    mbedtls_asn1_write_enum (Thumb, 10 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   asn1_write_tagged_int +
    + +

    mbedtls_asn1_write_tagged_string (Thumb, 60 bytes, Stack size 24 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_asn1_write_len_and_tag +
    +
    [Called By]
    • >>   mbedtls_asn1_write_ia5_string +
    • >>   mbedtls_asn1_write_printable_string +
    • >>   mbedtls_asn1_write_utf8_string +
    + +

    mbedtls_asn1_write_utf8_string (Thumb, 14 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_tagged_string +
    + +

    mbedtls_asn1_write_printable_string (Thumb, 14 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_tagged_string +
    + +

    mbedtls_asn1_write_ia5_string (Thumb, 14 bytes, Stack size 8 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_tagged_string +
    + +

    mbedtls_asn1_write_bitstring (Thumb, 96 bytes, Stack size 24 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_asn1_write_len_and_tag +
    +
    [Called By]
    • >>   mbedtls_asn1_write_named_bitstring +
    + +

    mbedtls_asn1_write_named_bitstring (Thumb, 50 bytes, Stack size 16 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_bitstring +
    + +

    mbedtls_asn1_write_octet_string (Thumb, 58 bytes, Stack size 16 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_asn1_write_len_and_tag +
    + +

    mbedtls_asn1_store_named_data (Thumb, 208 bytes, Stack size 40 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_asn1_find_named_data +
    + +

    mbedtls_base64_encode (Thumb, 274 bytes, Stack size 48 bytes, base64.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ct_base64_enc_char +
    • >>   __aeabi_uidivmod +
    + +

    mbedtls_base64_decode (Thumb, 536 bytes, Stack size 56 bytes, base64.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = mbedtls_base64_decode ⇒ mbedtls_ct_uchar_in_range_if +
    +
    [Calls]
    • >>   mbedtls_ct_uchar_in_range_if +
    +
    [Called By]
    • >>   fmna_crypto_init +
    + +

    mbedtls_mpi_lt_mpi_ct (Thumb, 128 bytes, Stack size 24 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_lt_ct +
    + +

    mbedtls_mpi_grow (Thumb, 76 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   __aeabi_memcpy4 +
    • >>   mbedtls_zeroize_and_free +
    +
    [Called By]
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_set_bit +
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_safe_cond_swap +
    • >>   mbedtls_mpi_safe_cond_assign +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_mul_int +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_add_abs +
    • >>   mbedtls_mpi_resize_clear +
    • >>   mpi_select +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_copy +
    • >>   ecp_mod_p224 +
    • >>   ecp_mod_p256 +
    + +

    mbedtls_mpi_safe_cond_assign (Thumb, 100 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_mpi_safe_cond_assign ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_cond_assign +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    + +

    mbedtls_mpi_safe_cond_swap (Thumb, 110 bytes, Stack size 24 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_cond_swap +
    • >>   mbedtls_mpi_grow +
    + +

    mbedtls_mpi_init (Thumb, 12 bytes, Stack size 0 bytes, bignum.o(.text)) +

    [Called By]

    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   ecp_randomize_jac +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   ecp_mul_comb +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    • >>   ecp_normalize_jac_many +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_restart_free +
    • >>   mbedtls_ecdsa_read_signature_restartable +
    • >>   mbedtls_ecdsa_write_signature_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecdh_init +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_group_init +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   _fm_crypto_scmult_reduce +
    + +

    mbedtls_mpi_free (Thumb, 36 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_zeroize_and_free +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   ecp_randomize_jac +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   ecp_mul_comb +
    • >>   ecp_restart_rsm_free +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    • >>   ecp_normalize_jac_many +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_restart_free +
    • >>   mbedtls_ecdsa_read_signature_restartable +
    • >>   mbedtls_ecdsa_write_signature_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecdh_free +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_resize_clear +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_keypair_free +
    • >>   mbedtls_ecp_group_free +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   _fm_crypto_scmult_reduce +
    • >>   mbedtls_ecp_read_key +
    + +

    mbedtls_mpi_shrink (Thumb, 106 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_mpi_shrink ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   __aeabi_memcpy4 +
    • >>   mbedtls_zeroize_and_free +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_mpi_core_get_mont_r2_unsafe +
    + +

    mbedtls_mpi_copy (Thumb, 116 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy4 +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_ecdsa_from_keypair +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_ecdh_get_params +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_mul_int +
    • >>   mbedtls_mpi_add_abs +
    • >>   mbedtls_ecdh_compute_shared +
    • >>   _fm_crypto_scmult_reduce +
    • >>   mbedtls_ecp_export +
    + +

    mbedtls_mpi_swap (Thumb, 22 bytes, Stack size 8 bytes, bignum.o(.text), UNUSED) + +

    mbedtls_mpi_lset (Thumb, 54 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = mbedtls_mpi_lset ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   mbedtls_ecp_point_read_string +
    • >>   mbedtls_ecp_set_zero +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    • >>   ecp_add_mixed +
    • >>   ecp_normalize_jac_many +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_mpi_core_get_mont_r2_unsafe +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_mul_int +
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_get_bit (Thumb, 32 bytes, Stack size 0 bytes, bignum.o(.text)) +

    [Called By]

    • >>   mbedtls_ecp_point_write_binary +
    • >>   ecp_mul_comb_after_precomp +
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_set_bit (Thumb, 86 bytes, Stack size 24 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_grow +
    + +

    mbedtls_mpi_lsb (Thumb, 50 bytes, Stack size 12 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = mbedtls_mpi_lsb +
    +
    [Called By]
    • >>   mbedtls_mpi_gcd +
    + +

    mbedtls_mpi_bitlen (Thumb, 12 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = mbedtls_mpi_bitlen ⇒ mbedtls_mpi_core_bitlen +
    +
    [Calls]
    • >>   mbedtls_mpi_core_bitlen +
    +
    [Called By]
    • >>   mbedtls_mpi_mul_mod +
    • >>   ecp_group_load +
    + +

    mbedtls_mpi_size (Thumb, 16 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = mbedtls_mpi_size ⇒ mbedtls_mpi_core_bitlen +
    +
    [Calls]
    • >>   mbedtls_mpi_core_bitlen +
    +
    [Called By]
    • >>   mbedtls_ecp_point_write_binary +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_asn1_write_mpi +
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_cmp_abs (Thumb, 116 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_mpi_cmp_abs +
    +
    [Called By]
    • >>   mbedtls_mpi_div_mpi +
    • >>   add_sub_mpi +
    + +

    mbedtls_mpi_add_int (Thumb, 48 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = mbedtls_mpi_add_int ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   add_sub_mpi +
    +
    [Called By]
    • >>   mbedtls_ecp_point_read_binary +
    • >>   _fm_crypto_scmult_reduce +
    + +

    mbedtls_mpi_read_string (Thumb, 426 bytes, Stack size 64 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   strlen +
    • >>   mbedtls_mpi_core_bitlen +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_mul_int +
    • >>   add_sub_mpi +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   mbedtls_ecp_point_read_string +
    + +

    mbedtls_mpi_cmp_mpi (Thumb, 168 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_mpi_cmp_mpi +
    +
    [Called By]
    • >>   mbedtls_ecp_check_privkey +
    • >>   mbedtls_ecp_point_cmp +
    • >>   ecp_mul_comb +
    • >>   mbedtls_mpi_shift_l_mod +
    • >>   mbedtls_mpi_add_mod +
    • >>   ecp_double_jac +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_ecp_check_pubkey +
    • >>   mbedtls_ecp_check_pub_priv +
    + +

    mbedtls_mpi_cmp_int (Thumb, 46 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_mpi_cmp_int ⇒ mbedtls_mpi_cmp_mpi +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_mpi +
    +
    [Called By]
    • >>   mbedtls_ecp_check_privkey +
    • >>   mbedtls_ecp_point_write_binary +
    • >>   ecp_mul_comb_after_precomp +
    • >>   mbedtls_mpi_sub_mod +
    • >>   ecp_sw_rhs +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_select_comb +
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_is_zero +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_random +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_ecp_check_pubkey +
    + +

    mbedtls_mpi_shift_r (Thumb, 20 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = mbedtls_mpi_shift_r ⇒ mbedtls_mpi_core_shift_r +
    +
    [Calls]
    • >>   mbedtls_mpi_core_shift_r +
    +
    [Called By]
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_shift_l (Thumb, 60 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = mbedtls_mpi_shift_l ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_shift_l +
    • >>   mbedtls_mpi_core_bitlen +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   mbedtls_mpi_shift_l_mod +
    • >>   mbedtls_mpi_core_get_mont_r2_unsafe +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_div_mpi +
    + +

    mbedtls_mpi_write_string (Thumb, 570 bytes, Stack size 88 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_bitlen +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   __aeabi_uidivmod +
    • >>   __aeabi_memmove +
    + +

    mbedtls_mpi_read_binary_le (Thumb, 42 bytes, Stack size 16 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_read_le +
    • >>   mbedtls_mpi_resize_clear +
    + +

    mbedtls_mpi_read_binary (Thumb, 42 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = mbedtls_mpi_read_binary ⇒ mbedtls_mpi_core_read_be ⇒ mbedtls_mpi_core_bigendian_to_host +
    +
    [Calls]
    • >>   mbedtls_mpi_core_read_be +
    • >>   mbedtls_mpi_resize_clear +
    +
    [Called By]
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_asn1_get_mpi +
    • >>   mbedtls_ecp_point_read_binary +
    • >>   _fm_crypto_scmult_reduce +
    • >>   mbedtls_ecp_read_key +
    + +

    mbedtls_mpi_write_binary_le (Thumb, 18 bytes, Stack size 8 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_write_le +
    +
    [Called By]
    • >>   mbedtls_ecdh_calc_secret +
    + +

    mbedtls_mpi_write_binary (Thumb, 18 bytes, Stack size 8 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_mpi_write_binary ⇒ mbedtls_mpi_core_write_be +
    +
    [Calls]
    • >>   mbedtls_mpi_core_write_be +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   fm_crypto_ckg_gen_c1 +
    • >>   fm_crypto_ckg_finish +
    • >>   mbedtls_ecp_point_write_binary +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_asn1_write_mpi +
    • >>   mbedtls_ecp_write_key +
    + +

    mbedtls_mpi_sub_int (Thumb, 50 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = mbedtls_mpi_sub_int ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   add_sub_mpi +
    +
    [Called By]
    • >>   ecp_sw_rhs +
    • >>   _fm_crypto_scmult_reduce +
    + +

    mbedtls_mpi_mod_mpi (Thumb, 130 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 264
    • Call Chain = mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_div_mpi +
    • >>   add_sub_mpi +
    +
    [Called By]
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_mpi_core_get_mont_r2_unsafe +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_exp_mod +
    • >>   _fm_crypto_scmult_reduce +
    + +

    mbedtls_mpi_exp_mod (Thumb, 1272 bytes, Stack size 152 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 416
    • Call Chain = mbedtls_mpi_exp_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_montmul_init +
    • >>   mbedtls_mpi_core_montmul +
    • >>   mbedtls_mpi_core_bitlen +
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_grow +
    • >>   mpi_montmul +
    • >>   add_sub_mpi +
    • >>   mpi_select +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   mbedtls_ecp_point_read_binary +
    + +

    mbedtls_mpi_gcd (Thumb, 362 bytes, Stack size 56 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = mbedtls_mpi_gcd ⇒ mbedtls_mpi_sub_abs ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_shift_r +
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_lsb +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   mbedtls_mpi_inv_mod +
    + +

    mbedtls_mpi_fill_random (Thumb, 54 bytes, Stack size 24 bytes, bignum.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_fill_random +
    • >>   mbedtls_mpi_resize_clear +
    + +

    mbedtls_mpi_random (Thumb, 70 bytes, Stack size 48 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 160
    • Call Chain = mbedtls_mpi_random ⇒ mbedtls_mpi_core_random ⇒ mbedtls_mpi_core_lt_ct +
    +
    [Calls]
    • >>   mbedtls_mpi_core_random +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_resize_clear +
    +
    [Called By]
    • >>   ecp_randomize_jac +
    • >>   mbedtls_ecp_gen_privkey +
    • >>   mbedtls_ecp_gen_keypair_base +
    + +

    mbedtls_mpi_inv_mod (Thumb, 732 bytes, Stack size 96 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 360
    • Call Chain = mbedtls_mpi_inv_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_shift_r +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   add_sub_mpi +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_normalize_jac_many +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    mbedtls_mpi_core_clz (Thumb, 22 bytes, Stack size 0 bytes, bignum_core.o(.text)) +

    [Called By]

    • >>   mbedtls_mpi_div_mpi +
    + +

    mbedtls_mpi_core_bitlen (Thumb, 58 bytes, Stack size 4 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = mbedtls_mpi_core_bitlen +
    +
    [Called By]
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_bitlen +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_size +
    + +

    mbedtls_mpi_core_bigendian_to_host (Thumb, 54 bytes, Stack size 8 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_mpi_core_bigendian_to_host +
    +
    [Called By]
    • >>   mbedtls_mpi_core_read_be +
    • >>   mbedtls_mpi_core_random +
    • >>   mbedtls_mpi_core_fill_random +
    + +

    mbedtls_mpi_core_uint_le_mpi (Thumb, 60 bytes, Stack size 24 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ct_uint_lt +
    + +

    mbedtls_mpi_core_lt_ct (Thumb, 184 bytes, Stack size 32 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = mbedtls_mpi_core_lt_ct +
    +
    [Called By]
    • >>   mbedtls_mpi_core_random +
    • >>   mbedtls_mpi_lt_mpi_ct +
    + +

    mbedtls_mpi_core_cond_assign (Thumb, 52 bytes, Stack size 16 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_core_cond_assign +
    +
    [Called By]
    • >>   mbedtls_mpi_safe_cond_assign +
    • >>   mpi_select +
    + +

    mbedtls_mpi_core_cond_swap (Thumb, 72 bytes, Stack size 20 bytes, bignum_core.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_mpi_safe_cond_swap +
    + +

    mbedtls_mpi_core_read_le (Thumb, 74 bytes, Stack size 24 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   mbedtls_mpi_read_binary_le +
    + +

    mbedtls_mpi_core_read_be (Thumb, 82 bytes, Stack size 40 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = mbedtls_mpi_core_read_be ⇒ mbedtls_mpi_core_bigendian_to_host +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy +
    • >>   mbedtls_mpi_core_bigendian_to_host +
    +
    [Called By]
    • >>   mbedtls_mpi_read_binary +
    + +

    mbedtls_mpi_core_write_le (Thumb, 92 bytes, Stack size 24 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr +
    +
    [Called By]
    • >>   mbedtls_mpi_write_binary_le +
    + +

    mbedtls_mpi_core_write_be (Thumb, 100 bytes, Stack size 16 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_core_write_be +
    +
    [Calls]
    • >>   __aeabi_memclr +
    +
    [Called By]
    • >>   mbedtls_mpi_write_binary +
    + +

    mbedtls_mpi_core_shift_r (Thumb, 112 bytes, Stack size 24 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_mpi_core_shift_r +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_gcd +
    • >>   mbedtls_mpi_shift_r +
    + +

    mbedtls_mpi_core_shift_l (Thumb, 104 bytes, Stack size 16 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_core_shift_l +
    +
    [Called By]
    • >>   mbedtls_mpi_shift_l +
    + +

    mbedtls_mpi_core_add (Thumb, 72 bytes, Stack size 16 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_core_add +
    +
    [Called By]
    • >>   mbedtls_mpi_add_abs +
    + +

    mbedtls_mpi_core_add_if (Thumb, 84 bytes, Stack size 20 bytes, bignum_core.o(.text), UNUSED) + +

    mbedtls_mpi_core_sub (Thumb, 62 bytes, Stack size 20 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 20
    • Call Chain = mbedtls_mpi_core_sub +
    +
    [Called By]
    • >>   mbedtls_mpi_sub_abs +
    + +

    mbedtls_mpi_core_mla (Thumb, 1032 bytes, Stack size 44 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 44
    • Call Chain = mbedtls_mpi_core_mla +
    +
    [Called By]
    • >>   mbedtls_mpi_core_mul +
    • >>   mbedtls_mpi_core_montmul +
    • >>   mbedtls_mpi_mul_int +
    + +

    mbedtls_mpi_core_mul (Thumb, 56 bytes, Stack size 40 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 84
    • Call Chain = mbedtls_mpi_core_mul ⇒ mbedtls_mpi_core_mla +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_mpi_core_mla +
    +
    [Called By]
    • >>   mbedtls_mpi_mul_mpi +
    + +

    mbedtls_mpi_core_montmul_init (Thumb, 40 bytes, Stack size 4 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = mbedtls_mpi_core_montmul_init +
    +
    [Called By]
    • >>   mbedtls_mpi_exp_mod +
    + +

    mbedtls_mpi_core_montmul (Thumb, 186 bytes, Stack size 48 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 92
    • Call Chain = mbedtls_mpi_core_montmul ⇒ mbedtls_mpi_core_mla +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_ct_memcpy_if +
    • >>   mbedtls_mpi_core_mla +
    +
    [Called By]
    • >>   mbedtls_mpi_core_from_mont_rep +
    • >>   mbedtls_mpi_core_to_mont_rep +
    • >>   mbedtls_mpi_core_exp_mod +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mpi_montmul +
    + +

    mbedtls_mpi_core_get_mont_r2_unsafe (Thumb, 54 bytes, Stack size 16 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_lset +
    + +

    mbedtls_mpi_core_fill_random (Thumb, 90 bytes, Stack size 48 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    • >>   mbedtls_mpi_core_bigendian_to_host +
    +
    [Called By]
    • >>   mbedtls_mpi_fill_random +
    + +

    mbedtls_mpi_core_random (Thumb, 412 bytes, Stack size 80 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = mbedtls_mpi_core_random ⇒ mbedtls_mpi_core_lt_ct +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_mpi_core_bigendian_to_host +
    • >>   mbedtls_ct_uint_lt +
    • >>   mbedtls_mpi_core_lt_ct +
    +
    [Called By]
    • >>   mbedtls_mpi_random +
    + +

    mbedtls_mpi_core_exp_mod_working_limbs (Thumb, 28 bytes, Stack size 0 bytes, bignum_core.o(.text), UNUSED) + +

    mbedtls_mpi_core_exp_mod (Thumb, 492 bytes, Stack size 112 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy4 +
    • >>   mbedtls_mpi_core_montmul +
    + +

    mbedtls_mpi_core_sub_int (Thumb, 40 bytes, Stack size 16 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_mpi_core_sub_int +
    +
    [Called By]
    • >>   mbedtls_mpi_sub_abs +
    + +

    mbedtls_mpi_core_check_zero_ct (Thumb, 28 bytes, Stack size 4 bytes, bignum_core.o(.text), UNUSED) + +

    mbedtls_mpi_core_to_mont_rep (Thumb, 28 bytes, Stack size 32 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_montmul +
    + +

    mbedtls_mpi_core_from_mont_rep (Thumb, 32 bytes, Stack size 40 bytes, bignum_core.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_core_montmul +
    + +

    mbedtls_cipher_list (Thumb, 42 bytes, Stack size 0 bytes, cipher.o(.text), UNUSED) + +

    mbedtls_cipher_info_from_type (Thumb, 30 bytes, Stack size 0 bytes, cipher.o(.text), UNUSED) + +

    mbedtls_cipher_info_from_string (Thumb, 46 bytes, Stack size 16 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   strcmp +
    + +

    mbedtls_cipher_info_from_values (Thumb, 72 bytes, Stack size 16 bytes, cipher.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_cipher_info_from_values +
    +
    [Called By]
    • >>   mbedtls_gcm_setkey +
    + +

    mbedtls_cipher_init (Thumb, 10 bytes, Stack size 8 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    + +

    mbedtls_cipher_free (Thumb, 44 bytes, Stack size 8 bytes, cipher.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_cipher_free +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_gcm_setkey +
    • >>   mbedtls_gcm_free +
    + +

    mbedtls_cipher_setup (Thumb, 52 bytes, Stack size 16 bytes, cipher.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_cipher_setup +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   mbedtls_gcm_setkey +
    + +

    mbedtls_cipher_setkey (Thumb, 116 bytes, Stack size 16 bytes, cipher.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_cipher_setkey +
    +
    [Called By]
    • >>   mbedtls_gcm_setkey +
    + +

    mbedtls_cipher_set_iv (Thumb, 92 bytes, Stack size 16 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   mbedtls_gcm_starts +
    +
    [Called By]
    • >>   mbedtls_cipher_crypt +
    + +

    mbedtls_cipher_reset (Thumb, 18 bytes, Stack size 0 bytes, cipher.o(.text), UNUSED) + +

    mbedtls_cipher_update_ad (Thumb, 34 bytes, Stack size 8 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_gcm_update_ad +
    + +

    mbedtls_cipher_update (Thumb, 152 bytes, Stack size 32 bytes, cipher.o(.text)) +

    [Stack]

    • Max Depth = 136
    • Call Chain = mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_gcm_update +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   mbedtls_gcm_starts +
    • >>   mbedtls_cipher_crypt +
    • >>   mbedtls_gcm_setkey +
    • >>   gcm_mask +
    + +

    mbedtls_cipher_finish (Thumb, 84 bytes, Stack size 0 bytes, cipher.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_cipher_crypt +
    + +

    mbedtls_cipher_write_tag (Thumb, 60 bytes, Stack size 24 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_gcm_finish +
    + +

    mbedtls_cipher_check_tag (Thumb, 96 bytes, Stack size 48 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_gcm_finish +
    • >>   mbedtls_ct_memcmp +
    • >>   mbedtls_platform_zeroize +
    + +

    mbedtls_cipher_crypt (Thumb, 128 bytes, Stack size 48 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_cipher_finish +
    • >>   mbedtls_cipher_update +
    • >>   mbedtls_cipher_set_iv +
    + +

    mbedtls_cipher_auth_encrypt_ext (Thumb, 114 bytes, Stack size 72 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_gcm_crypt_and_tag +
    + +

    mbedtls_cipher_auth_decrypt_ext (Thumb, 106 bytes, Stack size 64 bytes, cipher.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_gcm_auth_decrypt +
    + +

    mbedtls_ct_memcmp (Thumb, 34 bytes, Stack size 12 bytes, constant_time.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = mbedtls_ct_memcmp +
    +
    [Called By]
    • >>   mbedtls_cipher_check_tag +
    • >>   mbedtls_gcm_auth_decrypt +
    + +

    mbedtls_ct_memcpy_if (Thumb, 50 bytes, Stack size 16 bytes, constant_time.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_ct_memcpy_if +
    +
    [Called By]
    • >>   mbedtls_mpi_core_montmul +
    + +

    mbedtls_ct_memcpy_offset (Thumb, 96 bytes, Stack size 36 bytes, constant_time.o(.text), UNUSED) + +

    mbedtls_ecdh_can_do (Thumb, 4 bytes, Stack size 0 bytes, ecdh.o(.text), UNUSED) + +

    mbedtls_ecdh_gen_public (Thumb, 20 bytes, Stack size 24 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   ecdh_gen_public_restartable +
    + +

    mbedtls_ecdh_compute_shared (Thumb, 82 bytes, Stack size 72 bytes, ecdh.o(.text)) +

    [Stack]

    • Max Depth = 904
    • Call Chain = mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_mul_restartable +
    • >>   mbedtls_ecp_is_zero +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    + +

    mbedtls_ecdh_init (Thumb, 82 bytes, Stack size 16 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_restart_init +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_group_init +
    + +

    mbedtls_ecdh_setup (Thumb, 14 bytes, Stack size 8 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecdh_enable_restart (Thumb, 8 bytes, Stack size 0 bytes, ecdh.o(.text), UNUSED) + +

    mbedtls_ecdh_free (Thumb, 80 bytes, Stack size 8 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_restart_free +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_group_free +
    + +

    mbedtls_ecdh_make_params (Thumb, 128 bytes, Stack size 56 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_tls_write_point +
    • >>   mbedtls_ecp_tls_write_group +
    • >>   ecdh_gen_public_restartable +
    + +

    mbedtls_ecdh_read_params (Thumb, 60 bytes, Stack size 24 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_tls_read_point +
    • >>   mbedtls_ecp_tls_read_group_id +
    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecdh_get_params (Thumb, 116 bytes, Stack size 24 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecdh_make_public (Thumb, 94 bytes, Stack size 40 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_tls_write_point +
    • >>   ecdh_gen_public_restartable +
    + +

    mbedtls_ecdh_read_public (Thumb, 40 bytes, Stack size 16 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_tls_read_point +
    + +

    mbedtls_ecdh_calc_secret (Thumb, 200 bytes, Stack size 88 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_mul_restartable +
    • >>   mbedtls_ecp_is_zero +
    • >>   mbedtls_ecp_get_type +
    • >>   mbedtls_mpi_write_binary_le +
    • >>   mbedtls_mpi_size +
    • >>   mbedtls_mpi_write_binary +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    + +

    mbedtls_ecdsa_can_do (Thumb, 4 bytes, Stack size 0 bytes, ecdsa.o(.text), UNUSED) + +

    mbedtls_ecdsa_sign_restartable (Thumb, 712 bytes, Stack size 120 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_ecp_restart_is_enabled +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_mul_restartable +
    • >>   mbedtls_ecp_gen_privkey +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_shift_r +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_add_mpi +
    • >>   mbedtls_mpi_read_binary +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_write_signature_restartable +
    • >>   mbedtls_ecdsa_sign +
    + +

    mbedtls_ecdsa_sign (Thumb, 36 bytes, Stack size 48 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    mbedtls_ecdsa_verify_restartable (Thumb, 606 bytes, Stack size 120 bytes, ecdsa.o(.text)) +

    [Stack]

    • Max Depth = 1088
    • Call Chain = mbedtls_ecdsa_verify_restartable ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_ecp_restart_is_enabled +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_is_zero +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_shift_r +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_read_binary +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_read_signature_restartable +
    • >>   mbedtls_ecdsa_verify +
    + +

    mbedtls_ecdsa_verify (Thumb, 24 bytes, Stack size 32 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecdsa_verify_restartable +
    + +

    mbedtls_ecdsa_write_signature_restartable (Thumb, 200 bytes, Stack size 128 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    • >>   __aeabi_memcpy +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_asn1_write_mpi +
    • >>   mbedtls_asn1_write_tag +
    • >>   mbedtls_asn1_write_len +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_write_signature +
    + +

    mbedtls_ecdsa_write_signature (Thumb, 34 bytes, Stack size 48 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecdsa_write_signature_restartable +
    + +

    mbedtls_ecdsa_read_signature_restartable (Thumb, 146 bytes, Stack size 72 bytes, ecdsa.o(.text)) +

    [Stack]

    • Max Depth = 1160
    • Call Chain = mbedtls_ecdsa_read_signature_restartable ⇒ mbedtls_ecdsa_verify_restartable ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_asn1_get_mpi +
    • >>   mbedtls_asn1_get_tag +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_read_signature +
    + +

    mbedtls_ecdsa_read_signature (Thumb, 20 bytes, Stack size 24 bytes, ecdsa.o(.text)) +

    [Stack]

    • Max Depth = 1184
    • Call Chain = mbedtls_ecdsa_read_signature ⇒ mbedtls_ecdsa_read_signature_restartable ⇒ mbedtls_ecdsa_verify_restartable ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecdsa_read_signature_restartable +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    + +

    mbedtls_ecdsa_genkey (Thumb, 36 bytes, Stack size 24 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_gen_keypair +
    + +

    mbedtls_ecdsa_free (Thumb, 14 bytes, Stack size 8 bytes, ecdsa.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = mbedtls_ecdsa_free ⇒ mbedtls_ecp_keypair_free ⇒ mbedtls_ecp_group_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_keypair_free +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    + +

    mbedtls_ecdsa_from_keypair (Thumb, 58 bytes, Stack size 16 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_group_copy +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_keypair_free +
    + +

    mbedtls_ecdsa_init (Thumb, 8 bytes, Stack size 8 bytes, ecdsa.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = mbedtls_ecdsa_init ⇒ mbedtls_ecp_keypair_init ⇒ mbedtls_ecp_group_init ⇒ mbedtls_ecp_point_init +
    +
    [Calls]
    • >>   mbedtls_ecp_keypair_init +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    + +

    mbedtls_ecdsa_restart_init (Thumb, 16 bytes, Stack size 8 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_restart_init +
    + +

    mbedtls_ecdsa_restart_free (Thumb, 92 bytes, Stack size 24 bytes, ecdsa.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    • >>   mbedtls_ecp_restart_free +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    + +

    mbedtls_ecp_set_max_ops (Thumb, 6 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) + +

    mbedtls_ecp_restart_is_enabled (Thumb, 12 bytes, Stack size 0 bytes, ecp.o(.text)) +

    [Called By]

    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    mbedtls_ecp_point_init (Thumb, 26 bytes, Stack size 8 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_ecp_point_init +
    +
    [Calls]
    • >>   mbedtls_mpi_init +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_init +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_mul_comb +
    • >>   ecp_restart_rsm_free +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_restart_free +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_ecdh_init +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_group_init +
    • >>   mbedtls_ecdh_compute_shared +
    • >>   mbedtls_ecp_check_pub_priv +
    + +

    mbedtls_ecp_point_free (Thumb, 32 bytes, Stack size 8 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   fm_crypto_ckg_free +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_mul_comb +
    • >>   ecp_restart_rsm_free +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecp_restart_free +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_ecdh_free +
    • >>   mbedtls_ecp_keypair_free +
    • >>   mbedtls_ecp_group_free +
    • >>   mbedtls_ecdh_compute_shared +
    • >>   mbedtls_ecp_check_pub_priv +
    + +

    mbedtls_ecp_restart_init (Thumb, 12 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecdsa_restart_init +
    • >>   mbedtls_ecdh_init +
    + +

    mbedtls_ecp_restart_free (Thumb, 78 bytes, Stack size 24 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   os_mem_free +
    • >>   ecp_restart_rsm_free +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_restart_free +
    • >>   mbedtls_ecdh_free +
    + +

    mbedtls_ecp_check_budget (Thumb, 70 bytes, Stack size 4 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = mbedtls_ecp_check_budget +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdsa_sign_restartable +
    + +

    mbedtls_ecp_curve_list (Thumb, 4 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) + +

    mbedtls_ecp_grp_id_list (Thumb, 48 bytes, Stack size 4 bytes, ecp.o(.text), UNUSED) + +

    mbedtls_ecp_curve_info_from_grp_id (Thumb, 28 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) + +

    mbedtls_ecp_curve_info_from_tls_id (Thumb, 28 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) + +

    mbedtls_ecp_curve_info_from_name (Thumb, 46 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   strcmp +
    + +

    mbedtls_ecp_get_type (Thumb, 24 bytes, Stack size 0 bytes, ecp.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecdh_calc_secret +
    + +

    mbedtls_ecp_group_init (Thumb, 66 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = mbedtls_ecp_group_init ⇒ mbedtls_ecp_point_init +
    +
    [Calls]
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_ecp_point_init +
    +
    [Called By]
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   mbedtls_ecdh_init +
    • >>   mbedtls_ecp_keypair_init +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_check_pub_priv +
    + +

    mbedtls_ecp_keypair_init (Thumb, 26 bytes, Stack size 8 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = mbedtls_ecp_keypair_init ⇒ mbedtls_ecp_group_init ⇒ mbedtls_ecp_point_init +
    +
    [Calls]
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_group_init +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_init +
    • >>   mbedtls_ecdsa_init +
    + +

    mbedtls_ecp_group_free (Thumb, 134 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = mbedtls_ecp_group_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   mbedtls_ecdh_free +
    • >>   mbedtls_ecp_keypair_free +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_check_pub_priv +
    + +

    mbedtls_ecp_keypair_free (Thumb, 32 bytes, Stack size 8 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = mbedtls_ecp_keypair_free ⇒ mbedtls_ecp_group_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_group_free +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_free +
    • >>   mbedtls_ecdsa_from_keypair +
    • >>   mbedtls_ecdsa_free +
    + +

    mbedtls_ecp_copy (Thumb, 44 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = mbedtls_ecp_copy ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_add_mixed +
    • >>   mbedtls_ecp_muladd_restartable +
    • >>   mbedtls_ecdsa_from_keypair +
    • >>   mbedtls_ecdh_get_params +
    • >>   mbedtls_ecp_export +
    + +

    mbedtls_ecp_group_copy (Thumb, 10 bytes, Stack size 8 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_group_load +
    +
    [Called By]
    • >>   mbedtls_ecdsa_from_keypair +
    + +

    mbedtls_ecp_set_zero (Thumb, 40 bytes, Stack size 8 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_lset +
    + +

    mbedtls_ecp_is_zero (Thumb, 22 bytes, Stack size 8 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = mbedtls_ecp_is_zero ⇒ mbedtls_mpi_cmp_int ⇒ mbedtls_mpi_cmp_mpi +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    +
    [Called By]
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   mbedtls_ecdh_compute_shared +
    + +

    mbedtls_ecp_point_cmp (Thumb, 50 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_cmp_mpi +
    + +

    mbedtls_ecp_point_read_string (Thumb, 44 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_lset +
    + +

    mbedtls_ecp_point_write_binary (Thumb, 220 bytes, Stack size 48 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_get_bit +
    • >>   mbedtls_mpi_size +
    • >>   mbedtls_mpi_write_binary +
    +
    [Called By]
    • >>   mbedtls_ecp_tls_write_point +
    + +

    mbedtls_ecp_point_read_binary (Thumb, 334 bytes, Stack size 40 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 456
    • Call Chain = mbedtls_ecp_point_read_binary ⇒ mbedtls_mpi_exp_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_sw_rhs +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_shift_r +
    • >>   mbedtls_mpi_get_bit +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_size +
    • >>   mbedtls_mpi_read_binary +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_add_int +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   mbedtls_ecp_tls_read_point +
    + +

    mbedtls_ecp_tls_read_point (Thumb, 44 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_point_read_binary +
    +
    [Called By]
    • >>   mbedtls_ecdh_read_public +
    • >>   mbedtls_ecdh_read_params +
    + +

    mbedtls_ecp_tls_write_point (Thumb, 64 bytes, Stack size 24 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_point_write_binary +
    +
    [Called By]
    • >>   mbedtls_ecdh_make_public +
    • >>   mbedtls_ecdh_make_params +
    + +

    mbedtls_ecp_tls_read_group_id (Thumb, 132 bytes, Stack size 8 bytes, ecp.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecp_tls_read_group +
    • >>   mbedtls_ecdh_read_params +
    + +

    mbedtls_ecp_tls_read_group (Thumb, 26 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_tls_read_group_id +
    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecp_tls_write_group (Thumb, 92 bytes, Stack size 8 bytes, ecp.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_ecdh_make_params +
    + +

    mbedtls_ecp_check_pubkey (Thumb, 174 bytes, Stack size 40 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 344
    • Call Chain = mbedtls_ecp_check_pubkey ⇒ ecp_sw_rhs ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_sw_rhs +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_ecp_mul_shortcuts +
    + +

    mbedtls_ecp_check_privkey (Thumb, 56 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = mbedtls_ecp_check_privkey ⇒ mbedtls_mpi_cmp_int ⇒ mbedtls_mpi_cmp_mpi +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    +
    [Called By]
    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_ecp_read_key +
    + +

    mbedtls_ecp_mul_restartable (Thumb, 34 bytes, Stack size 32 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 832
    • Call Chain = mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_mul_restartable_internal +
    +
    [Called By]
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   mbedtls_ecdh_calc_secret +
    • >>   ecdh_gen_public_restartable +
    • >>   mbedtls_ecdh_compute_shared +
    + +

    mbedtls_ecp_mul (Thumb, 34 bytes, Stack size 32 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 832
    • Call Chain = mbedtls_ecp_mul ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_mul_restartable_internal +
    +
    [Called By]
    • >>   _fm_crypto_scmult_reduce +
    + +

    mbedtls_ecp_muladd_restartable (Thumb, 436 bytes, Stack size 104 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 968
    • Call Chain = mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   ecp_add_mixed +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   mbedtls_ecdsa_verify_restartable +
    • >>   mbedtls_ecp_muladd +
    + +

    mbedtls_ecp_muladd (Thumb, 24 bytes, Stack size 32 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 1000
    • Call Chain = mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_muladd_restartable +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_gen_c3 +
    + +

    mbedtls_ecp_gen_privkey (Thumb, 78 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_random +
    +
    [Called By]
    • >>   mbedtls_ecdsa_sign_restartable +
    • >>   ecdh_gen_public_restartable +
    + +

    mbedtls_ecp_gen_keypair_base (Thumb, 90 bytes, Stack size 48 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 848
    • Call Chain = mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_mpi_random +
    +
    [Called By]
    • >>   mbedtls_ecp_gen_keypair +
    • >>   mbedtls_ecp_gen_key +
    + +

    mbedtls_ecp_gen_keypair (Thumb, 28 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 864
    • Call Chain = mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_gen_keypair_base +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_ckg_init +
    • >>   mbedtls_ecdsa_genkey +
    + +

    mbedtls_ecp_gen_key (Thumb, 48 bytes, Stack size 24 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_gen_keypair_base +
    + +

    mbedtls_ecp_read_key (Thumb, 72 bytes, Stack size 24 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_check_privkey +
    • >>   mbedtls_mpi_read_binary +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecp_write_key (Thumb, 28 bytes, Stack size 8 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_mpi_write_binary +
    + +

    mbedtls_ecp_check_pub_priv (Thumb, 200 bytes, Stack size 184 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    • >>   mbedtls_ecp_group_load +
    • >>   mbedtls_ecp_group_init +
    • >>   mbedtls_ecp_group_free +
    + +

    mbedtls_ecp_export (Thumb, 46 bytes, Stack size 16 bytes, ecp.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_group_load +
    + +

    mbedtls_ecp_group_load (Thumb, 142 bytes, Stack size 56 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 96
    • Call Chain = mbedtls_ecp_group_load ⇒ mbedtls_ecp_group_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_group_init +
    • >>   mbedtls_ecp_group_free +
    • >>   ecp_group_load +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_derive_primary_or_secondary_x +
    • >>   fm_crypto_ckg_init +
    • >>   fm_crypto_ckg_gen_c3 +
    • >>   mbedtls_ecp_tls_read_group +
    • >>   mbedtls_ecp_group_copy +
    • >>   mbedtls_ecdsa_genkey +
    • >>   mbedtls_ecdh_get_params +
    • >>   mbedtls_ecdh_read_params +
    • >>   mbedtls_ecdh_setup +
    • >>   mbedtls_ecp_export +
    • >>   mbedtls_ecp_check_pub_priv +
    • >>   mbedtls_ecp_read_key +
    • >>   mbedtls_ecp_gen_key +
    + +

    mbedtls_gcm_init (Thumb, 12 bytes, Stack size 8 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_gcm_init +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_decrypt_e3 +
    • >>   gcm_ctx_alloc +
    + +

    mbedtls_gcm_setkey (Thumb, 802 bytes, Stack size 80 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 216
    • Call Chain = mbedtls_gcm_setkey ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_cipher_update +
    • >>   mbedtls_cipher_setkey +
    • >>   mbedtls_cipher_setup +
    • >>   mbedtls_cipher_free +
    • >>   mbedtls_cipher_info_from_values +
    • >>   __ARM_common_ll_muluu +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_decrypt_e3 +
    • >>   gcm_aes_setkey_wrap +
    + +

    mbedtls_gcm_starts (Thumb, 270 bytes, Stack size 64 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = mbedtls_gcm_starts ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   __ARM_common_memcpy1_8 +
    • >>   mbedtls_cipher_update +
    • >>   gcm_mult +
    +
    [Called By]
    • >>   mbedtls_cipher_set_iv +
    • >>   mbedtls_gcm_crypt_and_tag +
    + +

    mbedtls_gcm_update_ad (Thumb, 212 bytes, Stack size 24 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 68
    • Call Chain = mbedtls_gcm_update_ad ⇒ gcm_mult +
    +
    [Calls]
    • >>   gcm_mult +
    +
    [Called By]
    • >>   mbedtls_cipher_update_ad +
    • >>   mbedtls_gcm_crypt_and_tag +
    + +

    mbedtls_gcm_update (Thumb, 400 bytes, Stack size 56 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    • >>   gcm_mask +
    • >>   gcm_mult +
    +
    [Called By]
    • >>   mbedtls_cipher_update +
    • >>   mbedtls_gcm_crypt_and_tag +
    + +

    mbedtls_gcm_finish (Thumb, 412 bytes, Stack size 48 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 92
    • Call Chain = mbedtls_gcm_finish ⇒ gcm_mult +
    +
    [Calls]
    • >>   __aeabi_memcpy +
    • >>   gcm_mult +
    +
    [Called By]
    • >>   mbedtls_cipher_check_tag +
    • >>   mbedtls_cipher_write_tag +
    • >>   mbedtls_gcm_crypt_and_tag +
    + +

    mbedtls_gcm_crypt_and_tag (Thumb, 84 bytes, Stack size 48 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 248
    • Call Chain = mbedtls_gcm_crypt_and_tag ⇒ mbedtls_gcm_starts ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_gcm_update_ad +
    • >>   mbedtls_gcm_update +
    • >>   mbedtls_gcm_starts +
    • >>   mbedtls_gcm_finish +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   mbedtls_cipher_auth_encrypt_ext +
    • >>   mbedtls_gcm_auth_decrypt +
    + +

    mbedtls_gcm_auth_decrypt (Thumb, 82 bytes, Stack size 88 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 336
    • Call Chain = mbedtls_gcm_auth_decrypt ⇒ mbedtls_gcm_crypt_and_tag ⇒ mbedtls_gcm_starts ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_ct_memcmp +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_gcm_crypt_and_tag +
    +
    [Called By]
    • >>   fm_crypto_decrypt_e3 +
    • >>   mbedtls_cipher_auth_decrypt_ext +
    + +

    mbedtls_gcm_free (Thumb, 26 bytes, Stack size 8 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_gcm_free ⇒ mbedtls_cipher_free +
    +
    [Calls]
    • >>   mbedtls_cipher_free +
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   fm_crypto_encrypt_to_server +
    • >>   fm_crypto_decrypt_e3 +
    • >>   gcm_ctx_free +
    + +

    mbedtls_md_info_from_type (Thumb, 20 bytes, Stack size 0 bytes, md.o(.text)) +

    [Called By]

    • >>   fm_crypto_authenticate_with_ksn +
    + +

    mbedtls_md_init (Thumb, 10 bytes, Stack size 0 bytes, md.o(.text)) +

    [Called By]

    • >>   fm_crypto_authenticate_with_ksn +
    + +

    mbedtls_md_free (Thumb, 70 bytes, Stack size 8 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_md_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   mbedtls_zeroize_and_free +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_sha256_free +
    +
    [Called By]
    • >>   fm_crypto_authenticate_with_ksn +
    • >>   mbedtls_md_setup +
    • >>   mbedtls_md_hmac +
    + +

    mbedtls_md_clone (Thumb, 54 bytes, Stack size 8 bytes, md.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_sha256_clone +
    + +

    mbedtls_md_setup (Thumb, 130 bytes, Stack size 24 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = mbedtls_md_setup ⇒ mbedtls_md_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_sha256_init +
    • >>   mbedtls_md_free +
    +
    [Called By]
    • >>   fm_crypto_authenticate_with_ksn +
    • >>   mbedtls_md_hmac +
    + +

    mbedtls_md_starts (Thumb, 44 bytes, Stack size 8 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_md_starts ⇒ mbedtls_sha256_starts +
    +
    [Calls]
    • >>   mbedtls_sha256_starts +
    +
    [Called By]
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_hmac_finish +
    • >>   mbedtls_md_hmac_reset +
    + +

    mbedtls_md_update (Thumb, 36 bytes, Stack size 8 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_md_update ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   mbedtls_sha256_update +
    +
    [Called By]
    • >>   mbedtls_md_hmac_update +
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_hmac_finish +
    • >>   mbedtls_md_hmac +
    • >>   mbedtls_md_hmac_reset +
    + +

    mbedtls_md_finish (Thumb, 36 bytes, Stack size 8 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_md_finish ⇒ mbedtls_sha256_finish +
    +
    [Calls]
    • >>   mbedtls_sha256_finish +
    +
    [Called By]
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_hmac_finish +
    + +

    mbedtls_md (Thumb, 56 bytes, Stack size 16 bytes, md.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_sha256 +
    + +

    mbedtls_md_get_size (Thumb, 8 bytes, Stack size 0 bytes, md.o(.text), UNUSED) + +

    mbedtls_md_get_type (Thumb, 8 bytes, Stack size 0 bytes, md.o(.text), UNUSED) + +

    mbedtls_md_list (Thumb, 4 bytes, Stack size 0 bytes, md.o(.text), UNUSED) + +

    mbedtls_md_info_from_string (Thumb, 54 bytes, Stack size 16 bytes, md.o(.text), UNUSED) +

    [Calls]

    • >>   strcmp +
    + +

    mbedtls_md_get_name (Thumb, 26 bytes, Stack size 0 bytes, md.o(.text), UNUSED) + +

    mbedtls_md_info_from_ctx (Thumb, 8 bytes, Stack size 0 bytes, md.o(.text), UNUSED) + +

    mbedtls_md_hmac_starts (Thumb, 200 bytes, Stack size 56 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = mbedtls_md_hmac_starts ⇒ mbedtls_md_finish ⇒ mbedtls_sha256_finish +
    +
    [Calls]
    • >>   __aeabi_memset +
    • >>   mbedtls_platform_zeroize +
    • >>   mbedtls_md_finish +
    • >>   mbedtls_md_update +
    • >>   mbedtls_md_starts +
    +
    [Called By]
    • >>   fm_crypto_authenticate_with_ksn +
    • >>   mbedtls_md_hmac +
    + +

    mbedtls_md_hmac_update (Thumb, 22 bytes, Stack size 0 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = mbedtls_md_hmac_update ⇒ mbedtls_md_update ⇒ mbedtls_sha256_update +
    +
    [Calls]
    • >>   mbedtls_md_update +
    +
    [Called By]
    • >>   fm_crypto_authenticate_with_ksn +
    + +

    mbedtls_md_hmac_finish (Thumb, 98 bytes, Stack size 48 bytes, md.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = mbedtls_md_hmac_finish ⇒ mbedtls_md_finish ⇒ mbedtls_sha256_finish +
    +
    [Calls]
    • >>   mbedtls_md_finish +
    • >>   mbedtls_md_update +
    • >>   mbedtls_md_starts +
    +
    [Called By]
    • >>   fm_crypto_authenticate_with_ksn +
    • >>   mbedtls_md_hmac +
    + +

    mbedtls_md_hmac_reset (Thumb, 46 bytes, Stack size 16 bytes, md.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_md_update +
    • >>   mbedtls_md_starts +
    + +

    mbedtls_md_hmac (Thumb, 140 bytes, Stack size 48 bytes, md.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_md_setup +
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_hmac_finish +
    • >>   mbedtls_md_free +
    • >>   mbedtls_md_update +
    + +

    mbedtls_sha256_init (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256_init +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    +
    [Called By]
    • >>   mbedtls_md_setup +
    • >>   mbed_KDF963 +
    + +

    mbedtls_sha256_free (Thumb, 16 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256_free +
    +
    [Calls]
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_md_free +
    • >>   mbed_KDF963 +
    + +

    mbedtls_sha256_clone (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy4 +
    +
    [Called By]
    • >>   mbedtls_md_clone +
    + +

    mbedtls_sha256_starts (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256_starts +
    +
    [Calls]
    • >>   SHA256_Init +
    +
    [Called By]
    • >>   mbed_KDF963 +
    • >>   mbedtls_md_starts +
    + +

    mbedtls_internal_sha256_process (Thumb, 12 bytes, Stack size 8 bytes, sha256.o(.text), UNUSED) +

    [Calls]

    • >>   SHA256_Update +
    + +

    mbedtls_sha256_update (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256_update +
    +
    [Calls]
    • >>   SHA256_Update +
    +
    [Called By]
    • >>   mbed_KDF963 +
    • >>   mbedtls_md_update +
    + +

    mbedtls_sha256_finish (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256_finish +
    +
    [Calls]
    • >>   SHA256_Final +
    +
    [Called By]
    • >>   mbed_KDF963 +
    • >>   mbedtls_md_finish +
    + +

    mbedtls_sha256 (Thumb, 10 bytes, Stack size 8 bytes, sha256.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_sha256 +
    +
    [Calls]
    • >>   SHA256 +
    +
    [Called By]
    • >>   fm_crypto_verify_s2 +
    • >>   fm_crypto_sha256 +
    • >>   fm_crypto_ckg_gen_c1 +
    • >>   mbedtls_md +
    + +

    mbedtls_platform_zeroize (Thumb, 16 bytes, Stack size 0 bytes, platform_util.o(.text)) +

    [Called By]

    • >>   mbedtls_gcm_update +
    • >>   mbedtls_cipher_check_tag +
    • >>   mbedtls_cipher_free +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_asn1_free_named_data +
    • >>   mbedtls_asn1_get_alg +
    • >>   mbedtls_internal_aes_decrypt +
    • >>   mbedtls_internal_aes_encrypt +
    • >>   mbedtls_aes_setkey_dec +
    • >>   mbedtls_aes_free +
    • >>   mbedtls_sha256_free +
    • >>   mbedtls_md_hmac_starts +
    • >>   mbedtls_md_free +
    • >>   mbedtls_gcm_free +
    • >>   mbedtls_gcm_auth_decrypt +
    • >>   mbedtls_ecp_group_free +
    • >>   gcm_mask +
    + +

    mbedtls_zeroize_and_free (Thumb, 28 bytes, Stack size 8 bytes, platform_util.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    +
    [Called By]
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_md_free +
    + +

    mbedtls_platform_frng (Thumb, 68 bytes, Stack size 32 bytes, platform_util.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = mbedtls_platform_frng ⇒ free +
    +
    [Calls]
    • >>   free +
    • >>   malloc +
    • >>   __aeabi_memclr +
    • >>   __aeabi_memcpy +
    • >>   rand +
    +
    [Called By]
    • >>   fm_crypto_generate_seedk1 +
    • >>   fm_crypto_ckg_init +
    +
    [Address Reference Count : 1]
    • fm-crypto.o(.text) +
    +

    gap_lib_handle_btif_msg (Thumb, 40 bytes, Stack size 8 bytes, gap_lib.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = gap_lib_handle_btif_msg ⇒ le_handle_vendor_cmd_rsp ⇒ le_get_conn_id_by_handle +
    +
    [Calls]
    • >>   le_handle_vendor_evt_info +
    • >>   le_handle_vendor_cmd_rsp +
    +
    [Address Reference Count : 1]
    • gap_lib.o(.text) +
    +

    gap_lib_init (Thumb, 22 bytes, Stack size 8 bytes, gap_lib.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = gap_lib_init ⇒ gap_register_extend_cb +
    +
    [Calls]
    • >>   log_buffer +
    • >>   gap_register_extend_cb +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    + +

    btif_vendor_cmd_req (Thumb, 26 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   gap_vendor_read_thermal_meter_data +
    • >>   gap_vendor_set_ant_ctrl +
    • >>   le_vendor_measure_master_clk_freq_mode +
    • >>   le_vendor_more_precise_32k_option +
    • >>   le_vendor_set_priority +
    • >>   le_vendor_modify_bt_le_fw_policy +
    • >>   gap_vendor_cmd_req +
    • >>   le_vendor_trigger_internal_32k_calibration +
    • >>   le_vendor_update_conn_param +
    • >>   le_vendor_drop_acl_data +
    • >>   le_vendor_adv_3_data_set +
    • >>   le_vendor_adv_3_data_enable +
    • >>   gap_set_lps_bootup_active_time +
    + +

    btif_sw_reset_req (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    BTIF_VendorGetResponse (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    btif_send_event (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    hci_if_open (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    hci_if_close (Thumb, 16 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    hci_if_write (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    hci_if_confirm (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_start_bt_stack (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = gap_start_bt_stack +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_main_task +
    + +

    gap_register_app_cb (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_set_param (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = gap_set_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    + +

    gap_get_param (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = gap_get_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_global_data_init +
    + +

    gap_set_pairable_mode (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_write_airplan_mode (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_read_airplan_mode (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_handle_msg (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = gap_handle_msg +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_main_task +
    + +

    gap_buffer_free (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gap_register_extend_cb (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = gap_register_extend_cb +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   gap_lib_init +
    + +

    gap_register_direct_cb (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = gap_register_direct_cb +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    gap_send_dev_state (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_gap_init (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_gap_init +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    + +

    le_gap_msg_info_way (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_max_link_num (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_register_app_cb (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_register_app_cb +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    + +

    le_set_gap_param (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_set_gap_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    • >>   cust_adv_update_device_name +
    + +

    le_get_gap_param (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_get_gap_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_gatt_platform_send_indication_busy +
    + +

    le_modify_white_list (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_gen_rand_addr (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_gen_rand_addr +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   custom_new_adv_init +
    • >>   cust_adv_update_timer_callback +
    • >>   cust_adv_init +
    • >>   fmna_adv_platform_get_default_bt_addr +
    + +

    le_set_rand_addr (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_set_rand_addr +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   one_shot_adv_set_addr +
    + +

    le_cfg_local_identity_address (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_set_host_chann_classif (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_write_default_data_len (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_vendor_set_rem_min_sca (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_init (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = server_init +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    server_builtin_service_reg (Thumb, 12 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_add_service (Thumb, 44 bytes, Stack size 40 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = server_add_service +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   dis_add_service +
    • >>   sdd_add_service +
    • >>   ias_add_service +
    • >>   tps_add_service +
    • >>   accessory_info_add_service +
    • >>   findmy_network_add_service +
    + +

    server_add_service_by_start_handle (Thumb, 44 bytes, Stack size 48 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_register_app_cb (Thumb, 14 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = server_register_app_cb +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_gatt_platform_services_init +
    + +

    server_attr_read_confirm (Thumb, 42 bytes, Stack size 40 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   sdd_battery_level_value_read_confirm +
    + +

    server_exec_write_confirm (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_attr_write_confirm (Thumb, 30 bytes, Stack size 24 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_send_data (Thumb, 42 bytes, Stack size 40 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = server_send_data +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   sdd_send_array_value +
    • >>   sdd_battery_level_value_notify +
    • >>   fmna_gatt_platform_send_indication +
    + +

    server_get_write_cmd_data_buffer (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_get_start_handle (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_clear_service (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    server_set_service_reg_mode (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_adv_set_param (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_adv_set_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    • >>   one_shot_adv_set_param +
    + +

    le_adv_get_param (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_adv_start (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_adv_stop (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_adv_update_param (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_adv_update_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   one_shot_adv_set_param +
    + +

    le_adv_read_tx_power (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_adv_read_tx_power +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_dev_state_evt +
    + +

    le_adv_set_tx_power (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_vendor_one_shot_adv (Thumb, 44 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_vendor_one_shot_adv +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   one_shot_adv_set_param +
    • >>   app_gap_callback +
    + +

    le_get_conn_param (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_get_conn_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_handle_ble_evt +
    • >>   app_handle_conn_state_evt +
    • >>   app_handle_conn_param_update_evt +
    • >>   le_vendor_set_priority +
    • >>   le_vendor_update_conn_param +
    • >>   le_vendor_drop_acl_data +
    + +

    le_get_conn_info (Thumb, 26 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_conn_addr (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_get_conn_addr +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    + +

    le_get_conn_id (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_active_link_num (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_idle_link_num (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_disconnect (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_disconnect +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   cust_ble_set_to_idle +
    • >>   cust_feature_disable +
    • >>   cust_connection_disconnect_this +
    • >>   fmna_connection_platform_disconnect +
    + +

    le_read_rssi (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_read_rssi +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_io_msg +
    • >>   app_profile_callback +
    + +

    le_set_data_len (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_disable_slave_latency (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_update_passed_chann_map (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_update_conn_param (Thumb, 42 bytes, Stack size 48 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_set_conn_tx_power (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_conn_local_addr (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_get_conn_local_addr +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    + +

    le_bond_set_param (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_bond_set_param +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_ble_platform_init +
    + +

    le_bond_get_param (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_pair (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_get_display_key (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_bond_get_display_key +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    le_bond_passkey_input_confirm (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_bond_passkey_input_confirm +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    le_bond_just_work_confirm (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_bond_just_work_confirm +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    le_bond_passkey_display_confirm (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_bond_passkey_display_confirm +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_gap_msg +
    + +

    le_bond_user_confirm (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_cfg_local_key_distribute (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_clear_all_keys (Thumb, 12 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_delete_by_idx (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_bond_delete_by_idx +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_pm_delete_bonds +
    + +

    le_bond_delete_by_bd (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_get_sec_level (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_bond_get_pair_procedure_type (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_link_check_conn_id_internal (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   le_vendor_set_priority +
    • >>   le_vendor_update_conn_param +
    • >>   le_vendor_drop_acl_data +
    + +

    le_get_conn_id_by_handle (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_get_conn_id_by_handle +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_bt_direct_callback +
    • >>   le_handle_vendor_cmd_rsp +
    + +

    le_get_conn_handle (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_get_conn_handle +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_conn_state_evt +
    + +

    flash_save_local_name (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    flash_load_local_name (Thumb, 16 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    flash_save_local_appearance (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    flash_load_local_appearance (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    flash_save_local_irk (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    flash_load_local_irk (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_find_key_entry (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_find_key_entry_by_idx (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_find_key_entry_by_idx +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   cust_handle_connected_evt +
    • >>   app_gap_callback +
    • >>   app_handle_bond_modify_msg +
    • >>   app_handle_authen_state_evt +
    • >>   fmna_connection_set_active_ltk +
    + +

    le_get_bond_dev_num (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_get_bond_dev_num +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_pm_peer_count +
    + +

    le_get_low_priority_bond (Thumb, 16 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_high_priority_bond (Thumb, 16 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_set_high_priority_bond (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_resolve_random_address (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_cccd_data (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_find_key_entry_v2 (Thumb, 28 bytes, Stack size 24 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_set_high_priority_bond_v2 (Thumb, 32 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_set_high_priority_bond_v2 +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_handle_bond_modify_msg +
    • >>   app_handle_authen_state_evt +
    + +

    le_gen_bond_dev (Thumb, 40 bytes, Stack size 48 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_gen_bond_dev_v2 (Thumb, 46 bytes, Stack size 48 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_clear_cccd_data (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_dev_irk (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_get_dev_irk +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   cust_handle_connected_evt +
    + +

    le_get_max_le_paired_device_num (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_dev_bond_info_len (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_dev_bond_info (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_set_dev_bond_info (Thumb, 26 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_get_dev_info (Thumb, 26 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_get_dev_info +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   app_gap_callback +
    + +

    le_set_local_ltk (Thumb, 32 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = le_set_local_ltk +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   fmna_connection_set_active_ltk +
    + +

    le_privacy_check_resolvable_private_address (Thumb, 22 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_privacy_check_resolvable_private_address +
    +
    [Calls]
    • >>   SystemCall_Stack +
    +
    [Called By]
    • >>   cust_handle_connected_evt +
    + +

    le_dtm_receiver_test (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_dtm_transmitter_test (Thumb, 26 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    le_dtm_test_end (Thumb, 18 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gatt_register_callback (Thumb, 12 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gaps_set_parameter (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gaps_set_peripheral_preferred_conn_param (Thumb, 20 bytes, Stack size 8 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    gatts_service_changed_indicate (Thumb, 28 bytes, Stack size 16 bytes, gap_lib_system_call.o(.text), UNUSED) +

    [Calls]

    • >>   SystemCall_Stack +
    + +

    ADC_CalibrationInit (Thumb, 456 bytes, Stack size 40 bytes, adc_lib.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = ADC_CalibrationInit ⇒ ADC_GetKValue +
    +
    [Calls]
    • >>   flash_read_locked +
    • >>   ADC_GetKValue +
    +
    [Called By]
    • >>   bat_init_data +
    + +

    ADC_GetVoltage (Thumb, 132 bytes, Stack size 16 bytes, adc_lib.o(.text)) +

    [Stack]

    • Max Depth = 52
    • Call Chain = ADC_GetVoltage ⇒ ADC_GetKVoltage ⇒ __aeabi_fdiv +
    +
    [Calls]
    • >>   ADC_GetKVoltage +
    +
    [Called By]
    • >>   bat_update_battery_info +
    + +

    ADC_GetResistance (Thumb, 20 bytes, Stack size 0 bytes, adc_lib.o(.text), UNUSED) + +

    Timer4_Handler (Thumb, 40 bytes, Stack size 16 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = Timer4_Handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   TIM_Cmd +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • startup_rtl876x.o(VECTOR) +
    +

    fmna_main_task (Thumb, 84 bytes, Stack size 0 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 1392
    • Call Chain = fmna_main_task ⇒ fmna_crypto_roll_primary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_task_suspend +
    • >>   os_sem_give +
    • >>   os_sem_create +
    • >>   log_buffer +
    • >>   fmna_crypto_roll_primary_key +
    +
    [Address Reference Count : 1]
    • key_crypto.o(.text) +
    +

    fmna_task_init (Thumb, 26 bytes, Stack size 16 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = fmna_task_init +
    +
    [Calls]
    • >>   os_task_create +
    +
    [Called By]
    • >>   main +
    • >>   task_init +
    + +

    hw_timer_driver_init (Thumb, 76 bytes, Stack size 80 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 96
    • Call Chain = hw_timer_driver_init ⇒ RCC_PeriphClockCmd +
    +
    [Calls]
    • >>   RCC_PeriphClockCmd +
    • >>   NVIC_Init +
    • >>   TIM_INTConfig +
    • >>   TIM_StructInit +
    • >>   TIM_TimeBaseInit +
    +
    [Called By]
    • >>   driver_init +
    + +

    crypto_exit_dlps_config (Thumb, 46 bytes, Stack size 8 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = crypto_exit_dlps_config +
    +
    [Calls]
    • >>   os_task_resume +
    • >>   log_buffer +
    • >>   TIM_Cmd +
    +
    [Called By]
    • >>   io_dlps_exit_cb +
    + +

    crypto_enter_dlps_config (Thumb, 30 bytes, Stack size 8 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = crypto_enter_dlps_config +
    +
    [Calls]
    • >>   os_task_suspend +
    • >>   log_buffer +
    +
    [Called By]
    • >>   app_handle_io_msg +
    + +

    fmna_rotate_key_internal (Thumb, 66 bytes, Stack size 8 bytes, key_crypto.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = fmna_rotate_key_internal +
    +
    [Calls]
    • >>   os_task_resume +
    • >>   os_task_suspend +
    • >>   os_sem_take +
    • >>   log_buffer +
    +
    [Called By]
    • >>   fmna_state_machine_clear_keys +
    • >>   fmna_rotate_key +
    + +

    gap_register_vendor_cb (Thumb, 6 bytes, Stack size 0 bytes, gap_vendor_cmd.o(.text), UNUSED) + +

    gap_set_lps_bootup_active_time (Thumb, 42 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    lps_get_wakeup_time (Thumb, 14 bytes, Stack size 12 bytes, gap_vendor_cmd.o(.text), UNUSED) + +

    le_vendor_adv_3_data_enable (Thumb, 36 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_adv_3_data_set (Thumb, 98 bytes, Stack size 48 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_drop_acl_data (Thumb, 92 bytes, Stack size 32 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   le_get_conn_param +
    • >>   le_link_check_conn_id_internal +
    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_update_conn_param (Thumb, 102 bytes, Stack size 40 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   le_get_conn_param +
    • >>   le_link_check_conn_id_internal +
    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_trigger_internal_32k_calibration (Thumb, 30 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    le_handle_vendor_cmd_rsp (Thumb, 370 bytes, Stack size 40 bytes, gap_vendor_cmd.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = le_handle_vendor_cmd_rsp ⇒ le_get_conn_id_by_handle +
    +
    [Calls]
    • >>   le_get_conn_id_by_handle +
    • >>   __ARM_common_switch8 +
    +
    [Called By]
    • >>   gap_lib_handle_btif_msg +
    + +

    gap_vendor_cmd_req (Thumb, 18 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    le_handle_vendor_evt_info (Thumb, 22 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = le_handle_vendor_evt_info +
    +
    [Called By]
    • >>   gap_lib_handle_btif_msg +
    + +

    le_vendor_modify_bt_le_fw_policy (Thumb, 58 bytes, Stack size 16 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_check_priority_level (Thumb, 12 bytes, Stack size 0 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Called By]

    • >>   le_vendor_set_priority +
    + +

    le_vendor_set_priority (Thumb, 378 bytes, Stack size 72 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memclr4 +
    • >>   le_get_conn_param +
    • >>   le_vendor_check_priority_level +
    • >>   le_link_check_conn_id_internal +
    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_more_precise_32k_option (Thumb, 42 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    le_vendor_measure_master_clk_freq_mode (Thumb, 42 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    gap_vendor_set_ant_ctrl (Thumb, 68 bytes, Stack size 32 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   btif_vendor_cmd_req +
    + +

    gap_vendor_read_thermal_meter_data (Thumb, 24 bytes, Stack size 8 bytes, gap_vendor_cmd.o(.text), UNUSED) +

    [Calls]

    • >>   btif_vendor_cmd_req +
    + +

    vsnprintf (Thumb, 50 bytes, Stack size 24 bytes, vsnprintf.o(.text)) +

    [Stack]

    • Max Depth = 120 + Unknown Stack Size +
    • Call Chain = vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   _sputc +
    • >>   _printf_char_common +
    +
    [Called By]
    • >>   log_direct_app +
    + +

    srand (Thumb, 44 bytes, Stack size 12 bytes, rand.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = srand +
    +
    [Called By]
    • >>   main +
    • >>   _rand_init +
    + +

    _rand_init (Thumb, 4 bytes, Stack size 0 bytes, rand.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = _rand_init ⇒ srand +
    +
    [Calls]
    • >>   srand +
    +
    [Called By]
    • >>   __rt_lib_init_rand_2 +
    + +

    __aeabi_memmove4 (Thumb, 70 bytes, Stack size 16 bytes, rt_memmove.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy4 +
    +
    [Called By]
    • >>   __aeabi_memmove +
    + +

    __aeabi_memmove8 (Thumb, 0 bytes, Stack size 16 bytes, rt_memmove.o(.text), UNUSED) + +

    __aeabi_memmove (Thumb, 80 bytes, Stack size 24 bytes, rt_memmove.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_memcpy +
    • >>   __aeabi_memmove4 +
    +
    [Called By]
    • >>   mbedtls_mpi_write_string +
    + +

    __rt_memmove (Thumb, 0 bytes, Stack size 24 bytes, rt_memmove.o(.text), UNUSED) + +

    memset (Thumb, 28 bytes, Stack size 8 bytes, memset.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = memset +
    +
    [Calls]
    • >>   _memset +
    +
    [Address Reference Count : 1]
    • platform_util.o(.data) +
    +

    strcmp (Thumb, 160 bytes, Stack size 16 bytes, strcmpv6m.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = strcmp +
    +
    [Called By]
    • >>   mbedtls_ecp_curve_info_from_name +
    • >>   mbedtls_cipher_info_from_string +
    • >>   mbedtls_md_info_from_string +
    • >>   _get_lc_ctype +
    • >>   _get_lc_numeric +
    + +

    __aeabi_uidiv (Thumb, 0 bytes, Stack size 0 bytes, aeabi_sdivfast.o(.text), UNUSED) + +

    __aeabi_uidivmod (Thumb, 28 bytes, Stack size 0 bytes, aeabi_sdivfast.o(.text)) +

    [Called By]

    • >>   common_main +
    • >>   I2C_Init +
    • >>   TIM_PWMChangeFreqAndDuty +
    • >>   TIM_CmdSafe +
    • >>   TIM_TimeBaseInit +
    • >>   cust_adv_update_device_name +
    • >>   update_single_id +
    • >>   generate_random_id +
    • >>   one_shot_adv_set_param +
    • >>   fmna_update_secondary_index +
    • >>   buzzer_init +
    • >>   gap_sched_adv_random_delay +
    • >>   ecp_precompute_comb +
    • >>   ecp_mul_comb +
    • >>   mbedtls_cipher_update +
    • >>   mbedtls_mpi_write_string +
    • >>   mbedtls_mpi_mod_int +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_base64_encode +
    • >>   mbedtls_aes_setkey_enc +
    + +

    __aeabi_idiv (Thumb, 0 bytes, Stack size 8 bytes, aeabi_sdivfast.o(.text), UNUSED) + +

    __aeabi_idivmod (Thumb, 460 bytes, Stack size 8 bytes, aeabi_sdivfast.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = __aeabi_idivmod +
    +
    [Called By]
    • >>   bat_update_battery_info +
    • >>   app_gap_callback +
    • >>   _btod_etento +
    • >>   _printf_fp_hex_real +
    + +

    __aeabi_d2f (Thumb, 0 bytes, Stack size 12 bytes, d2f.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = __aeabi_d2f +
    +
    [Called By]
    • >>   bat_update_battery_info +
    + +

    _d2f (Thumb, 120 bytes, Stack size 12 bytes, d2f.o(.text), UNUSED) + +

    __aeabi_dadd (Thumb, 0 bytes, Stack size 8 bytes, daddsub.o(.text), UNUSED) + +

    _dadd (Thumb, 26 bytes, Stack size 8 bytes, daddsub.o(.text), UNUSED) +

    [Calls]

    • >>   _dsub1 +
    • >>   _dadd1 +
    + +

    __aeabi_dsub (Thumb, 0 bytes, Stack size 8 bytes, daddsub.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = __aeabi_dsub +
    +
    [Called By]
    • >>   bat_update_battery_info +
    + +

    _dsub (Thumb, 22 bytes, Stack size 8 bytes, daddsub.o(.text), UNUSED) +

    [Calls]

    • >>   _dsub1 +
    • >>   _dadd1 +
    + +

    __aeabi_drsub (Thumb, 0 bytes, Stack size 16 bytes, daddsub.o(.text), UNUSED) + +

    _drsb (Thumb, 28 bytes, Stack size 16 bytes, daddsub.o(.text), UNUSED) +

    [Calls]

    • >>   _dsub1 +
    • >>   _dadd1 +
    + +

    __aeabi_d2uiz (Thumb, 0 bytes, Stack size 8 bytes, dfixui.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = __aeabi_d2uiz +
    +
    [Called By]
    • >>   fmble_gap_adv_start +
    + +

    _dfixu (Thumb, 68 bytes, Stack size 8 bytes, dfixui.o(.text), UNUSED) + +

    __aeabi_i2d_normalise (Thumb, 66 bytes, Stack size 0 bytes, dflti.o(.text)) +

    [Called By]

    • >>   __aeabi_ui2d +
    • >>   __aeabi_i2d +
    + +

    __aeabi_i2d (Thumb, 16 bytes, Stack size 0 bytes, dflti.o(.text)) +

    [Calls]

    • >>   __aeabi_i2d_normalise +
    +
    [Called By]
    • >>   bat_update_battery_info +
    + +

    _dflt (Thumb, 0 bytes, Stack size 0 bytes, dflti.o(.text), UNUSED) + +

    __aeabi_ui2d (Thumb, 6 bytes, Stack size 0 bytes, dflti.o(.text)) +

    [Calls]

    • >>   __aeabi_i2d_normalise +
    +
    [Called By]
    • >>   fmble_gap_adv_start +
    + +

    _dfltu (Thumb, 0 bytes, Stack size 0 bytes, dflti.o(.text), UNUSED) + +

    __aeabi_dmul (Thumb, 0 bytes, Stack size 56 bytes, dmul.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = __aeabi_dmul +
    +
    [Called By]
    • >>   fmble_gap_adv_start +
    + +

    _dmul (Thumb, 558 bytes, Stack size 56 bytes, dmul.o(.text), UNUSED) + +

    __aeabi_fdiv (Thumb, 0 bytes, Stack size 20 bytes, fdiv.o(.text)) +

    [Stack]

    • Max Depth = 20
    • Call Chain = __aeabi_fdiv +
    +
    [Called By]
    • >>   ADC_GetKVoltage +
    + +

    _fdiv (Thumb, 334 bytes, Stack size 20 bytes, fdiv.o(.text), UNUSED) +

    [Called By]

    • >>   _frdiv +
    + +

    _frdiv (Thumb, 8 bytes, Stack size 0 bytes, fdiv.o(.text), UNUSED) +

    [Calls]

    • >>   _fdiv +
    + +

    __aeabi_f2uiz (Thumb, 0 bytes, Stack size 0 bytes, ffixui.o(.text)) +

    [Called By]

    • >>   bat_update_battery_info +
    + +

    _ffixu (Thumb, 48 bytes, Stack size 0 bytes, ffixui.o(.text), UNUSED) + +

    __aeabi_i2f_normalise (Thumb, 72 bytes, Stack size 0 bytes, fflti.o(.text)) +

    [Called By]

    • >>   __aeabi_ui2f +
    • >>   __aeabi_i2f +
    + +

    __aeabi_i2f (Thumb, 16 bytes, Stack size 0 bytes, fflti.o(.text)) +

    [Calls]

    • >>   __aeabi_i2f_normalise +
    +
    [Called By]
    • >>   ADC_GetKVoltage +
    + +

    _fflt (Thumb, 0 bytes, Stack size 0 bytes, fflti.o(.text), UNUSED) + +

    __aeabi_ui2f (Thumb, 6 bytes, Stack size 0 bytes, fflti.o(.text), UNUSED) +

    [Calls]

    • >>   __aeabi_i2f_normalise +
    + +

    _ffltu (Thumb, 0 bytes, Stack size 0 bytes, fflti.o(.text), UNUSED) + +

    _printf_pre_padding (Thumb, 44 bytes, Stack size 16 bytes, _printf_pad.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = _printf_pre_padding +
    +
    [Called By]
    • >>   _printf_str +
    • >>   _printf_fp_infnan +
    • >>   _printf_fp_hex_real +
    • >>   _printf_fp_dec_real +
    • >>   _printf_int_common +
    • >>   _printf_wctomb +
    + +

    _printf_post_padding (Thumb, 34 bytes, Stack size 16 bytes, _printf_pad.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = _printf_post_padding +
    +
    [Called By]
    • >>   _printf_str +
    • >>   _printf_fp_infnan +
    • >>   _printf_fp_hex_real +
    • >>   _printf_fp_dec_real +
    • >>   _printf_int_common +
    • >>   _printf_wctomb +
    + +

    _printf_truncate_signed (Thumb, 18 bytes, Stack size 0 bytes, _printf_truncate.o(.text)) +

    [Called By]

    • >>   _printf_int_dec +
    + +

    _printf_truncate_unsigned (Thumb, 18 bytes, Stack size 0 bytes, _printf_truncate.o(.text)) +

    [Called By]

    • >>   _printf_int_dec +
    • >>   _printf_int_hex +
    • >>   _printf_int_oct +
    + +

    _printf_str (Thumb, 82 bytes, Stack size 16 bytes, _printf_str.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = _printf_str ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    +
    [Called By]
    • >>   _printf_cs_common +
    + +

    _printf_int_dec (Thumb, 90 bytes, Stack size 32 bytes, _printf_dec.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_int_dec ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_truncate_unsigned +
    • >>   _printf_truncate_signed +
    • >>   __rt_udiv10 +
    • >>   _printf_int_common +
    +
    [Called By]
    • >>   _printf_u +
    • >>   _printf_d +
    • >>   _printf_i +
    + +

    _printf_charcount (Thumb, 38 bytes, Stack size 0 bytes, _printf_charcount.o(.text)) +

    [Called By]

    • >>   _printf_n +
    + +

    _printf_char_common (Thumb, 32 bytes, Stack size 64 bytes, _printf_char_common.o(.text)) +

    [Stack]

    • Max Depth = 96 + Unknown Stack Size +
    • Call Chain = _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   __printf +
    +
    [Called By]
    • >>   vsnprintf +
    + +

    _sputc (Thumb, 10 bytes, Stack size 0 bytes, _sputc.o(.text)) +

    [Called By]

    • >>   vsnprintf +
    + +

    _snputc (Thumb, 16 bytes, Stack size 0 bytes, _snputc.o(.text)) +
    [Address Reference Count : 1]

    • vsnprintf.o(.text) +
    +

    _printf_wctomb (Thumb, 182 bytes, Stack size 56 bytes, _printf_wctomb.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    • >>   _wcrtomb +
    +
    [Called By]
    • >>   _printf_lcs_common +
    + +

    _printf_longlong_dec (Thumb, 94 bytes, Stack size 32 bytes, _printf_longlong_dec.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_longlong_dec ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_common +
    • >>   _ll_udiv10 +
    +
    [Called By]
    • >>   _printf_llu +
    • >>   _printf_lld +
    • >>   _printf_lli +
    + +

    _printf_longlong_oct (Thumb, 68 bytes, Stack size 16 bytes, _printf_oct_int_ll.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = _printf_longlong_oct ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_common +
    +
    [Called By]
    • >>   _printf_ll_oct +
    • >>   _printf_int_oct +
    + +

    _printf_int_oct (Thumb, 24 bytes, Stack size 8 bytes, _printf_oct_int_ll.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = _printf_int_oct ⇒ _printf_longlong_oct ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_truncate_unsigned +
    • >>   _printf_longlong_oct +
    +
    [Called By]
    • >>   _printf_o +
    + +

    _printf_ll_oct (Thumb, 10 bytes, Stack size 0 bytes, _printf_oct_int_ll.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = _printf_ll_oct ⇒ _printf_longlong_oct ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_longlong_oct +
    +
    [Called By]
    • >>   _printf_llo +
    + +

    _printf_longlong_hex (Thumb, 88 bytes, Stack size 24 bytes, _printf_hex_int_ll_ptr.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_int_common +
    +
    [Called By]
    • >>   _printf_hex_ptr +
    • >>   _printf_ll_hex +
    • >>   _printf_int_hex +
    + +

    _printf_int_hex (Thumb, 28 bytes, Stack size 16 bytes, _printf_hex_int_ll_ptr.o(.text)) +

    [Stack]

    • Max Depth = 96
    • Call Chain = _printf_int_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_truncate_unsigned +
    • >>   _printf_longlong_hex +
    +
    [Called By]
    • >>   _printf_x +
    + +

    _printf_ll_hex (Thumb, 10 bytes, Stack size 0 bytes, _printf_hex_int_ll_ptr.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = _printf_ll_hex ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_longlong_hex +
    +
    [Called By]
    • >>   _printf_llx +
    + +

    _printf_hex_ptr (Thumb, 22 bytes, Stack size 8 bytes, _printf_hex_int_ll_ptr.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_hex_ptr ⇒ _printf_longlong_hex ⇒ _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_longlong_hex +
    +
    [Called By]
    • >>   _printf_p +
    + +

    __printf (Thumb, 386 bytes, Stack size 32 bytes, __printf_flags_ss_wp.o(.text)) +

    [Stack]

    • Max Depth = 32 + Unknown Stack Size +
    • Call Chain = __printf +
    +
    [Calls]
    • >>   _printf_percent +
    • >>   _is_digit +
    +
    [Called By]
    • >>   _printf_char_common +
    + +

    _ll_udiv10 (Thumb, 122 bytes, Stack size 16 bytes, lludiv10.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = _ll_udiv10 +
    +
    [Called By]
    • >>   _fp_digits +
    • >>   _printf_longlong_dec +
    + +

    _printf_int_common (Thumb, 176 bytes, Stack size 40 bytes, _printf_intcommon.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = _printf_int_common ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    +
    [Called By]
    • >>   _printf_int_dec +
    • >>   _printf_longlong_hex +
    • >>   _printf_longlong_oct +
    • >>   _printf_longlong_dec +
    + +

    __lib_sel_fp_printf (Thumb, 2 bytes, Stack size 0 bytes, _printf_fp_dec.o(.text), UNUSED) + +

    _printf_fp_dec_real (Thumb, 620 bytes, Stack size 96 bytes, _printf_fp_dec.o(.text)) +

    [Stack]

    • Max Depth = 368
    • Call Chain = _printf_fp_dec_real ⇒ _fp_digits ⇒ _btod_etento ⇒ _btod_emul ⇒ btod_internal_mul ⇒ __ARM_common_ll_muluu +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    • >>   __ARM_fpclassify +
    • >>   _printf_fp_infnan +
    • >>   __rt_locale +
    • >>   __rt_udiv10 +
    • >>   _fp_digits +
    +
    [Address Reference Count : 1]
    • printf1.o(x$fpl$printf1) +
    +

    _printf_fp_hex_real (Thumb, 718 bytes, Stack size 72 bytes, _printf_fp_hex.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = _printf_fp_hex_real ⇒ _printf_fp_infnan ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    • >>   __aeabi_idivmod +
    • >>   __ARM_fpclassify +
    • >>   _printf_fp_infnan +
    +
    [Address Reference Count : 1]
    • printf2.o(x$fpl$printf2) +
    +

    _printf_cs_common (Thumb, 22 bytes, Stack size 8 bytes, _printf_char.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = _printf_cs_common ⇒ _printf_str ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_str +
    • >>   _printf_mbtowc (Weak Reference) +
    +
    [Called By]
    • >>   _printf_string +
    • >>   _printf_char +
    + +

    _printf_char (Thumb, 16 bytes, Stack size 0 bytes, _printf_char.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = _printf_char ⇒ _printf_cs_common ⇒ _printf_str ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_cs_common +
    +
    [Called By]
    • >>   _printf_c +
    + +

    _printf_string (Thumb, 8 bytes, Stack size 0 bytes, _printf_char.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = _printf_string ⇒ _printf_cs_common ⇒ _printf_str ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_cs_common +
    +
    [Called By]
    • >>   _printf_s +
    + +

    _printf_lcs_common (Thumb, 22 bytes, Stack size 8 bytes, _printf_wchar.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_wc (Weak Reference) +
    • >>   _printf_wctomb +
    +
    [Called By]
    • >>   _printf_wstring +
    • >>   _printf_wchar +
    + +

    _printf_wchar (Thumb, 16 bytes, Stack size 0 bytes, _printf_wchar.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_wchar ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_lcs_common +
    +
    [Called By]
    • >>   _printf_lc +
    + +

    _printf_wstring (Thumb, 8 bytes, Stack size 0 bytes, _printf_wchar.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _printf_wstring ⇒ _printf_lcs_common ⇒ _printf_wctomb ⇒ _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   _printf_lcs_common +
    +
    [Called By]
    • >>   _printf_ls +
    + +

    _wcrtomb (Thumb, 64 bytes, Stack size 16 bytes, _wcrtomb.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = _wcrtomb ⇒ __rt_ctype_table +
    +
    [Calls]
    • >>   __rt_ctype_table +
    +
    [Called By]
    • >>   _printf_wctomb +
    + +

    __rt_udiv10 (Thumb, 40 bytes, Stack size 0 bytes, rtudiv10.o(.text)) +

    [Called By]

    • >>   _printf_int_dec +
    • >>   _printf_fp_dec_real +
    + +

    __rt_ctype_table (Thumb, 16 bytes, Stack size 8 bytes, rt_ctype_table.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = __rt_ctype_table +
    +
    [Calls]
    • >>   __rt_locale +
    +
    [Called By]
    • >>   _wcrtomb +
    + +

    __rt_locale (Thumb, 8 bytes, Stack size 0 bytes, rt_locale.o(.text)) +

    [Called By]

    • >>   __rt_ctype_table +
    • >>   _printf_fp_dec_real +
    • >>   __rt_lib_init_lc_common +
    + +

    _printf_fp_infnan (Thumb, 120 bytes, Stack size 24 bytes, _printf_fp_infnan.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = _printf_fp_infnan ⇒ _printf_post_padding +
    +
    [Calls]
    • >>   _printf_post_padding +
    • >>   _printf_pre_padding +
    +
    [Called By]
    • >>   _printf_fp_hex_real +
    • >>   _printf_fp_dec_real +
    + +

    _btod_etento (Thumb, 210 bytes, Stack size 72 bytes, bigflt0.o(.text)) +

    [Stack]

    • Max Depth = 176
    • Call Chain = _btod_etento ⇒ _btod_emul ⇒ btod_internal_mul ⇒ __ARM_common_ll_muluu +
    +
    [Calls]
    • >>   __aeabi_idivmod +
    • >>   _btod_ediv +
    • >>   _btod_emul +
    +
    [Called By]
    • >>   _fp_digits +
    + +

    _btod_d2e (Thumb, 64 bytes, Stack size 8 bytes, btod.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = _btod_d2e +
    +
    [Called By]
    • >>   _fp_digits +
    + +

    _btod_emul (Thumb, 28 bytes, Stack size 24 bytes, btod.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = _btod_emul ⇒ btod_internal_mul ⇒ __ARM_common_ll_muluu +
    +
    [Calls]
    • >>   btod_internal_mul +
    +
    [Called By]
    • >>   _btod_etento +
    • >>   _fp_digits +
    + +

    _btod_emuld (Thumb, 144 bytes, Stack size 56 bytes, btod.o(.text), UNUSED) +

    [Calls]

    • >>   btod_internal_mul +
    + +

    _btod_ediv (Thumb, 26 bytes, Stack size 24 bytes, btod.o(.text)) +

    [Stack]

    • Max Depth = 88
    • Call Chain = _btod_ediv ⇒ btod_internal_div +
    +
    [Calls]
    • >>   btod_internal_div +
    +
    [Called By]
    • >>   _btod_etento +
    • >>   _fp_digits +
    + +

    _btod_edivd (Thumb, 124 bytes, Stack size 56 bytes, btod.o(.text), UNUSED) +

    [Calls]

    • >>   btod_internal_div +
    + +

    __ARM_common_ll_muluu (Thumb, 48 bytes, Stack size 24 bytes, btod.o(i.__ARM_common_ll_muluu)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = __ARM_common_ll_muluu +
    +
    [Called By]
    • >>   mbedtls_gcm_setkey +
    • >>   btod_internal_mul +
    + +

    __ARM_common_memcpy1_6 (Thumb, 26 bytes, Stack size 0 bytes, custom_app.o(i.__ARM_common_memcpy1_6)) +

    [Called By]

    • >>   one_shot_bt_addr_set +
    • >>   read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data +
    • >>   fmna_adv_init_nearby +
    • >>   fmna_adv_init_separated +
    + +

    __ARM_common_memcpy1_8 (Thumb, 34 bytes, Stack size 0 bytes, overlay_mgr.o(i.__ARM_common_memcpy1_8)) +

    [Called By]

    • >>   load_overlay +
    • >>   fmna_adv_init_pairing +
    • >>   mbedtls_gcm_starts +
    + +

    __ARM_common_memcpy4_5 (Thumb, 10 bytes, Stack size 0 bytes, custom_app.o(i.__ARM_common_memcpy4_5)) +

    [Called By]

    • >>   cust_adv_update_device_name +
    + +

    __ARM_common_switch8 (Thumb, 26 bytes, Stack size 8 bytes, gap_vendor_cmd.o(i.__ARM_common_switch8)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = __ARM_common_switch8 +
    +
    [Called By]
    • >>   le_handle_vendor_cmd_rsp +
    + +

    __ARM_fpclassify (Thumb, 40 bytes, Stack size 0 bytes, fpclassify.o(i.__ARM_fpclassify)) +

    [Called By]

    • >>   _printf_fp_hex_real +
    • >>   _printf_fp_dec_real +
    + +

    _is_digit (Thumb, 14 bytes, Stack size 0 bytes, __printf_wp.o(i._is_digit)) +

    [Called By]

    • >>   __printf +
    + +

    _get_lc_numeric (Thumb, 44 bytes, Stack size 8 bytes, lc_numeric_c.o(locale$$code)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = _get_lc_numeric ⇒ strcmp +
    +
    [Calls]
    • >>   strcmp +
    +
    [Called By]
    • >>   __rt_lib_init_lc_numeric_2 +
    + +

    _get_lc_ctype (Thumb, 44 bytes, Stack size 8 bytes, lc_ctype_c.o(locale$$code)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = _get_lc_ctype ⇒ strcmp +
    +
    [Calls]
    • >>   strcmp +
    +
    [Called By]
    • >>   __rt_lib_init_lc_ctype_2 +
    +
    [Address Reference Count : 1]
    • rt_ctype_table.o(.text) +
    +

    __aeabi_fadd (Thumb, 0 bytes, Stack size 16 bytes, faddsub.o(x$fpl$fadd)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = __aeabi_fadd +
    +
    [Called By]
    • >>   ADC_GetKVoltage +
    + +

    _fadd (Thumb, 134 bytes, Stack size 16 bytes, faddsub.o(x$fpl$fadd), UNUSED) +

    [Calls]

    • >>   _fsub1 +
    + +

    __aeabi_fmul (Thumb, 0 bytes, Stack size 16 bytes, fmul.o(x$fpl$fmul)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = __aeabi_fmul +
    +
    [Called By]
    • >>   ADC_GetKVoltage +
    + +

    _fmul (Thumb, 172 bytes, Stack size 16 bytes, fmul.o(x$fpl$fmul), UNUSED) + +

    __aeabi_fsub (Thumb, 0 bytes, Stack size 16 bytes, faddsub.o(x$fpl$fsub), UNUSED) + +

    _fsub (Thumb, 204 bytes, Stack size 16 bytes, faddsub.o(x$fpl$fsub), UNUSED) +

    [Calls]

    • >>   _fadd1 +
    + +

    _printf_fp_dec (Thumb, 16 bytes, Stack size 8 bytes, printf1.o(x$fpl$printf1)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = _printf_fp_dec +
    +
    [Called By]
    • >>   _printf_g +
    • >>   _printf_e +
    • >>   _printf_f +
    + +

    _printf_fp_hex (Thumb, 16 bytes, Stack size 8 bytes, printf2.o(x$fpl$printf2)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = _printf_fp_hex +
    +
    [Called By]
    • >>   _printf_a +
    +

    +

    +Local Symbols +

    +

    AON_WDG_WriteReg (Thumb, 40 bytes, Stack size 12 bytes, rtl876x_aon_wdg.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = AON_WDG_WriteReg +
    +
    [Called By]
    • >>   AON_WDG_SystemReset +
    • >>   AON_WDG_Restart +
    • >>   AON_WDG_Disable +
    • >>   AON_WDG_Enable +
    • >>   AON_WDG_ConfigCntReload +
    • >>   AON_WDG_ConfigCntCtl +
    • >>   AON_WDG_ConfigComp +
    • >>   AON_WDG_ConfigResetLevel +
    • >>   AON_WDG_Config +
    + +

    handle_ten_click (Thumb, 88 bytes, Stack size 16 bytes, findmy_app.o(.text)) +

    [Stack]

    • Max Depth = 240
    • Call Chain = handle_ten_click ⇒ cust_factory_reset ⇒ cust_feature_disable ⇒ fmna_connection_set_max_connections ⇒ fmna_gatt_send_command_response ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   sdd_battery_level_value_notify +
    • >>   play_beep_mode +
    • >>   fmna_gatt_platform_get_gatt_data +
    • >>   custom_new_adv_stop +
    • >>   cust_get_conn_id +
    • >>   cust_factory_reset +
    +
    [Called By]
    • >>   app_handle_gpio_msg +
    • >>   double_click_detect_timer_cb +
    + +

    cust_adv_update_timer_callback (Thumb, 46 bytes, Stack size 16 bytes, custom_app.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = cust_adv_update_timer_callback ⇒ one_shot_bt_addr_set +
    +
    [Calls]
    • >>   trace_bdaddr +
    • >>   log_buffer +
    • >>   one_shot_bt_addr_set +
    • >>   le_gen_rand_addr +
    +
    [Address Reference Count : 1]
    • custom_app.o(.text) +
    +

    da213b_write_one_byte (Thumb, 76 bytes, Stack size 24 bytes, da213b.o(.text)) +

    [Stack]

    • Max Depth = 44
    • Call Chain = da213b_write_one_byte ⇒ I2C_MasterWrite +
    +
    [Calls]
    • >>   log_buffer +
    • >>   I2C_MasterWrite +
    +
    [Called By]
    • >>   da213b_deinit +
    • >>   da213b_init +
    • >>   da213b_check_motion_flag +
    + +

    da213b_read_one_byte (Thumb, 74 bytes, Stack size 24 bytes, da213b.o(.text)) +

    [Stack]

    • Max Depth = 52
    • Call Chain = da213b_read_one_byte ⇒ I2C_RepeatRead +
    +
    [Calls]
    • >>   log_buffer +
    • >>   I2C_RepeatRead +
    +
    [Called By]
    • >>   da213b_deinit +
    • >>   da213b_init +
    • >>   da213b_check_motion_flag +
    + +

    button_periodic_timer_cb (Thumb, 258 bytes, Stack size 24 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 312 + Unknown Stack Size +
    • Call Chain = button_periodic_timer_cb ⇒ fmna_factory_reset ⇒ log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   os_delay +
    • >>   log_buffer +
    • >>   fmna_sound_platform_stop +
    • >>   fmna_sound_platform_start +
    • >>   fmna_factory_reset +
    +
    [Address Reference Count : 1]
    • key_handle.o(.text) +
    +

    cust_button_int_handler (Thumb, 158 bytes, Stack size 32 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = cust_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO_GetPin +
    • >>   os_timer_stop +
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Called By]
    • >>   GPIO29_Handler +
    • >>   gpio_key_debounce_timeout_cb +
    + +

    trig_button_int_handler (Thumb, 208 bytes, Stack size 32 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 56
    • Call Chain = trig_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO_GetPin +
    • >>   os_timer_stop +
    • >>   os_timer_start +
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Called By]
    • >>   GPIO9_Handler +
    • >>   gpio_key_debounce_timeout_cb +
    + +

    gpio_key_debounce_timeout_cb (Thumb, 100 bytes, Stack size 24 bytes, key_handle.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = gpio_key_debounce_timeout_cb ⇒ trig_button_int_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   GPIO_GetPin +
    • >>   log_buffer +
    • >>   trig_button_int_handler +
    • >>   cust_button_int_handler +
    +
    [Address Reference Count : 1]
    • key_handle.o(.text) +
    +

    is_multi_status_bit_enabled (Thumb, 34 bytes, Stack size 0 bytes, fmna_connection.o(.text)) +

    [Called By]

    • >>   fmna_connection_send_multi_status +
    • >>   fmna_connection_is_status_bit_enabled +
    + +

    fmna_crypto_key_restore (Thumb, 476 bytes, Stack size 80 bytes, fmna_crypto.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = fmna_crypto_key_restore +
    +
    [Calls]
    • >>   ftl_load +
    • >>   trace_binary +
    • >>   trace_string +
    • >>   log_buffer +
    • >>   vAssertHandler +
    +
    [Called By]
    • >>   fmna_crypto_init +
    + +

    fmna_gatt_dispatch_send_next_packet_handler (Thumb, 8 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_gatt_dispatch_send_next_packet_handler ⇒ fmna_gatt_platform_send_next_indication ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   fmna_gatt_platform_send_next_indication +
    +
    [Address Reference Count : 1]
    • fmna_gatt.o(.text) +
    +

    fmna_gatt_dispatch_send_packet_extension_indication_handler (Thumb, 20 bytes, Stack size 8 bytes, fmna_gatt.o(.text)) +

    [Stack]

    • Max Depth = 144
    • Call Chain = fmna_gatt_dispatch_send_packet_extension_indication_handler ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   fmna_gatt_platform_get_most_recent_conn_handle +
    • >>   fmna_gatt_send_indication_internal +
    +
    [Address Reference Count : 1]
    • fmna_gatt.o(.text) +
    +

    motion_backoff_timeout_handler (Thumb, 48 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = motion_backoff_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_motion_detection.o(.text) +
    +

    motion_active_poll_duration_timeout_sched_handler (Thumb, 84 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 152
    • Call Chain = motion_active_poll_duration_timeout_sched_handler ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_motion_detection_platform_deinit +
    • >>   app_timer_stop +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_motion_detection.o(.text) +
    +

    motion_active_poll_duration_timer_timeout_handler (Thumb, 24 bytes, Stack size 8 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = motion_active_poll_duration_timer_timeout_handler ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_sched_event_put +
    +
    [Address Reference Count : 1]
    • fmna_motion_detection.o(.text) +
    +

    motion_poll_timer_timeout_handler (Thumb, 48 bytes, Stack size 16 bytes, fmna_motion_detection.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = motion_poll_timer_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_motion_detection.o(.text) +
    +

    set_is_nearby (Thumb, 128 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 176
    • Call Chain = set_is_nearby ⇒ fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_timer_stop +
    • >>   app_timer_start +
    • >>   fmna_motion_detection_stop +
    +
    [Called By]
    • >>   fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler +
    • >>   fmna_generic_evt_bonded_handler +
    • >>   fmna_connected_evt_debug_reset_handler +
    • >>   fmna_connected_evt_timeout_handler +
    • >>   fmna_nearby_evt_timeout_handler +
    • >>   fmna_boot_evt_boot_handler +
    + +

    fmna_update_secondary_index (Thumb, 102 bytes, Stack size 32 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1424
    • Call Chain = fmna_update_secondary_index ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   fmna_rotate_key +
    • >>   dispatch_set_next_secondary_key_rotation_index_handler +
    • >>   fmna_boot_evt_boot_handler +
    + +

    dispatch_update_next_secondary_key_rotation_index (Thumb, 18 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +
    [Address Reference Count : 1]

    • fmna_state_machine.o(.text) +
    +

    fmna_persistent_connection_disconnection_timeout_handler (Thumb, 56 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_persistent_connection_disconnection_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    separated_ut_timeout_handler (Thumb, 48 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = separated_ut_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_pair_connection_timeout_handler (Thumb, 54 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_pair_connection_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    • >>   fmna_gatt_platform_get_most_recent_conn_handle +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_non_owner_1_connection_timeout_handler (Thumb, 232 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_non_owner_1_connection_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_non_owner_0_connection_timeout_handler (Thumb, 52 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_non_owner_0_connection_timeout_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_one_time_key_rotation_handler (Thumb, 96 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_one_time_key_rotation_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    dispatch_fmna_sm_event_handler (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = dispatch_fmna_sm_event_handler ⇒ fmna_evt_handler +
    +
    [Calls]
    • >>   fmna_evt_handler +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_nearby_separated_timeout_handler (Thumb, 26 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_nearby_separated_timeout_handler ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_boot_evt_boot_handler (Thumb, 168 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1448
    • Call Chain = fmna_boot_evt_boot_handler ⇒ fmna_update_secondary_index ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   fmna_connection_is_fmna_paired +
    • >>   fmna_log_serial_number +
    • >>   fmna_crypto_init +
    • >>   fmna_pm_delete_bonds +
    • >>   fmna_connection_set_active_ltk +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_separated +
    • >>   fmna_update_secondary_index +
    • >>   set_is_nearby +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_pair_evt_pair_handler (Thumb, 30 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_pair_evt_pair_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_init_pairing +
    • >>   fmna_adv_reset_bd_addr +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_pair_evt_disconnected_handler (Thumb, 294 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_pair_evt_disconnected_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_init_pairing +
    • >>   app_timer_stop +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_pair_evt_bonded_handler (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +
    [Address Reference Count : 1]

    • fmna_state_machine.o(.constdata) +
    +

    fmna_pair_evt_connected_handler (Thumb, 44 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = fmna_pair_evt_connected_handler ⇒ fmna_connection_disconnect_this ⇒ fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_disconnect_this +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_connected_handler (Thumb, 98 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_separated_evt_connected_handler ⇒ fmna_connection_disconnect_this ⇒ fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_disconnect_this +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_key_rotate_handler (Thumb, 50 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = fmna_separated_evt_key_rotate_handler ⇒ fmna_adv_platform_start_slow_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_separated +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_unbonded_handler (Thumb, 16 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_separated_evt_unbonded_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_init_pairing +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_motion_detected_handler (Thumb, 24 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = fmna_separated_evt_motion_detected_handler ⇒ app_sched_event_put +
    +
    [Calls]
    • >>   app_sched_event_put +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_sound_start_handler (Thumb, 26 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_separated_evt_sound_start_handler ⇒ fmna_sound_platform_start ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_sound_platform_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_generic_evt_sound_complete_handler (Thumb, 78 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 184
    • Call Chain = fmna_generic_evt_sound_complete_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_connection_update_connection_info_all +
    • >>   fmna_connection_get_conn_handle_with_multi_status_enabled +
    • >>   fmna_connection_is_status_bit_enabled +
    +
    [Address Reference Count : 3]
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    +

    fmna_separated_evt_sound_complete_handler (Thumb, 98 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 184
    • Call Chain = fmna_separated_evt_sound_complete_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_connection_update_connection_info_all +
    • >>   fmna_connection_get_conn_handle_with_multi_status_enabled +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_motion_detection_start_active_polling +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_nearby_evt_connected_handler (Thumb, 98 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_nearby_evt_connected_handler ⇒ fmna_connection_disconnect_this ⇒ fmna_connection_platform_disconnect ⇒ le_disconnect +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_disconnect_this +
    • >>   app_timer_start +
    +
    [Address Reference Count : 2]
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    +

    fmna_nearby_evt_key_rotate_handler (Thumb, 18 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_nearby_evt_key_rotate_handler ⇒ fmna_adv_platform_start_slow_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_nearby_evt_timeout_handler (Thumb, 56 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 192
    • Call Chain = fmna_nearby_evt_timeout_handler ⇒ set_is_nearby ⇒ fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_separated +
    • >>   set_is_nearby +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_key_rotate_handler (Thumb, 76 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 184
    • Call Chain = fmna_connected_evt_key_rotate_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   fmna_gatt_send_indication +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_connection_get_max_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_unbonded_handler (Thumb, 6 bytes, Stack size 0 bytes, fmna_state_machine.o(.text)) +
    [Address Reference Count : 1]

    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_disconnected_handler (Thumb, 110 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 960
    • Call Chain = fmna_connected_evt_disconnected_handler ⇒ fmna_generic_evt_disconnected_handler ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_generic_evt_disconnected_handler +
    • >>   app_timer_stop +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_timeout_handler (Thumb, 66 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_connected_evt_timeout_handler ⇒ set_is_nearby ⇒ fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   set_is_nearby +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_generic_evt_sound_start_handler (Thumb, 20 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_generic_evt_sound_start_handler ⇒ fmna_sound_platform_start ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_sound_platform_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_sound_stop_handler (Thumb, 14 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_connected_evt_sound_stop_handler ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   fmna_sound_platform_stop +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_connected_evt_debug_reset_handler (Thumb, 66 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 184
    • Call Chain = fmna_connected_evt_debug_reset_handler ⇒ set_is_nearby ⇒ fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   os_delay +
    • >>   ftl_save +
    • >>   log_buffer +
    • >>   fmna_connection_disconnect_all +
    • >>   set_is_nearby +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler (Thumb, 228 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1888
    • Call Chain = fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler ⇒ fmna_crypto_generate_send_pairing_data_params ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_malloc +
    • >>   fmna_crypto_generate_send_pairing_data_params +
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_get_most_recent_conn_handle +
    • >>   fmna_connection_disconnect_this +
    • >>   app_timer_stop +
    +
    [Address Reference Count : 2]
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    +

    fmna_fmna_pair_evt_fmna_pairing_finalize_handler (Thumb, 62 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1888
    • Call Chain = fmna_fmna_pair_evt_fmna_pairing_finalize_handler ⇒ fmna_crypto_finalize_pairing ⇒ fm_crypto_encrypt_to_server ⇒ mbedtls_ecdh_compute_shared ⇒ mbedtls_ecp_mul_restartable ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_malloc +
    • >>   fmna_free +
    • >>   fmna_crypto_finalize_pairing +
    • >>   fmna_connection_disconnect_this +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler (Thumb, 44 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 176
    • Call Chain = fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler ⇒ fmna_gatt_send_indication ⇒ fmna_gatt_send_indication_internal ⇒ fmna_gatt_platform_send_indication ⇒ server_send_data +
    +
    [Calls]
    • >>   fmna_gatt_send_indication +
    • >>   fmna_gatt_get_most_recent_conn_handle +
    • >>   fmna_connection_disconnect_this +
    • >>   fmna_connection_mfi_token_stored +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_generic_evt_bonded_handler (Thumb, 160 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 200
    • Call Chain = fmna_generic_evt_bonded_handler ⇒ set_is_nearby ⇒ fmna_motion_detection_stop ⇒ fmna_motion_detection_platform_deinit ⇒ da213b_deinit ⇒ fmna_sound_platform_stop ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_connection_get_num_connections +
    • >>   fmna_connection_get_max_connections +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    • >>   set_is_nearby +
    • >>   app_timer_stop +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_fmna_pair_evt_disconnected_handler (Thumb, 20 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 952
    • Call Chain = fmna_fmna_pair_evt_disconnected_handler ⇒ fmna_generic_evt_disconnected_handler ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   fmna_all_pairing_buf_free +
    • >>   fmna_generic_evt_disconnected_handler +
    +
    [Address Reference Count : 3]
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    • fmna_state_machine.o(.constdata) +
    +

    fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler (Thumb, 176 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 1416
    • Call Chain = fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler ⇒ fmna_crypto_roll_secondary_key ⇒ fm_crypto_derive_primary_or_secondary_x ⇒ mbedtls_ecp_muladd ⇒ mbedtls_ecp_muladd_restartable ⇒ mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   trace_string +
    • >>   log_buffer +
    • >>   vAssertHandler +
    • >>   cust_adv_update_device_name +
    • >>   fmna_connection_set_is_fmna_paired +
    • >>   fmna_crypto_roll_secondary_key +
    • >>   fmna_primary_key_update +
    • >>   fmna_crypto_roll_primary_key +
    • >>   fmna_crypto_roll_secondary_sk +
    • >>   fmna_crypto_roll_primary_sk +
    • >>   fmna_crypto_pairing_complete +
    • >>   set_is_nearby +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_disconnecting_evt_nearby_handler (Thumb, 104 bytes, Stack size 24 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 128
    • Call Chain = fmna_disconnecting_evt_nearby_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_gatt_reset_queues +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_connection_is_status_bit_enabled +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_nearby +
    • >>   app_timer_start +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_disconnecting_evt_separated_handler (Thumb, 72 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 120
    • Call Chain = fmna_disconnecting_evt_separated_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   fmna_gatt_reset_queues +
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_platform_start_slow_adv +
    • >>   fmna_adv_init_separated +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_disconnecting_evt_pair_handler (Thumb, 16 bytes, Stack size 8 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 112
    • Call Chain = fmna_disconnecting_evt_pair_handler ⇒ fmna_adv_platform_start_fast_adv ⇒ fmble_gap_adv_start ⇒ __aeabi_dmul +
    +
    [Calls]
    • >>   fmna_adv_platform_start_fast_adv +
    • >>   fmna_adv_init_pairing +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.constdata) +
    +

    fmna_key_rotation_handler (Thumb, 38 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = fmna_key_rotation_handler ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_state_machine.o(.text) +
    +

    fmna_generic_evt_disconnected_handler (Thumb, 120 bytes, Stack size 16 bytes, fmna_state_machine.o(.text)) +

    [Stack]

    • Max Depth = 936
    • Call Chain = fmna_generic_evt_disconnected_handler ⇒ fmna_connection_fmna_unpair ⇒ fmna_crypto_unpair ⇒ fm_crypto_ckg_init ⇒ mbedtls_ecp_gen_keypair ⇒ mbedtls_ecp_gen_keypair_base ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   fmna_connection_is_fmna_paired +
    • >>   app_sched_event_put +
    • >>   fmna_connection_get_unpair_pending +
    • >>   fmna_connection_fmna_unpair +
    • >>   fmna_connection_set_unpair_pending +
    • >>   fmna_pm_peer_count +
    +
    [Called By]
    • >>   fmna_fmna_pair_evt_disconnected_handler +
    • >>   fmna_connected_evt_disconnected_handler +
    + +

    findmy_adv_timer_callback (Thumb, 38 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = findmy_adv_timer_callback ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_gap_platform.o(.text) +
    +

    customized_adv_timer_callback (Thumb, 38 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = customized_adv_timer_callback ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_gap_platform.o(.text) +
    +

    custom_new_adv_timer_callback (Thumb, 38 bytes, Stack size 16 bytes, fmna_gap_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = custom_new_adv_timer_callback ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_gap_platform.o(.text) +
    +

    app_bt_direct_callback (Thumb, 54 bytes, Stack size 32 bytes, fmna_gatt_platform.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = app_bt_direct_callback ⇒ le_get_conn_id_by_handle +
    +
    [Calls]
    • >>   log_buffer +
    • >>   le_get_conn_id_by_handle +
    +
    [Address Reference Count : 1]
    • fmna_gatt_platform.o(.text) +
    +

    buzzer_init (Thumb, 152 bytes, Stack size 32 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   Pad_Config +
    • >>   Pinmux_Config +
    • >>   TIM_PWMChangeFreqAndDuty +
    • >>   TIM_Cmd +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   fmna_sound_platform_stop +
    • >>   fmna_sound_platform_start +
    • >>   beep_stop +
    • >>   fmna_sound_timeout_handler +
    • >>   beep_sequence_handler +
    + +

    beep_sequence_handler (Thumb, 144 bytes, Stack size 24 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 96
    • Call Chain = beep_sequence_handler ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   os_delay +
    • >>   log_buffer +
    • >>   app_timer_start +
    • >>   buzzer_init +
    +
    [Called By]
    • >>   play_beep_mode +
    +
    [Address Reference Count : 1]
    • fmna_sound_platform.o(.text) +
    +

    fmna_sound_timeout_handler (Thumb, 70 bytes, Stack size 8 bytes, fmna_sound_platform.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = fmna_sound_timeout_handler ⇒ buzzer_init ⇒ Pad_Config +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_state_machine_dispatch_event +
    • >>   buzzer_init +
    +
    [Address Reference Count : 1]
    • fmna_sound_platform.o(.text) +
    +

    aon_watch_dog_wake_up_dlps_callback (Thumb, 40 bytes, Stack size 16 bytes, fmna_timer_platform.o(.app.data_ram.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = aon_watch_dog_wake_up_dlps_callback ⇒ app_send_msg_to_apptask +
    +
    [Calls]
    • >>   log_buffer +
    • >>   app_send_msg_to_apptask +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    sn_lookup_callback (Thumb, 26 bytes, Stack size 8 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 32
    • Call Chain = sn_lookup_callback ⇒ fmna_free +
    +
    [Calls]
    • >>   log_buffer +
    • >>   fmna_free +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    unpair_pending_callback (Thumb, 16 bytes, Stack size 8 bytes, fmna_timer_platform.o(.text)) +

    [Stack]

    • Max Depth = 296 + Unknown Stack Size +
    • Call Chain = unpair_pending_callback ⇒ fmna_factory_reset ⇒ log_direct_app ⇒ vsnprintf ⇒ _printf_char_common ⇒ __printf +
    +
    [Calls]
    • >>   fmna_factory_reset +
    • >>   fmna_connection_get_unpair_pending +
    +
    [Address Reference Count : 1]
    • fmna_timer_platform.o(.text) +
    +

    _fm_crypto_scmult_reduce (Thumb, 134 bytes, Stack size 48 bytes, fm-crypto.o(.text)) +

    [Stack]

    • Max Depth = 880
    • Call Chain = _fm_crypto_scmult_reduce ⇒ mbedtls_ecp_mul ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_sub_int +
    • >>   mbedtls_mpi_read_binary +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_mpi_add_int +
    • >>   mbedtls_ecp_mul +
    +
    [Called By]
    • >>   fm_crypto_derive_primary_or_secondary_x +
    + +

    asn1_get_sequence_of_cb (Thumb, 64 bytes, Stack size 40 bytes, asn1parse.o(.text)) +

    [Stack]

    • Max Depth = 40
    • Call Chain = asn1_get_sequence_of_cb +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    +
    [Address Reference Count : 1]
    • asn1parse.o(.text) +
    +

    asn1_get_tagged_int (Thumb, 124 bytes, Stack size 16 bytes, asn1parse.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_get_tag +
    +
    [Called By]
    • >>   mbedtls_asn1_get_enum +
    • >>   mbedtls_asn1_get_int +
    + +

    mbedtls_asn1_write_len_and_tag (Thumb, 100 bytes, Stack size 16 bytes, asn1write.o(.text), UNUSED) +

    [Called By]

    • >>   mbedtls_asn1_write_octet_string +
    • >>   mbedtls_asn1_write_bitstring +
    • >>   mbedtls_asn1_write_tagged_string +
    • >>   mbedtls_asn1_write_bool +
    • >>   mbedtls_asn1_write_algorithm_identifier_ext +
    • >>   mbedtls_asn1_write_oid +
    • >>   mbedtls_asn1_write_null +
    • >>   mbedtls_asn1_write_mpi +
    • >>   asn1_write_tagged_int +
    + +

    asn1_write_tagged_int (Thumb, 68 bytes, Stack size 24 bytes, asn1write.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_asn1_write_len_and_tag +
    +
    [Called By]
    • >>   mbedtls_asn1_write_enum +
    • >>   mbedtls_asn1_write_int +
    + +

    mbedtls_ct_base64_enc_char (Thumb, 90 bytes, Stack size 16 bytes, base64.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ct_uchar_in_range_if +
    +
    [Called By]
    • >>   mbedtls_base64_encode +
    + +

    mbedtls_ct_uchar_in_range_if (Thumb, 34 bytes, Stack size 8 bytes, base64.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = mbedtls_ct_uchar_in_range_if +
    +
    [Called By]
    • >>   mbedtls_base64_decode +
    • >>   mbedtls_ct_base64_enc_char +
    + +

    mpi_select (Thumb, 172 bytes, Stack size 40 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = mpi_select ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_core_cond_assign +
    • >>   mbedtls_mpi_grow +
    +
    [Called By]
    • >>   mbedtls_mpi_exp_mod +
    + +

    mbedtls_mpi_resize_clear (Thumb, 52 bytes, Stack size 16 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = mbedtls_mpi_resize_clear ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr4 +
    • >>   mbedtls_mpi_grow +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   mbedtls_mpi_random +
    • >>   mbedtls_mpi_fill_random +
    • >>   mbedtls_mpi_read_binary_le +
    • >>   mbedtls_mpi_read_binary +
    + +

    add_sub_mpi (Thumb, 96 bytes, Stack size 24 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 104
    • Call Chain = add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_abs +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_add_abs +
    +
    [Called By]
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_exp_mod +
    • >>   mbedtls_mpi_read_string +
    • >>   mbedtls_mpi_div_mpi +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_add_mpi +
    • >>   mbedtls_mpi_sub_int +
    • >>   mbedtls_mpi_mod_mpi +
    • >>   mbedtls_mpi_add_int +
    + +

    mpi_montmul (Thumb, 36 bytes, Stack size 32 bytes, bignum.o(.text)) +

    [Stack]

    • Max Depth = 124
    • Call Chain = mpi_montmul ⇒ mbedtls_mpi_core_montmul ⇒ mbedtls_mpi_core_mla +
    +
    [Calls]
    • >>   mbedtls_mpi_core_montmul +
    +
    [Called By]
    • >>   mbedtls_mpi_exp_mod +
    + +

    mbedtls_ct_uint_lt (Thumb, 70 bytes, Stack size 4 bytes, bignum_core.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = mbedtls_ct_uint_lt +
    +
    [Called By]
    • >>   mbedtls_mpi_core_uint_le_mpi +
    • >>   mbedtls_mpi_core_random +
    + +

    gcm_ctx_alloc (Thumb, 28 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = gcm_ctx_alloc ⇒ mbedtls_gcm_init +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_gcm_init +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    gcm_ctx_free (Thumb, 16 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 24
    • Call Chain = gcm_ctx_free ⇒ mbedtls_gcm_free ⇒ mbedtls_cipher_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   mbedtls_gcm_free +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    aes_crypt_ecb_wrap (Thumb, 8 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = aes_crypt_ecb_wrap ⇒ mbedtls_aes_crypt_ecb ⇒ mbedtls_internal_aes_decrypt +
    +
    [Calls]
    • >>   mbedtls_aes_crypt_ecb +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    aes_setkey_dec_wrap (Thumb, 8 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 888
    • Call Chain = aes_setkey_dec_wrap ⇒ mbedtls_aes_setkey_dec ⇒ mbedtls_aes_setkey_enc +
    +
    [Calls]
    • >>   mbedtls_aes_setkey_dec +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    aes_setkey_enc_wrap (Thumb, 8 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 576
    • Call Chain = aes_setkey_enc_wrap ⇒ mbedtls_aes_setkey_enc +
    +
    [Calls]
    • >>   mbedtls_aes_setkey_enc +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    aes_ctx_alloc (Thumb, 28 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = aes_ctx_alloc ⇒ mbedtls_aes_init +
    +
    [Calls]
    • >>   os_mem_zalloc_intern +
    • >>   mbedtls_aes_init +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    aes_ctx_free (Thumb, 16 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 16
    • Call Chain = aes_ctx_free ⇒ mbedtls_aes_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   mbedtls_aes_free +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    gcm_aes_setkey_wrap (Thumb, 14 bytes, Stack size 8 bytes, cipher_wrap.o(.text)) +

    [Stack]

    • Max Depth = 224
    • Call Chain = gcm_aes_setkey_wrap ⇒ mbedtls_gcm_setkey ⇒ mbedtls_cipher_update ⇒ mbedtls_gcm_update ⇒ gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_gcm_setkey +
    +
    [Address Reference Count : 1]
    • cipher_wrap.o(.constdata) +
    +

    ecdh_gen_public_restartable (Thumb, 72 bytes, Stack size 48 bytes, ecdh.o(.text), UNUSED) +

    [Calls]

    • >>   mbedtls_ecp_mul_restartable +
    • >>   mbedtls_ecp_gen_privkey +
    +
    [Called By]
    • >>   mbedtls_ecdh_make_public +
    • >>   mbedtls_ecdh_make_params +
    • >>   mbedtls_ecdh_gen_public +
    + +

    mbedtls_mpi_mul_mod (Thumb, 168 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 280
    • Call Chain = mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_bitlen +
    • >>   mbedtls_mpi_mul_mpi +
    • >>   mbedtls_mpi_add_mpi +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_mod_mpi +
    +
    [Called By]
    • >>   ecp_randomize_jac +
    • >>   ecp_sw_rhs +
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    • >>   ecp_normalize_jac_many +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecp_check_pubkey +
    + +

    ecp_normalize_jac (Thumb, 134 bytes, Stack size 32 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 392
    • Call Chain = ecp_normalize_jac ⇒ mbedtls_mpi_inv_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_ecp_muladd_restartable +
    + +

    ecp_normalize_jac_many (Thumb, 432 bytes, Stack size 56 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 448
    • Call Chain = ecp_normalize_jac_many ⇒ ecp_normalize_jac ⇒ mbedtls_mpi_inv_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_inv_mod +
    • >>   mbedtls_mpi_shrink +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_precompute_comb +
    + +

    ecp_double_jac (Thumb, 592 bytes, Stack size 72 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 352
    • Call Chain = ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_shift_l_mod +
    • >>   mbedtls_mpi_sub_mod +
    • >>   mbedtls_mpi_add_mod +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_mul_int +
    • >>   mbedtls_mpi_sub_abs +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   ecp_add_mixed +
    + +

    ecp_add_mixed (Thumb, 498 bytes, Stack size 64 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 416
    • Call Chain = ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_shift_l_mod +
    • >>   mbedtls_mpi_sub_mod +
    • >>   ecp_double_jac +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_copy +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   mbedtls_ecp_muladd_restartable +
    + +

    ecp_select_comb (Thumb, 170 bytes, Stack size 48 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 160
    • Call Chain = ecp_select_comb ⇒ mbedtls_mpi_sub_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_safe_cond_assign +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    + +

    mbedtls_ecp_mul_shortcuts (Thumb, 232 bytes, Stack size 64 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 864
    • Call Chain = mbedtls_ecp_mul_shortcuts ⇒ ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_mul_restartable_internal +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_safe_cond_assign +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_lset +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_check_pubkey +
    +
    [Called By]
    • >>   mbedtls_ecp_muladd_restartable +
    + +

    ecp_restart_rsm_free (Thumb, 98 bytes, Stack size 24 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 48
    • Call Chain = ecp_restart_rsm_free ⇒ mbedtls_ecp_point_free ⇒ mbedtls_mpi_free ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   ecp_mul_comb +
    • >>   mbedtls_ecp_restart_free +
    + +

    mbedtls_mpi_add_mod (Thumb, 64 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 128
    • Call Chain = mbedtls_mpi_add_mod ⇒ mbedtls_mpi_add_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_add_mpi +
    • >>   mbedtls_mpi_sub_abs +
    +
    [Called By]
    • >>   ecp_sw_rhs +
    • >>   ecp_double_jac +
    + +

    ecp_sw_rhs (Thumb, 130 bytes, Stack size 24 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 304
    • Call Chain = ecp_sw_rhs ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_add_mod +
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_add_mpi +
    • >>   mbedtls_mpi_sub_int +
    +
    [Called By]
    • >>   mbedtls_ecp_point_read_binary +
    • >>   mbedtls_ecp_check_pubkey +
    + +

    mbedtls_mpi_sub_mod (Thumb, 62 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 128
    • Call Chain = mbedtls_mpi_sub_mod ⇒ mbedtls_mpi_sub_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_add_mpi +
    +
    [Called By]
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    + +

    mbedtls_mpi_shift_l_mod (Thumb, 60 bytes, Stack size 16 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 72
    • Call Chain = mbedtls_mpi_shift_l_mod ⇒ mbedtls_mpi_sub_abs ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_shift_l +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_sub_abs +
    +
    [Called By]
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    + +

    ecp_mul_restartable_internal (Thumb, 148 bytes, Stack size 48 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 800
    • Call Chain = ecp_mul_restartable_internal ⇒ ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_ecp_check_privkey +
    • >>   ecp_mul_comb +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_check_pubkey +
    +
    [Called By]
    • >>   mbedtls_ecp_mul_shortcuts +
    • >>   mbedtls_ecp_mul_restartable +
    • >>   mbedtls_ecp_mul +
    • >>   mbedtls_ecp_check_pub_priv +
    • >>   mbedtls_ecp_gen_keypair_base +
    + +

    ecp_mul_comb (Thumb, 558 bytes, Stack size 64 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 752
    • Call Chain = ecp_mul_comb ⇒ ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   os_mem_free +
    • >>   os_mem_zalloc_intern +
    • >>   ecp_mul_comb_after_precomp +
    • >>   ecp_precompute_comb +
    • >>   ecp_restart_rsm_free +
    • >>   mbedtls_mpi_cmp_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   ecp_mul_restartable_internal +
    + +

    ecp_precompute_comb (Thumb, 624 bytes, Stack size 104 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 552
    • Call Chain = ecp_precompute_comb ⇒ ecp_normalize_jac_many ⇒ ecp_normalize_jac ⇒ mbedtls_mpi_inv_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    • >>   ecp_normalize_jac_many +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   __aeabi_uidivmod +
    +
    [Called By]
    • >>   ecp_mul_comb +
    + +

    ecp_mul_comb_after_precomp (Thumb, 736 bytes, Stack size 272 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 688
    • Call Chain = ecp_mul_comb_after_precomp ⇒ ecp_add_mixed ⇒ ecp_double_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   __aeabi_memclr +
    • >>   ecp_randomize_jac +
    • >>   ecp_select_comb +
    • >>   ecp_add_mixed +
    • >>   ecp_double_jac +
    • >>   ecp_normalize_jac +
    • >>   mbedtls_ecp_check_budget +
    • >>   mbedtls_ecp_copy +
    • >>   mbedtls_mpi_cmp_int +
    • >>   mbedtls_mpi_get_bit +
    • >>   mbedtls_mpi_safe_cond_assign +
    • >>   mbedtls_mpi_sub_mpi +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    • >>   mbedtls_mpi_copy +
    • >>   mbedtls_ecp_point_init +
    • >>   mbedtls_ecp_point_free +
    +
    [Called By]
    • >>   ecp_mul_comb +
    + +

    ecp_randomize_jac (Thumb, 140 bytes, Stack size 40 bytes, ecp.o(.text)) +

    [Stack]

    • Max Depth = 320
    • Call Chain = ecp_randomize_jac ⇒ mbedtls_mpi_mul_mod ⇒ mbedtls_mpi_mod_mpi ⇒ mbedtls_mpi_div_mpi ⇒ add_sub_mpi ⇒ mbedtls_mpi_add_abs ⇒ mbedtls_mpi_copy ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_mul_mod +
    • >>   mbedtls_mpi_random +
    • >>   mbedtls_mpi_init +
    • >>   mbedtls_mpi_free +
    +
    [Called By]
    • >>   ecp_mul_comb_after_precomp +
    + +

    ecp_group_load (Thumb, 130 bytes, Stack size 24 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 36
    • Call Chain = ecp_group_load ⇒ mbedtls_mpi_bitlen ⇒ mbedtls_mpi_core_bitlen +
    +
    [Calls]
    • >>   mbedtls_mpi_bitlen +
    +
    [Called By]
    • >>   mbedtls_ecp_group_load +
    + +

    ecp_mod_p256 (Thumb, 1044 bytes, Stack size 32 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = ecp_mod_p256 ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_grow +
    • >>   add32 +
    • >>   sub32 +
    • >>   mbedtls_ecp_fix_negative +
    +
    [Address Reference Count : 1]
    • ecp_curves.o(.text) +
    +

    ecp_mod_p224 (Thumb, 542 bytes, Stack size 32 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = ecp_mod_p224 ⇒ mbedtls_mpi_grow ⇒ mbedtls_zeroize_and_free +
    +
    [Calls]
    • >>   mbedtls_mpi_grow +
    • >>   add32 +
    • >>   sub32 +
    • >>   mbedtls_ecp_fix_negative +
    +
    [Address Reference Count : 1]
    • ecp_curves.o(.text) +
    +

    mbedtls_ecp_fix_negative (Thumb, 64 bytes, Stack size 12 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 12
    • Call Chain = mbedtls_ecp_fix_negative +
    +
    [Called By]
    • >>   ecp_mod_p224 +
    • >>   ecp_mod_p256 +
    + +

    sub32 (Thumb, 32 bytes, Stack size 4 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = sub32 +
    +
    [Called By]
    • >>   ecp_mod_p224 +
    • >>   ecp_mod_p256 +
    + +

    add32 (Thumb, 30 bytes, Stack size 4 bytes, ecp_curves.o(.text)) +

    [Stack]

    • Max Depth = 4
    • Call Chain = add32 +
    +
    [Called By]
    • >>   ecp_mod_p224 +
    • >>   ecp_mod_p256 +
    + +

    gcm_mult (Thumb, 394 bytes, Stack size 44 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 44
    • Call Chain = gcm_mult +
    +
    [Called By]
    • >>   mbedtls_gcm_update_ad +
    • >>   mbedtls_gcm_update +
    • >>   mbedtls_gcm_starts +
    • >>   mbedtls_gcm_finish +
    + +

    gcm_mask (Thumb, 162 bytes, Stack size 48 bytes, gcm.o(.text)) +

    [Stack]

    • Max Depth = 48 + In Cycle +
    • Call Chain = gcm_mask ⇒ mbedtls_cipher_update (Cycle) +
    +
    [Calls]
    • >>   mbedtls_cipher_update +
    • >>   mbedtls_platform_zeroize +
    +
    [Called By]
    • >>   mbedtls_gcm_update +
    + +

    ADC_GetKValue (Thumb, 66 bytes, Stack size 8 bytes, adc_lib.o(.text)) +

    [Stack]

    • Max Depth = 8
    • Call Chain = ADC_GetKValue +
    +
    [Called By]
    • >>   ADC_CalibrationInit +
    + +

    ADC_GetKVoltage (Thumb, 82 bytes, Stack size 16 bytes, adc_lib.o(.text)) +

    [Stack]

    • Max Depth = 36
    • Call Chain = ADC_GetKVoltage ⇒ __aeabi_fdiv +
    +
    [Calls]
    • >>   __aeabi_fmul +
    • >>   __aeabi_i2f +
    • >>   __aeabi_fdiv +
    • >>   __aeabi_fadd +
    +
    [Called By]
    • >>   ADC_GetVoltage +
    + +

    _dadd1 (Thumb, 290 bytes, Stack size 20 bytes, daddsub.o(.text), UNUSED) +

    [Called By]

    • >>   _drsb +
    • >>   _dsub +
    • >>   _dadd +
    + +

    _dsub1 (Thumb, 470 bytes, Stack size 40 bytes, daddsub.o(.text), UNUSED) +

    [Called By]

    • >>   _drsb +
    • >>   _dsub +
    • >>   _dadd +
    + +

    _fadd1 (Thumb, 0 bytes, Stack size unknown bytes, faddsub.o(x$fpl$fadd), UNUSED) +

    [Called By]

    • >>   _fsub +
    + +

    _fsub1 (Thumb, 0 bytes, Stack size unknown bytes, faddsub.o(x$fpl$fsub), UNUSED) +

    [Called By]

    • >>   _fadd +
    + +

    _printf_input_char (Thumb, 10 bytes, Stack size 0 bytes, _printf_char_common.o(.text)) +
    [Address Reference Count : 1]

    • _printf_char_common.o(.text) +
    +

    _fp_digits (Thumb, 412 bytes, Stack size 96 bytes, _printf_fp_dec.o(.text)) +

    [Stack]

    • Max Depth = 272
    • Call Chain = _fp_digits ⇒ _btod_etento ⇒ _btod_emul ⇒ btod_internal_mul ⇒ __ARM_common_ll_muluu +
    +
    [Calls]
    • >>   _btod_ediv +
    • >>   _btod_emul +
    • >>   _btod_d2e +
    • >>   _btod_etento +
    • >>   _ll_udiv10 +
    +
    [Called By]
    • >>   _printf_fp_dec_real +
    + +

    btod_internal_mul (Thumb, 492 bytes, Stack size 56 bytes, btod.o(.text)) +

    [Stack]

    • Max Depth = 80
    • Call Chain = btod_internal_mul ⇒ __ARM_common_ll_muluu +
    +
    [Calls]
    • >>   __ARM_common_ll_muluu +
    +
    [Called By]
    • >>   _btod_emuld +
    • >>   _btod_emul +
    + +

    btod_internal_div (Thumb, 520 bytes, Stack size 64 bytes, btod.o(.text)) +

    [Stack]

    • Max Depth = 64
    • Call Chain = btod_internal_div +
    +
    [Called By]
    • >>   _btod_edivd +
    • >>   _btod_ediv +
    +

    +

    +Undefined Global Symbols +

    +

    __scatterload (Unknown, 0 bytes, Stack size 0 bytes, UNDEFINED) +

    [Called By]

    • >>   __main +
    + +

    _printf_mbtowc (ARM, 0 bytes, Stack size 0 bytes, UNDEFINED) +

    [Called By]

    • >>   _printf_cs_common +
    + +

    _printf_wc (ARM, 0 bytes, Stack size 0 bytes, UNDEFINED) +

    [Called By]

    • >>   _printf_lcs_common +
    +
    diff --git a/board/evb/findmy/mdk/Objects/app.lnp b/board/evb/findmy/mdk/Objects/app.lnp new file mode 100644 index 0000000..741a82f --- /dev/null +++ b/board/evb/findmy/mdk/Objects/app.lnp @@ -0,0 +1,89 @@ +--cpu Cortex-M0+ +"..\..\..\..\bin\mdk\ROM.lib" +"..\..\..\..\bin\upperstack_img\upperstack_findmy_0\gap_utils.lib" +"..\..\..\..\bin\mdk\bee3_sdk.lib" +"..\..\..\..\bin\mdk\adc.lib" +"..\..\..\..\bin\mdk\key_crypto.lib" +".\objects\startup_rtl876x.o" +".\objects\system_rtl876x.o" +".\objects\rtl876x_io_dlps.o" +".\objects\rtl876x_gpio.o" +".\objects\rtl876x_rcc.o" +".\objects\rtl876x_tim.o" +".\objects\rtl876x_pinmux.o" +".\objects\rtl876x_nvic.o" +".\objects\rtl876x_adc.o" +".\objects\rtl876x_i2c.o" +".\objects\rtl876x_aon_wdg.o" +".\objects\findmy_network_service.o" +".\objects\accessory_info_service.o" +".\objects\firmware_update_service.o" +".\objects\tps.o" +".\objects\hids_kb.o" +".\objects\ias.o" +".\objects\sdd_service.o" +".\objects\dis.o" +".\objects\main.o" +".\objects\app_task.o" +".\objects\findmy_app.o" +".\objects\custom_app.o" +".\objects\dfu_flash.o" +".\objects\overlay_mgr.o" +".\objects\reset_watch_dog_timer.o" +".\objects\serial_number_send.o" +".\objects\da213b.o" +".\objects\key_handle.o" +".\objects\fmna_adv.o" +".\objects\fmna_config_control_point.o" +".\objects\fmna_connection.o" +".\objects\fmna_crypto.o" +".\objects\fmna_debug_control_point.o" +".\objects\fmna_gatt.o" +".\objects\fmna_motion_detection.o" +".\objects\fmna_nfc.o" +".\objects\fmna_nonowner_control_point.o" +".\objects\fmna_paired_owner_control_point.o" +".\objects\fmna_pairing_control_point.o" +".\objects\fmna_state_machine.o" +".\objects\fmna_uarp_control_point.o" +".\objects\fmna_version.o" +".\objects\fmnasampleuarp.o" +".\objects\fmna_adv_platform.o" +".\objects\fmna_battery_platform.o" +".\objects\fmna_connection_platform.o" +".\objects\fmna_dfu_platform.o" +".\objects\fmna_gap_platform.o" +".\objects\fmna_gatt_platform.o" +".\objects\fmna_malloc_platform.o" +".\objects\fmna_motion_detection_platform.o" +".\objects\fmna_peer_manager.o" +".\objects\fmna_sound_platform.o" +".\objects\fmna_timer_platform.o" +".\objects\coreuarputils.o" +".\objects\coreuarpaccessory.o" +".\objects\coreuarpplatformaccessory.o" +".\objects\coreuarpplatformrtk.o" +".\objects\fm-crypto.o" +".\objects\kdf963.o" +".\objects\aes.o" +".\objects\asn1parse.o" +".\objects\asn1write.o" +".\objects\base64.o" +".\objects\bignum.o" +".\objects\bignum_core.o" +".\objects\cipher.o" +".\objects\cipher_wrap.o" +".\objects\constant_time.o" +".\objects\ecdh.o" +".\objects\ecdsa.o" +".\objects\ecp.o" +".\objects\ecp_curves.o" +".\objects\gcm.o" +".\objects\md.o" +".\objects\sha256.o" +".\objects\platform.o" +".\objects\platform_util.o" +--strict --scatter ".\app_findmy.sct" +--diag_suppress=L6314,L6312 --datacompressor off --remove --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols +--info sizes --info totals --info unused --info veneers +--list ".\Listings\app.map" -o .\Objects\app.axf \ No newline at end of file diff --git a/board/evb/findmy/mdk/Objects/app_task.crf b/board/evb/findmy/mdk/Objects/app_task.crf new file mode 100644 index 0000000..a608204 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/app_task.crf differ diff --git a/board/evb/findmy/mdk/Objects/app_task.d b/board/evb/findmy/mdk/Objects/app_task.d new file mode 100644 index 0000000..5257d15 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/app_task.d @@ -0,0 +1,47 @@ +.\objects\app_task.o: ..\..\..\..\src\app\findmy\app_task.c +.\objects\app_task.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\app_task.o: ..\..\findmy\flash_map.h +.\objects\app_task.o: ..\..\..\..\inc\os\os_msg.h +.\objects\app_task.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\app_task.o: ..\..\..\..\inc\os\os_task.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\app_task.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\app_task.o: ..\..\findmy\board.h +.\objects\app_task.o: ..\..\..\..\inc\platform\otp.h +.\objects\app_task.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\app_task.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\app_task.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\app_task.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\app_task.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\app_task.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\app_task.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\app_task.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\app_task.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\app_task.o: ..\..\..\..\inc\app\app_msg.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\app_task.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\app_task.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\app_task.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\app_task.o: ..\..\..\..\inc\os\os_timer.h +.\objects\app_task.o: ..\..\..\..\inc\platform\trace.h +.\objects\app_task.o: ..\..\findmy\platform_autoconf.h +.\objects\app_task.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\app_task.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\app_task.o: ..\..\findmy\otp_config.h +.\objects\app_task.o: ..\..\..\..\inc\os\os_mem.h +.\objects\app_task.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\app_task.o: ..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h diff --git a/board/evb/findmy/mdk/Objects/app_task.o b/board/evb/findmy/mdk/Objects/app_task.o new file mode 100644 index 0000000..640e4d4 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/app_task.o differ diff --git a/board/evb/findmy/mdk/Objects/asn1parse.crf b/board/evb/findmy/mdk/Objects/asn1parse.crf new file mode 100644 index 0000000..362a81c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/asn1parse.crf differ diff --git a/board/evb/findmy/mdk/Objects/asn1parse.d b/board/evb/findmy/mdk/Objects/asn1parse.d new file mode 100644 index 0000000..8c1fa36 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/asn1parse.d @@ -0,0 +1,32 @@ +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\asn1parse.o: ..\..\findmy\flash_map.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\asn1parse.o: ..\..\..\..\inc\os\os_mem.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\asn1parse.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\asn1parse.o: ..\..\..\..\inc\platform\trace.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\asn1parse.o: ..\..\findmy\platform_autoconf.h +.\objects\asn1parse.o: ..\..\findmy\board.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1parse.o: ..\..\..\..\inc\platform\app_section.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\asn1parse.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1parse.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/asn1parse.o b/board/evb/findmy/mdk/Objects/asn1parse.o new file mode 100644 index 0000000..5a8881a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/asn1parse.o differ diff --git a/board/evb/findmy/mdk/Objects/asn1write.crf b/board/evb/findmy/mdk/Objects/asn1write.crf new file mode 100644 index 0000000..4be5604 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/asn1write.crf differ diff --git a/board/evb/findmy/mdk/Objects/asn1write.d b/board/evb/findmy/mdk/Objects/asn1write.d new file mode 100644 index 0000000..bb12b92 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/asn1write.d @@ -0,0 +1,33 @@ +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\asn1write.o: ..\..\findmy\flash_map.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\asn1write.o: ..\..\..\..\inc\os\os_mem.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\asn1write.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\asn1write.o: ..\..\..\..\inc\platform\trace.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\asn1write.o: ..\..\findmy\platform_autoconf.h +.\objects\asn1write.o: ..\..\findmy\board.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1write.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1write.o: ..\..\..\..\inc\platform\app_section.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\asn1write.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\asn1write.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/asn1write.o b/board/evb/findmy/mdk/Objects/asn1write.o new file mode 100644 index 0000000..1f80826 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/asn1write.o differ diff --git a/board/evb/findmy/mdk/Objects/base64.crf b/board/evb/findmy/mdk/Objects/base64.crf new file mode 100644 index 0000000..3705774 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/base64.crf differ diff --git a/board/evb/findmy/mdk/Objects/base64.d b/board/evb/findmy/mdk/Objects/base64.d new file mode 100644 index 0000000..fc87536 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/base64.d @@ -0,0 +1,29 @@ +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\base64.o: ..\..\findmy\flash_map.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\base64.o: ..\..\..\..\inc\os\os_mem.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\base64.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\base64.o: ..\..\..\..\inc\platform\trace.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\base64.o: ..\..\findmy\platform_autoconf.h +.\objects\base64.o: ..\..\findmy\board.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\base64.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/base64.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64_internal.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\base64.o: ..\..\..\..\inc\platform\app_section.h +.\objects\base64.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h diff --git a/board/evb/findmy/mdk/Objects/base64.o b/board/evb/findmy/mdk/Objects/base64.o new file mode 100644 index 0000000..f139cb4 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/base64.o differ diff --git a/board/evb/findmy/mdk/Objects/bignum.crf b/board/evb/findmy/mdk/Objects/bignum.crf new file mode 100644 index 0000000..d9c242a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/bignum.crf differ diff --git a/board/evb/findmy/mdk/Objects/bignum.d b/board/evb/findmy/mdk/Objects/bignum.d new file mode 100644 index 0000000..3f65fbf --- /dev/null +++ b/board/evb/findmy/mdk/Objects/bignum.d @@ -0,0 +1,34 @@ +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\bignum.o: ..\..\findmy\flash_map.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\bignum.o: ..\..\..\..\inc\os\os_mem.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\bignum.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\bignum.o: ..\..\..\..\inc\platform\trace.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\bignum.o: ..\..\findmy\platform_autoconf.h +.\objects\bignum.o: ..\..\findmy\board.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\bignum.o: ..\..\..\..\inc\platform\app_section.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\bignum.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\bignum.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/bignum.o b/board/evb/findmy/mdk/Objects/bignum.o new file mode 100644 index 0000000..9aec91b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/bignum.o differ diff --git a/board/evb/findmy/mdk/Objects/bignum_core.crf b/board/evb/findmy/mdk/Objects/bignum_core.crf new file mode 100644 index 0000000..b98f98b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/bignum_core.crf differ diff --git a/board/evb/findmy/mdk/Objects/bignum_core.d b/board/evb/findmy/mdk/Objects/bignum_core.d new file mode 100644 index 0000000..719a613 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/bignum_core.d @@ -0,0 +1,34 @@ +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\bignum_core.o: ..\..\findmy\flash_map.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\bignum_core.o: ..\..\..\..\inc\os\os_mem.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\bignum_core.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\bignum_core.o: ..\..\..\..\inc\platform\trace.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\bignum_core.o: ..\..\findmy\platform_autoconf.h +.\objects\bignum_core.o: ..\..\findmy\board.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\bignum_core.o: ..\..\..\..\inc\platform\app_section.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\bignum_core.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h +.\objects\bignum_core.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h diff --git a/board/evb/findmy/mdk/Objects/bignum_core.o b/board/evb/findmy/mdk/Objects/bignum_core.o new file mode 100644 index 0000000..e7cf4ce Binary files /dev/null and b/board/evb/findmy/mdk/Objects/bignum_core.o differ diff --git a/board/evb/findmy/mdk/Objects/cipher.crf b/board/evb/findmy/mdk/Objects/cipher.crf new file mode 100644 index 0000000..0883a4b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/cipher.crf differ diff --git a/board/evb/findmy/mdk/Objects/cipher.d b/board/evb/findmy/mdk/Objects/cipher.d new file mode 100644 index 0000000..ec4c850 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/cipher.d @@ -0,0 +1,38 @@ +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\cipher.o: ..\..\findmy\flash_map.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\cipher.o: ..\..\..\..\inc\os\os_mem.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\cipher.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\cipher.o: ..\..\..\..\inc\platform\trace.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\cipher.o: ..\..\findmy\platform_autoconf.h +.\objects\cipher.o: ..\..\findmy\board.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher.o: ..\..\..\..\inc\platform\app_section.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\cipher.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/cipher.o b/board/evb/findmy/mdk/Objects/cipher.o new file mode 100644 index 0000000..03fc899 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/cipher.o differ diff --git a/board/evb/findmy/mdk/Objects/cipher_wrap.crf b/board/evb/findmy/mdk/Objects/cipher_wrap.crf new file mode 100644 index 0000000..db57fb4 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/cipher_wrap.crf differ diff --git a/board/evb/findmy/mdk/Objects/cipher_wrap.d b/board/evb/findmy/mdk/Objects/cipher_wrap.d new file mode 100644 index 0000000..a26ffe3 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/cipher_wrap.d @@ -0,0 +1,34 @@ +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\cipher_wrap.o: ..\..\findmy\flash_map.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\cipher_wrap.o: ..\..\..\..\inc\os\os_mem.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\cipher_wrap.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\cipher_wrap.o: ..\..\..\..\inc\platform\trace.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\cipher_wrap.o: ..\..\findmy\platform_autoconf.h +.\objects\cipher_wrap.o: ..\..\findmy\board.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\cipher_wrap.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\cipher_wrap.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/cipher_wrap.o b/board/evb/findmy/mdk/Objects/cipher_wrap.o new file mode 100644 index 0000000..1d3209d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/cipher_wrap.o differ diff --git a/board/evb/findmy/mdk/Objects/constant_time.crf b/board/evb/findmy/mdk/Objects/constant_time.crf new file mode 100644 index 0000000..4e6f03e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/constant_time.crf differ diff --git a/board/evb/findmy/mdk/Objects/constant_time.d b/board/evb/findmy/mdk/Objects/constant_time.d new file mode 100644 index 0000000..601ee1a --- /dev/null +++ b/board/evb/findmy/mdk/Objects/constant_time.d @@ -0,0 +1,30 @@ +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\constant_time.o: ..\..\findmy\flash_map.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\constant_time.o: ..\..\..\..\inc\os\os_mem.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\constant_time.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\constant_time.o: ..\..\..\..\inc\platform\trace.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\constant_time.o: ..\..\findmy\platform_autoconf.h +.\objects\constant_time.o: ..\..\findmy\board.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\constant_time.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\constant_time.o: ..\..\..\..\inc\platform\app_section.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\constant_time.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h diff --git a/board/evb/findmy/mdk/Objects/constant_time.o b/board/evb/findmy/mdk/Objects/constant_time.o new file mode 100644 index 0000000..7f13514 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/constant_time.o differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpaccessory.crf b/board/evb/findmy/mdk/Objects/coreuarpaccessory.crf new file mode 100644 index 0000000..7aa19d5 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpaccessory.crf differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpaccessory.d b/board/evb/findmy/mdk/Objects/coreuarpaccessory.d new file mode 100644 index 0000000..3bce269 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/coreuarpaccessory.d @@ -0,0 +1,30 @@ +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\coreuarpaccessory.o: ..\..\findmy\flash_map.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\coreuarpaccessory.o: ..\..\findmy\board.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\otp.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\coreuarpaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\trace.h +.\objects\coreuarpaccessory.o: ..\..\findmy\platform_autoconf.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\os\os_sync.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\coreuarpaccessory.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h +.\objects\coreuarpaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h diff --git a/board/evb/findmy/mdk/Objects/coreuarpaccessory.o b/board/evb/findmy/mdk/Objects/coreuarpaccessory.o new file mode 100644 index 0000000..86071c1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpaccessory.o differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.crf b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.crf new file mode 100644 index 0000000..9c106eb Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.crf differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.d b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.d new file mode 100644 index 0000000..5cbb818 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.d @@ -0,0 +1,32 @@ +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\coreuarpplatformaccessory.o: ..\..\findmy\flash_map.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\coreuarpplatformaccessory.o: ..\..\findmy\board.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\otp.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\coreuarpplatformaccessory.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\trace.h +.\objects\coreuarpplatformaccessory.o: ..\..\findmy\platform_autoconf.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\os\os_sync.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\coreuarpplatformaccessory.o: ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.o b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.o new file mode 100644 index 0000000..19034a8 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpplatformaccessory.o differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.crf b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.crf new file mode 100644 index 0000000..1431169 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.crf differ diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.d b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.d new file mode 100644 index 0000000..8587c9c --- /dev/null +++ b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.d @@ -0,0 +1,25 @@ +.\objects\coreuarpplatformrtk.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\coreuarpplatformrtk.o: ..\..\findmy\flash_map.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\coreuarpplatformrtk.o: ..\..\findmy\board.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\otp.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\coreuarpplatformrtk.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\trace.h +.\objects\coreuarpplatformrtk.o: ..\..\findmy\platform_autoconf.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\os\os_sync.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\os\os_mem.h +.\objects\coreuarpplatformrtk.o: ..\..\..\..\inc\platform\mem_types.h diff --git a/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.o b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.o new file mode 100644 index 0000000..7487dd4 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarpplatformrtk.o differ diff --git a/board/evb/findmy/mdk/Objects/coreuarputils.crf b/board/evb/findmy/mdk/Objects/coreuarputils.crf new file mode 100644 index 0000000..3f753f8 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarputils.crf differ diff --git a/board/evb/findmy/mdk/Objects/coreuarputils.d b/board/evb/findmy/mdk/Objects/coreuarputils.d new file mode 100644 index 0000000..af6f010 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/coreuarputils.d @@ -0,0 +1,26 @@ +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\coreuarputils.o: ..\..\findmy\flash_map.h +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\coreuarputils.o: ..\..\findmy\board.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\otp.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\coreuarputils.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\coreuarputils.o: ..\..\..\..\inc\platform\trace.h +.\objects\coreuarputils.o: ..\..\findmy\platform_autoconf.h +.\objects\coreuarputils.o: ..\..\..\..\inc\os\os_sync.h +.\objects\coreuarputils.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h diff --git a/board/evb/findmy/mdk/Objects/coreuarputils.o b/board/evb/findmy/mdk/Objects/coreuarputils.o new file mode 100644 index 0000000..4a6983d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/coreuarputils.o differ diff --git a/board/evb/findmy/mdk/Objects/custom_app.crf b/board/evb/findmy/mdk/Objects/custom_app.crf new file mode 100644 index 0000000..393a6cd Binary files /dev/null and b/board/evb/findmy/mdk/Objects/custom_app.crf differ diff --git a/board/evb/findmy/mdk/Objects/custom_app.d b/board/evb/findmy/mdk/Objects/custom_app.d new file mode 100644 index 0000000..4f9b233 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/custom_app.d @@ -0,0 +1,83 @@ +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\custom_app.c +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\custom_app.o: ..\..\findmy\flash_map.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\trace.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\custom_app.o: ..\..\findmy\platform_autoconf.h +.\objects\custom_app.o: ..\..\findmy\board.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\custom_app.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_privacy.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_conn_le.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\custom_app.o: ..\..\..\..\inc\app\app_msg.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\custom_app.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\custom_app.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\custom_app.o: ..\..\..\..\inc\os\os_timer.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\otp.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\ftl.h +.\objects\custom_app.o: ..\..\..\..\inc\os\os_msg.h +.\objects\custom_app.o: ..\..\..\..\inc\os\os_mem.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\custom_app.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\custom_app.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\aes.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\custom_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\custom_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h diff --git a/board/evb/findmy/mdk/Objects/custom_app.o b/board/evb/findmy/mdk/Objects/custom_app.o new file mode 100644 index 0000000..1556ffd Binary files /dev/null and b/board/evb/findmy/mdk/Objects/custom_app.o differ diff --git a/board/evb/findmy/mdk/Objects/da213b.crf b/board/evb/findmy/mdk/Objects/da213b.crf new file mode 100644 index 0000000..bc58b7a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/da213b.crf differ diff --git a/board/evb/findmy/mdk/Objects/da213b.d b/board/evb/findmy/mdk/Objects/da213b.d new file mode 100644 index 0000000..178bd49 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/da213b.d @@ -0,0 +1,18 @@ +.\objects\da213b.o: ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c +.\objects\da213b.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\da213b.o: ..\..\findmy\flash_map.h +.\objects\da213b.o: ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.h +.\objects\da213b.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\da213b.o: ..\..\..\..\inc\peripheral\rtl876x_i2c.h +.\objects\da213b.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\da213b.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\da213b.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\da213b.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\da213b.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\da213b.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\da213b.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\da213b.o: ..\..\..\..\inc\platform\trace.h +.\objects\da213b.o: ..\..\findmy\platform_autoconf.h +.\objects\da213b.o: ..\..\findmy\board.h +.\objects\da213b.o: ..\..\..\..\inc\os\os_sched.h +.\objects\da213b.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h diff --git a/board/evb/findmy/mdk/Objects/da213b.o b/board/evb/findmy/mdk/Objects/da213b.o new file mode 100644 index 0000000..05c9b39 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/da213b.o differ diff --git a/board/evb/findmy/mdk/Objects/dfu_flash.crf b/board/evb/findmy/mdk/Objects/dfu_flash.crf new file mode 100644 index 0000000..4092fb1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/dfu_flash.crf differ diff --git a/board/evb/findmy/mdk/Objects/dfu_flash.d b/board/evb/findmy/mdk/Objects/dfu_flash.d new file mode 100644 index 0000000..6808e8d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/dfu_flash.d @@ -0,0 +1,26 @@ +.\objects\dfu_flash.o: ..\..\..\..\src\platform\dfu_flash.c +.\objects\dfu_flash.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\dfu_flash.o: ..\..\findmy\flash_map.h +.\objects\dfu_flash.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\trace.h +.\objects\dfu_flash.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\dfu_flash.o: ..\..\findmy\platform_autoconf.h +.\objects\dfu_flash.o: ..\..\findmy\board.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\hw_aes.h +.\objects\dfu_flash.o: ..\..\..\..\inc\peripheral\rtl876x_hw_aes.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\otp.h +.\objects\dfu_flash.o: ..\..\..\..\inc\app\dfu_api.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\sha256.h +.\objects\dfu_flash.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\dfu_flash.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\dfu_flash.h +.\objects\dfu_flash.o: ..\..\..\..\inc\platform\crc16btx.h diff --git a/board/evb/findmy/mdk/Objects/dfu_flash.o b/board/evb/findmy/mdk/Objects/dfu_flash.o new file mode 100644 index 0000000..e3175c9 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/dfu_flash.o differ diff --git a/board/evb/findmy/mdk/Objects/dis.crf b/board/evb/findmy/mdk/Objects/dis.crf new file mode 100644 index 0000000..7e98b88 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/dis.crf differ diff --git a/board/evb/findmy/mdk/Objects/dis.d b/board/evb/findmy/mdk/Objects/dis.d new file mode 100644 index 0000000..7b9de3e --- /dev/null +++ b/board/evb/findmy/mdk/Objects/dis.d @@ -0,0 +1,20 @@ +.\objects\dis.o: ..\..\..\..\src\ble\profile\server\dis.c +.\objects\dis.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\dis.o: ..\..\findmy\flash_map.h +.\objects\dis.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\dis.o: ..\..\..\..\inc\platform\trace.h +.\objects\dis.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\dis.o: ..\..\findmy\platform_autoconf.h +.\objects\dis.o: ..\..\findmy\board.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\dis.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\profile\server\dis.h +.\objects\dis.o: ..\..\..\..\inc\bluetooth\profile\server\dis_config.h +.\objects\dis.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h diff --git a/board/evb/findmy/mdk/Objects/dis.o b/board/evb/findmy/mdk/Objects/dis.o new file mode 100644 index 0000000..8f5f944 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/dis.o differ diff --git a/board/evb/findmy/mdk/Objects/ecdh.crf b/board/evb/findmy/mdk/Objects/ecdh.crf new file mode 100644 index 0000000..8662e30 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecdh.crf differ diff --git a/board/evb/findmy/mdk/Objects/ecdh.d b/board/evb/findmy/mdk/Objects/ecdh.d new file mode 100644 index 0000000..0a56303 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/ecdh.d @@ -0,0 +1,31 @@ +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\ecdh.o: ..\..\findmy\flash_map.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\ecdh.o: ..\..\..\..\inc\os\os_mem.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\ecdh.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\ecdh.o: ..\..\..\..\inc\platform\trace.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\ecdh.o: ..\..\findmy\platform_autoconf.h +.\objects\ecdh.o: ..\..\findmy\board.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\ecdh.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdh.o: ..\..\..\..\inc\platform\app_section.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\ecdh.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h diff --git a/board/evb/findmy/mdk/Objects/ecdh.o b/board/evb/findmy/mdk/Objects/ecdh.o new file mode 100644 index 0000000..565f428 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecdh.o differ diff --git a/board/evb/findmy/mdk/Objects/ecdsa.crf b/board/evb/findmy/mdk/Objects/ecdsa.crf new file mode 100644 index 0000000..4bcb9a1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecdsa.crf differ diff --git a/board/evb/findmy/mdk/Objects/ecdsa.d b/board/evb/findmy/mdk/Objects/ecdsa.d new file mode 100644 index 0000000..89143b5 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/ecdsa.d @@ -0,0 +1,39 @@ +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\ecdsa.o: ..\..\findmy\flash_map.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\ecdsa.o: ..\..\..\..\inc\os\os_mem.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\ecdsa.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\ecdsa.o: ..\..\..\..\inc\platform\trace.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\ecdsa.o: ..\..\findmy\platform_autoconf.h +.\objects\ecdsa.o: ..\..\findmy\board.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: ..\..\..\..\inc\platform\app_section.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1write.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecdsa.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\ecdsa.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h diff --git a/board/evb/findmy/mdk/Objects/ecdsa.o b/board/evb/findmy/mdk/Objects/ecdsa.o new file mode 100644 index 0000000..0049f28 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecdsa.o differ diff --git a/board/evb/findmy/mdk/Objects/ecp.crf b/board/evb/findmy/mdk/Objects/ecp.crf new file mode 100644 index 0000000..ae2648d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecp.crf differ diff --git a/board/evb/findmy/mdk/Objects/ecp.d b/board/evb/findmy/mdk/Objects/ecp.d new file mode 100644 index 0000000..b0cb6fe --- /dev/null +++ b/board/evb/findmy/mdk/Objects/ecp.d @@ -0,0 +1,37 @@ +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\ecp.o: ..\..\findmy\flash_map.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\ecp.o: ..\..\..\..\inc\os\os_mem.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\ecp.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\ecp.o: ..\..\..\..\inc\platform\trace.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\ecp.o: ..\..\findmy\platform_autoconf.h +.\objects\ecp.o: ..\..\findmy\board.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp.o: ..\..\..\..\inc\platform\app_section.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/threading.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_invasive.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\ecp.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_internal_alt.h diff --git a/board/evb/findmy/mdk/Objects/ecp.o b/board/evb/findmy/mdk/Objects/ecp.o new file mode 100644 index 0000000..6e551e1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecp.o differ diff --git a/board/evb/findmy/mdk/Objects/ecp_curves.crf b/board/evb/findmy/mdk/Objects/ecp_curves.crf new file mode 100644 index 0000000..c67e4a2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecp_curves.crf differ diff --git a/board/evb/findmy/mdk/Objects/ecp_curves.d b/board/evb/findmy/mdk/Objects/ecp_curves.d new file mode 100644 index 0000000..777c69e --- /dev/null +++ b/board/evb/findmy/mdk/Objects/ecp_curves.d @@ -0,0 +1,34 @@ +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\ecp_curves.o: ..\..\findmy\flash_map.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\ecp_curves.o: ..\..\..\..\inc\os\os_mem.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\ecp_curves.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\ecp_curves.o: ..\..\..\..\inc\platform\trace.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\ecp_curves.o: ..\..\findmy\platform_autoconf.h +.\objects\ecp_curves.o: ..\..\findmy\board.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\ecp_curves.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\ecp_curves.o: ..\..\..\..\inc\platform\app_section.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h +.\objects\ecp_curves.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_invasive.h diff --git a/board/evb/findmy/mdk/Objects/ecp_curves.o b/board/evb/findmy/mdk/Objects/ecp_curves.o new file mode 100644 index 0000000..70d8f6e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ecp_curves.o differ diff --git a/board/evb/findmy/mdk/Objects/findmy_app.crf b/board/evb/findmy/mdk/Objects/findmy_app.crf new file mode 100644 index 0000000..1ed5a7d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/findmy_app.crf differ diff --git a/board/evb/findmy/mdk/Objects/findmy_app.d b/board/evb/findmy/mdk/Objects/findmy_app.d new file mode 100644 index 0000000..921d97f --- /dev/null +++ b/board/evb/findmy/mdk/Objects/findmy_app.d @@ -0,0 +1,92 @@ +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\findmy_app.c +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\findmy_app.o: ..\..\findmy\flash_map.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\findmy_app.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_adv.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\gap\gap_conn_le.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\findmy_app.o: ..\..\findmy\board.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\otp.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\findmy_app.o: ..\..\..\..\inc\app\app_msg.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\findmy_app.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\findmy_app.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\dfu_flash.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\findmy_app.o: ..\..\..\..\inc\app\dfu_api.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\sha256.h +.\objects\findmy_app.o: ..\..\findmy\otp_config.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h +.\objects\findmy_app.o: ..\..\..\..\inc\os\os_sched.h +.\objects\findmy_app.o: ..\..\..\..\inc\os\os_timer.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\trace.h +.\objects\findmy_app.o: ..\..\findmy\platform_autoconf.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\ftl.h +.\objects\findmy_app.o: ..\..\..\..\inc\os\os_msg.h +.\objects\findmy_app.o: ..\..\..\..\inc\os\os_mem.h +.\objects\findmy_app.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\findmy_app.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\serial_number_send.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\aes.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\findmy_app.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\findmy_app.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\findmy_app.o: ..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h diff --git a/board/evb/findmy/mdk/Objects/findmy_app.o b/board/evb/findmy/mdk/Objects/findmy_app.o new file mode 100644 index 0000000..8bf01d4 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/findmy_app.o differ diff --git a/board/evb/findmy/mdk/Objects/findmy_findmy.dep b/board/evb/findmy/mdk/Objects/findmy_findmy.dep new file mode 100644 index 0000000..62da5d9 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/findmy_findmy.dep @@ -0,0 +1,3252 @@ +Dependencies for Project 'findmy', Target 'findmy': (DO NOT MODIFY !) +CompilerVersion: 5060750::V5.06 update 6 (build 750)::.\ARMCC +F (..\flash_map.h)(0x69084204)() +F (..\mem_config.h)(0x68D6441C)() +F (..\otp_config.h)(0x6918466E)() +F (..\board.h)(0x690D667B)() +F (..\..\..\..\bin\mdk\ROM.lib)(0x68D6441C)() +F (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\gap_utils.lib)(0x68D6441C)() +F (..\..\..\..\bin\mdk\bee3_sdk.lib)(0x68D6441C)() +F (..\..\..\..\bin\mdk\adc.lib)(0x68D6441C)() +F (..\..\..\..\bin\mdk\key_crypto.lib)(0x68D6441C)() +F (..\..\..\..\bin\mdk\system_trace.lib)(0x68D6441C)() +F (..\..\..\..\src\app\findmy\gfps\gfps_lib\gfps.lib)(0x68D64420)() +F (..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s)(0x68D64422)(--cpu Cortex-M0+ --li -g --16 --apcs=interwork --cpreproc -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include --pd "__UVISION_VERSION SETA 535" --pd "ARMCM0P_MPU SETA 1" --list .\listings\startup_rtl876x.lst --xref -o .\objects\startup_rtl876x.o --depend .\objects\startup_rtl876x.d) +F (..\..\..\..\src\mcu\rtl876x\system_rtl876x.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\system_rtl876x.o --omf_browse .\objects\system_rtl876x.crf --depend .\objects\system_rtl876x.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\locale.h)(0x5CEB79D6) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdarg.h)(0x5CEB79E4) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\findmy\version.h)(0x68D6441C) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rom_uuid.h)(0x68D6441E) +I (..\..\..\..\inc\platform\app_define.h)(0x68D6441E) +I (..\..\findmy\mem_config.h)(0x68D6441C) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\inc\platform\overlay_mgr.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\findmy\otp_config.h)(0x6918466E) +I (..\..\..\..\inc\platform\test_mode.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\dfu_flash.h)(0x68D6441E) +I (..\..\..\..\inc\app\dfu_api.h)(0x68D6441E) +I (..\..\..\..\inc\platform\sha256.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_lib_platform.h)(0x68D6441E) +I (..\..\..\..\inc\platform\dlps.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_queue.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_io_dlps.o --omf_browse .\objects\rtl876x_io_dlps.crf --depend .\objects\rtl876x_io_dlps.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\peripheral\rtl876x_io_dlps.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\dlps.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_queue.h)(0x68D6441E) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_nvic.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\..\..\inc\platform\test_mode.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_tim.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_gpio.o --omf_browse .\objects\rtl876x_gpio.crf --depend .\objects\rtl876x_gpio.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_gpio.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_rcc.o --omf_browse .\objects\rtl876x_rcc.crf --depend .\objects\rtl876x_rcc.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_tim.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_tim.o --omf_browse .\objects\rtl876x_tim.crf --depend .\objects\rtl876x_tim.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_tim.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_pinmux.o --omf_browse .\objects\rtl876x_pinmux.crf --depend .\objects\rtl876x_pinmux.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_nvic.o --omf_browse .\objects\rtl876x_nvic.crf --depend .\objects\rtl876x_nvic.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_nvic.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_adc.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_adc.o --omf_browse .\objects\rtl876x_adc.crf --depend .\objects\rtl876x_adc.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_adc.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_alias.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\adc_lib.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_i2c.o --omf_browse .\objects\rtl876x_i2c.crf --depend .\objects\rtl876x_i2c.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_i2c.h)(0x68D6441E) +F (..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\rtl876x_aon_wdg.o --omf_browse .\objects\rtl876x_aon_wdg.crf --depend .\objects\rtl876x_aon_wdg.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\findmy_network_service.o --omf_browse .\objects\findmy_network_service.crf --depend .\objects\findmy_network_service.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c)(0x69155430)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\accessory_info_service.o --omf_browse .\objects\accessory_info_service.crf --depend .\objects\accessory_info_service.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\firmware_update_service.o --omf_browse .\objects\firmware_update_service.crf --depend .\objects\firmware_update_service.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +F (..\..\..\..\src\ble\profile\server\tps.c)(0x690C461B)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\tps.o --omf_browse .\objects\tps.crf --depend .\objects\tps.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\hids_kb.o --omf_browse .\objects\hids_kb.crf --depend .\objects\hids_kb.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\hids_kb.h)(0x68D6441E) +F (..\..\..\..\src\ble\profile\server\ias.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\ias.o --omf_browse .\objects\ias.crf --depend .\objects\ias.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\ias.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c)(0x69095B2D)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\sdd_service.o --omf_browse .\objects\sdd_service.crf --depend .\objects\sdd_service.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h)(0x69095B05) +F (..\..\..\..\src\ble\profile\server\dis.c)(0x690C2E2E)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\dis.o --omf_browse .\objects\dis.crf --depend .\objects\dis.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\dis.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\dis_config.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +F (..\..\..\..\src\app\findmy\main.c)(0x69184465)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\main.o --omf_browse .\objects\main.crf --depend .\objects\main.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_adv.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\findmy\otp_config.h)(0x6918466E) +I (..\..\..\..\inc\platform\dlps.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_queue.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_io_dlps.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\serial_number_send.h)(0x691296EA) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\app_task.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\app_task.o --omf_browse .\objects\app_task.crf --depend .\objects\app_task.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\os\os_task.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\otp_config.h)(0x6918466E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\findmy_app.c)(0x6924FD6F)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\findmy_app.o --omf_browse .\objects\findmy_app.crf --depend .\objects\findmy_app.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_adv.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_conn_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\inc\platform\dfu_flash.h)(0x68D6441E) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\inc\app\dfu_api.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\sha256.h)(0x68D6441E) +I (..\..\findmy\otp_config.h)(0x6918466E) +I (..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h)(0x69095B05) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\serial_number_send.h)(0x691296EA) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\custom_app.c)(0x6924FB19)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\custom_app.o --omf_browse .\objects\custom_app.crf --depend .\objects\custom_app.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_privacy.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_conn_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +F (..\..\..\..\src\platform\dfu_flash.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\dfu_flash.o --omf_browse .\objects\dfu_flash.crf --depend .\objects\dfu_flash.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\hw_aes.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_hw_aes.h)(0x68D6441E) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\app\dfu_api.h)(0x68D6441E) +I (..\..\..\..\inc\platform\sha256.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\inc\platform\dfu_flash.h)(0x68D6441E) +I (..\..\..\..\inc\platform\crc16btx.h)(0x68D6441E) +F (..\..\..\..\src\mcu\rtl876x\overlay_mgr.c)(0x68D64422)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\overlay_mgr.o --omf_browse .\objects\overlay_mgr.crf --depend .\objects\overlay_mgr.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\overlay_mgr.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +F (..\..\..\..\src\app\findmy\reset_watch_dog_timer.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\reset_watch_dog_timer.o --omf_browse .\objects\reset_watch_dog_timer.crf --depend .\objects\reset_watch_dog_timer.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_tim.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_nvic.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +F (..\..\..\..\src\platform\system_trace.c)(0x68D64422)() +F (..\..\..\..\src\app\findmy\serial_number_send.c)(0x691296F0)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\serial_number_send.o --omf_browse .\objects\serial_number_send.crf --depend .\objects\serial_number_send.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\serial_number_send.h)(0x691296EA) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h)(0x68D6441E) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_adv.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\gfps\app_gfps.c)(0x68D64420)() +F (..\..\..\..\src\app\findmy\gfps\app_gfps_account_key.c)(0x68D64420)() +F (..\..\..\..\src\app\findmy\gfps\app_gfps_finder.c)(0x68D64420)() +F (..\..\..\..\src\app\findmy\gfps\app_gfps_finder_adv.c)(0x68D64420)() +F (..\..\..\..\src\app\findmy\gfps\app_dult.c)(0x68D64420)() +F (..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\da213b.o --omf_browse .\objects\da213b.crf --depend .\objects\da213b.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_peripheral\da213b.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\peripheral\rtl876x_i2c.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +F (..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c)(0x69129023)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\key_handle.o --omf_browse .\objects\key_handle.crf --depend .\objects\key_handle.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\peripheral\rtl876x_gpio.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_nvic.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h)(0x68D64420) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c)(0x690C6F56)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_adv.o --omf_browse .\objects\fmna_adv.crf --depend .\objects\fmna_adv.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_config_control_point.o --omf_browse .\objects\fmna_config_control_point.crf --depend .\objects\fmna_config_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_connection.o --omf_browse .\objects\fmna_connection.crf --depend .\objects\fmna_connection.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c)(0x69117FAA)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_crypto.o --omf_browse .\objects\fmna_crypto.crf --depend .\objects\fmna_crypto.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\crypto\fm-crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h)(0x68D64420) +I (..\..\..\..\inc\platform/sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/base64.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_debug_control_point.o --omf_browse .\objects\fmna_debug_control_point.crf --depend .\objects\fmna_debug_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_gatt.o --omf_browse .\objects\fmna_gatt.crf --depend .\objects\fmna_gatt.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_motion_detection.o --omf_browse .\objects\fmna_motion_detection.crf --depend .\objects\fmna_motion_detection.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_nfc.o --omf_browse .\objects\fmna_nfc.crf --depend .\objects\fmna_nfc.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_nfc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\fmna_peripheral\url_ndef.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_nonowner_control_point.o --omf_browse .\objects\fmna_nonowner_control_point.crf --depend .\objects\fmna_nonowner_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_paired_owner_control_point.o --omf_browse .\objects\fmna_paired_owner_control_point.crf --depend .\objects\fmna_paired_owner_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_pairing_control_point.o --omf_browse .\objects\fmna_pairing_control_point.crf --depend .\objects\fmna_pairing_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c)(0x69159992)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_state_machine.o --omf_browse .\objects\fmna_state_machine.crf --depend .\objects\fmna_state_machine.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h)(0x68D64420) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_uarp_control_point.o --omf_browse .\objects\fmna_uarp_control_point.crf --depend .\objects\fmna_uarp_control_point.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_version.o --omf_browse .\objects\fmna_version.crf --depend .\objects\fmna_version.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +F (..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmnasampleuarp.o --omf_browse .\objects\fmnasampleuarp.crf --depend .\objects\fmnasampleuarp.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c)(0x691461C1)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_adv_platform.o --omf_browse .\objects\fmna_adv_platform.crf --depend .\objects\fmna_adv_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_adv.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h)(0x68D6441E) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_battery_platform.o --omf_browse .\objects\fmna_battery_platform.crf --depend .\objects\fmna_battery_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\inc\peripheral\rtl876x_adc.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_alias.h)(0x68D6441E) +I (..\..\..\..\inc\platform\adc_lib.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c)(0x690AA060)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_connection_platform.o --omf_browse .\objects\fmna_connection_platform.crf --depend .\objects\fmna_connection_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\gap\gap_conn_le.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_dfu_platform.o --omf_browse .\objects\fmna_dfu_platform.crf --depend .\objects\fmna_dfu_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\dfu_flash.h)(0x68D6441E) +I (..\..\..\..\inc\app\dfu_api.h)(0x68D6441E) +I (..\..\..\..\inc\platform\sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c)(0x6917150A)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_gap_platform.o --omf_browse .\objects\fmna_gap_platform.crf --depend .\objects\fmna_gap_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_adv.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_conn_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_queue.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h)(0x69095B05) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c)(0x6924FD48)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_gatt_platform.o --omf_browse .\objects\fmna_gatt_platform.crf --depend .\objects\fmna_gatt_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_direct_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_conn_le.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h)(0x6909C7EF) +I (..\..\..\..\inc\bluetooth\profile\server\ias.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h)(0x69095B05) +I (..\..\..\..\inc\bluetooth\profile\server\dis.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_malloc_platform.o --omf_browse .\objects\fmna_malloc_platform.crf --depend .\objects\fmna_malloc_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_motion_detection_platform.o --omf_browse .\objects\fmna_motion_detection_platform.crf --depend .\objects\fmna_motion_detection_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_i2c.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\src\app\findmy\fmna_peripheral\da213b.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_peer_manager.o --omf_browse .\objects\fmna_peer_manager.crf --depend .\objects\fmna_peer_manager.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c)(0x691684AD)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_sound_platform.o --omf_browse .\objects\fmna_sound_platform.crf --depend .\objects\fmna_sound_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\inc\peripheral\rtl876x_pinmux.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_rcc.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_tim.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sched.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c)(0x691ABF99)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fmna_timer_platform.o --omf_browse .\objects\fmna_timer_platform.crf --depend .\objects\fmna_timer_platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h)(0x691840D1) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\os\os_timer.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h)(0x68F3571A) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\platform\ftl.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_msg.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_bond_le.h)(0x68D6441E) +I (..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h)(0x68D6441C) +I (..\..\..\..\inc\bluetooth\gap\gap_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\bt_types.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_callback_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_storage_le.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\gap\gap_le_types.h)(0x68D6441E) +I (..\..\..\..\inc\app\app_msg.h)(0x68F35C10) +I (..\..\..\..\src\app\findmy\app_task.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\findmy_app.h)(0x691ACAB8) +I (..\..\..\..\inc\bluetooth\gap\gap_msg.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\profile_server.h)(0x68D6441E) +I (..\..\..\..\inc\bluetooth\profile\gatt.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_wdg.h)(0x68D6441E) +I (..\..\..\..\inc\peripheral\rtl876x_bitfields.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\custom_app.h)(0x69205CC1) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h)(0x6917149C) +I (..\..\..\..\src\app\findmy\key_crypto.h)(0x68D64420) +I (..\..\..\..\inc\bluetooth\profile\server\tps.h)(0x690AFFF0) +I (..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h)(0x691ACA83) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h)(0x6912F2EC) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h)(0x69094CE5) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h)(0x69117FB5) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h)(0x68D64420) +I (..\..\findmy\otp_config.h)(0x6918466E) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\coreuarputils.o --omf_browse .\objects\coreuarputils.crf --depend .\objects\coreuarputils.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\coreuarpaccessory.o --omf_browse .\objects\coreuarpaccessory.crf --depend .\objects\coreuarpaccessory.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\coreuarpplatformaccessory.o --omf_browse .\objects\coreuarpplatformaccessory.crf --depend .\objects\coreuarpplatformaccessory.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h)(0x68D64420) +I (..\..\..\..\inc\platform\patch_header_check.h)(0x68D6441E) +I (..\..\..\..\inc\platform\flash_device.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\coreuarpplatformrtk.o --omf_browse .\objects\coreuarpplatformrtk.crf --depend .\objects\coreuarpplatformrtk.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h)(0x692035EF) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\inc\platform\otp.h)(0x68D6441E) +I (..\..\..\..\inc\platform\platform_utils.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cm0plus.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmInstr.h)(0x68D6441E) +I (..\..\..\..\inc\platform\cmsis_armcc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\core_cmFunc.h)(0x68D6441E) +I (..\..\..\..\inc\platform\system_rtl876x.h)(0x68D6441E) +I (..\..\..\..\inc\platform\rtl876x_ic_type.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\..\..\inc\os\os_sync.h)(0x68D6441E) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +F (..\..\..\..\src\app\findmy\crypto\fm-crypto.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\fm-crypto.o --omf_browse .\objects\fm-crypto.crf --depend .\objects\fm-crypto.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\fm-crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h)(0x68D64420) +I (..\..\..\..\inc\platform/sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\kdf963.o --omf_browse .\objects\kdf963.crf --depend .\objects\kdf963.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h)(0x68D64420) +I (..\..\..\..\inc\platform/sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\aes.o --omf_browse .\objects\aes.crf --depend .\objects\aes.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\asn1parse.o --omf_browse .\objects\asn1parse.crf --depend .\objects\asn1parse.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\asn1write.o --omf_browse .\objects\asn1write.crf --depend .\objects\asn1write.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1write.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\base64.o --omf_browse .\objects\base64.crf --depend .\objects\base64.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/base64.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\bignum.o --omf_browse .\objects\bignum.crf --depend .\objects\bignum.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\bignum_core.o --omf_browse .\objects\bignum_core.crf --depend .\objects\bignum_core.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\cipher.o --omf_browse .\objects\cipher.crf --depend .\objects\cipher.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\cipher_wrap.o --omf_browse .\objects\cipher_wrap.crf --depend .\objects\cipher_wrap.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\constant_time.o --omf_browse .\objects\constant_time.crf --depend .\objects\constant_time.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\ecdh.o --omf_browse .\objects\ecdh.crf --depend .\objects\ecdh.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\ecdsa.o --omf_browse .\objects\ecdsa.crf --depend .\objects\ecdsa.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1write.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/asn1.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\ecp.o --omf_browse .\objects\ecp.crf --depend .\objects\ecp.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/threading.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_invasive.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_internal_alt.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\ecp_curves.o --omf_browse .\objects\ecp_curves.crf --depend .\objects\ecp_curves.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h)(0x68D64420) +I (..\..\..\..\inc\platform\app_section.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bn_mul.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_internal.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time_impl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_invasive.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\gcm.o --omf_browse .\objects\gcm.crf --depend .\objects\gcm.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\md.o --omf_browse .\objects\md.crf --depend .\objects\md.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md_wrap.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md5.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ripemd160.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h)(0x68D64420) +I (..\..\..\..\inc\platform/sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\sha256.o --omf_browse .\objects\sha256.crf --depend .\objects\sha256.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (..\..\..\..\inc\platform/sha256.h)(0x68D6441E) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\platform.o --omf_browse .\objects\platform.crf --depend .\objects\platform.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h)(0x68D64420) +F (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c)(0x68D64420)(--c99 -c --cpu Cortex-M0+ --li -g -O2 -Otime --apcs=interwork -I ..\..\..\..\bin\upperstack_img\upperstack_findmy_0 -I ..\findmy -I ..\..\findmy -I ..\..\..\..\src\app\findmy -I ..\..\..\..\inc\app -I ..\..\..\..\inc\bluetooth\gap -I ..\..\..\..\inc\bluetooth\gap\gap_lib -I ..\..\..\..\inc\bluetooth\profile -I ..\..\..\..\inc\bluetooth\profile\server -I ..\..\..\..\inc -I ..\..\..\..\inc\os -I ..\..\..\..\inc\os\system_trace -I ..\..\..\..\inc\peripheral -I ..\..\..\..\inc\platform -I ..\..\..\..\src\app\findmy\fmna_adk -I ..\..\..\..\src\app\findmy\fmna_platform -I ..\..\..\..\src\app\findmy\fmna_profile -I ..\..\..\..\src\app\findmy\fmna_peripheral -I ..\..\..\..\src\app\findmy\UARPDK -I ..\..\..\..\src\app\findmy\crypto -I ..\..\..\..\src\app\findmy\crypto\third-party -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls -I ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library -I ..\..\..\..\..\bluetooth\crypto --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h -IE:\Keil_V5\ARM\CMSIS\5.4.0\Device\ARM\ARMCM0plus\Include -D__UVISION_VERSION="535" -DARMCM0P_MPU -o .\objects\platform_util.o --omf_browse .\objects\platform_util.crf --depend .\objects\platform_util.d) +I (E:\Keil_V5\ARM\ARMCC\include\stdint.h)(0x5CEB79E2) +I (..\..\findmy\flash_map.h)(0x69084204) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h)(0x68D64420) +I (..\..\..\..\inc\os\os_mem.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stddef.h)(0x5CEB79E2) +I (..\..\..\..\inc\platform\mem_types.h)(0x68D6441E) +I (..\..\..\..\inc\platform\trace.h)(0x68D6441E) +I (E:\Keil_V5\ARM\ARMCC\include\stdbool.h)(0x5CEB79DE) +I (..\..\findmy\platform_autoconf.h)(0x68D6441C) +I (..\..\findmy\board.h)(0x690D667B) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\limits.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\string.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\stdlib.h)(0x5CEB79E2) +I (E:\Keil_V5\ARM\ARMCC\include\assert.h)(0x5CEB79D6) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h)(0x68D64420) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h)(0x68D64420) +I (E:\Keil_V5\ARM\ARMCC\include\stdio.h)(0x5CEB79E2) +I (..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/threading.h)(0x68D64420) diff --git a/board/evb/findmy/mdk/Objects/findmy_network_service.crf b/board/evb/findmy/mdk/Objects/findmy_network_service.crf new file mode 100644 index 0000000..63ffaea Binary files /dev/null and b/board/evb/findmy/mdk/Objects/findmy_network_service.crf differ diff --git a/board/evb/findmy/mdk/Objects/findmy_network_service.d b/board/evb/findmy/mdk/Objects/findmy_network_service.d new file mode 100644 index 0000000..eee5b4a --- /dev/null +++ b/board/evb/findmy/mdk/Objects/findmy_network_service.d @@ -0,0 +1,33 @@ +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c +.\objects\findmy_network_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\findmy_network_service.o: ..\..\findmy\flash_map.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\findmy_network_service.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\findmy_network_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\findmy_network_service.o: ..\..\findmy\board.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\otp.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\findmy_network_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\platform\trace.h +.\objects\findmy_network_service.o: ..\..\findmy\platform_autoconf.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\findmy_network_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\findmy_network_service.o: ..\..\..\..\inc\os\os_timer.h diff --git a/board/evb/findmy/mdk/Objects/findmy_network_service.o b/board/evb/findmy/mdk/Objects/findmy_network_service.o new file mode 100644 index 0000000..68b32ad Binary files /dev/null and b/board/evb/findmy/mdk/Objects/findmy_network_service.o differ diff --git a/board/evb/findmy/mdk/Objects/firmware_update_service.crf b/board/evb/findmy/mdk/Objects/firmware_update_service.crf new file mode 100644 index 0000000..55acd23 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/firmware_update_service.crf differ diff --git a/board/evb/findmy/mdk/Objects/firmware_update_service.d b/board/evb/findmy/mdk/Objects/firmware_update_service.d new file mode 100644 index 0000000..c17f831 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/firmware_update_service.d @@ -0,0 +1,33 @@ +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c +.\objects\firmware_update_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\firmware_update_service.o: ..\..\findmy\flash_map.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\firmware_update_service.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\firmware_update_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\firmware_update_service.o: ..\..\findmy\board.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\otp.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\firmware_update_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\platform\trace.h +.\objects\firmware_update_service.o: ..\..\findmy\platform_autoconf.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\firmware_update_service.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\firmware_update_service.o: ..\..\..\..\inc\os\os_timer.h diff --git a/board/evb/findmy/mdk/Objects/firmware_update_service.o b/board/evb/findmy/mdk/Objects/firmware_update_service.o new file mode 100644 index 0000000..522d5de Binary files /dev/null and b/board/evb/findmy/mdk/Objects/firmware_update_service.o differ diff --git a/board/evb/findmy/mdk/Objects/fm-crypto.crf b/board/evb/findmy/mdk/Objects/fm-crypto.crf new file mode 100644 index 0000000..9ce9cf0 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fm-crypto.crf differ diff --git a/board/evb/findmy/mdk/Objects/fm-crypto.d b/board/evb/findmy/mdk/Objects/fm-crypto.d new file mode 100644 index 0000000..376fde3 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fm-crypto.d @@ -0,0 +1,49 @@ +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\fm-crypto.c +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fm-crypto.o: ..\..\findmy\flash_map.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fm-crypto.o: ..\..\..\..\inc\platform\trace.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fm-crypto.o: ..\..\findmy\platform_autoconf.h +.\objects\fm-crypto.o: ..\..\findmy\board.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\fm-crypto.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\fm-crypto.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fm-crypto.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\fm-crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\inc\platform/sha256.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\inc\platform\app_section.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h +.\objects\fm-crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h diff --git a/board/evb/findmy/mdk/Objects/fm-crypto.o b/board/evb/findmy/mdk/Objects/fm-crypto.o new file mode 100644 index 0000000..3979df2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fm-crypto.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_adv.crf b/board/evb/findmy/mdk/Objects/fmna_adv.crf new file mode 100644 index 0000000..2bb4c7a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_adv.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_adv.d b/board/evb/findmy/mdk/Objects/fmna_adv.d new file mode 100644 index 0000000..ed8fea4 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_adv.d @@ -0,0 +1,67 @@ +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c +.\objects\fmna_adv.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_adv.o: ..\..\findmy\flash_map.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_adv.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_adv.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_adv.o: ..\..\findmy\board.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_adv.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_adv.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_adv.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_adv.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_adv.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_adv.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_adv.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_adv.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_adv.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_adv.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_adv.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_adv.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_adv.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h diff --git a/board/evb/findmy/mdk/Objects/fmna_adv.o b/board/evb/findmy/mdk/Objects/fmna_adv.o new file mode 100644 index 0000000..1fe64c0 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_adv.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_adv_platform.crf b/board/evb/findmy/mdk/Objects/fmna_adv_platform.crf new file mode 100644 index 0000000..73097a3 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_adv_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_adv_platform.d b/board/evb/findmy/mdk/Objects/fmna_adv_platform.d new file mode 100644 index 0000000..e9bd90d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_adv_platform.d @@ -0,0 +1,69 @@ +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c +.\objects\fmna_adv_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_adv_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_adv_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_adv_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_adv_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_adv_platform.o: ..\..\findmy\board.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_adv_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_adv.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\app_section.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_adv_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_adv_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_adv_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_adv_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h diff --git a/board/evb/findmy/mdk/Objects/fmna_adv_platform.o b/board/evb/findmy/mdk/Objects/fmna_adv_platform.o new file mode 100644 index 0000000..9cd52d0 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_adv_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_battery_platform.crf b/board/evb/findmy/mdk/Objects/fmna_battery_platform.crf new file mode 100644 index 0000000..34ac6c8 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_battery_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_battery_platform.d b/board/evb/findmy/mdk/Objects/fmna_battery_platform.d new file mode 100644 index 0000000..ca79ca8 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_battery_platform.d @@ -0,0 +1,68 @@ +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c +.\objects\fmna_battery_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_battery_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_battery_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_battery_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_battery_platform.o: ..\..\findmy\board.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_battery_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_battery_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_battery_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_battery_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_battery_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\peripheral\rtl876x_adc.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\peripheral\rtl876x_alias.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\platform\adc_lib.h +.\objects\fmna_battery_platform.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h diff --git a/board/evb/findmy/mdk/Objects/fmna_battery_platform.o b/board/evb/findmy/mdk/Objects/fmna_battery_platform.o new file mode 100644 index 0000000..78efc91 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_battery_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_config_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_config_control_point.crf new file mode 100644 index 0000000..c73253e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_config_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_config_control_point.d b/board/evb/findmy/mdk/Objects/fmna_config_control_point.d new file mode 100644 index 0000000..416eb48 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_config_control_point.d @@ -0,0 +1,68 @@ +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c +.\objects\fmna_config_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_config_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_config_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_config_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_config_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_config_control_point.o: ..\..\findmy\board.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_config_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_config_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_config_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_config_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_config_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h diff --git a/board/evb/findmy/mdk/Objects/fmna_config_control_point.o b/board/evb/findmy/mdk/Objects/fmna_config_control_point.o new file mode 100644 index 0000000..e779a43 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_config_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_connection.crf b/board/evb/findmy/mdk/Objects/fmna_connection.crf new file mode 100644 index 0000000..58a6ade Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_connection.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_connection.d b/board/evb/findmy/mdk/Objects/fmna_connection.d new file mode 100644 index 0000000..dac36fa --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_connection.d @@ -0,0 +1,70 @@ +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c +.\objects\fmna_connection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_connection.o: ..\..\findmy\flash_map.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_connection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_connection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_connection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_connection.o: ..\..\findmy\board.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_connection.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_connection.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_connection.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_connection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_connection.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_connection.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_connection.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_connection.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_connection.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_connection.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_connection.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h +.\objects\fmna_connection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h diff --git a/board/evb/findmy/mdk/Objects/fmna_connection.o b/board/evb/findmy/mdk/Objects/fmna_connection.o new file mode 100644 index 0000000..3f00001 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_connection.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_connection_platform.crf b/board/evb/findmy/mdk/Objects/fmna_connection_platform.crf new file mode 100644 index 0000000..bc98849 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_connection_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_connection_platform.d b/board/evb/findmy/mdk/Objects/fmna_connection_platform.d new file mode 100644 index 0000000..45c1529 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_connection_platform.d @@ -0,0 +1,68 @@ +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c +.\objects\fmna_connection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_connection_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_connection_platform.o: ..\..\findmy\board.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_connection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_connection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_connection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_connection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_connection_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_connection_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_connection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h +.\objects\fmna_connection_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_conn_le.h diff --git a/board/evb/findmy/mdk/Objects/fmna_connection_platform.o b/board/evb/findmy/mdk/Objects/fmna_connection_platform.o new file mode 100644 index 0000000..0384398 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_connection_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_crypto.crf b/board/evb/findmy/mdk/Objects/fmna_crypto.crf new file mode 100644 index 0000000..d8cce1e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_crypto.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_crypto.d b/board/evb/findmy/mdk/Objects/fmna_crypto.d new file mode 100644 index 0000000..b66d49d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_crypto.d @@ -0,0 +1,104 @@ +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_crypto.o: ..\..\findmy\flash_map.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_crypto.o: ..\..\findmy\board.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_crypto.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_crypto.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\fm-crypto.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fmna_crypto.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform/sha256.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/aes.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdsa.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecp.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/bignum.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\inc\platform\app_section.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ecdh.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\fmna_crypto.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/base64.h diff --git a/board/evb/findmy/mdk/Objects/fmna_crypto.o b/board/evb/findmy/mdk/Objects/fmna_crypto.o new file mode 100644 index 0000000..21da90e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_crypto.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_debug_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.crf new file mode 100644 index 0000000..6076b61 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_debug_control_point.d b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.d new file mode 100644 index 0000000..296d980 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.d @@ -0,0 +1,67 @@ +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c +.\objects\fmna_debug_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_debug_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_debug_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_debug_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_debug_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_debug_control_point.o: ..\..\findmy\board.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_debug_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_debug_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_debug_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h diff --git a/board/evb/findmy/mdk/Objects/fmna_debug_control_point.o b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.o new file mode 100644 index 0000000..841958e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_debug_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_dfu_platform.crf b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.crf new file mode 100644 index 0000000..e9a2503 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_dfu_platform.d b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.d new file mode 100644 index 0000000..b33b7b9 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.d @@ -0,0 +1,68 @@ +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c +.\objects\fmna_dfu_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_dfu_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_dfu_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_dfu_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_dfu_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_dfu_platform.o: ..\..\findmy\board.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_dfu_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_dfu_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\dfu_flash.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\app\dfu_api.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\inc\platform\sha256.h +.\objects\fmna_dfu_platform.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h diff --git a/board/evb/findmy/mdk/Objects/fmna_dfu_platform.o b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.o new file mode 100644 index 0000000..6e32e1e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_dfu_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gap_platform.crf b/board/evb/findmy/mdk/Objects/fmna_gap_platform.crf new file mode 100644 index 0000000..5750752 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gap_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gap_platform.d b/board/evb/findmy/mdk/Objects/fmna_gap_platform.d new file mode 100644 index 0000000..eee2d60 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_gap_platform.d @@ -0,0 +1,47 @@ +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c +.\objects\fmna_gap_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_gap_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_gap_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_gap_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_adv.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_conn_le.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_gap_platform.o: ..\..\findmy\board.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_gap_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\os\os_queue.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_gap_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_gap_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_gap_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h +.\objects\fmna_gap_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fmna_gap_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h diff --git a/board/evb/findmy/mdk/Objects/fmna_gap_platform.o b/board/evb/findmy/mdk/Objects/fmna_gap_platform.o new file mode 100644 index 0000000..a954651 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gap_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt.crf b/board/evb/findmy/mdk/Objects/fmna_gatt.crf new file mode 100644 index 0000000..0dfb229 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gatt.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt.d b/board/evb/findmy/mdk/Objects/fmna_gatt.d new file mode 100644 index 0000000..ff8ebfa --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_gatt.d @@ -0,0 +1,71 @@ +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c +.\objects\fmna_gatt.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_gatt.o: ..\..\findmy\flash_map.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_gatt.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_gatt.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_gatt.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_gatt.o: ..\..\findmy\board.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_gatt.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_gatt.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_gatt.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_gatt.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.h +.\objects\fmna_gatt.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.h diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt.o b/board/evb/findmy/mdk/Objects/fmna_gatt.o new file mode 100644 index 0000000..88d035c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gatt.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt_platform.crf b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.crf new file mode 100644 index 0000000..92cce54 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt_platform.d b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.d new file mode 100644 index 0000000..8c92cd1 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.d @@ -0,0 +1,75 @@ +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c +.\objects\fmna_gatt_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_gatt_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_gatt_platform.o: ..\..\findmy\board.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_gatt_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_gatt_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_gatt_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_gatt_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_gatt_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\os\os_sync.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\os\os_sched.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_direct_msg.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_conn_le.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\profile\server\ias.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\inc\bluetooth\profile\server\dis.h +.\objects\fmna_gatt_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h diff --git a/board/evb/findmy/mdk/Objects/fmna_gatt_platform.o b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.o new file mode 100644 index 0000000..6babe9f Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_gatt_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_malloc_platform.crf b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.crf new file mode 100644 index 0000000..1705d13 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_malloc_platform.d b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.d new file mode 100644 index 0000000..bb19e31 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.d @@ -0,0 +1,12 @@ +.\objects\fmna_malloc_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c +.\objects\fmna_malloc_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_malloc_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_malloc_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_malloc_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_malloc_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_malloc_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_malloc_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_malloc_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fmna_malloc_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_malloc_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_malloc_platform.o: ..\..\findmy\board.h diff --git a/board/evb/findmy/mdk/Objects/fmna_malloc_platform.o b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.o new file mode 100644 index 0000000..39bf989 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_malloc_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection.crf b/board/evb/findmy/mdk/Objects/fmna_motion_detection.crf new file mode 100644 index 0000000..73fcb7a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_motion_detection.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection.d b/board/evb/findmy/mdk/Objects/fmna_motion_detection.d new file mode 100644 index 0000000..2d00062 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_motion_detection.d @@ -0,0 +1,67 @@ +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c +.\objects\fmna_motion_detection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_motion_detection.o: ..\..\findmy\flash_map.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_motion_detection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_motion_detection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_motion_detection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_motion_detection.o: ..\..\findmy\board.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_motion_detection.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_motion_detection.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_motion_detection.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_motion_detection.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h +.\objects\fmna_motion_detection.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection.o b/board/evb/findmy/mdk/Objects/fmna_motion_detection.o new file mode 100644 index 0000000..09f4512 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_motion_detection.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.crf b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.crf new file mode 100644 index 0000000..369a1b1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.d b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.d new file mode 100644 index 0000000..268f561 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.d @@ -0,0 +1,23 @@ +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c +.\objects\fmna_motion_detection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_motion_detection_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_motion_detection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_motion_detection_platform.o: ..\..\findmy\board.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_motion_detection_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\peripheral\rtl876x_i2c.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_motion_detection_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_motion_detection_platform.o: ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.h diff --git a/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.o b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.o new file mode 100644 index 0000000..60b0eb3 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_motion_detection_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_nfc.crf b/board/evb/findmy/mdk/Objects/fmna_nfc.crf new file mode 100644 index 0000000..e18c686 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_nfc.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_nfc.d b/board/evb/findmy/mdk/Objects/fmna_nfc.d new file mode 100644 index 0000000..4177548 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_nfc.d @@ -0,0 +1,70 @@ +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c +.\objects\fmna_nfc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_nfc.o: ..\..\findmy\flash_map.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_nfc.o: ..\..\findmy\board.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_nfc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_nfc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_nfc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_nfc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_nfc.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_nfc.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_nfc.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_nfc_platform.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\fmna_nfc.o: ..\..\..\..\src\app\findmy\fmna_peripheral\url_ndef.h diff --git a/board/evb/findmy/mdk/Objects/fmna_nfc.o b/board/evb/findmy/mdk/Objects/fmna_nfc.o new file mode 100644 index 0000000..21ec00e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_nfc.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.crf new file mode 100644 index 0000000..00403e1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.d b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.d new file mode 100644 index 0000000..b9c7116 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.d @@ -0,0 +1,67 @@ +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c +.\objects\fmna_nonowner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_nonowner_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_nonowner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_nonowner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_nonowner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_nonowner_control_point.o: ..\..\findmy\board.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_nonowner_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_nonowner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_nonowner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h diff --git a/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.o b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.o new file mode 100644 index 0000000..e9a8710 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_nonowner_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.crf new file mode 100644 index 0000000..fde814f Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.d b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.d new file mode 100644 index 0000000..a0b7a76 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.d @@ -0,0 +1,67 @@ +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c +.\objects\fmna_paired_owner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_paired_owner_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_paired_owner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_paired_owner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_paired_owner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_paired_owner_control_point.o: ..\..\findmy\board.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_paired_owner_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_paired_owner_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_paired_owner_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h diff --git a/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.o b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.o new file mode 100644 index 0000000..2a8e517 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_paired_owner_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.crf new file mode 100644 index 0000000..d22fdbe Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.d b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.d new file mode 100644 index 0000000..67e94db --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.d @@ -0,0 +1,67 @@ +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c +.\objects\fmna_pairing_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_pairing_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\findmy\board.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_pairing_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_pairing_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_pairing_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_pairing_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_pairing_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_pairing_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h diff --git a/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.o b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.o new file mode 100644 index 0000000..53a4503 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_pairing_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_peer_manager.crf b/board/evb/findmy/mdk/Objects/fmna_peer_manager.crf new file mode 100644 index 0000000..50997c6 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_peer_manager.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_peer_manager.d b/board/evb/findmy/mdk/Objects/fmna_peer_manager.d new file mode 100644 index 0000000..90c15cd --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_peer_manager.d @@ -0,0 +1,67 @@ +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c +.\objects\fmna_peer_manager.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_peer_manager.o: ..\..\findmy\flash_map.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_peer_manager.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_peer_manager.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_peer_manager.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_peer_manager.o: ..\..\findmy\board.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_peer_manager.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_peer_manager.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_peer_manager.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_peer_manager.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_peer_manager.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h diff --git a/board/evb/findmy/mdk/Objects/fmna_peer_manager.o b/board/evb/findmy/mdk/Objects/fmna_peer_manager.o new file mode 100644 index 0000000..650f0e1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_peer_manager.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_sound_platform.crf b/board/evb/findmy/mdk/Objects/fmna_sound_platform.crf new file mode 100644 index 0000000..a1f622c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_sound_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_sound_platform.d b/board/evb/findmy/mdk/Objects/fmna_sound_platform.d new file mode 100644 index 0000000..6782fd9 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_sound_platform.d @@ -0,0 +1,29 @@ +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c +.\objects\fmna_sound_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_sound_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_sound_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_sound_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_sound_platform.o: ..\..\findmy\board.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_sound_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\peripheral\rtl876x_tim.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_sound_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_sound_platform.o: ..\..\..\..\inc\os\os_sched.h diff --git a/board/evb/findmy/mdk/Objects/fmna_sound_platform.o b/board/evb/findmy/mdk/Objects/fmna_sound_platform.o new file mode 100644 index 0000000..0aa51d5 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_sound_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_state_machine.crf b/board/evb/findmy/mdk/Objects/fmna_state_machine.crf new file mode 100644 index 0000000..29fff5a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_state_machine.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_state_machine.d b/board/evb/findmy/mdk/Objects/fmna_state_machine.d new file mode 100644 index 0000000..b15f444 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_state_machine.d @@ -0,0 +1,72 @@ +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c +.\objects\fmna_state_machine.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_state_machine.o: ..\..\findmy\flash_map.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_state_machine.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_state_machine.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_state_machine.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_state_machine.o: ..\..\findmy\board.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_state_machine.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_state_machine.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_state_machine.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h +.\objects\fmna_state_machine.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.h +.\objects\fmna_state_machine.o: ..\..\..\..\inc\os\os_sched.h diff --git a/board/evb/findmy/mdk/Objects/fmna_state_machine.o b/board/evb/findmy/mdk/Objects/fmna_state_machine.o new file mode 100644 index 0000000..8a00e53 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_state_machine.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_timer_platform.crf b/board/evb/findmy/mdk/Objects/fmna_timer_platform.crf new file mode 100644 index 0000000..1f86b0b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_timer_platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_timer_platform.d b/board/evb/findmy/mdk/Objects/fmna_timer_platform.d new file mode 100644 index 0000000..ae54000 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_timer_platform.d @@ -0,0 +1,67 @@ +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c +.\objects\fmna_timer_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_timer_platform.o: ..\..\findmy\flash_map.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_timer_platform.o: ..\..\findmy\board.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_timer_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_timer_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_timer_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_timer_platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_timer_platform.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_timer_platform.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_timer_platform.o: ..\..\findmy\otp_config.h +.\objects\fmna_timer_platform.o: ..\..\..\..\inc\platform\app_section.h +.\objects\fmna_timer_platform.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h diff --git a/board/evb/findmy/mdk/Objects/fmna_timer_platform.o b/board/evb/findmy/mdk/Objects/fmna_timer_platform.o new file mode 100644 index 0000000..c33c564 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_timer_platform.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.crf b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.crf new file mode 100644 index 0000000..7639ee2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.d b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.d new file mode 100644 index 0000000..61e8fc7 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.d @@ -0,0 +1,77 @@ +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_uarp_control_point.o: ..\..\findmy\flash_map.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_uarp_control_point.o: ..\..\findmy\board.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_uarp_control_point.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\fmna_uarp_control_point.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\inc\os\os_sync.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h +.\objects\fmna_uarp_control_point.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h diff --git a/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.o b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.o new file mode 100644 index 0000000..369ba5d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_uarp_control_point.o differ diff --git a/board/evb/findmy/mdk/Objects/fmna_version.crf b/board/evb/findmy/mdk/Objects/fmna_version.crf new file mode 100644 index 0000000..82a4971 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_version.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmna_version.d b/board/evb/findmy/mdk/Objects/fmna_version.d new file mode 100644 index 0000000..f0ad423 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmna_version.d @@ -0,0 +1,66 @@ +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c +.\objects\fmna_version.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmna_version.o: ..\..\findmy\flash_map.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_version.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmna_version.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmna_version.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmna_version.o: ..\..\findmy\board.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmna_version.o: ..\..\findmy\platform_autoconf.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\ftl.h +.\objects\fmna_version.o: ..\..\..\..\inc\os\os_msg.h +.\objects\fmna_version.o: ..\..\..\..\inc\os\os_mem.h +.\objects\fmna_version.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\fmna_version.o: ..\..\..\..\inc\os\os_timer.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\fmna_version.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\fmna_version.o: ..\..\..\..\inc\app\app_msg.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\fmna_version.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\fmna_version.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\fmna_version.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmna_version.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\fmna_version.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h diff --git a/board/evb/findmy/mdk/Objects/fmna_version.o b/board/evb/findmy/mdk/Objects/fmna_version.o new file mode 100644 index 0000000..70581d8 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmna_version.o differ diff --git a/board/evb/findmy/mdk/Objects/fmnasampleuarp.crf b/board/evb/findmy/mdk/Objects/fmnasampleuarp.crf new file mode 100644 index 0000000..452cf89 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmnasampleuarp.crf differ diff --git a/board/evb/findmy/mdk/Objects/fmnasampleuarp.d b/board/evb/findmy/mdk/Objects/fmnasampleuarp.d new file mode 100644 index 0000000..c678236 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/fmnasampleuarp.d @@ -0,0 +1,32 @@ +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\fmnasampleuarp.o: ..\..\findmy\flash_map.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatform.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.h +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\fmnasampleuarp.o: ..\..\findmy\board.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\otp.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\fmnasampleuarp.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\trace.h +.\objects\fmnasampleuarp.o: ..\..\findmy\platform_autoconf.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\os\os_sync.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPProtocolDefines.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.h +.\objects\fmnasampleuarp.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\fmnasampleuarp.o: ..\..\..\..\inc\platform\flash_device.h diff --git a/board/evb/findmy/mdk/Objects/fmnasampleuarp.o b/board/evb/findmy/mdk/Objects/fmnasampleuarp.o new file mode 100644 index 0000000..ce044d1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/fmnasampleuarp.o differ diff --git a/board/evb/findmy/mdk/Objects/gcm.crf b/board/evb/findmy/mdk/Objects/gcm.crf new file mode 100644 index 0000000..c6230ca Binary files /dev/null and b/board/evb/findmy/mdk/Objects/gcm.crf differ diff --git a/board/evb/findmy/mdk/Objects/gcm.d b/board/evb/findmy/mdk/Objects/gcm.d new file mode 100644 index 0000000..428288a --- /dev/null +++ b/board/evb/findmy/mdk/Objects/gcm.d @@ -0,0 +1,32 @@ +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\gcm.o: ..\..\findmy\flash_map.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\gcm.o: ..\..\..\..\inc\os\os_mem.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\gcm.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\gcm.o: ..\..\..\..\inc\platform\trace.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\gcm.o: ..\..\findmy\platform_autoconf.h +.\objects\gcm.o: ..\..\findmy\board.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/gcm.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/cipher.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\gcm.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\gcm.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/constant_time.h diff --git a/board/evb/findmy/mdk/Objects/gcm.o b/board/evb/findmy/mdk/Objects/gcm.o new file mode 100644 index 0000000..7215f52 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/gcm.o differ diff --git a/board/evb/findmy/mdk/Objects/hids_kb.crf b/board/evb/findmy/mdk/Objects/hids_kb.crf new file mode 100644 index 0000000..206385d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/hids_kb.crf differ diff --git a/board/evb/findmy/mdk/Objects/hids_kb.d b/board/evb/findmy/mdk/Objects/hids_kb.d new file mode 100644 index 0000000..972077c --- /dev/null +++ b/board/evb/findmy/mdk/Objects/hids_kb.d @@ -0,0 +1,18 @@ +.\objects\hids_kb.o: ..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c +.\objects\hids_kb.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\hids_kb.o: ..\..\findmy\flash_map.h +.\objects\hids_kb.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\hids_kb.o: ..\..\..\..\inc\platform\trace.h +.\objects\hids_kb.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\hids_kb.o: ..\..\findmy\platform_autoconf.h +.\objects\hids_kb.o: ..\..\findmy\board.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\hids_kb.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\hids_kb.o: ..\..\..\..\inc\bluetooth\profile\server\hids_kb.h diff --git a/board/evb/findmy/mdk/Objects/hids_kb.o b/board/evb/findmy/mdk/Objects/hids_kb.o new file mode 100644 index 0000000..6df0b8b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/hids_kb.o differ diff --git a/board/evb/findmy/mdk/Objects/ias.crf b/board/evb/findmy/mdk/Objects/ias.crf new file mode 100644 index 0000000..60535f2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ias.crf differ diff --git a/board/evb/findmy/mdk/Objects/ias.d b/board/evb/findmy/mdk/Objects/ias.d new file mode 100644 index 0000000..7324e3f --- /dev/null +++ b/board/evb/findmy/mdk/Objects/ias.d @@ -0,0 +1,18 @@ +.\objects\ias.o: ..\..\..\..\src\ble\profile\server\ias.c +.\objects\ias.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\ias.o: ..\..\findmy\flash_map.h +.\objects\ias.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\ias.o: ..\..\..\..\inc\platform\trace.h +.\objects\ias.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\ias.o: ..\..\findmy\platform_autoconf.h +.\objects\ias.o: ..\..\findmy\board.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\ias.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\ias.o: ..\..\..\..\inc\bluetooth\profile\server\ias.h diff --git a/board/evb/findmy/mdk/Objects/ias.o b/board/evb/findmy/mdk/Objects/ias.o new file mode 100644 index 0000000..58eefe6 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/ias.o differ diff --git a/board/evb/findmy/mdk/Objects/kdf963.crf b/board/evb/findmy/mdk/Objects/kdf963.crf new file mode 100644 index 0000000..2dea7f5 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/kdf963.crf differ diff --git a/board/evb/findmy/mdk/Objects/kdf963.d b/board/evb/findmy/mdk/Objects/kdf963.d new file mode 100644 index 0000000..048d137 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/kdf963.d @@ -0,0 +1,30 @@ +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\kdf963.o: ..\..\findmy\flash_map.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/kdf963.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/common.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\kdf963.o: ..\..\..\..\inc\os\os_mem.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\kdf963.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\kdf963.o: ..\..\..\..\inc\platform\trace.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\kdf963.o: ..\..\findmy\platform_autoconf.h +.\objects\kdf963.o: ..\..\findmy\board.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\kdf963.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\kdf963.o: ..\..\..\..\inc\platform/sha256.h +.\objects\kdf963.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h diff --git a/board/evb/findmy/mdk/Objects/kdf963.o b/board/evb/findmy/mdk/Objects/kdf963.o new file mode 100644 index 0000000..805e975 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/kdf963.o differ diff --git a/board/evb/findmy/mdk/Objects/key_handle.crf b/board/evb/findmy/mdk/Objects/key_handle.crf new file mode 100644 index 0000000..cb8e048 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/key_handle.crf differ diff --git a/board/evb/findmy/mdk/Objects/key_handle.d b/board/evb/findmy/mdk/Objects/key_handle.d new file mode 100644 index 0000000..8b8785d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/key_handle.d @@ -0,0 +1,71 @@ +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c +.\objects\key_handle.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\key_handle.o: ..\..\findmy\flash_map.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_gpio.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\key_handle.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_nvic.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\key_handle.o: ..\..\findmy\board.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h +.\objects\key_handle.o: ..\..\..\..\inc\app\app_msg.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\otp.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\key_handle.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\trace.h +.\objects\key_handle.o: ..\..\findmy\platform_autoconf.h +.\objects\key_handle.o: ..\..\..\..\inc\os\os_timer.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\key_handle.o: ..\..\..\..\inc\os\os_sched.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\key_handle.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\key_handle.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\ftl.h +.\objects\key_handle.o: ..\..\..\..\inc\os\os_msg.h +.\objects\key_handle.o: ..\..\..\..\inc\os\os_mem.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\key_handle.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\key_handle.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\key_handle.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\key_handle.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\key_handle.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h diff --git a/board/evb/findmy/mdk/Objects/key_handle.o b/board/evb/findmy/mdk/Objects/key_handle.o new file mode 100644 index 0000000..2762885 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/key_handle.o differ diff --git a/board/evb/findmy/mdk/Objects/main.crf b/board/evb/findmy/mdk/Objects/main.crf new file mode 100644 index 0000000..5ceca40 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/main.crf differ diff --git a/board/evb/findmy/mdk/Objects/main.d b/board/evb/findmy/mdk/Objects/main.d new file mode 100644 index 0000000..1cf2dd4 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/main.d @@ -0,0 +1,79 @@ +.\objects\main.o: ..\..\..\..\src\app\findmy\main.c +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\main.o: ..\..\findmy\flash_map.h +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\main.o: ..\..\..\..\inc\os\os_sched.h +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\main.o: ..\..\..\..\inc\platform\trace.h +.\objects\main.o: ..\..\findmy\platform_autoconf.h +.\objects\main.o: ..\..\findmy\board.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\main.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_adv.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\main.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\main.o: ..\..\..\..\inc\platform\otp.h +.\objects\main.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\main.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\main.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\main.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\main.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\main.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\main.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\main.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\main.o: ..\..\..\..\inc\app\app_msg.h +.\objects\main.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\main.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\main.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\main.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\main.o: ..\..\..\..\inc\os\os_timer.h +.\objects\main.o: ..\..\findmy\otp_config.h +.\objects\main.o: ..\..\..\..\inc\platform\dlps.h +.\objects\main.o: ..\..\..\..\inc\os\os_queue.h +.\objects\main.o: ..\..\..\..\inc\peripheral\rtl876x_io_dlps.h +.\objects\main.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.h +.\objects\main.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\main.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\main.o: ..\..\..\..\inc\platform\ftl.h +.\objects\main.o: ..\..\..\..\inc\os\os_msg.h +.\objects\main.o: ..\..\..\..\inc\os\os_mem.h +.\objects\main.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\main.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\main.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\main.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\main.o: ..\..\..\..\src\app\findmy\serial_number_send.h +.\objects\main.o: ..\..\..\..\inc\platform\app_section.h +.\objects\main.o: ..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h diff --git a/board/evb/findmy/mdk/Objects/main.o b/board/evb/findmy/mdk/Objects/main.o new file mode 100644 index 0000000..3a1216d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/main.o differ diff --git a/board/evb/findmy/mdk/Objects/md.crf b/board/evb/findmy/mdk/Objects/md.crf new file mode 100644 index 0000000..b823321 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/md.crf differ diff --git a/board/evb/findmy/mdk/Objects/md.d b/board/evb/findmy/mdk/Objects/md.d new file mode 100644 index 0000000..76c08de --- /dev/null +++ b/board/evb/findmy/mdk/Objects/md.d @@ -0,0 +1,37 @@ +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\md.o: ..\..\findmy\flash_map.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\md.o: ..\..\..\..\inc\os\os_mem.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\md.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\md.o: ..\..\..\..\inc\platform\trace.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\md.o: ..\..\findmy\platform_autoconf.h +.\objects\md.o: ..\..\findmy\board.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md_wrap.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/md5.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/ripemd160.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\md.o: ..\..\..\..\inc\platform/sha256.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\md.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\md.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/md.o b/board/evb/findmy/mdk/Objects/md.o new file mode 100644 index 0000000..c64552c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/md.o differ diff --git a/board/evb/findmy/mdk/Objects/overlay_mgr.crf b/board/evb/findmy/mdk/Objects/overlay_mgr.crf new file mode 100644 index 0000000..d68d5c1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/overlay_mgr.crf differ diff --git a/board/evb/findmy/mdk/Objects/overlay_mgr.d b/board/evb/findmy/mdk/Objects/overlay_mgr.d new file mode 100644 index 0000000..59a5037 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/overlay_mgr.d @@ -0,0 +1,6 @@ +.\objects\overlay_mgr.o: ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c +.\objects\overlay_mgr.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\overlay_mgr.o: ..\..\findmy\flash_map.h +.\objects\overlay_mgr.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\overlay_mgr.o: ..\..\..\..\inc\platform\overlay_mgr.h +.\objects\overlay_mgr.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h diff --git a/board/evb/findmy/mdk/Objects/overlay_mgr.o b/board/evb/findmy/mdk/Objects/overlay_mgr.o new file mode 100644 index 0000000..dccce5c Binary files /dev/null and b/board/evb/findmy/mdk/Objects/overlay_mgr.o differ diff --git a/board/evb/findmy/mdk/Objects/platform.crf b/board/evb/findmy/mdk/Objects/platform.crf new file mode 100644 index 0000000..34281b7 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/platform.crf differ diff --git a/board/evb/findmy/mdk/Objects/platform.d b/board/evb/findmy/mdk/Objects/platform.d new file mode 100644 index 0000000..7a3e6b6 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/platform.d @@ -0,0 +1,27 @@ +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\platform.o: ..\..\findmy\flash_map.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\platform.o: ..\..\..\..\inc\os\os_mem.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\platform.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\platform.o: ..\..\..\..\inc\platform\trace.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\platform.o: ..\..\findmy\platform_autoconf.h +.\objects\platform.o: ..\..\findmy\board.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\platform.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\platform.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h diff --git a/board/evb/findmy/mdk/Objects/platform.o b/board/evb/findmy/mdk/Objects/platform.o new file mode 100644 index 0000000..e91e1ef Binary files /dev/null and b/board/evb/findmy/mdk/Objects/platform.o differ diff --git a/board/evb/findmy/mdk/Objects/platform_util.crf b/board/evb/findmy/mdk/Objects/platform_util.crf new file mode 100644 index 0000000..f1ed2b8 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/platform_util.crf differ diff --git a/board/evb/findmy/mdk/Objects/platform_util.d b/board/evb/findmy/mdk/Objects/platform_util.d new file mode 100644 index 0000000..6f333bb --- /dev/null +++ b/board/evb/findmy/mdk/Objects/platform_util.d @@ -0,0 +1,28 @@ +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\platform_util.o: ..\..\findmy\flash_map.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\platform_util.o: ..\..\..\..\inc\os\os_mem.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\platform_util.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\platform_util.o: ..\..\..\..\inc\platform\trace.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\platform_util.o: ..\..\findmy\platform_autoconf.h +.\objects\platform_util.o: ..\..\findmy\board.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\platform_util.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/threading.h +.\objects\platform_util.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h diff --git a/board/evb/findmy/mdk/Objects/platform_util.o b/board/evb/findmy/mdk/Objects/platform_util.o new file mode 100644 index 0000000..8ce1642 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/platform_util.o differ diff --git a/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.crf b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.crf new file mode 100644 index 0000000..d47984a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.crf differ diff --git a/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.d b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.d new file mode 100644 index 0000000..1fedef2 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.d @@ -0,0 +1,26 @@ +.\objects\reset_watch_dog_timer.o: ..\..\..\..\src\app\findmy\reset_watch_dog_timer.c +.\objects\reset_watch_dog_timer.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\reset_watch_dog_timer.o: ..\..\findmy\flash_map.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\peripheral\rtl876x_tim.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\reset_watch_dog_timer.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\peripheral\rtl876x_nvic.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\app\app_msg.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\reset_watch_dog_timer.o: ..\..\findmy\board.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\otp.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\reset_watch_dog_timer.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\trace.h +.\objects\reset_watch_dog_timer.o: ..\..\findmy\platform_autoconf.h +.\objects\reset_watch_dog_timer.o: ..\..\..\..\inc\platform\app_section.h diff --git a/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.o b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.o new file mode 100644 index 0000000..79b26b2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/reset_watch_dog_timer.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_adc.crf b/board/evb/findmy/mdk/Objects/rtl876x_adc.crf new file mode 100644 index 0000000..424f4bc Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_adc.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_adc.d b/board/evb/findmy/mdk/Objects/rtl876x_adc.d new file mode 100644 index 0000000..e7e26f8 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_adc.d @@ -0,0 +1,17 @@ +.\objects\rtl876x_adc.o: ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c +.\objects\rtl876x_adc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_adc.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_adc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\peripheral\rtl876x_adc.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\peripheral\rtl876x_alias.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\rtl876x_adc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\rtl876x_adc.o: ..\..\..\..\inc\platform\adc_lib.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_adc.o b/board/evb/findmy/mdk/Objects/rtl876x_adc.o new file mode 100644 index 0000000..8f04d4a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_adc.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.crf b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.crf new file mode 100644 index 0000000..da8b795 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.d b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.d new file mode 100644 index 0000000..390dbe0 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.d @@ -0,0 +1,12 @@ +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c +.\objects\rtl876x_aon_wdg.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_aon_wdg.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_aon_wdg.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_aon_wdg.o: ..\..\..\..\inc\peripheral\rtl876x_aon_wdg.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.o b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.o new file mode 100644 index 0000000..a38fbf7 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_aon_wdg.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_gpio.crf b/board/evb/findmy/mdk/Objects/rtl876x_gpio.crf new file mode 100644 index 0000000..fe30f78 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_gpio.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_gpio.d b/board/evb/findmy/mdk/Objects/rtl876x_gpio.d new file mode 100644 index 0000000..22aa10a --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_gpio.d @@ -0,0 +1,13 @@ +.\objects\rtl876x_gpio.o: ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c +.\objects\rtl876x_gpio.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_gpio.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_gpio.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_gpio.o: ..\..\..\..\inc\peripheral\rtl876x_gpio.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_gpio.o b/board/evb/findmy/mdk/Objects/rtl876x_gpio.o new file mode 100644 index 0000000..a8df351 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_gpio.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_i2c.crf b/board/evb/findmy/mdk/Objects/rtl876x_i2c.crf new file mode 100644 index 0000000..6790e03 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_i2c.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_i2c.d b/board/evb/findmy/mdk/Objects/rtl876x_i2c.d new file mode 100644 index 0000000..60ff866 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_i2c.d @@ -0,0 +1,13 @@ +.\objects\rtl876x_i2c.o: ..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c +.\objects\rtl876x_i2c.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_i2c.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_i2c.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_i2c.o: ..\..\..\..\inc\peripheral\rtl876x_i2c.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_i2c.o b/board/evb/findmy/mdk/Objects/rtl876x_i2c.o new file mode 100644 index 0000000..a28c6de Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_i2c.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.crf b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.crf new file mode 100644 index 0000000..64c8bd2 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.d b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.d new file mode 100644 index 0000000..4945ccf --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.d @@ -0,0 +1,29 @@ +.\objects\rtl876x_io_dlps.o: ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c +.\objects\rtl876x_io_dlps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_io_dlps.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_io_dlps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_io_dlps.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_io_dlps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\rtl876x_io_dlps.o: ..\..\findmy\board.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\dlps.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\os\os_queue.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\otp.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_nvic.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\app_section.h +.\objects\rtl876x_io_dlps.o: ..\..\findmy\platform_autoconf.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\trace.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\test_mode.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\rtl876x_io_dlps.o: ..\..\..\..\inc\peripheral\rtl876x_tim.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.o b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.o new file mode 100644 index 0000000..7757264 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_io_dlps.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_nvic.crf b/board/evb/findmy/mdk/Objects/rtl876x_nvic.crf new file mode 100644 index 0000000..f25ca3f Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_nvic.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_nvic.d b/board/evb/findmy/mdk/Objects/rtl876x_nvic.d new file mode 100644 index 0000000..cefe9ed --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_nvic.d @@ -0,0 +1,12 @@ +.\objects\rtl876x_nvic.o: ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c +.\objects\rtl876x_nvic.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_nvic.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\peripheral\rtl876x_nvic.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_nvic.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_nvic.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_nvic.o b/board/evb/findmy/mdk/Objects/rtl876x_nvic.o new file mode 100644 index 0000000..b5165d5 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_nvic.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_pinmux.crf b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.crf new file mode 100644 index 0000000..e29ec99 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_pinmux.d b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.d new file mode 100644 index 0000000..778b527 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.d @@ -0,0 +1,13 @@ +.\objects\rtl876x_pinmux.o: ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c +.\objects\rtl876x_pinmux.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_pinmux.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_pinmux.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_pinmux.o: ..\..\..\..\inc\peripheral\rtl876x_pinmux.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_pinmux.o b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.o new file mode 100644 index 0000000..5d7513e Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_pinmux.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_rcc.crf b/board/evb/findmy/mdk/Objects/rtl876x_rcc.crf new file mode 100644 index 0000000..4c0caa6 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_rcc.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_rcc.d b/board/evb/findmy/mdk/Objects/rtl876x_rcc.d new file mode 100644 index 0000000..fad3629 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_rcc.d @@ -0,0 +1,13 @@ +.\objects\rtl876x_rcc.o: ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c +.\objects\rtl876x_rcc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_rcc.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_rcc.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\rtl876x_rcc.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_rcc.o b/board/evb/findmy/mdk/Objects/rtl876x_rcc.o new file mode 100644 index 0000000..f78a037 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_rcc.o differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_tim.crf b/board/evb/findmy/mdk/Objects/rtl876x_tim.crf new file mode 100644 index 0000000..73066ed Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_tim.crf differ diff --git a/board/evb/findmy/mdk/Objects/rtl876x_tim.d b/board/evb/findmy/mdk/Objects/rtl876x_tim.d new file mode 100644 index 0000000..83b02c2 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/rtl876x_tim.d @@ -0,0 +1,13 @@ +.\objects\rtl876x_tim.o: ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c +.\objects\rtl876x_tim.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\rtl876x_tim.o: ..\..\findmy\flash_map.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\peripheral\rtl876x_rcc.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\rtl876x_tim.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\rtl876x_tim.o: ..\..\..\..\inc\peripheral\rtl876x_tim.h diff --git a/board/evb/findmy/mdk/Objects/rtl876x_tim.o b/board/evb/findmy/mdk/Objects/rtl876x_tim.o new file mode 100644 index 0000000..7a400c9 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/rtl876x_tim.o differ diff --git a/board/evb/findmy/mdk/Objects/sdd_service.crf b/board/evb/findmy/mdk/Objects/sdd_service.crf new file mode 100644 index 0000000..59ba23d Binary files /dev/null and b/board/evb/findmy/mdk/Objects/sdd_service.crf differ diff --git a/board/evb/findmy/mdk/Objects/sdd_service.d b/board/evb/findmy/mdk/Objects/sdd_service.d new file mode 100644 index 0000000..65d76b0 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/sdd_service.d @@ -0,0 +1,18 @@ +.\objects\sdd_service.o: ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c +.\objects\sdd_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\sdd_service.o: ..\..\findmy\flash_map.h +.\objects\sdd_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\sdd_service.o: ..\..\..\..\inc\platform\trace.h +.\objects\sdd_service.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\sdd_service.o: ..\..\findmy\platform_autoconf.h +.\objects\sdd_service.o: ..\..\findmy\board.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\sdd_service.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\sdd_service.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\sdd_service.o: ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.h diff --git a/board/evb/findmy/mdk/Objects/sdd_service.o b/board/evb/findmy/mdk/Objects/sdd_service.o new file mode 100644 index 0000000..63a6cae Binary files /dev/null and b/board/evb/findmy/mdk/Objects/sdd_service.o differ diff --git a/board/evb/findmy/mdk/Objects/serial_number_send.crf b/board/evb/findmy/mdk/Objects/serial_number_send.crf new file mode 100644 index 0000000..decb048 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/serial_number_send.crf differ diff --git a/board/evb/findmy/mdk/Objects/serial_number_send.d b/board/evb/findmy/mdk/Objects/serial_number_send.d new file mode 100644 index 0000000..7904623 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/serial_number_send.d @@ -0,0 +1,70 @@ +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\serial_number_send.c +.\objects\serial_number_send.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\serial_number_send.o: ..\..\findmy\flash_map.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\serial_number_send.h +.\objects\serial_number_send.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\findmy_app.h +.\objects\serial_number_send.o: ..\..\..\..\inc\app\app_msg.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_msg.h +.\objects\serial_number_send.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\serial_number_send.o: ..\..\findmy\board.h +.\objects\serial_number_send.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\serial_number_send.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\custom_app.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.h +.\objects\serial_number_send.o: ..\..\..\..\inc\os\os_timer.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\otp.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\serial_number_send.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_bond_le.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_lib\gap_config.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\app_section.h +.\objects\serial_number_send.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\trace.h +.\objects\serial_number_send.o: ..\..\findmy\platform_autoconf.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\gap\gap_adv.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_util.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_platform_includes.h +.\objects\serial_number_send.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\ftl.h +.\objects\serial_number_send.o: ..\..\..\..\inc\os\os_msg.h +.\objects\serial_number_send.o: ..\..\..\..\inc\os\os_mem.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\app_task.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\key_crypto.h +.\objects\serial_number_send.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\serial_number_send.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\serial_number_send.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.h diff --git a/board/evb/findmy/mdk/Objects/serial_number_send.o b/board/evb/findmy/mdk/Objects/serial_number_send.o new file mode 100644 index 0000000..74d6163 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/serial_number_send.o differ diff --git a/board/evb/findmy/mdk/Objects/sha256.crf b/board/evb/findmy/mdk/Objects/sha256.crf new file mode 100644 index 0000000..b58205a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/sha256.crf differ diff --git a/board/evb/findmy/mdk/Objects/sha256.d b/board/evb/findmy/mdk/Objects/sha256.d new file mode 100644 index 0000000..777f612 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/sha256.d @@ -0,0 +1,30 @@ +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\sha256.o: ..\..\findmy\flash_map.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\common.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/build_info.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/mbedtls_config.h +.\objects\sha256.o: ..\..\..\..\inc\os\os_mem.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\sha256.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\sha256.o: ..\..\..\..\inc\platform\trace.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\sha256.o: ..\..\findmy\platform_autoconf.h +.\objects\sha256.o: ..\..\findmy\board.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_legacy_crypto.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_x509.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/config_adjust_ssl.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/check_config.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\limits.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\alignment.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\assert.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/sha256.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\sha256.o: ..\..\..\..\inc\platform/sha256.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform_util.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/error.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/platform.h +.\objects\sha256.o: ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls/private_access.h +.\objects\sha256.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h diff --git a/board/evb/findmy/mdk/Objects/sha256.o b/board/evb/findmy/mdk/Objects/sha256.o new file mode 100644 index 0000000..7832b5b Binary files /dev/null and b/board/evb/findmy/mdk/Objects/sha256.o differ diff --git a/board/evb/findmy/mdk/Objects/startup_rtl876x.d b/board/evb/findmy/mdk/Objects/startup_rtl876x.d new file mode 100644 index 0000000..d6898be --- /dev/null +++ b/board/evb/findmy/mdk/Objects/startup_rtl876x.d @@ -0,0 +1 @@ +.\objects\startup_rtl876x.o: ..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s diff --git a/board/evb/findmy/mdk/Objects/startup_rtl876x.o b/board/evb/findmy/mdk/Objects/startup_rtl876x.o new file mode 100644 index 0000000..4e9c14a Binary files /dev/null and b/board/evb/findmy/mdk/Objects/startup_rtl876x.o differ diff --git a/board/evb/findmy/mdk/Objects/system_rtl876x.crf b/board/evb/findmy/mdk/Objects/system_rtl876x.crf new file mode 100644 index 0000000..dfd18b1 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/system_rtl876x.crf differ diff --git a/board/evb/findmy/mdk/Objects/system_rtl876x.d b/board/evb/findmy/mdk/Objects/system_rtl876x.d new file mode 100644 index 0000000..335d79d --- /dev/null +++ b/board/evb/findmy/mdk/Objects/system_rtl876x.d @@ -0,0 +1,47 @@ +.\objects\system_rtl876x.o: ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\system_rtl876x.o: ..\..\findmy\flash_map.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\locale.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdarg.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdio.h +.\objects\system_rtl876x.o: ..\..\findmy\version.h +.\objects\system_rtl876x.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\patch_header_check.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\flash_device.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\app_section.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\rom_uuid.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\app_define.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\system_rtl876x.o: ..\..\findmy\mem_config.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\otp.h +.\objects\system_rtl876x.o: ..\..\findmy\platform_autoconf.h +.\objects\system_rtl876x.o: ..\..\findmy\board.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\peripheral\rtl876x_wdg.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\peripheral\rtl876x_bitfields.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\overlay_mgr.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\os\os_sched.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\os\os_sync.h +.\objects\system_rtl876x.o: ..\..\findmy\otp_config.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\test_mode.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\trace.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\system_rtl876x.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\os\os_mem.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\mem_types.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\dfu_flash.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\app\dfu_api.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\sha256.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\rtl876x_lib_platform.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\platform\dlps.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\os\os_queue.h +.\objects\system_rtl876x.o: ..\..\..\..\inc\os\os_timer.h diff --git a/board/evb/findmy/mdk/Objects/system_rtl876x.o b/board/evb/findmy/mdk/Objects/system_rtl876x.o new file mode 100644 index 0000000..3fc0469 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/system_rtl876x.o differ diff --git a/board/evb/findmy/mdk/Objects/tps.crf b/board/evb/findmy/mdk/Objects/tps.crf new file mode 100644 index 0000000..3f2bd87 Binary files /dev/null and b/board/evb/findmy/mdk/Objects/tps.crf differ diff --git a/board/evb/findmy/mdk/Objects/tps.d b/board/evb/findmy/mdk/Objects/tps.d new file mode 100644 index 0000000..651f3c8 --- /dev/null +++ b/board/evb/findmy/mdk/Objects/tps.d @@ -0,0 +1,34 @@ +.\objects\tps.o: ..\..\..\..\src\ble\profile\server\tps.c +.\objects\tps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdint.h +.\objects\tps.o: ..\..\findmy\flash_map.h +.\objects\tps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\string.h +.\objects\tps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdlib.h +.\objects\tps.o: ..\..\..\..\inc\platform\trace.h +.\objects\tps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stdbool.h +.\objects\tps.o: ..\..\findmy\platform_autoconf.h +.\objects\tps.o: ..\..\findmy\board.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\profile\profile_server.h +.\objects\tps.o: ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\upperstack_config.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\bt_types.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\profile\gatt.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\gap_le.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\gap.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\gap_callback_le.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\gap_storage_le.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\gap\gap_le_types.h +.\objects\tps.o: ..\..\..\..\inc\bluetooth\profile\server\tps.h +.\objects\tps.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.h +.\objects\tps.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.h +.\objects\tps.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.h +.\objects\tps.o: ..\..\..\..\src\app\findmy\fmna_adk\fmna_constants.h +.\objects\tps.o: ..\..\..\..\src\app\findmy\fmna_platform\fmna_constants_platform.h +.\objects\tps.o: ..\..\..\..\inc\platform\otp.h +.\objects\tps.o: ..\..\..\..\inc\platform\platform_utils.h +.\objects\tps.o: E:\Keil_V5\ARM\ARMCC\Bin\..\include\stddef.h +.\objects\tps.o: ..\..\..\..\inc\platform\rtl876x.h +.\objects\tps.o: ..\..\..\..\inc\platform\core_cm0plus.h +.\objects\tps.o: ..\..\..\..\inc\platform\core_cmInstr.h +.\objects\tps.o: ..\..\..\..\inc\platform\cmsis_armcc.h +.\objects\tps.o: ..\..\..\..\inc\platform\core_cmFunc.h +.\objects\tps.o: ..\..\..\..\inc\platform\system_rtl876x.h +.\objects\tps.o: ..\..\..\..\inc\platform\rtl876x_ic_type.h diff --git a/board/evb/findmy/mdk/Objects/tps.o b/board/evb/findmy/mdk/Objects/tps.o new file mode 100644 index 0000000..1198cbf Binary files /dev/null and b/board/evb/findmy/mdk/Objects/tps.o differ diff --git a/board/evb/findmy/mdk/after_build_special.bat b/board/evb/findmy/mdk/after_build_special.bat new file mode 100644 index 0000000..5230156 --- /dev/null +++ b/board/evb/findmy/mdk/after_build_special.bat @@ -0,0 +1,2 @@ +@echo off +echo build_after_special bat diff --git a/board/evb/findmy/mdk/app_findmy.sct b/board/evb/findmy/mdk/app_findmy.sct new file mode 100644 index 0000000..2565ba8 --- /dev/null +++ b/board/evb/findmy/mdk/app_findmy.sct @@ -0,0 +1,126 @@ +#! armcc -E +#include "..\mem_config.h" + +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +; APP RAM definitions +#define APP_DATA_ON_ADR APP_GLOBAL_ADDR +#define APP_DATA_ON_SIZE APP_GLOBAL_SIZE + +#define CACHE_DATA_ON_ADR SHARE_CACHE_RAM_ADDR +#define CACHE_DATA_ON_SIZE SHARE_CACHE_RAM_SIZE + +#if (APP_BANK == 0) +#define APP_FLASH_ADR BANK0_APP_ADDR +#else +#define APP_FLASH_ADR BANK1_APP_ADDR +#endif +#define APP_FLASH_SIZE BANK0_APP_SIZE + +#define APP_TRACE_ADR 0x08800000 +#define APP_TRACE_SIZE (4*1024*1024) + + +LOAD_FLASH APP_FLASH_ADR APP_FLASH_SIZE +{ + app.bin +0 + { + * (.app.flash.header) + } + APP_FLASH_HEADER_EXT +0 + { + * (.app.flash.header_ext) + } + +#if (FEATURE_ENCRYPTION == 0) + FLASH_START_ADDR +0; + { + startup_rtl876x.o (RESET, +First) + } +#endif + + FLASH_TEXT +0 + { +#if FEATURE_RAM_CODE + * (InRoot$$Sections) +#else + .ANY (+RO) +#endif + * (.app.flash.text) + * (.app.flash.rodata) + } + + RAM_VECTOR_TABLE 0x00200000 OVERLAY 0xE8 ; 58 ISRs + { + * (VECTOR, +First) + } + +#if (FEATURE_ENCRYPTION == 1) + ENCRYPTION_RAM_CODE APP_DATA_ON_ADR OVERLAY + { + startup_rtl876x.o (RESET, +First) + * (.app.encryption.text) + * (.enc.dummy.align, +Last) + } +#endif + +#if (FEATURE_ENCRYPTION == 1) + RAM_DATA_ON +0 OVERLAY (APP_DATA_ON_SIZE) ;real limit is: (APP_DATA_ON_SIZE - ImageLength(ENCRYPTION_RAM_CODE)) +#else + RAM_DATA_ON APP_DATA_ON_ADR OVERLAY (APP_DATA_ON_SIZE) +#endif + { +#if FEATURE_RAM_CODE + .ANY (+RO) +#endif +; bignum.o + * (.app.data_ram.text) + * (+RW) + * (.ram.dataon.data) + * (+ZI) + * (.ram.dataon.bss) + } + +; overlay section begin + OVERLAY_A ImageLimit(RAM_DATA_ON) OVERLAY + { + *(.app.overlay_a) + } + + OVERLAY_B ImageLimit(RAM_DATA_ON) OVERLAY + { + *(.app.overlay_b) + } + OVERLAY_C ImageLimit(RAM_DATA_ON) OVERLAY + { + *(.app.overlay_c) + } +#if (FEATURE_ENCRYPTION == 0) + ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_A)) <= (APP_DATA_ON_SIZE)) + ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_B)) <= (APP_DATA_ON_SIZE)) + ScatterAssert((ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_C)) <= (APP_DATA_ON_SIZE)) +#else + ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_A)) <= (APP_DATA_ON_SIZE)) + ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_B)) <= (APP_DATA_ON_SIZE)) + ScatterAssert((ImageLength(ENCRYPTION_RAM_CODE) + ImageLength(RAM_DATA_ON) + ImageLength(OVERLAY_C)) <= (APP_DATA_ON_SIZE)) +#endif +; overlay section end + + CACHE_DATA_ON CACHE_DATA_ON_ADR OVERLAY CACHE_DATA_ON_SIZE + { +#if FEATURE_RAM_CODE + .ANY (+RO) +#endif + * (.ram.sharecacheram.text) + } +} + +LOAD_APP_TRACE APP_TRACE_ADR APP_TRACE_SIZE +{ + App.trace APP_TRACE_ADR APP_TRACE_SIZE + { + * (.TRACE) + } +} diff --git a/board/evb/findmy/mdk/before_build_special.bat b/board/evb/findmy/mdk/before_build_special.bat new file mode 100644 index 0000000..b881556 --- /dev/null +++ b/board/evb/findmy/mdk/before_build_special.bat @@ -0,0 +1,2 @@ +@echo off +echo build_before_special bat \ No newline at end of file diff --git a/board/evb/findmy/mdk/bin/App.trace b/board/evb/findmy/mdk/bin/App.trace new file mode 100644 index 0000000..fc2d006 Binary files /dev/null and b/board/evb/findmy/mdk/bin/App.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.bin b/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.bin new file mode 100644 index 0000000..5d54b49 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.trace b/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0026223a115e73fa63c4fadbbcab6ec8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.bin b/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.bin new file mode 100644 index 0000000..f496475 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.trace b/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.trace new file mode 100644 index 0000000..f3e5893 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-002adeb00bdb7b3ac019e68e1d0ffa2d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.bin b/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.bin new file mode 100644 index 0000000..d246014 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.trace b/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.trace new file mode 100644 index 0000000..e0874e1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0141171355aa877c7145fb4c63989b28.trace differ diff --git a/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.bin b/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.bin new file mode 100644 index 0000000..0ccfffa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.trace b/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-014c974d888aa53c1e07750f75abfcbf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.bin b/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.bin new file mode 100644 index 0000000..8d8c4f5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.trace b/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.trace new file mode 100644 index 0000000..c368f4f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-01b8f0abd448398b097935236f8d4ea3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.bin b/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.bin new file mode 100644 index 0000000..e10af6f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.bin differ diff --git a/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.trace b/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-028d457054822e1d51980a2adc8e3f78.trace differ diff --git a/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.bin b/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.bin new file mode 100644 index 0000000..8763d36 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.trace b/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-030946f85eb80d29588da9df1ca2f4a6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.bin b/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.bin new file mode 100644 index 0000000..e2b8582 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.trace b/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0313620cae4cd7860580f2dda1099aa4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.bin b/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.bin new file mode 100644 index 0000000..5151270 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.trace b/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-039b087adcb1d86607ea54789151b5f6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.bin b/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.bin new file mode 100644 index 0000000..c90663d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.trace b/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-03ae6321983edc027e800ae9010935bc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.bin b/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.bin new file mode 100644 index 0000000..a27408a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.bin differ diff --git a/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.trace b/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-04cdfde46fbbab9e1e4a2ec75d32bf37.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.bin b/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.bin new file mode 100644 index 0000000..b716f67 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.trace b/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0535aa8bb7c9fe75adea94a183325323.trace differ diff --git a/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.bin b/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.bin new file mode 100644 index 0000000..ec1fbce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.bin differ diff --git a/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.trace b/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-058eea637f6df5b61fcc542c1d60f531.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.bin b/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.bin new file mode 100644 index 0000000..1f47c1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.trace b/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0660605bd64410ffa8865684e5ba88dc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.bin b/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.bin new file mode 100644 index 0000000..217af04 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.trace b/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-06cf140bd369f96b2d42eb2baf9f6c3e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.bin b/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.bin new file mode 100644 index 0000000..783c169 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.bin differ diff --git a/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.trace b/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-06f6c4d75a7ac15e4b46a612a2156397.trace differ diff --git a/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.bin b/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.bin new file mode 100644 index 0000000..0807005 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.trace b/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-075f5244d760a5e3672a74c892cf754f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.bin b/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.bin new file mode 100644 index 0000000..b998b34 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.trace b/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-077fdf04a51e4d6a5a7453a3af38c06d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.bin b/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.bin new file mode 100644 index 0000000..fc93800 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.trace b/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07added102b3d257da90d57fd8bf658d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.bin b/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.bin new file mode 100644 index 0000000..927721e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.trace b/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07c0c74b2232992fa5afcaa5a9c1164c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.bin b/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.bin new file mode 100644 index 0000000..dd8f7b3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.trace b/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-07ec804a04bc6a96b89d7d09a25242c4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.bin b/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.bin new file mode 100644 index 0000000..763baf8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.trace b/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.trace new file mode 100644 index 0000000..1860ddd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0807a76b24432e61c4f4cb67db30025e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.bin b/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.bin new file mode 100644 index 0000000..85e1880 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.bin differ diff --git a/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.trace b/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.trace new file mode 100644 index 0000000..32a53d2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-083f85450a326110e4410f579a7bb902.trace differ diff --git a/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.bin b/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.bin new file mode 100644 index 0000000..502de05 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.trace b/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-087a1736dd51d2484c12f915c7c9cbb1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.bin b/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.bin new file mode 100644 index 0000000..0e580ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.bin differ diff --git a/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.trace b/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-08f52e15a7276d7377d33d784b9e38ab.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.bin b/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.bin new file mode 100644 index 0000000..85a9a7d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.trace b/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0956f7967e925c66fb60d8ad38f61ec0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.bin b/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.bin new file mode 100644 index 0000000..7c6bc20 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.bin differ diff --git a/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.trace b/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.trace new file mode 100644 index 0000000..7542f9c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-09969e817279a8d242972f3b68488292.trace differ diff --git a/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.bin b/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.bin new file mode 100644 index 0000000..c3db8f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.trace b/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.trace new file mode 100644 index 0000000..080c12f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-09a95a5d841202b02fb4e51868d5932a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.bin b/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.bin new file mode 100644 index 0000000..2a14340 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.trace b/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a2525e34b33f5f40ed820d7cb3d22dc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.bin b/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.bin new file mode 100644 index 0000000..85e9e71 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.trace b/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.trace new file mode 100644 index 0000000..a079f08 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a378d04fb27b62aec2a616c382dc28f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.bin b/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.bin new file mode 100644 index 0000000..4e648fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.trace b/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.trace new file mode 100644 index 0000000..08a0de8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0a4cb58ccb9a2cff178d4fb47d95dead.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.bin b/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.bin new file mode 100644 index 0000000..39a1c0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.trace b/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aa36afed6d361957420f85f81a9fb2b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.bin b/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.bin new file mode 100644 index 0000000..787e126 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.trace b/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aeb214ee72cca9567ebc6c64dd9be2c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.bin b/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.bin new file mode 100644 index 0000000..89550e3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.trace b/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0aee187a2c73ceaa8fcff30ec383ad4c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.bin b/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.bin new file mode 100644 index 0000000..159261f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.trace b/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.trace new file mode 100644 index 0000000..f3e5893 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c0273e12f36b4cb813c8807ce904c39.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.bin b/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.bin new file mode 100644 index 0000000..3892a2c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.trace b/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c0ee5f977ab9f5b587b46da39718057.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.bin b/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.bin new file mode 100644 index 0000000..814dd1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.trace b/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.trace new file mode 100644 index 0000000..08a0de8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c58faa4a0ec6ee2ab9cfd3479ec5568.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.bin b/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.bin new file mode 100644 index 0000000..5ac67af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.trace b/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c600bc19fdf9aa766a3874e82900dcb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.bin b/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.bin new file mode 100644 index 0000000..e87c33a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.trace b/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c6f450edbaa97c6802716503b45bc87.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.bin b/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.bin new file mode 100644 index 0000000..1e27b28 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.trace b/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c860b1e2514e8e2ad8c335bbc20703b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.bin b/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.bin new file mode 100644 index 0000000..c4816cf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.trace b/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.trace new file mode 100644 index 0000000..03f5f8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0c905b48fc5df18e596244139c87142b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.bin b/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.bin new file mode 100644 index 0000000..7aa810d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.trace b/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.trace new file mode 100644 index 0000000..824d24b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0cdb90f56108e3b9895b4dced372a174.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.bin b/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.bin new file mode 100644 index 0000000..501ae30 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.trace b/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0d4bcdb25dc55001939b93ab6318a52a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.bin b/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.bin new file mode 100644 index 0000000..7b3b696 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.trace b/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0d5b5fb9ff3dc1cae5872fd78eecd0c2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.bin b/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.bin new file mode 100644 index 0000000..36aced0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.trace b/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0de48e78976de3caf50d669f39b15828.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.bin b/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.bin new file mode 100644 index 0000000..747f3a2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.trace b/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0e5235cfd760f4b76c2865d30273c70e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.bin b/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.bin new file mode 100644 index 0000000..012cd07 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.trace b/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0e5c568c9b87621c6defeae4b651ff21.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.bin b/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.bin new file mode 100644 index 0000000..d53f3d7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.trace b/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0eb7f8e44d594ec6434bde4894a139c4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.bin b/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.bin new file mode 100644 index 0000000..f2d8a23 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.trace b/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.trace new file mode 100644 index 0000000..a4acaea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f2d26a6918b0123b46c66f45d203ede.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.bin b/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.bin new file mode 100644 index 0000000..a0e58a8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.trace b/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.trace new file mode 100644 index 0000000..b1c023e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f3d5f30cd5b154cb83a85c5a0e7d2d5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.bin b/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.bin new file mode 100644 index 0000000..1891724 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.trace b/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0f8998767c433fd59b54e65e9fe8a418.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.bin b/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.bin new file mode 100644 index 0000000..18250a5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.trace b/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.trace new file mode 100644 index 0000000..dffddb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0fc0609b46d602b231f3b1c3e9a84976.trace differ diff --git a/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.bin b/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.bin new file mode 100644 index 0000000..9f19d30 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.trace b/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-0fff9ae2193a670205611e2d9637cbfb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.bin b/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.bin new file mode 100644 index 0000000..8fca7dd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.trace b/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-10916269a1a0afe9957475bfcc3cf17b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.bin b/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.bin new file mode 100644 index 0000000..0b81e2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.trace b/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-10f3a9daa4aeb509d3d82e491ee25ac3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.bin b/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.bin new file mode 100644 index 0000000..653bb36 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.bin differ diff --git a/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.trace b/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.trace new file mode 100644 index 0000000..fc07329 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-11ecd9ca5c3d14b78af61cf67bdffd04.trace differ diff --git a/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.bin b/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.bin new file mode 100644 index 0000000..44c72e9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.bin differ diff --git a/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.trace b/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-12ae6ae41d4b3d79ad6981f0ef3a5963.trace differ diff --git a/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.bin b/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.bin new file mode 100644 index 0000000..40e4e47 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.trace b/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.trace new file mode 100644 index 0000000..4ef825c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-12d22241e7e1144d2cc9bf005f043d3f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.bin b/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.bin new file mode 100644 index 0000000..625fa86 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.trace b/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.trace new file mode 100644 index 0000000..c55fc2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1330bb73413fe728b1f8c5318fae03b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.bin b/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.bin new file mode 100644 index 0000000..57f96f3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.bin differ diff --git a/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.trace b/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-13a4fc930e8b9cbeecfcb2f86fae6611.trace differ diff --git a/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.bin b/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.bin new file mode 100644 index 0000000..8e557fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.trace b/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-13d9e4ca996f5bb395b91d451c9c8f9a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.bin b/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.bin new file mode 100644 index 0000000..7aa8c0a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.trace b/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1459d2518b9df3b2f062c67662cfa35f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.bin b/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.bin new file mode 100644 index 0000000..cee4279 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.trace b/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-146ec4b4267fa2e82887877a81d450d7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.bin b/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.bin new file mode 100644 index 0000000..76dadf9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.trace b/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-146f95aea2a5e5efb13db4ced1fef1e6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.bin b/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.bin new file mode 100644 index 0000000..9eb6559 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.bin differ diff --git a/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.trace b/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-14d8275b71840f7fe5df7e45915def40.trace differ diff --git a/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.bin b/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.bin new file mode 100644 index 0000000..a940174 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.bin differ diff --git a/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.trace b/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-15038adb89a20ea8d073c44de1fbe197.trace differ diff --git a/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.bin b/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.bin new file mode 100644 index 0000000..f056c2d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.trace b/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-157cdff327828311e399fb47310619f2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.bin b/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.bin new file mode 100644 index 0000000..5d2b803 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.bin differ diff --git a/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.trace b/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.trace new file mode 100644 index 0000000..b023c53 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-15be586e64a9c975e4a5a11640310a25.trace differ diff --git a/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.bin b/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.bin new file mode 100644 index 0000000..f7384bb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.trace b/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-161f0afccb231a1985148731d98f015b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.bin b/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.bin new file mode 100644 index 0000000..110de46 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.trace b/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.trace new file mode 100644 index 0000000..a4385dc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-16944ab49838553c66816ed98c789c3f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.bin b/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.bin new file mode 100644 index 0000000..ba53df1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.trace b/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.trace new file mode 100644 index 0000000..2ee423a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-16e87e782a1b4f1f7ea3cbf9e2ecb5e2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.bin b/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.bin new file mode 100644 index 0000000..1c98b33 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.trace b/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-17594378aefd3b7f3f58fd74bef5e65f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.bin b/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.bin new file mode 100644 index 0000000..b5913f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.trace b/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.trace new file mode 100644 index 0000000..dffddb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1770b94e3aba21792e7ec83bd3f9e44d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.bin b/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.bin new file mode 100644 index 0000000..342bb8c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.trace b/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1777a8062fa5c26100617a3119eac281.trace differ diff --git a/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.bin b/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.bin new file mode 100644 index 0000000..067ae5c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.trace b/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-17ae810c7fcb9d7a5baa850e04a7ec7b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.bin b/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.bin new file mode 100644 index 0000000..415dff2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.trace b/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.trace new file mode 100644 index 0000000..e1c982d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-184dbcbd31556472d418f4b4581bb7c6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.bin b/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.bin new file mode 100644 index 0000000..aed0be3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.trace b/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-186118dc07fc906f810d5fbf55068f9c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.bin b/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.bin new file mode 100644 index 0000000..52e0895 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.trace b/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-18834dec58a2abe02df1a3d0b8b2ce9b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.bin b/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.bin new file mode 100644 index 0000000..2d10d25 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.trace b/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.trace new file mode 100644 index 0000000..ff0a4ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-19126b8edb9efb2366a3765cddb7f8e9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.bin b/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.bin new file mode 100644 index 0000000..ffd5305 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.trace b/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1af026ccafaec137cf8b950b79e16d10.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.bin b/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.bin new file mode 100644 index 0000000..0a805e0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.trace b/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1b57da685c8685fe32ca2b8c54bde8a3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.bin b/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.bin new file mode 100644 index 0000000..b018625 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.trace b/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1cc1141838fc677a6d14e1fcf5d851f3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.bin b/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.bin new file mode 100644 index 0000000..94bf2a8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.trace b/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1ce405cd37a1509dbabbc117fc14f768.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.bin b/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.bin new file mode 100644 index 0000000..6272185 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.trace b/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1cffe94507add7a41a5859d5069439f8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.bin b/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.bin new file mode 100644 index 0000000..2a2bcec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.trace b/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.trace new file mode 100644 index 0000000..b3822db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1d2dee564234822090a83afcc8974ca0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.bin b/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.bin new file mode 100644 index 0000000..8b0d710 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.trace b/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1d60fe527a641f06598293ac06638a0a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.bin b/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.bin new file mode 100644 index 0000000..a5baff9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.trace b/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1da9a363e6fdcf4cd065c22b5c9b09d7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.bin b/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.bin new file mode 100644 index 0000000..8ca8f99 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.trace b/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1dba042e2f48c0e92c3e2178f529d29f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.bin b/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.bin new file mode 100644 index 0000000..3e8e870 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.trace b/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1e5ff5533edc82e3003902ea094f8496.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.bin b/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.bin new file mode 100644 index 0000000..c0870ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.trace b/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.trace new file mode 100644 index 0000000..f5c362b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1eec54fb82703fceab3e29a470cb6397.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.bin b/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.bin new file mode 100644 index 0000000..613484a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.trace b/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f158d85eda244d22cd8e78a24d06b90.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.bin b/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.bin new file mode 100644 index 0000000..107f177 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.trace b/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f176fb1e52a13684739d555b47999bd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.bin b/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.bin new file mode 100644 index 0000000..800104d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.trace b/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.trace new file mode 100644 index 0000000..dc2aa0a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1f8d874dc43ffb546335737d402674ef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.bin b/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.bin new file mode 100644 index 0000000..68d663e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.trace b/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1fc9b3af24ac135f02d7e750da301e69.trace differ diff --git a/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.bin b/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.bin new file mode 100644 index 0000000..7fa72f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.bin differ diff --git a/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.trace b/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-1feec72a3fc692e4b9c811f4c52cc877.trace differ diff --git a/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.bin b/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.bin new file mode 100644 index 0000000..e70b685 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.bin differ diff --git a/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.trace b/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.trace new file mode 100644 index 0000000..560223c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-20478674214bf69f435f4b6e4314a189.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.bin b/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.bin new file mode 100644 index 0000000..c6a2540 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.trace b/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.trace new file mode 100644 index 0000000..aeba6c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2072a57af3f18c8cf18b7642c24dbbe8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.bin b/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.bin new file mode 100644 index 0000000..6271458 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.trace b/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2079703518dabfbcf69ec0eb6e0f8f2e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.bin b/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.bin new file mode 100644 index 0000000..7528b9a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.trace b/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2098a1882364b4adb408d56de491b7b3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.bin b/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.bin new file mode 100644 index 0000000..ff47c73 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.trace b/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-20ad23b196418a254f70885136c8e5f0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.bin b/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.bin new file mode 100644 index 0000000..2d12e3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.bin differ diff --git a/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.trace b/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21157aa0c7e2a30e70e1471f4e54fd60.trace differ diff --git a/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.bin b/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.bin new file mode 100644 index 0000000..91aa81c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.bin differ diff --git a/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.trace b/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21319aed6edb838dd39874de9e25aa05.trace differ diff --git a/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.bin b/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.bin new file mode 100644 index 0000000..6deaa1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.bin differ diff --git a/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.trace b/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21365b41d62bddd2dfefdcce33473878.trace differ diff --git a/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.bin b/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.bin new file mode 100644 index 0000000..20393f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.bin differ diff --git a/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.trace b/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-214e62855f91adb3a50b80b771d64183.trace differ diff --git a/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.bin b/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.bin new file mode 100644 index 0000000..534e16b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.trace b/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-21a47f421af60cdbd52341a752167af7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.bin b/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.bin new file mode 100644 index 0000000..cdca54e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.trace b/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2208ede419380e6c796cb03dcb159650.trace differ diff --git a/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.bin b/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.bin new file mode 100644 index 0000000..135d10a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.bin differ diff --git a/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.trace b/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-22bdf17edb165dcd5e9426f2c8cd2b59.trace differ diff --git a/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.bin b/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.bin new file mode 100644 index 0000000..bd3a773 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.bin differ diff --git a/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.trace b/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.trace new file mode 100644 index 0000000..e1c982d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-22c5cfc187c6c3c63a17ded407d8e042.trace differ diff --git a/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.bin b/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.bin new file mode 100644 index 0000000..9d9172f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.trace b/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.trace new file mode 100644 index 0000000..8b16740 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-230bcda105e843c8bdd876cc4c05dba1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.bin b/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.bin new file mode 100644 index 0000000..42153c2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.trace b/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.trace new file mode 100644 index 0000000..ff0a4ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-231fc1bc848e0bb03837a43c711b752b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.bin b/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.bin new file mode 100644 index 0000000..56dc56c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.trace b/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2342122f1048cd89d27abd3e73a2c15d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.bin b/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.bin new file mode 100644 index 0000000..d1d2843 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.trace b/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-236584b23c1ec002750c7fa2e718cfcd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.bin b/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.bin new file mode 100644 index 0000000..68daa90 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.bin differ diff --git a/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.trace b/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.trace new file mode 100644 index 0000000..fefdad7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-23ba9243604cdfc23fc243ad9b9fb892.trace differ diff --git a/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.bin b/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.bin new file mode 100644 index 0000000..d939486 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.bin differ diff --git a/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.trace b/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-23bffbbd4dbefa48be741f113c2a9c85.trace differ diff --git a/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.bin b/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.bin new file mode 100644 index 0000000..89196fe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.bin differ diff --git a/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.trace b/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-24196f9c84ed71524ea71531f567be34.trace differ diff --git a/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.bin b/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.bin new file mode 100644 index 0000000..7a531d9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.trace b/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-24de47c2ee796f4741bc7736e477a6c2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.bin b/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.bin new file mode 100644 index 0000000..69d468c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.trace b/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2539c6fdef8026376279d39f919a577c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.bin b/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.bin new file mode 100644 index 0000000..fd19f52 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.trace b/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.trace new file mode 100644 index 0000000..8633155 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-257419460a962a276d23f27a13b50ea0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.bin b/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.bin new file mode 100644 index 0000000..b644aae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.trace b/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-262b5da78fae5eb1e8e0820021aee5c3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.bin b/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.bin new file mode 100644 index 0000000..d066280 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.trace b/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-273c1ff9a9e7bd108e4618b140dec29b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.bin b/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.bin new file mode 100644 index 0000000..96dfebb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.bin differ diff --git a/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.trace b/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-275cbe16563aa7fb7476b0e8bfc05482.trace differ diff --git a/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.bin b/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.bin new file mode 100644 index 0000000..afdef3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.bin differ diff --git a/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.trace b/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-27c0489833e78513056971e4b1fb3b18.trace differ diff --git a/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.bin b/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.bin new file mode 100644 index 0000000..bbc4e11 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.trace b/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-284537f50d6d46dc85b8525ba0270ae4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.bin b/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.bin new file mode 100644 index 0000000..5f66c2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.bin differ diff --git a/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.trace b/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-28fd381700dc11574d0c7498abfa6962.trace differ diff --git a/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.bin b/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.bin new file mode 100644 index 0000000..1fe71bd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.bin differ diff --git a/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.trace b/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29061bd602c5b2434730592c4a3b2728.trace differ diff --git a/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.bin b/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.bin new file mode 100644 index 0000000..d661774 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.bin differ diff --git a/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.trace b/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-294fac01a02dfcae77ec50024aa22156.trace differ diff --git a/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.bin b/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.bin new file mode 100644 index 0000000..3b3af29 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.bin differ diff --git a/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.trace b/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29ba945c5ea5108920cece4eebedd711.trace differ diff --git a/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.bin b/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.bin new file mode 100644 index 0000000..04910fa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.trace b/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-29fd315420fdbd6f122002f211cc232d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.bin b/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.bin new file mode 100644 index 0000000..07e6122 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.trace b/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2a4803d1be904998a98c480645ff6241.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.bin b/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.bin new file mode 100644 index 0000000..7ab5790 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.trace b/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2a52fa9784ba922fcbfd39570e525d64.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.bin b/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.bin new file mode 100644 index 0000000..92c6e66 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.trace b/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2abdf8f74f007c3a59b0fc2978729b59.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.bin b/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.bin new file mode 100644 index 0000000..d11b5d1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.trace b/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2bdda4a5f8fcfec32322a2d76a6529af.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.bin b/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.bin new file mode 100644 index 0000000..3b131b4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.trace b/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.trace new file mode 100644 index 0000000..8f944f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2c0ed915b629746c86b9a163aa6fbb04.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.bin b/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.bin new file mode 100644 index 0000000..961254a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.trace b/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2c2c737b53743d21714fbed67b8bcb8f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.bin b/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.bin new file mode 100644 index 0000000..d351291 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.trace b/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2cc253f33d43b071d4affe279661e81e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.bin b/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.bin new file mode 100644 index 0000000..3056d32 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.trace b/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2d551118672df4de95ff365880df61e5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.bin b/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.bin new file mode 100644 index 0000000..5f3be2b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.trace b/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.trace new file mode 100644 index 0000000..3fe3309 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2dce4a89fa908c2fae83772887e38377.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.bin b/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.bin new file mode 100644 index 0000000..79da471 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.trace b/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e2703a3d1188d65806e1fa99bd09bd6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.bin b/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.bin new file mode 100644 index 0000000..38a30e4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.trace b/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e2dd9c96ae7bf2d2ffef8e016c1c1af.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.bin b/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.bin new file mode 100644 index 0000000..46cf286 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.trace b/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.trace new file mode 100644 index 0000000..5d2a426 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2e72b8896b292123ce1914ff6a672626.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.bin b/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.bin new file mode 100644 index 0000000..9dedace Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.trace b/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.trace new file mode 100644 index 0000000..1324675 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2ef78a65d3727c3b6ed46b8eeef9d787.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.bin b/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.bin new file mode 100644 index 0000000..8e72566 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.trace b/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f1a9c75227e7e005f1fb86bf128e820.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.bin b/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.bin new file mode 100644 index 0000000..ae7cc4a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.trace b/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f5445ab13bebbf6adc0d0f4a584144d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.bin b/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.bin new file mode 100644 index 0000000..e2fae72 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.trace b/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2f9b709a867dfecba8357f5549c1c2b9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.bin b/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.bin new file mode 100644 index 0000000..77c4406 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.trace b/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2faf00f383d5ddeb9b0784d396e16e99.trace differ diff --git a/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.bin b/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.bin new file mode 100644 index 0000000..c059f0a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.trace b/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-2fb639c28878ca1242cdc9eea097c9a5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.bin b/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.bin new file mode 100644 index 0000000..2423e3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.trace b/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-302016b82e4d7f7bbf127e09f91c0fbf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.bin b/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.bin new file mode 100644 index 0000000..4861f61 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.trace b/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.trace new file mode 100644 index 0000000..f0093fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3035b8c73434bd2a35a81d16ad2b9b23.trace differ diff --git a/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.bin b/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.bin new file mode 100644 index 0000000..c9e7b9d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.bin differ diff --git a/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.trace b/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-303ab1251d3eeb463aee01d4094a3eda.trace differ diff --git a/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.bin b/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.bin new file mode 100644 index 0000000..73a2dd1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.trace b/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.trace new file mode 100644 index 0000000..ae3322d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-305a5ba80b6e254ef061c6ca5c2a0bc5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.bin b/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.bin new file mode 100644 index 0000000..e3d2c75 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.bin differ diff --git a/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.trace b/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-30998af21533506ec3279da138572138.trace differ diff --git a/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.bin b/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.bin new file mode 100644 index 0000000..2ab34ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.bin differ diff --git a/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.trace b/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-310490d86e2db75e30602f8dfc403a47.trace differ diff --git a/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.bin b/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.bin new file mode 100644 index 0000000..d3ac255 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.trace b/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-320088a43f65a958166956ab5a21af5e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.bin b/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.bin new file mode 100644 index 0000000..3764fb7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.trace b/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.trace new file mode 100644 index 0000000..b6e5285 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3225bf12b236e87f1ba4774fa74263ef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.bin b/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.bin new file mode 100644 index 0000000..dc9fb61 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.trace b/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-32cf9423bdce6f8b61fed1e521e5527d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.bin b/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.bin new file mode 100644 index 0000000..09b27ff Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.trace b/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.trace new file mode 100644 index 0000000..85fd017 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-335980fefcfb90b1b6109e5be5b7ebef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.bin b/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.bin new file mode 100644 index 0000000..8c33429 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.bin differ diff --git a/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.trace b/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-338073bde3a3d87e79af14342d54d979.trace differ diff --git a/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.bin b/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.bin new file mode 100644 index 0000000..ec13ebb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.bin differ diff --git a/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.trace b/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.trace new file mode 100644 index 0000000..cd7246d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-33b632479e9ec15f5df2d10cb0a56811.trace differ diff --git a/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.bin b/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.bin new file mode 100644 index 0000000..0203f14 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.bin differ diff --git a/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.trace b/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-33beffd5d33fde1a34931345bcd13f75.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.bin b/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.bin new file mode 100644 index 0000000..e1f19ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.trace b/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3502f2811c3285589e54c63b5bf6ab6f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.bin b/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.bin new file mode 100644 index 0000000..7777c18 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.trace b/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.trace new file mode 100644 index 0000000..9102e8c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3584e66309539423179c02b72822a215.trace differ diff --git a/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.bin b/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.bin new file mode 100644 index 0000000..aec405e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.bin differ diff --git a/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.trace b/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-369659537b49167016470a3fe48ee769.trace differ diff --git a/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.bin b/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.bin new file mode 100644 index 0000000..89bffb2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.trace b/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-369ae8bab82b35d49e0e873751d990b9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.bin b/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.bin new file mode 100644 index 0000000..61a62ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.trace b/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-36a79e1db7fc7b96f97c57f72845d16e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.bin b/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.bin new file mode 100644 index 0000000..46b266f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.trace b/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.trace new file mode 100644 index 0000000..a8d3e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-36b34e1664f7011146f1af69dc8d25b2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.bin b/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.bin new file mode 100644 index 0000000..0d8cf73 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.trace b/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3723d3a848afce953483d3675d02e54b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.bin b/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.bin new file mode 100644 index 0000000..62c0c4d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.trace b/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-37d73e04cc505f9b4f375d325c0a827e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.bin b/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.bin new file mode 100644 index 0000000..9222973 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.trace b/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.trace new file mode 100644 index 0000000..32a53d2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-380b38af100029569284c665964dcd9a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.bin b/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.bin new file mode 100644 index 0000000..34619b9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.bin differ diff --git a/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.trace b/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-38ba6189c6dbd0fefdb4690bdcbbf971.trace differ diff --git a/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.bin b/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.bin new file mode 100644 index 0000000..3d7de79 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.bin differ diff --git a/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.trace b/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-38f780131dd5d10788ccafa1257d7f20.trace differ diff --git a/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.bin b/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.bin new file mode 100644 index 0000000..5a2a9f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.trace b/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.trace new file mode 100644 index 0000000..e3b83ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39033a1f416bc98c33a607b23e78ae6c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.bin b/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.bin new file mode 100644 index 0000000..5dd9925 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.trace b/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3904323cd7e90e9a94329a6d450c9d03.trace differ diff --git a/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.bin b/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.bin new file mode 100644 index 0000000..597ab92 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.trace b/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.trace new file mode 100644 index 0000000..dc2aa0a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-392caf359fe0520280624a08b33f3db9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.bin b/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.bin new file mode 100644 index 0000000..9c17ec6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.bin differ diff --git a/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.trace b/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39386606f781fc868ee668cbe39b1e61.trace differ diff --git a/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.bin b/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.bin new file mode 100644 index 0000000..fb4b88e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.trace b/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.trace new file mode 100644 index 0000000..c55fc2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39506c685a79b62586c58fc8a1b025f1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.bin b/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.bin new file mode 100644 index 0000000..5e3689f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.bin differ diff --git a/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.trace b/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.trace new file mode 100644 index 0000000..2ac529c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-39762f9d58eabac27cf8efd6c950ac85.trace differ diff --git a/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.bin b/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.bin new file mode 100644 index 0000000..ac11574 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.trace b/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-398fb58bb6ae45545672b755f8ad3a4d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.bin b/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.bin new file mode 100644 index 0000000..09a4117 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.trace b/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3996a32f16ed5ea2f73bd6be6554dbc1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.bin b/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.bin new file mode 100644 index 0000000..ea74629 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.trace b/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3b78a3b20e1cd8332f5969d3c4d18578.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.bin b/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.bin new file mode 100644 index 0000000..e956dce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.trace b/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3ba82f444ab5bcca3b2a867e787f6b30.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.bin b/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.bin new file mode 100644 index 0000000..852f2b7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.trace b/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c4c2310bfc5edf0c21a752337da38a9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.bin b/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.bin new file mode 100644 index 0000000..0cc9a05 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.trace b/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c5c5828787652745807e55ee74f0845.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.bin b/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.bin new file mode 100644 index 0000000..b9388d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.trace b/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.trace new file mode 100644 index 0000000..c61fd85 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3c8332675c093ed66576355a65920342.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.bin b/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.bin new file mode 100644 index 0000000..4dc9227 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.trace b/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.trace new file mode 100644 index 0000000..3fe3309 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3cab62ac6889cab4d1d7e8083112f6ee.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.bin b/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.bin new file mode 100644 index 0000000..459e313 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.trace b/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.trace new file mode 100644 index 0000000..f0093fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3ce48c56c81a194a39dd2e905ca4c738.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.bin b/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.bin new file mode 100644 index 0000000..c82747d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.trace b/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d0afc069abeb7e10e7c77d556cbc616.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.bin b/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.bin new file mode 100644 index 0000000..4c5cafb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.trace b/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d71a9b03eedeba2876a5d324741717b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.bin b/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.bin new file mode 100644 index 0000000..59de9a6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.trace b/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3d9ff2bd3c7d8ed81a05995ecbee6b61.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.bin b/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.bin new file mode 100644 index 0000000..b2f6137 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.trace b/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3dabe53943e8f5cb0cb90a62db44dfc4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.bin b/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.bin new file mode 100644 index 0000000..389fe1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.trace b/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e36f1daff3c3e5bd7e9518eefa123d5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.bin b/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.bin new file mode 100644 index 0000000..ea5338f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.trace b/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e5a217287463a9dfcd631a909796775.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.bin b/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.bin new file mode 100644 index 0000000..f94a416 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.trace b/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.trace new file mode 100644 index 0000000..18a2dc8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3e8a87c9130b74aa7b01cc14e2205ab3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.bin b/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.bin new file mode 100644 index 0000000..b8bc4a8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.trace b/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.trace new file mode 100644 index 0000000..dd17b51 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-3f720a93ea150d79ccf4ba05f36304e7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.bin b/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.bin new file mode 100644 index 0000000..82172de Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.trace b/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4035ca16b9024d63b717f7216fc202b7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.bin b/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.bin new file mode 100644 index 0000000..b4b91d1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.bin differ diff --git a/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.trace b/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.trace new file mode 100644 index 0000000..a4acaea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-405b0cc1a3f605b2d1f11dba32c64933.trace differ diff --git a/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.bin b/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.bin new file mode 100644 index 0000000..a4e83b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.trace b/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.trace new file mode 100644 index 0000000..03f5f8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-40c21d357f6092296748cd955f2141b6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.bin b/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.bin new file mode 100644 index 0000000..a6f2655 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.bin differ diff --git a/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.trace b/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-41442ed428b4d099cb051beea7346e05.trace differ diff --git a/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.bin b/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.bin new file mode 100644 index 0000000..99e2b9b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.trace b/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-41945970b4f92b2954e212015622d8c8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.bin b/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.bin new file mode 100644 index 0000000..7eb35b9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.bin differ diff --git a/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.trace b/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-423af128cbdb9b2ca115424ca25214ee.trace differ diff --git a/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.bin b/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.bin new file mode 100644 index 0000000..de4149d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.bin differ diff --git a/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.trace b/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-425aff3365569ff782c7f16d6a3e2574.trace differ diff --git a/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.bin b/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.bin new file mode 100644 index 0000000..858b5c5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.trace b/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.trace new file mode 100644 index 0000000..750042c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42b262ed0cbac680a32e7f1919754f1b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.bin b/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.bin new file mode 100644 index 0000000..41f924c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.trace b/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.trace new file mode 100644 index 0000000..f624bca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42e1ac57d9e5adbe2ee3b553f95d2aaa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.bin b/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.bin new file mode 100644 index 0000000..23b0fa7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.trace b/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.trace new file mode 100644 index 0000000..b1c023e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-42f9aa45947ded75b0d9207cd8d88bb1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.bin b/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.bin new file mode 100644 index 0000000..4e6c4fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.trace b/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4304e1590d6510047157eeb743fd9721.trace differ diff --git a/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.bin b/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.bin new file mode 100644 index 0000000..8041b5e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.trace b/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.trace new file mode 100644 index 0000000..8b16740 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-445da1066bce61fb61aa6c87d1ff2c0f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.bin b/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.bin new file mode 100644 index 0000000..c16a30f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.trace b/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44783c6f67833eaea2532061b647830e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.bin b/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.bin new file mode 100644 index 0000000..3001fd1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.trace b/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4483fcf9c26587146c18055aad52fecb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.bin b/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.bin new file mode 100644 index 0000000..547b41e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.trace b/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44b25076d1ecdedab48236116cdd235d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.bin b/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.bin new file mode 100644 index 0000000..7637f7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.bin differ diff --git a/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.trace b/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.trace new file mode 100644 index 0000000..559eaf1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-44e0f4159f0805c37e1fc57348ed9401.trace differ diff --git a/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.bin b/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.bin new file mode 100644 index 0000000..9b3f2c8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.bin differ diff --git a/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.trace b/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.trace new file mode 100644 index 0000000..b740c98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-452f26b5c812a3929ba535c340da7c82.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.bin b/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.bin new file mode 100644 index 0000000..9f8ad97 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.trace b/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.trace new file mode 100644 index 0000000..a8d3e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4559fd67e28a655f2f2bd0ee52591bef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.bin b/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.bin new file mode 100644 index 0000000..f692293 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.bin differ diff --git a/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.trace b/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.trace new file mode 100644 index 0000000..5597c51 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-458adb26d79d25f746588d265c262115.trace differ diff --git a/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.bin b/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.bin new file mode 100644 index 0000000..e3a9562 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.trace b/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-45c1320720a577e08ec8bf6b4c52979a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.bin b/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.bin new file mode 100644 index 0000000..da66521 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.trace b/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.trace new file mode 100644 index 0000000..b740c98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-45fc298dabe46ed06ad66b26f7d44c8b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.bin b/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.bin new file mode 100644 index 0000000..4d520fe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.trace b/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4630a9f3c13095dee8820b7b42302776.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.bin b/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.bin new file mode 100644 index 0000000..dcac017 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.trace b/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4637b8b1286efaea62b1024e31e4fad7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.bin b/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.bin new file mode 100644 index 0000000..96c03a2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.trace b/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.trace new file mode 100644 index 0000000..b1a3ded Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4690a0a37d9daf4f18c9c88cdc623ac4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.bin b/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.bin new file mode 100644 index 0000000..c5a851a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.bin differ diff --git a/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.trace b/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.trace new file mode 100644 index 0000000..294ec7b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-46cb53ade7f0f31c21637ffc5d1de810.trace differ diff --git a/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.bin b/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.bin new file mode 100644 index 0000000..864e2d1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.trace b/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.trace new file mode 100644 index 0000000..e87d2ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-46d8d66ceeb0976dd47f2d5ab45bd3cd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.bin b/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.bin new file mode 100644 index 0000000..c21f96b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.trace b/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-474eb88611e3c61fa5659662582d40c8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.bin b/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.bin new file mode 100644 index 0000000..fb2c10b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.trace b/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.trace new file mode 100644 index 0000000..b90a55c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4765ebc4715026b5046c7439b87b9a91.trace differ diff --git a/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.bin b/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.bin new file mode 100644 index 0000000..cddaf17 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.bin differ diff --git a/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.trace b/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-49585b505d10d9ddeccd636990419b95.trace differ diff --git a/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.bin b/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.bin new file mode 100644 index 0000000..2a2ec7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.trace b/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.trace new file mode 100644 index 0000000..591dd4b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-496b64b36ed057b02a5515d7a9d9ecd6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.bin b/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.bin new file mode 100644 index 0000000..4f7f765 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.trace b/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4979eb9cd4834233bad2378eb5a6c31c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.bin b/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.bin new file mode 100644 index 0000000..0b370ac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.trace b/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a11ca4bd3afb3595f06be7e3bcfc728.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.bin b/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.bin new file mode 100644 index 0000000..8bd1ebd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.trace b/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a4ac26bd8ef92126cf61378aa88fd69.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.bin b/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.bin new file mode 100644 index 0000000..6483ddb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.trace b/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a65515a79f18f1fafc16e7303ed926c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.bin b/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.bin new file mode 100644 index 0000000..948c794 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.trace b/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.trace new file mode 100644 index 0000000..b55cfdc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4a7c546d158b181174dc8bdb6a206378.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.bin b/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.bin new file mode 100644 index 0000000..58ff71f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.trace b/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4bb96922656c04eb319f96653d687aee.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.bin b/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.bin new file mode 100644 index 0000000..3b9570f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.trace b/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4caa031eb4e45eb112a8d98a50ec8e66.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.bin b/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.bin new file mode 100644 index 0000000..4912cdb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.trace b/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.trace new file mode 100644 index 0000000..dffddb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4cacaeffbaeb8f6e0aed05b7b60a7bfa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.bin b/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.bin new file mode 100644 index 0000000..5c4bb62 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.trace b/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4d2a563369e8c159463ec91bc7f64c66.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.bin b/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.bin new file mode 100644 index 0000000..37c373b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.trace b/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4e25f19a3d5aef9e17af70cbe8ebedb3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.bin b/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.bin new file mode 100644 index 0000000..09bad06 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.trace b/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.trace new file mode 100644 index 0000000..52393d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4e286ae10eab928072f19d48c4ec8f8a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.bin b/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.bin new file mode 100644 index 0000000..e3c09d4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.trace b/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4eadf3c57a70154f0a26c372aed1b534.trace differ diff --git a/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.bin b/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.bin new file mode 100644 index 0000000..00b6576 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.trace b/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-4f47376cc7ccf4ba328d317e7afa24cf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.bin b/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.bin new file mode 100644 index 0000000..b2d4786 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.trace b/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5008cd9c04d5e8ecf79f8d364cdb2287.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.bin b/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.bin new file mode 100644 index 0000000..a7e0995 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.trace b/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5031cd53cddc6d718c72f79fa11514b3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.bin b/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.bin new file mode 100644 index 0000000..abd6093 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.trace b/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5070f20124660e04a2e83fbc5de4af7c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.bin b/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.bin new file mode 100644 index 0000000..c778d80 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.trace b/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.trace new file mode 100644 index 0000000..3fe3309 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-50eeedb1025913440f72ae11563cb0cc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.bin b/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.bin new file mode 100644 index 0000000..e42453e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.trace b/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.trace new file mode 100644 index 0000000..750042c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-51ccaf107aea889e9743ab77c50d144f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.bin b/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.bin new file mode 100644 index 0000000..8d90db8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.trace b/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-529b6981c8d0fef37fa1f77bacaceab9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.bin b/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.bin new file mode 100644 index 0000000..82dcda8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.trace b/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.trace new file mode 100644 index 0000000..ab74167 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-52dc45cfc11469ab09af3fc8290057bf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.bin b/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.bin new file mode 100644 index 0000000..0c0e3cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.trace b/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-53f95d1e058e76a521b4527f6909de8d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.bin b/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.bin new file mode 100644 index 0000000..263d9d3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.trace b/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-549029fd5beaf3589b15bd4a44c25ad7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.bin b/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.bin new file mode 100644 index 0000000..7460bbb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.bin differ diff --git a/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.trace b/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.trace new file mode 100644 index 0000000..aed0f2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-54fb352290340aa0ef3d8fa192daf430.trace differ diff --git a/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.bin b/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.bin new file mode 100644 index 0000000..243c2cf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.trace b/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.trace new file mode 100644 index 0000000..59e5410 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-553e8b1e70bfee7502f0896458734bb0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.bin b/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.bin new file mode 100644 index 0000000..cc0ca28 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.bin differ diff --git a/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.trace b/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.trace new file mode 100644 index 0000000..7542f9c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-55b2a56f2251e4b9e7aa04c009736641.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.bin b/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.bin new file mode 100644 index 0000000..b1b9177 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.trace b/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5614b1a74299b704f72a08276fd8246f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.bin b/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.bin new file mode 100644 index 0000000..b396771 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.trace b/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.trace new file mode 100644 index 0000000..bcf1721 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-568b0a272608233710476705093152fa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.bin b/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.bin new file mode 100644 index 0000000..9f65bff Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.trace b/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.trace new file mode 100644 index 0000000..5d2a426 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-570679f72023935546768895ca405f6e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.bin b/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.bin new file mode 100644 index 0000000..bf8cdc9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.trace b/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-572a6cfecf4b24f480b518adf3c41d2d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.bin b/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.bin new file mode 100644 index 0000000..bed7e97 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.trace b/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5780e8913518d93d40459fa085893e59.trace differ diff --git a/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.bin b/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.bin new file mode 100644 index 0000000..b766e95 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.trace b/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-57fd1aedb4c5092e19f8c8f878f289c2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.bin b/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.bin new file mode 100644 index 0000000..d98ab31 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.trace b/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-58ccd94feb3c60fce1b5debf712c724a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.bin b/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.bin new file mode 100644 index 0000000..796940b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.bin differ diff --git a/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.trace b/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-592bce6cf21ccc765f38e25a89651341.trace differ diff --git a/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.bin b/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.bin new file mode 100644 index 0000000..b966b24 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.bin differ diff --git a/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.trace b/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-598e8e9278be77d0dd562023d68388ce.trace differ diff --git a/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.bin b/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.bin new file mode 100644 index 0000000..d840a43 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.bin differ diff --git a/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.trace b/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.trace new file mode 100644 index 0000000..1b1b837 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-599983c7d1ebe40d306c654898ef3402.trace differ diff --git a/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.bin b/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.bin new file mode 100644 index 0000000..5149d17 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.trace b/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-599f1901ed0e23e4ed5bf500d655a0c4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.bin b/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.bin new file mode 100644 index 0000000..c818ad5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.bin differ diff --git a/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.trace b/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.trace new file mode 100644 index 0000000..1e4f411 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-59f12e77bee6010b32ce5826d657b815.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.bin b/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.bin new file mode 100644 index 0000000..d0480a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.trace b/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5b10a75334bd910a164850c1773789ec.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.bin b/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.bin new file mode 100644 index 0000000..4231c06 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.trace b/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5b91a6bd34851f6008d28200fa2d1179.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.bin b/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.bin new file mode 100644 index 0000000..f0ae055 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.trace b/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.trace new file mode 100644 index 0000000..850aa54 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5c45a5ed398ba463aabbe4e25fb85e18.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.bin b/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.bin new file mode 100644 index 0000000..d1ca4f6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.trace b/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5ca0beb06f5783010070b45d30f40004.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.bin b/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.bin new file mode 100644 index 0000000..597dd25 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.trace b/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5cbb2594c961dd9e5e7c9187cb4c37dd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.bin b/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.bin new file mode 100644 index 0000000..0a1dfaa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.trace b/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5cc3c15420408f0f6d2bb00e588950eb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.bin b/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.bin new file mode 100644 index 0000000..fe6c6f7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.trace b/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.trace new file mode 100644 index 0000000..a8d3e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5d5bd3a8fc79251b363acab66c6e36b5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.bin b/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.bin new file mode 100644 index 0000000..e05f4d5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.trace b/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5d6da3fdd514574b37964f50b65b4efa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.bin b/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.bin new file mode 100644 index 0000000..a51c93e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.trace b/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5e4a7fe91c46222c924390ee89cdce03.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.bin b/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.bin new file mode 100644 index 0000000..42235cf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.trace b/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5ecbb9ca35f4fb9e02fdd2d4fd7390cc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.bin b/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.bin new file mode 100644 index 0000000..f136fae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.bin differ diff --git a/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.trace b/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-5efa2bb170e69e319f8ae580acb75192.trace differ diff --git a/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.bin b/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.bin new file mode 100644 index 0000000..20385b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.trace b/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-60260610757c97d25db908623d88442e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.bin b/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.bin new file mode 100644 index 0000000..385b319 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.bin differ diff --git a/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.trace b/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-606d9ff57edebd405e1d4984fe6fbe31.trace differ diff --git a/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.bin b/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.bin new file mode 100644 index 0000000..9b54d05 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.trace b/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.trace new file mode 100644 index 0000000..8f944f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-60d99ac62eb60aacfbbe23ab710e01dc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.bin b/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.bin new file mode 100644 index 0000000..ff1d51d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.trace b/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6186efa40121c61cca4dd2d1b46674b7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.bin b/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.bin new file mode 100644 index 0000000..471d7c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.bin differ diff --git a/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.trace b/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.trace new file mode 100644 index 0000000..4e7338e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-61dcee7e917d0659b550be6af4db8315.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.bin b/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.bin new file mode 100644 index 0000000..31fe5af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.trace b/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6228f7a60985e3287b81a70c5888154d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.bin b/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.bin new file mode 100644 index 0000000..d8950cb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.trace b/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6233fe150bea6ae4ce4fc8e0d97209f5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.bin b/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.bin new file mode 100644 index 0000000..352c822 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.bin differ diff --git a/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.trace b/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-62550d49d63281160c04c01e78112825.trace differ diff --git a/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.bin b/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.bin new file mode 100644 index 0000000..1bd3479 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.trace b/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.trace new file mode 100644 index 0000000..52393d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-628985a19d973f51565a8a46254c57f6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.bin b/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.bin new file mode 100644 index 0000000..38cfe40 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.bin differ diff --git a/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.trace b/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-63104a98da5e6fb20a4d89c2d86b9e97.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.bin b/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.bin new file mode 100644 index 0000000..988a346 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.trace b/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.trace new file mode 100644 index 0000000..8e15ead Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6342aa70279f29cb47ca936bcc46482f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.bin b/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.bin new file mode 100644 index 0000000..a15ac87 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.trace b/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6465b5806df3f0e6cbf1c046492d3933.trace differ diff --git a/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.bin b/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.bin new file mode 100644 index 0000000..8fa2ecc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.bin differ diff --git a/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.trace b/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64dad516aa5ef7d009e458a97eea9a36.trace differ diff --git a/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.bin b/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.bin new file mode 100644 index 0000000..0fc7388 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.trace b/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64e7ac107825f49892cb604a881ba31e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.bin b/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.bin new file mode 100644 index 0000000..7c44b3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.bin differ diff --git a/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.trace b/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.trace new file mode 100644 index 0000000..1e4f411 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-64f217d696cf3c262a3d7a1febc39e96.trace differ diff --git a/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.bin b/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.bin new file mode 100644 index 0000000..6e5d03f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.bin differ diff --git a/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.trace b/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.trace new file mode 100644 index 0000000..59e5410 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-65c616ddb7032adbb186808886569c53.trace differ diff --git a/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.bin b/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.bin new file mode 100644 index 0000000..761e6c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.trace b/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-662fda554bac6bb2a4e87023eb3febef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.bin b/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.bin new file mode 100644 index 0000000..59b7a74 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.trace b/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6631e6edcff6b1dd116168d185695da5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.bin b/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.bin new file mode 100644 index 0000000..fd21632 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.trace b/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-66d4e0e09e2b07f0f0c4821f32c14cef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.bin b/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.bin new file mode 100644 index 0000000..1a7f569 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.bin differ diff --git a/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.trace b/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-66fa97868081467c9428854d9a564916.trace differ diff --git a/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.bin b/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.bin new file mode 100644 index 0000000..9821469 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.bin differ diff --git a/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.trace b/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.trace new file mode 100644 index 0000000..a5fff0e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-67899d2150b88ab28e5123bf8d3a1d50.trace differ diff --git a/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.bin b/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.bin new file mode 100644 index 0000000..d2e59ca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.trace b/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-67da07359ed5d69ab131ff84f5e556b3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.bin b/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.bin new file mode 100644 index 0000000..1c2010f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.bin differ diff --git a/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.trace b/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-681db18f1bd6f4886d45b7f7941e30ca.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.bin b/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.bin new file mode 100644 index 0000000..9f7a5df Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.trace b/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6882ee2c35db79457a394402ac060d41.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.bin b/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.bin new file mode 100644 index 0000000..e30a750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.trace b/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.trace new file mode 100644 index 0000000..3236e1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6918b2e4cf43d6694aff580fde8be59d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.bin b/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.bin new file mode 100644 index 0000000..73eac95 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.trace b/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6966a06aa820370715618df5e629654f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.bin b/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.bin new file mode 100644 index 0000000..05ab09c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.trace b/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-69711d4b669718370e2492f61552909f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.bin b/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.bin new file mode 100644 index 0000000..2ca759b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.bin differ diff --git a/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.trace b/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.trace new file mode 100644 index 0000000..6de6f26 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-69e1a16c0111174d609ba714a934f0fe.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.bin b/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.bin new file mode 100644 index 0000000..12422aa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.trace b/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.trace new file mode 100644 index 0000000..141f40e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6a237bcfc803306b43e51e449d70b037.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.bin b/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.bin new file mode 100644 index 0000000..4c2929d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.trace b/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6a46112fdcafb22033fb586e87b00049.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.bin b/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.bin new file mode 100644 index 0000000..80a0acb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.trace b/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6b341c314b1c50eb7523dca03d687373.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.bin b/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.bin new file mode 100644 index 0000000..62c2d4b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.trace b/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6ba35a4f00aa1ae2b63e584ca7c4b906.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.bin b/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.bin new file mode 100644 index 0000000..0b5bb09 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.trace b/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6bba0fa69f1da9fb115aa3359253f1a2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.bin b/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.bin new file mode 100644 index 0000000..194f5d6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.trace b/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.trace new file mode 100644 index 0000000..98fc8b6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6c8e0a6fb4c125f093888ec8739ee0bf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.bin b/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.bin new file mode 100644 index 0000000..a56743f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.trace b/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6d7ab312478642b9ee0ca04d3a8ed8ec.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.bin b/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.bin new file mode 100644 index 0000000..5dede8b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.trace b/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6dfae9fac35f6e4dee627d9533d21c3b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.bin b/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.bin new file mode 100644 index 0000000..8bc8ebd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.trace b/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.trace new file mode 100644 index 0000000..ba59ea3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6e3b772bfabce7f8e89590aab7b7f18b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.bin b/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.bin new file mode 100644 index 0000000..1db248f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.trace b/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6e546dd38091a3c9a3f9b2033ed58975.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.bin b/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.bin new file mode 100644 index 0000000..b52f488 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.trace b/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.trace new file mode 100644 index 0000000..f0093fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6ecbfcedfceeea4652f4d1644e813fe5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.bin b/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.bin new file mode 100644 index 0000000..60d4d8d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.trace b/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f075d75231988592f2b8e4ac6baec8c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.bin b/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.bin new file mode 100644 index 0000000..fc77ef7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.trace b/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f10d3c4e29e3060bc51eabf16d7e529.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.bin b/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.bin new file mode 100644 index 0000000..ec8a329 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.trace b/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f21a09630670e9bfb0dd64ddad2b840.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.bin b/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.bin new file mode 100644 index 0000000..ada8c2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.trace b/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.trace new file mode 100644 index 0000000..59e5410 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6f6598b32d5d284acce854bbdbd2c0ab.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.bin b/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.bin new file mode 100644 index 0000000..ed7ab25 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.trace b/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6fc902484182815f930ed4a1dfd77a0f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.bin b/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.bin new file mode 100644 index 0000000..7b14c35 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.trace b/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.trace new file mode 100644 index 0000000..974e083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-6fea87156f30b6c4c4ab63b89916ef0a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.bin b/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.bin new file mode 100644 index 0000000..cdef623 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.trace b/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-70295e489dcc5486b6052726dd6eac5e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.bin b/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.bin new file mode 100644 index 0000000..f712153 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.trace b/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-702cf914f5174830459e22371cd82c4f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.bin b/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.bin new file mode 100644 index 0000000..6cac2cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.trace b/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7038eba0c861286dfddbb07d9b5e980e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.bin b/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.bin new file mode 100644 index 0000000..7528a6a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.trace b/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7142850d42967ebb6279b7c0814cdd3c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.bin b/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.bin new file mode 100644 index 0000000..f7cda3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.trace b/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-71a53b902fc84ea9d34dc9105d301d9a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.bin b/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.bin new file mode 100644 index 0000000..9217a28 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.trace b/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-721b3594f0cc8388f6d4e21018b91b5a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.bin b/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.bin new file mode 100644 index 0000000..2f470f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.bin differ diff --git a/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.trace b/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-724500d28886834b7164c54be3a463db.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.bin b/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.bin new file mode 100644 index 0000000..8b8af3b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.trace b/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.trace new file mode 100644 index 0000000..821eca8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7261033563ac83cfc82d2fa68248a2bb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.bin b/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.bin new file mode 100644 index 0000000..bc3d1e1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.trace b/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-733b6b4d8e169e40edf4c40fa46f59f7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.bin b/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.bin new file mode 100644 index 0000000..c0cdb96 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.trace b/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7372809ea58801a8df7d9a9fc7916a7c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.bin b/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.bin new file mode 100644 index 0000000..61cc4fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.trace b/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-742684f50ff228a1df2919a7da4751c8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.bin b/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.bin new file mode 100644 index 0000000..6bcd070 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.trace b/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7428b400edcab2e685c56b3d5d9ca07a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.bin b/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.bin new file mode 100644 index 0000000..c809ce6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.bin differ diff --git a/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.trace b/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-746342f06cc554f3f3d266676aea2304.trace differ diff --git a/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.bin b/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.bin new file mode 100644 index 0000000..2474fb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.trace b/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.trace new file mode 100644 index 0000000..1860ddd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-752fa83bc31a308a23717084337694a7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.bin b/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.bin new file mode 100644 index 0000000..9ecc58b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.trace b/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-757a86244f6290d856131c38da5a653f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.bin b/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.bin new file mode 100644 index 0000000..7e78ce3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.trace b/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-75b3af9f94596244330aeb7d879451d7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.bin b/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.bin new file mode 100644 index 0000000..89284f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.bin differ diff --git a/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.trace b/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.trace new file mode 100644 index 0000000..3236e1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-75c41d042ae81dfd53ec12b4266d4574.trace differ diff --git a/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.bin b/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.bin new file mode 100644 index 0000000..354a9ff Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.trace b/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.trace new file mode 100644 index 0000000..1860ddd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-772182e326f0adff2750626f8e6f103e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.bin b/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.bin new file mode 100644 index 0000000..35bff1f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.trace b/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-776d9406133625aa28219e3ccdc8ecc1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.bin b/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.bin new file mode 100644 index 0000000..c628dd7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.trace b/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7773bac0c95aa169a35fe4c2f56e7f7c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.bin b/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.bin new file mode 100644 index 0000000..4cc8a82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.trace b/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-77e46501ce3cb0ecf50690d194e6d48d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.bin b/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.bin new file mode 100644 index 0000000..f0a8682 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.bin differ diff --git a/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.trace b/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-78a19060012ffbd41190ea5de43c2b23.trace differ diff --git a/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.bin b/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.bin new file mode 100644 index 0000000..b6b6757 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.trace b/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.trace new file mode 100644 index 0000000..f3f35f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-78c4ea539d6ef5562f10252db0ac37b5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.bin b/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.bin new file mode 100644 index 0000000..517aed9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.trace b/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-79a89a9473b935ffc0cf1f8b926d63f6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.bin b/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.bin new file mode 100644 index 0000000..62a7d6a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.trace b/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.trace new file mode 100644 index 0000000..86d81f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-79fa75646838d46aee0aec0f23f3a1a4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.bin b/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.bin new file mode 100644 index 0000000..3ef45b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.trace b/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7a1228b0dc4ebb6d012686e7398d125c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.bin b/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.bin new file mode 100644 index 0000000..f01161d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.trace b/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.trace new file mode 100644 index 0000000..560223c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7a56c9c705d04c4faa8ae008ade13b81.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.bin b/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.bin new file mode 100644 index 0000000..45455c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.trace b/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7b32557e407032e85281977def1d9b00.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.bin b/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.bin new file mode 100644 index 0000000..5c53190 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.trace b/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7b952c6963539618a0e93d31d1e58765.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.bin b/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.bin new file mode 100644 index 0000000..0bf8864 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.trace b/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7bab4a3503d147f04f6c157b6ff52145.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.bin b/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.bin new file mode 100644 index 0000000..e465fdf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.trace b/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7bec6fbfc503930870c6bf996a7b4145.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.bin b/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.bin new file mode 100644 index 0000000..a9c9803 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.trace b/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7c58a12e0c4e11f9d0ba849287eadf45.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.bin b/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.bin new file mode 100644 index 0000000..4c4dafd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.trace b/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7d2999de670a14116d9641f9997ecb67.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.bin b/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.bin new file mode 100644 index 0000000..895a362 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.trace b/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.trace new file mode 100644 index 0000000..c368f4f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7d694592f731e952a53b16085bf7148d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.bin b/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.bin new file mode 100644 index 0000000..bd42de0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.trace b/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.trace new file mode 100644 index 0000000..52393d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7e08baefd608adbcd1e87acc8552d74a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.bin b/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.bin new file mode 100644 index 0000000..4689ffc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.trace b/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7e9835e4099d977eb38857a58022559b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.bin b/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.bin new file mode 100644 index 0000000..2448cbf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.trace b/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.trace new file mode 100644 index 0000000..974e083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7eeadbb855c407376c2fd54a502cbcc0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.bin b/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.bin new file mode 100644 index 0000000..e77392e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.trace b/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.trace new file mode 100644 index 0000000..5d2a426 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7f0ece80033e2f9985b81dacf62775c0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.bin b/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.bin new file mode 100644 index 0000000..88af905 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.bin differ diff --git a/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.trace b/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-7ff434854c30339006be299ae04c5934.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.bin b/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.bin new file mode 100644 index 0000000..9405505 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.trace b/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8078e5601fb071a9eeccec492afc3b85.trace differ diff --git a/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.bin b/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.bin new file mode 100644 index 0000000..9916e7d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.bin differ diff --git a/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.trace b/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.trace new file mode 100644 index 0000000..6de6f26 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-80a34555552f3c4523a52ea9e6de4169.trace differ diff --git a/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.bin b/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.bin new file mode 100644 index 0000000..fb6884e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.bin differ diff --git a/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.trace b/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.trace new file mode 100644 index 0000000..a8d3e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-814b41f45f6fd3693e73dba3da3c8eec.trace differ diff --git a/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.bin b/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.bin new file mode 100644 index 0000000..36896db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.trace b/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.trace new file mode 100644 index 0000000..652971f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-816d56f9adc9edcfbd63113d014e019f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.bin b/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.bin new file mode 100644 index 0000000..0f96042 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.trace b/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-818c88efb3301d875d7790af92beb2f5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.bin b/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.bin new file mode 100644 index 0000000..7622a8c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.trace b/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-81bd442fd03dfd7cec337c39868fcd1e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.bin b/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.bin new file mode 100644 index 0000000..d191a9d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.bin differ diff --git a/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.trace b/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-81c9e827ede4e391862bb152d5812cde.trace differ diff --git a/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.bin b/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.bin new file mode 100644 index 0000000..d4a65e1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.bin differ diff --git a/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.trace b/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-826fcb9f979c14f30934ea4e1fa19964.trace differ diff --git a/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.bin b/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.bin new file mode 100644 index 0000000..237d649 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.trace b/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.trace new file mode 100644 index 0000000..560223c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82d92d3fbd048161d853d79519254d4c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.bin b/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.bin new file mode 100644 index 0000000..fe17d9c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.bin differ diff --git a/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.trace b/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82eb92ef0ac2b65b425fd96148e59b77.trace differ diff --git a/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.bin b/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.bin new file mode 100644 index 0000000..4f54dbe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.bin differ diff --git a/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.trace b/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-82f19583aa17326f11ff52949557f287.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.bin b/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.bin new file mode 100644 index 0000000..99820c4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.trace b/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8305ff9ce5846fe93d3e8a1b46b1563c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.bin b/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.bin new file mode 100644 index 0000000..5b7b79f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.trace b/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8354e946ff0d83d316c806f517e954b4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.bin b/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.bin new file mode 100644 index 0000000..ae100f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.trace b/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-852ce4c1bf17aa1134ec94e33e2b2d9d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.bin b/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.bin new file mode 100644 index 0000000..560cef9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.trace b/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-85b96547533a6a21c84e1e0f9bc630f7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.bin b/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.bin new file mode 100644 index 0000000..cba8654 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.trace b/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-869ddbd31f3077164adf64ca1507c1dc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.bin b/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.bin new file mode 100644 index 0000000..c5eb980 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.trace b/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-86a1b7fb7544c5b1f0da745e3f29f3bd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.bin b/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.bin new file mode 100644 index 0000000..b862523 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.trace b/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-86b38c7d6f8dcbd0e00ed7006b93291f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.bin b/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.bin new file mode 100644 index 0000000..60f2524 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.bin differ diff --git a/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.trace b/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.trace new file mode 100644 index 0000000..8ad6ce9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-87070d79fc009ad2ae81bea3f1fedf43.trace differ diff --git a/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.bin b/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.bin new file mode 100644 index 0000000..cdd6c96 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.bin differ diff --git a/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.trace b/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-872d8b02d20a44ae305bff948b21eb17.trace differ diff --git a/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.bin b/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.bin new file mode 100644 index 0000000..cf9c455 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.trace b/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-877f2f3ece4135a0047274193ba66c3a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.bin b/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.bin new file mode 100644 index 0000000..d006a05 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.trace b/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8807f69159fa5a6b8b0d35c37984cfcc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.bin b/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.bin new file mode 100644 index 0000000..35470d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.trace b/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-885fb903728fb2d076f5c9ab0ca31f7e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.bin b/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.bin new file mode 100644 index 0000000..e32e211 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.trace b/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-89f771dad198c706ca7865492a72c36f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.bin b/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.bin new file mode 100644 index 0000000..c90a80c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.trace b/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.trace new file mode 100644 index 0000000..a49f228 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8aafb4c73bc18254d7dabd9c09cee57a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.bin b/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.bin new file mode 100644 index 0000000..65a2236 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.trace b/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.trace new file mode 100644 index 0000000..4a0da37 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ada8f8598d3308eea861f0b757af811.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.bin b/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.bin new file mode 100644 index 0000000..c69a272 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.trace b/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.trace new file mode 100644 index 0000000..c0d15bf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8bc4accf5654ee434ed3fa3933dd21a4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.bin b/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.bin new file mode 100644 index 0000000..0ea1a1f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.trace b/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8bdcbc895c9f634edffb6f86b1cc8e95.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.bin b/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.bin new file mode 100644 index 0000000..ff5f817 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.trace b/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c44fa9157ebc95d0d63b06bb9ced8dc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.bin b/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.bin new file mode 100644 index 0000000..fb8f543 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.trace b/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.trace new file mode 100644 index 0000000..d31c556 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c5d6041c997981d579b1fbabe9015fe.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.bin b/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.bin new file mode 100644 index 0000000..3de7f56 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.trace b/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8c7fdc66a7d0dbf51a0b355f5e0d7fd8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.bin b/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.bin new file mode 100644 index 0000000..915b566 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.trace b/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ca2403bf268a28aedcd4746f4a2bbff.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.bin b/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.bin new file mode 100644 index 0000000..5735015 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.trace b/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8cb6db180d076385e32bf36fd95d88bd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.bin b/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.bin new file mode 100644 index 0000000..ce353a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.trace b/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8cd2e43d00e03225e475a175bfd09530.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.bin b/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.bin new file mode 100644 index 0000000..1311777 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.trace b/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d0602846cc2cb40e2da9914664ca544.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.bin b/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.bin new file mode 100644 index 0000000..4966254 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.trace b/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d1ec529bba8cad7658795ace90f3972.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.bin b/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.bin new file mode 100644 index 0000000..b2169f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.trace b/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.trace new file mode 100644 index 0000000..bf5dd43 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8d60ad3ef4cc60f083493e76d82702ca.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.bin b/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.bin new file mode 100644 index 0000000..f6a5852 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.trace b/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.trace new file mode 100644 index 0000000..b740c98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8da0be00b7d5455dcd0f8569e63e0f01.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.bin b/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.bin new file mode 100644 index 0000000..d000ed7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.trace b/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8e297c0d57b6a3b224d2d751c7add356.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.bin b/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.bin new file mode 100644 index 0000000..3221f49 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.trace b/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.trace new file mode 100644 index 0000000..c1f5583 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f0ac22dfd9c9e7b26dacd8869d30a38.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.bin b/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.bin new file mode 100644 index 0000000..ff90968 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.trace b/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f0e9ddf99948957c6a1d212c10a239d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.bin b/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.bin new file mode 100644 index 0000000..2b5bdac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.trace b/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f2d42b557f5003a6508c7c622ac33a5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.bin b/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.bin new file mode 100644 index 0000000..486d374 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.trace b/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8f621822466aa4e88d46dd1637ac2371.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.bin b/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.bin new file mode 100644 index 0000000..1613aa1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.trace b/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.trace new file mode 100644 index 0000000..1ec4284 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8fd3f5e76262ba1b41a333ff17b22704.trace differ diff --git a/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.bin b/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.bin new file mode 100644 index 0000000..7352bd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.bin differ diff --git a/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.trace b/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-8ff5bc199724b5bfd48198d55444db07.trace differ diff --git a/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.bin b/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.bin new file mode 100644 index 0000000..40f3f3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.trace b/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.trace new file mode 100644 index 0000000..148bfb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-90161f7e476036ff04102a85f31c1af4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.bin b/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.bin new file mode 100644 index 0000000..25cf519 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.trace b/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.trace new file mode 100644 index 0000000..a4acaea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9034038b16f0b71fb236c6925f4204bb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.bin b/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.bin new file mode 100644 index 0000000..d6e9754 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.trace b/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9038cd9f5d17b72c9bb6d74dfb099558.trace differ diff --git a/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.bin b/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.bin new file mode 100644 index 0000000..00bfb3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.trace b/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.trace new file mode 100644 index 0000000..4e7338e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-906d6e4f643351ab9d210f55f0c7b6b1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.bin b/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.bin new file mode 100644 index 0000000..d3c97a2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.trace b/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-91026a7eb2f02d4f2750d1de96ae048e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.bin b/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.bin new file mode 100644 index 0000000..40fc224 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.bin differ diff --git a/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.trace b/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-917b51e7de10e258fb657f01a066fc71.trace differ diff --git a/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.bin b/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.bin new file mode 100644 index 0000000..2b8ee14 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.trace b/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-91f0e5879c6b632dccf5eab18596812d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.bin b/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.bin new file mode 100644 index 0000000..fa5c5f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.trace b/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9212e1da9f7488e2f7803a72a736e3bf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.bin b/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.bin new file mode 100644 index 0000000..aec6af5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.trace b/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-926e388b8899c3c97a48785f5f749d5e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.bin b/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.bin new file mode 100644 index 0000000..9d0217f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.bin differ diff --git a/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.trace b/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-92fdee06033143367a8d35829969c627.trace differ diff --git a/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.bin b/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.bin new file mode 100644 index 0000000..25862b1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.trace b/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-93adcb179a7ef2a4747d49f0a3642cef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.bin b/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.bin new file mode 100644 index 0000000..c1d4c59 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.trace b/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-945637450814d9309864950da983f70b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.bin b/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.bin new file mode 100644 index 0000000..d2e3e58 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.trace b/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.trace new file mode 100644 index 0000000..a8d3e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-948e98a7d99ecc8d30bdec7fb25702e0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.bin b/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.bin new file mode 100644 index 0000000..049fc19 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.bin differ diff --git a/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.trace b/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-94a8bcb9d99945a4eff9c0691ecb69ac.trace differ diff --git a/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.bin b/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.bin new file mode 100644 index 0000000..f27b1dd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.trace b/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-94dfb0802ddb393c37ab3ca7703346aa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.bin b/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.bin new file mode 100644 index 0000000..5d07f64 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.trace b/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.trace new file mode 100644 index 0000000..b57abfb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-951069c0b44bf47bd724fc893cbf607f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.bin b/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.bin new file mode 100644 index 0000000..a4a4a06 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.bin differ diff --git a/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.trace b/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95511cc2b68b628a18897d91653c4b61.trace differ diff --git a/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.bin b/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.bin new file mode 100644 index 0000000..79ed2bb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.bin differ diff --git a/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.trace b/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.trace new file mode 100644 index 0000000..e3b83ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95774bf2e1909d50cf4ece34dd0ae791.trace differ diff --git a/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.bin b/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.bin new file mode 100644 index 0000000..6449506 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.trace b/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95826ad836f15de8683a56c24f09586b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.bin b/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.bin new file mode 100644 index 0000000..d6904bc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.bin differ diff --git a/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.trace b/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.trace new file mode 100644 index 0000000..aed0f2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95a7c911dc7fb4c75ff05fe54ba0f438.trace differ diff --git a/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.bin b/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.bin new file mode 100644 index 0000000..db37ad9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.trace b/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-95b82f74d3ac13e4bf0a333d32c1592d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.bin b/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.bin new file mode 100644 index 0000000..b375294 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.trace b/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96b9c56e59c5137db2c03a0cc0a2c79a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.bin b/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.bin new file mode 100644 index 0000000..ae91b5f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.bin differ diff --git a/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.trace b/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96bba344fa174f5de85a44fb8afae595.trace differ diff --git a/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.bin b/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.bin new file mode 100644 index 0000000..c9a5f4f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.trace b/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-96c317abbc5da8f218d5d5e8de4af6f0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.bin b/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.bin new file mode 100644 index 0000000..a3b109b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.trace b/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.trace new file mode 100644 index 0000000..c61fd85 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-973d1f54e1a19ae13194cd62bb79c1d3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.bin b/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.bin new file mode 100644 index 0000000..331a797 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.trace b/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.trace new file mode 100644 index 0000000..230182a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-97cbe6b97026013075ed9ef17a44383e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.bin b/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.bin new file mode 100644 index 0000000..a24f5c8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.trace b/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-97faa6aa1546c1f8a9d4b7cc5140c1b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.bin b/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.bin new file mode 100644 index 0000000..ee24c5b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.trace b/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.trace new file mode 100644 index 0000000..974e083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9806da8f5acc79b5f07d370ee38c61b4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.bin b/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.bin new file mode 100644 index 0000000..51102f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.bin differ diff --git a/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.trace b/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98092cfec4dbfde1cbffa7845bb6b1da.trace differ diff --git a/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.bin b/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.bin new file mode 100644 index 0000000..8bf5862 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.trace b/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-980c24d0ef1bfcc7d4c6e786996e41dd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.bin b/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.bin new file mode 100644 index 0000000..4cd5bb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.trace b/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.trace new file mode 100644 index 0000000..16db2f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9892f9f1877e338ab80ef63eb144378d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.bin b/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.bin new file mode 100644 index 0000000..f994bc3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.trace b/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98a03c8452b231652f47a6f4c3e4ac9e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.bin b/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.bin new file mode 100644 index 0000000..a032853 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.trace b/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98a6bdc1079e306267a6325b22ac99e4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.bin b/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.bin new file mode 100644 index 0000000..e09ad32 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.bin differ diff --git a/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.trace b/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.trace new file mode 100644 index 0000000..afa5ab5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-98f0dfa99f9c612319e20ad5d5ee8611.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.bin b/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.bin new file mode 100644 index 0000000..1a288f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.trace b/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.trace new file mode 100644 index 0000000..8b16740 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9953bf7be86df3c32077cce3939c4f75.trace differ diff --git a/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.bin b/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.bin new file mode 100644 index 0000000..6590535 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.bin differ diff --git a/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.trace b/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99541337c6ad66009e7711593f80b121.trace differ diff --git a/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.bin b/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.bin new file mode 100644 index 0000000..3430d2c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.trace b/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.trace new file mode 100644 index 0000000..ee8783a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99b47f35fc8f996d5dfec0db080fa2e7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.bin b/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.bin new file mode 100644 index 0000000..13538d5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.trace b/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-99b80f56f7524b1bfbc982716f79d32e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.bin b/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.bin new file mode 100644 index 0000000..ca90b31 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.trace b/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.trace new file mode 100644 index 0000000..bcdf99b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9a0693a3db5c55c7fc37c842f7bc2c3e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.bin b/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.bin new file mode 100644 index 0000000..3cf0de7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.trace b/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.trace new file mode 100644 index 0000000..b6e5285 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9a7709d765c7ab200fa8d688e2e7e159.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.bin b/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.bin new file mode 100644 index 0000000..16c01a7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.trace b/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ac92cdba4875830256f8b02e51faaa8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.bin b/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.bin new file mode 100644 index 0000000..9058a27 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.trace b/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9af6e60506f17e33fcadb5513f5452c2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.bin b/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.bin new file mode 100644 index 0000000..f3ab343 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.trace b/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c3aaea9fb79757789b22a59c93b7864.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.bin b/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.bin new file mode 100644 index 0000000..9af0b7f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.trace b/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c3d13f43bd59f575af0dd17ab2f9ea3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.bin b/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.bin new file mode 100644 index 0000000..41c4cef Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.trace b/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c52765d11afdea1730760f8a3b1fdf5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.bin b/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.bin new file mode 100644 index 0000000..340cb3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.trace b/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9c8c309f1d009ed53964a1f62fe004a6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.bin b/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.bin new file mode 100644 index 0000000..430e3fa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.trace b/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ccbf15b857ae4a9324af2218bacc4e7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.bin b/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.bin new file mode 100644 index 0000000..a2c4a66 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.trace b/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9da945d71e3e09ce3e4ccca532f4b9e0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.bin b/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.bin new file mode 100644 index 0000000..ff5f92a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.trace b/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9e01e3c5c31b1ac62cb1f3183429cedb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.bin b/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.bin new file mode 100644 index 0000000..67224c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.trace b/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ee8f26a06f9df9b45a78b1f6ddf61f7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.bin b/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.bin new file mode 100644 index 0000000..871a723 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.trace b/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9ef3575e50a96b3a15dc1f25994e5153.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.bin b/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.bin new file mode 100644 index 0000000..7c9d3c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.trace b/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f1a84170a49b05236e405dd2584d716.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.bin b/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.bin new file mode 100644 index 0000000..f6071de Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.trace b/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.trace new file mode 100644 index 0000000..7010cda Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f7e4d288bf82ffbe48d0c4ab48622b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.bin b/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.bin new file mode 100644 index 0000000..c64f1ab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.trace b/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-9f8539de14dcc30b978c92673d7d344b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.bin b/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.bin new file mode 100644 index 0000000..ac305cb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.trace b/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a14f827781bde52916833f3a13eff00e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.bin b/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.bin new file mode 100644 index 0000000..6ca5aa3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.trace b/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.trace new file mode 100644 index 0000000..b3822db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1695b114877592f9ba1109ba65cbeac.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.bin b/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.bin new file mode 100644 index 0000000..6373d0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.trace b/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1cca2ed015fab9275fad280ba85de0b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.bin b/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.bin new file mode 100644 index 0000000..219003c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.trace b/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a1fb2c71e7b1226f0055ab682601fb3f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.bin b/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.bin new file mode 100644 index 0000000..eefad81 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.trace b/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a21bdb68d52388007dad1dd8a42dc041.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.bin b/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.bin new file mode 100644 index 0000000..6bfd6cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.trace b/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a29f5fbc47c5764f854fb86d22fe3215.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.bin b/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.bin new file mode 100644 index 0000000..4eab752 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.trace b/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a2a24a1ae38d1b6a9a58b6ebf5dc8772.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.bin b/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.bin new file mode 100644 index 0000000..5a20dc4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.trace b/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a3136218ed980986a9742ccb8f1f8006.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.bin b/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.bin new file mode 100644 index 0000000..01e3791 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.trace b/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.trace new file mode 100644 index 0000000..b55cfdc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a3ad8c29fc5ea5d2a9c3a69201af6bf5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.bin b/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.bin new file mode 100644 index 0000000..218448a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.trace b/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a4b633e872d86968859651f053b7f73b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.bin b/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.bin new file mode 100644 index 0000000..a3e8c55 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.trace b/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a5994387f3885f22cec2bebb1fc204b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.bin b/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.bin new file mode 100644 index 0000000..be79808 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.trace b/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.trace new file mode 100644 index 0000000..fc2d006 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a67926a7362b2dc4aab66cce8253a76a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.bin b/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.bin new file mode 100644 index 0000000..f019cd7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.trace b/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.trace new file mode 100644 index 0000000..a4a74d9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a722390955c9861fe023b70369032a81.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.bin b/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.bin new file mode 100644 index 0000000..5cd512a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.trace b/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a7cc5902e1456bafa72565d2fe05e925.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.bin b/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.bin new file mode 100644 index 0000000..c2c405c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.trace b/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a88d41391aecc5b17f67dc336434ef76.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.bin b/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.bin new file mode 100644 index 0000000..11bb6d3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.trace b/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.trace new file mode 100644 index 0000000..b6e5285 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a8a7d1480e6ff27ec13ce281cd134baa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.bin b/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.bin new file mode 100644 index 0000000..a189bc3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.trace b/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a90e9dd76f066aac45f35e6fe85c7a7f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.bin b/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.bin new file mode 100644 index 0000000..39177c5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.trace b/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a9542c97142998b8ec112c29588c665d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.bin b/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.bin new file mode 100644 index 0000000..584e8ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.trace b/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a97f9ae999c7b6eb861fd243159384fb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.bin b/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.bin new file mode 100644 index 0000000..1f3b194 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.trace b/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.trace new file mode 100644 index 0000000..f0093fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a99f2c9d20a2e3881a3cd77fc819094b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.bin b/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.bin new file mode 100644 index 0000000..d960559 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.trace b/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-a9c413d1a2207601383167865d0c2ca8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.bin b/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.bin new file mode 100644 index 0000000..6204244 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.bin differ diff --git a/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.trace b/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa2276063bc9b97b3e25f802f06cef10.trace differ diff --git a/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.bin b/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.bin new file mode 100644 index 0000000..3c56d1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.bin differ diff --git a/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.trace b/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.trace new file mode 100644 index 0000000..e7524e3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa2d73abaa3c5d0ca7b75d39ff159f83.trace differ diff --git a/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.bin b/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.bin new file mode 100644 index 0000000..65429db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.bin differ diff --git a/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.trace b/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa3b71458853bf1584c21f435812dfed.trace differ diff --git a/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.bin b/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.bin new file mode 100644 index 0000000..de85628 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.bin differ diff --git a/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.trace b/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.trace new file mode 100644 index 0000000..1acf04f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-aa47ea90688f1194667c3246ea041a29.trace differ diff --git a/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.bin b/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.bin new file mode 100644 index 0000000..de1e90c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.bin differ diff --git a/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.trace b/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.trace new file mode 100644 index 0000000..bcf1721 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-abdfba7ea1e1e57daa1fb3a5ab4701fe.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.bin b/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.bin new file mode 100644 index 0000000..adf52e2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.trace b/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.trace new file mode 100644 index 0000000..85fd017 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac143d7633800ad741bfc1768e5c3657.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.bin b/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.bin new file mode 100644 index 0000000..cbb9a11 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.trace b/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac7a30bad1a464a46db4bad1e2804150.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.bin b/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.bin new file mode 100644 index 0000000..6adbe15 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.trace b/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.trace new file mode 100644 index 0000000..3236e1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ac94752e9c65b153380b199172f52cfb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.bin b/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.bin new file mode 100644 index 0000000..2f2beae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.trace b/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.trace new file mode 100644 index 0000000..ec64dd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ad42bdcb6c7d2b79d63dd329ee8b4706.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.bin b/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.bin new file mode 100644 index 0000000..7d1f536 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.trace b/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.trace new file mode 100644 index 0000000..b75cc27 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ad91e86c1e4f2e510343e8e18ecd6841.trace differ diff --git a/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.bin b/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.bin new file mode 100644 index 0000000..b41cb7f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.bin differ diff --git a/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.trace b/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adabfec3e1af0c1f67337c0b4a865a08.trace differ diff --git a/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.bin b/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.bin new file mode 100644 index 0000000..ce8833c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.trace b/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adb6aaca97727a94c5b991fb50771dc8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.bin b/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.bin new file mode 100644 index 0000000..324fd0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.trace b/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-adc3d02cc80bac15d121c99614272fd7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.bin b/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.bin new file mode 100644 index 0000000..f9edb13 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.trace b/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae00f5d52c3ab0dc815d12437c62cbe0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.bin b/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.bin new file mode 100644 index 0000000..24b2ce9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.trace b/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae08656b51fc6278dfa39449d16613f2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.bin b/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.bin new file mode 100644 index 0000000..4aa3f9f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.trace b/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.trace new file mode 100644 index 0000000..dffddb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ae71246b2158fb1133f8792f1d50fbea.trace differ diff --git a/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.bin b/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.bin new file mode 100644 index 0000000..3c85afe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.trace b/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.trace new file mode 100644 index 0000000..c55fc2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-af876377f5592ee216e43352041f166c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.bin b/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.bin new file mode 100644 index 0000000..dcaf2dc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.trace b/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-afc17291cccd37299d10ff292fc67f3b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.bin b/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.bin new file mode 100644 index 0000000..e7d5de7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.trace b/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b010cee26a938840cf9b8b6769f04ae8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.bin b/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.bin new file mode 100644 index 0000000..c4e0ce4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.trace b/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.trace new file mode 100644 index 0000000..05558a4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b04fb858d7e1f28534b6312d38d289e2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.bin b/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.bin new file mode 100644 index 0000000..239f346 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.trace b/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b080de8a062597d9c08d818a5b3d5bfd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.bin b/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.bin new file mode 100644 index 0000000..cf57ea8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.trace b/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b0ead7b85feab1573f8ec66c96784cd3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.bin b/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.bin new file mode 100644 index 0000000..cfacc94 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.trace b/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1591e9f208d59edfa23591a2a542775.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.bin b/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.bin new file mode 100644 index 0000000..135ed33 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.trace b/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b17044af6c39203d54572f275535ac80.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.bin b/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.bin new file mode 100644 index 0000000..273eb86 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.trace b/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1a4ee7d5e0079e2feb021c5064e82bb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.bin b/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.bin new file mode 100644 index 0000000..8c3dd7d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.trace b/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b1b6a799ba4d894cb6b2d1023e0172e3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.bin b/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.bin new file mode 100644 index 0000000..b5004c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.trace b/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.trace new file mode 100644 index 0000000..ae3322d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b3d66d3ac47477b884903bd4a0d13d42.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.bin b/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.bin new file mode 100644 index 0000000..7a935f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.trace b/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b42ce8fb93175a3e97a4bc7d4f6d4d37.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.bin b/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.bin new file mode 100644 index 0000000..f366ddc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.trace b/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b435cf84415c376a8596d23a78164df8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.bin b/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.bin new file mode 100644 index 0000000..b7bef7f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.trace b/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b46e622efcadc2f12ed45c897a45c7df.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.bin b/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.bin new file mode 100644 index 0000000..e91fc23 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.trace b/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b4ab7430f4234d67a1e119b2f21a42a5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.bin b/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.bin new file mode 100644 index 0000000..4bb7e57 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.trace b/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.trace new file mode 100644 index 0000000..aea587e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b559cf233f9727d45dd0b2a49b16dc2c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.bin b/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.bin new file mode 100644 index 0000000..ead81e7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.trace b/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b593f3cd4052b3243c5477bf50d5a2de.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.bin b/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.bin new file mode 100644 index 0000000..fedb70f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.trace b/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b5ae2e23670e4797d661beb27e22131b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.bin b/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.bin new file mode 100644 index 0000000..48b68d7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.trace b/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.trace new file mode 100644 index 0000000..f288146 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b5f2aabc1375236e0f32988db091a906.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.bin b/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.bin new file mode 100644 index 0000000..13db148 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.trace b/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6d98d1a1df847c66a83395d0d432eb9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.bin b/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.bin new file mode 100644 index 0000000..f19d36d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.trace b/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6e757793d2b9bf3bed16be6b9ad51f4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.bin b/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.bin new file mode 100644 index 0000000..6fb5438 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.trace b/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b6f2b39ddb29fa47eac08e441fcbed50.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.bin b/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.bin new file mode 100644 index 0000000..a205e77 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.trace b/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.trace new file mode 100644 index 0000000..974e083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b706c9e4932657b88ca287aea577b4ed.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.bin b/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.bin new file mode 100644 index 0000000..d4696c4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.trace b/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b779a586ca2e08a307f6da4ecc323ad8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.bin b/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.bin new file mode 100644 index 0000000..ab823a1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.trace b/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b7c93730c2bbcba5b4f6144d601d24a0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.bin b/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.bin new file mode 100644 index 0000000..438b73e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.trace b/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.trace new file mode 100644 index 0000000..750042c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b7ff03eb5c096e2458b1193e9c278cbe.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.bin b/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.bin new file mode 100644 index 0000000..cfd6161 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.trace b/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b82be2c041cd23f75bbe5c06eac9509f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.bin b/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.bin new file mode 100644 index 0000000..4685d2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.trace b/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b87fe5922cee743c2145d43c653e9198.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.bin b/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.bin new file mode 100644 index 0000000..544a754 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.trace b/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.trace new file mode 100644 index 0000000..32a53d2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9241cff0ccd03b25257272bd57b8ff8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.bin b/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.bin new file mode 100644 index 0000000..d0272f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.trace b/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9a5ca275d57745e0137a69b43f1ac38.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.bin b/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.bin new file mode 100644 index 0000000..5a78e48 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.trace b/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9c3d6d072999b90db0c163fbe9f2afd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.bin b/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.bin new file mode 100644 index 0000000..455820e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.trace b/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9d887a9b4858891d1125ab4c7533c68.trace differ diff --git a/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.bin b/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.bin new file mode 100644 index 0000000..bb544a6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.trace b/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-b9f17482db45ffe7fd50074edde9b0d2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.bin b/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.bin new file mode 100644 index 0000000..19da8b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.trace b/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ba1aba7adde0d9299399a3dae0a4ab49.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.bin b/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.bin new file mode 100644 index 0000000..325242e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.trace b/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.trace new file mode 100644 index 0000000..f3f35f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ba8cac4fb87a9bf2f0886cebdab0f77a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.bin b/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.bin new file mode 100644 index 0000000..a0fa4fa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.trace b/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bb04ec0efc478c296e84e444ce96233c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.bin b/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.bin new file mode 100644 index 0000000..c48e712 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.trace b/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.trace new file mode 100644 index 0000000..8f944f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bc2c56980e803990ff3e57445c285c39.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.bin b/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.bin new file mode 100644 index 0000000..09ed995 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.trace b/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bc69583e8f4114474e850cb9315accd2.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.bin b/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.bin new file mode 100644 index 0000000..498a7ea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.trace b/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bcd5398c6c2a93d951d5e4ffdac9f79f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.bin b/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.bin new file mode 100644 index 0000000..104a5b3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.trace b/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bd56b97a40fc8a48dda87674b0c49f41.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.bin b/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.bin new file mode 100644 index 0000000..b2285d5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.trace b/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bd6c42530a1e2c3c5131b14f301a55cc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.bin b/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.bin new file mode 100644 index 0000000..48a5f1f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.trace b/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bdeb7ec2fbe6abcc490f450f5adcbe2a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.bin b/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.bin new file mode 100644 index 0000000..73f1ac0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.trace b/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bf4602dedaf9f7e22ec98560a5645c04.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.bin b/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.bin new file mode 100644 index 0000000..530b97b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.trace b/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.trace new file mode 100644 index 0000000..12c9b93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bf7a993973b625f34c8c6bf9526f6e3b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.bin b/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.bin new file mode 100644 index 0000000..1ea4a5c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.trace b/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-bfb3b624ca8b12815d44b21c3836259a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.bin b/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.bin new file mode 100644 index 0000000..73f0322 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.trace b/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c02cd943225efa2de920c60f64207a11.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.bin b/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.bin new file mode 100644 index 0000000..e44cf23 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.trace b/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c0bff95ff8ccf8b1ecec40de45bd816e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.bin b/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.bin new file mode 100644 index 0000000..437d399 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.trace b/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c10f266b1735e3d8cb1ceb24add9721f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.bin b/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.bin new file mode 100644 index 0000000..41cb8e0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.trace b/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c12f7c045ec1c59764d7d7f4c2d4a3ba.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.bin b/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.bin new file mode 100644 index 0000000..7c7536a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.trace b/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c13c376ad257d807cbdc50b0e6c4d7bb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.bin b/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.bin new file mode 100644 index 0000000..f44b123 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.trace b/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.trace new file mode 100644 index 0000000..3236e1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c15ecae81ed036dd0ea83cd22bec28b4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.bin b/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.bin new file mode 100644 index 0000000..fec9426 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.trace b/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c16c7ff89e2b298a698c17b78d81f7c7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.bin b/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.bin new file mode 100644 index 0000000..d0cdd55 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.trace b/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c186d102e3aa6aac73f64060aae8356c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.bin b/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.bin new file mode 100644 index 0000000..5db22f3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.trace b/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1947848f636a3d63db3ebe46d3d37e5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.bin b/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.bin new file mode 100644 index 0000000..1a41748 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.trace b/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1b226478c0dd30134f247ed84aa0413.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.bin b/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.bin new file mode 100644 index 0000000..a56510a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.trace b/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c1c575cced6d9b4e9802bce6a080d368.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.bin b/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.bin new file mode 100644 index 0000000..cf1d808 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.trace b/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.trace new file mode 100644 index 0000000..f0093fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c2004df98d422585a30176b3b5cc1296.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.bin b/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.bin new file mode 100644 index 0000000..aa61567 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.trace b/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.trace new file mode 100644 index 0000000..f3e5893 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c202881662cd0849465d0fa062938b2d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.bin b/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.bin new file mode 100644 index 0000000..052875f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.trace b/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c231342783867f7b2b7516c543a1dc9e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.bin b/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.bin new file mode 100644 index 0000000..78450ca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.trace b/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.trace new file mode 100644 index 0000000..5bdff83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c247d7b4f69c3e2b2e792c5cda81ac3e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.bin b/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.bin new file mode 100644 index 0000000..1c6fc62 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.trace b/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3a772465c6c2b0876a624151299643e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.bin b/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.bin new file mode 100644 index 0000000..66b53ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.trace b/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3c56e0608b554abb66b42c69c9200d1.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.bin b/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.bin new file mode 100644 index 0000000..017412c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.trace b/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.trace new file mode 100644 index 0000000..3d5ad23 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c3c5bd0b9b2f20f74743c6844adbccae.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.bin b/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.bin new file mode 100644 index 0000000..52878cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.trace b/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c4a985d05bf2557f5424e54b0cacece5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.bin b/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.bin new file mode 100644 index 0000000..d85bd5f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.trace b/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c565bede8b05872f4a5256d7e819c1bf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.bin b/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.bin new file mode 100644 index 0000000..d3cad90 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.trace b/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6a46c44651e491f3fc835eda6ed3626.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.bin b/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.bin new file mode 100644 index 0000000..edcd4fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.trace b/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.trace new file mode 100644 index 0000000..974e083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6c003a556d25f0417c185a3088e568a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.bin b/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.bin new file mode 100644 index 0000000..219a861 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.trace b/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6ef9bae93b0be40474a021491ad328e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.bin b/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.bin new file mode 100644 index 0000000..4128ce1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.trace b/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.trace new file mode 100644 index 0000000..652971f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c6f829f6292b62eccd6cf50fa9565baf.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.bin b/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.bin new file mode 100644 index 0000000..d486150 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.trace b/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.trace new file mode 100644 index 0000000..ed66617 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c76dabeb89e94362ee31145fe12630c6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.bin b/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.bin new file mode 100644 index 0000000..abaf357 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.trace b/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c777e5e311e059065de31c82d808d885.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.bin b/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.bin new file mode 100644 index 0000000..46e80f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.trace b/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c7f05326a0ec6aa3158bb62a7e4d0c29.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.bin b/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.bin new file mode 100644 index 0000000..e75489f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.trace b/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8129a31e94afee9a4f0540c78784852.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.bin b/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.bin new file mode 100644 index 0000000..d250aef Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.trace b/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.trace new file mode 100644 index 0000000..b1c023e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8258e2e8ffcde97946d295c6fe456b5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.bin b/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.bin new file mode 100644 index 0000000..b8f8631 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.trace b/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c86ff4d386b2c254fd25d56e71cc04e8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.bin b/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.bin new file mode 100644 index 0000000..3d3d422 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.trace b/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c87badf50a2785dcdb92af0709060a81.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.bin b/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.bin new file mode 100644 index 0000000..8bbb82b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.trace b/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.trace new file mode 100644 index 0000000..e1c982d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c8d567cbd6094f686c52f5f932187c1c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.bin b/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.bin new file mode 100644 index 0000000..762bda1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.trace b/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.trace new file mode 100644 index 0000000..76a4d1d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c91b4be98a93460c057541993283c343.trace differ diff --git a/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.bin b/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.bin new file mode 100644 index 0000000..a8ae6d7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.bin differ diff --git a/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.trace b/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-c9c6b80a24828a26afc4317c372d7053.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.bin b/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.bin new file mode 100644 index 0000000..9ef2549 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.trace b/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ca6510bd7eb064312cb3fdb2ad7ab6b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.bin b/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.bin new file mode 100644 index 0000000..2dcfde2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.trace b/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cb8322a78ef0340786e0d5f234c2f6b4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.bin b/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.bin new file mode 100644 index 0000000..504e45a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.trace b/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cc442c4347fc56ba08deea340c8d5794.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.bin b/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.bin new file mode 100644 index 0000000..30d4667 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.trace b/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ccb26aac2ad8a4f9c871e90cc22ac4d0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.bin b/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.bin new file mode 100644 index 0000000..043db33 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.trace b/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd04425a559ce9c80a2f62b4ddebbe21.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.bin b/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.bin new file mode 100644 index 0000000..aed6f5a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.trace b/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd23c02ea5b1134d2aad1d768aa0212b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.bin b/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.bin new file mode 100644 index 0000000..3cac65b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.trace b/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cd251d7e34602582638564a9b4a2335f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.bin b/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.bin new file mode 100644 index 0000000..3410592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.trace b/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.trace new file mode 100644 index 0000000..db6b5db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ce83491f3364fce6797865685ec7c85d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.bin b/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.bin new file mode 100644 index 0000000..19bd695 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.trace b/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cebeb2c2f149afea9aac5e94878e7b18.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.bin b/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.bin new file mode 100644 index 0000000..d52d9ef Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.trace b/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cf0c2445006b2563b6a80c85eb5e5474.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.bin b/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.bin new file mode 100644 index 0000000..6718e2d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.trace b/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cf7fb6bd3d1c0bf3cffb10545b236ae7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.bin b/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.bin new file mode 100644 index 0000000..f094164 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.trace b/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-cfdf4afc242eddccd11de779d28b825c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.bin b/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.bin new file mode 100644 index 0000000..c61750f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.trace b/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.trace new file mode 100644 index 0000000..86d81f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d009e923a94cbe8996f07e9fa471ac83.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.bin b/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.bin new file mode 100644 index 0000000..5082b57 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.trace b/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.trace new file mode 100644 index 0000000..230182a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d0837258ae9725094c2fbf264a14288f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.bin b/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.bin new file mode 100644 index 0000000..fee64f6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.trace b/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d09e0085f4661f02ac26c4e320396e87.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.bin b/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.bin new file mode 100644 index 0000000..8803fed Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.trace b/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.trace new file mode 100644 index 0000000..c61fd85 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d1d576f77113ea130e4b6c95c3b63e86.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.bin b/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.bin new file mode 100644 index 0000000..d0fdf10 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.trace b/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d23cf7df2ed4588cf375688c3a0ad14b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.bin b/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.bin new file mode 100644 index 0000000..f0e7e77 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.trace b/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d2630362b16121d7ec0d620ad69b928d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.bin b/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.bin new file mode 100644 index 0000000..1c08b8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.trace b/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.trace new file mode 100644 index 0000000..b001205 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d2de5d61e3462368a206b33fd590aeef.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.bin b/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.bin new file mode 100644 index 0000000..1781e96 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.trace b/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d309b974b02a2082341bdb2af5ac2004.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.bin b/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.bin new file mode 100644 index 0000000..0755503 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.trace b/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.trace new file mode 100644 index 0000000..52393d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d342159fe0b014c60d586650ecec408f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.bin b/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.bin new file mode 100644 index 0000000..68baf41 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.trace b/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.trace new file mode 100644 index 0000000..59e5410 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d3c504882455730ad1a5671d86e07e62.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.bin b/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.bin new file mode 100644 index 0000000..d1bb61d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.trace b/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.trace new file mode 100644 index 0000000..ae9fa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d3d3412108e96e73459bd012f6692b7d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.bin b/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.bin new file mode 100644 index 0000000..98a6a16 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.trace b/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.trace new file mode 100644 index 0000000..e3b83ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d445bc577108d12e7bcbf18d4067142b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.bin b/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.bin new file mode 100644 index 0000000..8dbc13e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.trace b/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d54b63effc32499e6939b76c65e2e96f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.bin b/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.bin new file mode 100644 index 0000000..2918a8c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.trace b/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.trace new file mode 100644 index 0000000..6ca8822 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d55b808ba27c5d95adaa01e25bdd39b7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.bin b/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.bin new file mode 100644 index 0000000..3976643 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.trace b/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d568b807e00888347edf06925c6192e5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.bin b/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.bin new file mode 100644 index 0000000..4a276c5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.trace b/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.trace new file mode 100644 index 0000000..17cc3fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d580bb5c0f43d0fd311775f4ba5c5a3e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.bin b/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.bin new file mode 100644 index 0000000..ae9a2e1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.trace b/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.trace new file mode 100644 index 0000000..560223c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d594b7503dd92d85316a07c5d075ba5b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.bin b/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.bin new file mode 100644 index 0000000..d8f99b2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.trace b/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d5a5426f0f258dd6cb517a22baf797cb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.bin b/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.bin new file mode 100644 index 0000000..1bb9ac6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.trace b/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d73d96bcb42124625a5002eb681998f3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.bin b/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.bin new file mode 100644 index 0000000..f1b04bc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.trace b/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d74bccef4734128c9e743fdc332ad08d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.bin b/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.bin new file mode 100644 index 0000000..3212e86 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.trace b/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.trace new file mode 100644 index 0000000..1860ddd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d7918e517a8a02fbe86202c5d4e4011a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.bin b/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.bin new file mode 100644 index 0000000..9203734 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.trace b/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d85af6441ccde363b3e4a6e9729c8056.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.bin b/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.bin new file mode 100644 index 0000000..e341887 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.trace b/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.trace new file mode 100644 index 0000000..a926d3c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d88ae5f5f30d77a2aa419926b4883df6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.bin b/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.bin new file mode 100644 index 0000000..7dd7d82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.trace b/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d91f7a5bb7d085ae665271fbf1431cca.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.bin b/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.bin new file mode 100644 index 0000000..bcd0407 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.trace b/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d933764045cf51fdb0b4cdf78c9d54a8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.bin b/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.bin new file mode 100644 index 0000000..73d5c20 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.trace b/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d946fcedca6aa48be2c661106f0ef3c6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.bin b/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.bin new file mode 100644 index 0000000..0357c2a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.bin differ diff --git a/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.trace b/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.trace new file mode 100644 index 0000000..a72cbc6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-d9f25489af952fe67da8094052ac2d97.trace differ diff --git a/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.bin b/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.bin new file mode 100644 index 0000000..4a73183 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.bin differ diff --git a/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.trace b/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da23fbdc31ff42a3fac376fa07cc8672.trace differ diff --git a/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.bin b/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.bin new file mode 100644 index 0000000..835f2fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.trace b/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da3f9a27fc147b9a01e8b2132bb2f2e7.trace differ diff --git a/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.bin b/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.bin new file mode 100644 index 0000000..1c98831 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.bin differ diff --git a/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.trace b/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.trace new file mode 100644 index 0000000..ba59ea3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-da518fcc901ec111b1d6ffff7d4e3ced.trace differ diff --git a/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.bin b/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.bin new file mode 100644 index 0000000..af9aa55 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.bin differ diff --git a/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.trace b/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-db12101ae2495f349b1c435a0adeba17.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.bin b/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.bin new file mode 100644 index 0000000..fb270c2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.trace b/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbb082eb0c89ad566e9ae88e29f531ca.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.bin b/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.bin new file mode 100644 index 0000000..6360c5b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.trace b/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbc057cd08affdc9fafea884459ca21b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.bin b/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.bin new file mode 100644 index 0000000..e178d20 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.trace b/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbdf23ef07480912c21cd63d9e656d9d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.bin b/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.bin new file mode 100644 index 0000000..a83c56d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.trace b/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.trace new file mode 100644 index 0000000..9556fd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dbe794df0d119d3109442a60ae7cb2c3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.bin b/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.bin new file mode 100644 index 0000000..2baa756 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.trace b/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dca2d2e42c29b55849b08e12cc80582b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.bin b/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.bin new file mode 100644 index 0000000..c6401c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.trace b/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.trace new file mode 100644 index 0000000..1e4f411 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dd225635ffd080fead22456a235a1956.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.bin b/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.bin new file mode 100644 index 0000000..b13f1a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.trace b/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.trace new file mode 100644 index 0000000..aeba6c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ddb1bafd281d8200176f75c2211e59f5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.bin b/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.bin new file mode 100644 index 0000000..cfcc72d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.trace b/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.trace new file mode 100644 index 0000000..b57abfb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ddcee43b6d00d37cecc766eb05296524.trace differ diff --git a/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.bin b/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.bin new file mode 100644 index 0000000..5b237aa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.trace b/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-de65bbd8b7ecd86e6cea40ab07f3d11b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.bin b/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.bin new file mode 100644 index 0000000..ed8701a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.trace b/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dec2eb593a21c6ed40dae0eb2badfa1e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.bin b/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.bin new file mode 100644 index 0000000..37851be Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.trace b/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.trace new file mode 100644 index 0000000..52393d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dec4197fa069e7389a84e6ee1fdebfd9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.bin b/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.bin new file mode 100644 index 0000000..61f26df Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.bin differ diff --git a/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.trace b/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-dee373ea252cc2c334e626ee9175f120.trace differ diff --git a/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.bin b/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.bin new file mode 100644 index 0000000..bdb4e46 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.bin differ diff --git a/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.trace b/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df61aa1697a594e12c1b3d2b6613c2ff.trace differ diff --git a/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.bin b/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.bin new file mode 100644 index 0000000..d29d2bf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.bin differ diff --git a/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.trace b/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.trace new file mode 100644 index 0000000..f3e5893 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df7fbcf9c1b5ec169d7326195b5c24ac.trace differ diff --git a/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.bin b/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.bin new file mode 100644 index 0000000..83f0087 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.trace b/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-df87841fab9be63ebbcd1291cab6283a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.bin b/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.bin new file mode 100644 index 0000000..6987988 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.trace b/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e0f4739817d3bf332dcbc33d6bd39d27.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.bin b/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.bin new file mode 100644 index 0000000..53400c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.trace b/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.trace new file mode 100644 index 0000000..2b5c750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e156ecb1725cbcd6a8854cce708b6536.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.bin b/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.bin new file mode 100644 index 0000000..6e45b85 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.trace b/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.trace new file mode 100644 index 0000000..148bfb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e1a0dbf8518035ed209d6b4a92133855.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.bin b/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.bin new file mode 100644 index 0000000..5a567a1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.trace b/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e22e24cca8a36accce9b3becd2e62b34.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.bin b/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.bin new file mode 100644 index 0000000..fbc1614 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.trace b/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e30206549daff8dfac3b681ed6ee768c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.bin b/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.bin new file mode 100644 index 0000000..e9d8b92 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.trace b/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.trace new file mode 100644 index 0000000..00cfa6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e4f8fb8dac5c6068431937fee656f5a5.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.bin b/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.bin new file mode 100644 index 0000000..8b65557 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.trace b/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e5f38378d5f003b156fa1405f93b5976.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.bin b/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.bin new file mode 100644 index 0000000..d873506 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.trace b/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e65cfd643c0e9ad2931b3e051498596c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.bin b/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.bin new file mode 100644 index 0000000..aaa52f5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.trace b/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.trace new file mode 100644 index 0000000..c55fc2e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e7969437e98ff1c6d439a01f413ad161.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.bin b/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.bin new file mode 100644 index 0000000..295a3af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.trace b/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8840f1bfb2b81722d01063eb1cc813a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.bin b/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.bin new file mode 100644 index 0000000..c20fec4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.trace b/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.trace new file mode 100644 index 0000000..8f944f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8b4b8bed93b5c63bab2d08c1e70d310.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.bin b/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.bin new file mode 100644 index 0000000..ba72a19 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.trace b/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8b84c0164b81748986b88634f5492b3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.bin b/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.bin new file mode 100644 index 0000000..2742cff Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.trace b/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.trace new file mode 100644 index 0000000..b09f698 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8fd8a3b96fde8164d18f6978c3839dd.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.bin b/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.bin new file mode 100644 index 0000000..2065ee8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.trace b/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.trace new file mode 100644 index 0000000..e1c982d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e8ffe3d80a7407a2994df22678c1c17e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.bin b/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.bin new file mode 100644 index 0000000..f971b55 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.bin differ diff --git a/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.trace b/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.trace new file mode 100644 index 0000000..e87d2ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-e9d4083860dc53fb55d836d56fe43d22.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.bin b/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.bin new file mode 100644 index 0000000..30f4285 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.trace b/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.trace new file mode 100644 index 0000000..ba59ea3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ea11284cd2bb82e0419d037b82b25c22.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.bin b/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.bin new file mode 100644 index 0000000..3ba45b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.trace b/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eab29edff48d4b50af7baf584ab9cea0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.bin b/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.bin new file mode 100644 index 0000000..dc4209f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.trace b/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eac285978d42d2b51937c1567a7b435a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.bin b/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.bin new file mode 100644 index 0000000..4c88447 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.trace b/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.trace new file mode 100644 index 0000000..b7d1b2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb247c928fbe03ea2be306075312b054.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.bin b/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.bin new file mode 100644 index 0000000..6a8d73b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.trace b/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb79810b143dbd296cfd51ea4d891eb3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.bin b/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.bin new file mode 100644 index 0000000..a145f44 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.trace b/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.trace new file mode 100644 index 0000000..1860ddd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eb7b9395f246424a26d764be87125817.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.bin b/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.bin new file mode 100644 index 0000000..12c0d4b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.trace b/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.trace new file mode 100644 index 0000000..47d9c7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebb8678db235b9044f0e1a79a82f05d6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.bin b/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.bin new file mode 100644 index 0000000..59984b4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.trace b/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.trace new file mode 100644 index 0000000..03f5f8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebc7e8d66591cdadc45f75cbc26cbed6.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.bin b/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.bin new file mode 100644 index 0000000..70611a1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.trace b/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.trace new file mode 100644 index 0000000..a1948cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebee108c68ecd8ef861d67fd2d60c28f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.bin b/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.bin new file mode 100644 index 0000000..2e72d5e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.trace b/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ebf6172c2ededa008420c1c344f28c18.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.bin b/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.bin new file mode 100644 index 0000000..fdbfced Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.trace b/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.trace new file mode 100644 index 0000000..1e4f411 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ece1cacba3c7905f2582d120995f6001.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.bin b/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.bin new file mode 100644 index 0000000..fa6c9a2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.trace b/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ed27741a8c3fd421a73811f0a6774f5f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.bin b/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.bin new file mode 100644 index 0000000..13ad258 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.trace b/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.trace new file mode 100644 index 0000000..b740c98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ed8ca5c19073f102cec3b96944b16615.trace differ diff --git a/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.bin b/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.bin new file mode 100644 index 0000000..ea164c0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.bin differ diff --git a/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.trace b/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.trace new file mode 100644 index 0000000..b55cfdc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-edfacaa4e924236a16d97dba5766f4f9.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.bin b/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.bin new file mode 100644 index 0000000..289061e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.trace b/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee1e626099422c78546d85e815382bf0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.bin b/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.bin new file mode 100644 index 0000000..61381c3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.trace b/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.trace new file mode 100644 index 0000000..a4acaea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee22d6b2d8b9da1ffcbeac5c33172b5a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.bin b/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.bin new file mode 100644 index 0000000..742ec2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.trace b/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ee3d347864ddc84d0bf1a1f77b7c3573.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.bin b/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.bin new file mode 100644 index 0000000..a365e6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.trace b/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.trace new file mode 100644 index 0000000..fda5d7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eeea73f94db4eead023a0fc2c8d6e02b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.bin b/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.bin new file mode 100644 index 0000000..a74537e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.trace b/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-eeff0622a1f76d4ce6769da9da3986b4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.bin b/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.bin new file mode 100644 index 0000000..76706da Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.bin differ diff --git a/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.trace b/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-efebc4d6e36f2971ac5ad8c4ec925d54.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.bin b/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.bin new file mode 100644 index 0000000..53a5188 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.trace b/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f023250fb48b0a4f5ffbb12c9bee0191.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.bin b/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.bin new file mode 100644 index 0000000..64b9ddb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.trace b/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.trace new file mode 100644 index 0000000..148bfb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f06ba0e7155043e31ac3b1366ce43e45.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.bin b/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.bin new file mode 100644 index 0000000..2d15786 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.trace b/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.trace new file mode 100644 index 0000000..b55cfdc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f07742ada72a02c4067b446547335d09.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.bin b/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.bin new file mode 100644 index 0000000..cadf59f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.trace b/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f090fc092880926b781100e3617e84cb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.bin b/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.bin new file mode 100644 index 0000000..d0b0df9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.trace b/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f0aa4396cc6b6550c9ac62062294d00c.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.bin b/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.bin new file mode 100644 index 0000000..6920f86 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.trace b/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.trace new file mode 100644 index 0000000..a7f319f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f13ff8a56c152dbab9af0608403c2da4.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.bin b/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.bin new file mode 100644 index 0000000..b2cedac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.trace b/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f153968e9c3089ffa6cf52dbe4f36130.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.bin b/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.bin new file mode 100644 index 0000000..d3cc42b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.trace b/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.trace new file mode 100644 index 0000000..ee8783a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f316a5ebd4a1fa3e59e95802ca9d140b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.bin b/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.bin new file mode 100644 index 0000000..8762440 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.trace b/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.trace new file mode 100644 index 0000000..5eccc0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f372c4a22d33185cc9577d9b06b4318d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.bin b/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.bin new file mode 100644 index 0000000..7b132b2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.trace b/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f4049f72163eaa7f901a14dd577cda57.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.bin b/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.bin new file mode 100644 index 0000000..49b0859 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.trace b/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.trace new file mode 100644 index 0000000..84e45c8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f4f36a11ddccfdd81f5172f83cc1f124.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.bin b/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.bin new file mode 100644 index 0000000..636e1d1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.trace b/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.trace new file mode 100644 index 0000000..a72cbc6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f53155664557c0d9b11e420fbc3ed5e8.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.bin b/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.bin new file mode 100644 index 0000000..0fe2582 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.trace b/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.trace new file mode 100644 index 0000000..b6e5285 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f578ce011ad08eab0db992fc9f11bb9e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.bin b/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.bin new file mode 100644 index 0000000..5d3549b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.trace b/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.trace new file mode 100644 index 0000000..a43e898 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f5cee985e95b4c4e7c5cdceb826563bb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.bin b/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.bin new file mode 100644 index 0000000..c3a95b5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.trace b/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f61ef685a423601546b00c4cb4b5aa94.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.bin b/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.bin new file mode 100644 index 0000000..45a0ae8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.trace b/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.trace new file mode 100644 index 0000000..b740c98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f650c4570cfff7067bbc762403bbf275.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.bin b/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.bin new file mode 100644 index 0000000..308f02b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.trace b/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.trace new file mode 100644 index 0000000..697b914 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f73ccc45526760a99558ff9d5ed360eb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.bin b/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.bin new file mode 100644 index 0000000..2a1d8d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.trace b/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.trace new file mode 100644 index 0000000..412017c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f75fc5c564dc16a8b328dd5978c1401a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.bin b/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.bin new file mode 100644 index 0000000..baccbac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.trace b/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.trace new file mode 100644 index 0000000..823caf6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f77e9d92038fa461178c87fea685acbc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.bin b/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.bin new file mode 100644 index 0000000..a77b41f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.trace b/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.trace new file mode 100644 index 0000000..5c15091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f82c15a2d8259c7de26fa809dea2c8ab.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.bin b/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.bin new file mode 100644 index 0000000..f2db619 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.trace b/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.trace new file mode 100644 index 0000000..a72cbc6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f846c83e3b9cfba7028bd4f1a1af56aa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.bin b/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.bin new file mode 100644 index 0000000..3035c82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.trace b/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.trace new file mode 100644 index 0000000..4a1c125 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f94362ec75803936c11ea21397b77e2a.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.bin b/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.bin new file mode 100644 index 0000000..01b961a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.trace b/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.trace new file mode 100644 index 0000000..d4b429b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f9593ae7d21a5e21e91819ca4c0f462d.trace differ diff --git a/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.bin b/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.bin new file mode 100644 index 0000000..68e2acf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.trace b/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-f9f39442fc9fee4a584f7cf5ef4098f3.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.bin b/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.bin new file mode 100644 index 0000000..ec6efb8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.trace b/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.trace new file mode 100644 index 0000000..a107022 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fa904aa8c827bcbf09b23014aea7aaeb.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.bin b/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.bin new file mode 100644 index 0000000..a10b055 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.trace b/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.trace new file mode 100644 index 0000000..5e178f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fb02a362a7c348b9b826a91404157a5e.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.bin b/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.bin new file mode 100644 index 0000000..bd775fb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.trace b/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.trace new file mode 100644 index 0000000..09edf0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fb3fdf8eee4b1dcc0802c422771c8c23.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.bin b/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.bin new file mode 100644 index 0000000..b231fa9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.trace b/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.trace new file mode 100644 index 0000000..9c5c592 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fc592e5521302c6e6e0d4e7f47d8d2bc.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.bin b/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.bin new file mode 100644 index 0000000..d336334 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.trace b/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.trace new file mode 100644 index 0000000..5d439f0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fc8a5b654c054913df42ff7500d82c81.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.bin b/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.bin new file mode 100644 index 0000000..5ee8c56 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.trace b/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.trace new file mode 100644 index 0000000..1acf04f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fcf2a7c2a657bfeaee096d8a9b8114fa.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.bin b/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.bin new file mode 100644 index 0000000..e237e19 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.trace b/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.trace new file mode 100644 index 0000000..6637f0b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fd45e3490e2add38a95d9707ea37283b.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.bin b/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.bin new file mode 100644 index 0000000..6932958 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.trace b/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.trace new file mode 100644 index 0000000..ab2cbc1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fe0199bcfc5426ad38a8fbc592bd7c33.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.bin b/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.bin new file mode 100644 index 0000000..3978b0f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.trace b/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.trace new file mode 100644 index 0000000..86d81f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fe46e5404b8e5b540d2c62c84b451c28.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.bin b/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.bin new file mode 100644 index 0000000..86ae1de Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.trace b/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.trace new file mode 100644 index 0000000..5d2a426 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fea6514db16d7116041c48012efa6a92.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.bin b/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.bin new file mode 100644 index 0000000..a7fec61 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.trace b/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.trace new file mode 100644 index 0000000..9c1e4e6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fed972b5a8084f55f196b9008b0a0e7f.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.bin b/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.bin new file mode 100644 index 0000000..ff25205 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.trace b/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.trace new file mode 100644 index 0000000..78581cb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ff2a783c0f51eecde5f1d8b791ff69b0.trace differ diff --git a/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.bin b/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.bin new file mode 100644 index 0000000..1f9e5b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.bin differ diff --git a/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.trace b/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.trace new file mode 100644 index 0000000..7f464ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-ff3f614b9386a2bb0bd6665ab49c75ae.trace differ diff --git a/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.bin b/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.bin new file mode 100644 index 0000000..f1ccfe2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.bin differ diff --git a/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.trace b/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.trace new file mode 100644 index 0000000..85c05ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app-fff604fd5bedb0987de0455a216e8323.trace differ diff --git a/board/evb/findmy/mdk/bin/app.bin b/board/evb/findmy/mdk/bin/app.bin new file mode 100644 index 0000000..be79808 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0025d881463dc05aad49d92234e5219f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0025d881463dc05aad49d92234e5219f.bin new file mode 100644 index 0000000..3ead34a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0025d881463dc05aad49d92234e5219f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-00acb2e2cc301c6bf504e554d11efcaf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-00acb2e2cc301c6bf504e554d11efcaf.bin new file mode 100644 index 0000000..9b7fadb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-00acb2e2cc301c6bf504e554d11efcaf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-01b6d71dc94fa266852cdff217655cf6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-01b6d71dc94fa266852cdff217655cf6.bin new file mode 100644 index 0000000..f8cfa84 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-01b6d71dc94fa266852cdff217655cf6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-024de1ea74e8d426ebb17fff364f8db4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-024de1ea74e8d426ebb17fff364f8db4.bin new file mode 100644 index 0000000..cc32692 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-024de1ea74e8d426ebb17fff364f8db4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ccbcbce99ca45aecf3674c12fe1cae.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ccbcbce99ca45aecf3674c12fe1cae.bin new file mode 100644 index 0000000..d767691 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ccbcbce99ca45aecf3674c12fe1cae.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ede84a1a37bd8fdb77e6d35da42616.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ede84a1a37bd8fdb77e6d35da42616.bin new file mode 100644 index 0000000..de09583 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-02ede84a1a37bd8fdb77e6d35da42616.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0379491e4b97b9de9dab710d6105b50d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0379491e4b97b9de9dab710d6105b50d.bin new file mode 100644 index 0000000..cb95ee1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0379491e4b97b9de9dab710d6105b50d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03996c971f2c15995744e6613766e061.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03996c971f2c15995744e6613766e061.bin new file mode 100644 index 0000000..1eee1f3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03996c971f2c15995744e6613766e061.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03d93fb4263e64e4ff2228495de1bf71.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03d93fb4263e64e4ff2228495de1bf71.bin new file mode 100644 index 0000000..592b8a1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-03d93fb4263e64e4ff2228495de1bf71.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-044ec4454ae083493f7f6241885f0434.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-044ec4454ae083493f7f6241885f0434.bin new file mode 100644 index 0000000..aa7c047 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-044ec4454ae083493f7f6241885f0434.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-04a95bb9e695cd664b0b529a7b4065a6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-04a95bb9e695cd664b0b529a7b4065a6.bin new file mode 100644 index 0000000..33bf386 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-04a95bb9e695cd664b0b529a7b4065a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-054bcdf6a9ef3a3d0b2ef3220fb1942d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-054bcdf6a9ef3a3d0b2ef3220fb1942d.bin new file mode 100644 index 0000000..0667e28 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-054bcdf6a9ef3a3d0b2ef3220fb1942d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0586e6fbf7927394067f7074d19c3624.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0586e6fbf7927394067f7074d19c3624.bin new file mode 100644 index 0000000..f99d513 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0586e6fbf7927394067f7074d19c3624.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-065f4ddc59d2367f83237d66f82049e3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-065f4ddc59d2367f83237d66f82049e3.bin new file mode 100644 index 0000000..0dabeda Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-065f4ddc59d2367f83237d66f82049e3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-06aa844d39fb5a8dc2c90551f6a75ea2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-06aa844d39fb5a8dc2c90551f6a75ea2.bin new file mode 100644 index 0000000..39da7bd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-06aa844d39fb5a8dc2c90551f6a75ea2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07058763868d74c7826560f30d1a9134.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07058763868d74c7826560f30d1a9134.bin new file mode 100644 index 0000000..45a6137 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07058763868d74c7826560f30d1a9134.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-073f6c83dc8f831b514af4a1ba6988fc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-073f6c83dc8f831b514af4a1ba6988fc.bin new file mode 100644 index 0000000..9b2db3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-073f6c83dc8f831b514af4a1ba6988fc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07a6f190da9e888f1219b76db6fbeed6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07a6f190da9e888f1219b76db6fbeed6.bin new file mode 100644 index 0000000..8928259 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-07a6f190da9e888f1219b76db6fbeed6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-095c8d08d7ca71a30328c7c81f93b3a9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-095c8d08d7ca71a30328c7c81f93b3a9.bin new file mode 100644 index 0000000..4acbba8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-095c8d08d7ca71a30328c7c81f93b3a9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09bd7f3506f1cacc3331dc0367d28370.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09bd7f3506f1cacc3331dc0367d28370.bin new file mode 100644 index 0000000..75b6af0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09bd7f3506f1cacc3331dc0367d28370.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09f34302fb4c4056e7449a30a5a2a8ca.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09f34302fb4c4056e7449a30a5a2a8ca.bin new file mode 100644 index 0000000..14a5414 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-09f34302fb4c4056e7449a30a5a2a8ca.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a345ed6d7527d67394e493c9f4921ed.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a345ed6d7527d67394e493c9f4921ed.bin new file mode 100644 index 0000000..28a5d31 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a345ed6d7527d67394e493c9f4921ed.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a975ea11eeb4ecbcbcb1d8213d79f3d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a975ea11eeb4ecbcbcb1d8213d79f3d.bin new file mode 100644 index 0000000..c624eb0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0a975ea11eeb4ecbcbcb1d8213d79f3d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ac019d48376f6563ca5c7f8088699f3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ac019d48376f6563ca5c7f8088699f3.bin new file mode 100644 index 0000000..8e682c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ac019d48376f6563ca5c7f8088699f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b08db17baaf5eae30d2a235184acea9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b08db17baaf5eae30d2a235184acea9.bin new file mode 100644 index 0000000..0df0330 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b08db17baaf5eae30d2a235184acea9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ec62aee0028efd6a0a09562a03439.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ec62aee0028efd6a0a09562a03439.bin new file mode 100644 index 0000000..cc176f7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ec62aee0028efd6a0a09562a03439.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ecc15a57b89178f42a1013fc8951a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ecc15a57b89178f42a1013fc8951a.bin new file mode 100644 index 0000000..0b28873 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0b1ecc15a57b89178f42a1013fc8951a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ba05c81ed0c1ce41c3a5b4f25519e5d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ba05c81ed0c1ce41c3a5b4f25519e5d.bin new file mode 100644 index 0000000..43b92c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ba05c81ed0c1ce41c3a5b4f25519e5d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0bf3a6f05a5f14321843ef5bdd005a62.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0bf3a6f05a5f14321843ef5bdd005a62.bin new file mode 100644 index 0000000..be2e416 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0bf3a6f05a5f14321843ef5bdd005a62.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c1445be40a9a9d08322f38f0777760d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c1445be40a9a9d08322f38f0777760d.bin new file mode 100644 index 0000000..e9ad696 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c1445be40a9a9d08322f38f0777760d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c3348c9518ffe926f7e032aea80daaf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c3348c9518ffe926f7e032aea80daaf.bin new file mode 100644 index 0000000..7afc8a6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c3348c9518ffe926f7e032aea80daaf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c90678b2413d5cb1f81fd24996ac836.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c90678b2413d5cb1f81fd24996ac836.bin new file mode 100644 index 0000000..869a7bf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0c90678b2413d5cb1f81fd24996ac836.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ca10920f3bfb2b285dd22a6ec22ba53.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ca10920f3bfb2b285dd22a6ec22ba53.bin new file mode 100644 index 0000000..b8430a6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0ca10920f3bfb2b285dd22a6ec22ba53.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0cf37a9eced253bbc9cb23485c858acd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0cf37a9eced253bbc9cb23485c858acd.bin new file mode 100644 index 0000000..a6de326 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0cf37a9eced253bbc9cb23485c858acd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0d24e801ffe6b899990e322bec9f4a58.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0d24e801ffe6b899990e322bec9f4a58.bin new file mode 100644 index 0000000..4e58f74 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0d24e801ffe6b899990e322bec9f4a58.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dc0ef6835aa4668d4d790e39018dbdf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dc0ef6835aa4668d4d790e39018dbdf.bin new file mode 100644 index 0000000..d4a06ab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dc0ef6835aa4668d4d790e39018dbdf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dd9d8040a164ef89f88c3bd74104a99.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dd9d8040a164ef89f88c3bd74104a99.bin new file mode 100644 index 0000000..d340d29 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0dd9d8040a164ef89f88c3bd74104a99.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e09b59c6b2a969a66f7c9db8ec84244.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e09b59c6b2a969a66f7c9db8ec84244.bin new file mode 100644 index 0000000..9b6204c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e09b59c6b2a969a66f7c9db8ec84244.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e26aeeea2ac8ede9396250079a73f5d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e26aeeea2ac8ede9396250079a73f5d.bin new file mode 100644 index 0000000..e98534d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e26aeeea2ac8ede9396250079a73f5d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e4050f9875832f67c95dd506af872db.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e4050f9875832f67c95dd506af872db.bin new file mode 100644 index 0000000..ec6f7f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e4050f9875832f67c95dd506af872db.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e50fabc4394d09cb1b80628dd98e62c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e50fabc4394d09cb1b80628dd98e62c.bin new file mode 100644 index 0000000..68603d4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0e50fabc4394d09cb1b80628dd98e62c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f54a19dd9dfd5afc099853243da8e5b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f54a19dd9dfd5afc099853243da8e5b.bin new file mode 100644 index 0000000..6bfff71 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f54a19dd9dfd5afc099853243da8e5b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f86a74468aec1d0b86bd77ef0d9509c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f86a74468aec1d0b86bd77ef0d9509c.bin new file mode 100644 index 0000000..abd5236 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f86a74468aec1d0b86bd77ef0d9509c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f8d747ddab5b772d216efe092349057.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f8d747ddab5b772d216efe092349057.bin new file mode 100644 index 0000000..eec8243 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-0f8d747ddab5b772d216efe092349057.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-100600793a7d5ef9443dd128689ca39c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-100600793a7d5ef9443dd128689ca39c.bin new file mode 100644 index 0000000..b262045 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-100600793a7d5ef9443dd128689ca39c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-10d83fc1c36df74d53cc6a4fbd7eb2b4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-10d83fc1c36df74d53cc6a4fbd7eb2b4.bin new file mode 100644 index 0000000..0b79bb4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-10d83fc1c36df74d53cc6a4fbd7eb2b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11a83888160188eb0d5e20d71bb9db43.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11a83888160188eb0d5e20d71bb9db43.bin new file mode 100644 index 0000000..b93dff7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11a83888160188eb0d5e20d71bb9db43.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11c9b9332965403955a4cfcb16eacb77.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11c9b9332965403955a4cfcb16eacb77.bin new file mode 100644 index 0000000..605b8b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-11c9b9332965403955a4cfcb16eacb77.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1234463cbc5aaee608b9fcc2ff533d4d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1234463cbc5aaee608b9fcc2ff533d4d.bin new file mode 100644 index 0000000..33a312d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1234463cbc5aaee608b9fcc2ff533d4d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-12e2facf7845c50a9c3435de6b7e78df.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-12e2facf7845c50a9c3435de6b7e78df.bin new file mode 100644 index 0000000..32f8ee1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-12e2facf7845c50a9c3435de6b7e78df.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13a97be31bea36d2d339b5f7d05c6d5b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13a97be31bea36d2d339b5f7d05c6d5b.bin new file mode 100644 index 0000000..e206768 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13a97be31bea36d2d339b5f7d05c6d5b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13da1b438282e36c9dcdc4ad08ff8156.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13da1b438282e36c9dcdc4ad08ff8156.bin new file mode 100644 index 0000000..f57facd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13da1b438282e36c9dcdc4ad08ff8156.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13e35d5c44d6641e2f84813a86947e87.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13e35d5c44d6641e2f84813a86947e87.bin new file mode 100644 index 0000000..3195a89 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13e35d5c44d6641e2f84813a86947e87.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13f1e29c8a3f38521a192607693907be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13f1e29c8a3f38521a192607693907be.bin new file mode 100644 index 0000000..c050201 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-13f1e29c8a3f38521a192607693907be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-140f0ef9ef3afeec68850edd60415319.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-140f0ef9ef3afeec68850edd60415319.bin new file mode 100644 index 0000000..d0e79b4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-140f0ef9ef3afeec68850edd60415319.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-147d2d13b49ac8d4f2c91777dd9ca88a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-147d2d13b49ac8d4f2c91777dd9ca88a.bin new file mode 100644 index 0000000..b2866ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-147d2d13b49ac8d4f2c91777dd9ca88a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14878644c8ecf4be9a2f4bb78a00ecde.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14878644c8ecf4be9a2f4bb78a00ecde.bin new file mode 100644 index 0000000..f2f907a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14878644c8ecf4be9a2f4bb78a00ecde.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14d8a8ec772a0a8f40115d48b598ef37.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14d8a8ec772a0a8f40115d48b598ef37.bin new file mode 100644 index 0000000..19c7118 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14d8a8ec772a0a8f40115d48b598ef37.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14e20f3b9ab569da614432d4aab33ac6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14e20f3b9ab569da614432d4aab33ac6.bin new file mode 100644 index 0000000..42e32f5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-14e20f3b9ab569da614432d4aab33ac6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-156e1e21520da11aa3fd9057f52d5431.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-156e1e21520da11aa3fd9057f52d5431.bin new file mode 100644 index 0000000..ca0a3c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-156e1e21520da11aa3fd9057f52d5431.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15b5511dfcace6130c250bf31a726f8b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15b5511dfcace6130c250bf31a726f8b.bin new file mode 100644 index 0000000..65f9119 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15b5511dfcace6130c250bf31a726f8b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15cf69d0adc71d6c438569b63de3e177.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15cf69d0adc71d6c438569b63de3e177.bin new file mode 100644 index 0000000..4584e7f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-15cf69d0adc71d6c438569b63de3e177.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-163bd48d9fa2cbe98887986a229d6e2a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-163bd48d9fa2cbe98887986a229d6e2a.bin new file mode 100644 index 0000000..18676c3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-163bd48d9fa2cbe98887986a229d6e2a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1679032b56160872c2a76fc0ce35b3e7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1679032b56160872c2a76fc0ce35b3e7.bin new file mode 100644 index 0000000..8fb16e9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1679032b56160872c2a76fc0ce35b3e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-16b13d1f310e3b7c227166994d16c6af.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-16b13d1f310e3b7c227166994d16c6af.bin new file mode 100644 index 0000000..b82f32c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-16b13d1f310e3b7c227166994d16c6af.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17075bdcfdd733651617f7672952de38.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17075bdcfdd733651617f7672952de38.bin new file mode 100644 index 0000000..e7dd2bc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17075bdcfdd733651617f7672952de38.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1752ba88456ab3f210a37736c4ad93cf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1752ba88456ab3f210a37736c4ad93cf.bin new file mode 100644 index 0000000..5558dbc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1752ba88456ab3f210a37736c4ad93cf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17bfd135e797013c5b7cfd297ab87217.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17bfd135e797013c5b7cfd297ab87217.bin new file mode 100644 index 0000000..b33528b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-17bfd135e797013c5b7cfd297ab87217.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-183ccb2cd9a5f2423b8827c0230f8b48.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-183ccb2cd9a5f2423b8827c0230f8b48.bin new file mode 100644 index 0000000..03c61e3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-183ccb2cd9a5f2423b8827c0230f8b48.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1a49c1885b7b18c8dee02056a06b23aa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1a49c1885b7b18c8dee02056a06b23aa.bin new file mode 100644 index 0000000..a3d9e08 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1a49c1885b7b18c8dee02056a06b23aa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1b1a4d61f509eada4db23684ba6a0877.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1b1a4d61f509eada4db23684ba6a0877.bin new file mode 100644 index 0000000..e1f8071 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1b1a4d61f509eada4db23684ba6a0877.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1ba9ae11c35f8ea4fc55102df6b53cdf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1ba9ae11c35f8ea4fc55102df6b53cdf.bin new file mode 100644 index 0000000..0e55294 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1ba9ae11c35f8ea4fc55102df6b53cdf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c037f2aabd50fd599255d66e13c6c48.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c037f2aabd50fd599255d66e13c6c48.bin new file mode 100644 index 0000000..45b5e9b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c037f2aabd50fd599255d66e13c6c48.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c614dd55621f201e6a6d17efb4c465c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c614dd55621f201e6a6d17efb4c465c.bin new file mode 100644 index 0000000..02a0443 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c614dd55621f201e6a6d17efb4c465c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c965b51e6dd3247232a463369a48b91.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c965b51e6dd3247232a463369a48b91.bin new file mode 100644 index 0000000..5fe6479 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1c965b51e6dd3247232a463369a48b91.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1d49d4c8ab24176300aa5ed995f4c018.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1d49d4c8ab24176300aa5ed995f4c018.bin new file mode 100644 index 0000000..59599fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1d49d4c8ab24176300aa5ed995f4c018.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1db4042230cb68e26ab7b8a054bac733.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1db4042230cb68e26ab7b8a054bac733.bin new file mode 100644 index 0000000..a3d6642 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1db4042230cb68e26ab7b8a054bac733.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e1d53420a8b8190d8b25a2eaa571a9e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e1d53420a8b8190d8b25a2eaa571a9e.bin new file mode 100644 index 0000000..26952b2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e1d53420a8b8190d8b25a2eaa571a9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e54818667a6a78e7763a3dd463b1bf9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e54818667a6a78e7763a3dd463b1bf9.bin new file mode 100644 index 0000000..34884ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e54818667a6a78e7763a3dd463b1bf9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e90465dac10a41f5c6a1ab8292b4f79.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e90465dac10a41f5c6a1ab8292b4f79.bin new file mode 100644 index 0000000..f32a098 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1e90465dac10a41f5c6a1ab8292b4f79.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1eb1c0086d20162452286af85f8128ef.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1eb1c0086d20162452286af85f8128ef.bin new file mode 100644 index 0000000..2a107ca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1eb1c0086d20162452286af85f8128ef.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f3444a0cdedbed20dabe7732468927a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f3444a0cdedbed20dabe7732468927a.bin new file mode 100644 index 0000000..f7ca48c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f3444a0cdedbed20dabe7732468927a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f7ce07907f20a0b64477f42e85984dd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f7ce07907f20a0b64477f42e85984dd.bin new file mode 100644 index 0000000..81db53f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-1f7ce07907f20a0b64477f42e85984dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-200532804d253a4778f85c36c8a66e4e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-200532804d253a4778f85c36c8a66e4e.bin new file mode 100644 index 0000000..a0fcc2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-200532804d253a4778f85c36c8a66e4e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-203c325ed90a74910779f1726c0da678.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-203c325ed90a74910779f1726c0da678.bin new file mode 100644 index 0000000..546b48a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-203c325ed90a74910779f1726c0da678.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206bfb6d472b63da2890e9b2cb88981c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206bfb6d472b63da2890e9b2cb88981c.bin new file mode 100644 index 0000000..1cd6eb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206bfb6d472b63da2890e9b2cb88981c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206ea3e0a71a7804918913e647b546f3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206ea3e0a71a7804918913e647b546f3.bin new file mode 100644 index 0000000..edaf6ee Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-206ea3e0a71a7804918913e647b546f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21218d21fdcf58a369dbb5d686222a8b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21218d21fdcf58a369dbb5d686222a8b.bin new file mode 100644 index 0000000..2faccf1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21218d21fdcf58a369dbb5d686222a8b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21429a62f53403ecca192aece6a56657.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21429a62f53403ecca192aece6a56657.bin new file mode 100644 index 0000000..d7ee720 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21429a62f53403ecca192aece6a56657.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2181b013dd1dbad1a3ae2ee184fd0d01.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2181b013dd1dbad1a3ae2ee184fd0d01.bin new file mode 100644 index 0000000..efa674f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2181b013dd1dbad1a3ae2ee184fd0d01.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21aaa6cf21f82c512e7c22a3afdcadd8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21aaa6cf21f82c512e7c22a3afdcadd8.bin new file mode 100644 index 0000000..4aa4f97 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-21aaa6cf21f82c512e7c22a3afdcadd8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-22640926cf6f33df9987fb51c09f1547.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-22640926cf6f33df9987fb51c09f1547.bin new file mode 100644 index 0000000..300179a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-22640926cf6f33df9987fb51c09f1547.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2268bfa123804918feb5963a175d5a3b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2268bfa123804918feb5963a175d5a3b.bin new file mode 100644 index 0000000..0cc3ecf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2268bfa123804918feb5963a175d5a3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-228a7aa7f6ec2402e45e9493c6800539.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-228a7aa7f6ec2402e45e9493c6800539.bin new file mode 100644 index 0000000..8999931 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-228a7aa7f6ec2402e45e9493c6800539.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-238cd56a8c1f494a2b17b7503ed7c7be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-238cd56a8c1f494a2b17b7503ed7c7be.bin new file mode 100644 index 0000000..62999d7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-238cd56a8c1f494a2b17b7503ed7c7be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2437e600615d87e97106e7d6567625ef.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2437e600615d87e97106e7d6567625ef.bin new file mode 100644 index 0000000..c072665 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2437e600615d87e97106e7d6567625ef.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-245d899ee659322593415c686e557047.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-245d899ee659322593415c686e557047.bin new file mode 100644 index 0000000..7302ae9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-245d899ee659322593415c686e557047.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-25ee9b2d43a3194d8e3eac250c9d7140.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-25ee9b2d43a3194d8e3eac250c9d7140.bin new file mode 100644 index 0000000..c5821b6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-25ee9b2d43a3194d8e3eac250c9d7140.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-263987e392dc9f5713b29bfe17a53e80.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-263987e392dc9f5713b29bfe17a53e80.bin new file mode 100644 index 0000000..71cd2b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-263987e392dc9f5713b29bfe17a53e80.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-269ea1ee3905adec4aa7f162c6c9551e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-269ea1ee3905adec4aa7f162c6c9551e.bin new file mode 100644 index 0000000..4805c17 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-269ea1ee3905adec4aa7f162c6c9551e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26c17fb69df5f27c0246dae377a3719a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26c17fb69df5f27c0246dae377a3719a.bin new file mode 100644 index 0000000..cf2646d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26c17fb69df5f27c0246dae377a3719a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26f7fa791164a0094bd88371bc0a0303.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26f7fa791164a0094bd88371bc0a0303.bin new file mode 100644 index 0000000..a5435b9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-26f7fa791164a0094bd88371bc0a0303.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-274ab7fc670acc4833e0930f7db5def4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-274ab7fc670acc4833e0930f7db5def4.bin new file mode 100644 index 0000000..c858c67 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-274ab7fc670acc4833e0930f7db5def4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-275772c5ddf6f94fa462989748916d03.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-275772c5ddf6f94fa462989748916d03.bin new file mode 100644 index 0000000..93457ef Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-275772c5ddf6f94fa462989748916d03.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-276dafc467e53c831bf9f4f1bdb64d3d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-276dafc467e53c831bf9f4f1bdb64d3d.bin new file mode 100644 index 0000000..03b4ea3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-276dafc467e53c831bf9f4f1bdb64d3d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27a835379b4626b32212126ea0408fdb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27a835379b4626b32212126ea0408fdb.bin new file mode 100644 index 0000000..19badbe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27a835379b4626b32212126ea0408fdb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27afd93d2c528e225695b0a3606f332b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27afd93d2c528e225695b0a3606f332b.bin new file mode 100644 index 0000000..5dc6c52 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-27afd93d2c528e225695b0a3606f332b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-29013d5b24e57dbe5e50a416a9a29489.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-29013d5b24e57dbe5e50a416a9a29489.bin new file mode 100644 index 0000000..aa66939 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-29013d5b24e57dbe5e50a416a9a29489.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-291ef2ed631449b146ffdc1ffd4973f8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-291ef2ed631449b146ffdc1ffd4973f8.bin new file mode 100644 index 0000000..b458083 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-291ef2ed631449b146ffdc1ffd4973f8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-293a0069478b61031cd36430b7e44a58.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-293a0069478b61031cd36430b7e44a58.bin new file mode 100644 index 0000000..0485699 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-293a0069478b61031cd36430b7e44a58.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-297048bdb98203d5357ba2421af8f836.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-297048bdb98203d5357ba2421af8f836.bin new file mode 100644 index 0000000..40b21cc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-297048bdb98203d5357ba2421af8f836.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2a8acd291368e3129d126596fa744ba7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2a8acd291368e3129d126596fa744ba7.bin new file mode 100644 index 0000000..9ecefce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2a8acd291368e3129d126596fa744ba7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b36b5e1dbeed36ead7e8b55d03bd9a0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b36b5e1dbeed36ead7e8b55d03bd9a0.bin new file mode 100644 index 0000000..c7949b3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b36b5e1dbeed36ead7e8b55d03bd9a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b618aa1c2cc26e929de58977a9953d6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b618aa1c2cc26e929de58977a9953d6.bin new file mode 100644 index 0000000..a242a9d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b618aa1c2cc26e929de58977a9953d6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b7cbaca88dc96959bb7441967e5e28d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b7cbaca88dc96959bb7441967e5e28d.bin new file mode 100644 index 0000000..32c16c4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2b7cbaca88dc96959bb7441967e5e28d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2c8b2fbfaf3c53cf26b18d7b5ea595aa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2c8b2fbfaf3c53cf26b18d7b5ea595aa.bin new file mode 100644 index 0000000..93f0b7c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2c8b2fbfaf3c53cf26b18d7b5ea595aa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cbe16ba9d095731ee4e57feaf7641fb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cbe16ba9d095731ee4e57feaf7641fb.bin new file mode 100644 index 0000000..d637aa9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cbe16ba9d095731ee4e57feaf7641fb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cde7227c580177a5a0026dce207af1e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cde7227c580177a5a0026dce207af1e.bin new file mode 100644 index 0000000..3337ba3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cde7227c580177a5a0026dce207af1e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cfd3758a7898ffc47c6816233329e4b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cfd3758a7898ffc47c6816233329e4b.bin new file mode 100644 index 0000000..ea6a7a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2cfd3758a7898ffc47c6816233329e4b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d24f887427dbf9fd70f89d2c002983d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d24f887427dbf9fd70f89d2c002983d.bin new file mode 100644 index 0000000..cbcf67a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d24f887427dbf9fd70f89d2c002983d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d445ff3b4666ebf5c8323e26394e242.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d445ff3b4666ebf5c8323e26394e242.bin new file mode 100644 index 0000000..4405cd3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2d445ff3b4666ebf5c8323e26394e242.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2dac33b74fb9bf721372c244d6fa314f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2dac33b74fb9bf721372c244d6fa314f.bin new file mode 100644 index 0000000..8f609b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2dac33b74fb9bf721372c244d6fa314f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2de54d91d48650800a5a61ac947f7a88.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2de54d91d48650800a5a61ac947f7a88.bin new file mode 100644 index 0000000..b449b22 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2de54d91d48650800a5a61ac947f7a88.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2e83c08216a023083759baacb711a64d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2e83c08216a023083759baacb711a64d.bin new file mode 100644 index 0000000..bababab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2e83c08216a023083759baacb711a64d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ea6de27f9d74d4494a68cf72a34e611.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ea6de27f9d74d4494a68cf72a34e611.bin new file mode 100644 index 0000000..07961b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ea6de27f9d74d4494a68cf72a34e611.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fba1a4b709d5979b323476102bdbce6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fba1a4b709d5979b323476102bdbce6.bin new file mode 100644 index 0000000..b7ab881 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fba1a4b709d5979b323476102bdbce6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fbdbf31ada92f0fae672aa043d8d678.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fbdbf31ada92f0fae672aa043d8d678.bin new file mode 100644 index 0000000..f931d7a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fbdbf31ada92f0fae672aa043d8d678.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fe1dba4c09b098562de70afe8b2e460.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fe1dba4c09b098562de70afe8b2e460.bin new file mode 100644 index 0000000..56fcc60 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2fe1dba4c09b098562de70afe8b2e460.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ff1fbfbbf49fe1c99b27d25d75689c7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ff1fbfbbf49fe1c99b27d25d75689c7.bin new file mode 100644 index 0000000..6204d8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-2ff1fbfbbf49fe1c99b27d25d75689c7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3007dfb707793a442c702a39db8b887d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3007dfb707793a442c702a39db8b887d.bin new file mode 100644 index 0000000..857ea94 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3007dfb707793a442c702a39db8b887d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30a917f9955b6fbb629e869f4682a995.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30a917f9955b6fbb629e869f4682a995.bin new file mode 100644 index 0000000..c925873 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30a917f9955b6fbb629e869f4682a995.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30d02bda43e884c05b7a427cd20db31d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30d02bda43e884c05b7a427cd20db31d.bin new file mode 100644 index 0000000..7b182ed Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-30d02bda43e884c05b7a427cd20db31d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32d40ebe4fc6e08af263a36752e57bbf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32d40ebe4fc6e08af263a36752e57bbf.bin new file mode 100644 index 0000000..509a476 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32d40ebe4fc6e08af263a36752e57bbf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32e18008db9a74d6798d4f5346c7548a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32e18008db9a74d6798d4f5346c7548a.bin new file mode 100644 index 0000000..d2a273c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32e18008db9a74d6798d4f5346c7548a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32f42fe9516c2c867d8af76a8da21730.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32f42fe9516c2c867d8af76a8da21730.bin new file mode 100644 index 0000000..58c7c3d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-32f42fe9516c2c867d8af76a8da21730.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-332ba85efd3b2450d2431c185bbdc73d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-332ba85efd3b2450d2431c185bbdc73d.bin new file mode 100644 index 0000000..591a334 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-332ba85efd3b2450d2431c185bbdc73d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-33464ba5657463c25bcca634a9acb977.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-33464ba5657463c25bcca634a9acb977.bin new file mode 100644 index 0000000..781252e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-33464ba5657463c25bcca634a9acb977.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-34ead38833cfd7c3a74f765ae4af83c6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-34ead38833cfd7c3a74f765ae4af83c6.bin new file mode 100644 index 0000000..cc28538 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-34ead38833cfd7c3a74f765ae4af83c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-350c68e6e084ea09ec087e3b6759214a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-350c68e6e084ea09ec087e3b6759214a.bin new file mode 100644 index 0000000..1942ad3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-350c68e6e084ea09ec087e3b6759214a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3697c894fe2623b3810dd7e5b93d6f9d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3697c894fe2623b3810dd7e5b93d6f9d.bin new file mode 100644 index 0000000..d82fe08 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3697c894fe2623b3810dd7e5b93d6f9d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-36cf6b7ebe247e35b862be829fd2c5b4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-36cf6b7ebe247e35b862be829fd2c5b4.bin new file mode 100644 index 0000000..3e6b89a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-36cf6b7ebe247e35b862be829fd2c5b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3751d5099382542818ae7f207150a9cc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3751d5099382542818ae7f207150a9cc.bin new file mode 100644 index 0000000..1111380 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3751d5099382542818ae7f207150a9cc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3766da2ec104572bc6ff1fdb27bd18b8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3766da2ec104572bc6ff1fdb27bd18b8.bin new file mode 100644 index 0000000..27bb0d3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3766da2ec104572bc6ff1fdb27bd18b8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3778c7ae696a8d43a46fc2ff069c91c0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3778c7ae696a8d43a46fc2ff069c91c0.bin new file mode 100644 index 0000000..43dbe2a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3778c7ae696a8d43a46fc2ff069c91c0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3780170bb7d06e3ab0e4a8049b40c054.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3780170bb7d06e3ab0e4a8049b40c054.bin new file mode 100644 index 0000000..f94fba9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3780170bb7d06e3ab0e4a8049b40c054.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3800011a48ee551d0c62ad8e499cd2d0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3800011a48ee551d0c62ad8e499cd2d0.bin new file mode 100644 index 0000000..bf08f3a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3800011a48ee551d0c62ad8e499cd2d0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-382dab686ee81d6fc158588f307be1d8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-382dab686ee81d6fc158588f307be1d8.bin new file mode 100644 index 0000000..636b947 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-382dab686ee81d6fc158588f307be1d8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-383f83e24f7e45ce4c092c3acdaaf3f1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-383f83e24f7e45ce4c092c3acdaaf3f1.bin new file mode 100644 index 0000000..adc2e27 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-383f83e24f7e45ce4c092c3acdaaf3f1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-388cf4237e736121a5572d3aa9e5c4cd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-388cf4237e736121a5572d3aa9e5c4cd.bin new file mode 100644 index 0000000..3e8f270 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-388cf4237e736121a5572d3aa9e5c4cd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38a9b2050fb1e81e9849669e21cbde71.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38a9b2050fb1e81e9849669e21cbde71.bin new file mode 100644 index 0000000..ea737ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38a9b2050fb1e81e9849669e21cbde71.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38b21589e7a4a606f77e1b83195d3104.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38b21589e7a4a606f77e1b83195d3104.bin new file mode 100644 index 0000000..f28cbf6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-38b21589e7a4a606f77e1b83195d3104.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-392b54961ab2c9b11171fbc1239c76c0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-392b54961ab2c9b11171fbc1239c76c0.bin new file mode 100644 index 0000000..13a2a40 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-392b54961ab2c9b11171fbc1239c76c0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-399063409d6abc1f52fd5bd1a8a5dcc0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-399063409d6abc1f52fd5bd1a8a5dcc0.bin new file mode 100644 index 0000000..74d3cde Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-399063409d6abc1f52fd5bd1a8a5dcc0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39b5437fa4a29d5ba1b5eab8e84a63df.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39b5437fa4a29d5ba1b5eab8e84a63df.bin new file mode 100644 index 0000000..7fba317 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39b5437fa4a29d5ba1b5eab8e84a63df.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39c24ff685682c602b099cd257e5208a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39c24ff685682c602b099cd257e5208a.bin new file mode 100644 index 0000000..262f0e8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-39c24ff685682c602b099cd257e5208a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3a692b3905dcb6c7aaef898ab86e684f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3a692b3905dcb6c7aaef898ab86e684f.bin new file mode 100644 index 0000000..f338c53 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3a692b3905dcb6c7aaef898ab86e684f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b39141d151a1bcbf919de02082f10c1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b39141d151a1bcbf919de02082f10c1.bin new file mode 100644 index 0000000..4d4516f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b39141d151a1bcbf919de02082f10c1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b3bc720bd6fb9e57d757d43162b4645.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b3bc720bd6fb9e57d757d43162b4645.bin new file mode 100644 index 0000000..a077ac2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b3bc720bd6fb9e57d757d43162b4645.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b82d485330cbb61ae8b04779f3657da.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b82d485330cbb61ae8b04779f3657da.bin new file mode 100644 index 0000000..758094f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b82d485330cbb61ae8b04779f3657da.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b9d0e79fe4e712f144f8e19cee99772.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b9d0e79fe4e712f144f8e19cee99772.bin new file mode 100644 index 0000000..fbfefdc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3b9d0e79fe4e712f144f8e19cee99772.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3bb166dd7fe48c5b95b21924160a964d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3bb166dd7fe48c5b95b21924160a964d.bin new file mode 100644 index 0000000..a23c232 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3bb166dd7fe48c5b95b21924160a964d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c166f64a13ad7a646d1ece3a194cd07.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c166f64a13ad7a646d1ece3a194cd07.bin new file mode 100644 index 0000000..0a2d476 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c166f64a13ad7a646d1ece3a194cd07.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c2ac273bd3cd24f76972ae1488c93b4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c2ac273bd3cd24f76972ae1488c93b4.bin new file mode 100644 index 0000000..cdb4224 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c2ac273bd3cd24f76972ae1488c93b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c67d0c7c118b65a5ef921a927419c3d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c67d0c7c118b65a5ef921a927419c3d.bin new file mode 100644 index 0000000..0249e9e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3c67d0c7c118b65a5ef921a927419c3d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3d2814c4ff9d07462fe5f73c21d6f8c1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3d2814c4ff9d07462fe5f73c21d6f8c1.bin new file mode 100644 index 0000000..0b6bebe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3d2814c4ff9d07462fe5f73c21d6f8c1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3dfa3cbafb4013082b7ea41560961db3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3dfa3cbafb4013082b7ea41560961db3.bin new file mode 100644 index 0000000..6037016 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3dfa3cbafb4013082b7ea41560961db3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3e714a3cd05daa3588b3f659f50261a3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3e714a3cd05daa3588b3f659f50261a3.bin new file mode 100644 index 0000000..43f3cfe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3e714a3cd05daa3588b3f659f50261a3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fd9f497552f2e2cf73d2109461fc8c6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fd9f497552f2e2cf73d2109461fc8c6.bin new file mode 100644 index 0000000..fb84aea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fd9f497552f2e2cf73d2109461fc8c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fe63b40921ed425bb43eae9cec8da17.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fe63b40921ed425bb43eae9cec8da17.bin new file mode 100644 index 0000000..90e2b57 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-3fe63b40921ed425bb43eae9cec8da17.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-407dfd01e96fd3742b5e557e66589073.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-407dfd01e96fd3742b5e557e66589073.bin new file mode 100644 index 0000000..d0b527d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-407dfd01e96fd3742b5e557e66589073.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4088c180485d1dab7c1ef139df99b53d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4088c180485d1dab7c1ef139df99b53d.bin new file mode 100644 index 0000000..89a5d7f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4088c180485d1dab7c1ef139df99b53d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40b50442621d164ef270e256e3f035f6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40b50442621d164ef270e256e3f035f6.bin new file mode 100644 index 0000000..de62d68 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40b50442621d164ef270e256e3f035f6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40f36226eac856aae5c4a2d5c43c573e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40f36226eac856aae5c4a2d5c43c573e.bin new file mode 100644 index 0000000..0659a6f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-40f36226eac856aae5c4a2d5c43c573e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41d983755a42ea78b63c94fed6d88050.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41d983755a42ea78b63c94fed6d88050.bin new file mode 100644 index 0000000..d24e93d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41d983755a42ea78b63c94fed6d88050.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41f0fdaad19d26381dfaf6c389f1b873.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41f0fdaad19d26381dfaf6c389f1b873.bin new file mode 100644 index 0000000..43e0dda Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-41f0fdaad19d26381dfaf6c389f1b873.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-427da8b9c8adf0bde6fd5373f49dc913.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-427da8b9c8adf0bde6fd5373f49dc913.bin new file mode 100644 index 0000000..a9ff601 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-427da8b9c8adf0bde6fd5373f49dc913.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4318686cac3f5abab1d1f504e5916ebe.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4318686cac3f5abab1d1f504e5916ebe.bin new file mode 100644 index 0000000..cf95496 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4318686cac3f5abab1d1f504e5916ebe.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4375abdc6cb6050f4dcb02a0463e862a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4375abdc6cb6050f4dcb02a0463e862a.bin new file mode 100644 index 0000000..93aaef5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4375abdc6cb6050f4dcb02a0463e862a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4396ec93d68e9b1323ad6f3f85cae72a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4396ec93d68e9b1323ad6f3f85cae72a.bin new file mode 100644 index 0000000..0942736 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4396ec93d68e9b1323ad6f3f85cae72a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4413e1284bc8a640c4dfa7ccc4466dc9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4413e1284bc8a640c4dfa7ccc4466dc9.bin new file mode 100644 index 0000000..e0462d8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4413e1284bc8a640c4dfa7ccc4466dc9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4537aa8ff64e4be967f4d62716a9724b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4537aa8ff64e4be967f4d62716a9724b.bin new file mode 100644 index 0000000..d74693e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4537aa8ff64e4be967f4d62716a9724b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-45a7cbf51f342631c4eb3ac9963b4884.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-45a7cbf51f342631c4eb3ac9963b4884.bin new file mode 100644 index 0000000..bffbad2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-45a7cbf51f342631c4eb3ac9963b4884.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4607d4c0d2a8294494aea5bc5a5dd13d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4607d4c0d2a8294494aea5bc5a5dd13d.bin new file mode 100644 index 0000000..e1c7be8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4607d4c0d2a8294494aea5bc5a5dd13d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-464ca17f6bbf2134e76cc4b55160b872.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-464ca17f6bbf2134e76cc4b55160b872.bin new file mode 100644 index 0000000..58d6154 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-464ca17f6bbf2134e76cc4b55160b872.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-472a0478ca7da4d31cde168558d283a0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-472a0478ca7da4d31cde168558d283a0.bin new file mode 100644 index 0000000..ec5f6f0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-472a0478ca7da4d31cde168558d283a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4741d32d59666f212ed97fbb1b881514.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4741d32d59666f212ed97fbb1b881514.bin new file mode 100644 index 0000000..47da5ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4741d32d59666f212ed97fbb1b881514.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4809a9cc9eceafe979ff2f0b61a215a6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4809a9cc9eceafe979ff2f0b61a215a6.bin new file mode 100644 index 0000000..1b7f408 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4809a9cc9eceafe979ff2f0b61a215a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4818a07801a166ebf800fc8f5da0cbe1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4818a07801a166ebf800fc8f5da0cbe1.bin new file mode 100644 index 0000000..91d5805 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4818a07801a166ebf800fc8f5da0cbe1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-483f2a5d3766e796b0962c245bfe49d4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-483f2a5d3766e796b0962c245bfe49d4.bin new file mode 100644 index 0000000..b0814bb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-483f2a5d3766e796b0962c245bfe49d4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4929ed1c81f1ceb8bc347f470a87911b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4929ed1c81f1ceb8bc347f470a87911b.bin new file mode 100644 index 0000000..f2dbfa6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4929ed1c81f1ceb8bc347f470a87911b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4a2db81f5693ffc951d2555f99f388b6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4a2db81f5693ffc951d2555f99f388b6.bin new file mode 100644 index 0000000..3f2632e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4a2db81f5693ffc951d2555f99f388b6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ab0e740130d4b161649e47c816d7a5f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ab0e740130d4b161649e47c816d7a5f.bin new file mode 100644 index 0000000..70659ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ab0e740130d4b161649e47c816d7a5f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b814f91e024d756e4ecfd23ca1a9fbc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b814f91e024d756e4ecfd23ca1a9fbc.bin new file mode 100644 index 0000000..bc9e9b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b814f91e024d756e4ecfd23ca1a9fbc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b96d404d7f351afb610fe8a092290cd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b96d404d7f351afb610fe8a092290cd.bin new file mode 100644 index 0000000..9721545 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4b96d404d7f351afb610fe8a092290cd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4d131bc544398cfb1f6eba38ec34b261.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4d131bc544398cfb1f6eba38ec34b261.bin new file mode 100644 index 0000000..b832dc2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4d131bc544398cfb1f6eba38ec34b261.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e57a46822b24fd94630aa214065a943.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e57a46822b24fd94630aa214065a943.bin new file mode 100644 index 0000000..db14756 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e57a46822b24fd94630aa214065a943.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e80d6aecfb6c855e29456ab0fb5348d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e80d6aecfb6c855e29456ab0fb5348d.bin new file mode 100644 index 0000000..1202218 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e80d6aecfb6c855e29456ab0fb5348d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e98c054b09474a48f977ff257326faa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e98c054b09474a48f977ff257326faa.bin new file mode 100644 index 0000000..94be138 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4e98c054b09474a48f977ff257326faa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ea3345c91ec5b8550b10e8414954b7f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ea3345c91ec5b8550b10e8414954b7f.bin new file mode 100644 index 0000000..e5fc906 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4ea3345c91ec5b8550b10e8414954b7f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eaec9067d25e993794bbdea04e51c83.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eaec9067d25e993794bbdea04e51c83.bin new file mode 100644 index 0000000..08bf971 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eaec9067d25e993794bbdea04e51c83.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eef6bdb5dcf4faaf9a7fb76a22daece.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eef6bdb5dcf4faaf9a7fb76a22daece.bin new file mode 100644 index 0000000..490fdfb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-4eef6bdb5dcf4faaf9a7fb76a22daece.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5234a5c75a18f44bcf04e1e999e9dea0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5234a5c75a18f44bcf04e1e999e9dea0.bin new file mode 100644 index 0000000..2954fb6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5234a5c75a18f44bcf04e1e999e9dea0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-543dcaf08f61c548b453cc268b1bf147.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-543dcaf08f61c548b453cc268b1bf147.bin new file mode 100644 index 0000000..ff81917 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-543dcaf08f61c548b453cc268b1bf147.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-55f9e259b240384dde81430f6999dd2a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-55f9e259b240384dde81430f6999dd2a.bin new file mode 100644 index 0000000..e1d774f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-55f9e259b240384dde81430f6999dd2a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5606777bb08be81392543c31b45bcaa2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5606777bb08be81392543c31b45bcaa2.bin new file mode 100644 index 0000000..9431a7e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5606777bb08be81392543c31b45bcaa2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56559d29b91c3a1105da88d884df7213.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56559d29b91c3a1105da88d884df7213.bin new file mode 100644 index 0000000..e7d773e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56559d29b91c3a1105da88d884df7213.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56e23df83fe615c67d3d61a85f1302bf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56e23df83fe615c67d3d61a85f1302bf.bin new file mode 100644 index 0000000..00eff97 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56e23df83fe615c67d3d61a85f1302bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56ebc0ba1dcca936e98ac60f2da45c24.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56ebc0ba1dcca936e98ac60f2da45c24.bin new file mode 100644 index 0000000..8d22c6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-56ebc0ba1dcca936e98ac60f2da45c24.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-57398c75abe168376e8e84cef3fcd844.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-57398c75abe168376e8e84cef3fcd844.bin new file mode 100644 index 0000000..2a6c6d9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-57398c75abe168376e8e84cef3fcd844.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58d029d204eefcd342a96817cf34069d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58d029d204eefcd342a96817cf34069d.bin new file mode 100644 index 0000000..8a0aba6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58d029d204eefcd342a96817cf34069d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58e781bb5f26cab6179ffe083072bc9c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58e781bb5f26cab6179ffe083072bc9c.bin new file mode 100644 index 0000000..ed868fe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-58e781bb5f26cab6179ffe083072bc9c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-597d393130db9261e074a128cda4b13f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-597d393130db9261e074a128cda4b13f.bin new file mode 100644 index 0000000..dedc7e5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-597d393130db9261e074a128cda4b13f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a1ec6be031eccc27929581ad398cdc2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a1ec6be031eccc27929581ad398cdc2.bin new file mode 100644 index 0000000..0903f5b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a1ec6be031eccc27929581ad398cdc2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a4ffa37cf41aebe19c93aff3ce2dcf3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a4ffa37cf41aebe19c93aff3ce2dcf3.bin new file mode 100644 index 0000000..efbb8a2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a4ffa37cf41aebe19c93aff3ce2dcf3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a94fe875f95cc35af970818d7c7f446.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a94fe875f95cc35af970818d7c7f446.bin new file mode 100644 index 0000000..de91b73 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a94fe875f95cc35af970818d7c7f446.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a9e921d8e5bc31d40a3c7acef921306.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a9e921d8e5bc31d40a3c7acef921306.bin new file mode 100644 index 0000000..705b78f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5a9e921d8e5bc31d40a3c7acef921306.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5aed4c693797476c7bcf1f5b9a87f3ff.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5aed4c693797476c7bcf1f5b9a87f3ff.bin new file mode 100644 index 0000000..5637c0f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5aed4c693797476c7bcf1f5b9a87f3ff.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b1068f0d72a699d567bd4584637f6c8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b1068f0d72a699d567bd4584637f6c8.bin new file mode 100644 index 0000000..057057b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b1068f0d72a699d567bd4584637f6c8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b86c24b7feee4e52d7c20effb38b29c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b86c24b7feee4e52d7c20effb38b29c.bin new file mode 100644 index 0000000..5085ba3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b86c24b7feee4e52d7c20effb38b29c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b9fd9f007cefb91dccba17c6e754ebd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b9fd9f007cefb91dccba17c6e754ebd.bin new file mode 100644 index 0000000..9994679 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5b9fd9f007cefb91dccba17c6e754ebd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5bb0fb72bb90c76ea116fb06f388a6b4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5bb0fb72bb90c76ea116fb06f388a6b4.bin new file mode 100644 index 0000000..03f88d2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5bb0fb72bb90c76ea116fb06f388a6b4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5c49410409ff8813c4b8257027ded5df.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5c49410409ff8813c4b8257027ded5df.bin new file mode 100644 index 0000000..554d264 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5c49410409ff8813c4b8257027ded5df.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5d652ebd03dac848dec822c2a9dc5072.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5d652ebd03dac848dec822c2a9dc5072.bin new file mode 100644 index 0000000..71997e8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5d652ebd03dac848dec822c2a9dc5072.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5dbc4857c1e948f5568c83613f2a6fa4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5dbc4857c1e948f5568c83613f2a6fa4.bin new file mode 100644 index 0000000..5425ebf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5dbc4857c1e948f5568c83613f2a6fa4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5eb283759758684226bdc160395f9c51.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5eb283759758684226bdc160395f9c51.bin new file mode 100644 index 0000000..93e564b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5eb283759758684226bdc160395f9c51.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5f485dc8a956beb9839fb4b0f1a7a3e8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5f485dc8a956beb9839fb4b0f1a7a3e8.bin new file mode 100644 index 0000000..8de2db3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-5f485dc8a956beb9839fb4b0f1a7a3e8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-604558714e115177ed1f00f333cb55ce.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-604558714e115177ed1f00f333cb55ce.bin new file mode 100644 index 0000000..035418d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-604558714e115177ed1f00f333cb55ce.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-60cf5ea5b6d25b8daa1ede4e06f3165e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-60cf5ea5b6d25b8daa1ede4e06f3165e.bin new file mode 100644 index 0000000..16d8062 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-60cf5ea5b6d25b8daa1ede4e06f3165e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-612ad7a549f2735aff56a2d11d4228bd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-612ad7a549f2735aff56a2d11d4228bd.bin new file mode 100644 index 0000000..e267ade Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-612ad7a549f2735aff56a2d11d4228bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6177bbd559eaad55749562d5deb82e85.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6177bbd559eaad55749562d5deb82e85.bin new file mode 100644 index 0000000..d86971f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6177bbd559eaad55749562d5deb82e85.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-618c8dc41417381d4c9bb6d0d8005a12.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-618c8dc41417381d4c9bb6d0d8005a12.bin new file mode 100644 index 0000000..756757f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-618c8dc41417381d4c9bb6d0d8005a12.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61caffc7b3b4aa3016bb9add3a493e73.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61caffc7b3b4aa3016bb9add3a493e73.bin new file mode 100644 index 0000000..e52218a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61caffc7b3b4aa3016bb9add3a493e73.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61f0ce281449c9b2bcbbd575b118595b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61f0ce281449c9b2bcbbd575b118595b.bin new file mode 100644 index 0000000..fffb174 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61f0ce281449c9b2bcbbd575b118595b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61ff56bcf491b19504096a11b16fda75.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61ff56bcf491b19504096a11b16fda75.bin new file mode 100644 index 0000000..ebd8c2d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-61ff56bcf491b19504096a11b16fda75.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d46518c9f3feef1e29cf461f49ccdc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d46518c9f3feef1e29cf461f49ccdc.bin new file mode 100644 index 0000000..77ea645 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d46518c9f3feef1e29cf461f49ccdc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d54b51f1b384a42e3d933d53583093.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d54b51f1b384a42e3d933d53583093.bin new file mode 100644 index 0000000..a3bf32f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62d54b51f1b384a42e3d933d53583093.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62ef81bb6ffd2fb9c2e277b8752a22e1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62ef81bb6ffd2fb9c2e277b8752a22e1.bin new file mode 100644 index 0000000..2547fa0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-62ef81bb6ffd2fb9c2e277b8752a22e1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-642dcc38d80b429506d81fc9cb2c2bb4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-642dcc38d80b429506d81fc9cb2c2bb4.bin new file mode 100644 index 0000000..94dc0dd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-642dcc38d80b429506d81fc9cb2c2bb4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64d27d946798cccb08ce44d3f1d20413.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64d27d946798cccb08ce44d3f1d20413.bin new file mode 100644 index 0000000..69368e3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64d27d946798cccb08ce44d3f1d20413.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64f79be0363a27fa8682a1d0685e152c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64f79be0363a27fa8682a1d0685e152c.bin new file mode 100644 index 0000000..1f35a4a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-64f79be0363a27fa8682a1d0685e152c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6635320298b2aba751def888e72aeb49.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6635320298b2aba751def888e72aeb49.bin new file mode 100644 index 0000000..afb68af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6635320298b2aba751def888e72aeb49.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-66da163ab01227cbc75feeb3603b8847.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-66da163ab01227cbc75feeb3603b8847.bin new file mode 100644 index 0000000..4f50932 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-66da163ab01227cbc75feeb3603b8847.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-673085975406fdcbe882a628ff449b3c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-673085975406fdcbe882a628ff449b3c.bin new file mode 100644 index 0000000..e74ffbf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-673085975406fdcbe882a628ff449b3c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a4235d6121444ae1bb458ad8071b11.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a4235d6121444ae1bb458ad8071b11.bin new file mode 100644 index 0000000..d6dacf8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a4235d6121444ae1bb458ad8071b11.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a7db6009076fcd2145d43acb476ba8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a7db6009076fcd2145d43acb476ba8.bin new file mode 100644 index 0000000..1087e36 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67a7db6009076fcd2145d43acb476ba8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67f64c85d093f1f6809b2706aef33430.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67f64c85d093f1f6809b2706aef33430.bin new file mode 100644 index 0000000..3c58b77 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-67f64c85d093f1f6809b2706aef33430.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-681f21d881ccac700bada11dbc0d60c2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-681f21d881ccac700bada11dbc0d60c2.bin new file mode 100644 index 0000000..d56c10d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-681f21d881ccac700bada11dbc0d60c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68280ce562e57450a9638679c3570be2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68280ce562e57450a9638679c3570be2.bin new file mode 100644 index 0000000..d5aa459 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68280ce562e57450a9638679c3570be2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68306f6dca32218c8474b873ce402db5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68306f6dca32218c8474b873ce402db5.bin new file mode 100644 index 0000000..d66c448 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68306f6dca32218c8474b873ce402db5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6885181261e1780cb290fc65789c523f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6885181261e1780cb290fc65789c523f.bin new file mode 100644 index 0000000..0141bb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6885181261e1780cb290fc65789c523f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68905960b6e70f6bdb5f46f27c1b3d38.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68905960b6e70f6bdb5f46f27c1b3d38.bin new file mode 100644 index 0000000..0b685fa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68905960b6e70f6bdb5f46f27c1b3d38.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68d532f461dedd34f75f404dae6d9e48.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68d532f461dedd34f75f404dae6d9e48.bin new file mode 100644 index 0000000..9c03064 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68d532f461dedd34f75f404dae6d9e48.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68eda9ae7b61175f5645f2286caff4bd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68eda9ae7b61175f5645f2286caff4bd.bin new file mode 100644 index 0000000..8d9715d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68eda9ae7b61175f5645f2286caff4bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68fb8922a88ce98f55dd55f68b23a850.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68fb8922a88ce98f55dd55f68b23a850.bin new file mode 100644 index 0000000..962144d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-68fb8922a88ce98f55dd55f68b23a850.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a23517076daee590a938be4232eb643.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a23517076daee590a938be4232eb643.bin new file mode 100644 index 0000000..977f680 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a23517076daee590a938be4232eb643.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a579bd9c3fddde6ad78ee8f91504eb7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a579bd9c3fddde6ad78ee8f91504eb7.bin new file mode 100644 index 0000000..662024a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a579bd9c3fddde6ad78ee8f91504eb7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a9635fe0063f1c68e52434f46fc2b0d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a9635fe0063f1c68e52434f46fc2b0d.bin new file mode 100644 index 0000000..caf15f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6a9635fe0063f1c68e52434f46fc2b0d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ac01f86dac84b4d21def46663e4d2c5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ac01f86dac84b4d21def46663e4d2c5.bin new file mode 100644 index 0000000..b807522 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ac01f86dac84b4d21def46663e4d2c5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ad44238214c267830d974a0e6ff4bce.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ad44238214c267830d974a0e6ff4bce.bin new file mode 100644 index 0000000..7f48a43 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6ad44238214c267830d974a0e6ff4bce.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b27733144ec7aa3bca251644bf9ce0c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b27733144ec7aa3bca251644bf9ce0c.bin new file mode 100644 index 0000000..a522f41 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b27733144ec7aa3bca251644bf9ce0c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b33680d693f405d4de0936fbd5088bd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b33680d693f405d4de0936fbd5088bd.bin new file mode 100644 index 0000000..beef116 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6b33680d693f405d4de0936fbd5088bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6bddebfbf3f9c0c90f5b4469a1f7bd1d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6bddebfbf3f9c0c90f5b4469a1f7bd1d.bin new file mode 100644 index 0000000..d801bb8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6bddebfbf3f9c0c90f5b4469a1f7bd1d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6caac4dd0e225a523806fbcf6e4c9c5b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6caac4dd0e225a523806fbcf6e4c9c5b.bin new file mode 100644 index 0000000..7cb16af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6caac4dd0e225a523806fbcf6e4c9c5b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6d664a99c2508bdf0a18b6d2e648e8f3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6d664a99c2508bdf0a18b6d2e648e8f3.bin new file mode 100644 index 0000000..821849f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6d664a99c2508bdf0a18b6d2e648e8f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6eedf2a22a5c8a25a8dda6225a09e059.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6eedf2a22a5c8a25a8dda6225a09e059.bin new file mode 100644 index 0000000..977759d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6eedf2a22a5c8a25a8dda6225a09e059.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f13403fc1544dce85b64444e03c712b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f13403fc1544dce85b64444e03c712b.bin new file mode 100644 index 0000000..543358d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f13403fc1544dce85b64444e03c712b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f3b526e814a8fdbbe50b20679aca261.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f3b526e814a8fdbbe50b20679aca261.bin new file mode 100644 index 0000000..2572253 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6f3b526e814a8fdbbe50b20679aca261.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6fe73f9ae7a41800ebb27ab9119d4e39.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6fe73f9ae7a41800ebb27ab9119d4e39.bin new file mode 100644 index 0000000..0886772 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-6fe73f9ae7a41800ebb27ab9119d4e39.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-702f75e208614aeb8eb697349bfbdf8c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-702f75e208614aeb8eb697349bfbdf8c.bin new file mode 100644 index 0000000..c7c1140 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-702f75e208614aeb8eb697349bfbdf8c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-708e74f67332cd328f3445fde2486f30.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-708e74f67332cd328f3445fde2486f30.bin new file mode 100644 index 0000000..37e5a71 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-708e74f67332cd328f3445fde2486f30.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-70b7ce2f74b4be5e0748e923621db6f3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-70b7ce2f74b4be5e0748e923621db6f3.bin new file mode 100644 index 0000000..3606b41 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-70b7ce2f74b4be5e0748e923621db6f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7169b1fd0ab1c5619042e3af2e42c8e6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7169b1fd0ab1c5619042e3af2e42c8e6.bin new file mode 100644 index 0000000..1cf483c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7169b1fd0ab1c5619042e3af2e42c8e6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-720cacd7e8a15988da03d88ef8297084.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-720cacd7e8a15988da03d88ef8297084.bin new file mode 100644 index 0000000..d491a3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-720cacd7e8a15988da03d88ef8297084.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72c3f2f0455de1fa0cd6f985dcc81ba3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72c3f2f0455de1fa0cd6f985dcc81ba3.bin new file mode 100644 index 0000000..dced96b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72c3f2f0455de1fa0cd6f985dcc81ba3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72f5351e9012239a44758dd0db875b0b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72f5351e9012239a44758dd0db875b0b.bin new file mode 100644 index 0000000..a5d29d0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-72f5351e9012239a44758dd0db875b0b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7317307883533db52a580b5725f5ec57.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7317307883533db52a580b5725f5ec57.bin new file mode 100644 index 0000000..f9a516c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7317307883533db52a580b5725f5ec57.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74073fe5c3031bb67db0b058a0d2f781.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74073fe5c3031bb67db0b058a0d2f781.bin new file mode 100644 index 0000000..3a5bae4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74073fe5c3031bb67db0b058a0d2f781.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-740ebf9d55e94f1d07c6732aaa6ebd34.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-740ebf9d55e94f1d07c6732aaa6ebd34.bin new file mode 100644 index 0000000..ee04b19 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-740ebf9d55e94f1d07c6732aaa6ebd34.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74389572e76aa74fb088ff5a79249f4b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74389572e76aa74fb088ff5a79249f4b.bin new file mode 100644 index 0000000..a57777c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74389572e76aa74fb088ff5a79249f4b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-745407b09779d2a2d7df10360debca42.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-745407b09779d2a2d7df10360debca42.bin new file mode 100644 index 0000000..308cba0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-745407b09779d2a2d7df10360debca42.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74608f1219c98e8f46a8106cd5b7af0b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74608f1219c98e8f46a8106cd5b7af0b.bin new file mode 100644 index 0000000..3b71e2b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-74608f1219c98e8f46a8106cd5b7af0b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-749a27b11e97c9c2e34dd0764533c805.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-749a27b11e97c9c2e34dd0764533c805.bin new file mode 100644 index 0000000..394094e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-749a27b11e97c9c2e34dd0764533c805.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-753acfa79148da3d2d9ce20f2c5643fb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-753acfa79148da3d2d9ce20f2c5643fb.bin new file mode 100644 index 0000000..1d48f41 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-753acfa79148da3d2d9ce20f2c5643fb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7582d153b6b3a429ea7bab503736510e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7582d153b6b3a429ea7bab503736510e.bin new file mode 100644 index 0000000..7b91c9b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7582d153b6b3a429ea7bab503736510e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-75c525a44c610996e242ff58e18bf82e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-75c525a44c610996e242ff58e18bf82e.bin new file mode 100644 index 0000000..9b86d30 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-75c525a44c610996e242ff58e18bf82e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-76499262353da8fdcbb0a08da2188035.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-76499262353da8fdcbb0a08da2188035.bin new file mode 100644 index 0000000..6c95c29 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-76499262353da8fdcbb0a08da2188035.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-768cc2cd96c0413a1c4a87b106b71371.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-768cc2cd96c0413a1c4a87b106b71371.bin new file mode 100644 index 0000000..6179ff6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-768cc2cd96c0413a1c4a87b106b71371.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-770bd64714a708761398f710e1754d97.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-770bd64714a708761398f710e1754d97.bin new file mode 100644 index 0000000..8f5ca75 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-770bd64714a708761398f710e1754d97.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7784729d7499f62ffa1e2c412ae78c02.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7784729d7499f62ffa1e2c412ae78c02.bin new file mode 100644 index 0000000..cbd1531 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7784729d7499f62ffa1e2c412ae78c02.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-780bddee5abdd080fa4cdcb82573cbcf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-780bddee5abdd080fa4cdcb82573cbcf.bin new file mode 100644 index 0000000..f98baac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-780bddee5abdd080fa4cdcb82573cbcf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-78a26f926567ace122bc9856ff72b177.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-78a26f926567ace122bc9856ff72b177.bin new file mode 100644 index 0000000..79dcfe6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-78a26f926567ace122bc9856ff72b177.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2abc8e723cebc7685d30d4b3058ec6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2abc8e723cebc7685d30d4b3058ec6.bin new file mode 100644 index 0000000..50e7828 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2abc8e723cebc7685d30d4b3058ec6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2c30b10ce2538d1a834e8fdc848c20.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2c30b10ce2538d1a834e8fdc848c20.bin new file mode 100644 index 0000000..cbbf4ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a2c30b10ce2538d1a834e8fdc848c20.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a4c36821c0c983dd7412cd0a51f006d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a4c36821c0c983dd7412cd0a51f006d.bin new file mode 100644 index 0000000..793434a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7a4c36821c0c983dd7412cd0a51f006d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7aba5e8e8a778c194077f04053724582.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7aba5e8e8a778c194077f04053724582.bin new file mode 100644 index 0000000..9008b13 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7aba5e8e8a778c194077f04053724582.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7b25db0d831f8ed08daef2e0336e1ee7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7b25db0d831f8ed08daef2e0336e1ee7.bin new file mode 100644 index 0000000..3f90b38 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7b25db0d831f8ed08daef2e0336e1ee7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7beb79d7dec65638d1db9f035edf44f5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7beb79d7dec65638d1db9f035edf44f5.bin new file mode 100644 index 0000000..914b0da Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7beb79d7dec65638d1db9f035edf44f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7cc9a594804dfc89ca8037c6dea2f75e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7cc9a594804dfc89ca8037c6dea2f75e.bin new file mode 100644 index 0000000..f699bcb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7cc9a594804dfc89ca8037c6dea2f75e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7dbe35fc1ae438021e531c38366a715c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7dbe35fc1ae438021e531c38366a715c.bin new file mode 100644 index 0000000..ef26b41 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7dbe35fc1ae438021e531c38366a715c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7e488398e93c8ecff8d764e852e0780e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7e488398e93c8ecff8d764e852e0780e.bin new file mode 100644 index 0000000..ff61ba3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7e488398e93c8ecff8d764e852e0780e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7f79c7723a2c5188199e781f1729b331.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7f79c7723a2c5188199e781f1729b331.bin new file mode 100644 index 0000000..61813a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7f79c7723a2c5188199e781f1729b331.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7ff614c898534bd3b7cb784f9e1530e3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7ff614c898534bd3b7cb784f9e1530e3.bin new file mode 100644 index 0000000..1dcef45 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-7ff614c898534bd3b7cb784f9e1530e3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-803a6af086f8687ad1cde9b2d00ff661.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-803a6af086f8687ad1cde9b2d00ff661.bin new file mode 100644 index 0000000..7598fcd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-803a6af086f8687ad1cde9b2d00ff661.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80eb1fc43a988696050047293d1568b3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80eb1fc43a988696050047293d1568b3.bin new file mode 100644 index 0000000..6dfb756 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80eb1fc43a988696050047293d1568b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80ef2c193a050781867a9fd0ba4ffcae.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80ef2c193a050781867a9fd0ba4ffcae.bin new file mode 100644 index 0000000..7c01e79 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-80ef2c193a050781867a9fd0ba4ffcae.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81a563e650794cdfc11574168bf028cd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81a563e650794cdfc11574168bf028cd.bin new file mode 100644 index 0000000..a245633 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81a563e650794cdfc11574168bf028cd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81c23a444867fe82030c558027d769c6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81c23a444867fe82030c558027d769c6.bin new file mode 100644 index 0000000..de123cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81c23a444867fe82030c558027d769c6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81e0f618e5c1a44a940cabafa1f3fba4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81e0f618e5c1a44a940cabafa1f3fba4.bin new file mode 100644 index 0000000..dc14032 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81e0f618e5c1a44a940cabafa1f3fba4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81fc7962572eebcd39aea31f85bad4ad.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81fc7962572eebcd39aea31f85bad4ad.bin new file mode 100644 index 0000000..395805b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-81fc7962572eebcd39aea31f85bad4ad.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82251d48b35a79cd486a3f6b3180ef6f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82251d48b35a79cd486a3f6b3180ef6f.bin new file mode 100644 index 0000000..33848bf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82251d48b35a79cd486a3f6b3180ef6f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8257cf0031177b5827ad0e2b7bdab6fa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8257cf0031177b5827ad0e2b7bdab6fa.bin new file mode 100644 index 0000000..98e6280 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8257cf0031177b5827ad0e2b7bdab6fa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8293d8848372507746d3fff0563aa2f5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8293d8848372507746d3fff0563aa2f5.bin new file mode 100644 index 0000000..8530abe Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8293d8848372507746d3fff0563aa2f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82d043f232f66cda61c5364d233ea640.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82d043f232f66cda61c5364d233ea640.bin new file mode 100644 index 0000000..c18e07c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-82d043f232f66cda61c5364d233ea640.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83078e64372baa22eab61a81f4e918a9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83078e64372baa22eab61a81f4e918a9.bin new file mode 100644 index 0000000..a3f5de8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83078e64372baa22eab61a81f4e918a9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8348d6e19aa6bc6faa90e83143dd14a6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8348d6e19aa6bc6faa90e83143dd14a6.bin new file mode 100644 index 0000000..8b1ca94 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8348d6e19aa6bc6faa90e83143dd14a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8388fbde2c43745049bd88c16f60a5a0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8388fbde2c43745049bd88c16f60a5a0.bin new file mode 100644 index 0000000..3c3337f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8388fbde2c43745049bd88c16f60a5a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83b4babc4b13431e3aae35fbca5e1b81.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83b4babc4b13431e3aae35fbca5e1b81.bin new file mode 100644 index 0000000..dba4b71 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-83b4babc4b13431e3aae35fbca5e1b81.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-841c8224ad5c95f474732d61347191f3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-841c8224ad5c95f474732d61347191f3.bin new file mode 100644 index 0000000..348ccae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-841c8224ad5c95f474732d61347191f3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-844345b1f97cc1fe509258afb2ddaac9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-844345b1f97cc1fe509258afb2ddaac9.bin new file mode 100644 index 0000000..4b05d44 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-844345b1f97cc1fe509258afb2ddaac9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-851e774cb081558015b4fa00fb951d8a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-851e774cb081558015b4fa00fb951d8a.bin new file mode 100644 index 0000000..6d42735 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-851e774cb081558015b4fa00fb951d8a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8731a36478e46b1d455188e0291923a1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8731a36478e46b1d455188e0291923a1.bin new file mode 100644 index 0000000..8e22fc6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8731a36478e46b1d455188e0291923a1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f2892c5bcc735f29a8d6fcd7abdd31.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f2892c5bcc735f29a8d6fcd7abdd31.bin new file mode 100644 index 0000000..3102115 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f2892c5bcc735f29a8d6fcd7abdd31.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f68bf7aeeeac076dd23ee7f6312ff0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f68bf7aeeeac076dd23ee7f6312ff0.bin new file mode 100644 index 0000000..30aafdf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-87f68bf7aeeeac076dd23ee7f6312ff0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88157d30cb89a52e1c2b3236cc4afa3a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88157d30cb89a52e1c2b3236cc4afa3a.bin new file mode 100644 index 0000000..5722136 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88157d30cb89a52e1c2b3236cc4afa3a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8855858de92e4053cfc208c6bf6fa548.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8855858de92e4053cfc208c6bf6fa548.bin new file mode 100644 index 0000000..8abd3ed Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8855858de92e4053cfc208c6bf6fa548.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88912f64c61f6546381e6ffed73d9d57.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88912f64c61f6546381e6ffed73d9d57.bin new file mode 100644 index 0000000..d54a50d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88912f64c61f6546381e6ffed73d9d57.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88b35fe10d53110564935cce36b450e5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88b35fe10d53110564935cce36b450e5.bin new file mode 100644 index 0000000..a4c02f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-88b35fe10d53110564935cce36b450e5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-890971059d02fa352193eeab22501b7c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-890971059d02fa352193eeab22501b7c.bin new file mode 100644 index 0000000..f6dfca8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-890971059d02fa352193eeab22501b7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8925f0818e26c39e7d9597d3c3386eb9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8925f0818e26c39e7d9597d3c3386eb9.bin new file mode 100644 index 0000000..d056c07 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8925f0818e26c39e7d9597d3c3386eb9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8953bcc7f87c1417af2954096568dab6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8953bcc7f87c1417af2954096568dab6.bin new file mode 100644 index 0000000..8833a73 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8953bcc7f87c1417af2954096568dab6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8992ae93f964510a7b261a2c9f19d1e3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8992ae93f964510a7b261a2c9f19d1e3.bin new file mode 100644 index 0000000..0987483 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8992ae93f964510a7b261a2c9f19d1e3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a06f210783a9dd5af1189f6f015d4f8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a06f210783a9dd5af1189f6f015d4f8.bin new file mode 100644 index 0000000..4c56878 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a06f210783a9dd5af1189f6f015d4f8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a9dca7273b7fbed9823c7cabc43a648.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a9dca7273b7fbed9823c7cabc43a648.bin new file mode 100644 index 0000000..fea2161 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8a9dca7273b7fbed9823c7cabc43a648.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ae397d6b50205f913d2b257c9ccc375.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ae397d6b50205f913d2b257c9ccc375.bin new file mode 100644 index 0000000..77049c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ae397d6b50205f913d2b257c9ccc375.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8c1e3fa0f4c82034444769a3492256b5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8c1e3fa0f4c82034444769a3492256b5.bin new file mode 100644 index 0000000..cf32def Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8c1e3fa0f4c82034444769a3492256b5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8d3f975bb294c2d0f7aabbd44276b353.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8d3f975bb294c2d0f7aabbd44276b353.bin new file mode 100644 index 0000000..f13cfbf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8d3f975bb294c2d0f7aabbd44276b353.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8db4dbce8618ae4f56acd2a74b771fb5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8db4dbce8618ae4f56acd2a74b771fb5.bin new file mode 100644 index 0000000..0a6a346 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8db4dbce8618ae4f56acd2a74b771fb5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8dfdd6d7203b1f5b99cec09984135966.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8dfdd6d7203b1f5b99cec09984135966.bin new file mode 100644 index 0000000..40ac874 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8dfdd6d7203b1f5b99cec09984135966.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8e0659980555a5c31d79986e544e4eb5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8e0659980555a5c31d79986e544e4eb5.bin new file mode 100644 index 0000000..de3971e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8e0659980555a5c31d79986e544e4eb5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ea6ef988378badc80d631cb7314cca9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ea6ef988378badc80d631cb7314cca9.bin new file mode 100644 index 0000000..bd1560a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ea6ef988378badc80d631cb7314cca9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ef8bcac93cc832559e7f7eb1417f406.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ef8bcac93cc832559e7f7eb1417f406.bin new file mode 100644 index 0000000..f386830 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8ef8bcac93cc832559e7f7eb1417f406.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8efa38c03fbed3b8fc53e0b0dfa99168.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8efa38c03fbed3b8fc53e0b0dfa99168.bin new file mode 100644 index 0000000..3419825 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8efa38c03fbed3b8fc53e0b0dfa99168.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8f03b3e59b56ced216343b1f2b2a284b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8f03b3e59b56ced216343b1f2b2a284b.bin new file mode 100644 index 0000000..ef40bc2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8f03b3e59b56ced216343b1f2b2a284b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8feeed2bf6d8b686074de64562bd28fd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8feeed2bf6d8b686074de64562bd28fd.bin new file mode 100644 index 0000000..364eb18 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-8feeed2bf6d8b686074de64562bd28fd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-901c16626797cbfec40bea295421738f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-901c16626797cbfec40bea295421738f.bin new file mode 100644 index 0000000..ec0d276 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-901c16626797cbfec40bea295421738f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-90bef1a7982a2fc99477969d84f08fae.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-90bef1a7982a2fc99477969d84f08fae.bin new file mode 100644 index 0000000..d2358f3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-90bef1a7982a2fc99477969d84f08fae.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9236f325c668755f84cc7b8a295e3e19.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9236f325c668755f84cc7b8a295e3e19.bin new file mode 100644 index 0000000..c473a3a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9236f325c668755f84cc7b8a295e3e19.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92d610b11b24ea33a41c9337bf34a8bb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92d610b11b24ea33a41c9337bf34a8bb.bin new file mode 100644 index 0000000..9b800d7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92d610b11b24ea33a41c9337bf34a8bb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92eabd1f618748299ef6c75947a24c44.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92eabd1f618748299ef6c75947a24c44.bin new file mode 100644 index 0000000..c04ad72 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-92eabd1f618748299ef6c75947a24c44.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9345adadedd4e1f0ee8435f8bf8fa430.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9345adadedd4e1f0ee8435f8bf8fa430.bin new file mode 100644 index 0000000..bc4ceb5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9345adadedd4e1f0ee8435f8bf8fa430.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-93ee10a73601e0ad8e1281b45a006445.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-93ee10a73601e0ad8e1281b45a006445.bin new file mode 100644 index 0000000..e424a56 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-93ee10a73601e0ad8e1281b45a006445.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-950e8f86d2e07d3b779f0d119c9931a7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-950e8f86d2e07d3b779f0d119c9931a7.bin new file mode 100644 index 0000000..cb5be82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-950e8f86d2e07d3b779f0d119c9931a7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9587f5dc2886d490ee203e5855a779c9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9587f5dc2886d490ee203e5855a779c9.bin new file mode 100644 index 0000000..8b964cf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9587f5dc2886d490ee203e5855a779c9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96627502bc21343aa1b177cbb09421e3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96627502bc21343aa1b177cbb09421e3.bin new file mode 100644 index 0000000..d4b0315 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96627502bc21343aa1b177cbb09421e3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-969b6003c10f11d8e2ce21ac1a05431a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-969b6003c10f11d8e2ce21ac1a05431a.bin new file mode 100644 index 0000000..dc8236f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-969b6003c10f11d8e2ce21ac1a05431a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96c8e5c69fdf18ff6f48ca15ff048890.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96c8e5c69fdf18ff6f48ca15ff048890.bin new file mode 100644 index 0000000..0d17a5d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-96c8e5c69fdf18ff6f48ca15ff048890.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-97050574a90fc617e21a269240dc3c83.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-97050574a90fc617e21a269240dc3c83.bin new file mode 100644 index 0000000..17eb801 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-97050574a90fc617e21a269240dc3c83.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-982bdfb2a0a6fc0d98755240b6996688.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-982bdfb2a0a6fc0d98755240b6996688.bin new file mode 100644 index 0000000..93cc1fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-982bdfb2a0a6fc0d98755240b6996688.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-988407c4c77e823b5f7b64a971b7679c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-988407c4c77e823b5f7b64a971b7679c.bin new file mode 100644 index 0000000..85c403d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-988407c4c77e823b5f7b64a971b7679c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-99433d0bf3457786ebd6645e3bda8a4b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-99433d0bf3457786ebd6645e3bda8a4b.bin new file mode 100644 index 0000000..5209d7d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-99433d0bf3457786ebd6645e3bda8a4b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b4834c5067fb4619d864f80df02a797.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b4834c5067fb4619d864f80df02a797.bin new file mode 100644 index 0000000..fd685cb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b4834c5067fb4619d864f80df02a797.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b87c42c66631bebfdb8ed2069ad40a8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b87c42c66631bebfdb8ed2069ad40a8.bin new file mode 100644 index 0000000..fdf0eec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b87c42c66631bebfdb8ed2069ad40a8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b8923b23adce4f5e34a9ee4ea8f6b7c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b8923b23adce4f5e34a9ee4ea8f6b7c.bin new file mode 100644 index 0000000..71aaf10 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9b8923b23adce4f5e34a9ee4ea8f6b7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c55e6a46b4154573478393834927e91.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c55e6a46b4154573478393834927e91.bin new file mode 100644 index 0000000..5de8612 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c55e6a46b4154573478393834927e91.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c6ea664553dd1c2e5800af2d059a9cb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c6ea664553dd1c2e5800af2d059a9cb.bin new file mode 100644 index 0000000..392364d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c6ea664553dd1c2e5800af2d059a9cb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c93f2efa418c7fcbf430f31bb1f4381.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c93f2efa418c7fcbf430f31bb1f4381.bin new file mode 100644 index 0000000..a3077b5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9c93f2efa418c7fcbf430f31bb1f4381.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d333f1722dae6f192e6517b709e44fc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d333f1722dae6f192e6517b709e44fc.bin new file mode 100644 index 0000000..4e96b2a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d333f1722dae6f192e6517b709e44fc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d81640541edac9bfddb980dac24bb6f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d81640541edac9bfddb980dac24bb6f.bin new file mode 100644 index 0000000..5376c8b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9d81640541edac9bfddb980dac24bb6f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9da453956b68c3d4b7f797f992031d7b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9da453956b68c3d4b7f797f992031d7b.bin new file mode 100644 index 0000000..09ab7b3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9da453956b68c3d4b7f797f992031d7b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e5e302315b3d5a6a3fffc7701a7e4be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e5e302315b3d5a6a3fffc7701a7e4be.bin new file mode 100644 index 0000000..d9b0504 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e5e302315b3d5a6a3fffc7701a7e4be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7739ffe5b4f07a9d81844174ba3a2e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7739ffe5b4f07a9d81844174ba3a2e.bin new file mode 100644 index 0000000..6cbbe25 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7739ffe5b4f07a9d81844174ba3a2e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7c2b2db46c09a5ef951a521c1d3177.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7c2b2db46c09a5ef951a521c1d3177.bin new file mode 100644 index 0000000..d189482 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7c2b2db46c09a5ef951a521c1d3177.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7d38632470ff64bf6933d26eac654e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7d38632470ff64bf6933d26eac654e.bin new file mode 100644 index 0000000..5b52ab1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e7d38632470ff64bf6933d26eac654e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e8ad4332ca86bf4de4968c38bd1531f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e8ad4332ca86bf4de4968c38bd1531f.bin new file mode 100644 index 0000000..5c511c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e8ad4332ca86bf4de4968c38bd1531f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e972af59b536dcf55bbd074129550e6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e972af59b536dcf55bbd074129550e6.bin new file mode 100644 index 0000000..f2157f0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9e972af59b536dcf55bbd074129550e6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9eec7e8aa7a1bab8ffe16d5c2fc6b02f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9eec7e8aa7a1bab8ffe16d5c2fc6b02f.bin new file mode 100644 index 0000000..b707b89 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9eec7e8aa7a1bab8ffe16d5c2fc6b02f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f1b0f2c6c49522e0a8a466ff6d7ab6f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f1b0f2c6c49522e0a8a466ff6d7ab6f.bin new file mode 100644 index 0000000..4d71848 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f1b0f2c6c49522e0a8a466ff6d7ab6f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f8f624b526e8f150dad831843e05083.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f8f624b526e8f150dad831843e05083.bin new file mode 100644 index 0000000..424fadf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-9f8f624b526e8f150dad831843e05083.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a06ffa52847149fc36f93f3affc3127c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a06ffa52847149fc36f93f3affc3127c.bin new file mode 100644 index 0000000..93de2b6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a06ffa52847149fc36f93f3affc3127c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a070f159ed9f8307fe95920abaeb78f4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a070f159ed9f8307fe95920abaeb78f4.bin new file mode 100644 index 0000000..2242a82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a070f159ed9f8307fe95920abaeb78f4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a08408a94a7de877e7be064e1195408c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a08408a94a7de877e7be064e1195408c.bin new file mode 100644 index 0000000..db7272e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a08408a94a7de877e7be064e1195408c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0b970937ef6ca9c9d7a98f233f145c3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0b970937ef6ca9c9d7a98f233f145c3.bin new file mode 100644 index 0000000..89c4685 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0b970937ef6ca9c9d7a98f233f145c3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0bf4fe5c48e21941768aac7d6adad5f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0bf4fe5c48e21941768aac7d6adad5f.bin new file mode 100644 index 0000000..a083c8d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a0bf4fe5c48e21941768aac7d6adad5f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a24838a120e2bb7e7aa5b0849cae717a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a24838a120e2bb7e7aa5b0849cae717a.bin new file mode 100644 index 0000000..7ba3df4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a24838a120e2bb7e7aa5b0849cae717a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2acc7efb0ebe3a54f855675e98a57bd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2acc7efb0ebe3a54f855675e98a57bd.bin new file mode 100644 index 0000000..f606c0d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2acc7efb0ebe3a54f855675e98a57bd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2c905e906bfbd4bdc3744cf8c420523.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2c905e906bfbd4bdc3744cf8c420523.bin new file mode 100644 index 0000000..a751e32 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a2c905e906bfbd4bdc3744cf8c420523.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3d5f800fb5af17ac150f497357d7487.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3d5f800fb5af17ac150f497357d7487.bin new file mode 100644 index 0000000..0a62e35 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3d5f800fb5af17ac150f497357d7487.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3e402f3688a29f222d566d1a53f662f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3e402f3688a29f222d566d1a53f662f.bin new file mode 100644 index 0000000..cae5998 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a3e402f3688a29f222d566d1a53f662f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4cd916628ceefe9ff80c9a20ab59d58.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4cd916628ceefe9ff80c9a20ab59d58.bin new file mode 100644 index 0000000..c8b2926 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4cd916628ceefe9ff80c9a20ab59d58.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4d6f159b4d040a66a38a68e0f47baba.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4d6f159b4d040a66a38a68e0f47baba.bin new file mode 100644 index 0000000..8c3d244 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a4d6f159b4d040a66a38a68e0f47baba.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a607126b3c05f5b9b08b2eef4222915e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a607126b3c05f5b9b08b2eef4222915e.bin new file mode 100644 index 0000000..0aa2034 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a607126b3c05f5b9b08b2eef4222915e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6dd7a2a3e9caaa23844b84e6c6eb0ec.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6dd7a2a3e9caaa23844b84e6c6eb0ec.bin new file mode 100644 index 0000000..1af31d5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6dd7a2a3e9caaa23844b84e6c6eb0ec.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6eb144de6fcd0226bc5e511c4a1c81e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6eb144de6fcd0226bc5e511c4a1c81e.bin new file mode 100644 index 0000000..75f7feb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a6eb144de6fcd0226bc5e511c4a1c81e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9994d1cbf0c864b68e0eff10bf65bd5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9994d1cbf0c864b68e0eff10bf65bd5.bin new file mode 100644 index 0000000..41f5d2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9994d1cbf0c864b68e0eff10bf65bd5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9cd44011240f8b1069bd4d08d67f2be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9cd44011240f8b1069bd4d08d67f2be.bin new file mode 100644 index 0000000..898734a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9cd44011240f8b1069bd4d08d67f2be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9faabdbc2aa93ab7fca7e9643383c5e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9faabdbc2aa93ab7fca7e9643383c5e.bin new file mode 100644 index 0000000..48606af Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-a9faabdbc2aa93ab7fca7e9643383c5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa23edbfb310b01413b5a851ff74440d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa23edbfb310b01413b5a851ff74440d.bin new file mode 100644 index 0000000..71d2d09 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa23edbfb310b01413b5a851ff74440d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa8e63271735fbf22ef9f4220bc286d1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa8e63271735fbf22ef9f4220bc286d1.bin new file mode 100644 index 0000000..2e2bf9b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa8e63271735fbf22ef9f4220bc286d1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa91233beaa090549662fd04c35585fb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa91233beaa090549662fd04c35585fb.bin new file mode 100644 index 0000000..e3abe34 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-aa91233beaa090549662fd04c35585fb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab417932173e6841898ac3f0900b32b7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab417932173e6841898ac3f0900b32b7.bin new file mode 100644 index 0000000..13e9738 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab417932173e6841898ac3f0900b32b7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab4c1f4a5a2dc26e3ed1ece3ce717208.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab4c1f4a5a2dc26e3ed1ece3ce717208.bin new file mode 100644 index 0000000..5b6262f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab4c1f4a5a2dc26e3ed1ece3ce717208.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab742bd1183331936e342a53516f4d10.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab742bd1183331936e342a53516f4d10.bin new file mode 100644 index 0000000..0672d7b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ab742bd1183331936e342a53516f4d10.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abc506add9132269d23c80ab00cd9142.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abc506add9132269d23c80ab00cd9142.bin new file mode 100644 index 0000000..f03c54b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abc506add9132269d23c80ab00cd9142.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abdec91ac06399acee06df1913fdc708.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abdec91ac06399acee06df1913fdc708.bin new file mode 100644 index 0000000..3e9580f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abdec91ac06399acee06df1913fdc708.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abeabad116b715388d68be9f7c0b6d0f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abeabad116b715388d68be9f7c0b6d0f.bin new file mode 100644 index 0000000..c5c6be0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abeabad116b715388d68be9f7c0b6d0f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abef1f00979fbad8727275cfa07752d7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abef1f00979fbad8727275cfa07752d7.bin new file mode 100644 index 0000000..450cbf3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-abef1f00979fbad8727275cfa07752d7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac0d644e937f1535ed3d665ae3202237.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac0d644e937f1535ed3d665ae3202237.bin new file mode 100644 index 0000000..6a1796d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac0d644e937f1535ed3d665ae3202237.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac2c8b42c337b87f21a57364c497767a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac2c8b42c337b87f21a57364c497767a.bin new file mode 100644 index 0000000..09add5d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac2c8b42c337b87f21a57364c497767a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac3355d469b2b69dc72698fc3516d616.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac3355d469b2b69dc72698fc3516d616.bin new file mode 100644 index 0000000..0563a87 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ac3355d469b2b69dc72698fc3516d616.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-acdd9142b24ab521748ec98b99f20851.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-acdd9142b24ab521748ec98b99f20851.bin new file mode 100644 index 0000000..d720dc8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-acdd9142b24ab521748ec98b99f20851.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad24a65149ae8c4971ada61fa3d204e4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad24a65149ae8c4971ada61fa3d204e4.bin new file mode 100644 index 0000000..b0407f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad24a65149ae8c4971ada61fa3d204e4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad826cfbc182eb82bacc055d9749f124.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad826cfbc182eb82bacc055d9749f124.bin new file mode 100644 index 0000000..e6fbec3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad826cfbc182eb82bacc055d9749f124.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad8e77a8a9979fa05c959e8edfeaafae.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad8e77a8a9979fa05c959e8edfeaafae.bin new file mode 100644 index 0000000..38c7aab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ad8e77a8a9979fa05c959e8edfeaafae.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb5ec3b4c04a66299d88dfdd1dcb308.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb5ec3b4c04a66299d88dfdd1dcb308.bin new file mode 100644 index 0000000..5b3de19 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb5ec3b4c04a66299d88dfdd1dcb308.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb69affc77a51717d9f5dd7c9581423.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb69affc77a51717d9f5dd7c9581423.bin new file mode 100644 index 0000000..8ce117d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-adb69affc77a51717d9f5dd7c9581423.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ae672bfb6e06e8255b3a92f93f422b5f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ae672bfb6e06e8255b3a92f93f422b5f.bin new file mode 100644 index 0000000..ac03a8b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ae672bfb6e06e8255b3a92f93f422b5f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-af23d9e46df463748a7fd87b1373ba16.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-af23d9e46df463748a7fd87b1373ba16.bin new file mode 100644 index 0000000..e6094c0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-af23d9e46df463748a7fd87b1373ba16.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b062ee68a65b5b835ddb6ab7a8343a96.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b062ee68a65b5b835ddb6ab7a8343a96.bin new file mode 100644 index 0000000..43b41c8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b062ee68a65b5b835ddb6ab7a8343a96.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1517ea7f6f348f7409704a54cff21a8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1517ea7f6f348f7409704a54cff21a8.bin new file mode 100644 index 0000000..d635227 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1517ea7f6f348f7409704a54cff21a8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1a1a01fc137f95a6ec139af6981852e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1a1a01fc137f95a6ec139af6981852e.bin new file mode 100644 index 0000000..85892ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1a1a01fc137f95a6ec139af6981852e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1ffa9edb45641a7f2a21d7b5c5f846c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1ffa9edb45641a7f2a21d7b5c5f846c.bin new file mode 100644 index 0000000..e748d56 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b1ffa9edb45641a7f2a21d7b5c5f846c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b20009a35f37d379a40c61042e4eb799.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b20009a35f37d379a40c61042e4eb799.bin new file mode 100644 index 0000000..db33b72 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b20009a35f37d379a40c61042e4eb799.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b24fcb23147ec8d275d5054b6bf380b0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b24fcb23147ec8d275d5054b6bf380b0.bin new file mode 100644 index 0000000..a8dc845 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b24fcb23147ec8d275d5054b6bf380b0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b36ccd78e7f5c9ce5dac27e060687955.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b36ccd78e7f5c9ce5dac27e060687955.bin new file mode 100644 index 0000000..1a35a6e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b36ccd78e7f5c9ce5dac27e060687955.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b37f1ffa4d7597453c282e35691d32c7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b37f1ffa4d7597453c282e35691d32c7.bin new file mode 100644 index 0000000..92a6874 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b37f1ffa4d7597453c282e35691d32c7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b3dec4745f5b32081a5e8b3ca014e4f8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b3dec4745f5b32081a5e8b3ca014e4f8.bin new file mode 100644 index 0000000..e8ddaae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b3dec4745f5b32081a5e8b3ca014e4f8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b42b3f96ac5d4721eef455f212918841.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b42b3f96ac5d4721eef455f212918841.bin new file mode 100644 index 0000000..2762540 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b42b3f96ac5d4721eef455f212918841.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b46f7ae0ef80a6e6a46746330fa5deb6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b46f7ae0ef80a6e6a46746330fa5deb6.bin new file mode 100644 index 0000000..eca86ff Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b46f7ae0ef80a6e6a46746330fa5deb6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b53846fda71f8a0dfa164f8f48ac40f0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b53846fda71f8a0dfa164f8f48ac40f0.bin new file mode 100644 index 0000000..a2c5b32 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b53846fda71f8a0dfa164f8f48ac40f0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b5dbef906b4c29eb59a96d0b9aa66f5a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b5dbef906b4c29eb59a96d0b9aa66f5a.bin new file mode 100644 index 0000000..7d8e986 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b5dbef906b4c29eb59a96d0b9aa66f5a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b6054ddaaf47324580ecfacc14e49374.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b6054ddaaf47324580ecfacc14e49374.bin new file mode 100644 index 0000000..006db57 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b6054ddaaf47324580ecfacc14e49374.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b62df6794b81855e2387cefaa967fedd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b62df6794b81855e2387cefaa967fedd.bin new file mode 100644 index 0000000..568642c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b62df6794b81855e2387cefaa967fedd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b650726278a283081e490a07e79513a0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b650726278a283081e490a07e79513a0.bin new file mode 100644 index 0000000..d0e2932 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b650726278a283081e490a07e79513a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b69bfeefb000b46a98af7e2cf597c3fc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b69bfeefb000b46a98af7e2cf597c3fc.bin new file mode 100644 index 0000000..d2ef3b4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b69bfeefb000b46a98af7e2cf597c3fc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b75b265d435f61b989675c6cf126c337.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b75b265d435f61b989675c6cf126c337.bin new file mode 100644 index 0000000..0e99d7b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b75b265d435f61b989675c6cf126c337.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b78df4bc44a125f964197333af18fb16.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b78df4bc44a125f964197333af18fb16.bin new file mode 100644 index 0000000..61fa97c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b78df4bc44a125f964197333af18fb16.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7ef7fabbdc4cdd6e6bef995f3f91ddf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7ef7fabbdc4cdd6e6bef995f3f91ddf.bin new file mode 100644 index 0000000..166daa9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7ef7fabbdc4cdd6e6bef995f3f91ddf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7f1de4d95421886e07b6eb55a433282.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7f1de4d95421886e07b6eb55a433282.bin new file mode 100644 index 0000000..1ff885e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b7f1de4d95421886e07b6eb55a433282.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b90430489a1c2cf0788004afb78fd0e0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b90430489a1c2cf0788004afb78fd0e0.bin new file mode 100644 index 0000000..56a1415 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b90430489a1c2cf0788004afb78fd0e0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b9f6e12ba9a77d357b7841f0adb5b519.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b9f6e12ba9a77d357b7841f0adb5b519.bin new file mode 100644 index 0000000..981042c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-b9f6e12ba9a77d357b7841f0adb5b519.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba1b28a05e9883a656fd9952ddc776f9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba1b28a05e9883a656fd9952ddc776f9.bin new file mode 100644 index 0000000..3272ad6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba1b28a05e9883a656fd9952ddc776f9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba5036db8ef816a63530d6f15e70c2da.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba5036db8ef816a63530d6f15e70c2da.bin new file mode 100644 index 0000000..5248e23 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba5036db8ef816a63530d6f15e70c2da.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba9e170a54a497f0f8b8d1626c8cab0e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba9e170a54a497f0f8b8d1626c8cab0e.bin new file mode 100644 index 0000000..f1b0b82 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ba9e170a54a497f0f8b8d1626c8cab0e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bac516e1d4075517e74eff010737c314.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bac516e1d4075517e74eff010737c314.bin new file mode 100644 index 0000000..cf42519 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bac516e1d4075517e74eff010737c314.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-badd3ff610da4b86a13b1087b6e8a7a7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-badd3ff610da4b86a13b1087b6e8a7a7.bin new file mode 100644 index 0000000..7809d75 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-badd3ff610da4b86a13b1087b6e8a7a7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb2b68080a1a041b204c7f112835f431.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb2b68080a1a041b204c7f112835f431.bin new file mode 100644 index 0000000..c428d03 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb2b68080a1a041b204c7f112835f431.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb34470fd2bd20ce1d9abc8317253920.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb34470fd2bd20ce1d9abc8317253920.bin new file mode 100644 index 0000000..f0901b4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb34470fd2bd20ce1d9abc8317253920.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb7542902594da41a6b3ed82141ecf2a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb7542902594da41a6b3ed82141ecf2a.bin new file mode 100644 index 0000000..d6d80c9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bb7542902594da41a6b3ed82141ecf2a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd0c1b56af43fd493c892f032d06d3da.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd0c1b56af43fd493c892f032d06d3da.bin new file mode 100644 index 0000000..f30a4a7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd0c1b56af43fd493c892f032d06d3da.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd2f47f8f7dac6efcc4a84c376d88f26.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd2f47f8f7dac6efcc4a84c376d88f26.bin new file mode 100644 index 0000000..4db42bb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-bd2f47f8f7dac6efcc4a84c376d88f26.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-be7c2ce170ca33061167e333be7f07fa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-be7c2ce170ca33061167e333be7f07fa.bin new file mode 100644 index 0000000..a993d14 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-be7c2ce170ca33061167e333be7f07fa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c0d26b8691d50a8bcac160bf25d9c65e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c0d26b8691d50a8bcac160bf25d9c65e.bin new file mode 100644 index 0000000..6935aae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c0d26b8691d50a8bcac160bf25d9c65e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c14e8f1bbe54975d08e1cff54a16030d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c14e8f1bbe54975d08e1cff54a16030d.bin new file mode 100644 index 0000000..fbdfcd5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c14e8f1bbe54975d08e1cff54a16030d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c163c7cffe7413608c9cfcd6ddd79999.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c163c7cffe7413608c9cfcd6ddd79999.bin new file mode 100644 index 0000000..c11242a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c163c7cffe7413608c9cfcd6ddd79999.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1c84542b0392a58a78238b439f362cb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1c84542b0392a58a78238b439f362cb.bin new file mode 100644 index 0000000..b2f9413 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1c84542b0392a58a78238b439f362cb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ca7cab6962599d2b847b26c7f5b3ea.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ca7cab6962599d2b847b26c7f5b3ea.bin new file mode 100644 index 0000000..3928c99 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ca7cab6962599d2b847b26c7f5b3ea.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ff59425d14ead9731844efd1ae6e97.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ff59425d14ead9731844efd1ae6e97.bin new file mode 100644 index 0000000..a534f2f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c1ff59425d14ead9731844efd1ae6e97.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c22ef6467624e0c9de70c92e626e821d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c22ef6467624e0c9de70c92e626e821d.bin new file mode 100644 index 0000000..9f06d63 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c22ef6467624e0c9de70c92e626e821d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c278b1ffb42d16bf458b94735a5d0995.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c278b1ffb42d16bf458b94735a5d0995.bin new file mode 100644 index 0000000..ed78e5e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c278b1ffb42d16bf458b94735a5d0995.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c2c84025d37660af0694bd90f3cd33e7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c2c84025d37660af0694bd90f3cd33e7.bin new file mode 100644 index 0000000..436ae96 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c2c84025d37660af0694bd90f3cd33e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c31f8c429b28c7c708aa9f5da353a6e7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c31f8c429b28c7c708aa9f5da353a6e7.bin new file mode 100644 index 0000000..70e28c0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c31f8c429b28c7c708aa9f5da353a6e7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c3398042bd43524ff117dc30c5f26adb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c3398042bd43524ff117dc30c5f26adb.bin new file mode 100644 index 0000000..cd43808 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c3398042bd43524ff117dc30c5f26adb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4203ddc84554adda123905c91ac05dd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4203ddc84554adda123905c91ac05dd.bin new file mode 100644 index 0000000..a0399f3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4203ddc84554adda123905c91ac05dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4470fc53c69ad2ad4540198bf54e6c8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4470fc53c69ad2ad4540198bf54e6c8.bin new file mode 100644 index 0000000..c3b9915 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4470fc53c69ad2ad4540198bf54e6c8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c47dad3cc936f8aee9bb2d8527c983a9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c47dad3cc936f8aee9bb2d8527c983a9.bin new file mode 100644 index 0000000..4e350cf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c47dad3cc936f8aee9bb2d8527c983a9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4b0a1b564f3e8a3632d8adf5289724b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4b0a1b564f3e8a3632d8adf5289724b.bin new file mode 100644 index 0000000..3421947 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4b0a1b564f3e8a3632d8adf5289724b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4f6f0741653d28819f7803a2307e824.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4f6f0741653d28819f7803a2307e824.bin new file mode 100644 index 0000000..bce4400 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c4f6f0741653d28819f7803a2307e824.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c56990010838f8a4320d1fdc5bcdb855.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c56990010838f8a4320d1fdc5bcdb855.bin new file mode 100644 index 0000000..2dfd4b9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c56990010838f8a4320d1fdc5bcdb855.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c57a3f466bc6293dfe8936ff86738019.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c57a3f466bc6293dfe8936ff86738019.bin new file mode 100644 index 0000000..ef86f13 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c57a3f466bc6293dfe8936ff86738019.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63046a2aba09b22a5de7878daff52af.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63046a2aba09b22a5de7878daff52af.bin new file mode 100644 index 0000000..be9eaaf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63046a2aba09b22a5de7878daff52af.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63cbef0e2b3b705b2227a97f88597c9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63cbef0e2b3b705b2227a97f88597c9.bin new file mode 100644 index 0000000..acbe679 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c63cbef0e2b3b705b2227a97f88597c9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c64ff4b9dbf2bb005caf566e2ec9c8f1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c64ff4b9dbf2bb005caf566e2ec9c8f1.bin new file mode 100644 index 0000000..8d36ec1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c64ff4b9dbf2bb005caf566e2ec9c8f1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c71a095f26fc1d6d7092daa8bbfdb660.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c71a095f26fc1d6d7092daa8bbfdb660.bin new file mode 100644 index 0000000..19e715e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c71a095f26fc1d6d7092daa8bbfdb660.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c74c07e5b3356b704ae1e40e06093871.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c74c07e5b3356b704ae1e40e06093871.bin new file mode 100644 index 0000000..2edca5e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c74c07e5b3356b704ae1e40e06093871.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c754445dbba5139b0397caa56ccc0f93.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c754445dbba5139b0397caa56ccc0f93.bin new file mode 100644 index 0000000..0f7f70c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c754445dbba5139b0397caa56ccc0f93.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c79bdd16fc863eda7c4e1f35eb5ff71c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c79bdd16fc863eda7c4e1f35eb5ff71c.bin new file mode 100644 index 0000000..4230fd3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c79bdd16fc863eda7c4e1f35eb5ff71c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7ccd70083f756e77b62b388c86cb826.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7ccd70083f756e77b62b388c86cb826.bin new file mode 100644 index 0000000..38db7c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7ccd70083f756e77b62b388c86cb826.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7fc85d872103cc7085f1b25c95c9a08.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7fc85d872103cc7085f1b25c95c9a08.bin new file mode 100644 index 0000000..d0f58ec Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c7fc85d872103cc7085f1b25c95c9a08.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c8bf540191817a8ac1b32ccfea1e7cba.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c8bf540191817a8ac1b32ccfea1e7cba.bin new file mode 100644 index 0000000..e18fd3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-c8bf540191817a8ac1b32ccfea1e7cba.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ca0ab4503a8bd4c27dd2513b3de6f9e2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ca0ab4503a8bd4c27dd2513b3de6f9e2.bin new file mode 100644 index 0000000..9c664fd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ca0ab4503a8bd4c27dd2513b3de6f9e2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cadfdff1e98579f2e0de070f2f6102b5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cadfdff1e98579f2e0de070f2f6102b5.bin new file mode 100644 index 0000000..dee5970 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cadfdff1e98579f2e0de070f2f6102b5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cb14eff88f1015ccd1780cf938bf6a73.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cb14eff88f1015ccd1780cf938bf6a73.bin new file mode 100644 index 0000000..1fd8f93 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cb14eff88f1015ccd1780cf938bf6a73.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cc877d6ce101d1a2b17f82a494520966.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cc877d6ce101d1a2b17f82a494520966.bin new file mode 100644 index 0000000..fa81500 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cc877d6ce101d1a2b17f82a494520966.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ccd05564d1ed452248de0333f5e42910.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ccd05564d1ed452248de0333f5e42910.bin new file mode 100644 index 0000000..90cf705 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ccd05564d1ed452248de0333f5e42910.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cde8c59dabc4fb34d71e50e51890d2df.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cde8c59dabc4fb34d71e50e51890d2df.bin new file mode 100644 index 0000000..bda9147 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cde8c59dabc4fb34d71e50e51890d2df.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cdfc1ebb90c5d6402f906c34802e79d1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cdfc1ebb90c5d6402f906c34802e79d1.bin new file mode 100644 index 0000000..67179c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cdfc1ebb90c5d6402f906c34802e79d1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cebac935fbef8ac1d151cfb0333c19cb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cebac935fbef8ac1d151cfb0333c19cb.bin new file mode 100644 index 0000000..db169b6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cebac935fbef8ac1d151cfb0333c19cb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf0d04583001d8bc46c5dc5914931bb9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf0d04583001d8bc46c5dc5914931bb9.bin new file mode 100644 index 0000000..f8c44f2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf0d04583001d8bc46c5dc5914931bb9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf7d8eb9cba761b7dca95d9d18abfee0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf7d8eb9cba761b7dca95d9d18abfee0.bin new file mode 100644 index 0000000..3716e45 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cf7d8eb9cba761b7dca95d9d18abfee0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cfa7157b54dcfde258cfd4956bdbbc90.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cfa7157b54dcfde258cfd4956bdbbc90.bin new file mode 100644 index 0000000..78746b8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cfa7157b54dcfde258cfd4956bdbbc90.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cff0623e795a09aae6760a664ece1448.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cff0623e795a09aae6760a664ece1448.bin new file mode 100644 index 0000000..d949940 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-cff0623e795a09aae6760a664ece1448.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1bcb91e40a5f702af238dc6c50dd952.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1bcb91e40a5f702af238dc6c50dd952.bin new file mode 100644 index 0000000..276f7db Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1bcb91e40a5f702af238dc6c50dd952.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1c6de0879b13424b5d2e2daea21f180.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1c6de0879b13424b5d2e2daea21f180.bin new file mode 100644 index 0000000..fc3cdf5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d1c6de0879b13424b5d2e2daea21f180.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2182d114f1e0aa2548495b2d2ba2f11.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2182d114f1e0aa2548495b2d2ba2f11.bin new file mode 100644 index 0000000..d15bea5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2182d114f1e0aa2548495b2d2ba2f11.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2292573ec51401718c1ab107277ac43.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2292573ec51401718c1ab107277ac43.bin new file mode 100644 index 0000000..3e6456b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2292573ec51401718c1ab107277ac43.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d24e1dca5d23bf5ce1e8c189e1264817.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d24e1dca5d23bf5ce1e8c189e1264817.bin new file mode 100644 index 0000000..94e0053 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d24e1dca5d23bf5ce1e8c189e1264817.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d269244a95af2ef22948701126227ff7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d269244a95af2ef22948701126227ff7.bin new file mode 100644 index 0000000..6a3d2e0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d269244a95af2ef22948701126227ff7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d28198a6946b76c14d7e93c684c15f2c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d28198a6946b76c14d7e93c684c15f2c.bin new file mode 100644 index 0000000..7694f79 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d28198a6946b76c14d7e93c684c15f2c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d29e8541bc5ab1896618c06e57838490.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d29e8541bc5ab1896618c06e57838490.bin new file mode 100644 index 0000000..300320d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d29e8541bc5ab1896618c06e57838490.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2e2579c86c2c57133a76d791cf83276.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2e2579c86c2c57133a76d791cf83276.bin new file mode 100644 index 0000000..ac0a496 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d2e2579c86c2c57133a76d791cf83276.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d43ce7109c2df49604a82cdc3f990655.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d43ce7109c2df49604a82cdc3f990655.bin new file mode 100644 index 0000000..e24c358 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d43ce7109c2df49604a82cdc3f990655.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d478b45e9043b1353b8aea8d47717db2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d478b45e9043b1353b8aea8d47717db2.bin new file mode 100644 index 0000000..fdaa90b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d478b45e9043b1353b8aea8d47717db2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4b7646c7b3f9486714508545d3481f9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4b7646c7b3f9486714508545d3481f9.bin new file mode 100644 index 0000000..3c5b406 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4b7646c7b3f9486714508545d3481f9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4c667211160737a46014d33fa0e77ed.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4c667211160737a46014d33fa0e77ed.bin new file mode 100644 index 0000000..43ee033 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d4c667211160737a46014d33fa0e77ed.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5bbc5e1c0d97c76a31821cbae9854a0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5bbc5e1c0d97c76a31821cbae9854a0.bin new file mode 100644 index 0000000..1a76ad8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5bbc5e1c0d97c76a31821cbae9854a0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5c2d60793c0eb9356f89b79f71ac427.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5c2d60793c0eb9356f89b79f71ac427.bin new file mode 100644 index 0000000..9c26700 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d5c2d60793c0eb9356f89b79f71ac427.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d6dac19ee342a5dde1781befa3f86322.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d6dac19ee342a5dde1781befa3f86322.bin new file mode 100644 index 0000000..931d03a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d6dac19ee342a5dde1781befa3f86322.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d7bde2ce56acb2164b780eef99c9f3ef.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d7bde2ce56acb2164b780eef99c9f3ef.bin new file mode 100644 index 0000000..f0e2e1b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d7bde2ce56acb2164b780eef99c9f3ef.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d81c67e35f43b48172cf902cbd4a2427.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d81c67e35f43b48172cf902cbd4a2427.bin new file mode 100644 index 0000000..754c3b2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d81c67e35f43b48172cf902cbd4a2427.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d850f133fd334f5250e655bd89a0e0f0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d850f133fd334f5250e655bd89a0e0f0.bin new file mode 100644 index 0000000..d5def90 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d850f133fd334f5250e655bd89a0e0f0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d86f34454a74b810703b8d7fa70c1ad0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d86f34454a74b810703b8d7fa70c1ad0.bin new file mode 100644 index 0000000..5eba207 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d86f34454a74b810703b8d7fa70c1ad0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d8917013c20e3015079e617d2749bf4f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d8917013c20e3015079e617d2749bf4f.bin new file mode 100644 index 0000000..60c67f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d8917013c20e3015079e617d2749bf4f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d911609cdea5cabcd52014442a3f5420.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d911609cdea5cabcd52014442a3f5420.bin new file mode 100644 index 0000000..0db3979 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d911609cdea5cabcd52014442a3f5420.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d926d5fb66095a3af87d189ff3d4aaa5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d926d5fb66095a3af87d189ff3d4aaa5.bin new file mode 100644 index 0000000..39927d6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d926d5fb66095a3af87d189ff3d4aaa5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d96cc34ac03355ca8929599f8f13e585.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d96cc34ac03355ca8929599f8f13e585.bin new file mode 100644 index 0000000..06252b0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-d96cc34ac03355ca8929599f8f13e585.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-daa16d3b924e80d308d2216cb41e1ff1.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-daa16d3b924e80d308d2216cb41e1ff1.bin new file mode 100644 index 0000000..4df6725 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-daa16d3b924e80d308d2216cb41e1ff1.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dabb4a5cd6d91920f02d3eaa4b8218c5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dabb4a5cd6d91920f02d3eaa4b8218c5.bin new file mode 100644 index 0000000..9a98ee1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dabb4a5cd6d91920f02d3eaa4b8218c5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-db8bde4805d9eebc980ec38476e132c9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-db8bde4805d9eebc980ec38476e132c9.bin new file mode 100644 index 0000000..33488c2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-db8bde4805d9eebc980ec38476e132c9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc54b8b454f8952dd8e8edc2b75633aa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc54b8b454f8952dd8e8edc2b75633aa.bin new file mode 100644 index 0000000..f59a05c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc54b8b454f8952dd8e8edc2b75633aa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc84deef4c6ead5d539afec846c6ef80.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc84deef4c6ead5d539afec846c6ef80.bin new file mode 100644 index 0000000..92dc8b1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dc84deef4c6ead5d539afec846c6ef80.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd0c92845089fb4a5b252673370158fc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd0c92845089fb4a5b252673370158fc.bin new file mode 100644 index 0000000..b515543 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd0c92845089fb4a5b252673370158fc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd38a0b7b383c3dc762ebccfebc80740.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd38a0b7b383c3dc762ebccfebc80740.bin new file mode 100644 index 0000000..c2d9280 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd38a0b7b383c3dc762ebccfebc80740.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd69d46e6bfa54444751e7fb0ad56016.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd69d46e6bfa54444751e7fb0ad56016.bin new file mode 100644 index 0000000..551d8f7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dd69d46e6bfa54444751e7fb0ad56016.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de0180d6aa5858d5f3cfd6a526909f63.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de0180d6aa5858d5f3cfd6a526909f63.bin new file mode 100644 index 0000000..7c64bc1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de0180d6aa5858d5f3cfd6a526909f63.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de60974fd512034c1ba510299d0dc471.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de60974fd512034c1ba510299d0dc471.bin new file mode 100644 index 0000000..ef939ce Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-de60974fd512034c1ba510299d0dc471.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dee9f825892ef5a565726eee93389b03.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dee9f825892ef5a565726eee93389b03.bin new file mode 100644 index 0000000..dcfe20e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dee9f825892ef5a565726eee93389b03.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-deffc3c5ec5c5346d4ef48d1279343ee.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-deffc3c5ec5c5346d4ef48d1279343ee.bin new file mode 100644 index 0000000..d8071f4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-deffc3c5ec5c5346d4ef48d1279343ee.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-df13335d38bec066745824c6a64d5add.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-df13335d38bec066745824c6a64d5add.bin new file mode 100644 index 0000000..72bd50c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-df13335d38bec066745824c6a64d5add.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfb0c6fd721d3738cb6e541f325cd772.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfb0c6fd721d3738cb6e541f325cd772.bin new file mode 100644 index 0000000..1af9976 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfb0c6fd721d3738cb6e541f325cd772.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfc2e88b439b28e8fcb79c70100eb3bf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfc2e88b439b28e8fcb79c70100eb3bf.bin new file mode 100644 index 0000000..3a2d172 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-dfc2e88b439b28e8fcb79c70100eb3bf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e073f66e67eca9cc1d002da82f2e006d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e073f66e67eca9cc1d002da82f2e006d.bin new file mode 100644 index 0000000..ff47295 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e073f66e67eca9cc1d002da82f2e006d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e0bb01fe00d35511fa52d55968b72700.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e0bb01fe00d35511fa52d55968b72700.bin new file mode 100644 index 0000000..6f953c6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e0bb01fe00d35511fa52d55968b72700.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e12f90e566ff054cae0b9310aaf5c434.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e12f90e566ff054cae0b9310aaf5c434.bin new file mode 100644 index 0000000..8c2d1ad Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e12f90e566ff054cae0b9310aaf5c434.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e18def0394c32f20d9b696e0e3636c7c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e18def0394c32f20d9b696e0e3636c7c.bin new file mode 100644 index 0000000..5908fa5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e18def0394c32f20d9b696e0e3636c7c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e202ece1280c3cb61908a99fdab10132.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e202ece1280c3cb61908a99fdab10132.bin new file mode 100644 index 0000000..d378ec0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e202ece1280c3cb61908a99fdab10132.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e246dfdd3e51e1a8f4bab910f9906957.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e246dfdd3e51e1a8f4bab910f9906957.bin new file mode 100644 index 0000000..c7a251a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e246dfdd3e51e1a8f4bab910f9906957.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2579d8b6d48e7923a3e96240796ec1f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2579d8b6d48e7923a3e96240796ec1f.bin new file mode 100644 index 0000000..a57a7fa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2579d8b6d48e7923a3e96240796ec1f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2dc83ee62f6115ef75d8a77c92a6c83.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2dc83ee62f6115ef75d8a77c92a6c83.bin new file mode 100644 index 0000000..4f64122 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e2dc83ee62f6115ef75d8a77c92a6c83.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e3cd43c3c55a2329d6df132672e5ff9e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e3cd43c3c55a2329d6df132672e5ff9e.bin new file mode 100644 index 0000000..53e4dc6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e3cd43c3c55a2329d6df132672e5ff9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e45496ee408c333a77587028aaaec539.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e45496ee408c333a77587028aaaec539.bin new file mode 100644 index 0000000..5c04fb9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e45496ee408c333a77587028aaaec539.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e538df66d0cfd216e4afcc3d46ea92dd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e538df66d0cfd216e4afcc3d46ea92dd.bin new file mode 100644 index 0000000..79e5770 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e538df66d0cfd216e4afcc3d46ea92dd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e59e9916e8835438dcf417328deb57a2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e59e9916e8835438dcf417328deb57a2.bin new file mode 100644 index 0000000..7abc9bf Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e59e9916e8835438dcf417328deb57a2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6a7cf2c711cdcab0ff40c9d170ff3a6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6a7cf2c711cdcab0ff40c9d170ff3a6.bin new file mode 100644 index 0000000..3ca5d80 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6a7cf2c711cdcab0ff40c9d170ff3a6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6d8725812988c5a19b0aa59a04a1d52.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6d8725812988c5a19b0aa59a04a1d52.bin new file mode 100644 index 0000000..20e0cba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e6d8725812988c5a19b0aa59a04a1d52.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e72816ad12d4c23ff2e4ef011cf85117.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e72816ad12d4c23ff2e4ef011cf85117.bin new file mode 100644 index 0000000..9af89ac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e72816ad12d4c23ff2e4ef011cf85117.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e77b62a63e76418699b1149e105cc401.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e77b62a63e76418699b1149e105cc401.bin new file mode 100644 index 0000000..78b14f1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e77b62a63e76418699b1149e105cc401.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7912eea126bca4663a18a7b3bbee2d7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7912eea126bca4663a18a7b3bbee2d7.bin new file mode 100644 index 0000000..29e6ce5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7912eea126bca4663a18a7b3bbee2d7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7954205b2c68a7ba5508c241f399dba.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7954205b2c68a7ba5508c241f399dba.bin new file mode 100644 index 0000000..2e5f7b9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e7954205b2c68a7ba5508c241f399dba.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8077d134f7c18bc2d74d89518187992.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8077d134f7c18bc2d74d89518187992.bin new file mode 100644 index 0000000..818dc03 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8077d134f7c18bc2d74d89518187992.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8866c378b51b2b3343653cc4bd0f19e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8866c378b51b2b3343653cc4bd0f19e.bin new file mode 100644 index 0000000..788f4e8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e8866c378b51b2b3343653cc4bd0f19e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e93b6470f79ef3cfbd0b6aabbb0c3c38.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e93b6470f79ef3cfbd0b6aabbb0c3c38.bin new file mode 100644 index 0000000..449f1fc Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-e93b6470f79ef3cfbd0b6aabbb0c3c38.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ea62cbc307490ab4d12b452477db80e4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ea62cbc307490ab4d12b452477db80e4.bin new file mode 100644 index 0000000..30a4a53 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ea62cbc307490ab4d12b452477db80e4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ead5a5118a3ec44fe1bb9d80dd854dff.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ead5a5118a3ec44fe1bb9d80dd854dff.bin new file mode 100644 index 0000000..0def8b7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ead5a5118a3ec44fe1bb9d80dd854dff.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eadffe9bb4d4643da0a1847c96c51a3b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eadffe9bb4d4643da0a1847c96c51a3b.bin new file mode 100644 index 0000000..2c8af8f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eadffe9bb4d4643da0a1847c96c51a3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb0b422705ea61e14afdb4a176bb7aac.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb0b422705ea61e14afdb4a176bb7aac.bin new file mode 100644 index 0000000..e1bbfca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb0b422705ea61e14afdb4a176bb7aac.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb38fd8547b3116df17b5f36cc1a4edd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb38fd8547b3116df17b5f36cc1a4edd.bin new file mode 100644 index 0000000..2da0840 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eb38fd8547b3116df17b5f36cc1a4edd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eba0d9132f360ba169cd0ffddda2395f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eba0d9132f360ba169cd0ffddda2395f.bin new file mode 100644 index 0000000..ef8290e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eba0d9132f360ba169cd0ffddda2395f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ebb07c81c6fb8ec057bf55d8497ee1b3.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ebb07c81c6fb8ec057bf55d8497ee1b3.bin new file mode 100644 index 0000000..5f03996 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ebb07c81c6fb8ec057bf55d8497ee1b3.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ede79817b7df5ff54d39caaae0c9530e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ede79817b7df5ff54d39caaae0c9530e.bin new file mode 100644 index 0000000..278cfd2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ede79817b7df5ff54d39caaae0c9530e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edead2cb8f5ec12964d1cd9a907a66e0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edead2cb8f5ec12964d1cd9a907a66e0.bin new file mode 100644 index 0000000..ad6d870 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edead2cb8f5ec12964d1cd9a907a66e0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edf88acb5401345d49f90fb6f70ad41f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edf88acb5401345d49f90fb6f70ad41f.bin new file mode 100644 index 0000000..ba18774 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-edf88acb5401345d49f90fb6f70ad41f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eead9e9f2ec9047dccdb6af7c0ec3912.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eead9e9f2ec9047dccdb6af7c0ec3912.bin new file mode 100644 index 0000000..8de2b9c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eead9e9f2ec9047dccdb6af7c0ec3912.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eefa0b0135fc41e89d9eb790fd90c17a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eefa0b0135fc41e89d9eb790fd90c17a.bin new file mode 100644 index 0000000..c3543ac Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-eefa0b0135fc41e89d9eb790fd90c17a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ef073d4ba0620d36f55d459f7a0b3c87.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ef073d4ba0620d36f55d459f7a0b3c87.bin new file mode 100644 index 0000000..0387189 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-ef073d4ba0620d36f55d459f7a0b3c87.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-efd6353bec6489cc2521fbb48d86b5ff.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-efd6353bec6489cc2521fbb48d86b5ff.bin new file mode 100644 index 0000000..ca7f79e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-efd6353bec6489cc2521fbb48d86b5ff.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f023b17f18bd4243d0570dc20c3128f5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f023b17f18bd4243d0570dc20c3128f5.bin new file mode 100644 index 0000000..607d2a9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f023b17f18bd4243d0570dc20c3128f5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f08a8bb321013d66c4be788bde76003e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f08a8bb321013d66c4be788bde76003e.bin new file mode 100644 index 0000000..6bdb860 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f08a8bb321013d66c4be788bde76003e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f0d7ef3ae493f903553f98fa0bda9fdd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f0d7ef3ae493f903553f98fa0bda9fdd.bin new file mode 100644 index 0000000..e6531cd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f0d7ef3ae493f903553f98fa0bda9fdd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f144712faef2f38ebd606cfba7cfcd9e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f144712faef2f38ebd606cfba7cfcd9e.bin new file mode 100644 index 0000000..245c151 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f144712faef2f38ebd606cfba7cfcd9e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f1cb13e507489b8e1eb4b48020a3a609.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f1cb13e507489b8e1eb4b48020a3a609.bin new file mode 100644 index 0000000..88aaf0a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f1cb13e507489b8e1eb4b48020a3a609.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f29c395d49ae266f87143d06a141b12d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f29c395d49ae266f87143d06a141b12d.bin new file mode 100644 index 0000000..3555e09 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f29c395d49ae266f87143d06a141b12d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f31b71ae287118bccc69d39e64aec271.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f31b71ae287118bccc69d39e64aec271.bin new file mode 100644 index 0000000..f20b6a8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f31b71ae287118bccc69d39e64aec271.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f35200f8bf4362348688bb477ddbcf2b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f35200f8bf4362348688bb477ddbcf2b.bin new file mode 100644 index 0000000..69a2296 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f35200f8bf4362348688bb477ddbcf2b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f40d0e8e58dabbd62591f5e23c17db1f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f40d0e8e58dabbd62591f5e23c17db1f.bin new file mode 100644 index 0000000..3a72eae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f40d0e8e58dabbd62591f5e23c17db1f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f44a117a40b4780afd4e1d51b01ed645.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f44a117a40b4780afd4e1d51b01ed645.bin new file mode 100644 index 0000000..f3e72d8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f44a117a40b4780afd4e1d51b01ed645.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f532c3afca5bcb90901c3c9d65570bdc.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f532c3afca5bcb90901c3c9d65570bdc.bin new file mode 100644 index 0000000..4eebaa4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f532c3afca5bcb90901c3c9d65570bdc.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f5d2cccd3211674162ce90a3ffec9621.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f5d2cccd3211674162ce90a3ffec9621.bin new file mode 100644 index 0000000..412addd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f5d2cccd3211674162ce90a3ffec9621.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f62427f51f2f78f66910a21b64a28427.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f62427f51f2f78f66910a21b64a28427.bin new file mode 100644 index 0000000..259f56d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f62427f51f2f78f66910a21b64a28427.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67bef93f1022c6267c1ae23a2f5179d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67bef93f1022c6267c1ae23a2f5179d.bin new file mode 100644 index 0000000..dd43335 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67bef93f1022c6267c1ae23a2f5179d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67fb604133c1b793f94fec6eea2e94f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67fb604133c1b793f94fec6eea2e94f.bin new file mode 100644 index 0000000..71b2273 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f67fb604133c1b793f94fec6eea2e94f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f71ad6a3dc0481f386ab4585135ee266.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f71ad6a3dc0481f386ab4585135ee266.bin new file mode 100644 index 0000000..193b712 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f71ad6a3dc0481f386ab4585135ee266.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f84e750002cfc1caf72c8199b4c78e71.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f84e750002cfc1caf72c8199b4c78e71.bin new file mode 100644 index 0000000..744faab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f84e750002cfc1caf72c8199b4c78e71.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f877065d61e3a4b978d125dc72b9d4fe.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f877065d61e3a4b978d125dc72b9d4fe.bin new file mode 100644 index 0000000..f420f03 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f877065d61e3a4b978d125dc72b9d4fe.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f88e48eaffae7215fd4fb5a51e3c4a5e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f88e48eaffae7215fd4fb5a51e3c4a5e.bin new file mode 100644 index 0000000..c923299 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f88e48eaffae7215fd4fb5a51e3c4a5e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f94b89313e984302e830cfe865ce6eed.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f94b89313e984302e830cfe865ce6eed.bin new file mode 100644 index 0000000..5d33525 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f94b89313e984302e830cfe865ce6eed.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f9a9ee73851b2b08d167458f29fe4fdb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f9a9ee73851b2b08d167458f29fe4fdb.bin new file mode 100644 index 0000000..662c34a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-f9a9ee73851b2b08d167458f29fe4fdb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbab58856334bd8436ba604a72dce33b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbab58856334bd8436ba604a72dce33b.bin new file mode 100644 index 0000000..b1e719d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbab58856334bd8436ba604a72dce33b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbcbe83fe224d123de8ce0fc5b0fa0eb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbcbe83fe224d123de8ce0fc5b0fa0eb.bin new file mode 100644 index 0000000..cf44d00 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbcbe83fe224d123de8ce0fc5b0fa0eb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbd640e6254902e0d4c644004ff7d076.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbd640e6254902e0d4c644004ff7d076.bin new file mode 100644 index 0000000..a92e46d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fbd640e6254902e0d4c644004ff7d076.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc671adbcffcb68939665765db0f405a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc671adbcffcb68939665765db0f405a.bin new file mode 100644 index 0000000..fd047e0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc671adbcffcb68939665765db0f405a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc6afcdfd639d530e079202c0f50c238.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc6afcdfd639d530e079202c0f50c238.bin new file mode 100644 index 0000000..b53a986 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fc6afcdfd639d530e079202c0f50c238.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fca11b98fe945c54a7cee94f191b9182.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fca11b98fe945c54a7cee94f191b9182.bin new file mode 100644 index 0000000..cf8e612 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fca11b98fe945c54a7cee94f191b9182.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fd3cc68651fc82b9e8711e59437ef78e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fd3cc68651fc82b9e8711e59437ef78e.bin new file mode 100644 index 0000000..9379653 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fd3cc68651fc82b9e8711e59437ef78e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fecefd725eb3bdadc77c1c251f217197.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fecefd725eb3bdadc77c1c251f217197.bin new file mode 100644 index 0000000..aea133f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_1.1.1.0_8ab6d92f-fecefd725eb3bdadc77c1c251f217197.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-021646496fb9d560cd885bfd94f6b334.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-021646496fb9d560cd885bfd94f6b334.bin new file mode 100644 index 0000000..6e7aeab Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-021646496fb9d560cd885bfd94f6b334.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-068e5c469435fcf888e17dd5bd04848c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-068e5c469435fcf888e17dd5bd04848c.bin new file mode 100644 index 0000000..c9b7f53 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-068e5c469435fcf888e17dd5bd04848c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-07a0743d098993a1ccc2750f9c7dff6d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-07a0743d098993a1ccc2750f9c7dff6d.bin new file mode 100644 index 0000000..2af28c4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-07a0743d098993a1ccc2750f9c7dff6d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-088751c0bccc5509be4fbb82c2205982.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-088751c0bccc5509be4fbb82c2205982.bin new file mode 100644 index 0000000..c2ef08c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-088751c0bccc5509be4fbb82c2205982.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-08a134a251b99ba9ac63d743aabea51a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-08a134a251b99ba9ac63d743aabea51a.bin new file mode 100644 index 0000000..d626635 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-08a134a251b99ba9ac63d743aabea51a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-09533ee54dad40e3969a4d7c7f61e774.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-09533ee54dad40e3969a4d7c7f61e774.bin new file mode 100644 index 0000000..e987e1a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-09533ee54dad40e3969a4d7c7f61e774.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-0f3411ee652c984a34a9c1bab42bbc82.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-0f3411ee652c984a34a9c1bab42bbc82.bin new file mode 100644 index 0000000..0aba0e0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-0f3411ee652c984a34a9c1bab42bbc82.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-103a8ee850911c748bb4deea502e03ac.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-103a8ee850911c748bb4deea502e03ac.bin new file mode 100644 index 0000000..06d41d1 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-103a8ee850911c748bb4deea502e03ac.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-10dfbbbf2349a1233b8d0dd4ae12af0b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-10dfbbbf2349a1233b8d0dd4ae12af0b.bin new file mode 100644 index 0000000..6c36949 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-10dfbbbf2349a1233b8d0dd4ae12af0b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-11f9832e08a6cfdbb799e7647250e147.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-11f9832e08a6cfdbb799e7647250e147.bin new file mode 100644 index 0000000..8187102 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-11f9832e08a6cfdbb799e7647250e147.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1267144f1a7d53aa01f39fb0e44f7558.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1267144f1a7d53aa01f39fb0e44f7558.bin new file mode 100644 index 0000000..34ab391 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1267144f1a7d53aa01f39fb0e44f7558.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-13fd4a93fa51bb5fb3156d8d752be357.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-13fd4a93fa51bb5fb3156d8d752be357.bin new file mode 100644 index 0000000..c8f1091 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-13fd4a93fa51bb5fb3156d8d752be357.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-17411d1d8253d380e4374d5a550ee321.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-17411d1d8253d380e4374d5a550ee321.bin new file mode 100644 index 0000000..7411176 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-17411d1d8253d380e4374d5a550ee321.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1a08166b037d15d02d51fbabf3acbbf5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1a08166b037d15d02d51fbabf3acbbf5.bin new file mode 100644 index 0000000..d133fae Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1a08166b037d15d02d51fbabf3acbbf5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1eb473f234f1c22cf43f32e065885faa.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1eb473f234f1c22cf43f32e065885faa.bin new file mode 100644 index 0000000..1e081e8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-1eb473f234f1c22cf43f32e065885faa.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-255a60212629afecc0a79c757657f4f2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-255a60212629afecc0a79c757657f4f2.bin new file mode 100644 index 0000000..23c547b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-255a60212629afecc0a79c757657f4f2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-260541538dd77f834f9fced985c08e24.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-260541538dd77f834f9fced985c08e24.bin new file mode 100644 index 0000000..4014cd9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-260541538dd77f834f9fced985c08e24.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2acdfc53cc8d436fcce3b7f17f4a72e8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2acdfc53cc8d436fcce3b7f17f4a72e8.bin new file mode 100644 index 0000000..22a5fbd Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2acdfc53cc8d436fcce3b7f17f4a72e8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2d3d5947a39f7c7963f5f40b52a562e6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2d3d5947a39f7c7963f5f40b52a562e6.bin new file mode 100644 index 0000000..ec513aa Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-2d3d5947a39f7c7963f5f40b52a562e6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-30d484dd48dc167d28050c63504215e6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-30d484dd48dc167d28050c63504215e6.bin new file mode 100644 index 0000000..2435489 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-30d484dd48dc167d28050c63504215e6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-328be55477afb25199b32f4a76b5448f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-328be55477afb25199b32f4a76b5448f.bin new file mode 100644 index 0000000..7ef6da7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-328be55477afb25199b32f4a76b5448f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-32c1d759f419b8c3882ff6205f290a7e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-32c1d759f419b8c3882ff6205f290a7e.bin new file mode 100644 index 0000000..ca5da79 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-32c1d759f419b8c3882ff6205f290a7e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-349046d404a8add34da74ab3cda24199.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-349046d404a8add34da74ab3cda24199.bin new file mode 100644 index 0000000..6925ebb Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-349046d404a8add34da74ab3cda24199.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-365e2c4e50d947a5d5598a1feb3176c0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-365e2c4e50d947a5d5598a1feb3176c0.bin new file mode 100644 index 0000000..ed78b8c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-365e2c4e50d947a5d5598a1feb3176c0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-37cc975508c7df5096e3e2f9c3cef850.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-37cc975508c7df5096e3e2f9c3cef850.bin new file mode 100644 index 0000000..82499a3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-37cc975508c7df5096e3e2f9c3cef850.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3956c7ab63cd15556c96931ee92d8324.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3956c7ab63cd15556c96931ee92d8324.bin new file mode 100644 index 0000000..87f3609 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3956c7ab63cd15556c96931ee92d8324.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3ef509b4b5972bf5c3874092fe8a556e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3ef509b4b5972bf5c3874092fe8a556e.bin new file mode 100644 index 0000000..bf656ea Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3ef509b4b5972bf5c3874092fe8a556e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3f88258a1480a838e1952ac9c2ceed36.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3f88258a1480a838e1952ac9c2ceed36.bin new file mode 100644 index 0000000..9fc7134 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3f88258a1480a838e1952ac9c2ceed36.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3fe9eaa5a3c6ae15e9f81428617ea0c2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3fe9eaa5a3c6ae15e9f81428617ea0c2.bin new file mode 100644 index 0000000..2e30a31 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-3fe9eaa5a3c6ae15e9f81428617ea0c2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-425e4c6388d6479e785aeb819aebae96.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-425e4c6388d6479e785aeb819aebae96.bin new file mode 100644 index 0000000..ae17d0e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-425e4c6388d6479e785aeb819aebae96.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-46f4d5b3bcf61e4d5a8c4c40d1a6ff66.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-46f4d5b3bcf61e4d5a8c4c40d1a6ff66.bin new file mode 100644 index 0000000..5602379 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-46f4d5b3bcf61e4d5a8c4c40d1a6ff66.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-487e828561eb0b86d5968e82d06de89f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-487e828561eb0b86d5968e82d06de89f.bin new file mode 100644 index 0000000..a90fa83 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-487e828561eb0b86d5968e82d06de89f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-489b162431deba441dda85f18f1276ab.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-489b162431deba441dda85f18f1276ab.bin new file mode 100644 index 0000000..1aa4283 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-489b162431deba441dda85f18f1276ab.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-49ad0c1218ab876b0e292f93ea9ed4a2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-49ad0c1218ab876b0e292f93ea9ed4a2.bin new file mode 100644 index 0000000..40bf400 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-49ad0c1218ab876b0e292f93ea9ed4a2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4b7341ea5cc3a5877e0f97168c166d6e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4b7341ea5cc3a5877e0f97168c166d6e.bin new file mode 100644 index 0000000..0520f9e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4b7341ea5cc3a5877e0f97168c166d6e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4d107283eba251fea025a833225af512.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4d107283eba251fea025a833225af512.bin new file mode 100644 index 0000000..bb87b62 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-4d107283eba251fea025a833225af512.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-51b02cdaff7ae1cddc4465c8b78782ee.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-51b02cdaff7ae1cddc4465c8b78782ee.bin new file mode 100644 index 0000000..c02476c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-51b02cdaff7ae1cddc4465c8b78782ee.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5434c771c2558813d9e1994b8cc10e86.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5434c771c2558813d9e1994b8cc10e86.bin new file mode 100644 index 0000000..54d2a5e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5434c771c2558813d9e1994b8cc10e86.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-55c4184585acae11acbbc1202136390a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-55c4184585acae11acbbc1202136390a.bin new file mode 100644 index 0000000..3ef9da9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-55c4184585acae11acbbc1202136390a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5780543c1b837b9ea82fbb2b41b8833c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5780543c1b837b9ea82fbb2b41b8833c.bin new file mode 100644 index 0000000..b5f243b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5780543c1b837b9ea82fbb2b41b8833c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-587484e01ac23761d733aed206192506.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-587484e01ac23761d733aed206192506.bin new file mode 100644 index 0000000..f39a9ba Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-587484e01ac23761d733aed206192506.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5a7c48a4baa1d4c4fbcd4c43ad1e960e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5a7c48a4baa1d4c4fbcd4c43ad1e960e.bin new file mode 100644 index 0000000..1bee240 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5a7c48a4baa1d4c4fbcd4c43ad1e960e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ae92bcf77eccd197a98c7c3c8cbfcf6.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ae92bcf77eccd197a98c7c3c8cbfcf6.bin new file mode 100644 index 0000000..76ac9f8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ae92bcf77eccd197a98c7c3c8cbfcf6.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5b14983e01ef9c371638021d1294f577.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5b14983e01ef9c371638021d1294f577.bin new file mode 100644 index 0000000..66aeb51 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5b14983e01ef9c371638021d1294f577.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5bc23f10f1f019581020ddbfda21924f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5bc23f10f1f019581020ddbfda21924f.bin new file mode 100644 index 0000000..dc0b658 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5bc23f10f1f019581020ddbfda21924f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5dcec9e1b58a65931d3f69535dccfaa9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5dcec9e1b58a65931d3f69535dccfaa9.bin new file mode 100644 index 0000000..81b0560 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5dcec9e1b58a65931d3f69535dccfaa9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5e6cb59fa83d105ae780ac80aabda073.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5e6cb59fa83d105ae780ac80aabda073.bin new file mode 100644 index 0000000..f3d12a7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5e6cb59fa83d105ae780ac80aabda073.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ff849bc1565d152563da04cfb737ef7.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ff849bc1565d152563da04cfb737ef7.bin new file mode 100644 index 0000000..0d14214 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-5ff849bc1565d152563da04cfb737ef7.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6c4addd0e388e33c9d05e0e7c797921b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6c4addd0e388e33c9d05e0e7c797921b.bin new file mode 100644 index 0000000..ab219d8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6c4addd0e388e33c9d05e0e7c797921b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6d7c798e938601df9657b6494e6d4693.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6d7c798e938601df9657b6494e6d4693.bin new file mode 100644 index 0000000..bc3659b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6d7c798e938601df9657b6494e6d4693.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6e2f3142bdd9fb50d5d9268cb0f67493.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6e2f3142bdd9fb50d5d9268cb0f67493.bin new file mode 100644 index 0000000..ae586f9 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6e2f3142bdd9fb50d5d9268cb0f67493.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6fb607a108c3b300df244b9a2dadac8b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6fb607a108c3b300df244b9a2dadac8b.bin new file mode 100644 index 0000000..e692757 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-6fb607a108c3b300df244b9a2dadac8b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-714fd97b8fd13d7b43df72d8cb9a289d.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-714fd97b8fd13d7b43df72d8cb9a289d.bin new file mode 100644 index 0000000..bf83b4e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-714fd97b8fd13d7b43df72d8cb9a289d.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-722a57db969dabc110e7c7f3d60db2e5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-722a57db969dabc110e7c7f3d60db2e5.bin new file mode 100644 index 0000000..77bda55 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-722a57db969dabc110e7c7f3d60db2e5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-740eb24bc1019b73f0dc76c5b8ec302e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-740eb24bc1019b73f0dc76c5b8ec302e.bin new file mode 100644 index 0000000..0ddb5ca Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-740eb24bc1019b73f0dc76c5b8ec302e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-75ee4667cb7b4658c05fd769dddc7707.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-75ee4667cb7b4658c05fd769dddc7707.bin new file mode 100644 index 0000000..d94f76d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-75ee4667cb7b4658c05fd769dddc7707.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-78c433f4c2a06bc4f60f9052843ad305.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-78c433f4c2a06bc4f60f9052843ad305.bin new file mode 100644 index 0000000..afee03c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-78c433f4c2a06bc4f60f9052843ad305.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-7f38f54a5520fe1f29125060a71194c0.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-7f38f54a5520fe1f29125060a71194c0.bin new file mode 100644 index 0000000..58c3a3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-7f38f54a5520fe1f29125060a71194c0.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-839aadc6d80049ee1f950bd095a1ba8b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-839aadc6d80049ee1f950bd095a1ba8b.bin new file mode 100644 index 0000000..38ebbf6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-839aadc6d80049ee1f950bd095a1ba8b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-85913f7a4da20762e34194a22939acb9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-85913f7a4da20762e34194a22939acb9.bin new file mode 100644 index 0000000..b73097b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-85913f7a4da20762e34194a22939acb9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8598a95ec5900a7091a37c9a942c0693.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8598a95ec5900a7091a37c9a942c0693.bin new file mode 100644 index 0000000..02070d8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8598a95ec5900a7091a37c9a942c0693.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-874afb86576df8fe12321ec29d832584.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-874afb86576df8fe12321ec29d832584.bin new file mode 100644 index 0000000..cbcdc43 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-874afb86576df8fe12321ec29d832584.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-87cca14e813d686d62f7a355b6df84e2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-87cca14e813d686d62f7a355b6df84e2.bin new file mode 100644 index 0000000..4bee4c8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-87cca14e813d686d62f7a355b6df84e2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-88573c3cea88fc1658530233238a5c0b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-88573c3cea88fc1658530233238a5c0b.bin new file mode 100644 index 0000000..08eea13 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-88573c3cea88fc1658530233238a5c0b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8c547acb96b73bc953407aad654a323b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8c547acb96b73bc953407aad654a323b.bin new file mode 100644 index 0000000..20c64c3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8c547acb96b73bc953407aad654a323b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8cdc9fc30804f4229630d41b61e8a745.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8cdc9fc30804f4229630d41b61e8a745.bin new file mode 100644 index 0000000..5831ad8 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8cdc9fc30804f4229630d41b61e8a745.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8de5d234d6383ee2258170eb7b939774.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8de5d234d6383ee2258170eb7b939774.bin new file mode 100644 index 0000000..ed9d490 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-8de5d234d6383ee2258170eb7b939774.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-934ae611ffc7baa8284d887bfaebe70a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-934ae611ffc7baa8284d887bfaebe70a.bin new file mode 100644 index 0000000..6939e5d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-934ae611ffc7baa8284d887bfaebe70a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-93eeb36101476c02cdf29848a1810388.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-93eeb36101476c02cdf29848a1810388.bin new file mode 100644 index 0000000..a7cd72e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-93eeb36101476c02cdf29848a1810388.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-964536763d7f77741f38391328a71fdb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-964536763d7f77741f38391328a71fdb.bin new file mode 100644 index 0000000..0e611e4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-964536763d7f77741f38391328a71fdb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9809310c18e8f9781106907c62106ae4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9809310c18e8f9781106907c62106ae4.bin new file mode 100644 index 0000000..bb3f25e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9809310c18e8f9781106907c62106ae4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9910ef7b24d01e90c2630e489c60aeb4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9910ef7b24d01e90c2630e489c60aeb4.bin new file mode 100644 index 0000000..926b05c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9910ef7b24d01e90c2630e489c60aeb4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9b96c2500e59007b56596657f3404abf.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9b96c2500e59007b56596657f3404abf.bin new file mode 100644 index 0000000..da9921a Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9b96c2500e59007b56596657f3404abf.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9e72e83b8cde6da9d8b9a638fbc03f23.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9e72e83b8cde6da9d8b9a638fbc03f23.bin new file mode 100644 index 0000000..97f1485 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-9e72e83b8cde6da9d8b9a638fbc03f23.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a616f024e09a9b02e1de42df47cd36be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a616f024e09a9b02e1de42df47cd36be.bin new file mode 100644 index 0000000..bf8132e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a616f024e09a9b02e1de42df47cd36be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a74068f44d97e44278bca53e4e0855eb.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a74068f44d97e44278bca53e4e0855eb.bin new file mode 100644 index 0000000..d7b2c28 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a74068f44d97e44278bca53e4e0855eb.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a80b5c64b61fd6cbbea7981da2074fb8.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a80b5c64b61fd6cbbea7981da2074fb8.bin new file mode 100644 index 0000000..77e84c5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-a80b5c64b61fd6cbbea7981da2074fb8.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b2677920eea70d93f3ebc0829e1a870a.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b2677920eea70d93f3ebc0829e1a870a.bin new file mode 100644 index 0000000..74d7750 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b2677920eea70d93f3ebc0829e1a870a.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b334541c073bc7aebdf00d7d1a4ebf3b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b334541c073bc7aebdf00d7d1a4ebf3b.bin new file mode 100644 index 0000000..c08f3d4 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b334541c073bc7aebdf00d7d1a4ebf3b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b4a87f8a9cf2291f2f67f51cd88c5256.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b4a87f8a9cf2291f2f67f51cd88c5256.bin new file mode 100644 index 0000000..77e88da Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b4a87f8a9cf2291f2f67f51cd88c5256.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b51602df746e426b81ff0c14d220d2d5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b51602df746e426b81ff0c14d220d2d5.bin new file mode 100644 index 0000000..14e0420 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b51602df746e426b81ff0c14d220d2d5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7b66ebf31faaf185c1ac1b1db0cce37.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7b66ebf31faaf185c1ac1b1db0cce37.bin new file mode 100644 index 0000000..6cc16b2 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7b66ebf31faaf185c1ac1b1db0cce37.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7fc5edb8d4a7ed8ae1da1091db032cd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7fc5edb8d4a7ed8ae1da1091db032cd.bin new file mode 100644 index 0000000..a86bd3f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-b7fc5edb8d4a7ed8ae1da1091db032cd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c1548bf5261bd2c7641de398dfee254c.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c1548bf5261bd2c7641de398dfee254c.bin new file mode 100644 index 0000000..49c2915 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c1548bf5261bd2c7641de398dfee254c.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c21b09d9a2b65afcd0ec816c083738da.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c21b09d9a2b65afcd0ec816c083738da.bin new file mode 100644 index 0000000..b4bdc81 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c21b09d9a2b65afcd0ec816c083738da.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c27a90ebfb0f830115055c24059f3eec.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c27a90ebfb0f830115055c24059f3eec.bin new file mode 100644 index 0000000..83af836 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c27a90ebfb0f830115055c24059f3eec.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c294e1ecf36c8e9deea3ec43ee708abd.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c294e1ecf36c8e9deea3ec43ee708abd.bin new file mode 100644 index 0000000..c58b863 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c294e1ecf36c8e9deea3ec43ee708abd.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c496a9ca210731d86c2db5c40593eec9.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c496a9ca210731d86c2db5c40593eec9.bin new file mode 100644 index 0000000..61a40a5 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c496a9ca210731d86c2db5c40593eec9.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c604b4bed7b65a6327de13edccacfd9f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c604b4bed7b65a6327de13edccacfd9f.bin new file mode 100644 index 0000000..0b911b3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c604b4bed7b65a6327de13edccacfd9f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c83025a1bb76b0bce4d14a2f54d0a189.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c83025a1bb76b0bce4d14a2f54d0a189.bin new file mode 100644 index 0000000..c8514d6 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-c83025a1bb76b0bce4d14a2f54d0a189.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-cd658187b698d4d9a8b1c0a14a9f3f4f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-cd658187b698d4d9a8b1c0a14a9f3f4f.bin new file mode 100644 index 0000000..e08742d Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-cd658187b698d4d9a8b1c0a14a9f3f4f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d216c251e350dc417f5de358a0d56f66.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d216c251e350dc417f5de358a0d56f66.bin new file mode 100644 index 0000000..255f5df Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d216c251e350dc417f5de358a0d56f66.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d5f041cf70c24a682ed41dc88b635cda.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d5f041cf70c24a682ed41dc88b635cda.bin new file mode 100644 index 0000000..15d0086 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d5f041cf70c24a682ed41dc88b635cda.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d81b64dea823ece1e88e128595bf623e.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d81b64dea823ece1e88e128595bf623e.bin new file mode 100644 index 0000000..950a6de Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d81b64dea823ece1e88e128595bf623e.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d93f5e336aee5eab2a64a90b41b8d703.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d93f5e336aee5eab2a64a90b41b8d703.bin new file mode 100644 index 0000000..afb2b0e Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-d93f5e336aee5eab2a64a90b41b8d703.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dafb5893e5af800c5b47dad0df3e6ea2.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dafb5893e5af800c5b47dad0df3e6ea2.bin new file mode 100644 index 0000000..5988f12 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dafb5893e5af800c5b47dad0df3e6ea2.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfa44c04f7480584dbc430a0e581b6f4.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfa44c04f7480584dbc430a0e581b6f4.bin new file mode 100644 index 0000000..55969c7 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfa44c04f7480584dbc430a0e581b6f4.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfe34411b5135138b4d36f99bf21cd66.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfe34411b5135138b4d36f99bf21cd66.bin new file mode 100644 index 0000000..5e5da98 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-dfe34411b5135138b4d36f99bf21cd66.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-e80e35e6954ba7d71879244a2b82014b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-e80e35e6954ba7d71879244a2b82014b.bin new file mode 100644 index 0000000..6da0336 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-e80e35e6954ba7d71879244a2b82014b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ea219cf1cbcc1248b35e40d22b224006.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ea219cf1cbcc1248b35e40d22b224006.bin new file mode 100644 index 0000000..9d4dba0 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ea219cf1cbcc1248b35e40d22b224006.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-edc20f500383bdb3a07f3af7e72d719b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-edc20f500383bdb3a07f3af7e72d719b.bin new file mode 100644 index 0000000..432a30b Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-edc20f500383bdb3a07f3af7e72d719b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f00c0ab5c822a2373ca3f0e20a4b730f.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f00c0ab5c822a2373ca3f0e20a4b730f.bin new file mode 100644 index 0000000..2167f88 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f00c0ab5c822a2373ca3f0e20a4b730f.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f0f3a4a90dd6498f0ff691602c6e2aa5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f0f3a4a90dd6498f0ff691602c6e2aa5.bin new file mode 100644 index 0000000..953fe49 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f0f3a4a90dd6498f0ff691602c6e2aa5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f6be61310f11bd634683388fe6c9c52b.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f6be61310f11bd634683388fe6c9c52b.bin new file mode 100644 index 0000000..989300c Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f6be61310f11bd634683388fe6c9c52b.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f723664ccf0bd4a031ffb520f1f818d5.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f723664ccf0bd4a031ffb520f1f818d5.bin new file mode 100644 index 0000000..dc394d3 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f723664ccf0bd4a031ffb520f1f818d5.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f9abe37764cb0909a2dfc92af25ee5be.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f9abe37764cb0909a2dfc92af25ee5be.bin new file mode 100644 index 0000000..b2e7543 Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-f9abe37764cb0909a2dfc92af25ee5be.bin differ diff --git a/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ffe5e773c59ed49d6f630cf69cde3d53.bin b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ffe5e773c59ed49d6f630cf69cde3d53.bin new file mode 100644 index 0000000..c30d79f Binary files /dev/null and b/board/evb/findmy/mdk/bin/app_MP_findmy_6.5.5.0_8ab6d92f-ffe5e773c59ed49d6f630cf69cde3d53.bin differ diff --git a/board/evb/findmy/mdk/findmy.uvguix.Administrator b/board/evb/findmy/mdk/findmy.uvguix.Administrator new file mode 100644 index 0000000..806435f --- /dev/null +++ b/board/evb/findmy/mdk/findmy.uvguix.Administrator @@ -0,0 +1,1909 @@ + + + + -6.1 + +
    ### uVision Project, (C) Keil Software
    + + + C:\Users\Administrator\Desktop\Realtek_findmy_final_pakege\src\ble\profile\server + + + + + + + 38003 + Registers + 188 122 + + + 346 + Code Coverage + 1410 160 + + + 204 + Performance Analyzer + 1570 + + + + + + 35141 + Event Statistics + + 200 50 700 + + + 1506 + Symbols + + 106 106 106 + + + 1936 + Watch 1 + + 200 133 133 + + + 1937 + Watch 2 + + 200 133 133 + + + 1935 + Call Stack + Locals + + 200 133 133 + + + 2506 + Trace Data + + 75 135 130 95 70 230 200 150 + + + 466 + Source Browser + 500 + 300 + + + + + + + + 1 + 1 + 0 + 0 + -1 + + + + + + + 44 + 2 + 3 + + -32000 + -32000 + + + -1 + -1 + + + 30 + -2462 + -542 + 1085 + + + + 0 + + 778 + 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000100000028000000280000000200000003000000020000000000000058433A5C55736572735C41646D696E6973747261746F725C4465736B746F705C5265616C74656B5F66696E646D795F66696E616C5F70616B6567655F335C7372635C6170705C66696E646D795C66696E646D795F6170702E63000000000C66696E646D795F6170702E6301000000C5D4F200FFFFFFFF6E433A5C55736572735C41646D696E6973747261746F725C4465736B746F705C5265616C74656B5F66696E646D795F66696E616C5F70616B6567655F335C7372635C6170705C66696E646D795C666D6E615F706C6174666F726D5C666D6E615F676174745F706C6174666F726D2E630000000014666D6E615F676174745F706C6174666F726D2E6301000000BECEA100FFFFFFFF55433A5C55736572735C41646D696E6973747261746F725C4465736B746F705C5265616C74656B5F66696E646D795F66696E616C5F70616B6567655F335C626F6172645C6576625C66696E646D795C626F6172642E680000000007626F6172642E6801000000BECEA100FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD50001000000000000000200000044F7FFFF75000000A2FBFFFF7304000001000000000000000100000058433A5C55736572735C41646D696E6973747261746F725C4465736B746F705C5265616C74656B5F66696E646D795F66696E616C5F70616B6567655F335C7372635C6170705C66696E646D795C637573746F6D5F6170702E63000000000C637573746F6D5F6170702E6300000000C5D4F200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000A2FBFFFF750000000000000073040000 + + + + 0 + Build + + -1 + -1 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 440100004F0000007007000015010000 + + + 16 + 4401000066000000700700002C010000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000034040000 + + + 16 + 220A000039000000620B00004C010000 + + + + 109 + 109 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000034040000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 1465 + 1465 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1935 + 1935 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 195 + 195 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000034040000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 196 + 196 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000034040000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 197 + 197 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 198 + 198 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 00000000F102000070070000CB030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 199 + 199 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 203 + 203 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 35141 + 35141 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 38003 + 38003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000660000003D01000034040000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 38007 + 38007 + 1 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 463 + 463 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 466 + 466 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 0300000068040000FD09000035050000 + + + 16 + 220A0000390000009E0B000051030000 + + + + 470 + 470 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 47010000660000006D070000FC000000 + + + 16 + 220A000039000000DA0D0000FF000000 + + + + 50000 + 50000 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50001 + 50001 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50002 + 50002 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50003 + 50003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50004 + 50004 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50005 + 50005 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50006 + 50006 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50007 + 50007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50008 + 50008 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50009 + 50009 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50010 + 50010 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50011 + 50011 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50012 + 50012 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50013 + 50013 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50014 + 50014 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50015 + 50015 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50016 + 50016 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50017 + 50017 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50018 + 50018 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 50019 + 50019 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 33060000660000006D070000E8020000 + + + 16 + 220A000039000000620B00004C010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 966 + 0 + 8192 + 0 + + 16 + 0000000000000000D10300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 000000004E050000000A000061050000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 1 + 0 + 0 + 0 + 476 + 0 + 8192 + 1 + + 16 + 000000001C000000E701000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 0 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 00000000380000006F02000054000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 824 + 824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000080300006D070000B2030000 + + + 16 + 220A000039000000620B00004C010000 + + + + 3312 + 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFF44010000150100007007000019010000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E6500200000000000004401000066000000700700002C010000440100004F00000070070000150100000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF2C0600004F0000003006000001030000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C300000180004000000000000030060000660000007007000018030000300600004F000000700700000103000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF400100004F000000440100004D040000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C4000000739400000180001000000100000000000000660000004001000064040000000000004F000000400100004D0400000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF00000000ED02000070070000F102000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000000000000803000070070000E203000000000000F102000070070000CB03000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFB8030000F1020000BC030000CB03000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF000000004D040000000A00005104000001000000010000100400000001000000AFFDFFFFA3020000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF01000077940000018000800000010000000000000068040000000A0000650500000000000051040000000A00004E0500000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657301000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572010000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + + + 59392 + File + + 2700 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE80300000000000000000000000000000000000000000000000100000001000000960000000200205000000000196170705F68616E646C655F636F6E6E5F73746174655F65767496000000000000000500196170705F68616E646C655F636F6E6E5F73746174655F657674234741505F434F4E4E5F53544154455F434F4E4E45435445443A2072656D6F74655F62640132106C655F6765745F636F6E6E5F61646472244741505F434F4E4E5F53544154455F434F4E4E45435445443A2072656D6F74655F6264200000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000002000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000003002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000000002180E50100000000000078000000264B696C6C20416C6C20427265616B706F696E747320696E204163746976652050726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180E601000000000000790000002F4B696C6C20416C6C20427265616B706F696E747320696E204D756C74692D50726F6A65637420576F726B73706163650000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65C6030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 988 + 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050000000000666696E646D79960000000000000002000666696E646D790B66696E646D792B6766707300000000000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64DC010000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2373 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720100000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000007200000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7201000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72010000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 2560 + 1440 + + + + + + 3 + 1 + + 50 + 2 + + ..\..\..\..\src\app\findmy\findmy_app.c + 63 + 674 + 717 + 1 + + 0 + + + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c + 39 + 449 + 511 + 1 + + 0 + + + ..\board.h + 16 + 1 + 21 + 1 + + 0 + + + + 50 + 0 + + ..\..\..\..\src\app\findmy\custom_app.c + 0 + 437 + 487 + 1 + + 0 + + + + +
    diff --git a/board/evb/findmy/mdk/findmy.uvoptx b/board/evb/findmy/mdk/findmy.uvoptx new file mode 100644 index 0000000..f5c7046 --- /dev/null +++ b/board/evb/findmy/mdk/findmy.uvoptx @@ -0,0 +1,1772 @@ + + + + 1.0 + +
    ### uVision Project, (C) Keil Software
    + + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + findmy + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 4 + + + + + .\debug.ini + + + + + ..\rom\startup.ini + Segger\JL2CM3.dll + + + + 0 + DLGDARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + -U-O206 -O206 -S0 -C0 -P00 -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0RTL876x_SPI_FLASH -FS0800000 -FL01000000 + + + 0 + JL2CM3 + -U4294967295 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST1 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8001 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD200000 -FC4000 -FN2 -FF0RTL876x_LOG_TRACE -FS08000000 -FL01000000 -FF1Bee3_SPI_FLASH -FS1800000 -FL11000000 + + + 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)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + -T0 + + + + + 0 + 0 + 673 + 1 +
    8621170
    + 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + \\app\../../../../src/app/findmy/crypto/third-party/mbedtls/library/sha256.c\673 +
    + + 1 + 0 + 708 + 1 +
    8621200
    + 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + \\app\../../../../src/app/findmy/crypto/third-party/mbedtls/library/sha256.c\708 +
    + + 2 + 0 + 672 + 1 +
    0
    + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + +
    + + 3 + 0 + 707 + 1 +
    0
    + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + +
    +
    + + + 1 + 0 + 0x00286a60 + 0 + + + + 0 + + + 0 + 0 + 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 + + + + + + + + +
    +
    + + + findmy+gfps + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 0 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 4 + + + + + .\debug.ini + + + + + ..\rom\startup.ini + Segger\JL2CM3.dll + + + + 0 + DLGDARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + -U-O206 -O206 -S0 -C0 -P00 -TO65554 -TC10000000 -TT10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0RTL876x_SPI_FLASH -FS0800000 -FL01000000 + + + 0 + JL2CM3 + -U4294967295 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST1 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8001 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD200000 -FC4000 -FN2 -FF0RTL876x_LOG_TRACE -FS08000000 -FL01000000 -FF1Bee3_SPI_FLASH -FS1800000 -FL11000000 + + + 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)(1012=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + -T0 + + + + + 0 + 0 + 673 + 1 +
    8621170
    + 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + \\app\../../../../src/app/findmy/crypto/third-party/mbedtls/library/sha256.c\673 +
    + + 1 + 0 + 708 + 1 +
    8621200
    + 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + \\app\../../../../src/app/findmy/crypto/third-party/mbedtls/library/sha256.c\708 +
    + + 2 + 0 + 672 + 1 +
    0
    + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + +
    + + 3 + 0 + 707 + 1 +
    0
    + 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + +
    +
    + + + 1 + 0 + 0x00286a60 + 0 + + + + 0 + + + 0 + 0 + 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 + + + + + + + + +
    +
    + + + include + 1 + 0 + 0 + 0 + + 1 + 1 + 5 + 0 + 0 + 0 + ..\flash_map.h + flash_map.h + 0 + 0 + + + 1 + 2 + 5 + 0 + 0 + 0 + ..\mem_config.h + mem_config.h + 0 + 0 + + + 1 + 3 + 5 + 0 + 0 + 0 + ..\otp_config.h + otp_config.h + 0 + 0 + + + 1 + 4 + 5 + 0 + 0 + 0 + ..\board.h + board.h + 0 + 0 + + + + + lib + 1 + 0 + 0 + 0 + + 2 + 5 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\mdk\ROM.lib + ROM.lib + 0 + 0 + + + 2 + 6 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\gap_utils.lib + gap_utils.lib + 0 + 0 + + + 2 + 7 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\mdk\bee3_sdk.lib + bee3_sdk.lib + 0 + 0 + + + 2 + 8 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\mdk\adc.lib + adc.lib + 0 + 0 + + + 2 + 9 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\mdk\key_crypto.lib + key_crypto.lib + 0 + 0 + + + 2 + 10 + 4 + 0 + 0 + 0 + ..\..\..\..\bin\mdk\system_trace.lib + system_trace.lib + 0 + 0 + + + 2 + 11 + 4 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\gfps_lib\gfps.lib + gfps.lib + 0 + 0 + + + + + cmsis + 1 + 0 + 0 + 0 + + 3 + 12 + 2 + 0 + 0 + 0 + ..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s + startup_rtl876x.s + 0 + 0 + + + 3 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c + system_rtl876x.c + 0 + 0 + + + + + peripheral + 1 + 0 + 0 + 0 + + 4 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c + rtl876x_io_dlps.c + 0 + 0 + + + 4 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c + rtl876x_gpio.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c + rtl876x_rcc.c + 0 + 0 + + + 4 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c + rtl876x_tim.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c + rtl876x_pinmux.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c + rtl876x_nvic.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c + rtl876x_adc.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c + rtl876x_i2c.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c + rtl876x_aon_wdg.c + 0 + 0 + + + + + profile + 1 + 0 + 0 + 0 + + 5 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c + findmy_network_service.c + 0 + 0 + + + 5 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c + accessory_info_service.c + 0 + 0 + + + 5 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c + firmware_update_service.c + 0 + 0 + + + 5 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\src\ble\profile\server\tps.c + tps.c + 0 + 0 + + + 5 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c + hids_kb.c + 0 + 0 + + + 5 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\src\ble\profile\server\ias.c + ias.c + 0 + 0 + + + 5 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c + sdd_service.c + 0 + 0 + + + 5 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\src\ble\profile\server\dis.c + dis.c + 0 + 0 + + + + + app + 1 + 0 + 0 + 0 + + 6 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\main.c + main.c + 0 + 0 + + + 6 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\app_task.c + app_task.c + 0 + 0 + + + 6 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\findmy_app.c + findmy_app.c + 0 + 0 + + + 6 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\custom_app.c + custom_app.c + 0 + 0 + + + 6 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\src\platform\dfu_flash.c + dfu_flash.c + 0 + 0 + + + 6 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c + overlay_mgr.c + 0 + 0 + + + 6 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\reset_watch_dog_timer.c + reset_watch_dog_timer.c + 0 + 0 + + + 6 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\src\platform\system_trace.c + system_trace.c + 0 + 0 + + + 6 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\serial_number_send.c + serial_number_send.c + 0 + 0 + + + + + app_gfps + 1 + 0 + 0 + 0 + + 7 + 40 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\app_gfps.c + app_gfps.c + 0 + 0 + + + 7 + 41 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\app_gfps_account_key.c + app_gfps_account_key.c + 0 + 0 + + + 7 + 42 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder.c + app_gfps_finder.c + 0 + 0 + + + 7 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder_adv.c + app_gfps_finder_adv.c + 0 + 0 + + + 7 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\gfps\app_dult.c + app_dult.c + 0 + 0 + + + + + FMNA_peripheral + 1 + 0 + 0 + 0 + + 8 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c + da213b.c + 0 + 0 + + + 8 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c + key_handle.c + 0 + 0 + + + + + FMNA_adk + 1 + 0 + 0 + 0 + + 9 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c + fmna_adv.c + 0 + 0 + + + 9 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c + fmna_config_control_point.c + 0 + 0 + + + 9 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c + fmna_connection.c + 0 + 0 + + + 9 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c + fmna_crypto.c + 0 + 0 + + + 9 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c + fmna_debug_control_point.c + 0 + 0 + + + 9 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c + fmna_gatt.c + 0 + 0 + + + 9 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c + fmna_motion_detection.c + 0 + 0 + + + 9 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c + fmna_nfc.c + 0 + 0 + + + 9 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c + fmna_nonowner_control_point.c + 0 + 0 + + + 9 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c + fmna_paired_owner_control_point.c + 0 + 0 + + + 9 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c + fmna_pairing_control_point.c + 0 + 0 + + + 9 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c + fmna_state_machine.c + 0 + 0 + + + 9 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c + fmna_uarp_control_point.c + 0 + 0 + + + 9 + 60 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c + fmna_version.c + 0 + 0 + + + 9 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c + FMNASampleUARP.c + 0 + 0 + + + + + FMNA_platform + 1 + 0 + 0 + 0 + + 10 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c + fmna_adv_platform.c + 0 + 0 + + + 10 + 63 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c + fmna_battery_platform.c + 0 + 0 + + + 10 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c + fmna_connection_platform.c + 0 + 0 + + + 10 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c + fmna_dfu_platform.c + 0 + 0 + + + 10 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c + fmna_gap_platform.c + 0 + 0 + + + 10 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c + fmna_gatt_platform.c + 0 + 0 + + + 10 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c + fmna_malloc_platform.c + 0 + 0 + + + 10 + 69 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c + fmna_motion_detection_platform.c + 0 + 0 + + + 10 + 70 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c + fmna_peer_manager.c + 0 + 0 + + + 10 + 71 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c + fmna_sound_platform.c + 0 + 0 + + + 10 + 72 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c + fmna_timer_platform.c + 0 + 0 + + + + + UARPDK + 1 + 0 + 0 + 0 + + 11 + 73 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c + CoreUARPUtils.c + 0 + 0 + + + 11 + 74 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c + CoreUARPAccessory.c + 0 + 0 + + + 11 + 75 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c + CoreUARPPlatformAccessory.c + 0 + 0 + + + 11 + 76 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c + CoreUARPPlatformRTK.c + 0 + 0 + + + + + crypto + 1 + 0 + 0 + 0 + + 12 + 77 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\fm-crypto.c + fm-crypto.c + 0 + 0 + + + 12 + 78 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c + kdf963.c + 0 + 0 + + + + + MbedTLS + 1 + 0 + 0 + 0 + + 13 + 79 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c + aes.c + 0 + 0 + + + 13 + 80 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c + asn1parse.c + 0 + 0 + + + 13 + 81 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c + asn1write.c + 0 + 0 + + + 13 + 82 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c + base64.c + 0 + 0 + + + 13 + 83 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c + bignum.c + 0 + 0 + + + 13 + 84 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c + bignum_core.c + 0 + 0 + + + 13 + 85 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c + cipher.c + 0 + 0 + + + 13 + 86 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c + cipher_wrap.c + 0 + 0 + + + 13 + 87 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c + constant_time.c + 0 + 0 + + + 13 + 88 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c + ecdh.c + 0 + 0 + + + 13 + 89 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c + ecdsa.c + 0 + 0 + + + 13 + 90 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c + ecp.c + 0 + 0 + + + 13 + 91 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c + ecp_curves.c + 0 + 0 + + + 13 + 92 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c + gcm.c + 0 + 0 + + + 13 + 93 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c + md.c + 0 + 0 + + + 13 + 94 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + sha256.c + 0 + 0 + + + 13 + 95 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c + platform.c + 0 + 0 + + + 13 + 96 + 1 + 0 + 0 + 0 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c + platform_util.c + 0 + 0 + + + +
    diff --git a/board/evb/findmy/mdk/findmy.uvprojx b/board/evb/findmy/mdk/findmy.uvprojx new file mode 100644 index 0000000..a7b64db --- /dev/null +++ b/board/evb/findmy/mdk/findmy.uvprojx @@ -0,0 +1,2132 @@ + + + + 2.1 + +
    ### uVision Project, (C) Keil Software
    + + + + findmy + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::.\ARMCC + 0 + + + ARMCM0P_MPU + ARM + ARM.CMSIS.5.4.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ESEL ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000) + 0 + $$Device:ARMCM0P_MPU$Device\ARM\ARMCM0plus\Include\ARMCM0plus_MPU.h + + + + + + + + + + + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + app + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + ..\..\..\..\tool\before_build_common.bat $K + before_build_special.bat + 0 + 0 + 0 + 0 + + + 1 + 1 + ..\..\..\..\tool\after_build_common.bat $J #L @L + after_build_special.bat + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + .\download.ini + + + + 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-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 1 + 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 + 0x20000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 3 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h + + + ..\..\..\..\bin\upperstack_img\upperstack_findmy_0;..\findmy;..\..\findmy;..\..\..\..\src\app\findmy;..\..\..\..\inc\app;..\..\..\..\inc\bluetooth\gap;..\..\..\..\inc\bluetooth\gap\gap_lib;..\..\..\..\inc\bluetooth\profile;..\..\..\..\inc\bluetooth\profile\server;..\..\..\..\inc;..\..\..\..\inc\os;..\..\..\..\inc\os\system_trace;..\..\..\..\inc\peripheral;..\..\..\..\inc\platform;..\..\..\..\src\app\findmy\fmna_adk;..\..\..\..\src\app\findmy\fmna_platform;..\..\..\..\src\app\findmy\fmna_profile;..\..\..\..\src\app\findmy\fmna_peripheral;..\..\..\..\src\app\findmy\UARPDK;..\..\..\..\src\app\findmy\crypto;..\..\..\..\src\app\findmy\crypto\third-party;..\..\..\..\src\app\findmy\crypto\third-party\mbedtls;..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library;..\..\..\..\..\bluetooth\crypto + + + + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 4 + + --cpreproc + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\app_findmy.sct + + + --diag_suppress=L6314,L6312 --datacompressor off --remove + + + + + + + + include + + + flash_map.h + 5 + ..\flash_map.h + + + mem_config.h + 5 + ..\mem_config.h + + + otp_config.h + 5 + ..\otp_config.h + + + board.h + 5 + ..\board.h + + + + + lib + + + ROM.lib + 4 + ..\..\..\..\bin\mdk\ROM.lib + + + gap_utils.lib + 4 + ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\gap_utils.lib + + + bee3_sdk.lib + 4 + ..\..\..\..\bin\mdk\bee3_sdk.lib + + + adc.lib + 4 + ..\..\..\..\bin\mdk\adc.lib + + + key_crypto.lib + 4 + ..\..\..\..\bin\mdk\key_crypto.lib + + + system_trace.lib + 4 + ..\..\..\..\bin\mdk\system_trace.lib + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + + + gfps.lib + 4 + ..\..\..\..\src\app\findmy\gfps\gfps_lib\gfps.lib + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + + + + + cmsis + + + startup_rtl876x.s + 2 + ..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s + + + system_rtl876x.c + 1 + ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c + + + + + peripheral + + + rtl876x_io_dlps.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c + + + rtl876x_gpio.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c + + + rtl876x_rcc.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c + + + rtl876x_tim.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c + + + rtl876x_pinmux.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c + + + rtl876x_nvic.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c + + + rtl876x_adc.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c + + + rtl876x_i2c.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c + + + rtl876x_aon_wdg.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c + + + + + profile + + + findmy_network_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c + + + accessory_info_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c + + + firmware_update_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c + + + tps.c + 1 + ..\..\..\..\src\ble\profile\server\tps.c + + + hids_kb.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c + + + ias.c + 1 + ..\..\..\..\src\ble\profile\server\ias.c + + + sdd_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c + + + dis.c + 1 + ..\..\..\..\src\ble\profile\server\dis.c + + + + + app + + + main.c + 1 + ..\..\..\..\src\app\findmy\main.c + + + app_task.c + 1 + ..\..\..\..\src\app\findmy\app_task.c + + + findmy_app.c + 1 + ..\..\..\..\src\app\findmy\findmy_app.c + + + custom_app.c + 1 + ..\..\..\..\src\app\findmy\custom_app.c + + + dfu_flash.c + 1 + ..\..\..\..\src\platform\dfu_flash.c + + + overlay_mgr.c + 1 + ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c + + + reset_watch_dog_timer.c + 1 + ..\..\..\..\src\app\findmy\reset_watch_dog_timer.c + + + system_trace.c + 1 + ..\..\..\..\src\platform\system_trace.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + serial_number_send.c + 1 + ..\..\..\..\src\app\findmy\serial_number_send.c + + + + + app_gfps + + + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + app_gfps.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps.c + + + app_gfps_account_key.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_account_key.c + + + app_gfps_finder.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder.c + + + app_gfps_finder_adv.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder_adv.c + + + app_dult.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_dult.c + + + + + FMNA_peripheral + + + da213b.c + 1 + ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c + + + key_handle.c + 1 + ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c + + + + + FMNA_adk + + + fmna_adv.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c + + + fmna_config_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c + + + fmna_connection.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c + + + fmna_crypto.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c + + + fmna_debug_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c + + + fmna_gatt.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c + + + fmna_motion_detection.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c + + + fmna_nfc.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c + + + fmna_nonowner_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c + + + fmna_paired_owner_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c + + + fmna_pairing_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c + + + fmna_state_machine.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c + + + fmna_uarp_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c + + + fmna_version.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c + + + FMNASampleUARP.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c + + + + + FMNA_platform + + + fmna_adv_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c + + + fmna_battery_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c + + + fmna_connection_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c + + + fmna_dfu_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c + + + fmna_gap_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c + + + fmna_gatt_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c + + + fmna_malloc_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c + + + fmna_motion_detection_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c + + + fmna_peer_manager.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c + + + fmna_sound_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c + + + fmna_timer_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c + + + + + UARPDK + + + CoreUARPUtils.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c + + + CoreUARPAccessory.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c + + + CoreUARPPlatformAccessory.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c + + + CoreUARPPlatformRTK.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c + + + + + crypto + + + fm-crypto.c + 1 + ..\..\..\..\src\app\findmy\crypto\fm-crypto.c + + + kdf963.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c + + + + + MbedTLS + + + aes.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c + + + asn1parse.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c + + + asn1write.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c + + + base64.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c + + + bignum.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c + + + bignum_core.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c + + + cipher.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c + + + cipher_wrap.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c + + + constant_time.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c + + + ecdh.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c + + + ecdsa.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c + + + ecp.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c + + + ecp_curves.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c + + + gcm.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c + + + md.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c + + + sha256.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + + platform.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c + + + platform_util.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c + + + + + + + findmy+gfps + 0x4 + ARM-ADS + 5060960::V5.06 update 7 for Certification (build 960)::.\Arm_Compiler_5.06u7 + 0 + + + ARMCM0P_MPU + ARM + ARM.CMSIS.5.4.0 + http://www.keil.com/pack/ + IRAM(0x20000000,0x00020000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0+") CLOCK(12000000) ESEL ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000) + 0 + $$Device:ARMCM0P_MPU$Device\ARM\ARMCM0plus\Include\ARMCM0plus_MPU.h + + + + + + + + + + + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + app + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 1 + ..\..\..\..\tool\before_build_common.bat $K + before_build_special.bat + 0 + 0 + 0 + 0 + + + 1 + 1 + ..\..\..\..\tool\after_build_common.bat $J #L @L + after_build_special.bat + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DARMCM1.DLL + -pCM0+ + SARMCM3.DLL + -MPU + TARMCM1.DLL + -pCM0+ + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + .\download.ini + + + + 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-M0+" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 1 + 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 + 0x20000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 3 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + --gnu --bss_threshold=0 --diag_suppress=1276 --preinclude stdint.h --preinclude flash_map.h + GFPS_FEATURE_SUPPORT = 1 + + ..\..\..\..\bin\upperstack_img\upperstack_findmy_0;..\..\findmy;..\..\..\..\src\app\findmy;..\..\..\..\inc\app;..\..\..\..\inc\bluetooth\gap;..\..\..\..\inc\bluetooth\gap\gap_lib;..\..\..\..\inc\bluetooth\profile;..\..\..\..\inc\bluetooth\profile\server;..\..\..\..\inc;..\..\..\..\inc\os;..\..\..\..\inc\os\system_trace;..\..\..\..\inc\peripheral;..\..\..\..\inc\platform;..\..\..\..\src\app\findmy\fmna_adk;..\..\..\..\src\app\findmy\fmna_platform;..\..\..\..\src\app\findmy\fmna_profile;..\..\..\..\src\app\findmy\fmna_peripheral;..\..\..\..\src\app\findmy\UARPDK;..\..\..\..\src\app\findmy\crypto;..\..\..\..\src\app\findmy\crypto\third-party;..\..\..\..\src\app\findmy\crypto\third-party\mbedtls;..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library;..\..\..\..\..\bluetooth\crypto;..\..\..\..\src\app\findmy\gfps;..\..\..\..\src\app\findmy\gfps\gfps_lib + + + + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 4 + + --cpreproc + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + .\app_findmy.sct + + + --diag_suppress=L6314,L6312 --datacompressor off --remove + + + + + + + + include + + + flash_map.h + 5 + ..\flash_map.h + + + mem_config.h + 5 + ..\mem_config.h + + + otp_config.h + 5 + ..\otp_config.h + + + board.h + 5 + ..\board.h + + + + + lib + + + ROM.lib + 4 + ..\..\..\..\bin\mdk\ROM.lib + + + gap_utils.lib + 4 + ..\..\..\..\bin\upperstack_img\upperstack_findmy_0\gap_utils.lib + + + bee3_sdk.lib + 4 + ..\..\..\..\bin\mdk\bee3_sdk.lib + + + adc.lib + 4 + ..\..\..\..\bin\mdk\adc.lib + + + key_crypto.lib + 4 + ..\..\..\..\bin\mdk\key_crypto.lib + + + system_trace.lib + 4 + ..\..\..\..\bin\mdk\system_trace.lib + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + + + gfps.lib + 4 + ..\..\..\..\src\app\findmy\gfps\gfps_lib\gfps.lib + + + + + cmsis + + + startup_rtl876x.s + 2 + ..\..\..\..\src\mcu\rtl876x\arm\startup_rtl876x.s + + + system_rtl876x.c + 1 + ..\..\..\..\src\mcu\rtl876x\system_rtl876x.c + + + + + peripheral + + + rtl876x_io_dlps.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_io_dlps.c + + + rtl876x_gpio.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_gpio.c + + + rtl876x_rcc.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_rcc.c + + + rtl876x_tim.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_tim.c + + + rtl876x_pinmux.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_pinmux.c + + + rtl876x_nvic.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_nvic.c + + + rtl876x_adc.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_adc.c + + + rtl876x_i2c.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_i2c.c + + + rtl876x_aon_wdg.c + 1 + ..\..\..\..\src\mcu\peripheral\rtl876x_aon_wdg.c + + + + + profile + + + findmy_network_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\findmy_network_service.c + + + accessory_info_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\accessory_info_service.c + + + firmware_update_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\firmware_update_service.c + + + tps.c + 1 + ..\..\..\..\src\ble\profile\server\tps.c + + + hids_kb.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\hids_kb.c + + + ias.c + 1 + ..\..\..\..\src\ble\profile\server\ias.c + + + sdd_service.c + 1 + ..\..\..\..\src\app\findmy\fmna_profile\sdd_service.c + + + dis.c + 1 + ..\..\..\..\src\ble\profile\server\dis.c + + + + + app + + + main.c + 1 + ..\..\..\..\src\app\findmy\main.c + + + app_task.c + 1 + ..\..\..\..\src\app\findmy\app_task.c + + + findmy_app.c + 1 + ..\..\..\..\src\app\findmy\findmy_app.c + + + custom_app.c + 1 + ..\..\..\..\src\app\findmy\custom_app.c + + + dfu_flash.c + 1 + ..\..\..\..\src\platform\dfu_flash.c + + + overlay_mgr.c + 1 + ..\..\..\..\src\mcu\rtl876x\overlay_mgr.c + + + reset_watch_dog_timer.c + 1 + ..\..\..\..\src\app\findmy\reset_watch_dog_timer.c + + + system_trace.c + 1 + ..\..\..\..\src\platform\system_trace.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + serial_number_send.c + 1 + ..\..\..\..\src\app\findmy\serial_number_send.c + + + + + app_gfps + + + app_gfps.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps.c + + + app_gfps_account_key.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_account_key.c + + + app_gfps_finder.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder.c + + + app_gfps_finder_adv.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_gfps_finder_adv.c + + + app_dult.c + 1 + ..\..\..\..\src\app\findmy\gfps\app_dult.c + + + + + FMNA_peripheral + + + da213b.c + 1 + ..\..\..\..\src\app\findmy\fmna_peripheral\da213b.c + + + key_handle.c + 1 + ..\..\..\..\src\app\findmy\fmna_peripheral\key_handle.c + + + + + FMNA_adk + + + fmna_adv.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_adv.c + + + fmna_config_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_config_control_point.c + + + fmna_connection.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_connection.c + + + fmna_crypto.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_crypto.c + + + fmna_debug_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_debug_control_point.c + + + fmna_gatt.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_gatt.c + + + fmna_motion_detection.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_motion_detection.c + + + fmna_nfc.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nfc.c + + + fmna_nonowner_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_nonowner_control_point.c + + + fmna_paired_owner_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_paired_owner_control_point.c + + + fmna_pairing_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_pairing_control_point.c + + + fmna_state_machine.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_state_machine.c + + + fmna_uarp_control_point.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_uarp_control_point.c + + + fmna_version.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\fmna_version.c + + + FMNASampleUARP.c + 1 + ..\..\..\..\src\app\findmy\fmna_adk\FMNASampleUARP.c + + + + + FMNA_platform + + + fmna_adv_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_adv_platform.c + + + fmna_battery_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_battery_platform.c + + + fmna_connection_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_connection_platform.c + + + fmna_dfu_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_dfu_platform.c + + + fmna_gap_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gap_platform.c + + + fmna_gatt_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_gatt_platform.c + + + fmna_malloc_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_malloc_platform.c + + + fmna_motion_detection_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_motion_detection_platform.c + + + fmna_peer_manager.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_peer_manager.c + + + fmna_sound_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_sound_platform.c + + + fmna_timer_platform.c + 1 + ..\..\..\..\src\app\findmy\fmna_platform\fmna_timer_platform.c + + + + + UARPDK + + + CoreUARPUtils.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPUtils.c + + + CoreUARPAccessory.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPAccessory.c + + + CoreUARPPlatformAccessory.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformAccessory.c + + + CoreUARPPlatformRTK.c + 1 + ..\..\..\..\src\app\findmy\UARPDK\CoreUARPPlatformRTK.c + + + + + crypto + + + fm-crypto.c + 1 + ..\..\..\..\src\app\findmy\crypto\fm-crypto.c + + + kdf963.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\kdf963.c + + + + + MbedTLS + + + aes.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\aes.c + + + asn1parse.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1parse.c + + + asn1write.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\asn1write.c + + + base64.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\base64.c + + + bignum.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum.c + + + bignum_core.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\bignum_core.c + + + cipher.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher.c + + + cipher_wrap.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\cipher_wrap.c + + + constant_time.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\constant_time.c + + + ecdh.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdh.c + + + ecdsa.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecdsa.c + + + ecp.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp.c + + + ecp_curves.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\ecp_curves.c + + + gcm.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\gcm.c + + + md.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\md.c + + + sha256.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\sha256.c + + + platform.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform.c + + + platform_util.c + 1 + ..\..\..\..\src\app\findmy\crypto\third-party\mbedtls\library\platform_util.c + + + + + + + + + + + + + + + + + + + + + + + + RTE\Device\ARMCM0P_MPU\ARMCM0plus_ac5.sct + + + + + + RTE\Device\ARMCM0P_MPU\startup_ARMCM0plus.c + + + + + + RTE\Device\ARMCM0P_MPU\startup_ARMCM0plus.s + + + + + + RTE\Device\ARMCM0P_MPU\system_ARMCM0plus.c + + + + + + + + + + + findmy + 1 + + + + +
    diff --git a/board/evb/findmy/mem_config.h b/board/evb/findmy/mem_config.h new file mode 100644 index 0000000..b9288df --- /dev/null +++ b/board/evb/findmy/mem_config.h @@ -0,0 +1,81 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file mem_config.h + * @brief Memory Configuration + * @date 2017.6.6 + * @version v1.0 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef MEM_CONFIG_H +#define MEM_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "flash_map.h" + +/*============================================================================* + * Code configuration + *============================================================================*/ +/** @brief set app bank to support OTA: 1 is ota bank1, 0 is ota bank0 */ +#define APP_BANK 0 + +/** @brief ram code configuration: 1 is ram code, 0 is flash code */ +#define FEATURE_RAM_CODE 0 + +/** @brief encrypt app or not */ +#define FEATURE_ENCRYPTION 0 + + +/*============================================================================* + * data ram layout configuration + *============================================================================*/ +/* Data RAM layout: 88K +example: + 1) reserved for rom: 14K (fixed) + 2) Patch: 15K (fixed) + 3) upperstack: 2K (adjustable, depend on used upperstack version) + 4) app global + ram code: 24K (adjustable, config APP_GLOBAL_SIZE) + 5) Heap ON: 33K (adjustable, config HEAP_DATA_ON_SIZE) +*/ + +/** @brief data ram size for upperstack global variables and code */ +#define UPPERSTACK_GLOBAL_SIZE (2 * 1024) + +/** @brief data ram size for app global variables and code, could be changed */ +#define APP_GLOBAL_SIZE (18 * 1024) + +/** @brief data ram size for heap, could be changed, but (UPPERSTACK_GLOBAL_SIZE + APP_GLOBAL_SIZE + HEAP_DATA_ON_SIZE) must be 59k */ +#define HEAP_DATA_ON_SIZE (59 * 1024 - APP_GLOBAL_SIZE - UPPERSTACK_GLOBAL_SIZE + SHARE_CACHE_RAM_SIZE) + +/** @brief shared cache ram size (adjustable, config SHARE_CACHE_RAM_SIZE: 0/4KB/8KB) */ +#define SHARE_CACHE_RAM_SIZE (0 * 1024) +/*****************************************************/ + + +/***************The following macros can't be modified***************/ +#define DATA_RAM_START_ADDR 0x00200000 +#define DATA_RAM_TOTAL_SIZE (88 * 1024) +#define DATA_RAM_RESERVED_SIZE (29 * 1024) + +#define APP_GLOBAL_ADDR (DATA_RAM_START_ADDR + DATA_RAM_RESERVED_SIZE + UPPERSTACK_GLOBAL_SIZE) +#define SHARE_CACHE_RAM_ADDR (DATA_RAM_START_ADDR + DATA_RAM_TOTAL_SIZE) + + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* End of group MEM_CONFIG */ +#endif diff --git a/board/evb/findmy/mp.ini b/board/evb/findmy/mp.ini new file mode 100644 index 0000000..f553189 --- /dev/null +++ b/board/evb/findmy/mp.ini @@ -0,0 +1,51 @@ +; This is a config file used by prepend_header tool to generate MP header for a given image. +; +; The following four sections are mandatory: BinID, Version, PartNumber and DataLength. Among +; which the DataLength key is not really needed to write in this file, as it would be calculated +; by the prepend_header tool and automatically filled in the MP header. +; +; Note that MP header is a 512 bytes fixed data area, pay attention to the long strings you have +; written and ensure they are not out of bound of the header. + + +[MandatoryInfo] + +; To recognize what is this .bin and where is came from. Defined IDs are: ID_APP, ID_PATCH, +; ID_CONFIG, ID_SECURE_BOOTLOADER, ID_OTA_HEADER, ID_APP_DATA1, ID_APP_DATA2 +BinID=ID_APP + +; This bin version (suggested sync with tool version). Range: 0.0.0.0 ~ 255.255.255.255 +Version=1.0.0.0 + +; This bin is for what IC part number, ASCII type, 32 bytes maximum. +PartNumber=RTL8762E + + +[OptionalInfo] + +; Optional. Depended on what other .bins, for .bin merging check. Fill the required version number +; in specific field if specific image is needed. Item would be ignored if the format of the value +; is wrong or the value is not exist. +DependOnConfig = +DependOnPatch = +DependOnApp = +DependOnAppData = +DependOnAppDataTone = +DependOnAppDataVp = +DependOnAppDspParam = +DependOnDspSys = +DependOnDspPatch = +DependOnDspScenario1 = +DependOnDspScenario2 = + +; Optional ASCII type comment string, 255 bytes maximum. +Comment= + +; Optional ASCII type author information string, 255 bytes maximum. +Author= + +; Optional ASCII type date and time string, 255 bytes maximum. +Date= + +; Optional bin header format revision. +Revision=0x01 diff --git a/board/evb/findmy/otp_config.h b/board/evb/findmy/otp_config.h new file mode 100644 index 0000000..087af42 --- /dev/null +++ b/board/evb/findmy/otp_config.h @@ -0,0 +1,144 @@ +/** +***************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file otp_config.h + * @brief Update Configuration in APP + * @date 2020.03.10 + * @version v1.1 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2020 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef OTP_CONFIG_H +#define OTP_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rtl876x_wdg.h" +/*============================================================================* + * debug configuration + *============================================================================*/ +/** @brief just for OTA Demo test */ +#define OTA_TEST 0 +/** @brief just for OTA Demo test */ +#define OTA_TEST_BANK_SWITCH 0 +#if (OTA_TEST_BANK_SWITCH == 0) +#define OTA_TEST_IMAGE_VERSION 0 +#endif + +/** @brief just for debug */ +#define SYSTEM_TRACE_ENABLE 0 + + +/*============================================================================* + * flash configuration + *============================================================================*/ +/** @brief support for puran flash*/ +#define FTL_APP_CALLBACK_ENABLE 0 +/** @brief modify ftl logic space size to adjust the RAM footprint of the ftl Mapping Table + * PAGE_ELEMENT_DATA_NUM = ((FMC_PAGE_SIZE / 8) - 1). + * MAX_LOGICAL_ADDR_SIZE = (((PAGE_ELEMENT_DATA_NUM * (g_page_num - 1)) - 1) << 2) + * if sector size is 4KB, PAGE_ELEMENT_DATA_NUM equal 511. + * g_page_num = ftl physical size / FMC_PAGE_SIZE. so if ftl size is 16KB, g_page_num is 4. + * example: default ftl size in flash layout is 16KB, MAX_LOGICAL_ADDR_SIZE = 0x17F0 = 6128 + * FTL_REAL_LOGIC_ADDR_SIZE must be less or equal MAX_LOGICAL_ADDR_SIZE, otherwise will init ftl fail. +*/ +#define FTL_REAL_LOGIC_ADDR_SIZE (2 * 1024) +/** @brief enable BP, set lock level depend on flash layout and selected flash id */ +#define FLASH_BLOCK_PROTECT_ENABLE 0 +/** @brief modify delay time for wakeup flash from power down mode to standby mode*/ +#define AFTER_TOGGLE_CS_DELAY 6 + + +/*============================================================================* + * platform configuration + *============================================================================*/ +/** @brief default enable swd pinmux */ +#define SWD_PINMUX_ENABLE 0 +/** @brief enable aon wdg which continue work in dlps state */ +#define AON_WDG_ENABLE 1 +/** @brief set aon wdg timeout period in seconds, max value is 65s */ +#define AON_WDG_TIME_OUT_PERIOD_SECOND 4 +/** @brief default disable watch dog in rom */ +#define ROM_WATCH_DOG_ENABLE 0 +/** @brief set wdg mode, default reset all */ +#define ROM_WATCH_DOG_MODE RESET_ALL +/** @brief Watch Dog Timer Config, default 4s timeout + * div_factor: 16Bit: 32.768k/(1+divfactor). + * cnt_limit: 2^(cnt_limit+1) - 1 ; max 11~15 = 0xFFF. + * wdg_mode: + * 1: RESET_ALL_EXCEPT_AON + * 3: RESET_ALL +**/ +#define ROM_WATCH_DOG_CFG_DIV_FACTOR 31 +#define ROM_WATCH_DOG_CFG_CNT_LIMIT 15 + +/*before wdg system reset, write reset reason to specific flash addr if enable*/ +#define WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE 0 +#if (WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0) +/*write reset reason to specific flash address*/ +#define REBOOT_REASON_RECORD_ADDRESS 0x8cb000 +/** @brief The maximum number of reboot records is 2^(n-1). Each reset reason record requires 8 bytes, occupied flash size is 2^(n+2) bytes. */ +#define REBOOT_REASON_RECORD_LIMIT_POWERT2 10 //reserve 4KB +#endif + +/** @brief to fix bug need disable dump callstack info before WDG_SystemReset, default enable */ +#define DUMP_INFO_BEFORE_RESET_DISABLE 1 + + +/*============================================================================* + * upperstack configuration + *============================================================================*/ +#define BT_STACK_CONFIG_ENABLE + +#ifdef BT_STACK_CONFIG_ENABLE +void bt_stack_config_init(void); +#endif +/*============================================================================* +* OTA configuration +*============================================================================*/ +/*If support unsafe single bank ota user data, must define the following macros */ +#define SUPPORT_SINGLE_BANK_OTA_USER_DATA +#ifdef SUPPORT_SINGLE_BANK_OTA_USER_DATA +#define USER_DATA_START_ADDR 0x00840000 //back 8M(0x1000000) or 0x00840000 +#define USER_DATA_MAX_SIZE (1025 * 1024) //1M+1K +#endif + +/*normal ota timeout settings*/ +#define OTA_TIMEOUT_TOTAL 240 +#define OTA_TIMEOUT_WAIT4_CONN 60 +#define OTA_TIMEOUT_WAIT4_IMAGE_TRANS 200 +#define OTA_TIMEOUT_CTITTV 0xFF + +/*============================================================================* + * timer configuration + *============================================================================*/ +/*default sw timer number is 32*/ +#define TIMER_MAX_NUMBER 48 +/*default sw timer task stack size is 1KB*/ +#define TIMER_TASK_STACK_SIZE (256 * 4) + +/*============================================================================* + * app configuration + *============================================================================*/ +//add more here + + + +#ifdef __cplusplus +} +#endif + + +/** @} */ /* End of group OTP_CONFIG */ +#endif + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/board/evb/findmy/platform_autoconf.h b/board/evb/findmy/platform_autoconf.h new file mode 100644 index 0000000..cc4c6f1 --- /dev/null +++ b/board/evb/findmy/platform_autoconf.h @@ -0,0 +1,51 @@ +/** +************************************************************************************************************ +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file platform_autoconf.h +* @brief Platform configuration +* @author +* @date 2018-04-16 +* @version v0.1 +************************************************************************************************************* +*/ +#ifndef _PLATFORM_AUTOCONF_H_ +#define _PLATFORM_AUTOCONF_H_ + +#include "board.h" + +/** @defgroup BUILD_CONFIGURATION Build Configuration + * @brief Platform build configuration + * @{ + */ + +#if IS_RELEASE_VERSION +#define RELEASE_VERSION +#endif + +#ifdef RELEASE_VERSION +#define CHECK_STACK_OVERFLOW_ENABLE 0 +#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 0 +#define PLATFORM_ASSERT_ENABLE 0 +#define CONFIG_LOG_FUNCTION_ENABLE 0 +#define RUN_APP_IN_HCIMODE_ENABLE 0 +#define SUPPORT_FTL_IN_APP 0 +/*disable it if need reduce code size*/ +#define ENABLE_FULL_FEATURED_DIRECT_LOG 1 +#else +#define CHECK_STACK_OVERFLOW_ENABLE 1 +#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 1 +#define PLATFORM_ASSERT_ENABLE 1 +#define CONFIG_LOG_FUNCTION_ENABLE 1 +#define RUN_APP_IN_HCIMODE_ENABLE 0 +#define SUPPORT_FTL_IN_APP 0 +/*disable it if need reduce code size*/ +#define ENABLE_FULL_FEATURED_DIRECT_LOG 1 +#endif + + +/** End of BUILD_CONFIGURATION + * @} + */ + +#endif /* End of _PLATFORM_AUTOCONF_H_ */ diff --git a/board/evb/findmy/version.h b/board/evb/findmy/version.h new file mode 100644 index 0000000..98c494d --- /dev/null +++ b/board/evb/findmy/version.h @@ -0,0 +1,21 @@ +#include "fmna_version.h" +#define VERSION_MAJOR FW_VERSION_MAJOR_NUMBER +#define VERSION_MINOR FW_VERSION_MINOR_NUMBER +#define VERSION_REVISION FW_VERSION_REVISION_NUMBER +#define VERSION_BUILDNUM 0 +#define VERSION_GCID 0x8ab6d92f +#define CUSTOMER_NAME sdk +#define CN_1 'f' +#define CN_2 'i' +#define CN_3 'n' +#define CN_4 'd' +#define CN_5 'm' +#define CN_6 'y' +#define CN_7 '#' +#define CN_8 '#' +#define BUILDING_TIME "Wed Jun 22 16:51:36 2022" +#define NAME2STR(a) #a +#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME) +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILDNUM) diff --git a/doc/buttonClickDemo.html b/doc/buttonClickDemo.html new file mode 100644 index 0000000..4a18912 --- /dev/null +++ b/doc/buttonClickDemo.html @@ -0,0 +1,513 @@ + + + + + + 短按检测演示 - 1下、2下、10下 + + + +
    +

    短按检测演示

    +

    测试短按1下、短按2下和短按10下的效果

    + +
    + +
    + +
    +
    +

    当前点击次数

    +
    0
    +
    +
    +

    检测到的操作

    +
    --
    +
    +
    +

    操作次数

    +
    0
    +
    +
    + +
    + + + + +
    + +
    +

    参数设置

    +
    + + +
    +
    + + +
    +
    + +
    +
    === 短按检测系统已启动 ===
    +
    +
    + + + + \ No newline at end of file diff --git a/doc/buttonClickHandler.js b/doc/buttonClickHandler.js new file mode 100644 index 0000000..1c8936a --- /dev/null +++ b/doc/buttonClickHandler.js @@ -0,0 +1,179 @@ +// 按钮短按检测与处理示例 +// 本代码展示如何实现短按1下、短按2下和短按10下的检测与处理逻辑 + +class ButtonClickHandler { + constructor() { + // 配置参数 + this.clickTimeout = 300; // 点击间隔超时时间(毫秒),超过此时间认为是新的点击序列 + this.longPressThreshold = 600; // 长按判断阈值(毫秒) + + // 状态变量 + this.clickCount = 0; // 当前点击序列的点击次数 + this.lastClickTime = 0; // 上次点击时间戳 + this.isLongPress = false; // 是否为长按 + this.isPressed = false; // 按钮是否处于按下状态 + this.clickTimer = null; // 点击定时器 + this.longPressTimer = null; // 长按定时器 + + // 绑定事件 + this.setupEventListeners(); + } + + setupEventListeners() { + // 这里模拟按钮事件监听,实际使用时替换为真实的DOM事件 + console.log('按钮点击处理器已初始化,请使用模拟函数测试: simulateButtonDown(), simulateButtonUp()'); + } + + // 模拟按钮按下事件 + onButtonDown() { + this.isPressed = true; // 设置按钮按下状态 + console.log('按钮按下'); + + // 重置长按标志 + this.isLongPress = false; + + // 启动长按检测定时器 + this.longPressTimer = setTimeout(() => { + this.isLongPress = true; + console.log('检测到长按'); + this.handleLongPress(); + }, this.longPressThreshold); + } + + // 模拟按钮释放事件 + onButtonUp() { + // 只有在按钮确实被按下的情况下才处理释放事件 + if (!this.isPressed) { + console.log('警告: 检测到无效的按钮释放事件'); + return; + } + + this.isPressed = false; // 重置按钮按下状态 + console.log('按钮释放'); + + // 清除长按定时器 + if (this.longPressTimer) { + clearTimeout(this.longPressTimer); + this.longPressTimer = null; + } + + // 如果不是长按,则处理短按 + if (!this.isLongPress) { + this.handleShortPress(); + } + } + + // 处理短按 + handleShortPress() { + const currentTime = Date.now(); + const timeSinceLastClick = currentTime - this.lastClickTime; + + // 判断是否为新的点击序列(两次点击间隔超过阈值) + if (timeSinceLastClick > this.clickTimeout) { + // 重置点击计数 + this.clickCount = 1; + } else { + // 增加点击计数 + this.clickCount++; + } + + // 更新上次点击时间 + this.lastClickTime = currentTime; + + // 清除之前的定时器 + if (this.clickTimer) { + clearTimeout(this.clickTimer); + } + + // 启动新的定时器,超时后处理点击序列 + this.clickTimer = setTimeout(() => { + this.processClickSequence(); + }, this.clickTimeout); + } + + // 处理长按 + handleLongPress() { + console.log('执行长按操作'); + // 可以在这里添加长按的具体处理逻辑 + } + + // 处理点击序列 + processClickSequence() { + console.log(`检测到 ${this.clickCount} 次短按`); + + // 根据点击次数执行不同的操作 + switch (this.clickCount) { + case 1: + this.handleSingleClick(); + break; + case 2: + this.handleDoubleClick(); + break; + case 10: + this.handleTenClicks(); + break; + default: + if (this.clickCount > 2 && this.clickCount < 10) { + console.log(`检测到 ${this.clickCount} 次短按,但没有特定处理逻辑`); + } else if (this.clickCount > 10) { + console.log(`检测到 ${this.clickCount} 次短按,次数过多`); + } + } + + // 重置点击计数 + this.clickCount = 0; + } + + // 处理单击 + handleSingleClick() { + console.log('执行单击操作 - 短按1下'); + // 这里添加单击的具体逻辑 + } + + // 处理双击 + handleDoubleClick() { + console.log('执行双击操作 - 短按2下'); + // 这里添加双击的具体逻辑 + } + + // 处理十连击 + handleTenClicks() { + console.log('执行十连击操作 - 短按10下'); + // 这里添加十连击的具体逻辑 + } + + // 模拟测试函数 + simulateButtonDown() { + this.onButtonDown(); + } + + simulateButtonUp() { + this.onButtonUp(); + } + + // 模拟单次点击 + simulateSingleClick() { + this.simulateButtonDown(); + setTimeout(() => this.simulateButtonUp(), 100); + } + + // 模拟双击 + simulateDoubleClick() { + this.simulateSingleClick(); + setTimeout(() => this.simulateSingleClick(), 150); // 两次点击间隔小于clickTimeout + } + + // 模拟十连击 + simulateTenClicks() { + for (let i = 0; i < 10; i++) { + setTimeout(() => this.simulateSingleClick(), i * 150); + } + } +} + +// 测试代码 +console.log('短按检测系统演示'); +const buttonHandler = new ButtonClickHandler(); + +// 导出处理器实例供外部使用 +module.exports = buttonHandler; \ No newline at end of file diff --git a/doc/testButtonClicks.js b/doc/testButtonClicks.js new file mode 100644 index 0000000..ef67596 --- /dev/null +++ b/doc/testButtonClicks.js @@ -0,0 +1,58 @@ +// 测试短按处理逻辑的示例脚本 +const buttonHandler = require('./buttonClickHandler'); + +console.log('开始测试短按处理逻辑...\n'); + +// 测试场景1: 短按1下 +testSingleClick(); + +// 测试场景2: 短按2下 (双击) +setTimeout(testDoubleClick, 1000); + +// 测试场景3: 短按10下 (十连击) +setTimeout(testTenClicks, 3000); + +// 测试场景4: 混合点击模式(单击后双击) +setTimeout(testMixedClicks, 6000); + +function testSingleClick() { + console.log('===== 测试场景1: 短按1下 ====='); + buttonHandler.simulateSingleClick(); +} + +function testDoubleClick() { + console.log('\n===== 测试场景2: 短按2下 (双击) ====='); + buttonHandler.simulateDoubleClick(); +} + +function testTenClicks() { + console.log('\n===== 测试场景3: 短按10下 (十连击) ====='); + buttonHandler.simulateTenClicks(); +} + +function testMixedClicks() { + console.log('\n===== 测试场景4: 混合点击模式 ====='); + console.log('先单击一次:'); + buttonHandler.simulateSingleClick(); + + setTimeout(() => { + console.log('\n然后双击:'); + buttonHandler.simulateDoubleClick(); + + // 程序结束提示 + setTimeout(() => { + console.log('\n\n所有测试完成!'); + console.log('\n总结:'); + console.log('1. 短按1下: 通过单击事件触发,会执行handleSingleClick()'); + console.log('2. 短按2下: 通过双击事件触发,会执行handleDoubleClick()'); + console.log('3. 短按10下: 通过连续快速点击10次触发,会执行handleTenClicks()'); + console.log('\n实现原理:'); + console.log('- 使用定时器和时间阈值区分不同的点击序列'); + console.log('- 记录点击次数,超时后根据次数执行相应逻辑'); + console.log('- 可以轻松扩展支持更多次数的点击模式'); + }, 1000); + }, 1000); +} + +console.log('\n测试将按顺序自动执行,请查看输出结果...'); +console.log('注意: 各个测试场景之间有时间间隔,以便清晰观察输出\n'); \ No newline at end of file diff --git a/doc/testInvalidRelease.js b/doc/testInvalidRelease.js new file mode 100644 index 0000000..93bf34f --- /dev/null +++ b/doc/testInvalidRelease.js @@ -0,0 +1,53 @@ +// 测试无效按钮释放事件的处理 +const buttonHandler = require('./buttonClickHandler'); + +console.log('开始测试无效按钮释放事件处理...\n'); + +// 测试场景1: 直接调用释放事件(应该被拒绝) +console.log('===== 测试场景1: 尝试直接调用按钮释放事件 ====='); +buttonHandler.onButtonUp(); // 这应该被拒绝,因为按钮没有被按下 + +// 测试场景2: 正常的按下和释放序列(应该正常工作) +setTimeout(() => { + console.log('\n===== 测试场景2: 正常的按下和释放序列 ====='); + buttonHandler.onButtonDown(); + setTimeout(() => { + buttonHandler.onButtonUp(); + }, 100); +}, 1000); + +// 测试场景3: 按下后多次尝试释放(只有第一次应该有效) +setTimeout(() => { + console.log('\n===== 测试场景3: 按下后多次尝试释放 ====='); + buttonHandler.onButtonDown(); + setTimeout(() => { + buttonHandler.onButtonUp(); // 第一次释放应该有效 + setTimeout(() => { + buttonHandler.onButtonUp(); // 第二次释放应该被拒绝 + }, 100); + }, 100); +}, 2000); + +// 测试场景4: 尝试释放后再按下和正常释放 +setTimeout(() => { + console.log('\n===== 测试场景4: 尝试释放后再按下和正常释放 ====='); + buttonHandler.onButtonUp(); // 无效释放,应该被拒绝 + setTimeout(() => { + buttonHandler.onButtonDown(); // 按下应该正常 + setTimeout(() => { + buttonHandler.onButtonUp(); // 正常释放 + }, 100); + }, 100); + + // 测试完成提示 + setTimeout(() => { + console.log('\n\n所有测试完成!'); + console.log('\n总结:'); + console.log('1. 直接调用按钮释放事件已被正确拒绝'); + console.log('2. 正常的按下和释放序列仍然可以正常工作'); + console.log('3. 按下后多次尝试释放,只有第一次有效'); + console.log('4. 无效释放后,正常的按下和释放操作不受影响'); + }, 500); +}, 3000); + +console.log('测试将按顺序自动执行,请查看输出结果...\n'); \ No newline at end of file diff --git a/doc/需求说明.pdf b/doc/需求说明.pdf new file mode 100644 index 0000000..584b959 Binary files /dev/null and b/doc/需求说明.pdf differ diff --git a/inc/app/app_msg.h b/inc/app/app_msg.h new file mode 100644 index 0000000..667f984 --- /dev/null +++ b/inc/app/app_msg.h @@ -0,0 +1,266 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** + * @file app_msg.h + * @brief Message definition for user application task. + * @note If new message types/sub types are to be added, add to the end of enumeration. + * The orders are NOT to changed. + * @author Lory + * @date 2017.2.9 + * @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ + +#ifndef _APP_MSG_H_ +#define _APP_MSG_H_ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @defgroup APP_MSG APP Message + * @brief message definition for user application task + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup APP_MSG_Exported_Types APP Message Exported Types + * @{ + */ + +/** @brief Event type definitions.*/ +typedef enum +{ + EVENT_GAP_MSG = 0x01, /**< message from gap layer for stack */ + EVENT_IO_TO_APP = 0x02, /**< message from IO to user application */ +} T_EVENT_TYPE; + +/** @brief IO type definitions for IO message, may extend as requested */ +typedef enum +{ + IO_MSG_TYPE_BT_STATUS, /**< BT status change with subtype @ref GAP_MSG_TYPE */ + IO_MSG_TYPE_KEYSCAN, /**< Key scan message with subtype @ref T_IO_MSG_KEYSCAN */ + IO_MSG_TYPE_QDECODE, /**< subtype to be defined */ + IO_MSG_TYPE_UART, /**< Uart message with subtype @ref T_IO_MSG_UART */ + IO_MSG_TYPE_KEYPAD, /**< subtype to be defined */ + IO_MSG_TYPE_IR, /**< subtype to be defined */ + IO_MSG_TYPE_GDMA, /**< subtype to be defined */ + IO_MSG_TYPE_ADC, /**< subtype to be defined */ + IO_MSG_TYPE_D3DG, /**< subtype to be defined */ + IO_MSG_TYPE_SPI, /**< subtype to be defined */ + IO_MSG_TYPE_MOUSE_BUTTON, /**< subtype to be defined */ + IO_MSG_TYPE_GPIO, /**< Gpio message with subtype @ref T_IO_MSG_GPIO*/ + IO_MSG_TYPE_MOUSE_SENSOR, /**< subtype to be defined */ + IO_MSG_TYPE_TIMER, /**< App timer message with subtype @ref T_IO_MSG_TIMER */ + IO_MSG_TYPE_WRISTBNAD, /**< wristband message with subtype @ref T_IO_MSG_WRISTBAND */ + IO_MSG_TYPE_MESH_STATUS, /**< subtype to be defined */ + IO_MSG_TYPE_KEYBOARD_BUTTON, /**< subtype to be defined */ + IO_MSG_TYPE_ANCS, /**< ANCS message*/ + IO_MSG_TYPE_IR_LEARN_DATA, /**< ir learn data message*/ + IO_MSG_TYPE_IR_LEARN_STOP, /**< ir learn stop message*/ + IO_MSG_TYPE_IR_START_SEND_REPEAT_CODE, /**< ir send repeat code message*/ + IO_MSG_TYPE_IR_SEND_COMPLETE, /**< ir send complete message*/ + IO_MSG_TYPE_BAT_LPC, /**< lpc send low power message*/ + IO_MSG_TYPE_BAT_DETECT, /**< BAT adc detect battery value*/ + IO_MSG_TYPE_AUDIO, /**< Audio message with subtype @ref T_IO_MSG_TYPE_AUDIO*/ + IO_MSG_TYPE_RESET_WDG_TIMER, /**< reset watch dog timer*/ + IO_MSG_TYPE_RESET_AON_WDG_TIMER, /**< reset aon watch dog timer*/ + IO_MSG_TYPE_BBPRO_HCI, /**< bbpro hci message*/ + IO_MSG_TYPE_RTC, /**< subtype to be defined */ + IO_MSG_TYPE_I2C, /**< subtype to be defined */ + IO_MSG_TYPE_WIFI_UART, /**< wifi uart message */ + IO_MSG_TYPE_PD_TIMER, + IO_MSG_TYPE_AMA_BT_MSG, + IO_MSG_TYPE_DFU_VALID_FW, + IO_MSG_TYPE_VOICE, /**< voice message */ + IO_MSG_TYPE_IR_FLASH, + IO_MSG_TYPE_LE_AUDIO, + IO_MSG_TYPE_DONGLE_STOP_SYNC, + IO_MSG_TYPE_LATENCY, + IO_MSG_TYPE_MOUSE_MODE_MONITOR, + IO_MSG_TYPE_BAT_FORCE_DETECT, + IO_MSG_TYPE_PPT, + IO_MSG_TYPE_DPI, + IO_MSG_TYPE_LED, + IO_MSG_TYPE_GFPS, /**< google fast fair service message */ + IO_MSG_TYPE_PPT_RESET, + IO_MSG_TYPE_PPT_CONNECTED, + IO_MSG_TYPE_IC_RESET, + IO_MSG_TYPE_FMNA, /**< apple find my message */ + IO_MSG_TYPE_ADV, + IO_MSG_TYPE_ADV_TIMEOUT, + IO_MSG_TYPE_OTHERS, +} T_IO_MSG_TYPE; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_ADC type */ +typedef enum +{ + IO_MSG_ADC_FIFO_READ_ERR, + IO_MSG_ADC_FIFO_OVERFLOW, +} T_IO_MSG_TYPE_ADC; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_AUDIO type */ +typedef enum +{ + IO_MSG_AUDIO_INPUT_BUFF_READY, + IO_MSG_AUDIO_PROCESS_DONE, + IO_MSG_AUDIO_TIMEOUT, + IO_MSG_AUDIO_HD_ATTACHED, + IO_MSG_AUDIO_HD_DETACHED, +} T_IO_MSG_TYPE_AUDIO; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_KEYSCAN type */ +typedef enum +{ + IO_MSG_KEYSCAN_RX_PKT = 1, /**< Keyscan RX data event */ + IO_MSG_KEYSCAN_MAX = 2, /**< */ + IO_MSG_KEYSCAN_ALLKEYRELEASE = 3, /**< All keys are released event */ + IO_MSG_KEYSCAN_STUCK = 4, /**< key stuck message */ + IO_MSG_KEYSCAN_LONG_PRESS = 5, + IO_MSG_KEYSCAN_REPEAT_SEND = 6, +} T_IO_MSG_KEYSCAN; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_UART type */ +typedef enum +{ + IO_MSG_UART_RX = 1, + IO_MSG_UART_RX_TIMEOUT = 2, + IO_MSG_UART_RX_OVERFLOW = 3, + IO_MSG_UART_RX_TIMEOUT_OVERFLOW = 4, + IO_MSG_UART_RX_EMPTY = 5, +} T_IO_MSG_UART; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_GPIO type */ +typedef enum +{ + IO_MSG_GPIO_KEY, /**< KEY GPIO event */ + IO_MSG_GPIO_LINE_IN, /**< LINE IN event */ + IO_MSG_GPIO_NFC, /**< NFC event */ + IO_MSG_GPIO_UART_WAKE_UP, /**< UART WAKE UP event */ + IO_MSG_GPIO_CHARGER, /**< CHARGER event */ + IO_MSG_GPIO_TRIG_SHORT_PRESS, + IO_MSG_GPIO_TRIG_LONG_PRESS_1S, + IO_MSG_GPIO_TRIG_LONG_PRESS_2S, + IO_MSG_GPIO_TRIG_LONG_PRESS_3S, + IO_MSG_GPIO_TRIG_LONG_PRESS_5S, + IO_MSG_GPIO_TRIG_LONG_PRESS_10S, + IO_MSG_GPIO_CUST_SHORT_PRESS, + IO_MSG_GPIO_CUST_LONG_PRESS_2S, + IO_MSG_GPIO_CUST_LONG_PRESS_10S, +} T_IO_MSG_GPIO; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_TIMER type */ +typedef enum +{ + IO_MSG_TIMER_ALARM, + IO_MSG_TIMER_RWS +} T_IO_MSG_TIMER; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_WRISTBNAD type */ +typedef enum +{ + IO_MSG_BWPS_TX_VALUE, + IO_MSG_RTC_TIMEROUT_WALL_CLOCK, + IO_MSG_SENSOR_WAKE_UP, + IO_MSG_LED_TWINKLE, + IO_MSG_MOTOR_VIBRATE, + IO_MSG_CHARGER_STATE, + IO_MSG_RTC_LOW_BATTERY_RESTORE, + IO_MSG_RTC_ALARM, + IO_MSG_POWER_OFF, + IO_MSG_POWER_ON, + IO_MSG_HRS_EVENT, + IO_MSG_SENSOR_MOTION_INTERRUPT, + IO_MSG_UART_CMD_DEBUG, + IO_MSG_HRS_TIMEOUT_HANDLE, + IO_MSG_UPDATE_CONPARA, + IO_MSG_REPORT_BUTTON, + IO_MSG_UART_GPS, + IO_MSG_UART_DEBUG_RX, + IO_MSG_WAS_RX_VALUE, + IO_MSG_WAS_ENABLE_CCCD, + IO_MSG_VOICE_DMA_RX, + IO_MSG_TOUCH_GES, + IO_MSG_TOUCH_INT, + IO_MSG_TOUCH_TIMEOUT, + IO_MSG_TOUCH_HANDLE, + IO_MSG_MENU_TIMER, + IO_MSG_LCD_SYNC, + IO_MSG_MAGIC_OPEN_ADV, + IO_MSG_MAGIC_PAIR_ADV, + IO_MSG_MAGIC_STOP_ADV, + IO_MSG_BREEZE_AIS_CB, + IO_MSG_ANCS_DISCOVERY, + IO_MSG_TYPE_AMS +} T_IO_MSG_WRISTBAND; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_BBPRO_HCI type */ +typedef enum +{ + IO_MSG_BBPRO_HCI_RX_PKT = 1, /**< BBPRO HCI RX data event */ + IO_MSG_BBPRO_HCI_RETRANS = 2, /**< BBPRO HCI retransmission event*/ + IO_MSG_BBPRO_HCI_RETRANS_FAIL = 3, /**< BBPRO HCI retransmission failed event*/ + IO_MSG_BBPRO_HCI_TIMEOUT = 4, /**< BBPRO HCI timeout event */ +} T_IO_MSG_BBPRO_HCI; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_UART type */ +typedef enum +{ + IO_MSG_WIFI_UART_RX_PKT = 1, /**< WIFI UART RX data event */ + IO_MSG_WIFI_UART_RETRANS = 2, /**< WIFI UART retransmission event*/ + IO_MSG_WIFI_UART_RETRANS_FAIL = 3, /**< WIFI UART retransmission failed event*/ +} T_IO_MSG_WIFI_UART; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_GFPS type */ +typedef enum +{ + IO_MSG_GFPS_ID_ROTAION, + IO_MSG_GFPS_UPDATE_RPA, + IO_MSG_GFPS_ECC, + IO_MSG_GFPS_LOCATOR_TAG_UNPAIR, +} T_IO_MSG_TYPE_GFPS; + +/** @brief IO subtype definitions for @ref IO_MSG_TYPE_FMNA type */ +typedef enum +{ + IO_MSG_FMNA_KEYROLL, + IO_MSG_FMNA_DISCONNECT, + IO_MSG_FMNA_RECONNECT_TIMEOUT, + IO_MSG_FMNA_UT_START, + IO_MSG_FMNA_MT, + IO_MSG_FMNA_GAP, +} T_IO_MSG_TYPE_FMNA; + +/** @brief IO message definition for communications between tasks*/ +typedef struct +{ + uint16_t type; + uint16_t subtype; + union + { + uint32_t param; + void *buf; + } u; +} T_IO_MSG; + +/** @} */ /* End of group APP_MSG_Exported_Types */ + +/** @} */ /* End of group APP_MSG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _APP_MSG_H_ */ diff --git a/inc/app/dfu_api.h b/inc/app/dfu_api.h new file mode 100644 index 0000000..c828cbf --- /dev/null +++ b/inc/app/dfu_api.h @@ -0,0 +1,179 @@ +/** +************************************************************************************************************ +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file dfu_api.h +* @brief APIs to implement device firmware update. +* @details OTA is used to update device firmware via bluetooth. +* @author ranhui +* @date 2015-10-29 +* @version v1.0 +************************************************************************************************************* +*/ + +#ifndef _DFU_API_H_ +#define _DFU_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "string.h" +#include "patch_header_check.h" +#include "sha256.h" + +#define MAJOR_IMG_VER(p) (p & 0xf) +#define MINOR_IMG_VER(p) ((p & 0xff0) >> 4) +#define REVISION_IMG_VER(p) ((p & 0x07fff000) >> 12) +#define RESERVE_IMG_VER(p) ((p & 0xf8000000) >> 27) + +/*convert T_IMAGE_VERSION to little endian uint32_t value, so that compare version value directly */ +#define IMAGE_VERSION_TO_LE_UINT32(ver) (((ver & 0xf) << 28 )\ + + (((ver & 0xff0) >> 4) << 20)\ + + (((ver & 0x07fff000) >> 12) << 5)\ + + ((ver & 0xf8000000) >> 27)) + + +/* dfu service uuid */ +#define GATT_UUID128_DFU_SERVICE 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x62, 0x00, 0x00 +#define GATT_UUID128_DFU_DATA 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x63, 0x00, 0x00 +#define GATT_UUID128_DFU_CONTROL_POINT 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x64, 0x00, 0x00 + +/*length of each control point procedure*/ +#define DFU_LENGTH_START_DFU (1+12+4)/*4 bytes is padding for encrypt*/ +#define DFU_LENGTH_RECEIVE_FW_IMAGE_INFO (1+2+4) //img_id + cur_offset +#define DFU_LENGTH_VALID_FW (1+2) //img_id +#define DFU_LENGTH_ACTIVE_IMAGE_RESET (1) +#define DFU_LENGTH_ACTIVE_IMAGE_RESET_TO_OTA_MODE (1+1) //uint8_t reset_mode, 1: reset to ota mode +#define DFU_LENGTH_SYSTEM_RESET (1) +#define DFU_LENGTH_REPORT_TARGET_INFO (1+2) //img_id +#define DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ (1+2+2+2+2) //conn_interval_min,conn_interval_max,conn_latency,superv_tout +#define DFU_LENGTH_BUFFER_CHECK_EN (1) +#define DFU_LENGTH_REPORT_BUFFER_CRC (1+2+2) //buf_size, buf_crc +#define DFU_LENGTH_MAX DFU_LENGTH_START_DFU + +/*length of notification*/ +#define DFU_NOTIFY_LENGTH_ARV 3 //others opcode notification length +#define DFU_NOTIFY_LENGTH_START_DFU (DFU_NOTIFY_LENGTH_ARV) +#define DFU_NOTIFY_LENGTH_VALID_FW (DFU_NOTIFY_LENGTH_ARV) +#define DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ (DFU_NOTIFY_LENGTH_ARV) +#define DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO (DFU_NOTIFY_LENGTH_ARV+4+4) //img_ver, cur_offset +#define DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN (DFU_NOTIFY_LENGTH_ARV+2+2) //buf_size, mtu_size +#define DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC (DFU_NOTIFY_LENGTH_ARV+4) //cur_offset +#define DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE (DFU_NOTIFY_LENGTH_ARV+1) //ic_type +/*max length*/ +#define DFU_NOTIFY_LENGTH_MAX DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO + + +/** @defgroup DFU_Client_Exported_Types Exported Types + * @{ + */ + +typedef union +{ + uint8_t value; + struct + { + uint8_t buf_check_en: 1; // 1:support, 0:don't support + uint8_t aesflg: 1; // 1:aes encrypt when ota, 0:not encrypt + uint8_t aesmode: 1; // 1:all data is encrypted, 0:only encrypt 16byte + uint8_t copy_img: 1; //1:support ,0:don't support + uint8_t multi_img: 1; //1:support(update multi img at a time) ,0:don't support(one img at a time) + uint8_t rsvd: 3; + } mode_flag; +} T_OTA_MODE; + + +/*each control point procedure,can't modify exist value*/ +typedef enum +{ + DFU_OPCODE_MIN = 0x00, /*control point opcode min*/ + DFU_OPCODE_START_DFU = 0x01, + DFU_OPCODE_RECEIVE_FW_IMAGE_INFO = 0x02, + DFU_OPCODE_VALID_FW = 0x03, + DFU_OPCODE_ACTIVE_IMAGE_RESET = 0x04, + DFU_OPCODE_SYSTEM_RESET = 0x05, + DFU_OPCODE_REPORT_TARGET_INFO = 0x06, + DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ = 0x07, + DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE = 0x08, + DFU_OPCODE_BUFFER_CHECK_EN = 0x09, + DFU_OPCODE_REPORT_BUFFER_CRC = 0x0a, + DFU_OPCODE_RECEIVE_IC_TYPE = 0x0b, + DFU_OPCODE_COPY_IMG = 0x0c, + DFU_OPCODE_MAX = 0x0d, /*control point opcode max*/ + DFU_OPCODE_NOTIFICATION = 0x10, /*notification opcode,fixed*/ +} T_DFU_CP_OPCODE; + +/*dfu error code*/ +typedef enum +{ + DFU_ARV_SUCCESS = 0x01, + DFU_ARV_FAIL_INVALID_PARAMETER = 0x02, + DFU_ARV_FAIL_OPERATION = 0x03, + DFU_ARV_FAIL_DATA_SIZE_EXCEEDS_LIMIT = 0x04, + DFU_ARV_FAIL_CRC_ERROR = 0x05, + DFU_ARV_FAIL_LENGTH_ERROR = 0x06, + DFU_ARV_FAIL_PROG_ERROR = 0x07, + DFU_ARV_FAIL_ERASE_ERROR = 0x08, + DFU_ARV_FAIL_SYS_VERSION_ERROR = 0x09, +} T_DFU_ARV_ERROR_CODE; + + +/** @defgroup DFU_API DFU API Sets + * @brief API sets for device firmware update implementation + * @{ + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Functions + * @{ + */ +bool dfu_reset(uint16_t image_id); + +/** + * @brief set specified image valid bit.. + * @param p_header specified image. + * @return true if ready bit sets to 0, false otherwise +*/ +extern void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header); + +extern void dfu_set_obsolete(T_IMG_CTRL_HEADER_FORMAT *p_header); + +/** + * @brief dump image header for debug. +*/ +extern void dfu_dump_header(T_IMG_HEADER_FORMAT *p_header); + +extern uint16_t dfu_process_crc(uint16_t fcs, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata, + size_t data_len); + +extern void dfu_process_sha256(SHA256_CTX *ctx, uint8_t *buf, uint32_t buf_max_size, uint8_t *pdata, + size_t data_len); + + +static inline uint32_t get_image_version_le_value_from_start_addr(uint32_t start_addr) +{ + uint32_t img_ver = 0; + T_IMG_HEADER_FORMAT *p_header = (T_IMG_HEADER_FORMAT *)start_addr; + if (p_header) + { + img_ver = (p_header->git_ver.ver_info.sub_version._version_major << 28) + + (p_header->git_ver.ver_info.sub_version._version_minor << 20) + + (p_header->git_ver.ver_info.sub_version._version_revision << 5) + + p_header->git_ver.ver_info.sub_version._version_reserve; + } + return img_ver; +} + + +/** @} */ /* End of group DFU_API_Exported_Functions */ +/** @} */ /* End of group DFU_API */ + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif + diff --git a/inc/app/readme b/inc/app/readme new file mode 100644 index 0000000..e69de29 diff --git a/inc/bluetooth/gap/bt_direct_msg.h b/inc/bluetooth/gap/bt_direct_msg.h new file mode 100644 index 0000000..94d9289 --- /dev/null +++ b/inc/bluetooth/gap/bt_direct_msg.h @@ -0,0 +1,163 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bt_direct_msg.h + * @brief This file contains all the constants and functions prototypes for BT direct message. + * @details This file is used both bredr and le. + * @author jane + * @date 2017-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef BT_DIRECT_MSG_H +#define BT_DIRECT_MSG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include "upperstack_config.h" + +/** @addtogroup BT_DIRECT_MSG BT Direct Message + * @brief BT Direct Message module + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup BT_DIRECT_MSG_Exported_Macros BT Direct Message Exported Macros + * @{ + */ + +/** @defgroup BT_DIRECT_MSG_TYPE BT Direct Message Type + * @{ + */ +#define BT_DIRECT_MSG_ISO_DATA_IND 0x01 + +#define BT_DIRECT_MSG_GATT_SERVER_SERVICE_GET_ALLOW_INFO 0xD0 +/** + * @} + */ + +/** End of BT_DIRECT_MSG_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BT_DIRECT_MSG_Exported_Types BT Direct Message Exported Types + * @{ + */ +typedef enum +{ + ISOCH_DATA_PKT_STATUS_VALID_DATA = 0, /**< Valid data. The complete SDU was received correctly.*/ + ISOCH_DATA_PKT_STATUS_POSSIBLE_ERROR_DATA = 1, /**< Possibly invalid data. The contents of the SDU may contain errors or part of the SDU may be missing. This is reported as "data with possible errors".*/ + ISOCH_DATA_PKT_STATUS_LOST_DATA = 2, /**< Part(s) of the SDU were not received correctly. This is reported as "lost data".*/ +} T_ISOCH_DATA_PKT_STATUS; + +typedef struct +{ + uint16_t conn_handle; + T_ISOCH_DATA_PKT_STATUS pkt_status_flag; + uint8_t *p_buf; + uint16_t offset; + uint16_t iso_sdu_len; + uint16_t pkt_seq_num; + bool ts_flag; + uint32_t time_stamp; +} T_BT_DIRECT_ISO_DATA_IND; + +typedef struct +{ + uint16_t conn_handle; + uint8_t remote_addr[6]; + uint8_t remote_addr_type; + uint8_t local_addr[6]; /**< Valid if remote_addr_type is not @ref GAP_REMOTE_ADDR_CLASSIC. */ + uint8_t local_addr_type; /**< Valid if remote_addr_type is not @ref GAP_REMOTE_ADDR_CLASSIC. */ + uint8_t role; /**< Valid if remote_addr_type is not @ref GAP_REMOTE_ADDR_CLASSIC. + - 0x00: Central. + - 0x01: Peripheral. */ + uint8_t service_id; + uint8_t *p_use_flag; /**< APP supply use flag to indicate whether *p_allow could be used. + - *p_use_flag = value. + - 0: Not use *p_allow. + - 1: Use *p_allow. */ + uint16_t *p_allow; /**< APP supply allowance of service. + - *p_allow = value. + - 0: Not allow. + - 1: Allow. */ + uint16_t attribute_idx; + uint16_t attribute_handle; +} T_BT_DIRECT_GATT_SERVER_SERVICE_GET_ALLOW_INFO; + +typedef union +{ + T_BT_DIRECT_ISO_DATA_IND *p_bt_direct_iso; + + T_BT_DIRECT_GATT_SERVER_SERVICE_GET_ALLOW_INFO *p_bt_direct_gatt_server_service_get_allow_info; +} T_BT_DIRECT_CB_DATA; + +/** End of BT_DIRECT_MSG_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @defgroup BT_DIRECT_MSG_EXPORT_Functions BT Direct Message Exported Functions + * + * @{ + */ + +/** + * @brief Callback to notify app + * @param[in] cb_type callback msy type @ref BT_DIRECT_MSG_TYPE. + * @param[in] p_cb_data point to callback data @ref T_BT_DIRECT_CB_DATA. + * @retval void + */ +typedef void(*P_FUN_BT_DIRECT_CB)(uint8_t cb_type, void *p_cb_data); + +/** + * @brief Register callback to gap, when messages in @ref BT_DIRECT_MSG_TYPE happens, it will callback to app. + * @param[in] app_callback Callback function provided by the APP to handle BT direct messages. + * @arg NULL -> Not send BT direct messages to APP. + * @arg Other -> Use application defined callback function. + * @return void + * + * Example usage + * \code{.c} + void app_le_gap_init() + { + ... + gap_register_direct_cb(app_gap_direct_callback); + } + \endcode + */ +void gap_register_direct_cb(P_FUN_BT_DIRECT_CB app_callback); + +/** @} */ /* End of group BT_DIRECT_MSG_EXPORT_Functions */ + +/** @} */ /* End of group BT_DIRECT_MSG */ + +/*------------------------------------------------------------------- +-------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* BT_DIRECT_MSG_H */ diff --git a/inc/bluetooth/gap/bt_types.h b/inc/bluetooth/gap/bt_types.h new file mode 100644 index 0000000..7ec2173 --- /dev/null +++ b/inc/bluetooth/gap/bt_types.h @@ -0,0 +1,752 @@ +/** + * Copyright (c) 2017, Realtek Semiconductor Corporation. All rights reserved. + */ + +#ifndef _BT_TYPES_H_ +#define _BT_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "upperstack_config.h" + +/** + * \defgroup BTTYPES BT Types + * + * \brief Defines BT related macros for the upper layers. + * + */ + + +/** + * bt_types.h + * + * \name BT_LE_LOCAL_SUPPORTED_FEATURES + * \brief BT LE Local Supported Features definitions. + * \anchor BT_LE_LOCAL_SUPPORTED_FEATURES + */ +/** + * \ingroup BTTYPES + */ +#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX0 0 + +#define LE_SUPPORT_FEATURES_ENCRYPTION_MASK_BIT ((uint8_t)0x01) +#define LE_SUPPORT_FEATURES_CONNPARA_REQ_PROC_MASK_BIT ((uint8_t)0x02) +#define LE_SUPPORT_FEATURES_EXTENDED_REJECTION_IND_MASK_BIT ((uint8_t)0x04) +#define LE_SUPPORT_FEATURES_SLAVE_INITIATED_FEATURE_EXCHANGE_MASK_BIT ((uint8_t)0x08) +#define LE_SUPPORT_FEATURES_LE_PING_MASK_BIT ((uint8_t)0x10) +#define LE_SUPPORT_FEATURES_LE_DATA_LENGTH_EXTENSION_MASK_BIT ((uint8_t)0x20) +#define LE_SUPPORT_FEATURES_LL_PRIVACY_MASK_BIT ((uint8_t)0x40) +#define LE_SUPPORT_FEATURES_EXTENDED_SCANNER_FILTER_POLICY_MASK_BIT ((uint8_t)0x80) + +#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX1 1 + +#define LE_SUPPORT_FEATURES_LE_2M_MASK_BIT ((uint8_t)0x01) +#define LE_SUPPORT_FEATURES_STABLE_MODULATION_INDEX_TX_MASK_BIT ((uint8_t)0x02) +#define LE_SUPPORT_FEATURES_STABLE_MODULATION_INDEX_RX_MASK_BIT ((uint8_t)0x04) +#define LE_SUPPORT_FEATURES_LE_CODED_PHY_MASK_BIT ((uint8_t)0x08) +#define LE_SUPPORT_FEATURES_LE_EXTENDED_ADV_BIT ((uint8_t)0x10) +#define LE_SUPPORT_FEATURES_LE_PERIODIC_ADV_MASK_BIT ((uint8_t)0x20) +#define LE_SUPPORT_FEATURES_CSA2_BIT ((uint8_t)0x40) +#define LE_SUPPORT_FEATURES_LE_POWER_CLASS1_MASK_BIT ((uint8_t)0x80) + +#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX2 2 + +#define LE_SUPPORT_FEATURES_MIN_NUM_USED_CHANNEL_MASK_BIT ((uint8_t)0x01) +#define LE_SUPPORT_FEATURES_CONNECTION_CTE_REQUEST_MASK_BIT ((uint8_t)0x02) +#define LE_SUPPORT_FEATURES_CONNECTION_CTE_RESPONSE_MASK_BIT ((uint8_t)0x04) +#define LE_SUPPORT_FEATURES_CONNECTIONLESS_CTE_TRANSMITTER_MASK_BIT ((uint8_t)0x08) +#define LE_SUPPORT_FEATURES_CONNECTIONLESS_CTE_RECEIVER_MASK_BIT ((uint8_t)0x10) +#define LE_SUPPORT_FEATURES_AOD_MASK_BIT ((uint8_t)0x20) +#define LE_SUPPORT_FEATURES_AOA_MASK_BIT ((uint8_t)0x40) +#define LE_SUPPORT_FEATURES_RECEIVING_CTE_MASK_BIT ((uint8_t)0x80) + +#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX3 3 + +#define LE_SUPPORT_FEATURES_PAST_SENDER_MASK_BIT ((uint8_t)0x01) +#define LE_SUPPORT_FEATURES_PAST_RECIPIENT_MASK_BIT ((uint8_t)0x02) +#define LE_SUPPORT_FEATURES_SLEEP_CLOCK_ACCURACY_UPDATES_MASK_BIT ((uint8_t)0x04) +#define LE_SUPPORT_FEATURES_REMOTE_PUBLIC_KEY_VALIDATION_MASK_BIT ((uint8_t)0x08) +#define LE_SUPPORT_FEATURES_CIS_MASTER_MASK_BIT ((uint8_t)0x10) +#define LE_SUPPORT_FEATURES_CIS_SLAVE_MASK_BIT ((uint8_t)0x20) +#define LE_SUPPORT_FEATURES_ISOCHRONOUS_BROADCASTER_MASK_BIT ((uint8_t)0x40) +#define LE_SUPPORT_FEATURES_SYNCHRONIZED_RECEIVER_MASK_BIT ((uint8_t)0x80) + +#define LE_SUPPORT_FEATURES_MASK_ARRAY_INDEX4 4 + +#define LE_SUPPORT_FEATURES_ISOCH_HOST_SUPPORT_MASK_BIT ((uint8_t)0x01) +#define LE_SUPPORT_FEATURES_LE_POWER_CONTROL_REQUEST_MASK_BIT ((uint8_t)0x02) +#define LE_SUPPORT_FEATURES_LE_POWER_CHANGE_INDICATION_MASK_BIT ((uint8_t)0x04) +#define LE_SUPPORT_FEATURES_LE_PATH_LOSS_MONITORING_MASK_BIT ((uint8_t)0x08) + +/** + * bt_types.h + * + * \name BT_LE_SET_HOST_FEATURE + * \brief BT LE Set Host Feature definitions. + * \anchor BT_LE_SET_HOST_FEATURE + */ +/** + * \ingroup BTTYPES + */ +#define LE_SET_HOST_FEATURE_BIT_VALUE_DISABLE ((uint8_t)0x00) +#define LE_SET_HOST_FEATURE_BIT_VALUE_ENABLE ((uint8_t)0x01) +#define LE_SET_HOST_FEATURE_BIT_VALUE_RFU ((uint8_t)0xFF) + +#define LE_SET_HOST_FEATURE_BIT_NUMBER_ISOCH_HOST_SUPPORT ((uint8_t)0x20) +#define LE_SET_HOST_FEATURE_BIT_NUMBER_RFU ((uint8_t)0xFF) + +/** + * bt_types.h + * + * \name BT_STACK_MODULE_ERROR + * \brief BT stack module error code mask. + * \anchor BT_STACK_MODULE_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define GAP_ERR 0x0000 +#define HCI_ERR 0x0100 +#define L2C_ERR 0x0200 +#define SDP_ERR 0x0300 +#define ATT_ERR 0x0400 +#define SM_ERR 0x0500 + +#define GATT_ERR 0x0C00 +#define APP_ERR 0x0D00 + +/** + * bt_types.h + * + * \name BT_HCI_ERROR + * \brief BT hci error code definitions. + * \anchor BT_HCI_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define HCI_SUCCESS 0x00 +#define HCI_ERR_UNKNOWN_CMD 0x01 +#define HCI_ERR_UNKNOWN_CONN_ID 0x02 +#define HCI_ERR_HARDWARE_FAIL 0x03 +#define HCI_ERR_PAGE_TIMEOUT 0x04 +#define HCI_ERR_AUTHEN_FAIL 0x05 +#define HCI_ERR_KEY_MISSING 0x06 +#define HCI_ERR_MEMORY_FULL 0x07 +#define HCI_ERR_CONN_TIMEOUT 0x08 +#define HCI_ERR_MAX_NUM_CONN 0x09 +#define HCI_ERR_MAX_NUM_SCO_CONN 0x0A /* 10 */ +#define HCI_ERR_ACL_CONN_EXIST 0x0B /* 11 */ +#define HCI_ERR_CMD_DISALLOWED 0x0C /* 12 */ +#define HCI_ERR_REJECT_LIMITED_RESOURCE 0x0D /* 13 */ +#define HCI_ERR_REJECT_SECURITY_REASON 0x0E /* 14 */ +#define HCI_ERR_REJECT_UNACCEPTABLE_ADDR 0x0F /* 15 */ +#define HCI_ERR_HOST_TIMEOUT 0x10 /* 16 */ +#define HCI_ERR_UNSUPPORTED_PARAM 0x11 /* 17 */ +#define HCI_ERR_INVALID_PARAM 0x12 /* 18 */ +#define HCI_ERR_REMOTE_USER_TERMINATE 0x13 /* 19 */ +#define HCI_ERR_REMOTE_LOW_RESOURCE 0x14 /* 20 */ +#define HCI_ERR_REMOTE_POWER_OFF 0x15 /* 21 */ +#define HCI_ERR_LOCAL_HOST_TERMINATE 0x16 /* 22 */ +#define HCI_ERR_REPEATED_ATTEMPTS 0x17 /* 23 */ +#define HCI_ERR_PARING_NOT_ALLOWED 0x18 /* 24 */ +#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 /* 25 */ +#define HCI_ERR_UNSUPPORTED_REMOTE_FEAT 0x1A /* 26 */ +#define HCI_ERR_SCO_OFFSET_REJECTED 0x1B /* 27 */ +#define HCI_ERR_SCO_INTERVAL_REJECTED 0x1C /* 28 */ +#define HCI_ERR_SCO_AIR_MODE_REJECTED 0x1D /* 29 */ +#define HCI_ERR_INVALID_LMP_PARAM 0x1E /* 30 */ +#define HCI_ERR_UNSPECIFIED_ERROR 0x1F /* 31 */ +#define HCI_ERR_UNSUPPORTED_LMP_PARAM 0x20 /* 32 */ +#define HCI_ERR_ROLE_CHANGE_NOT_ALLOWED 0x21 /* 33 */ +#define HCI_ERR_LMP_RESPONSE_TIMEOUT 0x22 /* 34 */ +#define HCI_ERR_LMP_ERROR_TRANS_COLLISION 0x23 /* 35 */ +#define HCI_ERR_LMP_PDU_NOT_ALLOWED 0x24 /* 36 */ +#define HCI_ERR_ENCRYPT_MODE_NOT_ACCEPTABLE 0x25 /* 37 */ +#define HCI_ERR_UNIT_KEY_USED 0x26 /* 38 */ +#define HCI_ERR_QOS_NOT_SUPPORTED 0x27 /* 39 */ +#define HCI_ERR_INSTANT_PASSED 0x28 /* 40 */ +#define HCI_ERR_PAIR_UNIT_KEY_NOT_SUPPORT 0x29 /* 41 */ +#define HCI_ERR_DIFF_TRANS_COLLISION 0x2A /* 42 */ +#define HCI_ERR_QOS_UNACCEPTABLE_PARAM 0x2C /* 44 */ +#define HCI_ERR_QOS_REJECT 0x2D /* 45 */ +#define HCI_ERR_CHANN_ASSESS_NOT_SUPPORT 0x2E /* 46 */ +#define HCI_ERR_INSUFFICIENT_SECURITY 0x2F /* 47 */ +#define HCI_ERR_PARAM_OUT_OF_RANGE 0x30 /* 48 */ +#define HCI_ERR_ROLE_SWITCH_PENDING 0x32 /* 50 */ +#define HCI_ERR_RESERVED_SLOT_VIOLATION 0x34 /* 52 */ +#define HCI_ERR_ROLE_SWITCH_FAILED 0x35 /* 53 */ +#define HCI_ERR_EXT_INQUIRY_RSP_TOO_LARGE 0x36 /* 54 */ +#define HCI_ERR_SSP_NOT_SUPPORTED_BY_HOST 0x37 /* 55 */ +#define HCI_ERR_HOST_BUSY_PAIRING 0x38 /* 56 */ +#define HCI_ERR_REJECT_NO_SUITABLE_CHANN 0x39 /* 57 */ +#define HCI_ERR_CONTROLLER_BUSY 0x3A /* 58 */ +#define HCI_ERR_UNACCEPTABLE_CONN_INTERVAL 0x3B /* 59 */ +#define HCI_ERR_DIRECTED_ADV_TIMEOUT 0x3C /* 60 */ +#define HCI_ERR_MIC_FAILURE 0x3D /* 61 */ +#define HCI_ERR_FAIL_TO_ESTABLISH_CONN 0x3E /* 62 */ +#define HCI_ERR_MAC_CONN_FAIL 0x3F /* 63 */ +#define HCI_ERR_COARSE_CLOCK_ADJUST_REJECTED 0x40 +#define HCI_ERR_TYPE0_SUBMAP_NOT_DEFINED 0x41 +#define HCI_ERR_UNKNOWN_ADVERTISING_IDENTIFIER 0x42 +#define HCI_ERR_LIMIT_REACHED 0x43 +#define HCI_ERR_OPERATION_CANCELLED_BY_HOST 0x44 +#define HCI_ERR_OPERATION_PACKET_TOO_LONG 0x45 + +/* hci local error code */ +#define HCI_ERR_INVALID_ADDR 0x64 /* 100 */ +#define HCI_ERR_TIMEOUT 0x65 /* 101 */ +#define HCI_ERR_OUT_OF_SYNC 0x66 /* 102 */ +#define HCI_ERR_NO_DESCRIPTOR 0x67 /* 103 */ +#define HCI_ERR_NO_MEMORY 0x68 /* 104 */ +#define HCI_ERR_INVALID_STATE 0x69 /* 105 */ +#define HCI_ERR_LOCAL_KEY_MISSING 0x6A /* 106 */ + +/** + * bt_types.h + * + * \name BT_L2CAP_ERROR + * \brief BT l2cap error code definitions. + * \anchor BT_L2CAP_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define L2C_SUCCESS 0x00 + +#define L2C_CONN_ACCEPT 0x0000 +#define L2C_CONN_RSP_PENDING 0x0001 +#define L2C_CONN_RSP_INVALID_PSM 0x0002 +#define L2C_CONN_RSP_SECURITY_BLOCK 0x0003 +#define L2C_CONN_RSP_NO_RESOURCE 0x0004 +#define L2C_CONN_RSP_INVALID_PARAM 0x0005 +#define L2C_CONN_RSP_INVALID_SOURCE_CID 0x0006 +#define L2C_CONN_RSP_SOURCE_CID_ALLOCATED 0x0007 + +/* requset cmd reject reasons */ +#define L2C_CMD_REJ_NOT_UNDERSTOOD 0x0000 +#define L2C_CMD_REJ_SIGNAL_MTU_EXCEEDED 0x0001 +#define L2C_CMD_REJ_INVALID_CID_IN_REQ 0x0002 + +/* config response result codes */ +#define L2C_CFG_RSP_SUCCESS 0x0000 +#define L2C_CFG_RSP_UNACCEPTABLE_PARAMS 0x0001 +#define L2C_CFG_RSP_REJECTED 0x0002 +#define L2C_CFG_RSP_UNKNOWN_OPTIONS 0x0003 +#define L2C_CFG_RSP_PENDING 0x0004 +#define L2C_CFG_RSP_FLOW_SPEC_REJECTED 0x0005 + +#define L2C_LE_CREDIT_CONN_SUCCESS 0x0000 +#define L2C_LE_CREDIT_RSP_PSM_NOT_SUPPORTED 0x0002 +#define L2C_LE_CREDIT_RSP_NO_RESOURCES 0x0004 +#define L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHEN 0x0005 +#define L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHOR 0x0006 +#define L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP_KEY_SIZE 0x0007 +#define L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP 0x0008 +#define L2C_LE_CREDIT_RSP_INVALID_SOURCE_CID 0x0009 +#define L2C_LE_CREDIT_RSP_SOURCE_CID_ALREADY_ALLOC 0x000A + +/* status for connection updata response */ +#define L2C_LE_CONN_UPDATE_ACCEPT 0x0000 +#define L2C_LE_CONN_UPDATE_RSP_REJECT 0x0001 +#define L2C_LE_CONN_UPDATE_RSP_TOUT 0x0002 + +/* l2cap error code */ +#define L2C_ERR_REJ_BASE 0x0010 +#define L2C_ERR_CFG_BASE 0x0020 +#define L2C_ERR_LE_CREDIT_BASE 0x0030 +#define L2C_ERR_LE_CONN_UPDATE_BASE 0x0040 +#define L2C_ERR_VND_BASE 0x00F0 + +#define L2C_ERR_PENDING L2C_CONN_RSP_PENDING +#define L2C_ERR_INVALID_PSM L2C_CONN_RSP_INVALID_PSM +#define L2C_ERR_SECURITY_BLOCK L2C_CONN_RSP_SECURITY_BLOCK +#define L2C_ERR_NO_RESOURCE L2C_CONN_RSP_NO_RESOURCE +#define L2C_ERR_INVALID_PARAM L2C_CONN_RSP_INVALID_PARAM +#define L2C_ERR_INVALID_SOURCE_CID L2C_CONN_RSP_INVALID_SOURCE_CID +#define L2C_ERR_SOURCE_CID_ALLOCATED L2C_CONN_RSP_SOURCE_CID_ALLOCATED + +#define L2C_ERR_CMD_NOT_UNDERSTOOD (L2C_ERR_REJ_BASE + L2C_CMD_REJ_NOT_UNDERSTOOD) +#define L2C_ERR_SIGNAL_MTU_EXCEEDED (L2C_ERR_REJ_BASE + L2C_CMD_REJ_SIGNAL_MTU_EXCEEDED) +#define L2C_ERR_INVALID_CID_IN_REQ (L2C_ERR_REJ_BASE + L2C_CMD_REJ_INVALID_CID_IN_REQ) + +#define L2C_ERR_CFG_UNACCEPTABLE_PARAM (L2C_ERR_CFG_BASE + L2C_CFG_RSP_UNACCEPTABLE_PARAMS) +#define L2C_ERR_CFG_REJECTED (L2C_ERR_CFG_BASE + L2C_CFG_RSP_REJECTED) +#define L2C_ERR_CFG_UNKNOWN_OPTIONS (L2C_ERR_CFG_BASE + L2C_CFG_RSP_UNKNOWN_OPTIONS) +#define L2C_ERR_CFG_PENDING (L2C_ERR_CFG_BASE + L2C_CFG_RSP_PENDING) +#define L2C_ERR_CFG_FLOW_SPEC_REJECTED (L2C_ERR_CFG_BASE + L2C_CFG_RSP_FLOW_SPEC_REJECTED) + +#define L2C_ERR_LE_CREDIT_PSM_NOT_SUPPORTED (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_PSM_NOT_SUPPORTED) +#define L2C_ERR_LE_CREDIT_NO_RESOURCES (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_NO_RESOURCES) +#define L2C_ERR_LE_CREDIT_INSUFFICIENT_AUTHEN (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHEN) +#define L2C_ERR_LE_CREDIT_INSUFFICIENT_AUTHOR (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_AUTHOR) +#define L2C_ERR_LE_CREDIT_INSUFFICIENT_ENCRYP_KEY_SIZE (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP_KEY_SIZE) +#define L2C_ERR_LE_CREDIT_INSUFFICIENT_ENCRYP (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INSUFFICIENT_ENCRYP) +#define L2C_ERR_LE_CREDIT_INVALID_SOURCE_CID (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_INVALID_SOURCE_CID) +#define L2C_ERR_LE_CREDIT_SOURCE_CID_ALREADY_ALLOC (L2C_ERR_LE_CREDIT_BASE + L2C_LE_CREDIT_RSP_SOURCE_CID_ALREADY_ALLOC) + +#define L2C_ERR_LE_CONN_PARAM_UPDATE_REJECT (L2C_ERR_LE_CONN_UPDATE_BASE + L2C_LE_CONN_UPDATE_RSP_REJECT) +#define L2C_ERR_LE_CONN_PARAM_UPDATE_TOUT (L2C_ERR_LE_CONN_UPDATE_BASE + L2C_LE_CONN_UPDATE_RSP_TOUT) + +#define L2C_ERR_VND_CREDITS_EXCEED (L2C_ERR_VND_BASE + 0x00) +#define L2C_ERR_VND_INVAILD_PDU (L2C_ERR_VND_BASE + 0x01) +#define L2C_ERR_VND_CREDITS_LACK (L2C_ERR_VND_BASE + 0x02) +#define L2C_ERR_VND_NO_MEMORY (L2C_ERR_VND_BASE + 0x03) +#define L2C_ERR_VND_INVALID_STATE (L2C_ERR_VND_BASE + 0x04) +#define L2C_ERR_VND_INVALID_RX_SEQ (L2C_ERR_VND_BASE + 0x05) +#define L2C_ERR_VND_TIMEOUT (L2C_ERR_VND_BASE + 0x06) +#define L2C_ERR_VND_INVALID_MODE (L2C_ERR_VND_BASE + 0x07) +#define L2C_ERR_VND_REMOTE_DISCONNECT (L2C_ERR_VND_BASE + 0x08) + +/** + * bt_types.h + * + * \name BT_ATT_ERROR + * \brief BT att error code definitions. + * \anchor BT_ATT_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define ATT_SUCCESS 0 /**< internal value .. */ +#define ATT_ERR_INVALID_HANDLE 0x01 /**< Attribute handle value given was not valid on this attribute server */ +#define ATT_ERR_READ_NOT_PERMITTED 0x02 /**< Attribute cannot be read */ +#define ATT_ERR_WRITE_NOT_PERMITTED 0x03 /**< Attribute cannot be written */ +#define ATT_ERR_INVALID_PDU 0x04 /**< The attribute PDU was invalid */ +#define ATT_ERR_INSUFFICIENT_AUTHEN 0x05 /**< The attribute requires authentication before it can be read or written */ +#define ATT_ERR_UNSUPPORTED_REQ 0x06 /**< Attribute server doesn't support the request received from the attribute client */ +#define ATT_ERR_INVALID_OFFSET 0x07 /**< Offset specified was past the end of the attribute */ +#define ATT_ERR_INSUFFICIENT_AUTHOR 0x08 /**< The attribute requires an authorization before it can be read or written */ +#define ATT_ERR_PREP_QUEUE_FULL 0x09 /**< Too many prepare writes have been queued */ +#define ATT_ERR_ATTR_NOT_FOUND 0x0A /**< No attribute found within the given attribute handle range */ +#define ATT_ERR_ATTR_NOT_LONG 0x0B /**< Attribute cannot be read or written using the Read Blob Request or Prepare Write Request */ +#define ATT_ERR_INSUFFICIENT_KEY_SIZE 0x0C /**< The Encryption Key Size used for encrypting this link is insufficient */ +#define ATT_ERR_INVALID_VALUE_SIZE 0x0D /**< The attribute value length is invalid for the operation */ +#define ATT_ERR_UNLIKELY 0x0E /**< The attribute request that was requested has encountered an error that was very unlikely, and therefore could not be completed as requested */ +#define ATT_ERR_INSUFFICIENT_ENCRYPT 0x0F /**< The attribute requires encryption before it can be read or written */ +#define ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10 /**< The attribute type is not a supported grouping attribute as defined by a higher layer specification */ +#define ATT_ERR_INSUFFICIENT_RESOURCES 0x11 /**< Insufficient Resources to complete the request */ +#define ATT_ERR_DATABASE_OUT_OF_SYNC 0x12 /**< The server requests the client to rediscover the database. */ +#define ATT_ERR_VALUE_NOT_ALLOWED 0x13 /**< The attribute parameter value was not allowed. */ + +/* profile dependent application error codes >= 0x80: */ +#define ATT_ERR_INVALID_VALUE 0x80 /**< The attribute value is invalid for the operation */ + +/* manufacturer specific error codes that are "missing" in GATT spec. >= 0xC0: */ +#define ATT_ERR_INVALID_CCC_BITS 0xC0 /**< Invalid client char. config. bits */ +#define ATT_ERR_INVALID_SIGNED_COUNT 0xC1 /**< Invalid sign count */ +#define ATT_ERR_INVALID_SIGNED_MAC_FAILED 0xC2 /**< Invalid sign mac value */ +#define ATT_ERR_MIN_APPLIC_CODE 0xC3 + +/* error codes common to various profiles (see "CSS v2.pdf"), >= 0xE0 */ +#define ATT_ERR_WRITE_REQUEST_REJECTED 0xFC /**< Write Request Rejected */ +#define ATT_ERR_CCCD_IMPROPERLY_CONFIGURED 0xFD /**< CCCD improperly configured */ +#define ATT_ERR_PROC_ALREADY_IN_PROGRESS 0xFE /**< Procedure Already in Progress */ +#define ATT_ERR_OUT_OF_RANGE 0xFF /**< An attribute value is out of range as defined by a profile or service specification. */ + +/** + * bt_types.h + * + * \name BT_GATT_ERROR + * \brief BT gatt error code definitions. + * \anchor BT_GATT_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define GATT_SUCCESS 0x00 +#define GATT_ERR_OUT_OF_RESOURCE 0x01 +#define GATT_ERR_UNSUPPORTED 0x02 +#define GATT_ERR_INVALID_ROLE 0x03 +#define GATT_ERR_INVALID_STATE 0x04 +#define GATT_ERR_INVALID_CODING 0x05 +#define GATT_ERR_INVALID_HANDLE 0x06 +#define GATT_ERR_INVALID_PARAM 0x07 +#define GATT_ERR_INTERNAL 0x08 +#define GATT_ERR_NOT_ALLOWED 0x09 +#define GATT_ERR_NOTIF_IND_NOT_CFG 0x0A +#define GATT_ERR_NOTIF_IND_CFG 0x0B +#define GATT_ERR_NOTIF_IND_CONF_PD 0x0C +#define GATT_ERR_TIMEOUT 0x0D +#define GATT_ERR_LINK_DEACTIVATED 0x0E +#define GATT_ERR_NOT_AUTHENTICATED 0x0F +#define GATT_ERR_NOT_ENCRYPTED 0x10 +#define GATT_ERR_PROC_FAIL 0x11 + +/* sm error code */ +#define SM_SUCCESS 0x00 +/* SMP_OP_PAIRING_FAILED causes */ +#define SMP_ERR_SUCCESS 0x00 +#define SMP_ERR_PASSKEY_ENTRY_FAIL 0x01 +#define SMP_ERR_OOB_NOT_AVAIABLE 0x02 +#define SMP_ERR_AUTHEN_REQUIREMENTS 0x03 +#define SMP_ERR_CFM_VALUE_FAILED 0x04 +#define SMP_ERR_PAIRING_NOT_SUPPORTED 0x05 +#define SMP_ERR_ENCRYPTION_KEY_SIZE 0x06 +#define SMP_ERR_CMD_NOT_SUPPORTED 0x07 +#define SMP_ERR_UNSPECIFIED_REASON 0x08 +#define SMP_ERR_REPEATED_ATTEMPTS 0x09 +#define SMP_ERR_INVALID_PARAM 0x0A +#define SMP_ERR_DHKEY_CHECK_FAILED 0x0B +#define SMP_ERR_NUMERIC_COMPARISION_FAIL 0x0C +#define SMP_ERR_BREDR_PAIRING_IN_PROGRESS 0x0D +#define SMP_ERR_CRS_TRANS_KEY_GEN_NOT_ALLOW 0x0E + +#define SM_ERR_NO_ENTRY 0xE1 +#define SM_ERR_DB_FULL 0xE2 +#define SM_ERR_INVALID_PARAM 0xE3 +#define SM_ERR_INSUFFICIENT_LINK_KEY 0xE4 +#define SM_ERR_LE_ADDR_NOT_RESOLVED 0xE5 +#define SM_ERR_INVALID_STATE 0xE6 +#define SM_ERR_NO_RESOURCE 0xE7 +#define SM_ERR_LINK_KEY_MISSING 0xE8 +#define SM_ERR_DISCONNECT 0xE9 +#define SM_ERR_PARING_NOT_ALLOWED 0xEA +#define SM_ERR_KEY_SAVE_FAILED 0xEB +#define SM_ERR_TIMEOUT 0xEC +#define SM_ERR_UNKNOWN 0xED +#define SM_ERR_NO_PAIRABLE_MODE 0xEF + +/** + * bt_types.h + * + * \name BT_BTIF_ERROR + * \brief BT btif error code definitions. + * \anchor BT_BTIF_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define BTIF_ERR 0x0000 +#define BTIF_SUCCESS 0x00 +#define BTIF_ACCEPT 0x01 +#define BTIF_ERR_REJECT 0x02 +#define BTIF_ERR_NO_RESOURCE 0x03 +#define BTIF_ERR_INVALID_PARAM 0x04 +#define BTIF_ERR_INVALID_STATE 0x05 +#define BTIF_ERR_CONN_DISCONNECT 0x06 +#define BTIF_ERR_CONN_LOST 0x07 +#define BTIF_ERR_AUTHEN_FAIL 0x08 +#define BTIF_ERR_INIT_TOUT 0x09 +#define BTIF_ERR_INIT_OUT_OF_SYNC 0x0A +#define BTIF_ERR_INIT_HARDWARE_ERROR 0x0B +#define BTIF_ERR_LOWER_LAYER_ERROR 0x0C +#define BTIF_ERR_ADDR_NOT_RESOLVED 0x0D +#define BTIF_ERR_TOUT 0x0E + +#define BTIF_ERR_UNSPECIFIED 0xFD +#define BTIF_ERR_NOT_SUPPORTED 0xFE + +/** + * bt_types.h + * + * \name BT_GAP_ERROR + * \brief BT GAP error code definitions. + * \anchor BT_GAP_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define GAP_SUCCESS 0x00 +#define GAP_ACCEPT 0x01 +#define GAP_ERR_REJECT 0x02 +#define GAP_ERR_NO_RESOURCE 0x03 +#define GAP_ERR_INVALID_PARAM 0x04 +#define GAP_ERR_INVALID_STATE 0x05 +#define GAP_ERR_CONN_DISCONNECT 0x06 +#define GAP_ERR_CONN_LOST 0x07 +#define GAP_ERR_AUTHEN_FAIL 0x08 +#define GAP_ERR_INIT_TOUT 0x09 +#define GAP_ERR_INIT_OUT_OF_SYNC 0x0A +#define GAP_ERR_INIT_HARDWARE_ERROR 0x0B +#define GAP_ERR_LOWER_LAYER_ERROR 0x0C +#define GAP_ERR_ADDR_NOT_RESOLVED 0x0D +#define GAP_ERR_TOUT 0x0E + +#define GAP_ERR_REQ_FAILED 0xFB +#define GAP_ERR_SW_RESET 0xFC +#define GAP_ERR_UNSPECIFIED 0xFD +#define GAP_ERR_NOT_SUPPORTED 0xFE + +/** + * bt_types.h + * + * \name BT_APP_ERROR + * \brief BT APP error code definitions. + * \anchor BT_APP_ERROR + */ +/** + * \ingroup BTTYPES + */ +#define APP_SUCCESS 0x00 +#define APP_ERR_PENDING 0x01 +#define APP_ERR_ACCEPT 0x03 +#define APP_ERR_REJECT 0x04 +#define APP_ERR_NOT_RELEASE 0x05 + +/** + * bt_types.h + * + * \name BT_BYTE_ORDER + * \brief BT buffer/array byte-order utility macros. + * \anchor BT_BYTE_ORDER + */ +/** + * \ingroup BTTYPES + */ +/** Calculate integer bit count of b'1 */ +#define INT_BIT_COUNT(integer, count) { \ + count = 0; \ + while (integer) \ + { \ + count++; \ + integer &= integer - 1; \ + } \ + } + +/** Stream skip len */ +#define STREAM_SKIP_LEN(s, len) { \ + s += len; \ + } + +/** Stream to array */ +#define STREAM_TO_ARRAY(a, s, len) { \ + uint32_t ii; \ + for (ii = 0; ii < len; ii++) \ + { \ + *((uint8_t *)(a) + ii) = *s++; \ + } \ + } + +/** Array to stream */ +#define ARRAY_TO_STREAM(s, a, len) { \ + uint32_t ii; \ + for (ii = 0; ii < len; ii++) \ + { \ + *s++ = *((uint8_t *)(a) + ii); \ + } \ + } + +/** Little Endian stream to uint8 */ +#define LE_STREAM_TO_UINT8(u8, s) { \ + u8 = (uint8_t)(*s); \ + s += 1; \ + } + +/** Little Endian stream to uint16 */ +#define LE_STREAM_TO_UINT16(u16, s) { \ + u16 = ((uint16_t)(*(s + 0)) << 0) + \ + ((uint16_t)(*(s + 1)) << 8); \ + s += 2; \ + } + +/** Little Endian stream to uint24 */ +#define LE_STREAM_TO_UINT24(u24, s) { \ + u24 = ((uint32_t)(*(s + 0)) << 0) + \ + ((uint32_t)(*(s + 1)) << 8) + \ + ((uint32_t)(*(s + 2)) << 16); \ + s += 3; \ + } + +/** Little Endian stream to uint32 */ +#define LE_STREAM_TO_UINT32(u32, s) { \ + u32 = ((uint32_t)(*(s + 0)) << 0) + \ + ((uint32_t)(*(s + 1)) << 8) + \ + ((uint32_t)(*(s + 2)) << 16) + \ + ((uint32_t)(*(s + 3)) << 24); \ + s += 4; \ + } + +/** Little Endian uint8 to stream */ +#define LE_UINT8_TO_STREAM(s, u8) { \ + *s++ = (uint8_t)(u8); \ + } + +/** Little Endian uint16 to stream */ +#define LE_UINT16_TO_STREAM(s, u16) { \ + *s++ = (uint8_t)((u16) >> 0); \ + *s++ = (uint8_t)((u16) >> 8); \ + } + +/** Little Endian uint24 to stream */ +#define LE_UINT24_TO_STREAM(s, u24) { \ + *s++ = (uint8_t)((u24) >> 0); \ + *s++ = (uint8_t)((u24) >> 8); \ + *s++ = (uint8_t)((u24) >> 16); \ + } + +/** Little Endian uint32 to stream */ +#define LE_UINT32_TO_STREAM(s, u32) { \ + *s++ = (uint8_t)((u32) >> 0); \ + *s++ = (uint8_t)((u32) >> 8); \ + *s++ = (uint8_t)((u32) >> 16); \ + *s++ = (uint8_t)((u32) >> 24); \ + } + +/** Little Endian array to uint8 */ +#define LE_ARRAY_TO_UINT8(u8, a) { \ + u8 = (uint8_t)(*(a + 0)); \ + } + +/** Little Endian array to uint16 */ +#define LE_ARRAY_TO_UINT16(u16, a) { \ + u16 = ((uint16_t)(*(a + 0)) << 0) + \ + ((uint16_t)(*(a + 1)) << 8); \ + } + +/** Little Endian array to uint24 */ +#define LE_ARRAY_TO_UINT24(u24, a) { \ + u24 = ((uint32_t)(*(a + 0)) << 0) + \ + ((uint32_t)(*(a + 1)) << 8) + \ + ((uint32_t)(*(a + 2)) << 16); \ + } + +/** Little Endian array to uint32 */ +#define LE_ARRAY_TO_UINT32(u32, a) { \ + u32 = ((uint32_t)(*(a + 0)) << 0) + \ + ((uint32_t)(*(a + 1)) << 8) + \ + ((uint32_t)(*(a + 2)) << 16) + \ + ((uint32_t)(*(a + 3)) << 24); \ + } + +/** Little Endian uint8 to array */ +#define LE_UINT8_TO_ARRAY(a, u8) { \ + *((uint8_t *)(a) + 0) = (uint8_t)(u8); \ + } + +/** Little Endian uint16 to array */ +#define LE_UINT16_TO_ARRAY(a, u16) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u16) >> 0); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u16) >> 8); \ + } + +/** Little Endian uint24 to array */ +#define LE_UINT24_TO_ARRAY(a, u24) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u24) >> 0); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u24) >> 8); \ + *((uint8_t *)(a) + 2) = (uint8_t)((u24) >> 16); \ + } + +/** Little Endian uint32 to array */ +#define LE_UINT32_TO_ARRAY(a, u32) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u32) >> 0); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u32) >> 8); \ + *((uint8_t *)(a) + 2) = (uint8_t)((u32) >> 16); \ + *((uint8_t *)(a) + 3) = (uint8_t)((u32) >> 24); \ + } + +/** Big Endian stream to uint8 */ +#define BE_STREAM_TO_UINT8(u8, s) { \ + u8 = (uint8_t)(*(s + 0)); \ + s += 1; \ + } + +/** Big Endian stream to uint16 */ +#define BE_STREAM_TO_UINT16(u16, s) { \ + u16 = ((uint16_t)(*(s + 0)) << 8) + \ + ((uint16_t)(*(s + 1)) << 0); \ + s += 2; \ + } + +/** Big Endian stream to uint24 */ +#define BE_STREAM_TO_UINT24(u24, s) { \ + u24 = ((uint32_t)(*(s + 0)) << 16) + \ + ((uint32_t)(*(s + 1)) << 8) + \ + ((uint32_t)(*(s + 2)) << 0); \ + s += 3; \ + } + +/** Big Endian stream to uint32 */ +#define BE_STREAM_TO_UINT32(u32, s) { \ + u32 = ((uint32_t)(*(s + 0)) << 24) + \ + ((uint32_t)(*(s + 1)) << 16) + \ + ((uint32_t)(*(s + 2)) << 8) + \ + ((uint32_t)(*(s + 3)) << 0); \ + s += 4; \ + } + +/** Big Endian uint8 to stream */ +#define BE_UINT8_TO_STREAM(s, u8) { \ + *s++ = (uint8_t)(u8); \ + } + +/** Big Endian uint16 to stream */ +#define BE_UINT16_TO_STREAM(s, u16) { \ + *s++ = (uint8_t)((u16) >> 8); \ + *s++ = (uint8_t)((u16) >> 0); \ + } + +/** Big Endian uint24 to stream */ +#define BE_UINT24_TO_STREAM(s, u24) { \ + *s++ = (uint8_t)((u24) >> 16); \ + *s++ = (uint8_t)((u24) >> 8); \ + *s++ = (uint8_t)((u24) >> 0); \ + } + +/** Big Endian uint32 to stream */ +#define BE_UINT32_TO_STREAM(s, u32) { \ + *s++ = (uint8_t)((u32) >> 24); \ + *s++ = (uint8_t)((u32) >> 16); \ + *s++ = (uint8_t)((u32) >> 8); \ + *s++ = (uint8_t)((u32) >> 0); \ + } + +/** Big Endian array to uint8 */ +#define BE_ARRAY_TO_UINT8(u8, a) { \ + u8 = (uint8_t)(*(a + 0)); \ + } + +/** Big Endian array to uint16 */ +#define BE_ARRAY_TO_UINT16(u16, a) { \ + u16 = ((uint16_t)(*(a + 0)) << 8) + \ + ((uint16_t)(*(a + 1)) << 0); \ + } + +/** Big Endian array to uint24 */ +#define BE_ARRAY_TO_UINT24(u24, a) { \ + u24 = ((uint32_t)(*(a + 0)) << 16) + \ + ((uint32_t)(*(a + 1)) << 8) + \ + ((uint32_t)(*(a + 2)) << 0); \ + } + +/** Big Endian array to uint32 */ +#define BE_ARRAY_TO_UINT32(u32, a) { \ + u32 = ((uint32_t)(*(a + 0)) << 24) + \ + ((uint32_t)(*(a + 1)) << 16) + \ + ((uint32_t)(*(a + 2)) << 8) + \ + ((uint32_t)(*(a + 3)) << 0); \ + } + +/** Big Endian uint8 to array */ +#define BE_UINT8_TO_ARRAY(a, u8) { \ + *((uint8_t *)(a) + 0) = (uint8_t)(u8); \ + } + +/** Big Endian uint16 to array */ +#define BE_UINT16_TO_ARRAY(a, u16) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u16) >> 8); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u16) >> 0); \ + } + +/** Big Endian uint24 to array */ +#define BE_UINT24_TO_ARRAY(a, u24) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u24) >> 16); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u24) >> 8); \ + *((uint8_t *)(a) + 2) = (uint8_t)((u24) >> 0); \ + } + +/** Big Endian uint32 to array */ +#define BE_UINT32_TO_ARRAY(a, u32) { \ + *((uint8_t *)(a) + 0) = (uint8_t)((u32) >> 24); \ + *((uint8_t *)(a) + 1) = (uint8_t)((u32) >> 16); \ + *((uint8_t *)(a) + 2) = (uint8_t)((u32) >> 8); \ + *((uint8_t *)(a) + 3) = (uint8_t)((u32) >> 0); \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* _BT_TYPES_H_ */ diff --git a/inc/bluetooth/gap/gap.h b/inc/bluetooth/gap/gap.h new file mode 100644 index 0000000..861eeaf --- /dev/null +++ b/inc/bluetooth/gap/gap.h @@ -0,0 +1,644 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap.h + * @brief This file contains all the constants and functions prototypes for GAP. + * @details This file is used both bredr and le. + * @author jane + * @date 2017-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_H +#define GAP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include "upperstack_config.h" +#include + +/** @addtogroup GAP_COMMON GAP Common + * @brief GAP common module + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_Common_Exported_Macros GAP Common Exported Macros + * @{ + */ + +/** @defgroup GAP_Common_Macros GAP Common Macros + * @{ + */ +#define GAP_BD_ADDR_LEN 6 //!< Default Bluetooth Device Address Length. +#define GAP_KEY_LEN 16 //!< Default Long Term Key(LTK) length. +#define GAP_DEVICE_NAME_LEN (39+1)//!< Max length of device name, if device name length exceeds it, it will be truncated. +#define GAP_PASSCODE_MAX 999999//!< Maximum Pairing Passcode/Passkey value. Range of a passkey can be 0 - 999,999. +#define GAP_OOB_LEN 16 //!< Length of out of band data. +/** + * @} + */ + +/** @defgroup BOND_PAIRING_MODE_DEFINES Pairing Modes + * @{ + */ +#define GAP_PAIRING_MODE_NO_PAIRING 0x00 //!< Pairing is not allowed. +#define GAP_PAIRING_MODE_PAIRABLE 0x01 //!< Pairable, Wait for a pairing request from master or security request from slave. +/** + * @} + */ + +/** @defgroup BOND_MITM_DEFINES Mitm And Bonding Flags + * @{ + */ +#define GAP_AUTHEN_BIT_NONE 0 //!< No authentication required. +#define GAP_AUTHEN_BIT_BONDING_FLAG 0x0001 //!< Bonding is required +#define GAP_AUTHEN_BIT_MITM_FLAG 0x0004 //!< Mitm is preferred +#if F_BT_LE_4_2_SC_SUPPORT +#define GAP_AUTHEN_BIT_SC_FLAG 0x0008 //!< Secure connection is preferred +#define GAP_AUTHEN_BIT_SC_ONLY_FLAG 0x0200 //!< Secure connection only mode for BLE is required +#endif +#if F_BT_KEY_PRESS_SUPPORT +#define GAP_AUTHEN_BIT_KEYPRESS_FLAG 0x0010 //!< Keypress notifaction is preferred +#endif +#define GAP_AUTHEN_BIT_FORCE_BONDING_FLAG 0x0100 //!< Force bonding is required + +/** + * @} + */ + +/** @defgroup GAP_COMMON_MSG_TYPE GAP Msg Type + * @{ + */ +#define GAP_MSG_WRITE_AIRPLAN_MODE 0x00 //!Example usage + * \code{.c} + void app_main_task(void *p_param) + { + uint8_t event; + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + while (true) + { + if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true) + { + if (event == EVENT_IO_TO_APP) + { + T_IO_MSG io_msg; + if (os_msg_recv(io_queue_handle, &io_msg, 0) == true) + { + app_handle_io_msg(io_msg); + } + } + else + { + gap_handle_msg(event); + } + } + } + } + * \endcode + */ +bool gap_start_bt_stack(void *evt_queue, void *io_queue, uint16_t msg_queue_elem_num); + +/** + * @brief Initialize gap lib to use some extended functions. + * @return void + * Example usage + * \code{.c} + int main(void) + { + ... + gap_lib_init(); + ... + } + * \endcode + */ +void gap_lib_init(void); + +/** + * @brief Register callback to gap, when messages in @ref GAP_COMMON_MSG_TYPE happens, it will callback to app. + * @param[in] app_callback Callback function provided by the APP to handle gap common messages sent from the GAP. + * @arg NULL -> Not send gap common messages to APP. + * @arg Other -> Use application defined callback function. + * @return void + * + * Example usage + * \code{.c} + void app_le_gap_init() + { + ... + le_register_app_cb(app_gap_callback); + gap_register_app_cb(app_gap_common_callback); + } + \endcode + */ +void gap_register_app_cb(P_FUN_GAP_APP_CB app_callback); + +/** + * @brief Set a GAP parameter. + * + * NOTE: You can call this function with a GAP Common Parameter type and it will set the + * GAP Parameter. GAP Peripheral Parameters are defined in @ref T_GAP_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param GAP parameter ID: @ref T_GAP_PARAM_TYPE. + * @param[in] len Length of data to write. + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ... + //GAP Bond Manager parameters + uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE; + uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_MITM_FLAG; + uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT; + uint8_t auth_oob = false; + + // Setup the GAP Bond Manager + gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode); + gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags); + gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap); + gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob); + ... + } + * \endcode + */ +T_GAP_CAUSE gap_set_param(T_GAP_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a GAP Common parameter. + * + * NOTE: You can call this function with a GAP Common Parameter type and it will get a + * GAP Common Parameter. GAP Common Parameters are defined in @ref T_GAP_PARAM_TYPE. + * + * @param[in] param GAP parameter type: @ref T_GAP_PARAM_TYPE + * @param[in,out] p_value Pointer to location to get the value. This is dependent on + * the parameter ID and WILL be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t bt_addr[6]; + gap_get_param(GAP_PARAM_BD_ADDR, bt_addr); + } + * \endcode + */ +T_GAP_CAUSE gap_get_param(T_GAP_PARAM_TYPE param, void *p_value); + +/** + * @brief Make the device in pairable mode. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE gap_set_pairable_mode(void); + +/** + * @brief Write command to control device to enter airplane mode, the result will be notified by callback + regisgtered by @ref gap_register_app_cb. + * @param[in] mode the mode of the device + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_wairplane(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + uint8_t mode = p_parse_value->dw_param[0]; + cause = gap_write_airplan_mode(mode); + return (T_USER_CMD_PARSE_RESULT)cause; + } + + void app_gap_common_callback(uint8_t cb_type, void *p_cb_data) + { + T_GAP_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA)); + APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type); + switch (cb_type) + { + case GAP_MSG_WRITE_AIRPLAN_MODE: + APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x", + cb_data.p_gap_write_airplan_mode_rsp->cause); + break; + case GAP_MSG_READ_AIRPLAN_MODE: + APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d", + cb_data.p_gap_read_airplan_mode_rsp->cause, + cb_data.p_gap_read_airplan_mode_rsp->mode); + break; + default: + break; + } + return; + } + * \endcode + */ + +T_GAP_CAUSE gap_write_airplan_mode(uint8_t mode); + +/** + * @brief Read the airplane mode of the device, the result will be notified by callback regisgtered + by @ref gap_register_app_cb. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_rairplane(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + cause = gap_read_airplan_mode(); + return (T_USER_CMD_PARSE_RESULT)cause; + } + + void app_gap_common_callback(uint8_t cb_type, void *p_cb_data) + { + T_GAP_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA)); + APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type); + switch (cb_type) + { + case GAP_MSG_WRITE_AIRPLAN_MODE: + APP_PRINT_INFO1("GAP_MSG_WRITE_AIRPLAN_MODE: cause 0x%x", + cb_data.p_gap_write_airplan_mode_rsp->cause); + break; + case GAP_MSG_READ_AIRPLAN_MODE: + APP_PRINT_INFO2("GAP_MSG_READ_AIRPLAN_MODE: cause 0x%x, mode %d", + cb_data.p_gap_read_airplan_mode_rsp->cause, + cb_data.p_gap_read_airplan_mode_rsp->mode); + break; + default: + break; + } + return; + } + * \endcode + */ +T_GAP_CAUSE gap_read_airplan_mode(void); + +/** + * @brief Handle GAP message received from BT stack or timeout event for GAP timer. + * @param[in] event Event type which is received from APP event queue. + * @return None. + * + * Example usage + * \code{.c} + void app_main_task(void *p_param) + { + uint8_t event; + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + while (true) + { + if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true) + { + if (event == EVENT_IO_TO_APP) + { + T_IO_MSG io_msg; + if (os_msg_recv(io_queue_handle, &io_msg, 0) == true) + { + app_handle_io_msg(io_msg); + } + } + else + { + gap_handle_msg(event); + } + } + } + } + * \endcode + */ +void gap_handle_msg(uint8_t event); + +/** + * @brief Release the buffer of GAP supplied. + * @param[in] p_buf Point the buffer that needs to release. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + uint8_t *p_data_buf; + uint16_t data_offset; + T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) + { + ...... + server_get_write_cmd_data_buffer(conn_id, &p_data_buf, &data_offset); + return APP_RESULT_NOT_RELEASE; + } + void release(void) + { + if(p_data_buf != NULL) + { + gap_buffer_free(p_data_buf); + p_data_buf = NULL; + } + } + * \endcode + */ +T_GAP_CAUSE gap_buffer_free(void *p_buf); + +/** + * @brief Send vendor command. + * @param[in] op Opcode of command. + * @param[in] len Length of parameters. + * @param[in] p_param Pointer to parameters to write. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Send request successfully. + * @retval Others Failure. + * + * Example usage + * \code{.c} + //send vendor command + void test(void) + { + T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS; + uint16_t opcode; + uint8_t param[2]; + param[0] = 0; + param[1] = 0; + cause = gap_vendor_cmd_req(opcode, 2, param); + } + + //register callback, and handle response + void app_le_gap_init(void) + { + ...... + gap_register_app_cb(app_gap_common_callback); + } + + void app_gap_common_callback(uint8_t cb_type, void *p_cb_data) + { + T_GAP_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_GAP_CB_DATA)); + APP_PRINT_INFO1("app_gap_common_callback: cb_type = %d", cb_type); + switch (cb_type) + { + case GAP_MSG_VENDOR_CMD_RSP: + APP_PRINT_INFO3("GAP_MSG_VENDOR_CMD_RSP: command 0x%x, cause 0x%x, param_len %d", + cb_data.p_gap_vendor_cmd_rsp->command, + cb_data.p_gap_vendor_cmd_rsp->cause, + cb_data.p_gap_vendor_cmd_rsp->param_len); + break; + ...... + } + * \endcode + */ +T_GAP_CAUSE gap_vendor_cmd_req(uint16_t op, uint8_t len, uint8_t *p_param); +/** @} */ /* End of group GAP_COMMON_EXPORT_Functions */ + +/** @} */ /* End of group GAP_COMMON */ + +/*------------------------------------------------------------------- +-------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_H */ diff --git a/inc/bluetooth/gap/gap_adv.h b/inc/bluetooth/gap/gap_adv.h new file mode 100644 index 0000000..11275b2 --- /dev/null +++ b/inc/bluetooth/gap/gap_adv.h @@ -0,0 +1,482 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_adv.h +* @brief Head file for Gap adv +* @details This file defines advertising related API +* @author ranhui +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_ADV_H +#define GAP_ADV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#if F_BT_LE_GAP_PERIPHERAL_SUPPORT +#include "gap_le.h" + + +/** @addtogroup GAP_BROADCASTER_Role GAP Broadcaster Role + * @brief GAP Broadcaster Role + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup GAP_Broadcaster_Exported_Macros GAP Broadcaster Exported Macros + * @brief + * @{ + */ +#define GAP_MAX_ADV_LEN 31 //!< BLE Maximum Advertising or Scan Response Packet Length + +/** End of GAP_Broadcaster_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_Broadcaster_Exported_Types GAP Broadcaster Exported Types + * @brief + * @{ + */ + +/** @brief LE advertising parameter types */ +typedef enum +{ + GAP_PARAM_ADV_LOCAL_ADDR_TYPE = 0x260,//!< Advertisement used local bluetooth device address type. Read/Write Size is uint8. + GAP_PARAM_ADV_DATA = 0x261,//!< Advertisement Data. Read/Write. Max size is uint8[GAP_MAX_ADV_LEN]. Default is "02:01:05", which means that it is a Limited Discoverable Advertisement. + GAP_PARAM_SCAN_RSP_DATA = 0x262,//!< Scan Response Data. Read/Write. Max size is uint8[GAP_MAX_ADV_LEN]. Defaults to all 0. + GAP_PARAM_ADV_EVENT_TYPE = 0x263,//!< Advertisement Type. Read/Write. Size is uint8. Default is GAP_ADTYPE_ADV_IND (@ref T_GAP_ADTYPE). + GAP_PARAM_ADV_DIRECT_ADDR_TYPE = 0x264,//!< Direct Advertisement Address Type. Read/Write. Size is uint8. + GAP_PARAM_ADV_DIRECT_ADDR = 0x265,//!< Direct Advertisement Address. Read/Write. Size is uint8[GAP_BD_ADDR_LEN]. Default is NULL. + GAP_PARAM_ADV_CHANNEL_MAP = 0x266,//!< Which channels to advertise on. Read/Write Size is uint8. Default is GAP_ADVCHAN_ALL (@ref ADV_CHANNEL_MAP) + GAP_PARAM_ADV_FILTER_POLICY = 0x267,//!< Filter Policy. Ignored when directed advertising is used. Read/Write. Size is uint8. Default is GAP_ADV_FILTER_ANY (@ref T_GAP_ADV_FILTER_POLICY). + GAP_PARAM_ADV_INTERVAL_MIN = 0x268,//!< Minimum advertising interval for undirected and low duty cycle directed advertising. Value range: 0x0020 - 0x4000 (20ms - 10240ms 0.625ms/step),Read/Write Size is uint16_t. + GAP_PARAM_ADV_INTERVAL_MAX = 0x269,//!< Maximum advertising interval for undirected and low duty cycle directed advertising. Value range: 0x0020 - 0x4000 (20ms - 10240ms 0.625ms/step)),Read/Write Size is uint16_t. +} T_LE_ADV_PARAM_TYPE; + +/** End of GAP_Broadcaster_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_Broadcaster_Exported_Functions GAP Broadcaster Exported Functions + * @brief + * @{ + */ + +/** + * @brief Set a GAP advertising parameter. + * + * NOTE: You can call this function with a advertising parameter type and it will set the + * advertising parameter. Advertising parameters are defined in @ref T_LE_ADV_PARAM_TYPE. + * If the "len" field sets to the size of "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param LE advertising parameter type: @ref T_LE_ADV_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + //advertising parameters + uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND; + uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0}; + uint8_t adv_chann_map = GAP_ADVCHAN_ALL; + uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY; + uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN; + + //Set advertising parameters + le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr); + le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map); + le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max); + le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), adv_data); + le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), scan_rsp_data); + } + * \endcode + */ +T_GAP_CAUSE le_adv_set_param(T_LE_ADV_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a GAP advertising parameter. + * + * NOTE: You can call this function with a advertising parameter type and it will get a + * advertising parameter. Advertising parameters are defined in @ref T_LE_ADV_PARAM_TYPE. + * Also, the "p_value" field must point to a data with type "uint16_t". + * + * @param[in] param Advertising parameter type: @ref T_LE_ADV_PARAM_TYPE + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_PUBLIC; + le_adv_get_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, &local_bd_type); + } + * \endcode + */ +T_GAP_CAUSE le_adv_get_param(T_LE_ADV_PARAM_TYPE param, void *p_value); + +/** + * @brief Start advertising with params set by @ref le_adv_set_param. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Start request success. + * @retval other Start request failed. + * + * Example usage + * \code{.c} + void test() + { + + uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND; + uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0}; + uint8_t adv_chann_map = GAP_ADVCHAN_ALL; + uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY; + uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN; + + le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr); + le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map); + le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max); + le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), (void *)adv_data); + le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(scan_rsp_data), (void *)scan_rsp_data); + + le_adv_start(); + } + + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x", + new_state.gap_init_state, new_state.gap_adv_state, cause); + if (gap_dev_state.gap_init_state != new_state.gap_init_state) + { + if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + APP_PRINT_INFO0("GAP stack ready"); + + le_adv_start(); + } + } + + if (gap_dev_state.gap_adv_state != new_state.gap_adv_state) + { + if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE) + { + if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN) + { + APP_PRINT_INFO0("GAP adv stoped: because connection created"); + } + else + { + APP_PRINT_INFO0("GAP adv stoped"); + } + } + else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING) + { + APP_PRINT_INFO0("GAP adv start"); + } + } + + gap_dev_state = new_state; + } + + //When the link was establishment, app_gap_callback will be called with callback type GAP_MSG_LE_CREATE_CONN_IND + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_CREATE_CONN_IND: + APP_PRINT_INFO0("GAP_MSG_LE_CREATE_CONN_IND"); + result = APP_RESULT_ACCEPT; + break; + ... + } + } + + * \endcode + */ +T_GAP_CAUSE le_adv_start(void); + +/** + * @brief Stop advertising. When the device is in advertising state, App can call this API to stop advertising. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + le_adv_stop(); + } + + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x", + new_state.gap_init_state, new_state.gap_adv_state, cause); + if (gap_dev_state.gap_init_state != new_state.gap_init_state) + { + if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + APP_PRINT_INFO0("GAP stack ready"); + + le_adv_start(); + } + } + + if (gap_dev_state.gap_adv_state != new_state.gap_adv_state) + { + if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE) + { + if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN) + { + APP_PRINT_INFO0("GAP adv stoped: because connection created"); + } + else + { + APP_PRINT_INFO0("GAP adv stoped"); + } + } + else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING) + { + APP_PRINT_INFO0("GAP adv start"); + } + } + + gap_dev_state = new_state; + } + * \endcode + */ +T_GAP_CAUSE le_adv_stop(void); + +/** + * @brief Update advertising parameters. + * Application can update one or more advertising paramters, @ref le_adv_set_param should be called first to specify + * which paramter shall be update. If gap adv state is not @ref GAP_ADV_STATE_IDLE, application can only update + * advertising data and scan response data. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + ... + le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data), adv_data); + le_adv_update_param(); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_ADV_UPDATE_PARAM: + APP_PRINT_INFO1("GAP_MSG_LE_ADV_UPDATE_PARAM: cause 0x%x", + cb_data.p_le_adv_update_param_rsp->cause); + break; + } + ... + } + * \endcode + */ + +T_GAP_CAUSE le_adv_update_param(void); + +#if F_BT_LE_READ_ADV_TX_POWRE_SUPPORT +/** + * @brief Read advertising transmit power. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + le_adv_read_tx_power(); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_ADV_READ_TX_POWER: + APP_PRINT_INFO2("GAP_MSG_LE_ADV_READ_TX_POWER: cause 0x%x, tx_power_level 0x%x", + cb_data.p_le_adv_read_tx_power_rsp->cause, + cb_data.p_le_adv_read_tx_power_rsp->tx_power_level); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_adv_read_tx_power(void); +#endif +/** + * @brief Set the advertising tx power for the device, or reset advertising tx power to default value. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @param[in] type adv tx power type. + * @param[in] tx_gain index for power level. NOTE: The following tx gain table may be changed in future version. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_CAUSE cause; + uint8_t type = GAP_ADV_TX_POW_SET_1M; + uint8_t tx_gain = 0x80; + cause = le_adv_set_tx_power((T_GAP_ADV_TX_POW_TYPE)type, tx_gain); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_ADV_SET_TX_POWER: + APP_PRINT_INFO1("GAP_MSG_LE_ADV_SET_TX_POWER: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + } + * \endcode + */ +T_GAP_CAUSE le_adv_set_tx_power(T_GAP_ADV_TX_POW_TYPE type, uint8_t tx_gain); + +/** + * @brief Trigger One Shot Advertising. + * NOTE: Trigger advertising after guard_slot * 625 + guard_usec + wait_usec(us). + * This function can be called after @ref gap_start_bt_stack is invoked. + * This function cannot be used if advertising type is connectable high duty cycle directed advertising. + * + * @param[in] guard_slot The delay time to trigger advertising in units of 625us, range: 0~224 + * @param[in] guard_usec The delay time to trigger advertising in units of us, range: 0~65535 + * @param[in] wait_usec The delay time to trigger advertising in units of us, range: 0~65535 + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_oneshot(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t guard_slot = p_parse_value->dw_param[0]; + uint16_t guard_usec = p_parse_value->dw_param[1]; + uint16_t wait_usec = p_parse_value->dw_param[2]; + T_GAP_CAUSE cause; + + cause = le_vendor_one_shot_adv(guard_slot, guard_usec, wait_usec); + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_VENDOR_ONE_SHOT_ADV: + APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_ONE_SHOT_ADV: cause 0x%x", + p_data->le_cause.cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_vendor_one_shot_adv(uint8_t guard_slot, uint16_t guard_usec, uint16_t wait_usec); + +/** @} */ /* End of group GAP_Broadcaster_Exported_Functions */ +/** @} */ /* End of group GAP_Broadcaster_Role */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_ADV_H */ diff --git a/inc/bluetooth/gap/gap_aox.h b/inc/bluetooth/gap/gap_aox.h new file mode 100644 index 0000000..4f5227d --- /dev/null +++ b/inc/bluetooth/gap/gap_aox.h @@ -0,0 +1,375 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_aox.h +* @brief Head file for GAP AoA/AoD +* @details +* @author +* @date 2020-06-18 +* @version v0.8 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_AOX_H +#define GAP_AOX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap_le_types.h" + +#if F_BT_LE_5_1_AOA_AOD_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_AOX GAP LE AoA/AoD Module + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_AOX_Exported_Macros GAP LE AoX Exported Macros + * @{ + */ + +/** @defgroup GAP_LE_AOX_MSG_Types GAP LE AoX Msg Types + * @{ + */ +#define GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION 0x01 /** Not send gap aox command messages to APP. + * @arg Other -> Use application defined callback function. + * @return void + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ...... + le_register_aox_cb(app_gap_aox_callback); + } + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: + APP_PRINT_INFO5("GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: cause 0x%x, supported_switching_sampling_rates 0x%x, num_antennae %d, max_switching_pattern_length %d, max_cte_length %d", + p_data->p_le_aox_read_antenna_information_rsp->cause, + p_data->p_le_aox_read_antenna_information_rsp->supported_switching_sampling_rates, + p_data->p_le_aox_read_antenna_information_rsp->num_antennae, + p_data->p_le_aox_read_antenna_information_rsp->max_switching_pattern_length, + p_data->p_le_aox_read_antenna_information_rsp->max_cte_length + ); + break; + ...... + } + ...... + } + \endcode + */ +void le_register_aox_cb(P_FUN_LE_AOX_CB aox_callback); + +/** + * @brief Read antenna information. + * Read the supported_switching_sampling_rates, num_antennae, max_switching_pattern_length, max_cte_length + * of a transmitted Constant Tone Extension supported by the Controller. + * Antenna information will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION. + * + * Application can only call this API after stack is ready. + * Explanation: If stack is ready, Application will be notified by message @ref GAP_MSG_LE_DEV_STATE_CHANGE + * with new_state about gap_init_state which is configured as @ref GAP_INIT_STATE_STACK_READY. + * + * @return Result of sending request. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * + * Example usage + * \code{.c} + void test() + { + le_aox_read_antenna_information(); + } + + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: + APP_PRINT_INFO5("GAP_MSG_LE_AOX_READ_ANTENNA_INFORMATION: cause 0x%x, supported_switching_sampling_rates 0x%x, num_antennae %d, max_switching_pattern_length %d, max_cte_length %d", + p_data->p_le_aox_read_antenna_information_rsp->cause, + p_data->p_le_aox_read_antenna_information_rsp->supported_switching_sampling_rates, + p_data->p_le_aox_read_antenna_information_rsp->num_antennae, + p_data->p_le_aox_read_antenna_information_rsp->max_switching_pattern_length, + p_data->p_le_aox_read_antenna_information_rsp->max_cte_length + ); + break; + ...... + } + ...... + } + * \endcode + */ +T_GAP_CAUSE le_aox_read_antenna_information(void); + +/** End of GAP_LE_AOA_AOD_Exported_Functions + * @} + */ + +/** End of GAP_LE_AOA_AOD + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_AOX_H */ diff --git a/inc/bluetooth/gap/gap_aox_conn.h b/inc/bluetooth/gap/gap_aox_conn.h new file mode 100644 index 0000000..5016411 --- /dev/null +++ b/inc/bluetooth/gap/gap_aox_conn.h @@ -0,0 +1,374 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_aox_conn.h +* @brief Head file for GAP AoA/AoD connection +* @details +* @author +* @date 2020-06-18 +* @version v0.8 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_AOX_CONN_H +#define GAP_AOX_CONN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap_le_types.h" + +#if F_BT_LE_5_1_AOX_CONN_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_AOX_CONN GAP LE AoA/AoD Module + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_AOX_CONN_Exported_Macros GAP LE AoX Exported Macros + * @{ + */ + +/** @defgroup GAP_AOX_CONN_CTE_TYPES_BITS LE AoX Connection CTE Types Bits +* @{ + */ +#define GAP_AOX_CONN_CTE_TYPES_AOA_BIT 0x01 /**< Allow AoA Constant Tone Extension Response. */ +#define GAP_AOX_CONN_CTE_TYPES_AOD_1US_BIT 0x02 /**< Allow AoD Constant Tone Extension Response with 1 us slots. */ +#define GAP_AOX_CONN_CTE_TYPES_AOD_2US_BIT 0x04 /**< Allow AoD Constant Tone Extension Response with 2 us slots. */ +/** + * @} + */ + +/** End of GAP_LE_AOX_CONN_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_AOX_CONN_Exported_Types GAP LE AoA/AoD Exported Types + * @brief + * @{ + */ +typedef enum +{ + GAP_AOX_SAMPLING_DISABLE = 0x00, /**< Connection IQ sampling is disabled (default). */ + GAP_AOX_SAMPLING_ENABLE = 0x01, /**< Connection IQ sampling is enabled. */ +} T_GAP_AOX_SAMPLING_ENABLE_TYPE; + +typedef enum +{ + GAP_AOX_CTE_REQUEST_DISABLE = 0x00, /**< Disable Constant Tone Extension Request for the connection (default). */ + GAP_AOX_CTE_REQUEST_ENABLE = 0x01, /**< Enable Constant Tone Extension Request for the connection. */ +} T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE; + +typedef enum +{ + GAP_AOX_CTE_RESPONSE_DISABLE = 0x00, /**< Disable Constant Tone Extension Response for the connection (default). */ + GAP_AOX_CTE_RESPONSE_ENABLE = 0x01, /**< Enable Constant Tone Extension Response for the connection. */ +} T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE; + +/** End of GAP_LE_AOX_CONN_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup GAP_LE_AOA_AOD_CONN_Exported_Functions GAP LE AoA/AoD Exported Functions + * @brief + * @{ + */ +/** + * @brief Set Connection CTE Receive Parameters. + * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS. + * + * @param[in] conn_id Connection ID. + * @param[in] sampling_enable Enable/disable Connection IQ sampling: @ref T_GAP_AOX_SAMPLING_ENABLE_TYPE. + * @param[in] slot_durations Switching and sampling slots: @ref T_GAP_SLOT_DUATIONS_TYPE. + * @param[in] switching_pattern_length The number of Antenna IDs in the pattern. + Range: 0x02 to max_switching_pattern_length supported by controller + max_switching_pattern_length shall be less than or equal to 0x4B. + * @param[in] p_antenna_ids Antenna ID in the pattern. + * @return Result of sending request. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * @retval GAP_CAUSE_NON_CONN: Failed. No connection. + * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter. + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + T_GAP_AOX_SAMPLING_ENABLE_TYPE sampling_enable = GAP_AOX_SAMPLING_ENABLE; + T_GAP_SLOT_DUATIONS_TYPE slot_durations = GAP_SLOT_DURATIONS_SWITCH_SAMPLE_2US; + uint8_t switching_pattern_length = 2; + uint8_t p_antenna_ids[2] = {0, 1}; + + le_aox_set_conn_cte_receive_params(conn_id, sampling_enable, slot_durations, + switching_pattern_length, p_antenna_ids); + } + + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS: + APP_PRINT_INFO2("GAP_MSG_LE_AOX_SET_CONN_CTE_RECEIVE_PARAMS: cause 0x%x, conn_id %d", + p_data->p_le_aox_set_conn_cte_receive_params_rsp->cause, + p_data->p_le_aox_set_conn_cte_receive_params_rsp->conn_id); + break; + ...... + } + ...... + } + * \endcode + */ +T_GAP_CAUSE le_aox_set_conn_cte_receive_params(uint8_t conn_id, + T_GAP_AOX_SAMPLING_ENABLE_TYPE sampling_enable, + T_GAP_SLOT_DUATIONS_TYPE slot_durations, + uint8_t switching_pattern_length, + uint8_t *p_antenna_ids); + +/** + * @brief Set Connection CTE Transmit Parameters. + * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS. + * + * @param[in] conn_id Connection ID + * @param[in] cte_types A bit field that indicates the type of Constant Tone Extension that the Controller support + @ref GAP_AOX_CONN_CTE_TYPES_BITS. + * @param[in] switching_pattern_length The number of Antenna IDs in the pattern, and shall be ignored when cte_types does not + have a bit set for an AoD Constant Tone Extension. + Range: 0x02 to max_switching_pattern_length supported by controller + max_switching_pattern_length shall be less than or equal to 0x4B. + * @param[in] p_antenna_ids Antenna ID in the pattern, and shall be ignored when cte_types does not + have a bit set for an AoD Constant Tone Extension. + * @return Result of sending request. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * @retval GAP_CAUSE_NON_CONN: Failed. No connection. + * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter. + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + uint8_t cte_types = GAP_AOX_CONN_CTE_TYPES_AOA_BIT | GAP_AOX_CONN_CTE_TYPES_AOD_2US_BIT; + uint8_t switching_pattern_length = 2; + uint8_t p_antenna_ids[2] = {0, 1}; + + le_aox_set_conn_cte_transmit_params(conn_id, cte_types, switching_pattern_length, p_antenna_ids); + } + + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS: + APP_PRINT_INFO2("GAP_MSG_LE_AOX_SET_CONN_CTE_TRANSMIT_PARAMS: cause 0x%x, conn_id %d", + p_data->p_le_aox_set_conn_cte_transmit_params_rsp->cause, + p_data->p_le_aox_set_conn_cte_transmit_params_rsp->conn_id); + break; + ...... + } + ...... + } + * \endcode + */ +T_GAP_CAUSE le_aox_set_conn_cte_transmit_params(uint8_t conn_id, uint8_t cte_types, + uint8_t switching_pattern_length, + uint8_t *p_antenna_ids); + +/** + * @brief Request the Controller to start or stop initiating the Constant Tone Extension Request procedure. + * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE. + * + * IQ samples will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO + * on Constant Tone Extensions received. + * Otherwise, request failed info will be returned by @ref app_gap_aox_callback with cb_type + * @ref GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO. + * + * @param[in] conn_id Connection ID + * @param[in] enable Enable/disable Constant Tone Extension Request: @ref T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE. + If Enable is set to GAP_AOX_CTE_REQUEST_DISABLE, the remaining parameters shall be ignored. + * @param[in] cte_request_interval Defines whether the Constant Tone Extension Request procedure is initiated + only once or periodically. + 0x0000: Initiate the Constant Tone Extension Request procedure once, at the + earliest practical opportunity + 0x0001 to 0xFFFF: Requested interval for initiating the Constant Tone Extension + Request procedure in number of connection events. + * @param[in] requested_cte_length The minimum length of the Constant Tone Extension that the Controller shall + request from the remote device. + Range: 0x02 to 0x14. + Units: 8 us. + * @param[in] requested_cte_type The type of Constant Tone Extension that the Controller shall request from the remote device: + * @ref T_GAP_CTE_TYPE. + * @return Result of sending request. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * @retval GAP_CAUSE_NON_CONN: Failed. No connection. + * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter. + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE enable = GAP_AOX_CTE_REQUEST_ENABLE; + uint16_t cte_request_interval = 0; + uint8_t requested_cte_length = 2; + T_GAP_CTE_TYPE requested_cte_type = GAP_CTE_TYPE_AOA; + + le_aox_conn_cte_request_enable(conn_id, enable, cte_request_interval, + requested_cte_length, requested_cte_type); + } + + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE: + APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_CTE_REQUEST_ENABLE: cause 0x%x, conn_id %d", + p_data->p_le_aox_conn_cte_request_enable_rsp->cause, + p_data->p_le_aox_conn_cte_request_enable_rsp->conn_id); + break; + case GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: + APP_PRINT_INFO8("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: conn_id %d, rx_phy %d, data_chan_index %d, rssi %d, rssi_antenna_id %d, cte_type %d, slot_durations %d, packet_status %d", + p_data->p_le_aox_conn_iq_report_info->conn_id, + p_data->p_le_aox_conn_iq_report_info->rx_phy, + p_data->p_le_aox_conn_iq_report_info->data_chan_index, + p_data->p_le_aox_conn_iq_report_info->rssi, + p_data->p_le_aox_conn_iq_report_info->rssi_antenna_id, + p_data->p_le_aox_conn_iq_report_info->cte_type, + p_data->p_le_aox_conn_iq_report_info->slot_durations, + p_data->p_le_aox_conn_iq_report_info->packet_status); + APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: connection_event_counter %d, sample_count %d", + p_data->p_le_aox_conn_iq_report_info->connection_event_counter, + p_data->p_le_aox_conn_iq_report_info->sample_count); + if (p_data->p_le_aox_conn_iq_report_info->sample_count) + { + APP_PRINT_INFO1("GAP_MSG_LE_AOX_CONN_IQ_REPORT_INFO: iq_sample %b", + TRACE_BINARY(p_data->p_le_aox_conn_iq_report_info->sample_count * 2, + p_data->p_le_aox_conn_iq_report_info->p_iq_sample)); + } + break; + case GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO: + APP_PRINT_INFO2("GAP_MSG_LE_AOX_CTE_REQUEST_FAILED_INFO: cause 0x%x, conn_id %d", + p_data->p_le_aox_cte_request_failed_info->cause, + p_data->p_le_aox_cte_request_failed_info->conn_id); + break; + ...... + } + ...... + } + * \endcode + */ +T_GAP_CAUSE le_aox_conn_cte_request_enable(uint8_t conn_id, + T_GAP_AOX_CTE_REQUEST_ENABLE_TYPE enable, + uint16_t cte_request_interval, uint8_t requested_cte_length, + T_GAP_CTE_TYPE requested_cte_type); + +/** + * @brief Request the Controller to respond to Constant Tone Extension Request. + * Result will be returned by @ref app_gap_aox_callback with cb_type @ref GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE. + * + * @param[in] conn_id Connection ID. + * @param[in] enable Enable/disable Constant Tone Extension Response: @ref T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE. + * @return Result of sending request. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * @retval GAP_CAUSE_NON_CONN: Failed. No connection. + * @retval GAP_CAUSE_INVALID_PARAM: Failed. Invalid parameter. + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE enable = GAP_AOX_CTE_RESPONSE_ENABLE; + + le_aox_conn_cte_response_enable(conn_id, enable); + } + + T_APP_RESULT app_gap_aox_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_AOX_CB_DATA *p_data = (T_LE_AOX_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE: + APP_PRINT_INFO2("GAP_MSG_LE_AOX_CONN_CTE_RESPONSE_ENABLE: cause 0x%x, conn_id %d", + p_data->p_le_aox_conn_cte_response_enable_rsp->cause, + p_data->p_le_aox_conn_cte_response_enable_rsp->conn_id); + break; + ...... + } + ...... + } + * \endcode + */ +T_GAP_CAUSE le_aox_conn_cte_response_enable(uint8_t conn_id, + T_GAP_AOX_CTE_RESPONSE_ENABLE_TYPE enable); + +/** End of GAP_LE_AOA_AOD_CONN_Exported_Functions + * @} + */ + +/** End of GAP_LE_AOA_AOD + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_AOX_CONN_H */ diff --git a/inc/bluetooth/gap/gap_aox_connless_receiver.h b/inc/bluetooth/gap/gap_aox_connless_receiver.h new file mode 100644 index 0000000..752fbac --- /dev/null +++ b/inc/bluetooth/gap/gap_aox_connless_receiver.h @@ -0,0 +1,108 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_aox_connless_receiver.h +* @brief Head file for GAP AoA/AoD +* @details +* @author +* @date 2020-06-18 +* @version v0.8 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_AOX_CONNLESS_RECEIVER_H +#define GAP_AOX_CONNLESS_RECEIVER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap_le_types.h" + +#if F_BT_LE_5_1_AOX_CONNLESS_RECEIVER_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_AOX GAP LE AoA/AoD Module + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_AOX_Exported_Macros GAP LE AoX Exported Macros + * @{ + */ +/** @defgroup AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE Periodic Advertising Enable flag + * @brief Use the macro definitions to describe the enable parameters. + * @{ + */ +#define AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE_IQ_SAMPLING_DISABLED 0x00 /**< Connectionless IQ sampling is disabled (default). */ +#define AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE_IQ_SAMPLING_ENABLED 0x01 /**< Connectionless IQ sampling is enabled. */ +/** End of AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE + * @} + */ + +/** End of GAP_LE_AOX_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup GAP_LE_AOA_AOD_Exported_Functions GAP LE AoA/AoD Exported Functions + * @brief + * @{ + */ +/* + sampling_enable: @ref AOX_CONNLESS_RECEIVER_SAMPLING_ENABLE +*/ +T_GAP_CAUSE le_aox_connless_receiver_set_iq_sampling_enable(uint8_t sync_id, + uint8_t sampling_enable, T_GAP_SLOT_DUATIONS_TYPE slot_durations, uint8_t max_sampled_ctes, + uint8_t switching_pattern_length, uint8_t *p_antenna_ids); + +/** End of GAP_LE_AOA_AOD_Exported_Functions + * @} + */ + +/** End of GAP_LE_AOA_AOD + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_AOX_CONNLESS_RECEIVER_H */ diff --git a/inc/bluetooth/gap/gap_aox_connless_transmitter.h b/inc/bluetooth/gap/gap_aox_connless_transmitter.h new file mode 100644 index 0000000..a7cab6a --- /dev/null +++ b/inc/bluetooth/gap/gap_aox_connless_transmitter.h @@ -0,0 +1,143 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_aox_connless_transmitter.h +* @brief Head file for GAP AoA/AoD connless transmitter +* @details +* @author +* @date 2020-10-18 +* @version v0.4 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_AOX_CONNLESS_TRANSMITTER_H +#define GAP_AOX_CONNLESS_TRANSMITTER_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap_le_types.h" + +#if F_BT_LE_5_1_AOX_CONNLESS_TRANSMITTER_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_AOX_CONNLESS_TRANSMITTER GAP LE AoA/AoD Module + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Macros GAP LE AoX Exported Macros + * @{ + */ + +/** @defgroup AOX_CONNLESS_TRANSMITTER_CTE_ENABLE Periodic Advertising Enable flag + * @brief Use the macro definitions to describe the enable parameters. + * @{ + */ +#define AOX_CONNLESS_TRANSMITTER_CTE_ENABLE_ADV_WITH_CTE_DISABLED 0x00 /**< Advertising with Constant Tone Extension is disabled (default). */ +#define AOX_CONNLESS_TRANSMITTER_CTE_ENABLE_ADV_WITH_CTE_ENABLED 0x01 /**< Advertising with Constant Tone Extension is enabled. */ +/** End of AOX_CONNLESS_TRANSMITTER_CTE_ENABLE + * @} + */ + +/** End of GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Types GAP LE AoA/AoD Exported Types + * @brief + * @{ + */ +typedef enum +{ + GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOA = 0x00, /**< AoA Constant Tone Extension. */ + GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOD_1US = 0x01, /**< AoD Constant Tone Extension with 1 μs slots. */ + GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES_AOD_2US = 0x02, /**< AoD Constant Tone Extension with 2 μs slots. */ +} T_GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES; + +typedef enum +{ + AOX_CONNLESS_TRANSMITTER_STATE_IDLE = 0x00, + AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_EXT_ADV_STATE_PA_ADV_STATE_IDLE = 0x01, + AOX_CONNLESS_TRANSMITTER_STATE_WAIT_EXT_ADV_STATE_PA_ADV_STATE_ADVERTISING = 0x02, + AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_PA_ADV_STATE_IDLE = 0x03, + AOX_CONNLESS_TRANSMITTER_STATE_WAIT_PA_ADV_STATE_ADVERTISING = 0x04, + AOX_CONNLESS_TRANSMITTER_STATE_ENABLING_EXT_ADV_STATE_IDLE = 0x05, + AOX_CONNLESS_TRANSMITTER_STATE_WAIT_EXT_ADV_STATE_ADVERTISING = 0x06, + AOX_CONNLESS_TRANSMITTER_STATE_ENABLING = 0x07, + AOX_CONNLESS_TRANSMITTER_STATE_TRANSMITTING = 0x08, /**< Transmitting Constant Tone Extensions. */ + AOX_CONNLESS_TRANSMITTER_STATE_DISABLING = 0x09, +} T_GAP_AOX_CONNLESS_TRANSMITTER_STATE; + +/** End of GAP_LE_AOX_CONNLESS_TRANSMITTER_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup GAP_LE_AOA_AOD_Exported_Functions GAP LE AoA/AoD Exported Functions + * @brief + * @{ + */ + +T_GAP_CAUSE le_aox_connless_transmitter_init(uint8_t adv_set_num); + +T_GAP_CAUSE le_aox_connless_transmitter_set_cte_transmit_params(uint8_t adv_handle, + uint8_t cte_length, T_GAP_AOX_CONNLESS_TRANSMITTER_CTE_TYPES cte_type, uint8_t cte_count, + uint8_t switching_pattern_length, uint8_t *p_antenna_ids); + +/* + cte_enable: @ref AOX_CONNLESS_TRANSMITTER_CTE_ENABLE +*/ +T_GAP_CAUSE le_aox_connless_transmitter_set_cte_transmit_enable(uint8_t adv_handle, + uint8_t cte_enable); + +/** End of GAP_LE_AOA_AOD_Exported_Functions + * @} + */ + +/** End of GAP_LE_AOA_AOD + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_AOX_CONNLESS_TRANSMITTER_H */ diff --git a/inc/bluetooth/gap/gap_bond_le.h b/inc/bluetooth/gap/gap_bond_le.h new file mode 100644 index 0000000..7c431fe --- /dev/null +++ b/inc/bluetooth/gap/gap_bond_le.h @@ -0,0 +1,850 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_bond_le.h + * @brief This file contains all the functions prototypes for the GAP bond and pairing + * related functions. + * @details + * @author ranhui + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_BOND_LE_H +#define GAP_BOND_LE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" + +/** @defgroup GAP_LE_Bond_Manager GAP LE Bond Manager + * @brief GAP LE Bond Manager + * @{ + */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_BOND_MANAGER_Exported_Types GAP LE Bond Manager Exported Types + * @{ + */ + +/** @brief LE bond parameter types */ +typedef enum +{ +#if F_BT_LE_SMP_OOB_SUPPORT + GAP_PARAM_BOND_OOB_DATA = 0x210,//!< OOB Data. Read/Write. size uint8_t[16]. Default is all 0's. +#endif + GAP_PARAM_BOND_FIXED_PASSKEY = 0x211,//!< The fix passcode for MITM protection. Read/Write. size is uint32_t. Range is 0 - 999,999. Default is 0. + GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE = 0x212,//!< The fix passcode available for pairing. Read/Write. size is uint8_t. Default is 0(disabled). + GAP_PARAM_BOND_SEC_REQ_ENABLE = 0x213,//!< Send smp security request when connected. Read/Write. size is uint8_t. Default is 0(disabled). + GAP_PARAM_BOND_SEC_REQ_REQUIREMENT = 0x214,//!< Security request requirements. Read/Write. size is uint8_t. Default is GAP_AUTHEN_BIT_BONDING_FLAG (@ref BOND_MITM_DEFINES) + GAP_PARAM_BOND_MIN_KEY_SIZE = 0x215,//!< Minium LTK size required. Read/Write. size is uint8_t. +#if F_BT_LE_LOCAL_IRK_SETTING_SUPPORT + GAP_PARAM_BOND_GEN_LOCAL_IRK_AUTO = 0x216,//!< Auto generate local IRK. Write only. size is uint8_t. Default is 0(disabled). + GAP_PARAM_BOND_SET_LOCAL_IRK = 0x217,//!< Set local IRK. Write only. size is uint8_t. Default is all zero. +#endif + GAP_PARAM_BOND_KEY_MANAGER = 0x218,//!< Key manager. Write only. size is uint8_t. Default is 0(disabled). + GAP_PARAM_BOND_SIGN_KEY_FLAG = 0x219,//!< Sign key flag configure. Write only. size is uint8_t. Default is 0(disabled). + GAP_PARAM_BOND_CCCD_STORAGE = 0x21A,//!< Whether to store cccd information. Write only. size is uint8_t. Default is true. +} T_LE_BOND_PARAM_TYPE; + +#if F_BT_LE_4_2_SC_OOB_SUPPORT +/** @brief LE local Out of Band data */ +typedef struct +{ + uint8_t present; + uint8_t rand[16]; + uint8_t confirm[16]; + uint8_t bd_addr_to[6]; + uint8_t local_sk[32]; + uint8_t local_pk[64]; +} T_GAP_LE_LOCAL_OOB_DATA; + +/** @brief LE peer Out of Band data */ +typedef struct +{ + uint8_t present; + uint8_t rand[16]; + uint8_t confirm[16]; + uint8_t bd_addr_from[6]; +} T_GAP_LE_PEER_OOB_DATA; +#endif + +/** End of GAP_LE_BOND_MANAGER_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_LE_BONDMGR_Exported_Functions GAP LE Bond Manager Exported Functions + * @brief + * @{ + */ + +/** + * @brief Set a GAP Bond Manager Parameter. + * + * NOTE: You can call this function with a bond parameter type and it will set the + * bond parameter. Bond parameters are defined in @ref T_LE_BOND_PARAM_TYPE. + * if the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param Bond parameter type: @ref T_LE_BOND_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * + * @return Set result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ... + uint8_t auth_use_fix_passkey = false; + uint32_t auth_fix_passkey = 0; + uint8_t auth_sec_req_enable = false; + uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_NONE; + + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey), + &auth_use_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags), + &auth_sec_req_flags); + .... + } + * \endcode + */ +T_GAP_CAUSE le_bond_set_param(T_LE_BOND_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a GAP Bond Manager Parameter. + * + * NOTE: You can call this function with a bond parameter type and it will get a + * bond parameter. Bond parameters are defined in @ref T_LE_BOND_PARAM_TYPE. Also, the + * "p_value" field must point to a "uint16". + * + * @param[in] param Profile parameter ID: @ref T_LE_BOND_PARAM_TYPE + * @param[in,out] p_value pointer to location to get the value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * + * @return Get result + * @retval GAP_CAUSE_SUCCESS Get parameter success. + * @retval other Get parameter failed. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t seq_req; + le_bond_get_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, &seq_req); + } + * \endcode + */ +T_GAP_CAUSE le_bond_get_param(T_LE_BOND_PARAM_TYPE param, void *p_value); + +/** + * @brief Start authentication the link. + * + * NOTE: If the link has not been bonded, it will trigger pairing procedure, otherwise + * it will trigger the link encryption procedure. + * @param[in] conn_id Connection ID. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + le_bond_pair(conn_id); + } + + void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause) + { + APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause); + + switch (new_state) + { + case GAP_AUTHEN_STATE_STARTED: + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED"); + } + break; + + case GAP_AUTHEN_STATE_COMPLETE: + { + if (cause == GAP_SUCCESS) + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success"); + + } + else + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed"); + } + } + break; + + default: + { + APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state); + } + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_bond_pair(uint8_t conn_id); + +/** + * @brief Get the display key information + * + * @param[in] conn_id Connection ID. + * @param[in,out] p_key Passkey valueto be displayed as a 6 digit decimal number. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_PASSKEY_DISPLAY: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id; + le_bond_get_display_key(conn_id, &display_value); + APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value); + le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_get_display_key(uint8_t conn_id, uint32_t *p_key); + +/** + * @brief Send passkey to gap bond manager when pairing with passkey entry, + * and local should input passkey. + * + * @param[in] conn_id Connection ID. + * @param[in] passcode Result of Keyboard input. + * @param[in] cause User confirm result. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_PASSKEY_INPUT: + { + conn_id = bt_msg.msg_data.gap_bond_passkey_input.conn_id; + APP_PRINT_INFO0("GAP_MSG_LE_BOND_PASSKEY_INPUT"); + uint32_t passKey = 888888; + le_bond_passkey_input_confirm(conn_id, passKey, GAP_CFM_CAUSE_ACCEPT); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_passkey_input_confirm(uint8_t conn_id, uint32_t passcode, + T_GAP_CFM_CAUSE cause); + +#if F_BT_LE_SMP_OOB_SUPPORT +/** + * @brief Send oob data to gap bond manager when pairing with out of bond, + * and local should input oob data. + * @param[in] conn_id connection ID. + * @param[in] cause User confirm result. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_OOB_INPUT: + { + conn_id = bt_msg.msg_data.gap_bond_oob_input.conn_id; + APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT"); + uint8_t ooBData[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, ooBData); + le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_oob_input_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause); +#endif +/** + * @brief Send user confirmation request to confirm result to upper stack when + pairing with jsut work. + * @param[in] conn_id Connection ID. + * @param[in] cause User confirm result. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_JUST_WORK: + { + conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id; + le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK"); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_just_work_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause); + + +/** + * @brief Send user confirmation request to confirm result to upper stack when + pairing with passkey entry, and local shall display a passkey. + * @param[in] conn_id Connection ID. + * @param[in] cause User confirm result. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_PASSKEY_DISPLAY: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id; + le_bond_get_display_key(conn_id, &display_value); + APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value); + le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_passkey_display_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause); + +#if F_BT_LE_4_2_SC_SUPPORT +/** + * @brief Send user confirmation request to confirm result to upper stack + * @param[in] conn_id Connection ID. + * @param[in] cause User confirm result. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + void app_handle_gap_msg(T_IO_MSG *p_io_msg) + { + T_LE_GAP_MSG bt_msg; + uint8_t conn_id; + + memcpy(&bt_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + + switch (p_io_msg->subtype) + { + ... + case GAP_MSG_LE_BOND_USER_CONFIRMATION: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id; + le_bond_get_display_key(conn_id, &display_value); + APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value); + le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_bond_user_confirm(uint8_t conn_id, T_GAP_CFM_CAUSE cause); +#endif + +#if F_BT_LE_4_2_KEY_PRESS_SUPPORT +/** + * @brief Send keypress notification to upper stack + * @param[in] conn_id Connection ID. + * @param[in] type Keypress notify type @ref T_GAP_KEYPRESS_NOTIF_TYPE. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NON_CONN Operation failure. No connection. + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_KEYPRESS_NOTIFY: + APP_PRINT_INFO2("GAP_MSG_LE_KEYPRESS_NOTIFY:conn %d, cause 0x%x", + cb_data.p_le_keypress_notify_rsp->conn_id, cb_data.p_le_keypress_notify_rsp->cause); + break; + + case GAP_MSG_LE_KEYPRESS_NOTIFY_INFO: + APP_PRINT_INFO2("GAP_MSG_LE_KEYPRESS_NOTIFY_INFO:conn %d, type 0x%x", + cb_data.p_le_keypress_notify_info->conn_id, cb_data.p_le_keypress_notify_info->event_type); + break; + ... + } + } + * \endcode + */ +T_GAP_CAUSE le_bond_keypress_notify(uint8_t conn_id, T_GAP_KEYPRESS_NOTIF_TYPE type); +#endif +/** + * @brief Set local key distribution field + * @param[in] init_dist Initiator key distribution. + * @param[in] rsp_dist Responder key distribution. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. No connection. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_setkeydis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t init_dist = p_parse_value->dw_param[0]; + uint8_t rsp_dist = p_parse_value->dw_param[1]; + le_bond_cfg_local_key_distribute(init_dist, rsp_dist); + return (RESULT_SUCESS); + } + * \endcode + */ +T_GAP_CAUSE le_bond_cfg_local_key_distribute(uint8_t init_dist, uint8_t rsp_dist); + +#if F_BT_LE_4_2_SC_OOB_SUPPORT +/** + * @brief Initialize local Out of Band data. + * + * @note APP should call this API if OOB for LE Secure Connections pairing will be used. + * + * @param[in] p_ecc_rand_in Pointer to ecc rand. + * @param[in] local_rand Pointer to local rand. + * @param[in,out] p_local_oob_data Pointer to local oob data. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE ret; + uint64_t ecc_rand_in[4]; + uint8_t local_rand[16]; + + // APP set parameters value according to requirements + + if (idx == 1) + { + ret = le_bond_sc_local_oob_init(NULL, local_rand, &local_oob_data); + } + else + { + ret = le_bond_sc_local_oob_init(ecc_rand_in, local_rand, &local_oob_data); + } + } + * \endcode + */ +T_GAP_CAUSE le_bond_sc_local_oob_init(uint64_t *p_ecc_rand_in, uint8_t *local_rand, + T_GAP_LE_LOCAL_OOB_DATA *p_local_oob_data); + +/** + * @brief Initialize peer Out of Band data. + * @param[in] p_peer_oob_data Pointer to peer Out of Band data. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE ret; + T_GAP_LE_PEER_OOB_DATA peer_oob_data; + uint8_t bd_addr[6]; + uint8_t confirmation[16]; + uint8_t random_number[16]; + + // APP set parameters value according to requirements + + peer_oob_data.present = peer_oob_data_present_flag; + + memcpy(peer_oob_data.rand, random_number, 16); + memcpy(peer_oob_data.confirm, confirmation, 16); + memcpy(peer_oob_data.bd_addr_from, bd_addr, 6); + + ret = le_bond_sc_peer_oob_init(&peer_oob_data); + + // APP call gap_set_param(GAP_PARAM_BOND_OOB_ENABLED,), and value is same as value of peer_oob_data.present + // APP call gap_set_pairable_mode() + } + * \endcode + */ +T_GAP_CAUSE le_bond_sc_peer_oob_init(T_GAP_LE_PEER_OOB_DATA *p_peer_oob_data); +#endif +/** + * @brief Erase all link keys of bonded devices + * @return void + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ... +#if APP_PRIVACY_EN + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry, true); + break; +#endif + ... + } + } + + void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry, + bool handle_add) + { + APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type); + + if (type == LE_BOND_CLEAR) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false); + } + else if (type == LE_BOND_DELETE) + { + if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type, + p_entry->resolved_remote_bd.addr, false); + } + else + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, false); + } + } + else if (type == LE_BOND_ADD) + { + if (handle_add) + { + privacy_add_device(p_entry); + } + } + privacy_handle_resolv_list(); + } + * \endcode + */ +void le_bond_clear_all_keys(void); + +/** + * @brief Delete bond information by index + * @param[in] idx Index of key entry. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_NOT_FIND: Operation failure. Not found. + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ... +#if APP_PRIVACY_EN + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry, true); + break; +#endif + ... + } + } + + void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry, + bool handle_add) + { + APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type); + + if (type == LE_BOND_CLEAR) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false); + } + else if (type == LE_BOND_DELETE) + { + if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type, + p_entry->resolved_remote_bd.addr, false); + } + else + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, false); + } + } + else if (type == LE_BOND_ADD) + { + if (handle_add) + { + privacy_add_device(p_entry); + } + } + privacy_handle_resolv_list(); + } + * \endcode + */ +T_GAP_CAUSE le_bond_delete_by_idx(uint8_t idx); + +/** + * @brief Delete bond information by bluetooth device address and address type + * @param[in] bd_addr Bonded bluetooth device address. + * @param[in] bd_type Bonded bluetooth device address type. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_NOT_FIND: Operation failure. Not found. + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ... +#if APP_PRIVACY_EN + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry, true); + break; +#endif + ... + } + } + + void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry, + bool handle_add) + { + APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type); + + if (type == LE_BOND_CLEAR) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false); + } + else if (type == LE_BOND_DELETE) + { + if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type, + p_entry->resolved_remote_bd.addr, false); + } + else + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, false); + } + } + else if (type == LE_BOND_ADD) + { + if (handle_add) + { + privacy_add_device(p_entry); + } + } + privacy_handle_resolv_list(); + } + * \endcode + */ +T_GAP_CAUSE le_bond_delete_by_bd(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type); + +/** + * @brief Get the security level. + * @param[in] conn_id Connection ID. + * @param[out] p_type Pointer to location to get the security level. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. No connection. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_seclevel(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + T_GAP_SEC_LEVEL sec_level; + uint8_t conn_id = p_parse_value->dw_param[0]; + + cause = le_bond_get_sec_level(conn_id, &sec_level); + if(sec_level == GAP_SEC_LEVEL_NO) + { + data_uart_print("GAP_SEC_LEVEL_NO\r\n"); + } + else if(sec_level == GAP_SEC_LEVEL_UNAUTHEN) + { + data_uart_print("GAP_SEC_LEVEL_UNAUTHEN\r\n"); + } + else if(sec_level == GAP_SEC_LEVEL_AUTHEN) + { + data_uart_print("GAP_SEC_LEVEL_AUTHEN\r\n"); + } + else if(sec_level == GAP_SEC_LEVEL_SC_UNAUTHEN) + { + data_uart_print("GAP_SEC_LEVEL_SC_UNAUTHEN\r\n"); + } + else if(sec_level == GAP_SEC_LEVEL_SC_AUTHEN) + { + data_uart_print("GAP_SEC_LEVEL_SC_AUTHEN\r\n"); + } + return (T_USER_CMD_PARSE_RESULT)cause; + } + * \endcode + */ +T_GAP_CAUSE le_bond_get_sec_level(uint8_t conn_id, T_GAP_SEC_LEVEL *p_type); + +#if F_BT_LE_APP_KEY_MANAGER +T_GAP_CAUSE le_bond_authen_result_confirm(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_addr_type, + T_GAP_KEY_TYPE key_type, T_GAP_CFM_CAUSE cause); + +T_GAP_CAUSE le_bond_authen_key_req_confirm(uint8_t *bd_addr, + T_GAP_REMOTE_ADDR_TYPE remote_addr_type, + uint8_t key_len, uint8_t *p_key, T_GAP_KEY_TYPE key_type, + T_GAP_CFM_CAUSE cause); +T_GAP_CAUSE le_bond_gatt_server_store_confirm(T_GATT_STORE_OPCODE op, uint8_t *bd_addr, + T_GAP_REMOTE_ADDR_TYPE remote_addr_type, + uint8_t data_len, uint8_t *data, T_GAP_CFM_CAUSE cause); +#endif + +#if F_BT_LE_GATT_CCCD_DATA_PENDING +bool le_bond_set_cccd_data_pending(T_LE_KEY_ENTRY *p_entry, uint16_t handle, bool data_pending); +#endif + +/** End of GAP_LE_BONDMGR_Exported_Functions + * @} + */ + +/** End of GAP_LE_Bond_Manager + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_BOND_LE_H */ diff --git a/inc/bluetooth/gap/gap_callback_le.h b/inc/bluetooth/gap/gap_callback_le.h new file mode 100644 index 0000000..03eb81c --- /dev/null +++ b/inc/bluetooth/gap/gap_callback_le.h @@ -0,0 +1,902 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_callback_le.h + * @brief This file contains function prototype for all GAP roles. + * @details + * @author ranhui + * @date 2016-02-18 + * @version v0.1 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_CALLBACK_LE_H +#define GAP_CALLBACK_LE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_storage_le.h" +#include "gap_le_types.h" + +/** @defgroup GAP_CB_MSG_MODULE GAP Callback Message + * @brief GAP Callback Message + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup Gap_CB_Msg_Exported_Macros GAP Callback Msg Exported Macros + * @{ + */ + +/** @defgroup GAP_LE_MSG_Types GAP LE Msg Types + * @{ + */ + +//gap_le.h +#define GAP_MSG_LE_MODIFY_WHITE_LIST 0x01 //!Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + le_disconnect(conn_id); + } + + void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) + { + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, gap_conn_state, new_state, disc_cause); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE)) + && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + + le_adv_start(); + } + break; + + case GAP_CONN_STATE_CONNECTED: + { + uint16_t conn_interval; + uint16_t conn_latency; + uint16_t conn_supervision_timeout; + uint8_t remote_bd[6]; + T_GAP_REMOTE_ADDR_TYPE remote_bd_type; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + le_get_conn_addr(conn_id, remote_bd, &remote_bd_type); + APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x", + TRACE_BDADDR(remote_bd), remote_bd_type, + conn_interval, conn_latency, conn_supervision_timeout); + } + break; + + default: + break; + } + gap_conn_state = new_state; + } + * \endcode + */ +T_GAP_CAUSE le_disconnect(uint8_t conn_id); + +/** + * @brief Terminates the existing connection with reason. When link is disconnected, app_handle_conn_state_evt will be + * called with new_state as @ref GAP_CONN_STATE_DISCONNECTED. + * + * @param[in] conn_id connection ID to be disconnected. + * @param[in] reason disconnection reason. + * @arg HCI_ERR_REMOTE_USER_TERMINATE: 0x13 + * @arg HCI_ERR_REMOTE_LOW_RESOURCE: 0x14 + * @arg HCI_ERR_REMOTE_POWER_OFF: 0x15 + * @arg HCI_ERR_UNSUPPORTED_REMOTE_FEAT: 0x1A + * @arg HCI_ERR_UNACCEPTABLE_CONN_INTERVAL: 0x3B + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Send request success + * @retval GAP_CAUSE_NON_CONN Failed. No connection + * @retval GAP_CAUSE_INVALID_PARAM Failed. Invalid parameter + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0x01; + le_disconnect_with_reason(conn_id, HCI_ERR_REMOTE_USER_TERMINATE); + } + * \endcode + */ +T_GAP_CAUSE le_disconnect_with_reason(uint8_t conn_id, uint8_t reason); + +#if F_BT_LE_READ_REMOTE_VERSION_INFO_SUPPORT +/** + * @brief Obtain the values for the version information for the remote device identified by the conn_id parameter. + * Remote version information will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_REMOTE_VERSION. + * + * @param[in] conn_id Connection ID + * @return Read request result. + * @retval GAP_CAUSE_SUCCESS: Send request success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Send request sent fail. + * @retval GAP_CAUSE_NON_CONN: Failed. No connection + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + le_read_remote_version(conn_id); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type is %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_READ_REMOTE_VERSION: + APP_PRINT_INFO5("GAP_MSG_LE_READ_REMOTE_VERSION: conn_id %d, cause 0x%x, version 0x%x, manufacturer_name 0x%x, subversion 0x%x", + p_data->p_le_read_remote_version_rsp->conn_id, + p_data->p_le_read_remote_version_rsp->cause, + p_data->p_le_read_remote_version_rsp->version, + p_data->p_le_read_remote_version_rsp->manufacturer_name, + p_data->p_le_read_remote_version_rsp->subversion); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_read_remote_version(uint8_t conn_id); +#endif + +/** + * @brief Read rssi value of the connection. RSSI value will be returned by + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_RSSI. + * + * @param[in] conn_id Connection ID + * @return Read request result. + * @retval GAP_CAUSE_SUCCESS: Read request sent success.
    + * @retval GAP_CAUSE_NON_CONN: Read request sent fail.
    + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + le_read_rssi(conn_id); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_READ_RSSI: + APP_PRINT_INFO3("GAP_MSG_LE_READ_RSSI: conn_id %d, cause 0x%x, rssi %d", + cb_data.p_le_read_rssi_rsp->conn_id, + cb_data.p_le_read_rssi_rsp->cause, + cb_data.p_le_read_rssi_rsp->rssi); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_read_rssi(uint8_t conn_id); + +#if F_BT_LE_READ_CHANN_MAP +/** + * @brief Read the used channel map of the connection. Channel map value will be returned by + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_READ_CHANN_MAP. + * + * @param[in] conn_id Connection ID + * @return Read request result. + * @retval GAP_CAUSE_SUCCESS: Read request sent success.
    + * @retval GAP_CAUSE_NON_CONN: Read request sent fail.
    + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + le_read_chann_map(conn_id); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_READ_CHANN_MAP: + APP_PRINT_INFO7("GAP_MSG_LE_READ_CHANN_MAP: conn_id %d, cause 0x%x, map[0x%x:0x%x:0x%x:0x%x:0x%x]", + cb_data.p_le_read_chann_map_rsp->conn_id, + cb_data.p_le_read_chann_map_rsp->cause, + cb_data.p_le_read_chann_map_rsp->channel_map[0], + cb_data.p_le_read_chann_map_rsp->channel_map[1], + cb_data.p_le_read_chann_map_rsp->channel_map[2], + cb_data.p_le_read_chann_map_rsp->channel_map[3], + cb_data.p_le_read_chann_map_rsp->channel_map[4]); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_read_chann_map(uint8_t conn_id); +#endif + +#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT +/** + * @brief Set the data length used in LL for data length extension. LE set data length response will be returned by + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_SET_DATA_LEN. And if data length was changed, + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_DATA_LEN_CHANGE_INFO will be called. + * + * @param[in] conn_id Connection ID + * @param[in] tx_octets Preferred maximum number of payload octets that the local Controller + * should include in a single Link Layer packet on this connection. + Range 0x001B-0x00FB (all other values reserved for future use) + * @param[in] tx_time Preferred maximum number of microseconds that the local Controller + should use to transmit a single Link Layer packet on this connection. + Range 0x0148-0x4290 (all other values reserved for future use) + * @return result. + * @retval GAP_CAUSE_SUCCESS: Set request sent success.
    + * @retval GAP_CAUSE_NON_CONN: Set request sent fail.
    + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + uint16_t tx_octets = 251; + uint16_t tx_time = 2120; + le_set_data_len(conn_id, tx_octets, tx_time); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_SET_DATA_LEN: + APP_PRINT_INFO2("GAP_MSG_LE_SET_DATA_LEN: conn_id %d, cause 0x%x", + cb_data.p_le_set_data_len_rsp->conn_id, + cb_data.p_le_set_data_len_rsp->cause); + break; + case GAP_MSG_LE_DATA_LEN_CHANGE_INFO: + APP_PRINT_INFO5("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, max_tx_octets 0x%x, max_tx_time 0x%x, + max_rx_octets 0x%x, max_rx_time 0x%x", + cb_data.p_le_data_len_change_info->conn_id, + cb_data.p_le_data_len_change_info->max_tx_octets, + cb_data.p_le_data_len_change_info->max_tx_time, + cb_data.p_le_data_len_change_info->max_rx_octets, + cb_data.p_le_data_len_change_info->max_rx_time); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_set_data_len(uint8_t conn_id, uint16_t tx_octets, uint16_t tx_time); +#endif + +#if F_BT_LE_5_0_SET_PHYS_SUPPORT +/** + * @brief Set the PHY preferences for the connection identified by the Connection_Handle. + * The Controller might not be able to make the change (e.g. because the peer does + * not support the requested PHY) or may decide that the current PHY is preferable. + * If the phy used was changed, @ref app_gap_callback with cb_type @ref GAP_MSG_LE_PHY_UPDATE_INFO will be called. + * + * @param[in] conn_id Connection ID + * @param[in] all_phys A bit field that allows the Host to specify, for each direction, + * whether it has no preference among the PHYs that the Controller + * supports in a given direction or whether it has specified particular PHYs that it + * prefers in the TX_PHYS or RX_PHYS parameter. + * @param[in] tx_phys A bit field that indicates the transmitter PHYs that + * the Host prefers the Controller to use. If the ALL_PHYS parameter specifies + * that the Host has no preference, the TX_PHYS parameter is ignored; + * otherwise at least one bit shall be set to 1. + * @param[in] rx_phys A bit field that indicates the receiver PHYs that the + * Host prefers the Controller to use. If the ALL_PHYS parameter specifies that + * the Host has no preference, the RX_PHYS parameter is ignored; otherwise at + * least one bit shall be set to 1. + * @param[in] phy_options A bit field that allows the Host to specify options + * for PHYs. The default value for a new connection shall be all zero bits. The + * Controller may override any preferred coding for transmitting on the LE Coded + * PHY. + * @return result. + * @retval GAP_CAUSE_SUCCESS: Set request sent success.
    + * @retval GAP_CAUSE_NON_CONN: Set request sent fail.
    + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + uint8_t all_phys = GAP_PHYS_NO_PREFER_TX_BIT; + uint8_t tx_phys = GAP_PHYS_PREFER_CODED_BIT; + uint8_t rx_phys = GAP_PHYS_PREFER_CODED_BIT; + uint16_t phy_options = GAP_PHYS_OPTIONS_CODED_PREFER_S8; + le_set_phy(conn_id, all_phys, tx_phys, rx_phys, phy_options); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_PHY_UPDATE_INFO: + APP_PRINT_INFO4("GAP_MSG_LE_PHY_UPDATE_INFO:conn %d, cause 0x%x, rx_phy %d, tx_phy %d", + cb_data.p_le_phy_update_info->conn_id, + cb_data.p_le_phy_update_info->cause, + cb_data.p_le_phy_update_info->rx_phy, + cb_data.p_le_phy_update_info->tx_phy); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_set_phy(uint8_t conn_id, uint8_t all_phys, uint8_t tx_phys, uint8_t rx_phys, + T_GAP_PHYS_OPTIONS phy_options); +#endif + +/** + * @brief Disable the slave latency used in slave role. LE disable slave latency response will be returned by + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_DISABLE_SLAVE_LATENCY. + * + * NOTE: When slave latency is not 0, and user disable slave latency, the slave will listen to pkts in + * every connection interval. + * + * @param[in] conn_id Connection ID + * @param[in] disable Disable/enable slave latency + * \arg \c true disable slave latency + * \arg \c false enable slave latency + * @return result. + * @retval GAP_CAUSE_SUCCESS: Set request sent success.
    + * @retval GAP_CAUSE_NON_CONN: Set request sent fail.
    + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + bool disable = true; + le_disable_slave_latency(conn_id); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_DISABLE_SLAVE_LATENCY: + APP_PRINT_INFO1("GAP_MSG_LE_DISABLE_SLAVE_LATENCY: cause 0x%x", + cb_data.p_le_disable_slave_latency_rsp->cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_disable_slave_latency(uint8_t conn_id, bool disable); + +/** + * @brief Update instant passed channel map. LE update passed channel map response will be returned by + * @ref app_gap_callback with cb_type @ref GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP. + * + * When this feature is enabled, if we receive a instant passed channel map req, we will not disconnect + * the link. + * + * @param[in] enable Enable/disable instant update passed channel map feature. + * \arg \c true enable instant update passed channel map feature + * \arg \c false disable instant update passed channel map feature + * @return result. + * @retval GAP_CAUSE_SUCCESS Send request success + * @retval GAP_CAUSE_NON_CONN Failed. No connection + * + * Example usage + * \code{.c} + void test() + { + bool enable = true; + le_update_passed_chann_map(enable); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP: + APP_PRINT_INFO1("GAP_MSG_LE_UPDATE_PASSED_CHANN_MAP:cause 0x%x", + cb_data.p_le_update_passed_chann_map_rsp->cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_update_passed_chann_map(bool enable); + +#if F_BT_LE_GAP_CENTRAL_SUPPORT +/** + * @brief Set connection parameter. + * + * App can call this api to modify connection interval, latency and supervision timeout value. + * + * @param[in] type Connection ID for this link. + * @param[in] p_conn_param Connection parameters @ref T_GAP_LE_CONN_REQ_PARAM. + * @return result. + * @retval GAP_CAUSE_SUCCESS Send request success + * @retval GAP_CAUSE_NON_CONN Failed. No connection + * + * Example usage + * \code{.c} + void test() + { + T_GAP_LE_CONN_REQ_PARAM conn_req_param; + T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t bd_addr[BD_ADDR_SIZE] = {0x00, 0xe0, x04c, 0x23, 0x99, 0x87}; + conn_req_param.scan_interval = 0x10; + conn_req_param.scan_window = 0x10; + conn_req_param.conn_interval_min = 80; + conn_req_param.conn_interval_max = 80; + conn_req_param.conn_latency = 0; + conn_req_param.supv_tout = 1000; + conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1); + conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1); + le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param); + + le_connect(0, bd_addr, + bd_type, + GAP_LOCAL_ADDR_LE_PUBLIC, + 1000); + } + * \endcode + */ +T_GAP_CAUSE le_set_conn_param(T_GAP_CONN_PARAM_TYPE type, + T_GAP_LE_CONN_REQ_PARAM *p_conn_param); + +/** + * @brief Create a connection to a connectable advertiser. @ref le_set_conn_param shall be called first to set connection parameters. + * + * @param[in] init_phys A bit field that indicates the PHY(s) on which the advertising packets should be received on the primary + * advertising channel and the PHYs for which connection parameters have been specified. @ref GAP_PHYS_CONN_INIT. + * @param[in] remote_bd The Peer's Public Device Address, Random (static) Device Address, Non-Resolvable Private Address, or + Resolvable Private Address depending on the Peer_Address_Type parameter. + * @param[in] remote_bd_type The type of address used in the connectable advertisement sent by the peer. + * @param[in] local_bd_type The type of address being used in the connection request packets. + * @param[in] scan_timeout Scan timeout value. If time has expired before connection has been established, stack will + * cancel create connection. + * Time = N * 10 ms, if time equals 0, stack will wait forever. + * @return result. + * @retval GAP_CAUSE_SUCCESS Send request success + * @retval GAP_CAUSE_NON_CONN Failed. No connection + * + * Example usage + * \code{.c} + void test() + { + T_GAP_LE_CONN_REQ_PARAM conn_req_param; + T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t bd_addr[BD_ADDR_SIZE] = {0x00, 0xe0, x04c, 0x23, 0x99, 0x87}; + conn_req_param.scan_interval = 0x10; + conn_req_param.scan_window = 0x10; + conn_req_param.conn_interval_min = 80; + conn_req_param.conn_interval_max = 80; + conn_req_param.conn_latency = 0; + conn_req_param.supv_tout = 1000; + conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1); + conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1); + le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param); + + le_connect(0, bd_addr, + bd_type, + GAP_LOCAL_ADDR_LE_PUBLIC, + 1000); + } + + void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) + { + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, gap_conn_state, new_state, disc_cause); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE)) + && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + + le_adv_start(); + } + break; + + case GAP_CONN_STATE_CONNECTED: + { + uint16_t conn_interval; + uint16_t conn_latency; + uint16_t conn_supervision_timeout; + uint8_t remote_bd[6]; + T_GAP_REMOTE_ADDR_TYPE remote_bd_type; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + le_get_conn_addr(conn_id, remote_bd, &remote_bd_type); + APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x", + TRACE_BDADDR(remote_bd), remote_bd_type, + conn_interval, conn_latency, conn_supervision_timeout); + } + break; + + default: + break; + } + gap_conn_state = new_state; + } + + //When link is connected, stack will read remote used feaures, and the result will be notified by msg GAP_MSG_LE_REMOTE_FEATS_INFO + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_REMOTE_FEATS_INFO: + APP_PRINT_INFO3("GAP_MSG_LE_REMOTE_FEATS_INFO: conn id %d, cause 0x%x, remote_feats %b", + cb_data.p_le_remote_feats_info->conn_id, + cb_data.p_le_remote_feats_info->cause, + TRACE_BINARY(8, cb_data.p_le_remote_feats_info->remote_feats)); + break; + } + ... + } + * + * \endcode + */ +T_GAP_CAUSE le_connect(uint8_t init_phys, uint8_t *remote_bd, + T_GAP_REMOTE_ADDR_TYPE remote_bd_type, + T_GAP_LOCAL_ADDR_TYPE local_bd_type, uint16_t scan_timeout); +#endif +/** + * @brief Send connection parameter update request msg to bt stack. Connection parameter update result will be returned + * by @ref app_handle_conn_param_update_evt. + * + * App can call this api to modify connection interval, latency and supervision timeout value. + * + * @param[in] conn_id Connection ID for this link. + * @param[in] conn_interval_min Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step). + * @param[in] conn_interval_max Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step). + * @param[in] conn_latency Value range: 0x0000 - 0x01F3 + This shall be less than or equal to (((supervision_timeout * 10ms) / (conn_interval_max * 1.25ms * 2)) - 1). + * @param[in] supervision_timeout Value range: 0x000A - 0x0C80 (100ms - 32000ms, 10ms/step). + * @param[in] ce_length_min Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step). + * @param[in] ce_length_max Value range: 0x0006 - 0x0C80 (7.5ms - 4000ms, 1.25ms/step). + * @return result. + * @retval GAP_CAUSE_SUCCESS Send request success. + * @retval GAP_CAUSE_NON_CONN Failed. No connection. + * + * Example usage + * \code{.c} + void test() + { + uint8_t conn_id = 0; + T_GAP_CAUSE cause; + uint16_t conn_interval_min = 0x10; + uint16_t conn_interval_max = 0x10; + uint16_t conn_latency = 50; + uint16_t supervision_timeout = 1000; + uint16_t ce_length_min = 2 * (conn_interval_min - 1); + uint16_t ce_length_max = 2 * (conn_interval_max - 1); + + + cause = le_update_conn_param(conn_id, + conn_interval_min, + conn_interval_max, + conn_latency, + supervision_timeout, + ce_length_min, + ce_length_max + ); + + } + + void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause) + { + switch (status) + { + case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS: + { + uint16_t conn_interval; + uint16_t conn_slave_latency; + uint16_t conn_supervision_timeout; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x", + conn_interval, conn_slave_latency, conn_supervision_timeout); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_FAIL: + { + APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_PENDING: + { + APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending."); + } + break; + + default: + break; + } + } + + + //If app receive connection parameter update request from remote device, app will receive GAP_MSG_LE_CONN_UPDATE_IND + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_CONN_UPDATE_IND: + APP_PRINT_INFO4("GAP_MSG_LE_CONN_UPDATE_IND: conn_interval_max 0x%x, conn_interval_min 0x%x, conn_latency 0x%x + , supervision_timeout 0x%x", + cb_data.p_le_conn_update_ind->conn_interval_max, + cb_data.p_le_conn_update_ind->conn_interval_min, + cb_data.p_le_conn_update_ind->conn_latency, + cb_data.p_le_conn_update_ind->supervision_timeout); + if (cb_data.p_le_conn_update_ind->conn_latency > 60) + { + result = APP_RESULT_REJECT; + } + else + { + result = APP_RESULT_ACCEPT; + } + break; + ... + } + } + * \endcode + */ +T_GAP_CAUSE le_update_conn_param(uint8_t conn_id, + uint16_t conn_interval_min, + uint16_t conn_interval_max, + uint16_t conn_latency, + uint16_t supervision_timeout, + uint16_t ce_length_min, + uint16_t ce_length_max); + +/** + * @brief Set the link tx power for the device. + * + * Set LE link tx power. Or reset link tx power to default value. + * Tx power is set to default every time a link is connect. Use this command + * after the link is connected. + * + * @param[in] conn_id Connection ID for this link. + * @param[in] reset Whether to reset to default value. + * @param[in] tx_power index for power level. NOTE: The following tx power table may be changed in future version. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_CAUSE cause; + uint8_t conn_id = 0; + bool reset = false; + uint8_t tx_pwr = 0x80; + + cause = le_set_conn_tx_power(conn_id, reset, tx_pwr); + + return (T_USER_CMD_PARSE_RESULT)cause; + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_SET_CONN_TX_PWR: + APP_PRINT_INFO1("GAP_MSG_LE_SET_CONN_TX_PWR: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + } + * \endcode + */ +T_GAP_CAUSE le_set_conn_tx_power(uint8_t conn_id, bool reset, uint8_t tx_power); +/** @} */ /* End of group GAP_CONNECTION_COMMON_EXPORT_Functions */ +/** @} */ /* End of group GAP_LE_CONNECTION_MODULE */ + + +/*------------------------------------------------------------------- +-------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_CONN_LE_H */ + + diff --git a/inc/bluetooth/gap/gap_credit_based_conn.h b/inc/bluetooth/gap/gap_credit_based_conn.h new file mode 100644 index 0000000..54cb568 --- /dev/null +++ b/inc/bluetooth/gap/gap_credit_based_conn.h @@ -0,0 +1,155 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file gap_credit_based_conn.h +* @brief header file of LE Credit-Based Connection message handle. +* @details none. +* @author Tifnan +* @date 2016-03-16 +* @version v0.1 +********************************************************************************************************* +*/ + +#ifndef _LE_CREDIT_BASED_CONN_H_ +#define _LE_CREDIT_BASED_CONN_H_ + +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap.h" + +#if F_BT_LE_4_1_COC_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_CREDIT_BASED_CONN GAP LE Credit Based Connection Module + * @{ + */ +typedef enum +{ + GAP_CHANN_STATE_DISCONNECTED, //!< Disconnected. + GAP_CHANN_STATE_CONNECTING, //!< Connecting. + GAP_CHANN_STATE_CONNECTED, //!< Connected. + GAP_CHANN_STATE_DISCONNECTING //!< Disconnecting. +} T_GAP_CHANN_STATE; + +typedef enum +{ + COC_PARAM_CREDITS_THRESHOLD = 0x400, + COC_PARAM_LOCAL_MTU = 0x401, +} T_LE_COC_PARAM_TYPE; + +typedef enum +{ + COC_CHANN_PARAM_CUR_CREDITS = 0x410, + COC_CHANN_PARAM_MAX_CREDITS = 0x411, + COC_CHANN_PARAM_MTU = 0x412, +} T_LE_COC_CHANN_PARAM_TYPE; + +/** @brief Definition of LE security requirement*/ +typedef enum +{ + LE_COC_SECURITY_NONE, /**< Security None */ + LE_COC_SECURITY_UNAUTHEN_ENCRYT, /**< Security unauthenticated encryption */ + LE_COC_SECURITY_AUTHEN_ENCRYT, /**< Security authenticated encryption */ + LE_COC_SECURITY_UNAUTHEN_DATA_SIGN,/**< Security unauthenticated data signed */ + LE_COC_SECURITY_AUTHEN_DATA_SIGN, /**< Security authenticated data signed */ + LE_COC_SECURITY_AUTHOR /**< Security authorized */ +} T_LE_COC_SECURITY_MODE; + +typedef struct +{ + uint8_t conn_id; /**< local link ID. */ + uint16_t cid; /**< channel ID */ + uint16_t value_len; /**< value length */ + uint8_t *p_data; +} T_LE_COC_RECEIVE_DATA; + +typedef struct +{ + uint8_t conn_id; /**< local link ID. */ + uint16_t cid; /**< channel ID */ + uint16_t cause; /**< value length */ + uint8_t credit; +} T_LE_COC_SEND_DATA; + +typedef struct +{ + uint8_t conn_id; + uint16_t cid; + T_GAP_CHANN_STATE conn_state; + uint16_t cause; +} T_LE_COC_CHANN_STATE; + +/** @brief Response of le credit based security register request.*/ +typedef struct +{ + uint16_t cause; +} T_LE_COC_CREDIT_BASED_SECURITY_REG_RSP; + +/** @brief Response of le credit based psm register request.*/ +typedef struct +{ + uint16_t le_psm; + uint16_t cause; +} T_LE_COC_CREDIT_BASED_PSM_REG_RSP; + +#define GAP_COC_MSG_LE_CHANN_STATE 0x01 +#define GAP_COC_MSG_LE_REG_PSM 0x02 +#define GAP_COC_MSG_LE_SET_PSM_SECURITY 0x03 +#define GAP_COC_MSG_LE_SEND_DATA 0x04 +#define GAP_COC_MSG_LE_RECEIVE_DATA 0x05 + +typedef union +{ + T_LE_COC_CHANN_STATE *p_le_chann_state; + T_LE_COC_RECEIVE_DATA *p_le_receive_data; + T_LE_COC_SEND_DATA *p_le_send_data; + T_LE_COC_CREDIT_BASED_SECURITY_REG_RSP *p_le_set_psm_security_rsp; + T_LE_COC_CREDIT_BASED_PSM_REG_RSP *p_le_reg_psm_rsp; +} T_LE_COC_DATA; + +typedef T_APP_RESULT(*P_FUN_LE_COC_APP_CB)(uint8_t coc_type, void *p_coc_data); +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_LE_CREDIT_BASED_CONN_Exported_Functions GAP LE Credit Based Connection Exported Functions + * @brief + * @{ + */ +bool le_coc_init(uint8_t chann_num); +void le_coc_register_app_cb(P_FUN_LE_COC_APP_CB app_callback); +T_GAP_CAUSE le_coc_set_param(T_LE_COC_PARAM_TYPE param, uint8_t len, void *p_value); +T_GAP_CAUSE le_coc_get_chann_param(T_LE_COC_CHANN_PARAM_TYPE param, void *p_value, uint16_t cid); +T_GAP_CAUSE le_coc_create(uint8_t conn_id, uint16_t le_psm); +T_GAP_CAUSE le_coc_disc(uint16_t cid); +T_GAP_CAUSE le_coc_send_data(uint16_t cid, uint8_t *p_data, uint16_t data_len); +T_GAP_CAUSE le_coc_reg_psm(uint16_t le_psm, uint8_t action); +T_GAP_CAUSE le_coc_set_psm_security(uint16_t le_psm, bool active, T_LE_COC_SECURITY_MODE mode, + uint8_t key_size); +/** End of GAP_LE_CREDIT_BASED_CONN_Exported_Functions + * @} + */ + +/** End of GAP_LE_CREDIT_BASED_CONN + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ +#endif + + + +#endif /* _LE_CREDIT_BASED_CONN_H_ */ diff --git a/inc/bluetooth/gap/gap_dtm.h b/inc/bluetooth/gap/gap_dtm.h new file mode 100644 index 0000000..e1b489e --- /dev/null +++ b/inc/bluetooth/gap/gap_dtm.h @@ -0,0 +1,560 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_dtm.h + * @brief + * @details + * @author jeff_zheng + * @date 2017-08-02 + * @version v1.0 + ****************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + ****************************************************************************** + */ +/* Define to prevent recursive inclusion **/ +#ifndef GAP_DTM_H +#define GAP_DTM_H + +#include "upperstack_config.h" +#include "gap_le.h" +#include + +#if F_BT_LE_4_0_DTM_SUPPORT +/** @addtogroup GAP_LE_DTM GAP LE Direct Test Mode Module + * @brief GAP LE Direct Test Mode Module + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_DTM_Exported_Types GAP LE DTM Exported Types + * @brief + * @{ + */ +typedef enum +{ + GAP_DTM_MODULATION_INDEX_STANDARD = 0x00, /**< Assume transmitter will have a standard modulation index. */ + GAP_DTM_MODULATION_INDEX_STABLE = 0x01, /**< Assume transmitter will have a stable modulation index. */ +} T_GAP_DTM_MODULATION_INDEX_TYPE; + +typedef enum +{ + GAP_DTM_PACKET_PAYLOAD_PRBS9 = 0x00, /**< PRBS9 sequence '11111111100000111101' (in transmission order). */ + GAP_DTM_PACKET_PAYLOAD_1100 = 0x01, /**< Repeated '11110000' (in transmission order) sequence. */ + GAP_DTM_PACKET_PAYLOAD_10 = 0x02, /**< Repeated '10101010' (in transmission order) sequence. */ + GAP_DTM_PACKET_PAYLOAD_PRBS15 = 0x03, /**< PRBS15 sequence. */ + GAP_DTM_PACKET_PAYLOAD_ALL1 = 0x04, /**< Repeated '11111111' (in transmission order) sequence. . */ + GAP_DTM_PACKET_PAYLOAD_ALL0 = 0x05, /**< Repeated '00000000' (in transmission order) sequence. . */ + GAP_DTM_PACKET_PAYLOAD_0011 = 0x06, /**< Repeated '00001111' (in transmission order) sequence. . */ + GAP_DTM_PACKET_PAYLOAD_01 = 0x07 /**< Repeated '01010101' (in transmission order) sequence. . */ +} T_GAP_DTM_PACKET_PAYLOAD_TYPE; + +typedef enum +{ + GAP_DTM_PHYS_1M = 0x01, /**< LE PHY 1M used. */ + GAP_DTM_PHYS_2M = 0x02, /**< LE PHY 2M used. */ + GAP_DTM_PHYS_CODED_S8 = 0x03, /**< LE Coded PHY with S=8 data coding. */ + GAP_DTM_PHYS_CODED_S2 = 0x04, /**< LE Coded PHY with S=2 data coding. */ +} T_GAP_DTM_PHYS_TYPE; + +/** End of GAP_LE_DTM_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup GAP_LE_DTM_Exported_Functions GAP LE Direct Test Mode Exported Functions + * @brief GAP LE Direct Test Mode Exported Functions + * @{ + */ + +/** +* @brief Start a test where the DUT receives test reference packets at a fixed interval. + The tester generates the test reference packets. +* +* @param[in] rx_chann - channel to receive packets. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + rx_chann = (command & 0x3f00) >> 8; + le_dtm_receiver_test_req(rx_chann); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_RECEIVER_TEST: + status = p_data->p_le_receive_test_rsp->cause; + if (status == 0) + { + APP_PRINT_INFO2("dtm_event_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + else + { + event |= 1; + APP_PRINT_INFO2("dtm_evt_trace: EV = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + dtm_uart_send_bytes(event); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_receiver_test(uint8_t rx_chann); + +/** +* @brief Start a test where the DUT generates test reference packets at a fixed interval. + The Controller shall transmit at maximum power. +* +* @param[in] tx_chann - channel to transmit packets. +* @param[in] data_len - length in bytes of payload data in each packet. +* @param[in] pkt_pl - the value of packet payload. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + tx_chann = (command & 0x3f00) >> 8; + data_len = up_2_bits << 6 | (command & 0xfc) >> 2; + pkt_pl = command & 0x03; + le_dtm_transmitter_test(tx_chann, data_len, pkt_pl); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_TRANSMITTER_TEST: + status = p_data->le_cause.cause; + if (status == 0) + { + APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + else + { + event |= 1; + APP_PRINT_INFO2("dtm_evt_trace: st = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + dtm_uart_send_bytes(event); + break; + } + ... + } + * \endcode + */ + +T_GAP_CAUSE le_dtm_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl); + +/** +* @brief Stop any test which is in progress. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + ... + le_dtm_test_end(); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_TEST_END: + status = p_data->p_le_dtm_test_end_rsp->cause; + if (status == 0) + { + event |= 1 << 15; + event |= p_data->p_le_dtm_test_end_rsp->num_pkts; + APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, packet count = 0x%x", (event & 0x8000) >> 15, + event & 0x7fff); + } + else + { + event |= 1; + APP_PRINT_INFO2("dtm_evt_trace: ev = 0x%x, st = 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + dtm_uart_send_bytes(event); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_test_end(void); + +#if F_BT_LE_5_0_DTM_SUPPORT +/** +* @brief Start a test where the DUT receives test reference packets at a fixed interval. +* +* @param[in] rx_chann - channel to receive packets. +* @param[in] phy - physical to receive packets. +* @param[in] mod_idx - modulation index to receive packets. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + static uint8_t phy = 1; + static uint8_t mod_idx = 0; + rx_chann = (command & 0x3f00) >> 8; +#if F_BT_LE_5_0_SUPPORT + if (le_dtm_enhanced_receiver_test(rx_chann, phy, mod_idx) != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_receiver_test fail"); + } +#endif + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... +#if F_BT_LE_5_0_SUPPORT + case GAP_MSG_LE_DTM_ENHANCED_RECEIVER_TEST: +#endif + status = p_data->le_cause.cause; + if (status == 0) + { + APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + else + { + event |= 1; + APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + dtm_uart_send_bytes(event); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_enhanced_receiver_test(uint8_t rx_chann, uint8_t phy, uint8_t mod_idx); + +/** +* @brief Start a test where the DUT generates test reference packets at a fixed interval. +* +* @param[in] tx_chann - Channel to transmit packets. +* @param[in] data_len - Length in bytes of payload data in each packet. +* @param[in] pkt_pl - the value of packet payload. +* @param[in] phy - physical to transmit packets. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + static uint8_t phy = 1; + tx_chann = (command & 0x3f00) >> 8; + data_len = up_2_bits << 6 | (command & 0xfc) >> 2; + pkt_pl = command & 0x03;; +#if F_BT_LE_5_0_SUPPORT + if (le_dtm_enhanced_transmitter_test(tx_chann, data_len, pkt_pl, phy) != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR0("dtm_test_req: le_dtm_enhanced_transmitter_test fail"); + } +#endif + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... +#if F_BT_LE_5_0_SUPPORT + case GAP_MSG_LE_DTM_ENHANCED_TRANSMITTER_TEST: +#endif + status = p_data->le_cause.cause; + if (status == 0) + { + APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + else + { + event |= 1; + APP_PRINT_INFO2("app_gap_callback: event 0x%x, status 0x%x", (event & 0x8000) >> 15, event & 0x1); + } + dtm_uart_send_bytes(event); + break; + + ... + } + * \endcode + */ + +T_GAP_CAUSE le_dtm_enhanced_transmitter_test(uint8_t tx_chann, uint8_t data_len, uint8_t pkt_pl, + uint8_t phy); +#endif + +#if F_BT_LE_5_1_DTM_SUPPORT +/** +* @brief Start a test where the DUT receives test reference packets at a fixed interval. +* +* @param[in] rx_chann - channel to receive packets. + Range: 0x00 to 0x27. +* @param[in] phy - physical to receive packets: @ref T_GAP_PHYS_TYPE. +* @param[in] modulation_index - modulation index to receive packets: @ref T_GAP_DTM_MODULATION_INDEX_TYPE. +* @param[in] expected_cte_length - the expected length of the Constant Tone Extensions in received + test reference packets. + Range: 0x00 (No Constant Tone Extension expected (default)) or 0x02 to 0x14. + Units: 8 us. +* @param[in] expected_cte_type - the expected type of the Constant Tone Extensions in received + test reference packets: @ref T_GAP_CTE_TYPE. +* @param[in] slot_durations - modulation index to receive packets and shall be ignored when expected_cte_type + is not set to GAP_CTE_TYPE_AOA: @ref T_GAP_SLOT_DUATIONS_TYPE. +* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when + expected_cte_type is not set to GAP_CTE_TYPE_AOA. + Range: 0x02 to max_switching_pattern_length supported by controller + max_switching_pattern_length shall be less than or equal to 0x4B. +* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type + is not set to GAP_CTE_TYPE_AOA. +* +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + uint8_t rx_channel = 0; + T_GAP_PHYS_TYPE phy = GAP_PHYS_1M; + T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index = GAP_DTM_MODULATION_INDEX_STANDARD; + uint8_t expected_cte_length = 2; + T_GAP_CTE_TYPE expected_cte_type = GAP_CTE_TYPE_AOA; + T_GAP_SLOT_DUATIONS_TYPE slot_durations = GAP_SLOT_DURATIONS_SWITCH_SAMPLE_1US; + uint8_t switching_pattern_length = 2; + uint8_t p_antenna_ids[2] = {0, 1}; + + le_dtm_receiver_test_v3(rx_channel, phy, modulation_index, expected_cte_length, + expected_cte_type, slot_durations, + switching_pattern_length, p_antenna_ids); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_RECEIVER_TEST_V3: + APP_PRINT_INFO1("GAP_MSG_LE_DTM_RECEIVER_TEST_V3: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_receiver_test_v3(uint8_t rx_channel, T_GAP_PHYS_TYPE phy, + T_GAP_DTM_MODULATION_INDEX_TYPE modulation_index, + uint8_t expected_cte_length, T_GAP_CTE_TYPE expected_cte_type, + T_GAP_SLOT_DUATIONS_TYPE slot_durations, + uint8_t switching_pattern_length, uint8_t *p_antenna_ids); + +/** +* @brief Start a test where the DUT transmits test reference packets at a fixed interval. +* +* @param[in] tx_channel - channel to transmit packets. + Range: 0x00 to 0x27. +* @param[in] test_data_length - length in bytes of payload data in each packet. + Range: 0x00 to 0xFF. +* @param[in] packet_payload - contents of the payload of the test reference packets: +* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE. +* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE. +* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets. + Range: 0x00 (Do not transmit a Constant Tone Extension) or 0x02 to 0x14. + Units: 8 us. +* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets. + @ref T_GAP_CTE_TYPE. +* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when + cte_type is set to GAP_CTE_TYPE_AOA. + Range: 0x02 to max_switching_pattern_length supported by controller + max_switching_pattern_length shall be less than or equal to 0x4B. +* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type +* is set to GAP_CTE_TYPE_AOA. +* +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + uint8_t tx_channel = 0; + uint8_t test_data_length = 2; + T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9; + T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M; + uint8_t cte_length = 2; + T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT; + uint8_t switching_pattern_length = 2; + uint8_t p_antenna_ids[2] = {0, 1}; + + le_dtm_transmitter_test_v3(tx_channel, test_data_length, + packet_payload, phy, cte_length, cte_type, + switching_pattern_length, p_antenna_ids); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3: + APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V3: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_transmitter_test_v3(uint8_t tx_channel, uint8_t test_data_length, + T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy, + uint8_t cte_length, T_GAP_CTE_TYPE cte_type, + uint8_t switching_pattern_length, uint8_t *p_antenna_ids); +#endif + +#if F_BT_LE_5_2_DTM_SUPPORT +/** +* @brief Start a test where the DUT transmits test reference packets at a fixed interval. +* +* @param[in] tx_channel - channel to transmit packets. + N = (F-2402) / 2 + Range: 0x00 to 0x27 + Frequency Range: 2402 MHz to 2480 MHz. +* @param[in] test_data_length - length in bytes of payload data in each packet. + Range: 0x00 to 0xFF. +* @param[in] packet_payload - contents of the payload of the test reference packets: +* @ref T_GAP_DTM_PACKET_PAYLOAD_TYPE. +* @param[in] phy - physical to transmit packets: @ref T_GAP_DTM_PHYS_TYPE. +* @param[in] cte_length - the length of the Constant Tone Extension in the test reference packets. + 0x00: Do not transmit a Constant Tone Extension + 0x02 to 0x14: Length of the Constant Tone Extension in 8 us units. +* @param[in] cte_type - the type of the Constant Tone Extension in the test reference packets. + @ref T_GAP_CTE_TYPE. +* @param[in] switching_pattern_length - the number of Antenna IDs in the pattern and shall be ignored when + cte_type is set to GAP_CTE_TYPE_AOA. + Range: 0x02 to max_switching_pattern_length supported by controller + max_switching_pattern_length shall be less than or equal to 0x4B. +* @param[in] p_antenna_ids - Antenna ID in the pattern and shall be ignored when expected_cte_type +* is set to GAP_CTE_TYPE_AOA. +* @param[in] tx_power_level - set transmitter to the specified or the nearest transmit power level. + Range: -127 to +20. + Units: dBm. + Note: 0x7E Set transmitter to minimum transmit power level. + 0x7F Set transmitter to maximum transmit power level. +* +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. + * + * Example usage + * \code{.c} + void dtm_test_req(uint16_t command) + { + uint8_t tx_channel = 0; + uint8_t test_data_length = 2; + T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload = GAP_DTM_PACKET_PAYLOAD_PRBS9; + T_GAP_DTM_PHYS_TYPE phy = GAP_DTM_PHYS_1M; + uint8_t cte_length = 2; + T_GAP_CTE_TYPE cte_type = GAP_CTE_TYPE_AOD_2US_SLOT; + uint8_t switching_pattern_length = 2; + uint8_t p_antenna_ids[2] = {0, 1}; + int8_t tx_power_level = 0x10; + + le_dtm_transmitter_test_v3(tx_channel, test_data_length, + packet_payload, phy, cte_length, cte_type, + switching_pattern_length, p_antenna_ids, tx_power_level); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + uint16_t status = 0; + uint16_t event = 0; + switch (cb_type) + { + ... + case GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4: + APP_PRINT_INFO1("GAP_MSG_LE_DTM_TRANSMITTER_TEST_V4: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_dtm_transmitter_test_v4(uint8_t tx_channel, uint8_t test_data_length, + T_GAP_DTM_PACKET_PAYLOAD_TYPE packet_payload, T_GAP_DTM_PHYS_TYPE phy, + uint8_t cte_length, T_GAP_CTE_TYPE cte_type, + uint8_t switching_pattern_length, uint8_t *p_antenna_ids, int8_t tx_power_level); +#endif +/** End of GAP_LE_DTM_Exported_Functions + * @} + */ + +/** End of GAP_LE_DTM + * @} + */ +#endif + +#endif /* GAP_DTM_H */ diff --git a/inc/bluetooth/gap/gap_ext_adv.h b/inc/bluetooth/gap/gap_ext_adv.h new file mode 100644 index 0000000..fec7de4 --- /dev/null +++ b/inc/bluetooth/gap/gap_ext_adv.h @@ -0,0 +1,834 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_ext_adv.h +* @brief Header file for Gap ext adv +* @details This file defines extended advertising related API. +* @author ranhui +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_EXT_ADV_H +#define GAP_EXT_ADV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" + +#if F_BT_LE_5_0_AE_ADV_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_EXTENDED_ADV GAP LE Extended Adv Module + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Macros GAP LE Extended Adv Exported Macros + * @{ + */ + +/** @defgroup EXT_ADV_PARAM Extended Advertising Parameter flag + * @brief Use the combination of macro definitions to set extended advertising related parameters + for a specified advertising set by calling @ref le_ext_adv_start_setting. + * @{ + */ +#define EXT_ADV_SET_AUTO 0x00 /**< Automatically set extended advertising related parameters (including advertising parameters, + advertising data and scan response data) according to advertising event properties. */ +#define EXT_ADV_SET_ADV_PARAS 0x01 /**< Set advertising parameters supplied by @ref le_ext_adv_set_adv_param. */ +#define EXT_ADV_SET_ADV_DATA 0x02 /**< Set advertising data supplied by @ref le_ext_adv_set_adv_data. */ +#define EXT_ADV_SET_SCAN_RSP_DATA 0x04 /**< Set scan response data supplied by @ref le_ext_adv_set_scan_response_data. */ +#define EXT_ADV_SET_RANDOM_ADDR 0x08 /**< Set random address supplied by @ref le_ext_adv_set_random. */ +/** End of EXT_ADV_PARAM + * @} + */ + +/** @defgroup EXT_ADV_EVT_PROP Extended Advertising Event Properties flag + * @brief Use the combination of macro definitions to describe the type of advertising event. + Optional values: @ref T_LE_EXT_ADV_LEGACY_ADV_PROPERTY and @ref T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY. + * @{ + */ +#define GAP_EXT_ADV_EVT_PROP_CONNECTABLE_ADV 0x01 /**< Connectable advertising. */ +#define GAP_EXT_ADV_EVT_PROP_SCANNABLE_ADV 0x02 /**< Scannable advertising. */ +#define GAP_EXT_ADV_EVT_PROP_DIRECTED_ADV 0x04 /**< Directed advertising. */ +#define GAP_EXT_ADV_EVT_PROP_HDC_DIRECTED_ADV 0x08 /**< High Duty Cycle Directed Connectable advertising. */ +#define GAP_EXT_ADV_EVT_PROP_USE_LEGACY_ADV 0x10 /**< Use legacy advertising PDUs. */ +#define GAP_EXT_ADV_EVT_PROP_OMIT_ADV_ADDR 0x20 /**< Omit advertiser's address from all PDUs ("anonymous advertising"). */ +#define GAP_EXT_ADV_EVT_PROP_INCLUDE_TX_POWER 0x40 /**< Include TxPower in the extended header of the advertising PDU. */ +/** End of EXT_ADV_EVT_PROP + * @} + */ + +#define GAP_MAX_LEGACY_ADV_LEN 31 + +#define GAP_INVALID_ADV_HANDLE 0xFF +/** End of GAP_LE_EXTENDED_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Types GAP LE Extended Adv Exported Types + * @{ + */ + +/** @brief GAP extended advertising state. */ +typedef enum +{ + EXT_ADV_STATE_IDLE, /**< Idle, no advertising. */ + EXT_ADV_STATE_START, /**< Start Advertising. A temporary state, haven't received the result. */ + EXT_ADV_STATE_ADVERTISING, /**< Advertising. */ + EXT_ADV_STATE_STOP, /**< Stop Advertising. A temporary state, haven't received the result. */ +} T_GAP_EXT_ADV_STATE; + +/** @brief Advertising Event Properties values for legacy advertising PDUs. */ +typedef enum +{ + LE_EXT_ADV_LEGACY_ADV_CONN_SCAN_UNDIRECTED = 0x13, /**< Connectable and scannable undirected. Advertising data or scan response data shall not exceed 31 bytes. */ + LE_EXT_ADV_LEGACY_ADV_CONN_LOW_DUTY_DIRECTED = 0x15, /**< Connectable directed (low duty cycle). */ + LE_EXT_ADV_LEGACY_ADV_CONN_HIGH_DUTY_DIRECTED = 0x1D, /**< Connectable directed (high duty cycle). */ + LE_EXT_ADV_LEGACY_ADV_SCAN_UNDIRECTED = 0x12, /**< Scannable undirected. Advertising data or scan response data shall not exceed 31 bytes. */ + LE_EXT_ADV_LEGACY_ADV_NON_SCAN_NON_CONN_UNDIRECTED = 0x10, /**< Non-connectable and non-scannable undirected. Advertising data shall not exceed 31 bytes. */ +} T_LE_EXT_ADV_LEGACY_ADV_PROPERTY; + +/** @brief Advertising Event Properties values for extended advertising PDUs. */ +typedef enum +{ + LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_UNDIRECTED = 0x00, /**< Non-connectable and non-scannable undirected. If only one advertising set is used, advertising data shall not exceed 1024 bytes. */ + LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_DIRECTED = 0x04, /**< Non-connectable and non-scannable directed. If only one advertising set is used, advertising data shall not exceed 1024 bytes. */ + LE_EXT_ADV_EXTENDED_ADV_CONN_UNDIRECTED = 0x01, /**< Connectable undirected. Advertising data shall not exceed 245 bytes. */ + LE_EXT_ADV_EXTENDED_ADV_CONN_DIRECTED = 0x05, /**< Connectable directed. Advertising data shall not exceed 239 bytes. */ + LE_EXT_ADV_EXTENDED_ADV_SCAN_UNDIRECTED = 0x02, /**< Scannable undirected. If only one advertising set is used, scan response data shall not exceed 991 bytes. */ + LE_EXT_ADV_EXTENDED_ADV_SCAN_DIRECTED = 0x06, /**< Scannable directed. If only one advertising set is used, scan response data shall not exceed 991 bytes. */ +} T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY; + +/** @brief Supported advertising parameters type. */ +typedef enum +{ + GAP_PARAM_EXT_ADV_MAX_DATA_LEN = 0x330, /**< Maximum length of supported data for use as advertisement data or scan + response data. Read only. Size is 2 bytes. */ + GAP_PARAM_EXT_ADV_MAX_SETS = 0x331, /**< Maximum number of supported advertising sets. Read only. Size is 1 byte. */ +} T_LE_EXT_ADV_PARAM_TYPE; + +/** End of GAP_LE_EXTENDED_ADV_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_ADV_Exported_Functions GAP LE Extended Adv Exported Functions + * @brief + * @{ + */ +/** + * @brief Initialization the number of advertising sets. + * + * @param[in] adv_set_num Advertising sets number, range: 1 - 10. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure, invalid parameter. + * @retval GAP_CAUSE_NO_RESOURCE Operation failure, memory acquisition failure. + * + * Example usage + * \code{.c} + void test(void) + { + le_ext_adv_init(6); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_init(uint8_t adv_set_num); + +/** + * @brief Get a GAP extended advertising parameter. + * + * NOTE: You can call this function with a extended advertising parameter type and it will get a + * extended advertising parameter. Extended advertising parameters are defined in @ref T_LE_EXT_ADV_PARAM_TYPE. + * + * @param[in] param Advertising parameter type: @ref T_LE_EXT_ADV_PARAM_TYPE + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate data type (For example: + * if data type of param is uint16_t, p_value will be cast to pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure, invalid parameter. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t max_adv_data_len; + le_ext_adv_get_param(GAP_PARAM_EXT_ADV_MAX_DATA_LEN, &max_adv_data_len); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_get_param(T_LE_EXT_ADV_PARAM_TYPE param, void *p_value); + +/** + * @brief Create an advertising handle which is used to identify an advertising set. + * + * @return Advertising handle. + * @retval 0x00-0xFE Operation success. + * @retval 0xFF Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t adv_handle; + adv_handle = le_ext_adv_create_adv_handle(); + } + * \endcode + */ +uint8_t le_ext_adv_create_adv_handle(void); + +/** + * @brief Get adv handle from connection ID. + * + * If the advertising ends because a connection was created, + * application can call le_ext_adv_get_adv_handle_by_conn_id() to get the adverting handle information + * when the advertising set state switches to EXT_ADV_STATE_IDLE. + * + * @param[in] conn_id Connection ID. + * @return adv_handle. + * @retval 0-0xFE Operation success. + * @retval 0xFF Operation failure, Get advertising handle failed. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t adv_handle; + adv_handle = le_ext_adv_get_adv_handle_by_conn_id(conn_id); + } + * \endcode + */ +uint8_t le_ext_adv_get_adv_handle_by_conn_id(uint8_t conn_id); + +/** + * @brief Set GAP extended advertising parameters for an advertising set. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] adv_event_prop Type of advertising event. + Values for extended advertising PDUs: @ref T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY. + Values for legacy advertising PDUs: @ref T_LE_EXT_ADV_LEGACY_ADV_PROPERTY. + * @param[in] primary_adv_interval_min Minimum advertising interval for undirected and low duty directed advertising. + In units of 0.625ms, range: 0x000020 to 0xFFFFFF. + * @param[in] primary_adv_interval_max Maximum advertising interval for undirected and low duty directed advertising. + In units of 0.625ms, range: 0x000020 to 0xFFFFFF. + * @param[in] primary_adv_channel_map A bit field that indicates the advertising channels that shall be used when + transmitting advertising packets. @ref ADV_CHANNEL_MAP. + * @param[in] own_address_type Local address type, @ref T_GAP_LOCAL_ADDR_TYPE. + * @param[in] peer_address_type Remote address type, GAP_REMOTE_ADDR_LE_PUBLIC or GAP_REMOTE_ADDR_LE_RANDOM in @ref T_GAP_REMOTE_ADDR_TYPE. + GAP_REMOTE_ADDR_LE_PUBLIC: Public Device Address or Public Identity Address. + GAP_REMOTE_ADDR_LE_RANDOM: Random Device Address or Random(static) Identity Address. + * @param[in] p_peer_address Remote address. + * @param[in] filter_policy Advertising filter policy: @ref T_GAP_ADV_FILTER_POLICY. + * @param[in] tx_power Advertising Tx power. + * @param[in] primary_adv_phy Indicate the PHY on which the advertising packets are transmitted on the primary advertising channel. + @ref T_GAP_PHYS_PRIM_ADV_TYPE. + If legacy advertising PDUs are being used, the primary_adv_phy shall indicate the LE 1M PHY (@ref GAP_PHYS_PRIM_ADV_1M). + * @param[in] secondary_adv_max_skip Maximum number of advertising events that can be skipped. Usually set to zero. + * @param[in] secondary_adv_phy Indicate the PHY on which the advertising packets are transmitted on the secondary advertising channel. + @ref T_GAP_PHYS_TYPE. + * @param[in] adv_sid Specify the value to be transmitted in Advertising SID subfield of those advertising channel + PDUs that have this field. Usually set to zero. + * @param[in] scan_req_notification_enable Indicate whether Host will be notified upon the receipt of a scan request PDU. + Usually set to false. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found. + * + * Example usage + * \code{.c} + void le_init_ext_adv_params_ext_conn(void) + { + uint8_t adv_handle; + T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = LE_EXT_ADV_EXTENDED_ADV_CONN_UNDIRECTED; + uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX; + uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL; + T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC; + T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t p_peer_address[6] = {0}; + T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY; + uint8_t tx_power = 127; //Host has no preference. + T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M; + uint8_t secondary_adv_max_skip = 0; + T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M; + uint8_t adv_sid = 0; + bool scan_req_notification_enable = false; + + adv_handle = le_ext_adv_create_adv_handle(); + le_ext_adv_set_adv_param(adv_handle, + adv_event_prop, + primary_adv_interval_min, + primary_adv_interval_max, + primary_adv_channel_map, + own_address_type, + peer_address_type, + p_peer_address, + filter_policy, + tx_power, + primary_adv_phy, + secondary_adv_max_skip, + secondary_adv_phy, + adv_sid, + scan_req_notification_enable); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_set_adv_param(uint8_t adv_handle, uint16_t adv_event_prop, + uint32_t primary_adv_interval_min, uint32_t primary_adv_interval_max, + uint8_t primary_adv_channel_map, T_GAP_LOCAL_ADDR_TYPE own_address_type, + T_GAP_REMOTE_ADDR_TYPE peer_address_type, uint8_t *p_peer_address, + T_GAP_ADV_FILTER_POLICY filter_policy, uint8_t tx_power, + T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy, uint8_t secondary_adv_max_skip, + T_GAP_PHYS_TYPE secondary_adv_phy, uint8_t adv_sid, + bool scan_req_notification_enable); + +/** + * @brief Set GAP advertising data for an advertising set. + * + * NOTE: This function just saves the pointer of the advertising data and will not copy the advertising data. + * So application should the const array or the global array to save the advertising data. + * If application uses a dynamically requested buffer to save the advertising data, do not release it. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] adv_data_len The length of advertising data. + * @param[in] p_adv_data Pointer to advertising data to write. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure, the length of advertising data exceeds + 1024 bytes(Maximum total length of GAP extended advertising data). + * + * Example usage + * \code{.c} + static const uint8_t ext_adv_data[] = + { + // Flags + 0x02, + GAP_ADTYPE_FLAGS, + GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, + // Local name + 0x13, + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'B', 'L', 'E', '_', 'B', 'T', '5', '_', 'P', 'e', 'r', 'i', 'p', 'h', 'e', 'r', 'a', 'l', + // Manufacturer Specific Data + 0xdd, + GAP_ADTYPE_MANUFACTURER_SPECIFIC, + 0x5d, 0x00, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, + 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, + 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd + }; + + void test(void) + { + le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_set_adv_data(uint8_t adv_handle, uint16_t adv_data_len, uint8_t *p_adv_data); + +/** + * @brief Set GAP scan response data for an advertising set. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] scan_data_len The length of scan response data. + * @param[in] p_scan_data Pointer to scan response data to write. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure, the length of advertising data exceeds + 1024 bytes(Maximum total length of GAP extended advertising data). + * + * Example usage + * \code{.c} + static const uint8_t ext_scan_rsp_data[] = + { + // Manufacturer Specific Data + 0xfc, + GAP_ADTYPE_MANUFACTURER_SPECIFIC, + 0x5d, 0x00, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, + 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, + 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, + 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, + 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, 0xd, + 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf + }; + + void test(void) + { + le_ext_adv_set_scan_response_data(adv_handle, sizeof(ext_scan_rsp_data), (uint8_t *)ext_scan_rsp_data); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_set_scan_response_data(uint8_t adv_handle, uint16_t scan_data_len, + uint8_t *p_scan_data); + +/** + * @brief Set GAP random device address for an advertising set. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] random_address Pointer to random address to write. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NOT_FIND Operation failure, the advertising handle is not found. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t rand_addr[6]; + le_gen_rand_addr(GAP_RAND_ADDR_STATIC, rand_addr); + le_ext_adv_set_random(adv_handle, rand_addr); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_set_random(uint8_t adv_handle, uint8_t *random_address); + +/** + * @brief Set extended advertising parameters for an advertising set. + If request success, the result of setting extended advertising parameters will be returned by + @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_START_SETTING. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] update_flags A bit field that indicates extended advertising parameters that shall be set. @ref EXT_ADV_PARAM. + Recommendation: if random address is not used, set update_flags to @ref EXT_ADV_SET_AUTO. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Set parameters request success. + * @retval GAP_CAUSE_NOT_FIND Set parameters request failed, the advertising handle is not found. + * + * Example usage + * \code{.c} + void le_init_ext_adv_params_ext(void) + { + T_LE_EXT_ADV_EXTENDED_ADV_PROPERTY adv_event_prop = + LE_EXT_ADV_EXTENDED_ADV_NON_SCAN_NON_CONN_UNDIRECTED; + uint32_t primary_adv_interval_min = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint32_t primary_adv_interval_max = DEFAULT_ADVERTISING_INTERVAL_MAX; + uint8_t primary_adv_channel_map = GAP_ADVCHAN_ALL; + T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC; + T_GAP_REMOTE_ADDR_TYPE peer_address_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t p_peer_address[6] = {0}; + T_GAP_ADV_FILTER_POLICY filter_policy = GAP_ADV_FILTER_ANY; + uint8_t tx_power = 127; //Host has no preference. + T_GAP_PHYS_PRIM_ADV_TYPE primary_adv_phy = GAP_PHYS_PRIM_ADV_1M; + uint8_t secondary_adv_max_skip = 0; + T_GAP_PHYS_TYPE secondary_adv_phy = GAP_PHYS_2M; + uint8_t adv_sid = 0; + bool scan_req_notification_enable = false; + + adv_handle = le_ext_adv_create_adv_handle(); + le_ext_adv_set_adv_param(adv_handle, + adv_event_prop, + primary_adv_interval_min, + primary_adv_interval_max, + primary_adv_channel_map, + own_address_type, + peer_address_type, + p_peer_address, + filter_policy, + tx_power, + primary_adv_phy, + secondary_adv_max_skip, + secondary_adv_phy, + adv_sid, + scan_req_notification_enable); + + le_ext_adv_set_adv_data(adv_handle, sizeof(ext_adv_data), (uint8_t *)ext_adv_data); + } + + void test(void) + { + le_init_ext_adv_params_ext(); + le_ext_adv_start_setting(adv_handle, EXT_ADV_SET_AUTO); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_START_SETTING: + APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d", + p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag, + p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + + if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS) + { + // Initialize enable parameters + le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + // Enable one advertising set + le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + } + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_start_setting(uint8_t adv_handle, uint8_t update_flags); + +/** + * @brief Set GAP extended advertising enable parameters for an advertising set. + * + * @param[in] adv_handle Identify an advertising set, which is assigned by @ref le_ext_adv_create_adv_handle. + * @param[in] duration If non-zero, indicates the duration that advertising set is enabled. + 0x0000: No advertising duration. + 0x0001-0xFFFF: Advertising duration, in units of 10ms. + * @param[in] max_ext_adv_evt If non-zero, indicates the maximum extended advertising events that shall be + sent prior to disabling the extended advertising set. + 0x00: No maximum number of advertising events. + 0x01-0xFF: Maximum number of extended advertising events to send prior to terminating + the extended advertising. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_NOT_FIND Operartion failure, the advertising handle is not found. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t duration = 0; + uint8_t max_ext_adv_evt = 0; + + le_ext_adv_set_adv_enable_param(adv_handle, duration, max_ext_adv_evt); + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_set_adv_enable_param(uint8_t adv_handle, uint16_t duration, + uint8_t max_ext_adv_evt); + +/** + * @brief Enable extended advertising for one or more advertising sets. + If device changes to advertising state, @ref app_handle_ext_adv_state_evt will be called, and + @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_ENABLE will be called. + * + * @param[in] num_of_sets Number of advertising sets to enable. + * @param[in] adv_handle Pointer to advertising set to enable. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Enable request success. + * @retval GAP_CAUSE_NOT_FIND Enable request failed, the advertising handle is not found. + * + * Example usage + * \code{.c} + void test(void) + { + case GAP_MSG_LE_EXT_ADV_START_SETTING: + APP_PRINT_INFO3("GAP_MSG_LE_EXT_ADV_START_SETTING:cause 0x%x, flag 0x%x, adv_handle %d", + p_data->p_le_ext_adv_start_setting_rsp->cause, p_data->p_le_ext_adv_start_setting_rsp->flag, + p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + + if (p_data->p_le_ext_adv_start_setting_rsp->cause == GAP_CAUSE_SUCCESS) + { + // Initialize enable parameters + le_init_ext_adv_enable_params(p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + // Enable one advertising set + le_ext_adv_enable(1, &p_data->p_le_ext_adv_start_setting_rsp->adv_handle); + } + break; + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_ENABLE: + APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_ENABLE:cause 0x%x", p_data->le_cause.cause); + break; + } + } + + void app_handle_gap_msg(T_IO_MSG *p_gap_msg) + { + T_LE_GAP_MSG gap_msg; + uint8_t conn_id; + memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param)); + + APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype); + switch (p_gap_msg->subtype) + { + case GAP_MSG_LE_EXT_ADV_STATE_CHANGE: + { + app_handle_ext_adv_state_evt(gap_msg.msg_data.gap_ext_adv_state_change.adv_handle, + (T_GAP_EXT_ADV_STATE)gap_msg.msg_data.gap_ext_adv_state_change.new_state, + gap_msg.msg_data.gap_ext_adv_state_change.cause); + } + break; + } + } + + void app_handle_ext_adv_state_evt(uint8_t adv_handle, T_GAP_EXT_ADV_STATE new_state, uint16_t cause) + { + for (int i = 0; i < APP_MAX_ADV_SET; i++) + { + if (ext_adv_state[i].adv_handle == adv_handle) + { + APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d oldState = %d", + ext_adv_state[i].adv_handle, ext_adv_state[i].ext_adv_state); + ext_adv_state[i].ext_adv_state = new_state; + break; + } + } + APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d newState = %d", + adv_handle, new_state); + switch (new_state) + { + // device is idle + case EXT_ADV_STATE_IDLE: + { + APP_PRINT_INFO2("EXT_ADV_STATE_IDLE: adv_handle %d, cause 0x%x", adv_handle, cause); + } + break; + + // device is advertising + case EXT_ADV_STATE_ADVERTISING: + { + APP_PRINT_INFO2("EXT_ADV_STATE_ADVERTISING: adv_handle %d, cause 0x%x", adv_handle, cause); + } + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_enable(uint8_t num_of_sets, uint8_t *adv_handle); + +/** + * @brief Disable extended advertising for one or more advertising sets. + If device changes to idle state, @ref app_handle_ext_adv_state_evt will be called, and + @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_DISABLE will be called. + * + * @param[in] num_of_sets Number of advertising sets to enable. + * @param[in] adv_handle Pointer to advertising set to enable. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Disable request success. + * @retval GAP_CAUSE_NOT_FIND Disable request failed, the advertising handle is not found. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_stopeadv(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t adv_handle[4]; + uint8_t num_of_sets = 1; + T_GAP_CAUSE cause; + adv_handle[0] = p_parse_value->dw_param[0]; + + cause = le_ext_adv_disable(num_of_sets, adv_handle); + return (T_USER_CMD_PARSE_RESULT)cause; + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_DISABLE: + APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_DISABLE:cause 0x%x", p_data->le_cause.cause); + break; + } + } + + void app_handle_gap_msg(T_IO_MSG *p_gap_msg) + { + T_LE_GAP_MSG gap_msg; + uint8_t conn_id; + memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param)); + + APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype); + switch (p_gap_msg->subtype) + { + case GAP_MSG_LE_EXT_ADV_STATE_CHANGE: + { + app_handle_ext_adv_state_evt(gap_msg.msg_data.gap_ext_adv_state_change.adv_handle, + (T_GAP_EXT_ADV_STATE)gap_msg.msg_data.gap_ext_adv_state_change.new_state, + gap_msg.msg_data.gap_ext_adv_state_change.cause); + } + break; + } + } + + void app_handle_ext_adv_state_evt(uint8_t adv_handle, T_GAP_EXT_ADV_STATE new_state, uint16_t cause) + { + for (int i = 0; i < APP_MAX_ADV_SET; i++) + { + if (ext_adv_state[i].adv_handle == adv_handle) + { + APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d oldState = %d", + ext_adv_state[i].adv_handle, ext_adv_state[i].ext_adv_state); + ext_adv_state[i].ext_adv_state = new_state; + break; + } + } + APP_PRINT_INFO2("app_handle_ext_adv_state_evt: adv_handle = %d newState = %d", + adv_handle, new_state); + switch (new_state) + { + // device is idle + case EXT_ADV_STATE_IDLE: + { + APP_PRINT_INFO2("EXT_ADV_STATE_IDLE: adv_handle %d, cause 0x%x", adv_handle, cause); + } + break; + + // device is advertising + case EXT_ADV_STATE_ADVERTISING: + { + APP_PRINT_INFO2("EXT_ADV_STATE_ADVERTISING: adv_handle %d, cause 0x%x", adv_handle, cause); + } + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_disable(uint8_t num_of_sets, uint8_t *adv_handle); + +/** + * @brief Remove all existing advertising sets. + The result of removing all existing advertising sets will be returned by + @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_CLEAR_SET. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Clear request success. + * + * Example usage + * \code{.c} + void test(void) + { + le_ext_adv_clear_set(); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_CLEAR_SET: + APP_PRINT_INFO1("GAP_MSG_LE_EXT_ADV_CLEAR_SET:cause 0x%x", + p_data->p_le_ext_adv_clear_set_rsp->cause); + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_clear_set(void); + +/** + * @brief Remove an advertising set. + If request success, the result of removing an advertising set will be returned by + @ref app_gap_callback with cb_type @ref GAP_MSG_LE_EXT_ADV_REMOVE_SET. + * + * @param[in] adv_handle Identify an advertising set. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Remove request success. + * @retval GAP_CAUSE_NOT_FIND Remove request failed, the advertising handle is not found. + * @retval GAP_CAUSE_INVALID_STATE Remove request failed, invalid state. + * @retval GAP_CAUSE_ALREADY_IN_REQ Remove request failed, operation is already in progress. + * + * Example usage + * \code{.c} + void test(void) + { + le_ext_adv_remove_set(adv_handle); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_REMOVE_SET: + APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REMOVE_SET:cause 0x%x, adv_handle %d", + p_data->p_le_ext_adv_remove_set_rsp->cause, p_data->p_le_ext_adv_remove_set_rsp->adv_handle); + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_adv_remove_set(uint8_t adv_handle); + +#if F_BT_LE_GAP_MSG_INFO_WAY +void le_ext_adv_gap_msg_info_way(bool use_msg); +#endif + +/** End of GAP_LE_EXTENDED_ADV_Exported_Functions + * @} + */ + +/** End of GAP_LE_EXTENDED_ADV + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_EXT_ADV_H */ diff --git a/inc/bluetooth/gap/gap_ext_scan.h b/inc/bluetooth/gap/gap_ext_scan.h new file mode 100644 index 0000000..bed535e --- /dev/null +++ b/inc/bluetooth/gap/gap_ext_scan.h @@ -0,0 +1,447 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_ext_scan.h +* @brief Header file for Gap ext scan +* @details +* @author jane +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/* Define to prevent recursive inclusion **/ +#ifndef GAP_EXT_SCAN_H +#define GAP_EXT_SCAN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "upperstack_config.h" +#include "gap_le.h" +#if F_BT_LE_5_0_AE_SCAN_SUPPORT + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_EXTENDED_SCAN GAP LE Extended Scan Module + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Macros GAP LE Extended Scan Exported Macros + * @brief + * @{ + */ + +#define GAP_EXT_SCAN_MAX_PHYS_NUM 2 /**< Maximum number of scan PHYs. */ + +/** @defgroup EXT_SCAN_PHY Extended Scan PHY + * @brief Indicate the PHY(s) on which the advertising packets should be received + on the primary advertising channel. LE 1M PHY and LE Coded PHY are primary + advertising channel. + * @{ + */ +#define GAP_EXT_SCAN_PHYS_1M_BIT 0x01 /**< Scan advertisements on the LE 1M PHY. */ +#define GAP_EXT_SCAN_PHYS_CODED_BIT 0x04 /**< Scan advertisements on the LE Coded PHY. */ +#define GAP_EXT_SCAN_PHYS_ALL 0x05 /**< Scan advertisements on the LE 1M PHY and LE Coded PHY. */ +/** End of EXT_SCAN_PHY + * @} + */ + +/** @defgroup EXT_ADV_REPORT Extended Advertising Report flag + * @brief Indicate properties of advertising event in extended advertising report. + When a scan response is received, bits 0-2 and 4 of event type shall + indicate the properties of the original advertising event. + * @{ + */ +#define GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV 0x01 /**< Connectable advertising. */ +#define GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV 0x02 /**< Scannable advertising. */ +#define GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV 0x04 /**< Directed advertising. */ +#define GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE 0x08 /**< Scan response. */ +#define GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV 0x10 /**< Legacy advertising PDUs used. */ +/** End of EXT_ADV_REPORT + * @} + */ + +/** End of GAP_LE_EXTENDED_SCAN_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Types GAP LE Extended Scan Exported Types + * @brief + * @{ + */ +/** @brief Scan PHY type used in @ref le_ext_scan_set_phy_param. */ +typedef enum +{ + LE_SCAN_PHY_LE_1M, /**< Set @ref T_GAP_LE_EXT_SCAN_PARAM for LE 1M PHY. */ + LE_SCAN_PHY_LE_CODED, /**< Set @ref T_GAP_LE_EXT_SCAN_PARAM for LE Coded PHY. */ +} T_LE_EXT_SCAN_PHY_TYPE; + +/** @brief Extended scan parameter. */ +typedef struct +{ + T_GAP_SCAN_MODE + scan_type; /**< Scan type. Write only. Default is GAP_SCAN_MODE_ACTIVE, @ref T_GAP_SCAN_MODE. */ + uint16_t + scan_interval; /**< Scan Interval. Write only. In units of 0.625ms, range: 0x0004 to 0xFFFF. Default is 0x40. */ + uint16_t + scan_window; /**< Scan Window. Write only. In units of 0.625ms, range: 0x0004 to 0xFFFF. Default is 0x20. */ +} T_GAP_LE_EXT_SCAN_PARAM; + +/** @brief Extended scan parameter type. */ +typedef enum +{ + GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE = 0x340, /**< The type of address being used in the scan request packets. Read/Write. Size is uint8_t. Default is GAP_LOCAL_ADDR_LE_PUBLIC (@ref T_GAP_LOCAL_ADDR_TYPE). */ + GAP_PARAM_EXT_SCAN_FILTER_POLICY = 0x341, /**< Scanning filter policy. Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_ANY (@ref T_GAP_SCAN_FILTER_POLICY). */ + GAP_PARAM_EXT_SCAN_PHYS = 0x342, /**< Scanning PHYs. window. Read/Write. Size is uint8_t. Default is GAP_EXT_SCAN_PHYS_1M_BIT (@ref EXT_SCAN_PHY). */ + GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES = 0x343, /**< Scan Filter Duplicates. Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_DUPLICATE_ENABLE (@ref T_GAP_SCAN_FILTER_DUPLICATE). */ + GAP_PARAM_EXT_SCAN_DURATION = 0x344, /**< Scan duration. Read/Write. Size is uint16_t. In units of 10ms, range: 0x0000~0xFFFF. Default is zero. */ + GAP_PARAM_EXT_SCAN_PERIOD = 0x345, /**< Scan period. Read/Write. Size is uint16_t. In units of 1.28sec, range: 0x0000~0xFFFF. Default is zero. */ +} T_LE_EXT_SCAN_PARAM_TYPE; + +/** End of GAP_LE_EXTENDED_SCAN_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_LE_EXTENDED_SCAN_Exported_Functions GAP LE Extended Scan Exported Functions + * @brief + * @{ + */ +#if F_BT_LE_GAP_SCAN_FILTER_SUPPORT +/** + * @brief Set extended scan information filter. + * + * NOTE: This function can be called before @ref gap_start_bt_stack is invoked. + * + * @param[in] enable Whether to open the extend scan info filter function. + * @param[in] report_type A logical OR of the bit values that provide the list of report type to receive. + * @param[in] legacy_adv Whether to receive the legacy scan info. + * @return bool. + * @retval TRUE Operation success. + * @retval FALSE Operation Failure. + * + * Example usage + * \code{.c} + void test(void) + { + le_ext_scan_report_filter(true, + GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV|GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV, false); + } + * \endcode + */ +bool le_ext_scan_report_filter(bool enable, uint16_t report_type, bool legacy_adv); +#endif + +/** + * @brief Set a GAP extended scan parameter. + * + * NOTE: You can call this function with a extended scan parameter type and it will set the + * extended scan parameter. Extended scan parameters are defined in @ref T_LE_EXT_SCAN_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must + * point to a data with type "uint16". + * Combination of Duration parameter (@ref GAP_PARAM_EXT_SCAN_DURATION) and + * Period parameter(@ref GAP_PARAM_EXT_SCAN_PERIOD) determines scan mode, + * please refer to below code about scan_mode. + * + * @param[in] param Extended scan parameter type: @ref T_LE_EXT_SCAN_PARAM_TYPE + * @param[in] len Length of data to write. + * @param[in] p_value Pointer to data to write. This is dependent on the parameter type and will + be cast to the appropriate data type (For example: if data type param is uint16, + p_value will be cast to pointer of uint16_t). + * + * @return Set result + * @retval GAP_CAUSE_SUCCESS Set parameter success. + * @retval other Set parameter failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + T_GAP_LOCAL_ADDR_TYPE own_address_type = GAP_LOCAL_ADDR_LE_PUBLIC; + T_GAP_SCAN_FILTER_POLICY ext_scan_filter_policy = GAP_SCAN_FILTER_ANY; + T_GAP_SCAN_FILTER_DUPLICATE ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE; + uint16_t ext_scan_duration; + uint16_t ext_scan_period; + uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT | GAP_EXT_SCAN_PHYS_CODED_BIT; + T_EXT_SCAN_MODE scan_mode = (T_EXT_SCAN_MODE)p_parse_value->dw_param[0]; + + link_mgr_clear_device_list(); + if (scan_mode == SCAN_UNTIL_DISABLED) + { + // If Duration paramter is zero, continue scanning until scanning is disabled. + ext_scan_duration = 0; + ext_scan_period = 0; + } + else if (scan_mode == PERIOD_SCAN_UNTIL_DISABLED) + { + // If Duration and Period parameters are non-zero, scan for the duration within a scan period, + // and scan periods continue until scanning is disabled. Duration shall be less than Period. + ext_scan_duration = 500; + ext_scan_period = 8; + ext_scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLED_RESET_FOR_EACH_PERIOD; + } + else if (scan_mode == SCAN_UNTIL_DURATION_EXPIRED) + { + // If Duration parameter is non-zero and Period parameter is zero, continue scanning until duration has expired. + ext_scan_duration = 500; + ext_scan_period = 0; + } + if (p_parse_value->param_count > 1) + { + scan_phys = p_parse_value->dw_param[1]; + } + + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_LOCAL_ADDR_TYPE, sizeof(own_address_type), &own_address_type); + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys), &scan_phys); + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_DURATION, sizeof(ext_scan_duration), &ext_scan_duration); + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PERIOD, sizeof(ext_scan_period),&ext_scan_period); + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_POLICY, sizeof(ext_scan_filter_policy), &ext_scan_filter_policy); + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_FILTER_DUPLICATES, sizeof(ext_scan_filter_duplicate), &ext_scan_filter_duplicate); + + cause = le_ext_scan_start(); + return (T_USER_CMD_PARSE_RESULT)cause; + } + * \endcode + */ +T_GAP_CAUSE le_ext_scan_set_param(T_LE_EXT_SCAN_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a extended scan parameter. + * + * NOTE: You can call this function with a extended scan parameter type and it will get a + * extended scan parameter. Extended scan parameters are defined in @ref T_LE_EXT_SCAN_PARAM_TYPE. + * + * @param[in] param Extended scan parameter type: @ref T_LE_EXT_SCAN_PARAM_TYPE. + * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Get result + * @retval GAP_CAUSE_SUCCESS Get parameter success. + * @retval GAP_CAUSE_INVALID_PARAM Get parameter failed, invalid parameter. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t scan_duration; + le_ext_scan_get_param(GAP_PARAM_EXT_SCAN_DURATION, &scan_duration); + } + * \endcode + */ +T_GAP_CAUSE le_ext_scan_get_param(T_LE_EXT_SCAN_PARAM_TYPE param, void *p_value); + +/** + * @brief Set a extended scan phy parameter including scan type, scan interval and scan window + for scan advertisements on LE 1M PHY or/and LE Coded PHY. + * + * @param[in] type Scan PHY type: @ref T_LE_EXT_SCAN_PHY_TYPE + * @param[in] p_param Pointer to data to write, @ref T_GAP_LE_EXT_SCAN_PARAM. + scan_type: Passive scanning or active scanning, @ref T_GAP_SCAN_MODE. + scan_interval: The frequency of scan, in units of 0.625ms, range: 0x0004 to 0xFFFF. + scan_window: The length of scan, in units of 0.625ms, range: 0x0004 to 0xFFFF. + * + * @return void + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_escan(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t scan_phys = GAP_EXT_SCAN_PHYS_1M_BIT | GAP_EXT_SCAN_PHYS_CODED_BIT; + T_GAP_LE_EXT_SCAN_PARAM extended_scan_param[GAP_EXT_SCAN_MAX_PHYS_NUM]; + extended_scan_param[0].scan_type = GAP_SCAN_MODE_ACTIVE; + extended_scan_param[0].scan_interval = 400; + extended_scan_param[0].scan_window = 200; + extended_scan_param[1].scan_type = GAP_SCAN_MODE_ACTIVE; + extended_scan_param[1].scan_interval = 440; + extended_scan_param[1].scan_window = 220; + + le_ext_scan_set_param(GAP_PARAM_EXT_SCAN_PHYS, sizeof(scan_phys), &scan_phys); + + le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_1M, &extended_scan_param[0]); + le_ext_scan_set_phy_param(LE_SCAN_PHY_LE_CODED, &extended_scan_param[1]); + + return (RESULT_SUCESS); + } + * \endcode + */ +void le_ext_scan_set_phy_param(T_LE_EXT_SCAN_PHY_TYPE type, T_GAP_LE_EXT_SCAN_PARAM *p_param); + +/** + * @brief Start a device discovery extended scan. + If device changes to scanning state, @ref app_handle_dev_state_evt will be called. And the + advertising data or scan response data will be returned by @ref app_gap_callback with + cb_type @ref GAP_MSG_LE_EXT_ADV_REPORT_INFO. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Start request success. + * @retval GAP_CAUSE_INVALID_STATE: Start request failed, invalid device state. + * + * Example usage + * \code{.c} + void test() + { + le_ext_scan_start(); + } + + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x", + new_state.gap_init_state, + new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause); + + if (gap_dev_state.gap_scan_state != new_state.gap_scan_state) + { + if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE) + { + APP_PRINT_INFO0("GAP scan stop"); + data_uart_print("GAP scan stop\r\n"); + } + else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING) + { + APP_PRINT_INFO0("GAP scan start"); + data_uart_print("GAP scan start\r\n"); + } + } + + gap_dev_state = new_state; + } + + //Received advertising or scan response data will be handled in app_gap_callback + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + + switch (cb_type) + { + case GAP_MSG_LE_EXT_ADV_REPORT_INFO: + APP_PRINT_INFO6("GAP_MSG_LE_EXT_ADV_REPORT_INFO:connectable %d, scannable %d, direct %d, scan response %d, legacy %d, data status 0x%x", + p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_CONNECTABLE_ADV, + p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCANNABLE_ADV, + p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_DIRECTED_ADV, + p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_SCAN_RESPONSE, + p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV, + p_data->p_le_ext_adv_report_info->data_status); + APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:event_type 0x%x, bd_addr %s, addr_type %d, rssi %d, data_len %d", + p_data->p_le_ext_adv_report_info->event_type, + TRACE_BDADDR(p_data->p_le_ext_adv_report_info->bd_addr), + p_data->p_le_ext_adv_report_info->addr_type, + p_data->p_le_ext_adv_report_info->rssi, + p_data->p_le_ext_adv_report_info->data_len); + APP_PRINT_INFO5("GAP_MSG_LE_EXT_ADV_REPORT_INFO:primary_phy %d, secondary_phy %d, adv_sid %d, tx_power %d, peri_adv_interval %d", + p_data->p_le_ext_adv_report_info->primary_phy, + p_data->p_le_ext_adv_report_info->secondary_phy, + p_data->p_le_ext_adv_report_info->adv_sid, + p_data->p_le_ext_adv_report_info->tx_power, + p_data->p_le_ext_adv_report_info->peri_adv_interval); + APP_PRINT_INFO2("GAP_MSG_LE_EXT_ADV_REPORT_INFO:direct_addr_type 0x%x, direct_addr %s", + p_data->p_le_ext_adv_report_info->direct_addr_type, + TRACE_BDADDR(p_data->p_le_ext_adv_report_info->direct_addr)); + + link_mgr_add_device(p_data->p_le_ext_adv_report_info->bd_addr, + p_data->p_le_ext_adv_report_info->addr_type); + + #if APP_RECOMBINE_ADV_DATA + if (!(p_data->p_le_ext_adv_report_info->event_type & GAP_EXT_ADV_REPORT_BIT_USE_LEGACY_ADV)) + { + app_handle_ext_adv_report(p_data->p_le_ext_adv_report_info->event_type, + p_data->p_le_ext_adv_report_info->data_status, p_data->p_le_ext_adv_report_info->bd_addr, + p_data->p_le_ext_adv_report_info->data_len, p_data->p_le_ext_adv_report_info->p_data); + } + #endif + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_ext_scan_start(void); + +/** + * @brief Stop a device discovery extended scan. + If device changes to idle state, @ref app_handle_dev_state_evt will be called. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Stop request success. + * @retval GAP_CAUSE_INVALID_STATE: Stop request failed. Invalid state, not in scan state. + * + * Example usage + * \code{.c} + void test() + { + le_ext_scan_stop(); + } + + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x", + new_state.gap_init_state, + new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause); + + if (gap_dev_state.gap_scan_state != new_state.gap_scan_state) + { + if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE) + { + APP_PRINT_INFO0("GAP scan stop"); + data_uart_print("GAP scan stop\r\n"); + } + else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING) + { + APP_PRINT_INFO0("GAP scan start"); + data_uart_print("GAP scan start\r\n"); + } + } + + gap_dev_state = new_state; + } + * \endcode + */ +T_GAP_CAUSE le_ext_scan_stop(void); + +#if F_BT_LE_GAP_MSG_INFO_WAY +void le_ext_scan_gap_msg_info_way(bool use_msg); +#endif +/** End of GAP_LE_EXTENDED_SCAN_Exported_Functions + * @} + */ + +/** End of GAP_LE_EXTENDED_SCAN + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* GAP_EXT_SCAN_H */ diff --git a/inc/bluetooth/gap/gap_fix_chann_conn.h b/inc/bluetooth/gap/gap_fix_chann_conn.h new file mode 100644 index 0000000..7b92df7 --- /dev/null +++ b/inc/bluetooth/gap/gap_fix_chann_conn.h @@ -0,0 +1,28 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file gap_fix_chann_conn.h +* @brief header file of LE Fixed Channel Connection message handle. +* @details none. +* @author Tifnan +* @date 2016-03-16 +* @version v0.1 +********************************************************************************************************* +*/ + +#ifndef _LE_FIX_CHANN_CONN_H_ +#define _LE_FIX_CHANN_CONN_H_ + +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap.h" + +#if F_BT_LE_FIX_CHANN_SUPPORT +T_GAP_CAUSE le_fixed_chann_reg(uint16_t cid); + +T_GAP_CAUSE le_fixed_chann_data_send(uint8_t conn_id, uint16_t cid, uint8_t *p_data, + uint16_t data_len); +#endif + +#endif /* _LE_FIX_CHANN_CONN_H_ */ diff --git a/inc/bluetooth/gap/gap_le.h b/inc/bluetooth/gap/gap_le.h new file mode 100644 index 0000000..0db0c3e --- /dev/null +++ b/inc/bluetooth/gap/gap_le.h @@ -0,0 +1,527 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_le.h + * @brief This file contains all the constants and functions prototypes for GAP protocol. + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_LE_H +#define GAP_LE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap.h" +#include "gap_callback_le.h" + +/** @addtogroup GAP_LE_COMMON GAP LE Common Module + * @brief GAP LE common module + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_Exported_Types GAP LE Exported Types + * @brief + * @{ + */ +/** @brief GAP LE Parameter Types List.*/ +typedef enum +{ + GAP_PARAM_DEV_STATE = 0x220, //!< Device's current GAP device state. Read/Write. Size is sizeof(TGapDevState). + GAP_PARAM_APPEARANCE = 0x221, //!< Local Device's Appearance. Read/Write. size is uint16. Appearance value please refer to GAP Appearance Values.(@ref GAP_LE_APPEARANCE_VALUES) + GAP_PARAM_DEVICE_NAME = 0x222, //!< Local Device's Name. Write Only. Name string length is GAP_DEVICE_NAME_LEN. +#if F_BT_LE_GAP_PERIPHERAL_SUPPORT + GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ = 0x223, //!< Slave initiate the GATT exchange MTU procedure. Write Only. +#endif + GAP_PARAM_RANDOM_ADDR = 0x224, //!< Random address. Write Only. + GAP_PARAM_LATEST_CONN_BD_ADDR = 0x226, //!< Latest connected bluetooth devive address. Read Only. + GAP_PARAM_LATEST_CONN_BD_ADDR_TYPE = 0x227, //!< Latest connected bluetooth devive address type. Read Only. + GAP_PARAM_HANDLE_CREATE_CONN_IND = 0x228, //!< App handle the create connection indication message. +#if F_BT_LE_5_0_SET_PHYS_SUPPORT + GAP_PARAM_DEFAULT_PHYS_PREFER = 0x229, //!< Preferred values for the transmitter PHY and receiver PHY to be used for all subsequent connections over the LE transport. + GAP_PARAM_DEFAULT_TX_PHYS_PREFER = 0x22a, //!< The transmitter PHYs that the Host prefers the Controller to use. + GAP_PARAM_DEFAULT_RX_PHYS_PREFER = 0x22b, //!< The receiver PHYs that the Host prefers the Controller to use. +#endif +#if F_BT_LE_5_0_AE_ADV_SUPPORT + GAP_PARAM_USE_EXTENDED_ADV = 0x22c, //!< Use LE Advertising Extensions. +#endif + GAP_PARAM_SET_REM_MIN_SCA = 0x22d, +#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT + GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_OCTETS = 0x22e, + GAP_PARAM_DEFAULT_DATA_LEN_MAX_TX_TIME = 0x22f, +#endif + GAP_PARAM_LOCAL_FEATURES = 0x230, //!< Local supported features. + GAP_PARAM_DS_POOL_ID = 0x231, //!< Downstream PoolID. Read only. size is uint16. + GAP_PARAM_DS_DATA_OFFSET = 0x232, //!< Downstream pool buffer data offset. Read only. size is uint16. + GAP_PARAM_LE_REMAIN_CREDITS = 0x233, //!< Remain credits avaiable for TX. Read only. size is uint16. + GAP_PARAM_MAX_WL_SIZE = 0x234, //!< Max white list size. Read only. size is uint16. +#if F_BT_LE_5_0_READ_POWER_SUPPORT + GAP_PARAM_MIN_TX_POWER = 0x235, //!< The minimum transmit powers supported by the Controller. + GAP_PARAM_MAX_TX_POWER = 0x236, //!< The maximum transmit powers supported by the Controller. +#endif +#if F_BT_LE_5_2_ISOC_CIS_SUPPORT + GAP_PARAM_ISOCH_HOST_SUPPORT = 0x237, //!< Use CIS of LE Isochronous Channels. +#endif +} T_GAP_LE_PARAM_TYPE; + +/** + * @brief Callback for gap le to notify app + * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types. + * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA. + * @retval result @ref T_APP_RESULT + */ +typedef T_APP_RESULT(*P_FUN_LE_APP_CB)(uint8_t cb_type, void *p_cb_data); +/** End of GAP_LE_Exported_Types + * @} + */ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @defgroup GAP_LE_COMMON_Exported_Functions GAP LE Common Exported Functions + * + * @{ + */ + +/** + * @brief Initialize parameters of GAP. + * @param[in] link_num Initialize link number. + * @retval true Success. + * @retval false Failed because of invalid parameter. + * + * Example usage + * \code{.c} + int main(void) + { + board_init(); + driver_init(); + le_gap_init(1); + app_le_gap_init(); + app_le_profile_init(); + pwr_mgr_init(); + task_init(); + os_sched_start(); + + return 0; + } + * \endcode + */ +bool le_gap_init(uint8_t link_num); + +/** + * @brief Set gap message inform way. + * + * Default value is true. + * 1. When use_msg is true, gap will send the gap message to io_queue registered by gap_start_bt_stack. + * Message type is @ref GAP_MSG_TYPE. + * 2. When use_msg is false, gap will send the gap message using callback function registered by le_register_app_cb. + * Message type is @ref GAP_MSG_LE_GAP_STATE_MSG. + * + * @param[in] use_msg Whether to use message. + * @retval void + * + * Example usage + * \code{.c} + int test(void) + { + le_gap_msg_info_way(false); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: msgType = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_GAP_STATE_MSG: + APP_PRINT_INFO0("GAP_MSG_LE_GAP_STATE_MSG"); + app_handle_gap_msg((T_IO_MSG *)cb_data->p_gap_state_msg); + break; + ... + } + } + + * \endcode + */ +void le_gap_msg_info_way(bool use_msg); + +/** + * @brief Get max supported le link count. + * @retval max_link_num Max supported le link count. + * + * Example usage + * \code{.c} + void test(void) + { + link_num = le_get_max_link_num(); + le_gap_init(link_num); + } + * \endcode + */ +uint8_t le_get_max_link_num(void); + +/** + * @brief Register app callback from gap le. + * @param[in] app_callback callback + * @return void + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + le_register_app_cb(app_gap_callback); + client_init(1); + simple_ble_client_id = simp_ble_add_client(app_client_callback); + client_register_general_client_cb(app_client_callback); + } + * \endcode + */ +void le_register_app_cb(P_FUN_LE_APP_CB app_callback); + +/** + * @brief Set a GAP Common parameter. + * + * NOTE: You can call this function with a GAP Common Parameter ID and it will set the + * GAP Parameter. GAP Peripheral Parameters are defined in (gap.h). + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param Profile parameter ID: @ref T_GAP_LE_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter ID and WILL be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * @return Set result + * @retval GAP_CAUSE_SUCCESS Set parameter success. + * @retval other Set parameter failed. + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ... + //device name and device appearance + uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BLE_PERIP"; + uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN; + + //Set device name and device appearance + le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name); + le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance); + ... + } + * \endcode + */ +T_GAP_CAUSE le_set_gap_param(T_GAP_LE_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a GAP Common parameter. + * + * NOTE: You can call this function with a GAP Common Parameter ID and it will get a + * GAP Common Parameter. GAP Common Parameters are defined in (gap.h). Also, the + * "p_value" field must point to a "uint16". + * + * @param[in] param Profile parameter ID: @ref T_GAP_LE_PARAM_TYPE + * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on + * the parameter ID and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Get result + * @retval GAP_CAUSE_SUCCESS Get parameter success. + * @retval other Get parameter failed. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t addr_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t addr[GAP_BD_ADDR_LEN] = {0}; + + //get connected device address and address type + le_get_gap_param(GAP_PARAM_LATEST_CONN_BD_ADDR_TYPE, &addr_type); + le_get_gap_param(GAP_PARAM_LATEST_CONN_BD_ADDR, &addr); + } + * \endcode + */ +T_GAP_CAUSE le_get_gap_param(T_GAP_LE_PARAM_TYPE param, void *p_value); + +/** + * @brief Modify local white list. + * NOTE: You can call this function to add, remove or clear whist list. + * This function can be called after @ref gap_start_bt_stack is invoked. + * + * @param[in] operation Add, remove or clear white list, @ref T_GAP_WHITE_LIST_OP. + * @param[in] bd_addr Bluetooth Device Address. + * @param[in] bd_type Bluetooth Device Address type. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_WHITE_LIST_OP operation = GAP_WHITE_LIST_OP_ADD; + uint8_t *bd_addr = {0}; + T_GAP_REMOTE_ADDR_TYPE bd_type = GAP_REMOTE_ADDR_LE_PUBLIC; + le_modify_white_list(operation, bd_addr, bd_type); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_MODIFY_WHITE_LIST: + APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation 0x%x, cause 0x%x", + cb_data.p_le_modify_white_list_rsp->operation, + cb_data.p_le_modify_white_list_rsp->cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_modify_white_list(T_GAP_WHITE_LIST_OP operation, uint8_t *bd_addr, + T_GAP_REMOTE_ADDR_TYPE bd_type); + +/** + * @brief Generate local random address. + * @param[in] rand_addr_type Bluetooth Device Random Address type, @ref T_GAP_RAND_ADDR_TYPE. + * @param[in,out] random_bd pointer to Bluetooth Device Address. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_RAND_ADDR_TYPE rand_addr_type = GAP_RAND_ADDR_RESOLVABLE; + uint8_t random_bd[BD_ADDR_SIZE] = {0}; + le_gen_rand_addr(rand_addr_type, random_bd); + } + * + * \endcode + */ +T_GAP_CAUSE le_gen_rand_addr(T_GAP_RAND_ADDR_TYPE rand_addr_type, uint8_t *random_bd); + +/** + * @brief Set local random address. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @param[in] random_bd Bluetooth Device Address. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + uint8_t random_bd[BD_ADDR_SIZE] = {0}; + le_set_rand_addr(random_bd); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_SET_RAND_ADDR: + APP_PRINT_INFO1("GAP_MSG_LE_SET_RAND_ADDR: cause 0x%x", + cb_data.p_le_set_rand_addr_rsp->cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_set_rand_addr(uint8_t *random_bd); + +/** + * @brief Configure local identity address. + * + * NOTE: This function can be called before @ref gap_start_bt_stack is invoked. + * + * @param[in] addr Bluetooth Device Address. + * @param[in] type Bluetooth Device Address type. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_IDENT_ADDR_TYPE type = GAP_IDENT_ADDR_PUBLIC; + uint8_t addr[BD_ADDR_SIZE] = {0}; + le_cfg_local_identity_address(addr, type); + } + * \endcode + */ +T_GAP_CAUSE le_cfg_local_identity_address(uint8_t *addr, T_GAP_IDENT_ADDR_TYPE type); + +/** +* @brief Set the Host Channel Classification for master role. +* +* NOTE: This function can be called after @ref gap_start_bt_stack is invoked. +* +* @param[in] p_channel_map Channel bit map, the most 3 significant bits are reserved. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void test() + { + uint8_t channel_map = 0; + le_set_host_chann_classif(channel_map); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_SET_HOST_CHANN_CLASSIF: + APP_PRINT_INFO1("GAP_MSG_LE_SET_HOST_CHANN_CLASSIF: cause 0x%x", + cb_data.p_le_set_host_chann_classif_rsp->cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_set_host_chann_classif(uint8_t *p_channel_map); + +#if F_BT_LE_4_2_DATA_LEN_EXT_SUPPORT +/** +* @brief Specify suggested values for maximum transmission number of payload + octets and maximum packet transmission time for new connections. +* +* NOTE: This function can be called after @ref gap_start_bt_stack is invoked. +* +* @param[in] tx_octets maximum transmission number of payload octets, range: 0x001B-0x00FB +* @param[in] tx_time maximum packet transmission time, range: 0x0148-0x4290 +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void test() + { + uint16_t tx_octets = 0x00FB; + uint16_t tx_time = 0x0848; + le_write_default_data_len(tx_octets, tx_time); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_WRITE_DEFAULT_DATA_LEN: + APP_PRINT_INFO1("GAP_MSG_LE_WRITE_DEFAULT_DATA_LEN: cause 0x%x", + cb_data->le_cause.cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_write_default_data_len(uint16_t tx_octets, uint16_t tx_time); +#endif + +/** +* @brief Set Minimum Remote SCA. +* +* NOTE: This function can be called after @ref gap_start_bt_stack is invoked. +* +* Set Min_sca to compare with M_sca sent by master (carried in CONNECT_REQ pdu). +* The finally used master sca is set to MIN(Min_sca, M_sca). +* The default Min_sca is 7. +* The setting is used by all links in slave role, can set when boot up or link exist, and will reset to default value when HCI_RESET. +* +* @param[in] index Minimum Remote SCA Index. +* +* @retval GAP_CAUSE_SUCCESS: Operation success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void test() + { + T_GAP_CAUSE cause; + T_GAP_SCA_FIELD_ENCODING index = GAP_SCA_76_TO_100_PPM; + cause = le_vendor_set_rem_min_sca(index); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_VENDOR_SET_MIN_REM_SCA: + APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_SET_MIN_REM_SCA: cause 0x%x", + p_data->le_cause.cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_vendor_set_rem_min_sca(T_GAP_SCA_FIELD_ENCODING min_sca); + +/** @} */ /* End of group GAP_LE_COMMON_Exported_Functions */ +/** @} */ /* End of group GAP_LE_COMMON */ + + +/*------------------------------------------------------------------- +-------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_LE_H */ + + + + diff --git a/inc/bluetooth/gap/gap_le_rf.h b/inc/bluetooth/gap/gap_le_rf.h new file mode 100644 index 0000000..4467c56 --- /dev/null +++ b/inc/bluetooth/gap/gap_le_rf.h @@ -0,0 +1,656 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_le_rf.h +* @brief Head file for GAP RF +* @details +* @author +* @date 2020-06-18 +* @version v0.8 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_LE_RF_H +#define GAP_LE_RF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_RF GAP LE RF Module + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_RF_Exported_Macros GAP LE Rf Exported Macros + * @{ + */ + +/** @defgroup GAP_LE_RF_MSG_Types GAP LE RF Msg Types + * @{ + */ +#define GAP_MSG_LE_RF_INFO 0xD1 +/** End of GAP_LE_RF_MSG_Types + * @} + */ + +/** @defgroup GAP_LE_RF_MSG_Opcodes GAP LE RF Msg Opcodes + * @{ + */ +#define GAP_LE_RF_READ_RF_PATH_COMPENSATION 0x0000 //!Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + cause = le_rf_read_rf_path_compensation(); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_0_RF_PATH_SUPPORT + case GAP_LE_RF_READ_RF_PATH_COMPENSATION: + APP_PRINT_INFO3("GAP_LE_RF_READ_RF_PATH_COMPENSATION:cause 0x%x, rf tx path comp value %d, rf rx path comp value %d", + p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->cause, + p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->rf_tx_path_comp_value, + p_le_rf_cb->data.p_le_rf_read_rf_path_compensation_rsp->rf_rx_path_comp_value); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_read_rf_path_compensation(void); + +/** +* @brief Indicate the RF path gain or loss between the RF transceiver and the antenna contributed +* by intermediate components. +* +* @param[in] rf_tx_path_comp_value RF Tx Path Compensation + Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500) + Units: 0.1 dB +* @param[in] rf_rx_path_comp_value RF Rx Path Compensation + Range: -128.0 dB (0xFB00) to 128.0 dB (0x0500) + Units: 0.1 dB +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + + cause = le_rf_write_rf_path_compensation(rf_tx_path_comp_value, + rf_rx_path_comp_value); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_0_RF_PATH_SUPPORT + case GAP_LE_RF_WRITE_RF_PATH_COMPENSATION: + APP_PRINT_INFO1("GAP_LE_RF_WRITE_RF_PATH_COMPENSATION:cause 0x%x", + p_le_rf_cb->data.le_rf_cause.cause); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_write_rf_path_compensation(int16_t rf_tx_path_comp_value, + int16_t rf_rx_path_comp_value); +#endif + +#if F_BT_LE_5_2_POWER_CONTROL_SUPPORT +/** +* @brief Read the current and maximum transmit power levels of the local Controller on the ACL connection and the PHY. +* Read result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_RF_INFO with +* opcode @ref GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL. +* +* @param[in] conn_id Connection ID +* @param[in] phy phy physical: @ref T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE. +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. +* @retval GAP_CAUSE_NON_CONN: Set request sent fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + uint8_t conn_id; + + cause = le_rf_enhanced_read_transmit_power_level(conn_id, phy); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT + case GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL: + APP_PRINT_INFO5("GAP_LE_RF_ENHANCED_READ_TRANSMIT_POWER_LEVEL:conn id %d, cause 0x%x, phy %d, cur trans power level %d, max trans power level %d", + p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->conn_id, + p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->cause, + p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->phy, + p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->cur_tx_power_level, + p_le_rf_cb->data.p_le_rf_enhanced_read_transmit_power_level_rsp->max_tx_power_level); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_enhanced_read_transmit_power_level(uint8_t conn_id, + T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy); + +/** +* @brief Read the transmit power level used by the remote Controller on the ACL connection and the PHY. +* Read result will be returned by @ref app_gap_callback with cb_type @ref GAP_MSG_LE_RF_INFO with +* opcode @ref GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO. +* +* @param[in] conn_id Connection ID +* @param[in] phy phy physical: @ref T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE. +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. +* @retval GAP_CAUSE_NON_CONN: Set request sent fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + uint8_t conn_id; + + cause = le_rf_read_remote_transmit_power_level(conn_id, phy); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT + case GAP_LE_RF_READ_REMOTE_TRANSMIT_POWER_LEVEL: + APP_PRINT_INFO2("GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE:conn id %d, cause 0x%x", + p_le_rf_cb->data.p_le_rf_read_remote_transmit_power_level_rsp->conn_id, + p_le_rf_cb->data.p_le_rf_read_remote_transmit_power_level_rsp->cause); + break; + + case GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO: + APP_PRINT_INFO7("GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:conn id %d, cause 0x%x, reason 0x%x, phy %d, transmit power level %d, transmit power level flag %d, delta %d", + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->conn_id, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->cause, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->reason, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->phy, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level_flag, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->delta); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_read_remote_transmit_power_level(uint8_t conn_id, + T_GAP_LE_RF_POWER_CONTROL_PHYS_TYPE phy); + +/** +* @brief Enable or disable the reporting to the local Host of transmit power level changes +* in the local and remote Controllers for the ACL connection. +* +* @param[in] conn_id Connection ID +* @param[in] local_enable enable or disable local transmit power reports +* @param[in] remote_enable enable or disable remote transmit power reports +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. +* @retval GAP_CAUSE_NON_CONN: Set request sent fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + uint8_t conn_id; + + cause = le_rf_set_transmit_power_reporting_enable(conn_id, local_enable, remote_enable); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_2_POWER_CONTROL_SUPPORT + case GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE: + APP_PRINT_INFO2("GAP_LE_RF_SET_TRANSMIT_POWER_REPORTING_ENABLE:conn id %d, cause 0x%x", + p_le_rf_cb->data.p_le_rf_set_transmit_power_reporting_enable_rsp->conn_id, + p_le_rf_cb->data.p_le_rf_set_transmit_power_reporting_enable_rsp->cause); + break; + + case GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO: + APP_PRINT_INFO7("GAP_LE_RF_TRANSMIT_POWER_REPORTING_INFO:conn id %d, cause 0x%x, reason 0x%x, phy %d, transmit power level %d, transmit power level flag %d, delta %d", + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->conn_id, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->cause, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->reason, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->phy, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->tx_power_level_flag, + p_le_rf_cb->data.p_le_rf_transmit_power_reporting_info->delta); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_set_transmit_power_reporting_enable(uint8_t conn_id, uint8_t local_enable, + uint8_t remote_enable); +#endif + +#if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT +/** +* @brief Set the path loss threshold reporting parameters for the ACL connection +* +* @param[in] conn_id Connection ID +* @param[in] high_threshold High threshold for the path loss + Units: dB + 0xFF: High Threshold unused +* @param[in] high_hysteresis Hysteresis value for the high threshold + Units: dB +* @param[in] low_threshold Low threshold for the path loss + Units: dB +* @param[in] low_hysteresis Hysteresis value for the low threshold + Units: dB +* @param[in] min_time_spent Minimum time in number of connection events to be observed once the + path crosses the threshold before an event is generated. +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. +* @retval GAP_CAUSE_NON_CONN: Set request sent fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + uint8_t conn_id; + + cause = le_rf_set_path_loss_reporting_params(conn_id, high_threshold, high_hysteresis, + low_threshold, low_hysteresis, min_time_spent); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT + case GAP_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS: + APP_PRINT_INFO2("GAP_LE_RF_SET_PATH_LOSS_REPORTING_PARAMS:conn id %d, cause 0x%x", + p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_params_rsp->conn_id, + p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_params_rsp->cause); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_set_path_loss_reporting_params(uint8_t conn_id, uint8_t high_threshold, + uint8_t high_hysteresis, uint8_t low_threshold, + uint8_t low_hysteresis, uint16_t min_time_spent); + +/** +* @brief Enable or disable path loss reporting. +* +* @param[in] conn_id Connection ID +* @param[in] enable enable or disable path loss reporting +* @retval GAP_CAUSE_SUCCESS: Send request success. +* @retval GAP_CAUSE_SEND_REQ_FAILED: Send request fail. +* @retval GAP_CAUSE_NON_CONN: Set request sent fail. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_CAUSE cause; + uint8_t conn_id; + + cause = le_rf_set_path_loss_reporting_enable(conn_id, enable); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + T_GAP_LE_RF_CB *p_le_rf_cb = NULL; + + switch (cb_type) + { + ... + case GAP_MSG_LE_RF_INFO: + APP_PRINT_INFO0("GAP_MSG_LE_RF_INFO"); + p_le_rf_cb = (T_GAP_LE_RF_CB *)p_data->p_le_cb_data; + + switch (p_le_rf_cb->opcode) + { + ... + #if F_BT_LE_5_2_PATH_LOSS_MONITORING_SUPPORT + case GAP_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE: + APP_PRINT_INFO2("GAP_LE_RF_SET_PATH_LOSS_REPORTING_ENABLE:conn id %d, cause 0x%x", + p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_enable_rsp->conn_id, + p_le_rf_cb->data.p_le_rf_set_path_loss_reporting_enable_rsp->cause); + break; + + case GAP_LE_RF_PATH_LOSS_THRESHOLD_INFO: + APP_PRINT_INFO3("GAP_LE_RF_PATH_LOSS_THRESHOLD_INFO:conn id %d, current path loss %d, zone entered %d", + p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->conn_id, + p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->current_path_loss, + p_le_rf_cb->data.p_le_rf_path_loss_threshold_info->zone_entered); + break; + #endif + ... + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_rf_set_path_loss_reporting_enable(uint8_t conn_id, uint8_t enable); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_LE_RF_H */ diff --git a/inc/bluetooth/gap/gap_le_types.h b/inc/bluetooth/gap/gap_le_types.h new file mode 100644 index 0000000..ff1ec0b --- /dev/null +++ b/inc/bluetooth/gap/gap_le_types.h @@ -0,0 +1,486 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_le_types.h + * @brief This file contains all the constants and functions prototypes for GAP protocol. + * @details This file is used both bredr and le. + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_LE_TYPES_H +#define GAP_LE_TYPES_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include "upperstack_config.h" +#include + +/** @addtogroup GAP_LE_TYPES GAP LE Related Definitions + * @brief Defines GAP related definitions. + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup GAP_LE_TYPES_Exported_Macros + * @{ + */ +#define GAP_LE_SUPPORTED_FEATURES_LEN 8 //!< LE supported feature length. + +/** @defgroup RANDOM_ADDR_MASK Random Address Mask + * @{ + */ +#define RANDOM_ADDR_MASK_STATIC 0xC0 /**< Random address mask for static random address */ +#define RANDOM_ADDR_MASK_RESOLVABLE 0x40 /**< Random address mask for resolvable random address */ +#define RANDOM_ADDR_MASK_NON_RESOLVABLE 0x00 /**< Random address mask for non-resolvable random address */ +#define RANDOM_ADDR_MASK 0xC0 /**< Mask for random address */ +/** End of RANDOM_ADDR_MASK + * @} + */ + +/** @defgroup ADV_CHANNEL_MAP Advertising Channel Map + * @{ + */ +#define GAP_ADVCHAN_37 0x01 //!< Advertisement Channel 37 +#define GAP_ADVCHAN_38 0x02 //!< Advertisement Channel 38 +#define GAP_ADVCHAN_39 0x04 //!< Advertisement Channel 39 +#define GAP_ADVCHAN_ALL (GAP_ADVCHAN_37 | GAP_ADVCHAN_38 | GAP_ADVCHAN_39) //!< All Advertisement Channels Enabled +/** End of ADV_CHANNEL_MAP + * @} + */ + + +/** @defgroup ADV_DATA_TYPE EIR Data Type, Advertising Data Type (AD Type) and OOB Data Type Definitions + * @{ + */ +#define GAP_ADTYPE_FLAGS 0x01 //!< The Flags data type contains one bit Boolean flags. Please reference @ref ADV_TYPE_FLAGS for details. +#define GAP_ADTYPE_16BIT_MORE 0x02 //!< Service: More 16-bit UUIDs available +#define GAP_ADTYPE_16BIT_COMPLETE 0x03 //!< Service: Complete list of 16-bit UUIDs +#define GAP_ADTYPE_32BIT_MORE 0x04 //!< Service: More 32-bit UUIDs available +#define GAP_ADTYPE_32BIT_COMPLETE 0x05 //!< Service: Complete list of 32-bit UUIDs +#define GAP_ADTYPE_128BIT_MORE 0x06 //!< Service: More 128-bit UUIDs available +#define GAP_ADTYPE_128BIT_COMPLETE 0x07 //!< Service: Complete list of 128-bit UUIDs +#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 //!< Shortened local name +#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 //!< Complete local name +#define GAP_ADTYPE_POWER_LEVEL 0x0A //!< TX Power Level: 0xXX: -127 to +127 dBm +#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D //!< Simple Pairing OOB Tag: Class of device (3 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E //!< Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets) +#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F //!< Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets) +#define GAP_ADTYPE_SM_TK 0x10 //!< Security Manager TK Value +#define GAP_ADTYPE_SM_OOB_FLAG 0x11 //!< Secutiry Manager OOB Flags +#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 //!< Min and Max values of the connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max) +#define GAP_ADTYPE_SIGNED_DATA 0x13 //!< Signed Data field +#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 //!< Service Solicitation: list of 16-bit Service UUIDs +#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 //!< Service Solicitation: list of 128-bit Service UUIDs +#define GAP_ADTYPE_SERVICE_DATA 0x16 //!< Service Data +#define GAP_ADTYPE_PUBLIC_TGT_ADDR 0x17 //!< Public Target Address +#define GAP_ADTYPE_RANDOM_TGT_ADDR 0x18 //!< Random Target Address +#define GAP_ADTYPE_APPEARANCE 0x19 //!< Appearance +#define GAP_ADTYPE_ADV_INTERVAL 0x1A //!< Advertising Interval +#define GAP_ADTYPE_LE_BT_ADDR 0x1B //!< LE Bluetooth Device Address +#define GAP_ADTYPE_LE_ROLE 0x1C //!< LE Role +#define GAP_ADTYPE_SP_HASH_C256 0x1D //!< Simple Pairing Hash C-256 +#define GAP_ADTYPE_SP_RAND_R256 0x1E //!< Simple Pairing Randomizer R-256 +#define GAP_ADTYPE_LIST_32BIT_SILI 0x1F //!< List of 32-bit Service Solicitation UUIDs +#define GAP_ADTYPE_SERVICE_DATA_32BIT 0x20 //!< Service Data - 32-bit UUID +#define GAP_ADTYPE_SERVICE_DATA_128BIT 0x21 //!< Service Data - 128-bit UUID +#define GAP_ADTYPE_SC_CONF_VALUE 0x22 //!< LE Secure Connections Confirmation Value +#define GAP_ADTYPE_SC_RAND_VALUE 0x23 //!< LE Secure Connections Random Value +#define GAP_ADTYPE_URI 0x24 //!< URI +#define GAP_ADTYPE_INDOOR_POSITION 0x25 //!< Indoor Positioning +#define GAP_ADTYPE_TRANSPORT_DISCOVERY_DATA 0x26 //!< Transport Discovery Data +#define GAP_ADTYPE_LE_SUPPORTED_FEATURES 0x27 //!< LE Supported Features +#define GAP_ADTYPE_CHAN_MAP_UPDATE_IND 0x28 //!< Channel Map Update Indication +#define GAP_ADTYPE_MESH_PB_ADV 0x29 //!< Mesh Pb-Adv +#define GAP_ADTYPE_MESH_PACKET 0x2A //!< Mesh Packet +#define GAP_ADTYPE_MESH_BEACON 0x2B //!< Mesh Beacon +#define GAP_ADTYPE_3D_INFO_DATA 0x3D //!< 3D Information Data +#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF //!< Manufacturer Specific Data: first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data +/** End of ADV_DATA_TYPE + * @} + */ + +/** @defgroup ADV_TYPE_FLAGS The Flags data type + * @{ + */ +#define GAP_ADTYPE_FLAGS_LIMITED 0x01 //!< Discovery Mode: LE Limited Discoverable Mode +#define GAP_ADTYPE_FLAGS_GENERAL 0x02 //!< Discovery Mode: LE General Discoverable Mode +#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 //!< Discovery Mode: BR/EDR Not Supported +#define GAP_ADTYPE_FLAGS_SIMULTANEOUS_LE_BREDR_CONTROLLER 0x08 //!< Discovery Mode: Simultaneous LE and BR/EDR Controller Supported +#define GAP_ADTYPE_FLAGS_SIMULTANEOUS_LE_BREDR_HOST 0x10 //!< Discovery Mode: Simultaneous LE and BR/EDR Host Supported +/** @} End ADV_TYPE_FLAGS */ + +/** @defgroup GAP_LE_APPEARANCE_VALUES GAP Appearance Values + * @{ + */ +#define GAP_GATT_APPEARANCE_UNKNOWN 0 +#define GAP_GATT_APPEARANCE_GENERIC_PHONE 64 +#define GAP_GATT_APPEARANCE_GENERIC_COMPUTER 128 +#define GAP_GATT_APPEARANCE_GENERIC_WATCH 192 +#define GAP_GATT_APPEARANCE_WATCH_SPORTS_WATCH 193 + +#define GAP_GATT_APPEARANCE_GENERIC_CLOCK 256 +#define GAP_GATT_APPEARANCE_GENERIC_DISPLAY 320 +#define GAP_GATT_APPEARANCE_GENERIC_REMOTE_CONTROL 384 +#define GAP_GATT_APPEARANCE_GENERIC_EYE_GLASSES 448 +#define GAP_GATT_APPEARANCE_GENERIC_TAG 512 +#define GAP_GATT_APPEARANCE_GENERIC_KEYRING 576 +#define GAP_GATT_APPEARANCE_GENERIC_MEDIA_PLAYER 640 +#define GAP_GATT_APPEARANCE_GENERIC_BARCODE_SCANNER 704 + +#define GAP_GATT_APPEARANCE_GENERIC_THERMOMETER 768 +#define GAP_GATT_APPEARANCE_THERMOMETER_EAR 769 + +#define GAP_GATT_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 +#define GAP_GATT_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 + +#define GAP_GATT_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 +#define GAP_GATT_APPEARANCE_BLOOD_PRESSURE_ARM 897 +#define GAP_GATT_APPEARANCE_BLOOD_PRESSURE_WRIST 898 + +#define GAP_GATT_APPEARANCE_HUMAN_INTERFACE_DEVICE 960 +#define GAP_GATT_APPEARANCE_KEYBOARD 961 +#define GAP_GATT_APPEARANCE_MOUSE 962 +#define GAP_GATT_APPEARANCE_JOYSTICK 963 +#define GAP_GATT_APPEARANCE_GAMEPAD 964 +#define GAP_GATT_APPEARANCE_DIGITIZER_TABLET 965 +#define GAP_GATT_APPEARANCE_CARD_READER 966 +#define GAP_GATT_APPEARANCE_DIGITAL_PEN 967 +#define GAP_GATT_APPEARANCE_BARCODE_SCANNER 968 + +#define GAP_GATT_APPEARANCE_GENERIC_GLUCOSE_METER 1024 + +#define GAP_GATT_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 +#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 +#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 +#define GAP_GATT_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 + +#define GAP_GATT_APPEARANCE_GENERIC_CYCLING 1152 +#define GAP_GATT_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 +#define GAP_GATT_APPEARANCE_CYCLING_SPEED_SENSOR 1154 +#define GAP_GATT_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 +#define GAP_GATT_APPEARANCE_CYCLING_POWER_SENSOR 1156 +#define GAP_GATT_APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR 1157 + +#define GAP_GATT_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 +#define GAP_GATT_APPEARANCE_FINGERTIP 3137 +#define GAP_GATT_APPEARANCE_WRIST_WORN 3138 +#define GAP_GATT_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 + +#define GAP_GATT_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACTIVITY 5184 +#define GAP_GATT_APPEARANCE_LOCATION_DISPLAY_DEVICE 5185 +#define GAP_GATT_APPEARANCE_LOCATION_AND_NAVIGATION_DISPLAY_DEVICE 5186 +#define GAP_GATT_APPEARANCE_LOCATION_POD 5187 +#define GAP_GATT_APPEARANCE_LOCATION_AND_NAVIGATION_POD 5188 +/** @} End GAP_LE_APPEARANCE_VALUES */ + +#define GAP_PHYS_PREFER_ALL 0 +#define GAP_PHYS_NO_PREFER_TX_BIT 0x01 /**< The Host has no preference among the transmitter PHYs supported by the Controller */ +#define GAP_PHYS_NO_PREFER_RX_BIT 0x02 /**< The Host has no preference among the receiver PHYs supported by the Controller */ + +#define GAP_PHYS_PREFER_1M_BIT 0x01 /**< The Host prefers to use the LE 1M transmitter PHY (possibly among others) */ +#define GAP_PHYS_PREFER_2M_BIT 0x02 /**< The Host prefers to use the LE 2M transmitter PHY (possibly among others) */ +#define GAP_PHYS_PREFER_CODED_BIT 0x04 /**< The Host prefers to use the LE Coded transmitter PHY (possibly among others) */ + +/** @defgroup GAP_PHYS_CONN_INIT Connection Initiating PHYs + * @{ + */ +#define GAP_PHYS_CONN_INIT_1M_BIT 0x01/**< Scan connectable advertisements on the LE 1M PHY. Connection +parameters for the LE 1M PHY are provided. */ +#define GAP_PHYS_CONN_INIT_2M_BIT 0x02 /**< Connection parameters for the LE 2M PHY are provided.*/ +#define GAP_PHYS_CONN_INIT_CODED_BIT 0x04 /**< Scan connectable advertisements on the LE Coded PHY. Connection +parameters for the LE Coded PHY are provided.*/ +/** End of GAP_PHYS_CONN_INIT + * @} + */ + +/** End of GAP_LE_TYPES_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @addtogroup GAP_LE_TYPES_Exported_Types + * @{ + */ + +/** @brief define local adress type */ +typedef enum +{ + GAP_LOCAL_ADDR_LE_PUBLIC = 0x00, /**< Bluetooth low energy public address. */ + GAP_LOCAL_ADDR_LE_RANDOM = 0x01, /**< Bluetooth low energy random address. */ +#if F_BT_LE_PRIVACY_SUPPORT + GAP_LOCAL_ADDR_LE_RAP_OR_PUBLIC = 0x02, /**< Controller generates the Resolvable Private Address based on the local +IRK from the resolving list. If the resolving list contains no matching entry, then use the public address. */ + GAP_LOCAL_ADDR_LE_RAP_OR_RAND = 0x03 /**< Controller generates the Resolvable Private Address based on the local +IRK from the resolving list. If the resolving list contains no matching entry, then use the random address from the most recent successful LE_Set_Random_Address Command. */ + /** @} End GAP_LE_LOCAL_ADDR_TYPE_DEFINES */ +#endif +} T_GAP_LOCAL_ADDR_TYPE; + +/** @brief Define random adress type */ +typedef enum +{ + GAP_RAND_ADDR_STATIC = 0x00,/**< Static random device address. */ + GAP_RAND_ADDR_NON_RESOLVABLE = 0x01,/**< Non resolvable random device address. */ + GAP_RAND_ADDR_RESOLVABLE = 0x02 /**< Resolvable random device address. */ +} T_GAP_RAND_ADDR_TYPE; + +/** @brief Define indentify address type */ +typedef enum +{ + GAP_IDENT_ADDR_PUBLIC = 0x00, /* low energy public address. */ + GAP_IDENT_ADDR_RAND = 0x01, /* low energy random address. */ +} T_GAP_IDENT_ADDR_TYPE; + +/** @brief Definition of LE direct address type.*/ +typedef enum +{ + GAP_DIRECT_ADDR_LE_PUBLIC = 0x00, /**< Public Device Address (default) */ + GAP_DIRECT_ADDR_LE_RAND = 0x01, /**< Random Device Address */ + GAP_DIRECT_ADDR_LE_PUBLIC_IDENT = 0x02, /**< Public Identity Address (Corresponds to Resolved Private Address ) */ + GAP_DIRECT_ADDR_LE_RAND_IDENT = 0x03, /**< Random (static) Identity Address (Corresponds to Resolved Private Address) */ + GAP_DIRECT_ADDR_LE_RAND_UNABLE_RESOLV = 0xFE /**< No address provided (anonymous advertisement) */ +} T_GAP_DIRECT_ADDR_TYPE; + +/** @brief Definition of LE white list operation.*/ +typedef enum +{ + GAP_WHITE_LIST_OP_CLEAR = 0x00, /**< Clear white list. */ + GAP_WHITE_LIST_OP_ADD = 0x01, /**< Add a device to the white list. */ + GAP_WHITE_LIST_OP_REMOVE = 0x02 /**< Remove a device from the white list. */ +} T_GAP_WHITE_LIST_OP; + +#if F_BT_LE_GAP_PERIPHERAL_SUPPORT +/** @brief Advertising Event Types.*/ +typedef enum +{ + GAP_ADTYPE_ADV_IND = 0x00, //!< Connectable undirected advertisement + GAP_ADTYPE_ADV_HDC_DIRECT_IND = 0x01, //!< Connectable high duty cycle directed advertisement + GAP_ADTYPE_ADV_SCAN_IND = 0x02, //!< Scannable undirected advertisement + GAP_ADTYPE_ADV_NONCONN_IND = 0x03, //!< Non-Connectable undirected advertisement + GAP_ADTYPE_ADV_LDC_DIRECT_IND = 0x04, //!< Connectable low duty cycle directed advertisement +} T_GAP_ADTYPE; + +/** @brief Definition of LE advertising filter policy.*/ +typedef enum +{ + GAP_ADV_FILTER_ANY = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default). */ + GAP_ADV_FILTER_WHITE_LIST_SCAN = 0x01,/**< Process connection requests from all devices and only scan requests from +devices that are in the White List. */ + GAP_ADV_FILTER_WHITE_LIST_CONN = 0x02,/**< Process scan requests from all devices and only connection requests from +devices that are in the White List. */ + GAP_ADV_FILTER_WHITE_LIST_ALL = 0x03,/**< Process scan and connection requests only from devices in the White List. */ +} T_GAP_ADV_FILTER_POLICY; +#endif + +#if F_BT_LE_GAP_SCAN_SUPPORT +/** @brief Definition of LE scan type.*/ +typedef enum +{ + GAP_SCAN_MODE_PASSIVE = 0x00, /**< Passive Scanning. No scan request PDUs shall be sent. */ + GAP_SCAN_MODE_ACTIVE = 0x01 /**< Active Scanning. Scan request PDUs may be sent. */ +} T_GAP_SCAN_MODE; + +/** @brief Definition of LE scan filter policy.*/ +typedef enum +{ + GAP_SCAN_FILTER_ANY = 0x00, /**< Accept all advertising packets except directed advertising packets not +addressed to this device (default). */ + GAP_SCAN_FILTER_WHITE_LIST = 0x01,/**< Accept only advertising packets from devices where the advertiser's +address is in the White List. Directed advertising packets which are not +addressed to this device shall be ignored. */ + GAP_SCAN_FILTER_ANY_RPA = 0x02, /**< Accept all advertising packets except directed advertising packets +where the initiator's identity address does not address this device. +Note: Directed advertising packets where the initiator's address is a +resolvable private address that cannot be resolved are also accepted. */ + GAP_SCAN_FILTER_WHITE_LIST_RPA = 0x03,/**< Accept all advertising packets except: +1) advertising packets where the advertiser's identity address is not in +the White List; and +2) directed advertising packets where the initiator's identity address +does not address this device +Note: Directed advertising packets where the initiator's address is a +resolvable private address that cannot be resolved are also accepted. */ +} T_GAP_SCAN_FILTER_POLICY; + +/** @brief Definition of LE extended scan duplicate filter type.*/ +typedef enum +{ + GAP_SCAN_FILTER_DUPLICATE_DISABLE = 0x00, /**< Duplicate filtering disabled. */ + GAP_SCAN_FILTER_DUPLICATE_ENABLE = 0x01, /**< Duplicate filtering enabled. */ + GAP_SCAN_FILTER_DUPLICATE_ENABLED_RESET_FOR_EACH_PERIOD = 0x02, /**< Duplicate filtering enabled, reset for each scan period. */ +} T_GAP_SCAN_FILTER_DUPLICATE; + +/** This enum type describes adv type for T_GAP_ADV_EVT_TYPE. */ +typedef enum +{ + GAP_ADV_EVT_TYPE_UNDIRECTED = 0x00, /**< Connectable undirected advertising. */ + GAP_ADV_EVT_TYPE_DIRECTED = 0x01, /**< Connectable directed advertising. */ + GAP_ADV_EVT_TYPE_SCANNABLE = 0x02, /**< Scanable undirected advertising. */ + GAP_ADV_EVT_TYPE_NON_CONNECTABLE = 0x03, /**< Nonconnectable undirected advertising. */ + GAP_ADV_EVT_TYPE_SCAN_RSP = 0x04 /**< scan response. */ +} T_GAP_ADV_EVT_TYPE; +#endif + +/** @brief Definition of security level. */ +typedef enum +{ + GAP_SEC_LEVEL_NO = 0x00,/**< No security (No authentication and no encryption).*/ + GAP_SEC_LEVEL_UNAUTHEN = 0x04,/**< Unauthenticated pairing with encryption.*/ + GAP_SEC_LEVEL_AUTHEN = 0x05,/**< Authenticated pairing with encryption.*/ + GAP_SEC_LEVEL_SC_UNAUTHEN = 0x07,/**< Unuthenticated LE Secure Connections pairing with encryption using a 128- +bit strength encryption key.*/ + GAP_SEC_LEVEL_SC_AUTHEN = 0x08/**< Authenticated LE Secure Connections pairing with encryption using a 128- +bit strength encryption key.*/ +} T_GAP_SEC_LEVEL; + +/** @brief Definition of adv tx power type. */ +typedef enum +{ + GAP_ADV_TX_POW_SET_1M, /**< Configure 1M adv tx power. */ + GAP_ADV_TX_POW_SET_2M, /**< Configure 2M adv tx power. */ + GAP_ADV_TX_POW_RESET_1M, /**< Reset 1M adv tx power to default value. */ + GAP_ADV_TX_POW_RESET_2M, /**< Reset 2M adv tx power to default value. */ +} T_GAP_ADV_TX_POW_TYPE; + +/** @brief Definition of SCA field encoding. */ +typedef enum +{ + GAP_SCA_251_TO_500_PPM = 0, //!< Sleep Clock Accuracy: 251 - 500 ppm. + GAP_SCA_151_TO_250_PPM = 1, //!< Sleep Clock Accuracy: 151 - 250 ppm. + GAP_SCA_101_TO_150_PPM = 2, //!< Sleep Clock Accuracy: 101 - 150 ppm. + GAP_SCA_76_TO_100_PPM = 3, //!< Sleep Clock Accuracy: 76 - 100 ppm. + GAP_SCA_51_TO_75_PPM = 4, //!< Sleep Clock Accuracy: 51 - 75 ppm. + GAP_SCA_31_TO_50_PPM = 5, //!< Sleep Clock Accuracy: 31 - 50 ppm. + GAP_SCA_21_TO_30_PPM = 6, //!< Sleep Clock Accuracy: 21 - 30 ppm. + GAP_SCA_0_TO_20_PPM = 7, //!< Sleep Clock Accuracy: 0 - 20 ppm. + GAP_SCA_INVALID = 8 //!< Invalid Sleep Clock Accuracy. +} T_GAP_SCA_FIELD_ENCODING; + +#if F_BT_LE_PRIVACY_SUPPORT +/** @brief Definition of LE resolving list operation.*/ +typedef enum +{ + GAP_RESOLV_LIST_OP_CLEAR = 0x00, /**< Clear resolving list operation. */ + GAP_RESOLV_LIST_OP_ADD = 0x01, /**< Add a device to the resolving list operation. */ + GAP_RESOLV_LIST_OP_REMOVE = 0x02 /**< Remove a device from the resolving list operation. */ +} T_GAP_RESOLV_LIST_OP; + +/** @brief Definition of LE privacy mode.*/ +typedef enum +{ + GAP_PRIVACY_MODE_NETWORK = 0x00, /**< Network privacy mode. */ + GAP_PRIVACY_MODE_DEVICE = 0x01 /**< Device privacy mode. */ +} T_GAP_PRIVACY_MODE; +#endif + +/** @brief Definition of LE PHY type.*/ +typedef enum +{ + GAP_PHYS_1M = 0x01, /**< LE PHY 1M used. */ + GAP_PHYS_2M = 0x02, /**< LE PHY 2M used. */ + GAP_PHYS_CODED = 0x03 /**< LE Coded PHY used. */ +} T_GAP_PHYS_TYPE; + +/** @brief Definition of LE primary advertising PHY type.*/ +typedef enum +{ + GAP_PHYS_PRIM_ADV_1M = 0x01, /**< Primary advertisement PHY is LE 1M */ + GAP_PHYS_PRIM_ADV_CODED = 0x03 /**< Primary advertisement PHY is LE Coded */ +} T_GAP_PHYS_PRIM_ADV_TYPE; + +/** @brief Definition of LE Coded PHY preference options.*/ +typedef enum +{ + GAP_PHYS_OPTIONS_CODED_PREFER_NO = 0x00,/**< Host has no preferred coding when transmitting on the LE Coded PHY */ + GAP_PHYS_OPTIONS_CODED_PREFER_S2 = 0x01,/**< Host prefers that S=2 coding be used when transmitting on the LE Coded PHY */ + GAP_PHYS_OPTIONS_CODED_PREFER_S8 = 0x02 /**< Host prefers that S=8 coding be used when transmitting on the LE Coded PHY */ +} T_GAP_PHYS_OPTIONS; + +#if F_BT_LE_5_0_AE_SCAN_SUPPORT +typedef enum +{ + GAP_EXT_ADV_EVT_DATA_STATUS_COMPLETE = 0x00, /**< Data status: Complete */ + GAP_EXT_ADV_EVT_DATA_STATUS_MORE = 0x01, /**< Data status: Incomplete, more data to come */ + GAP_EXT_ADV_EVT_DATA_STATUS_TRUNCATED = 0x02, /**< Data status: Incomplete, data truncated, no more to come */ + GAP_EXT_ADV_EVT_DATA_STATUS_RFU = 0x03 /**< Data status: Reserved for future use */ +} T_GAP_EXT_ADV_EVT_DATA_STATUS; +#endif + +#if F_BT_LE_APP_KEY_MANAGER +typedef enum +{ + GATT_STORE_OP_GET_CCC_BITS, /**< get CCC Bits for one */ + GATT_STORE_OP_SET_CCC_BITS, /**< set CCC Bits for one */ + GATT_STORE_OP_DELETE_ALL_CCC_BITS, /**< delete all CCC Bits for all peers */ +} T_GATT_STORE_OPCODE; +#endif + +typedef enum +{ + GAP_CTE_TYPE_AOA = 0x00, /**< AoA Constant Tone Extension> */ + GAP_CTE_TYPE_AOD_1US_SLOT = 0x01, /**< AoD Constant Tone Extension with 1 us slots> */ + GAP_CTE_TYPE_AOD_2US_SLOT = 0x02, /**< AoD Constant Tone Extension with 2 us slots> */ +} T_GAP_CTE_TYPE; + +typedef enum +{ + GAP_SLOT_DURATIONS_SWITCH_SAMPLE_1US = 0x01, /** */ + GAP_SLOT_DURATIONS_SWITCH_SAMPLE_2US = 0x02, /** */ +} T_GAP_SLOT_DUATIONS_TYPE; + +#if F_BT_LE_5_0_PA_SYNC_SUPPORT +/** @brief Definition of LE periodic advertiser list operation.*/ +typedef enum +{ + GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_CLEAR = 0x00, /**< Clear periodic advertiser list. */ + GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_ADD = 0x01, /**< Add an entry to the periodic advertiser list. */ + GAP_PA_SYNC_PERIODIC_ADV_LIST_OP_REMOVE = 0x02 /**< Remove an entry from the periodic advertiser list. */ +} T_GAP_PA_SYNC_PERIODIC_ADV_LIST_OP; + +typedef enum +{ + GAP_PERIODIC_ADV_REPORT_DATA_STATUS_COMPLETE = 0x00, /**< Data complete */ + GAP_PERIODIC_ADV_REPORT_DATA_STATUS_MORE = 0x01, /**< Data incomplete, more data to come */ + GAP_PERIODIC_ADV_REPORT_DATA_STATUS_TRUNCATED = 0x02, /**< Data incomplete, data truncated, no more to come */ +} T_GAP_PERIODIC_ADV_REPORT_DATA_STATUS; + +typedef enum +{ + GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOA_CTE = 0x00, /**< AoA Constant Tone Extension */ + GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOD_CTE_1US = 0x01, /**< AoD Constant Tone Extension with 1 μs slots */ + GAP_PERIODIC_ADV_REPORT_CTE_TYPE_AOD_CTE_2US = 0x02, /**< AoD Constant Tone Extension with 2 μs slots */ + GAP_PERIODIC_ADV_REPORT_CTE_TYPE_NO_CTE = 0xFF, /**< No Constant Tone Extension */ +} T_GAP_PERIODIC_ADV_REPORT_CTE_TYPE; +#endif +/** End of GAP_LE_TYPES_Exported_Types + * @} + */ + +/** @} */ /* End of group GAP_LE_TYPES */ + + +/*------------------------------------------------------------------- +-------------------------------------------------------------------*/ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_H */ diff --git a/inc/bluetooth/gap/gap_lib/gap_config.h b/inc/bluetooth/gap/gap_lib/gap_config.h new file mode 100644 index 0000000..3fc7336 --- /dev/null +++ b/inc/bluetooth/gap/gap_lib/gap_config.h @@ -0,0 +1,352 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_config.h +* @brief Header file for configuration of bt stack related features +* @details This file defines configuration of bt stack related features related API. +* @author ranhui +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_CONFIG_H +#define GAP_CONFIG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "gap_le_types.h" +#include "app_section.h" + +/** @addtogroup GAP GAP Module + * @{ + */ + +/** @addtogroup GAP_LE GAP LE Module + * @{ + */ + +/** @addtogroup GAP_LE_CONFIG GAP LE Config Module + * @{ + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_CONFIG_Exported_Types GAP LE Config Exported Types + * @{ + */ + +/** @brief GAP gatt cccd not check. */ +typedef enum +{ + CONFIG_GATT_CCCD_CHECK, /**< Check cccd when server sends notification or indication. */ + CONFIG_GATT_CCCD_NOT_CHECK, /**< Not check cccd when server sends notification or indication. */ +} T_GAP_CONFIG_GATT_CCCD_NOT_CHECK; + +/** @brief GAP set minimum remote SCA automatically in GAP initialization. */ +typedef enum +{ + CONFIG_LE_MIN_REM_SCA = 1, /**< Set minimum remote SCA automatically in GAP initialization. */ +} T_GAP_CONFIG_LE_MIN_REM_SCA_INIT; + +/** @brief GAP bqb enable. */ +typedef enum +{ + CONFIG_BQB_DISABLE, /**< Disable bqb. */ + CONFIG_BQB_ENABLE, /**< Enable bqb. */ +} T_GAP_CONFIG_BQB_EN; + +/** End of GAP_LE_CONFIG_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_LE_CONFIG_Exported_Functions GAP LE Config Exported Functions + * @brief + * @{ + */ + +/** + * @brief Configure address of bluetooth device. + * Recommendation: configure address of bluetooth device by configFile in MPTool. + * + * NOTE: If device uses address A for first N device boot, and then device uses address B. + * The process is implemented by application, and application needs to delete bonding + * information by @ref le_bond_clear_all_keys() before (N+1)th device boot. + * + * @param[in] bd_addr Address of bluetooth device. + * + *Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + //Address of bluetoooth device is 00:11:22:33:44:55 + uint8_t addr[6] = {0x55, 0x44, 0x33, 0x22, 0x11, 0x00}; + gap_config_bt_bd_addr(addr); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_bt_bd_addr(uint8_t *bd_addr); + +/** + * @brief Configure whether to check cccd when server sends notification or indication. + * + * @param[in] cccd_not_check_flag Whether to check cccd: @ref T_GAP_CONFIG_GATT_CCCD_NOT_CHECK + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_cccd_not_check(CONFIG_GATT_CCCD_NOT_CHECK); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_cccd_not_check(T_GAP_CONFIG_GATT_CCCD_NOT_CHECK + cccd_not_check_flag); + +/** + * @brief Configure whether to set minimum remote SCA automatically in GAP initialization. + * + * @param[in] le_min_rem_sca_flag whether to set minimum remote SCA automatically in GAP initialization, @ref T_GAP_CONFIG_LE_MIN_REM_SCA_INIT + * @param[in] le_min_rem_sca_encoding SCA field encoding, @ref T_GAP_SCA_FIELD_ENCODING + Note: The value is valid if le_min_rem_sca_flag is set to CONFIG_LE_MIN_REM_SCA, and will be replaced + if app calls @ref le_set_gap_param() with parameter @ref GAP_PARAM_SET_REM_MIN_SCA. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_le_min_rem_sca(CONFIG_LE_MIN_REM_SCA, GAP_SCA_31_TO_50_PPM); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_le_min_rem_sca(T_GAP_CONFIG_LE_MIN_REM_SCA_INIT + le_min_rem_sca_flag, + T_GAP_SCA_FIELD_ENCODING le_min_rem_sca_encoding); + +/** + * @brief Configure bte pool size. + * NOTE: Default value of size is 4 * 1024. + * + * @param[in] bte_pool_size bte pool size in units of 1024, range: 4 ~ 10. NOTE: The range may be changed in future version. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + //bte pool size is 6 * 1024 + gap_config_bte_pool_size(6); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_bte_pool_size(uint8_t bte_pool_size); + +/** + * @brief Configure bt report buffer number for observer role or central role. + * NOTE: Default value is 16. + * + * @param[in] bt_report_buf_num bt report buffer number + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_bt_report_buf_num(17); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_bt_report_buf_num(uint8_t bt_report_buf_num); + +/** + * @brief Configure maximum server CCCD number and maximum storage CCCD number. + * + * @param[in] gatt_server_ccc_bits_count maximum server CCCD number, default value is 16. + * @param[in] gatt_storage_ccc_bits_count maximum storage CCCD number, default value is 16. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_ccc_bits_count(18, 18); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_ccc_bits_count(uint8_t gatt_server_ccc_bits_count, + uint8_t gatt_storage_ccc_bits_count); + +/** + * @brief Configure maximum service table number for GATT server. + * NOTE: Default value is 12. The number of service table can be used by app is (gatt_max_attribute_table_count - 1). + * + * @param[in] gatt_max_attribute_table_count maximum service table number. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_max_attribute_table_count(14); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_max_attribute_table_count(uint8_t + gatt_max_attribute_table_count); + +/** + * @brief Configure maximum size of Maximum Transmission Unit. + * NOTE: Default value is 247. + * + * @param[in] att_max_mtu_size maximum size of Maximum Transmission Unit. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_max_mtu_size(200); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_max_mtu_size(uint16_t att_max_mtu_size); + +/** + * @brief Configure key storage flag to determine keys that need to be saved. + * + * NOTE: Storage bits are defined by group GAP_LE_STORAGE_BITS in gap_storage_le.h. + storage bit: 0-not save, 1-save. + Default value is 0xFF, which indicates all keys need to be saved. + * + * @param[in] le_key_storage_flag key storage flag to determine keys that need to be saved + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_le_key_storage_flag(LE_KEY_STORE_CCCD_DATA_BIT | LE_KEY_STORE_REMOTE_LTK_BIT | LE_KEY_STORE_REMOTE_BD_BIT); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_le_key_storage_flag(uint16_t le_key_storage_flag); + +/** + * @brief Configure LE maximum bonded device number. + * + * NOTE: Default value is 1. + * + * @param[in] max_le_paired_device LE maximum bonded device number + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_max_le_paired_device(2); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_max_le_paired_device(uint8_t max_le_paired_device); + +/** + * @brief Configure periodic advertising parameter. + * + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_pa_parameter(); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_pa_parameter(void); + +#if F_BT_CONFIG_INTERNAL_API +APP_FLASH_TEXT_SECTION void gap_config_bqb_en(T_GAP_CONFIG_BQB_EN bqb_en); + +/** + * @brief Configure L2CAP parameters. + * + * @param[in] le_l2c_chann_num maximum L2CAP channel number, default value is 0. + * @param[in] le_sec_entry_num maximum security entry number, default value is 0. + * @param[in] psm_num maximum number of Protocol/Service Multiplexer, default value is 0. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_l2c_param(3, 1, 3); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_l2c_param(uint8_t le_l2c_chann_num, uint8_t le_sec_entry_num, + uint8_t psm_num); +#endif + +/** + * @brief Print parameters configured by app. + * + * Example usage + * \code{.c} + void test(void) + { + gap_config_print_config_param(); + } + * \endcode + */ +void gap_config_print_config_param(void); + +/** + * @brief Configure LE local address storage flag. + * + * NOTE: Default value is false. + * + * @param[in] enable Disable/enable le local address storage flag + * \arg \c true enable le local address storage + * \arg \c false disable le local address storage + * + * @return void. + * + * Example usage + * \code{.c} + APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) + { + gap_config_local_addr_storage(true); + } + * \endcode + */ +APP_FLASH_TEXT_SECTION void gap_config_local_addr_storage(bool enable); + +/** End of GAP_LE_CONFIG_Exported_Functions + * @} + */ + +/** End of GAP_LE_CONFIG + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + + +#endif +#ifdef __cplusplus +} + +#endif /* GAP_CONFIG_H */ + diff --git a/inc/bluetooth/gap/gap_lib/gap_vendor.h b/inc/bluetooth/gap/gap_lib/gap_vendor.h new file mode 100644 index 0000000..258665a --- /dev/null +++ b/inc/bluetooth/gap/gap_lib/gap_vendor.h @@ -0,0 +1,499 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_vendor.h + * @brief + * @details + * @author ranhui_xia + * @date 2017-08-02 + * @version v1.0 + ****************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + ****************************************************************************** + */ +#ifndef GAP_VNR_H +#define GAP_VNR_H + +#include + +/** @addtogroup GAP_LE_VENDOR GAP LE vendor command API. + * @brief GAP LE vendor command API provides extended function for controller. + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup Gap_LE_Vendor_Exported_Macros GAP LE Vendor Exported Macros + * @{ + */ + +/** @defgroup GAP_LE_MSG_Types GAP LE Msg Types + * @{ + */ +#define GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE 0xA0 //! Not send @ref GAP_VENDOR_MSG_TYPE messages to APP. + * @arg Other -> Use application defined callback function. + * @return void + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ...... + gap_register_vendor_cb(app_gap_vendor_callback); + } + void app_gap_vendor_callback(uint8_t cb_type, void *p_cb_data) + { + T_GAP_VENDOR_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_GAP_VENDOR_CB_DATA)); + APP_PRINT_INFO1("app_gap_vendor_callback: cb_type is %d", cb_type); + switch (cb_type) + { + case GAP_MSG_GAP_VENDOR_SET_ANT_CTRL: + APP_PRINT_INFO1("GAP_MSG_GAP_VENDOR_SET_ANT_CTRL: cause 0x%x", + cb_data.gap_vendor_cause.cause); + break; + default: + break; + } + return; + } + \endcode + */ +void gap_register_vendor_cb(P_FUN_GAP_APP_CB vendor_callback); + +/** + * @brief Enable 3 advertising channel advertising data. + * Set 3 adv data please refence to @ref le_vendor_adv_3_data_enable. + * + * @param[in] enable 0: disable, 1: enable each adv channel with diff data. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + void gap_vendor_test(bool enable) + { + ... + cause = le_vendor_adv_3_data_enable(enable); + return cause; + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE: + APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_ADV_3_DATA_ENABLE: cause 0x%x", + p_data->le_cause.cause); + break; + } + ... + } + * \endcode + */ +T_GAP_CAUSE le_vendor_adv_3_data_enable(bool enable); + +/** + * @brief Set different advertising date or scan response data in 3 advertising channel. + * This command is used to set 38 / 39 channel data, set 37 channel data please use normal HCI command. + * It is necessary to enable 3 adv data with @ref le_vendor_adv_3_data_enable. + * + * @param[in] type LE vendor advertising data type @ref T_GAP_ADV_VENDOR_DATA_TYPE. + * @param[in] len The number of significant octets in the advertising data. + * @param[in] p_data Pointer to data to write + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * @retval GAP_CAUSE_INVALID_PARAM: Invalid parameter. + * + * Example usage + * \code{.c} + T_GAP_CAUSE gap_vendor_test(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + T_GAP_ADV_VENDOR_DATA_TYPE type = (T_GAP_ADV_VENDOR_DATA_TYPE)p_parse_value->dw_param[0]; + uint8_t len = p_parse_value->dw_param[1]; + uint8_t value = p_parse_value->dw_param[2]; + uint8_t adv_data[31]; + if (len > GAP_MAX_ADV_LEN) + { + return (RESULT_ERR); + } + memset(adv_data, value, len); + + cause = le_vendor_adv_3_data_set((T_GAP_ADV_VENDOR_DATA_TYPE)type, len, adv_data); + return (T_GAP_CAUSE)cause; + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_VENDOR_ADV_3_DATA_SET: + APP_PRINT_INFO2("GAP_MSG_LE_VENDOR_ADV_3_DATA_SET: type %d, cause 0x%x", + p_data->p_le_vendor_adv_3_data_set_rsp->type, + p_data->p_le_vendor_adv_3_data_set_rsp->cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_vendor_adv_3_data_set(T_GAP_ADV_VENDOR_DATA_TYPE type, + uint8_t len, uint8_t *p_data); + +/** + * @brief LE Drop Acl Data + * + * Drop pending LE acl packet that assigned by user except the acl packet which is currently waiting for ack. + * The packet-dropping rule is cleared if link is disconnected or HCI_RESET. + * + * @param[in] conn_id Connection ID for this link. + * @param[in] mask Assign the mask to compare with data. + * @param[in] pattern Drop data that match pattern + * @param[in] offset The offset in bytes started from Data + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_vdropdata(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + uint8_t conn_id = p_parse_value->dw_param[0]; + + cause = le_vendor_drop_acl_data(conn_id, 0xffff, 0x0015, 5); + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_VENDOR_DROP_ACL_DATA: + APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_DROP_ACL_DATA: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_vendor_drop_acl_data(uint8_t conn_id, uint16_t mask, uint16_t pattern, + uint8_t offset); + +/** + * @brief Modify BT LE Fw Policy + * + * Modify the firmware bt le policy + * + * @param[in] mask Assign the mask to compare with data. + * @param[in] mask Assign the mask to compare with data. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + */ +T_GAP_CAUSE le_vendor_modify_bt_le_fw_policy(uint32_t mask, uint32_t value); + +/** + * @brief Reset BT controller + * + * @param[in] reset_mode GAP software reset mode @ref T_GAP_SW_RESET_MODE. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED: Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_reset(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + T_GAP_SW_RESET_MODE reset_mode = (T_GAP_SW_RESET_MODE)p_parse_value->dw_param[0]; + cause = gap_sw_reset_req(reset_mode); + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_GAP_SW_RESET: + APP_PRINT_INFO1("GAP_MSG_GAP_SW_RESET: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE gap_sw_reset_req(T_GAP_SW_RESET_MODE reset_mode); + +/** + * @brief Set platform bootup active time. + * + * Platform allowed to enter low power mode after this timeout value. + * Can use this command in any time even low power mode is set. + * + * @param[in] active_time Unit: 50msec, Range:0x03-0x800. Default value is 5 sec. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_lpstime(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint16_t active_time = p_parse_value->dw_param[0]; + + if(gap_set_lps_bootup_active_time(active_time)) + { + return RESULT_SUCESS; + } + else + { + return RESULT_GAP_CAUSE_INVALID_PARAM; + } + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_GAP_SET_LPS_BOOTUP_ACTIVE_TIME: + APP_PRINT_INFO1("GAP_MSG_GAP_SET_LPS_BOOTUP_ACTIVE_TIME: cause 0x%x", + p_data->le_cause.cause); + break; + ... + } + * \endcode + */ +bool gap_set_lps_bootup_active_time(uint16_t active_time); + +/** + * @brief Configure coding scheme of LE Coded PHY when device uses LE Advertising Extensions. + * + * NOTE: Advertiser should delete advertising set before changing coding scheme. + * + * @param[in] coding_scheme Coding scheme of LE Coded PHY when when device uses LE Advertising Extensions, @ref T_GAP_AE_CODING_SCHEME. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Send request success. + * @retval other Send request failed. + * + * Example usage + * \code{.c} + void test(void) + { + le_ae_coding_scheme(GAP_AE_CODING_SCHEME_S8); + } + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_AE_CODING_SCHEME: + APP_PRINT_INFO1("GAP_MSG_LE_AE_CODING_SCHEME: cause 0x%x", + cb_data->le_cause.cause); + break; + ... + } + * \endcode + */ +T_GAP_CAUSE le_ae_coding_scheme(T_GAP_AE_CODING_SCHEME coding_scheme); + +/** End of GAP_LE_VENDOR_Exported_Functions + * @} + */ + +/** End of GAP_LE_VENDOR + * @} + */ +#endif /* GAP_VNR_H */ diff --git a/inc/bluetooth/gap/gap_lib/readme b/inc/bluetooth/gap/gap_lib/readme new file mode 100644 index 0000000..e69de29 diff --git a/inc/bluetooth/gap/gap_msg.h b/inc/bluetooth/gap/gap_msg.h new file mode 100644 index 0000000..cdc6034 --- /dev/null +++ b/inc/bluetooth/gap/gap_msg.h @@ -0,0 +1,271 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_msg.h + * @brief This file contains function prototype for all GAP roles. + * @details + * @author ranhui + * @date 2016-02-18 + * @version v0.1 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_MSG_H +#define GAP_MSG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" + +/** @defgroup GAP_MSG_MODULE GAP Message + * @brief GAP message + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup Gap_Msg_Exported_Macros GAP Msg Exported Macros + * @{ + */ + +/** @defgroup GAP_MSG_TYPE GAP BT Message Type Definitions + * @brief Define the subtype of Message IO_MSG_TYPE_BT_STATUS. + * @{ + */ +#define GAP_MSG_LE_DEV_STATE_CHANGE 0x01 //!< Device state change msg type. +#define GAP_MSG_LE_CONN_STATE_CHANGE 0x02 //!< Connection state change msg type. +#define GAP_MSG_LE_CONN_PARAM_UPDATE 0x03 //!< Connection parameter update changed msg type. +#define GAP_MSG_LE_CONN_MTU_INFO 0x04 //!< Connection MTU size info msg type. + +#define GAP_MSG_LE_AUTHEN_STATE_CHANGE 0x05 //!< Authentication state change msg type. +#define GAP_MSG_LE_BOND_PASSKEY_DISPLAY 0x06 //!< Bond passkey display msg type. +#define GAP_MSG_LE_BOND_PASSKEY_INPUT 0x07 //!< Bond passkey input msg type. +#define GAP_MSG_LE_BOND_OOB_INPUT 0x08 //!< Bond passkey oob input msg type. +#define GAP_MSG_LE_BOND_USER_CONFIRMATION 0x09 //!< Bond user confirmation msg type. +#define GAP_MSG_LE_BOND_JUST_WORK 0x0A //!< Bond user confirmation msg type. + +#if F_BT_LE_5_0_AE_ADV_SUPPORT +#define GAP_MSG_LE_EXT_ADV_STATE_CHANGE 0x0B //!< Extended advertising state change msg type. +#endif +/** + * @} + */ + +/** @defgroup GAP_DEVICE_STATE GAP Device State + * @{ + */ +/** @defgroup GAP_INIT_STATE GAP Initial State + * @{ + */ +#define GAP_INIT_STATE_INIT 0 //!< Waiting to be started +#define GAP_INIT_STATE_STACK_READY 1 //!< Stack is ready +/** @} End GAP_INIT_STATE */ + +/** @defgroup GAP_ADV_STATE GAP Advertising State + * @{ + */ +#define GAP_ADV_STATE_IDLE 0 //!< Idle, no advertising +#define GAP_ADV_STATE_START 1 //!< Start Advertising. A temporary state, haven't received the result. +#define GAP_ADV_STATE_ADVERTISING 2 //!< Advertising +#define GAP_ADV_STATE_STOP 3 //!< Stop Advertising. A temporary state, haven't received the result. +/** @} End GAP_ADV_STATE */ + +/** @defgroup GAP_ADV_SUB_STATE GAP Advertising Substate + * @{ + */ +#define GAP_ADV_TO_IDLE_CAUSE_STOP 0 //!Example usage + * \code{.c} + void test() + { + le_write_authen_payload_timeout(conn_id, authen_payload_timeout); + } + + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ... + case GAP_MSG_LE_PING_INFO: + { + APP_PRINT_INFO0("GAP_MSG_LE_PING_INFO"); + T_GAP_LE_PING_CB *p_le_ping_cb; + p_le_ping_cb = (T_GAP_LE_PING_CB *)p_data->p_le_cb_data; + + switch (p_le_ping_cb->opcode) + { + case GAP_LE_PING_WRITE_AUTHEN_PAYLOAD_TIMEOUT: + APP_PRINT_INFO2("GAP_LE_PING_WRITE_AUTHEN_PAYLOAD_TIMEOUT: conn_id %d, cause 0x%x", + p_le_ping_cb->data.p_le_write_authen_payload_timeout_rsp->conn_id, + p_le_ping_cb->data.p_le_write_authen_payload_timeout_rsp->cause); + break; + + default: + APP_PRINT_ERROR1("app_gap_ping_callback: unhandled cb_type 0x%x", cb_type); + break; + } + + break; + } + ... + } + } + * \endcode + */ +T_GAP_CAUSE le_write_authen_payload_timeout(uint8_t conn_id, uint16_t authen_payload_timeout); +#endif + +/** End of GAP_LE_PING_Exported_Functions + * @} + */ + +/** End of GAP_LE_PING + * @} + */ + +/** End of GAP_LE + * @} + */ + +/** End of GAP + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_PING_LE_H */ diff --git a/inc/bluetooth/gap/gap_privacy.h b/inc/bluetooth/gap/gap_privacy.h new file mode 100644 index 0000000..ce4ffa0 --- /dev/null +++ b/inc/bluetooth/gap/gap_privacy.h @@ -0,0 +1,315 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gap_privacy.h + * @brief This file contains all the functions prototypes for the GAP bond and pairing + * related functions. + * @details + * @author ranhui + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_PRIVACY_H +#define GAP_PRIVACY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap_le.h" +#include "gap_conn_le.h" +#include "gap_storage_le.h" + +#if F_BT_LE_PRIVACY_SUPPORT +/** @defgroup GAP_PRIVACY_MODULE GAP LE Privacy + * @brief GAP LE privacy + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup Gap_Privacy_Exported_Types GAP Privacy Exported Types + * @{ + */ + +/** @brief Define the privacy callback type */ +#define GAP_MSG_LE_PRIVACY_RESOLUTION_STATUS_INFO 0x00 //! Use gap defualt callback function. + * @arg Other -> Use application defined callback function. + * @return none + */ +void le_privacy_register_cb(P_FUN_PRIVACY_CB p_privacy_cb); + +/** + * @brief Enable/disable le privacy address resolution mode. + * @param[in] enable Enable or disable address resolution. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_set_addr_resolution(bool enable); + +/** + * @brief Read peer resolvable random address. + * @param[in] peer_identity_address_type Peer identity address type. + * @param[in] peer_identity_address Peer identity address. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_read_peer_resolv_addr(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type, + uint8_t *peer_identity_address); + +/** + * @brief Read local resolvable random address. + * @param[in] peer_identity_address_type Peer identity address type. + * @param[in] peer_identity_address Peer identity address. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_read_local_resolv_addr(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type, + uint8_t *peer_identity_address); + +/** + * @brief Set resolvable private address timeout. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_set_resolv_priv_addr_timeout(void); + + +/** + * @brief Modicy local resolvable device list. + * NOTE: You can call this function to add, remove or clear the resolvable list + * + * When the default value of @ref gap_config_local_addr_storage is true or + * @ref gap_config_local_addr_storage (true) has been configured and operation + * equals @ref GAP_RESOLV_LIST_OP_ADD, this function cannot be used if local + * device uses different local addresses to bond with the same remote device. + * In this situation, @ref le_privacy_add_resolv_list shall be called. + * + * @param[in] operation type, @ref T_GAP_RESOLV_LIST_OP. + * @param[in] peer_identity_address_type Peer identity address type. + * @param[in] peer_identity_address Peer identity address. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_modify_resolv_list(T_GAP_RESOLV_LIST_OP operation, + T_GAP_IDENT_ADDR_TYPE peer_identity_address_type, + uint8_t *peer_identity_address); + +/** + * @brief Add device to local resolving list. + * + * @param[in] peer_identity_address_type Peer identity address type. + * @param[in] peer_identity_address Peer identity address. + * @param[in] peer_irk Pointer to peer IRK (16 octets). + Note: + NULL: no peer IRK, use all-zero IRK. + * @param[in] use_local_irk Indicates whether local IRK has been distributed to peer device. + False: local IRK has not been distributed to peer device + True: local IRK has been distributed to peer device. + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_GAP_CAUSE le_privacy_add_resolv_list(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type, + uint8_t *peer_identity_address, uint8_t *peer_irk, bool use_local_irk); + +/** + * @brief Set privacy mode. + * @param[in] peer_identity_address_type Peer identity address type. + * @param[in] peer_identity_address Peer identity address. + * @param[in] privacy_mode Privacy mode @ref T_GAP_PRIVACY_MODE. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_SEND_REQ_FAILED Operation failure. + */ +T_GAP_CAUSE le_privacy_set_mode(T_GAP_IDENT_ADDR_TYPE peer_identity_address_type, + uint8_t *peer_identity_address, + T_GAP_PRIVACY_MODE privacy_mode); + +/** + * @brief Convert remote bluetooth device address type to identity address type. + * @param[in] type Bluetooth device address type @ref T_GAP_REMOTE_ADDR_TYPE. + * @return Identity address type @ref T_GAP_IDENT_ADDR_TYPE + * @retval GAP_IDENT_ADDR_PUBLIC Public identity address. + * @retval GAP_IDENT_ADDR_RAND Random identity address. + */ +T_GAP_IDENT_ADDR_TYPE le_privacy_convert_addr_type(T_GAP_REMOTE_ADDR_TYPE type); +#endif + +/** + * @brief Check if a given Resolvable Private Address (RPA) can be resolved using a specified Identity Resolving Key (IRK). + * + * This function determines if a provided Resolvable Private Address (RPA) associated with Bluetooth Low Energy (BLE) privacy + * mechanisms can be resolved using the specified Identity Resolving Key (IRK). It achieves this by utilizing encryption and + * comparison methods as defined in the Bluetooth specification for privacy address resolution. + * + * @param[in] rpa Pointer to a 6-byte Resolvable Private Address that needs to be resolved. This address is typically a random + * address generated for privacy protection during BLE operations. + * @param[in] irk Pointer to a 16-byte Identity Resolving Key used for resolving the Resolvable Private Address. + * + * @return Check result. + * @retval true The Resolvable Private Address matches the IRK and successfully resolves. This indicates that the provided RPA + * is associated with the given IRK and should be accepted as a legitimate identity. + * @retval false The Resolvable Private Address does not match the IRK and fails to resolve. This means that the RPA is either + * not associated with the given IRK or could not be resolved, indicating it is not recognized as a valid identity + * with the provided key. + */ +bool le_privacy_check_resolvable_private_address(uint8_t *rpa, uint8_t *irk); + +/** @} */ /* End of group Gap_Privacy_Exported_Functions */ +/** @} */ /* End of group GAP_PRIVACY_MODULE */ + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_PRIVACY_H */ diff --git a/inc/bluetooth/gap/gap_scan.h b/inc/bluetooth/gap/gap_scan.h new file mode 100644 index 0000000..8b22fc3 --- /dev/null +++ b/inc/bluetooth/gap/gap_scan.h @@ -0,0 +1,307 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_scan.h +* @brief Head file for Gap Observer role +* @details +* @author jane +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef GAP_SCAN_H +#define GAP_SCAN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#if F_BT_LE_GAP_SCAN_SUPPORT +#include "gap_le.h" + + +/** @defgroup Observer_Role GAP Observer Role + * @brief GAP observer role + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup Observer_Exported_Types GAP Observer Exported Types + * @{ + */ + +/** @brief LE scan parameter type */ +typedef enum +{ + GAP_PARAM_SCAN_LOCAL_ADDR_TYPE = 0x240, //!< The type of address being used in the scan request packets. Read/Write. + GAP_PARAM_SCAN_MODE = 0x241, //!< Scan mode. Read/Write. Size is uint8. Default is GAP_SCAN_MODE_ACTIVE (@ref T_GAP_SCAN_MODE). + GAP_PARAM_SCAN_INTERVAL = 0x242, //!< Scan Interval. Read/Write. Size is uint16_t. Default is 0x10. Value range: 0x0004 - 0x4000 (2.5ms - 10240ms 0.625ms/step). + GAP_PARAM_SCAN_WINDOW = 0x243, //!< Scan Window. Read/Write. Size is uint16_t. Default is 0x10. Value range: 0x0004 - 0x4000 (2.5ms - 10240ms 0.625ms/step). + GAP_PARAM_SCAN_FILTER_POLICY = 0x244, //!< Scan Filter Policy.Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_ANY (@ref T_GAP_SCAN_FILTER_POLICY). + GAP_PARAM_SCAN_FILTER_DUPLICATES = 0x245 //!< Scan Filter Duplicates.Read/Write. Size is uint8_t. Default is GAP_SCAN_FILTER_DUPLICATE_DISABLE (@ref T_GAP_SCAN_FILTER_DUPLICATE). +} T_LE_SCAN_PARAM_TYPE; + + +/** End of Observer_Exported_Types + * @} + */ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup Observer_Exported_Functions GAP Observer Exported Functions + * @{ + */ + +/** + * @brief Set a scan parameter. + * + * NOTE: You can call this function with a scan parameter type and it will set the + * scan parameter. Scan parameters are defined in @ref T_LE_SCAN_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must + * point to a data with type "uint16". + * + * @param[in] param Scan parameter type: @ref T_LE_SCAN_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type param is uint16, p_value will be cast to + * pointer of uint16_t). + * + * @return Set result + * @retval GAP_CAUSE_SUCCESS Set parameter success. + * @retval other Set parameter failed. + * + * Example usage + * \code{.c} + void app_le_gap_init() + { + uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BBPro_central"; + uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN; + + uint8_t scan_mode = GAP_SCAN_MODE_ACTIVE; + uint16_t scan_interval = DEFAULT_SCAN_INTERVAL; + uint16_t scan_window = DEFAULT_SCAN_WINDOW; + uint8_t scan_filter_policy = GAP_SCAN_FILTER_ANY; + uint8_t scan_filter_duplicate = GAP_SCAN_FILTER_DUPLICATE_ENABLE; + + uint8_t pair_mode = GAP_PAIRING_MODE_PAIRABLE; + uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG; + uint8_t io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT; + uint8_t oob_enable = false; + uint32_t passkey = 0; + uint8_t fix_passkey_enable = false; + + le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name); + le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance); + gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(uint8_t), &pair_mode); + gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(uint16_t), &auth_flags); + gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(uint8_t), &io_cap); + gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(uint8_t), &oob_enable); + + le_scan_set_param(GAP_PARAM_SCAN_MODE, sizeof(scan_mode), &scan_mode); + le_scan_set_param(GAP_PARAM_SCAN_INTERVAL, sizeof(scan_interval), &scan_interval); + le_scan_set_param(GAP_PARAM_SCAN_WINDOW, sizeof(scan_window), &scan_window); + le_scan_set_param(GAP_PARAM_SCAN_FILTER_POLICY, sizeof(scan_filter_policy), + &scan_filter_policy); + le_scan_set_param(GAP_PARAM_SCAN_FILTER_DUPLICATES, sizeof(scan_filter_duplicate), + &scan_filter_duplicate); + + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(uint32_t), &passkey); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(uint8_t), &fix_passkey_enable); + } + * \endcode + */ +T_GAP_CAUSE le_scan_set_param(T_LE_SCAN_PARAM_TYPE param, uint8_t len, void *p_value); + +/** + * @brief Get a scan parameter. + * + * NOTE: You can call this function with a scan parameter type and it will get a + * scan parameter. Scan parameters are defined in @ref T_LE_SCAN_PARAM_TYPE. + * Also, the "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param Scan parameter type: @ref T_LE_SCAN_PARAM_TYPE. + * @param[in,out] p_value Pointer to location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Get result + * @retval GAP_CAUSE_SUCCESS Get parameter success. + * @retval Others Get parameter failed. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t scan_interval; + le_scan_get_param(GAP_PARAM_SCAN_INTERVAL, &scan_interval); + } + * \endcode + */ +T_GAP_CAUSE le_scan_get_param(T_LE_SCAN_PARAM_TYPE param, void *p_value); + +/** + * @brief Start a device discovery scan. If device changes to scanning state, @ref app_handle_dev_state_evt + * will be called. And the advertising data or scan response data will be returned by @ref app_gap_callback + * with cb_type @ref GAP_MSG_LE_SCAN_INFO. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success, scan started. + * @retval GAP_CAUSE_ALREADY_IN_REQ: Operation failure, scan state is GAP_SCAN_STATE_START. + * @retval GAP_CAUSE_INVALID_STATE: Operation failure, invalid device state. + * + * Example usage + * \code{.c} + void test() + { + le_scan_start(); + } + + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x", + new_state.gap_init_state, + new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause); + + if (gap_dev_state.gap_scan_state != new_state.gap_scan_state) + { + if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE) + { + APP_PRINT_INFO0("GAP scan stop"); + data_uart_print("GAP scan stop\r\n"); + } + else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING) + { + APP_PRINT_INFO0("GAP scan start"); + data_uart_print("GAP scan start\r\n"); + } + } + } + //Received advertising or scan rsp data will be handled in app_gap_callback + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + case GAP_MSG_LE_SCAN_INFO: + APP_PRINT_INFO5("GAP_MSG_LE_SCAN_INFO:adv_type 0x%x, bd_addr %s, remote_addr_type %d, rssi %d, data_len %d", + cb_data.p_le_scan_info->adv_type, + TRACE_BDADDR(cb_data.p_le_scan_info->bd_addr), + cb_data.p_le_scan_info->remote_addr_type, + cb_data.p_le_scan_info->rssi, + cb_data.p_le_scan_info->data_len); + break; + } + } + * \endcode + */ +T_GAP_CAUSE le_scan_start(void); + +/** + * @brief Cancel a device discovery scan. + * + * NOTE: This function can be called after @ref gap_start_bt_stack is invoked. + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS: Operation success, Cancel started. + * @retval GAP_CAUSE_INVALID_STATE: Operation Failure. Invalid state, not in scan mode. + * + * Example usage + * \code{.c} + void test() + { + le_scan_stop(); + } + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO5("app_handle_dev_state_evt: init state = %d scan state = %d adv state = %d conn state = %d cause = 0x%x", + new_state.gap_init_state, + new_state.gap_scan_state, new_state.gap_adv_state, new_state.gap_conn_state, cause); + + if (gap_dev_state.gap_scan_state != new_state.gap_scan_state) + { + if (new_state.gap_scan_state == GAP_SCAN_STATE_IDLE) + { + APP_PRINT_INFO0("GAP scan stop"); + data_uart_print("GAP scan stop\r\n"); + } + else if (new_state.gap_scan_state == GAP_SCAN_STATE_SCANNING) + { + APP_PRINT_INFO0("GAP scan start"); + data_uart_print("GAP scan start\r\n"); + } + } + } + * \endcode + */ +T_GAP_CAUSE le_scan_stop(void); + +#if F_BT_LE_GAP_SCAN_FILTER_SUPPORT +/** + * @brief Set scan information filter. + * + * NOTE: This function can be called before @ref gap_start_bt_stack is invoked. + * + * @param[in] enable Whether to open the scan info comparison function. + * @param[in] offset The start offset of the scan info to compare. + * @param[in] len Length of data to compare + * @param[in] p_filter Point the data to compare with the scan info. + * @return bool. + * @retval TRUE Operation success. + * @retval FALSE Operation Failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_scanf(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t type = p_parse_value->dw_param[0]; + uint8_t offset = 0; + uint8_t len = 0; + uint8_t filter_data[31]; + if(type == 0) + { + le_scan_info_filter(false, offset, len, filter_data); + } + else + { + offset = 5; + len = 2; + filter_data[0] = LO_WORD(GATT_UUID_SIMPLE_PROFILE), + filter_data[1] = HI_WORD(GATT_UUID_SIMPLE_PROFILE); + le_scan_info_filter(true, offset, len, filter_data); + } + return RESULT_SUCESS; + } + * \endcode + */ +bool le_scan_info_filter(bool enable, uint8_t offset, uint8_t len, uint8_t *p_filter); +#endif +/** @} */ /* End of group Observer_Exported_Functions */ +/** @} */ /* End of group Observer_Role */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* GAP_SCAN_H */ diff --git a/inc/bluetooth/gap/gap_storage_le.h b/inc/bluetooth/gap/gap_storage_le.h new file mode 100644 index 0000000..ff14323 --- /dev/null +++ b/inc/bluetooth/gap/gap_storage_le.h @@ -0,0 +1,815 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file gap_storage_le.h +* @brief key storage function. +* @details +* @author jane +* @date 2016-02-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef FLASH_KEY_MGR_LE_H +#define FLASH_KEY_MGR_LE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#include "gap.h" +#include "gap_le_types.h" + +/** @defgroup GAP_LE_STORAGE GAP LE Storage + * @brief GAP LE Storage + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_LE_STORAGE_Exported_Macros GAP LE Storage Exported Macros + * @{ + */ + +/** @defgroup GAP_LE_STORAGE_BITS LE Key Storage Bits +* @{ + */ +#define LE_KEY_STORE_REMOTE_BD_BIT 0x01 +#define LE_KEY_STORE_LOCAL_LTK_BIT 0x02 +#define LE_KEY_STORE_REMOTE_LTK_BIT 0x04 +#define LE_KEY_STORE_REMOTE_IRK_BIT 0x08 +#define LE_KEY_STORE_LOCAL_CSRK_BIT 0x10 +#define LE_KEY_STORE_REMOTE_CSRK_BIT 0x20 +#define LE_KEY_STORE_CCCD_DATA_BIT 0x40 +#define LE_KEY_STORE_LOCAL_IRK_BIT 0x80 +#define LE_KEY_STORE_REMOTE_CLIENT_SUPPORTED_FEATURES_BIT 0x0100 +#define LE_KEY_STORE_REMOTE_SRV_CHANGE_AWARE_STATE_BIT 0x0200 +#define LE_KEY_STORE_LOCAL_BD_BIT 0x8000 +/** + * @} + */ + +/** End of GAP_LE_STORAGE_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_LE_STORAGE_Exported_Types GAP LE Storage Exported Types + * @{ + */ + +/** @brief Local Device Name */ +typedef struct +{ + uint8_t local_name[40]; +} T_LOCAL_NAME; + +/** @brief Local Device Appearance */ +typedef struct +{ + uint16_t local_appearance; + uint8_t padding[2]; +} T_LOCAL_APPEARANCE; + +/** @brief Local IRK */ +typedef struct +{ + uint8_t local_irk[16]; +} T_LOCAL_IRK; + +/** @brief Remote Bluetooth device address info */ +typedef struct +{ + uint8_t addr[6]; + uint8_t remote_bd_type; + uint8_t bond_flags; +} T_LE_REMOTE_BD; + +#if F_BT_LE_PRIVACY_SUPPORT +/** @brief LE privacy information */ +typedef struct +{ + bool is_discov; + bool central_addr_resolv; + bool resolv_addr_only; +} T_LE_PRIVACY_INFO; +#endif + +/** @brief LE CCCD info */ +typedef struct +{ + uint16_t handle; + uint16_t ccc_bits; +} T_LE_CCCD_ELEM; + +typedef struct +{ + uint8_t data_length; + uint8_t padding[3]; + uint8_t data[1]; +} T_LE_CCCD; + +/** @brief LE Key Type */ +typedef enum +{ + LE_KEY_UNAUTHEN = 0x04, /**< SSP generated link key without MITM protection. */ + LE_KEY_AUTHEN = 0x05, /**< SSP generated link key with MITM protection. */ + LE_KEY_UNAUTHEN_P256 = 0x07, /**< Security Connections generated link key without MITM protection. */ + LE_KEY_AUTHEN_P256 = 0x08, /**< Security Connections link key with MITM protection. */ +} T_LE_KEY_TYPE; + +/** @brief LE key entry */ +typedef struct +{ + bool is_used; + uint8_t idx; + uint16_t flags; + uint8_t local_bd_type; + uint8_t app_data; + uint8_t reserved[2]; + T_LE_REMOTE_BD remote_bd; + T_LE_REMOTE_BD resolved_remote_bd; + uint8_t local_bd_addr[6]; +} T_LE_KEY_ENTRY; + +typedef struct +{ + uint16_t flags; + T_LE_REMOTE_BD remote_bd; + uint8_t local_ltk[32]; + uint8_t remote_ltk[32]; + uint8_t remote_irk[24]; +} T_LE_DEV_INFO; + +typedef struct +{ + uint8_t link_key_length; + uint8_t padding[3]; + uint8_t key[28]; +} T_LE_LTK; + +/** End of GAP_LE_STORAGE_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @defgroup GAP_LE_STORAGE_EXPORT_Functions GAP LE Storage Exported Functions + * + * @{ + */ + +/** + * @brief Save local device name to flash. + * @param[in] p_data pointer to local device name + * @return Operation result. + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para; + APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id, + p_gap_data->msg_type); + if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + switch (p_gap_data->msg_data.opcode) + { + case GAPS_WRITE_DEVICE_NAME: + { + T_LOCAL_NAME device_name; + memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len); + device_name.local_name[p_gap_data->msg_data.len] = 0; + flash_save_local_name(&device_name); + } + break; + + case GAPS_WRITE_APPEARANCE: + { + uint16_t appearance_val; + T_LOCAL_APPEARANCE appearance; + + LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value); + appearance.local_appearance = appearance_val; + flash_save_local_appearance(&appearance); + } + break; + + default: + break; + } + } + else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION) + { + if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE) + { + APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE"); + } + } + return result; + } + * \endcode + */ +uint32_t flash_save_local_name(T_LOCAL_NAME *p_data); + +/** + * @brief Load local device name from flash. + * @param[in] p_data pointer to local device name + * @return Operation result. + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest"; + uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN; + uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE; + uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE; + T_LOCAL_APPEARANCE appearance_local; + T_LOCAL_NAME local_device_name; + if (flash_load_local_appearance(&appearance_local) == 0) + { + if (appearance_local.local_appearance != 0xffff) + { + appearance = appearance_local.local_appearance; + } + } + + if (flash_load_local_name(&local_device_name) == 0) + { + if (local_device_name.local_name[0] != 0xff) + { + memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN); + } + } + } + * \endcode + */ +uint32_t flash_load_local_name(T_LOCAL_NAME *p_data); + +/** + * @brief Save local device appearance to flash. + * @param[in] p_data Pointer to local device name + * @return Operation result + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para; + APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id, + p_gap_data->msg_type); + if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + switch (p_gap_data->msg_data.opcode) + { + case GAPS_WRITE_DEVICE_NAME: + { + T_LOCAL_NAME device_name; + memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len); + device_name.local_name[p_gap_data->msg_data.len] = 0; + flash_save_local_name(&device_name); + } + break; + + case GAPS_WRITE_APPEARANCE: + { + uint16_t appearance_val; + T_LOCAL_APPEARANCE appearance; + + LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value); + appearance.local_appearance = appearance_val; + flash_save_local_appearance(&appearance); + } + break; + + default: + break; + } + } + else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION) + { + if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE) + { + APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE"); + } + } + return result; + } + * \endcode + */ +uint32_t flash_save_local_appearance(T_LOCAL_APPEARANCE *p_data); + +/** + * @brief Load local device appearance from flash. + * @param[in] p_data Pointer to local device name + * @return Operation result + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest"; + uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN; + uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE; + uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE; + T_LOCAL_APPEARANCE appearance_local; + T_LOCAL_NAME local_device_name; + if (flash_load_local_appearance(&appearance_local) == 0) + { + if (appearance_local.local_appearance != 0xffff) + { + appearance = appearance_local.local_appearance; + } + } + + if (flash_load_local_name(&local_device_name) == 0) + { + if (local_device_name.local_name[0] != 0xff) + { + memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN); + } + } + } + * \endcode + */ +uint32_t flash_load_local_appearance(T_LOCAL_APPEARANCE *p_data); + +#if F_BT_LE_LOCAL_IRK_SETTING_SUPPORT +/** + * @brief Save local IRK to flash. + * @param[in] p_data Pointer to local device name + * @return Operation result + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_LOCAL_IRK irk = {0x01,0x02,0x03,}; + flash_save_local_irk(&irk); + } + * \endcode + */ +uint32_t flash_save_local_irk(T_LOCAL_IRK *p_data); + +/** + * @brief Load local IRK from flash. + * @param[in] p_data Pointer to local device name + * @return Operation result + * @retval 0 Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test() + { + T_LOCAL_IRK irk; + flash_load_local_irk(&irk); + } + * \endcode + */ +uint32_t flash_load_local_irk(T_LOCAL_IRK *p_data); +#endif + +/** + * @brief Find key entry by bluetooth device address and address type. + * + * @param[in] bd_addr Remote bluetooth device address. + * @param[in] bd_type Remote bluetooth device address type. + * @return p_entry Pointer to the found key entry. + * @retval null No entry found. + * @retval others Pointer to the found key entry. + */ +T_LE_KEY_ENTRY *le_find_key_entry(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type); + +/** + * @brief Find key entry by bluetooth device address and address type. + * + * @param[in] remote_bd_addr Remote bluetooth device address. + * @param[in] remote_bd_type Remote bluetooth device address type. + * @param[in] local_bd_addr Local bluetooth device address. + * @param[in] local_bd_type Local bluetooth device address type. + * @return p_entry Pointer to the found key entry. + * @retval null No entry found. + * @retval others Pointer to the found key entry. + */ +T_LE_KEY_ENTRY *le_find_key_entry_v2(uint8_t *remote_bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_bd_type, + uint8_t *local_bd_addr, uint8_t local_bd_type); + +/** + * @brief Find key entry by index. + * + * @param[in] idx Key entry index. + * @return p_entry Pointer to the found key entry. + * @retval null No entry found. + * @retval Others Pointer to the found key entry. + */ +T_LE_KEY_ENTRY *le_find_key_entry_by_idx(uint8_t idx); + +/** + * @brief Get the bonded device count. + * + * Note: You can call this function after @ref le_gap_init is invoked. + * + * @return num Bonded device count. + */ +uint8_t le_get_bond_dev_num(void); + +/** + * @brief Get the low priority bond device key entry. + * + * Note: You can call this function after @ref le_gap_init is invoked. + * + * @return p_entry Pointer to the found key entry. + * @retval null No entry found. + * @retval Others Pointer to the found key entry. + */ +T_LE_KEY_ENTRY *le_get_low_priority_bond(void); + +/** + * @brief Get the high priority bond device key entry. + * + * Note: You can call this function after @ref le_gap_init is invoked. + * + * @return p_entry Pointer to the found key entry. + * @retval null No entry found. + * @retval others Pointer to the found key entry. + */ +T_LE_KEY_ENTRY *le_get_high_priority_bond(void); + +/** + * @brief Make the specified bonded device with the high priority. + * + * NOTE: When the default value of @ref gap_config_local_addr_storage is true + * or @ref gap_config_local_addr_storage (true) has been configured, + * this function cannot be used if local device uses different local + * addresses to bond with the same remote device. In this situation, + * @ref le_set_high_priority_bond_v2 shall be called. + * + * @param[in] bd_addr Remote bluetooth device address. + * @param[in] bd_type Remote bluetooth device address type. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_set_high_priority_bond(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type); + +/** + * @brief Make the specified bonded device with the high priority. + * + * @param[in] p_entry Pointer the key entry of the bonded device. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_set_high_priority_bond_v2(T_LE_KEY_ENTRY *p_entry); + +/** + * @brief Resolve the specified bonded device. + * + * @param[in] unresolved_addr Unresolved remote bluetooth device address. + * @param[in,out] resolved_addr Resolved remote bluetooth device address. + * @param[in,out] resolved_addr_type Resolved remote bluetooth device address type. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t status) + { + APP_PRINT_INFO1("app_handle_authen_state_evt:conn_id %d", conn_id); + switch (new_state) + { + ... + case GAP_AUTHEN_STATE_COMPLETE: + { + APP_PRINT_INFO1("GAP_MSG_LE_AUTHEN_STATE_CHANGE:(GAP_AUTHEN_STATE_COMPLETE) status 0x%x", + status); + if (status == 0) + { + APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair success"); + { + uint8_t addr[6]; + T_GAP_REMOTE_ADDR_TYPE bd_type; + uint8_t resolved_addr[6]; + T_GAP_IDENT_ADDR_TYPE resolved_bd_type; + le_get_conn_addr(conn_id, addr, &bd_type); + if (bd_type == GAP_REMOTE_ADDR_LE_RANDOM) + { + if (le_resolve_random_address(addr, resolved_addr, &resolved_bd_type)) + { + APP_PRINT_INFO2("GAP_AUTHEN_STATE_COMPLETE: resolved_addr %s, resolved_addr_type %d", + TRACE_BDADDR(resolved_addr), resolved_bd_type); + } + else + { + APP_PRINT_INFO0("GAP_AUTHEN_STATE_COMPLETE: resolved addr failed"); + } + } + } + } + else + { + APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair failed"); + } + } + break; + ... + } + } + * \endcode + */ +bool le_resolve_random_address(uint8_t *unresolved_addr, uint8_t *resolved_addr, + T_GAP_IDENT_ADDR_TYPE *resolved_addr_type); + +/** + * @brief Get the cccd information of the bonded device. + * + * @param[in] p_entry Pointer the key entry of the bonded device. + * @param[out] p_data Pointer to ccccd data to read. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_REMOTE_ADDR_TYPE remote_addr_type; + uint8_t bd_addr[6]; + uint8_t conn_id = 0; + uint8_t ccc_bits_count = 16; + T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4); + T_LE_KEY_ENTRY *p_entry = NULL; + if(le_get_conn_addr(conn_id, bd_addr, &remote_addr_type)) + { + p_entry = le_find_key_entry(bd_addr, remote_addr_type); + if (p_entry) + { + if (le_get_cccd_data(p_entry, p_cccd_data)) + { + APP_PRINT_INFO2("Get cccd data: len %d, data %s", p_cccd_data->data_length, + TRACE_BINARY(p_cccd_data->data_length, p_cccd_data->data)); + } + } + } + os_mem_free(p_cccd_data); + } + * \endcode + */ +bool le_get_cccd_data(T_LE_KEY_ENTRY *p_entry, T_LE_CCCD *p_data); + +/** + * @brief Generate a new bonded device information by APP. + * + * NOTE: When the default value of @ref gap_config_local_addr_storage is true + * or @ref gap_config_local_addr_storage (true) has been configured, this + * function cannot be used. In this situation, @ref le_gen_bond_dev_v2 + * shall be called. + * + * @param[in] bd_addr Remote bluetooth device address. + * @param[in] bd_type Remote bluetooth device address type. + * @param[in] local_bd_type Local bluetooth device address type. + * @param[in] ltk_length LTK length. + * @param[in] p_ltk Pointer to LTK to write. + * @param[in] p_cccd Pointer to cccd data to write. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t bd_addr[6] = {0x11,0x22,0x33,0x44,0x55,0x66}; + uint8_t ltk_length = 16; + uint8_t ltk[16] = {0x0, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN; + uint8_t ccc_bits_count = 16; + T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4); + + p_cccd_data->data_length = 4; + p_cccd_data->data[0] = 0x04; + p_cccd_data->data[1] = 0x00; + p_cccd_data->data[2] = 0x02; + p_cccd_data->data[3] = 0x00; + + if(le_gen_bond_dev(bd_addr, remote_addr_type, GAP_LOCAL_ADDR_LE_PUBLIC, + ltk_length, ltk, key_type, p_cccd_data)) + { + APP_PRINT_INFO0("Generate bond device success"); + } + + os_mem_free(p_cccd_data); + } + * \endcode + */ +bool le_gen_bond_dev(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type, + T_GAP_LOCAL_ADDR_TYPE local_bd_type, + uint8_t ltk_length, uint8_t *p_ltk, T_LE_KEY_TYPE key_type, T_LE_CCCD *p_cccd); + +/** + * @brief Generate a new bonded device information by APP. + * + * @param[in] remote_bd_addr Remote bluetooth device address. + * @param[in] remote_bd_type Remote bluetooth device address type. + * @param[in] local_bd_addr Local bluetooth device address. + * @param[in] local_bd_type Local bluetooth device address type. + * @param[in] ltk_length LTK length. + * @param[in] p_ltk Pointer to LTK to write. + * @param[in] p_cccd Pointer to cccd data to write. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t remote_bd_addr[6] = {0x11,0x22,0x33,0x44,0x55,0x66}; + uint8_t local_bd_addr[6] = {0x00,0x22,0x33,0x44,0x55,0x66}; + uint8_t ltk_length = 16; + uint8_t ltk[16] = {0x0, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN; + uint8_t ccc_bits_count = 16; + T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4); + + p_cccd_data->data_length = 4; + p_cccd_data->data[0] = 0x04; + p_cccd_data->data[1] = 0x00; + p_cccd_data->data[2] = 0x02; + p_cccd_data->data[3] = 0x00; + + if(le_gen_bond_dev_v2(remote_bd_addr, remote_addr_type, local_bd_addr, GAP_LOCAL_ADDR_LE_PUBLIC, + ltk_length, ltk, key_type, p_cccd_data)) + { + APP_PRINT_INFO0("Generate bond device success"); + } + + os_mem_free(p_cccd_data); + } + * \endcode + */ +bool le_gen_bond_dev_v2(uint8_t *remote_bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_bd_type, + uint8_t *local_bd_addr, T_GAP_LOCAL_ADDR_TYPE local_bd_type, uint8_t ltk_length, + uint8_t *p_ltk, T_LE_KEY_TYPE key_type, T_LE_CCCD *p_cccd); + +#if F_BT_LE_PRIVACY_SUPPORT +/** + * @brief Save privacy information. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[in] p_privacy_info Pointer to privacy information to write. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_set_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info); + +/** + * @brief Get privacy information. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[out] p_privacy_info Pointer to privacy information to read. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_get_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info); + +/** + * @brief Check the bonded device whether it is a privacy device. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @return Operation result. + * @retval true This bonded device is a privacy device. + * @retval false This bonded device is not a privacy device. + */ +bool le_check_privacy_bond(T_LE_KEY_ENTRY *p_entry); +#endif + +/** + * @brief Get length of device bond information. + * + * @return Length of device bond information. + */ +uint16_t le_get_dev_bond_info_len(void); + +/** + * @brief Get device bond information. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[in] p_data Pointer to bond information to read. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_get_dev_bond_info(T_LE_KEY_ENTRY *p_entry, uint8_t *p_data); + +/** + * @brief Set device bond information. + * + * @param[in] length Length of device bond information. + * @param[in] p_data Pointer to bond information to write. + * @param[in,out] exist Indicate whether bond information of the device is existed. + * @return p_entry Pointer to the key entry. + * @retval null No entry, operation failure. + * @retval others Pointer to the key entry. If parameter exist is false, operation success. If parameter exist is true, bond information of the device is existed. + */ +T_LE_KEY_ENTRY *le_set_dev_bond_info(uint16_t length, uint8_t *p_data, bool *exist); + +/** + * @brief Get maximum pairing information number that can be stored. + * + * NOTE: This function can be called after @ref le_gap_init is invoked. + * + * @return Maximum number of LE paired device information that can be stored. + */ +uint8_t le_get_max_le_paired_device_num(void); + +/** + * @brief Get device information. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[out] p_data Pointer to bond information to read. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_get_dev_info(T_LE_KEY_ENTRY *p_entry, T_LE_DEV_INFO *p_info); + +/** + * @brief Modify local LTK. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[in] key_length key length, Range: 7 to 16. + * @param[in] p_ltk Pointer to local ltk to save. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_set_local_ltk(T_LE_KEY_ENTRY *p_entry, uint8_t key_length, uint8_t *p_ltk); + +/** + * @brief Erase CCCD except specific attribute handle. + * + * NOTE: This function can only be used for standby state (i.e., no link, not initiating, etc.). + * + * @param[in] handle_num Number of attribute handle of CCCD which will not be erased + * @param[in] p_handle Pointer to attribute handle of CCCD which will not be erased + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_clear_cccd_data(uint16_t handle_num, uint16_t *p_handle); + +/** + * @brief Get remote device IRK information. + * + * @param[in] p_entry Pointer to the key entry of bonded device. + * @param[in] remote Read the remote IRK or the local IRK. + * @param[out] p_irk Pointer to IRK to read. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool le_get_dev_irk(T_LE_KEY_ENTRY *p_entry, bool remote, uint8_t *p_irk); + +/** @} */ /* End of group GAP_LE_STORAGE_EXPORT_Functions */ +/** @} */ /* End of group GAP_LE_STORAGE */ + + +#ifdef __cplusplus +} +#endif + +#endif /* FLASH_KEY_MGR_LE_H */ diff --git a/inc/bluetooth/leaudio/bap.h b/inc/bluetooth/leaudio/bap.h new file mode 100644 index 0000000..5bfe78b --- /dev/null +++ b/inc/bluetooth/leaudio/bap.h @@ -0,0 +1,127 @@ +#ifndef _BAP_H_ +#define _BAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ble_audio_def.h" +#include "pacs_client.h" +#include "codec_qos.h" +//#include "ascs_def.h" + +#define BAP_BROADCAST_SOURCE_ROLE 0x01 +#define BAP_BROADCAST_SINK_ROLE 0x02 +#define BAP_BROADCAST_ASSISTANT_ROLE 0x04 +#define BAP_SCAN_DELEGATOR_ROLE 0x08 +#define BAP_UNICAST_CLT_SRC_ROLE 0x10 +#define BAP_UNICAST_CLT_SNK_ROLE 0x20 +#define BAP_UNICAST_SRV_SRC_ROLE 0x40 +#define BAP_UNICAST_SRV_SNK_ROLE 0x80 + +typedef struct +{ + uint8_t role_mask; + uint8_t brs_num; //use isoc_big_receiver_num + + uint8_t snk_ase_num; + uint8_t src_ase_num; + + bool init_gap; +//for BAP_UNICAST_CLT_SRC_ROLE, BAP_UNICAST_CLT_SNK_ROLE + uint8_t isoc_cig_max_num; + +//for BAP_UNICAST_CLT_SRC_ROLE, BAP_UNICAST_CLT_SNK_ROLE, BAP_UNICAST_SRV_SRC_ROLE, BAP_UNICAST_SRV_SNK_ROLE + uint8_t isoc_cis_max_num; + +//for BAP_BROADCAST_SOURCE_ROLE + uint8_t pa_adv_num; + uint8_t isoc_big_broadcaster_num; + uint8_t isoc_bis_broadcaster_num; + +//for BAP_BROADCAST_SINK_ROLE and BAP_BROADCAST_ASSISTANT_ROLE + uint8_t pa_sync_num; + uint8_t isoc_big_receiver_num; + uint8_t isoc_bis_receiver_num; +} T_BAP_ROLE_INFO; + +#if LE_AUDIO_PACS_CLIENT_SUPPORT +#define PACS_AUDIO_AVAILABLE_CONTEXTS_EXIST 0x01 +#define PACS_AUDIO_SUPPORTED_CONTEXTS_EXIST 0x02 +#define PACS_SINK_AUDIO_LOC_EXIST 0x04 +#define PACS_SINK_PAC_EXIST 0x08 +#define PACS_SOURCE_AUDIO_LOC_EXIST 0x10 +#define PACS_SOURCE_PAC_EXIST 0x20 + +typedef struct +{ + uint16_t value_exist; + uint8_t sink_pac_num; + uint8_t source_pac_num; + uint32_t snk_audio_loc; + uint32_t src_audio_loc; + uint16_t snk_sup_context; + uint16_t src_sup_context; + uint16_t snk_avail_context; + uint16_t src_avail_context; +} T_BAP_PACS_INFO; + +typedef struct +{ + uint8_t codec_id[CODEC_ID_LEN]; + uint16_t handle; + uint16_t pref_audio_contexts; + T_CODEC_CAP codec_cap; + uint32_t lc3_sup_cfg_bits; +} T_BAP_PAC_RECORD; + +//LE_AUDIO_MSG_BAP_PACS_DIS_DONE +typedef struct +{ + uint16_t conn_handle; + bool is_found; + uint8_t sink_pac_num; + uint8_t source_pac_num; +} T_BAP_PACS_DIS_DONE; + +//LE_AUDIO_MSG_BAP_PAC_NOTIFY +typedef struct +{ + uint16_t conn_handle; + uint16_t handle; +} T_BAP_PAC_NOTIFY; + +bool bap_pacs_get_info(uint16_t conn_handle, T_BAP_PACS_INFO *p_pacs_info); +bool bap_pacs_get_pac_record(uint16_t conn_handle, T_AUDIO_DIRECTION direction, uint8_t *p_pac_num, + T_BAP_PAC_RECORD *p_pac_tbl); +bool bap_pacs_get_pac_record_by_handle(uint16_t conn_handle, uint16_t handle, uint8_t *p_pac_num, + T_BAP_PAC_RECORD *p_pac_tbl); +uint32_t bap_pacs_get_lc3_snk_table_msk(uint16_t conn_handle, uint16_t prefer_context, + uint8_t chl_cnt, + uint8_t block_num); +uint32_t bap_pacs_get_lc3_src_table_msk(uint16_t conn_handle, uint16_t prefer_context, + uint8_t chl_cnt, + uint8_t block_num); +#endif + +#if LE_AUDIO_ASCS_CLIENT_SUPPORT +#define ASE_ID_MAX_NUM 8 +//LE_AUDIO_MSG_BAP_ASCS_DIS_DONE +typedef struct +{ + uint16_t conn_handle; + bool is_found; + uint8_t sink_ase_num; + uint8_t sink_ase_id[ASE_ID_MAX_NUM]; + uint8_t source_ase_num; + uint8_t source_ase_id[ASE_ID_MAX_NUM]; +} T_BAP_ASCS_DIS_DONE; +#endif + +bool bap_role_init(T_BAP_ROLE_INFO *p_role_info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/base_data_parse.h b/inc/bluetooth/leaudio/base_data_parse.h new file mode 100644 index 0000000..2d1842c --- /dev/null +++ b/inc/bluetooth/leaudio/base_data_parse.h @@ -0,0 +1,53 @@ +#ifndef _BASE_DATA_PARSE_H_ +#define _BASE_DATA_PARSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "codec_def.h" + +#if LE_AUDIO_BASE_DATA_PARSE + +typedef struct +{ + uint8_t subgroup_idx; + uint8_t bis_index; + uint8_t codec_id[CODEC_ID_LEN]; + T_CODEC_CFG bis_codec_cfg; +} T_BASE_DATA_BIS_PARAM; + +typedef struct +{ + uint8_t subgroup_idx; + uint8_t num_bis; + uint8_t metadata_len; + uint32_t bis_array; + uint8_t *p_metadata; + T_BASE_DATA_BIS_PARAM *p_bis_param; +} T_BASE_DATA_SUBGROUP_PARAM; + +typedef struct +{ + uint8_t num_bis; + uint8_t num_subgroups; + uint32_t presentation_delay; + //Level2 param + T_BASE_DATA_SUBGROUP_PARAM *p_subgroup; +} T_BASE_DATA_MAPPING; + +void base_data_print(T_BASE_DATA_MAPPING *p_mapping); +T_BASE_DATA_MAPPING *base_data_parse_data(uint16_t pa_data_len, uint8_t *p_pa_data); +bool base_data_cmp(T_BASE_DATA_MAPPING *p_mapping_a, T_BASE_DATA_MAPPING *p_mapping_b); +bool base_data_get_bis_codec_cfg(T_BASE_DATA_MAPPING *p_mapping, uint8_t bis_idx, + T_CODEC_CFG *p_cfg); +void base_data_free(T_BASE_DATA_MAPPING *p_mapping); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/bass_client.h b/inc/bluetooth/leaudio/bass_client.h new file mode 100644 index 0000000..4a7c397 --- /dev/null +++ b/inc/bluetooth/leaudio/bass_client.h @@ -0,0 +1,80 @@ +#ifndef _BASS_CLIENT_H_ +#define _BASS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "bass_def.h" +#include "ble_audio_sync.h" +//#include "broadcast_source_sm.h" + +#if LE_AUDIO_BASS_CLIENT_SUPPORT +//LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE +typedef struct +{ + uint16_t conn_handle; + bool is_found; + bool load_form_ftl; + uint8_t brs_char_num; +} T_BASS_CLIENT_DIS_DONE; + +//LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA +typedef struct +{ + uint16_t conn_handle; + bool notify; + uint16_t read_cause; + uint8_t instance_id; + T_BASS_BRS_DATA *p_brs_data; +} T_BASS_CLIENT_BRS_DATA; + +//LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ +typedef struct +{ + uint16_t conn_handle; + uint8_t instance_id; + T_BASS_BRS_DATA *p_brs_data; +} T_BASS_CLIENT_SYNC_INFO_REQ; + +//LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT +typedef struct +{ + uint16_t conn_handle; + uint16_t cause; +} T_BASS_CLIENT_CP_RESULT; + +//LE_AUDIO_MSG_BASS_CLIENT_CCCD +typedef struct +{ + uint16_t conn_handle; + uint16_t cause; +} T_BASS_CLIENT_CCCD; + +bool bass_enable_cccd(uint16_t conn_handle); +bool bass_read_brs_value(uint16_t conn_handle, uint8_t instance_id); + +bool bass_cp_remote_scan_stop(uint16_t conn_handle, bool is_req); +bool bass_cp_remote_scan_start(uint16_t conn_handle, bool is_req); +bool bass_cp_add_source(uint16_t conn_handle, T_BASS_CP_ADD_SOURCE *p_cp_data, bool is_req); +bool bass_cp_modify_source(uint16_t conn_handle, T_BASS_CP_MODIFY_SOURCE *p_cp_data, bool is_req); +bool bass_cp_set_broadcast_code(uint16_t conn_handle, T_BASS_CP_SET_BROADCAST_CODE *p_cp_data, + bool is_req); +bool bass_cp_remove_source(uint16_t conn_handle, T_BASS_CP_REMOVE_SOURCE *p_cp_data, bool is_req); +T_BASS_BRS_DATA *bass_get_brs_data(uint16_t conn_handle, uint8_t instance_id); + +bool bass_cp_add_source_by_sync_info(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle, + T_BASS_PA_SYNC pa_sync, uint32_t bis_array, bool is_req); +bool bass_cp_modify_source_by_sync_info(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle, + uint8_t source_id, + T_BASS_PA_SYNC pa_sync, uint32_t bis_array, bool is_req); + +bool bass_transfer_syncinfo_of_remote_src(T_BLE_AUDIO_SYNC_HANDLE handle, uint16_t conn_handle, + T_BASS_PAST_SRV_DATA srv_data); + +#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/bass_def.h b/inc/bluetooth/leaudio/bass_def.h new file mode 100644 index 0000000..047ba88 --- /dev/null +++ b/inc/bluetooth/leaudio/bass_def.h @@ -0,0 +1,154 @@ +#ifndef _BASS_DEF_H_ +#define _BASS_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "gap.h" +#include "metadata_def.h" +#include "ble_audio_def.h" + +#define ATT_ERR_BASS_OPCODE_NOT_SUPPORT 0x80 +#define ATT_ERR_BASS_INVALID_SRC_ID 0x81 + +#define BASS_FAILED_TO_SYNC_TO_BIG 0xFFFFFFFF +#define BASS_CP_BIS_SYNC_NO_PREFER 0xFFFFFFFF +#define BASS_PA_INTERVAL_UNKNOWN 0xFFFF + +#define BASS_BRS_DATA_MIN_LEN 15 +// BASS CP minimum possible total length +#define BASS_CP_OP_MIN_LEN 1 +#define BASS_CP_OP_REMOTE_SCAN_STOP_LEN 1 +#define BASS_CP_OP_REMOTE_SCAN_START_LEN 1 +#define BASS_CP_OP_ADD_SOURCE_MIN_LEN 16 +#define BASS_CP_OP_MODIFY_SOURCE_MIN_LEN 6 +#define BASS_CP_OP_SET_BROADCAST_CODE_LEN 18 +#define BASS_CP_OP_REMOVE_SOURCE_LEN 2 + +#define BASS_BRA_INC_BST_CODE_LEN 31 + +#define BASS_BRS_CHAR_MAX_NUM 4 +#define GATT_UUID_BASS 0x184F +#define BASS_UUID_CHAR_BROADCAST_AUDIO_SCAN_CP 0x2BC7 +#define BASS_UUID_CHAR_BROADCAST_RECEIVE_STATE 0x2BC8 + +typedef enum +{ + PA_SYNC_STATE_NOT_SYNC = 0x00, + PA_SYNC_STATE_SYNCINFO_REQ = 0x01, + PA_SYNC_STATE_SYNC = 0x02, + PA_SYNC_STATE_FAILED = 0x03, + PA_SYNC_STATE_NO_PAST = 0x04, +} T_PA_SYNC_STATE; + +typedef enum +{ + BIG_NOT_ENCRYPTED = 0x00, + BIG_BROADCAST_CODE_REQUIRED = 0x01, + BIG_DECRYPTING = 0x02, + BIG_BAD_CODE = 0x03, +} T_BIG_ENCRYPTION_STATE; + +typedef enum +{ + BASS_CP_OP_REMOTE_SCAN_STOP = 0x00, + BASS_CP_OP_REMOTE_SCAN_START = 0x01, + BASS_CP_OP_ADD_SOURCE = 0x02, + BASS_CP_OP_MODIFY_SOURCE = 0x03, + BASS_CP_OP_SET_BROADCAST_CODE = 0x04, + BASS_CP_OP_REMOVE_SOURCE = 0x05, +} T_BASS_CP_OP; + +typedef enum +{ + BASS_PA_NOT_SYNC = 0x00, + BASS_PA_SYNC_PAST = 0x01, + BASS_PA_SYNC_NO_PAST = 0x02, +} T_BASS_PA_SYNC; + +typedef struct +{ + uint8_t adv_a_match_ext_adv; //AdvA in PAST matches AdvA in ADB_EXT_IND, 0b0=Yes, 0b1=No/Do't know + uint8_t adv_a_match_src;//AdvA in PAST matches Source_Address, 0b0=Yes, 0b1=No/Do't know + uint8_t source_id; +} T_BASS_PAST_SRV_DATA; + +typedef struct +{ + uint32_t bis_sync; + uint8_t metadata_len; + uint8_t *p_metadata; +} T_BASS_CP_BIS_INFO; + +typedef struct +{ + bool brs_is_used; + //Broadcast Receive State Field + uint8_t source_id; + uint8_t source_address_type; + uint8_t source_address[GAP_BD_ADDR_LEN]; + uint8_t source_adv_sid; + uint8_t broadcast_id[BROADCAST_ID_LEN]; + T_PA_SYNC_STATE pa_sync_state; + uint32_t bis_sync_state; + T_BIG_ENCRYPTION_STATE big_encryption; + uint8_t bad_code[BROADCAST_CODE_LEN]; + uint8_t num_subgroups; + uint16_t bis_info_size; + T_BASS_CP_BIS_INFO *p_cp_bis_info; +} T_BASS_BRS_DATA; + +typedef struct +{ + uint8_t advertiser_address_type; + uint8_t advertiser_address[GAP_BD_ADDR_LEN]; + uint8_t advertiser_sid; + uint8_t broadcast_id[BROADCAST_ID_LEN]; + T_BASS_PA_SYNC pa_sync; + uint16_t pa_interval; + uint8_t num_subgroups; + uint16_t bis_info_size; + T_BASS_CP_BIS_INFO *p_cp_bis_info; +} T_BASS_CP_ADD_SOURCE; + +typedef struct +{ + uint8_t source_id; + T_BASS_PA_SYNC pa_sync; + uint16_t pa_interval; + uint8_t num_subgroups; + uint16_t bis_info_size; + T_BASS_CP_BIS_INFO *p_cp_bis_info; +} T_BASS_CP_MODIFY_SOURCE; + +typedef struct +{ + uint8_t source_id; + uint8_t broadcast_code[BROADCAST_CODE_LEN]; +} T_BASS_CP_SET_BROADCAST_CODE; + +typedef struct +{ + uint8_t source_id; +} T_BASS_CP_REMOVE_SOURCE; + +typedef union +{ + T_BASS_CP_ADD_SOURCE add_source; + T_BASS_CP_MODIFY_SOURCE modify_source; + T_BASS_CP_SET_BROADCAST_CODE set_broadcast_code; + T_BASS_CP_REMOVE_SOURCE remove_source; +} T_BASS_CP_PARAM; + +typedef struct +{ + T_BASS_CP_OP opcode; + T_BASS_CP_PARAM param; +} T_BASS_CP_DATA; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/ble_audio.h b/inc/bluetooth/leaudio/ble_audio.h new file mode 100644 index 0000000..9ac02d3 --- /dev/null +++ b/inc/bluetooth/leaudio/ble_audio.h @@ -0,0 +1,85 @@ +#ifndef _BLE_AUDIO_H_ +#define _BLE_AUDIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "gap_msg.h" +#include "gap.h" +#include "app_msg.h" +//#include "profile_server_def.h" + +typedef enum +{ + LE_AUDIO_MSG_GROUP_BASS = 0x0000, + LE_AUDIO_MSG_GROUP_BASS_CLIENT = 0x0100, + LE_AUDIO_MSG_GROUP_PACS = 0x0200, + LE_AUDIO_MSG_GROUP_PACS_CLIENT = 0x0300, + LE_AUDIO_MSG_GROUP_CSIS = 0x0400, + LE_AUDIO_MSG_GROUP_CSIS_CLIENT = 0x0500, + + LE_AUDIO_MSG_GROUP_CAP = 0x2000, + LE_AUDIO_MSG_GROUP_BAP = 0x2100, +} T_LE_AUDIO_MSG_GROUP; + +typedef enum +{ + //bass_client.h + LE_AUDIO_MSG_BASS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x00, + LE_AUDIO_MSG_BASS_CLIENT_CCCD = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x01, + LE_AUDIO_MSG_BASS_CLIENT_CP_RESULT = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x02, + LE_AUDIO_MSG_BASS_CLIENT_BRS_DATA = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x03, + LE_AUDIO_MSG_BASS_CLIENT_SYNC_INFO_REQ = LE_AUDIO_MSG_GROUP_BASS_CLIENT | 0x04, + + //pacs_client.h + LE_AUDIO_MSG_PACS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x00, + LE_AUDIO_MSG_PACS_CLIENT_CCCD = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x01, + LE_AUDIO_MSG_PACS_CLIENT_WRITE_SINK_LOC_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x02, + LE_AUDIO_MSG_PACS_CLIENT_WRITE_SOURCE_LOC_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x03, + LE_AUDIO_MSG_PACS_CLIENT_READ_RESULT = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x04, + LE_AUDIO_MSG_PACS_CLIENT_NOTIFY = LE_AUDIO_MSG_GROUP_PACS_CLIENT | 0x05, + + //csis_client.h + LE_AUDIO_MSG_CSIS_CLIENT_DIS_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x00, + LE_AUDIO_MSG_CSIS_CLIENT_SEARCH_TIMEOUT = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x01, + LE_AUDIO_MSG_CSIS_CLIENT_SEARCH_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x02, + LE_AUDIO_MSG_CSIS_CLIENT_SET_MEM_FOUND = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x04, + LE_AUDIO_MSG_CSIS_CLIENT_COOR_SET_DEL = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x05, + LE_AUDIO_MSG_CSIS_CLIENT_LOCK_REQ_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x06, + LE_AUDIO_MSG_CSIS_CLIENT_UNLOCK_REQ_DONE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x07, + LE_AUDIO_MSG_CSIS_CLIENT_LOCK_STATE_CHANGE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x08, + LE_AUDIO_MSG_CSIS_CLIENT_READ_RESULT = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x09, + LE_AUDIO_MSG_CSIS_CLIENT_SIRK_CHANGE = LE_AUDIO_MSG_GROUP_CSIS_CLIENT | 0x0a, + + //bap.h + LE_AUDIO_MSG_BAP_PACS_DIS_DONE = LE_AUDIO_MSG_GROUP_BAP | 0x00, + LE_AUDIO_MSG_BAP_PAC_NOTIFY = LE_AUDIO_MSG_GROUP_BAP | 0x01, + LE_AUDIO_MSG_BAP_ASCS_DIS_DONE = LE_AUDIO_MSG_GROUP_BAP | 0x02, + + //cap.h + LE_AUDIO_MSG_CAP_DIS_DONE = LE_AUDIO_MSG_GROUP_CAP | 0x00, +} T_LE_AUDIO_MSG; + +typedef T_APP_RESULT(*P_FUN_BLE_AUDIO_CB)(T_LE_AUDIO_MSG msg, void *buf); + +typedef struct +{ + P_FUN_BLE_AUDIO_CB p_fun_cb; + void *evt_queue_handle; + void *io_queue_handle; +} T_BLE_AUDIO_PARAMS; + +bool ble_audio_init(T_BLE_AUDIO_PARAMS *p_param); +bool ble_audio_check_remote_features(uint16_t conn_handle, uint8_t array_index, + uint8_t feature_mask); + +void ble_audio_handle_msg(T_IO_MSG *p_io_msg); +void ble_audio_handle_gap_msg(uint16_t subtype, T_LE_GAP_MSG gap_msg); +void ble_audio_handle_gap_cb(uint8_t cb_type, void *p_cb_data); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/ble_audio_def.h b/inc/bluetooth/leaudio/ble_audio_def.h new file mode 100644 index 0000000..7360f1a --- /dev/null +++ b/inc/bluetooth/leaudio/ble_audio_def.h @@ -0,0 +1,80 @@ +#ifndef _BLE_AUDIO_DEF_H_ +#define _BLE_AUDIO_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +#define BROADCAST_ID_LEN 3 +#define BROADCAST_CODE_LEN 16 + +#define BROADCAST_AUDIO_ANNOUNCEMENT_SRV_UUID 0x1852 +#define BASIC_AUDIO_ANNOUNCEMENT_SRV_UUID 0x1851 + +#define AUDIO_DEFAULT_PRESENTATION_DELAY 40000 + +#define ADV_TARGETED_ANNOUNCEMENT 0x01 +#define ADV_GENERAL_ANNOUNCEMENT 0x00 + +#define AUDIO_LOCATION_MONO 0x00000000 +#define AUDIO_LOCATION_FL 0x00000001 +#define AUDIO_LOCATION_FR 0x00000002 +#define AUDIO_LOCATION_FC 0x00000004 +#define AUDIO_LOCATION_LFE1 0x00000008 +#define AUDIO_LOCATION_BL 0x00000010 +#define AUDIO_LOCATION_BR 0x00000020 +#define AUDIO_LOCATION_FLC 0x00000040 +#define AUDIO_LOCATION_FRC 0x00000080 +#define AUDIO_LOCATION_BC 0x00000100 +#define AUDIO_LOCATION_LFE2 0x00000200 +#define AUDIO_LOCATION_SIL 0x00000400 +#define AUDIO_LOCATION_SIR 0x00000800 +#define AUDIO_LOCATION_TPFL 0x00001000 +#define AUDIO_LOCATION_TPFR 0x00002000 +#define AUDIO_LOCATION_TPFC 0x00004000 +#define AUDIO_LOCATION_TPC 0x00008000 +#define AUDIO_LOCATION_TPBL 0x00010000 +#define AUDIO_LOCATION_TPBR 0x00020000 +#define AUDIO_LOCATION_TPSIL 0x00040000 +#define AUDIO_LOCATION_TPSIR 0x00080000 +#define AUDIO_LOCATION_TPBC 0x00100000 +#define AUDIO_LOCATION_BTFC 0x00200000 +#define AUDIO_LOCATION_BTFL 0x00400000 +#define AUDIO_LOCATION_BTFR 0x00800000 +#define AUDIO_LOCATION_FLW 0x01000000 +#define AUDIO_LOCATION_FRW 0x02000000 +#define AUDIO_LOCATION_LS 0x04000000 +#define AUDIO_LOCATION_RS 0x08000000 +#define AUDIO_LOCATION_RFU 0xF0000000 +#define AUDIO_LOCATION_MASK 0x0FFFFFFF + +typedef enum +{ + AUDIO_UNFRAMED = 0x00, + AUDIO_FRAMED = 0x01, +} T_AUDIO_FRAMING; + +typedef enum +{ + SERVER_AUDIO_SINK = 0x01, + SERVER_AUDIO_SOURCE = 0x02, +} T_AUDIO_DIRECTION; + +typedef enum +{ + UNSPEC_AUDIO_INPUT = 0x00, + BLUETOOTH_AUDIO_INPUT = 0x01, + MICROPHONE_AUDIO_INTPUT = 0x02, + ANLOG_AUDIO_INTPUT = 0x03, + DIGITAL_AUDIO_INTPUT = 0x04, + RADIO_AUDIO_INTPUT = 0x05, + STREAMING_AUDIO_INTPUT = 0x06, +} T_AUDIO_INPUT_TYPE; +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/ble_audio_flags.h b/inc/bluetooth/leaudio/ble_audio_flags.h new file mode 100644 index 0000000..9e419e2 --- /dev/null +++ b/inc/bluetooth/leaudio/ble_audio_flags.h @@ -0,0 +1,56 @@ +#ifndef _BLE_AUDIO_FLAGS_H_ +#define _BLE_AUDIO_FLAGS_H_ + +#define LE_AUDIO_DEBUG 1 + +#define MAX_BLE_LINK_NUM 2 +#define MAX_BLE_SRV_NUM 16 + +#define LE_AUDIO_PACS_SUPPORT 0 +#define LE_AUDIO_ASCS_SUPPORT 0 +#define LE_AUDIO_BASS_SUPPORT 0 + +#define LE_AUDIO_VCS_SUPPORT 0 +#define LE_AUDIO_VOCS_SUPPORT 0 +#define LE_AUDIO_AICS_SUPPORT 0 +#define LE_AUDIO_AICS_NUM 0 +#define LE_AUDIO_MICS_SUPPORT 0 + +#define LE_AUDIO_CSIS_SUPPORT 0 +#define LE_AUDIO_CAS_SUPPORT 0 + +#define LE_AUDIO_TBS_SUPPORT 0 +#define LE_AUDIO_TMAS_SUPPORT 0 +#define LE_AUDIO_HAS_SUPPORT 0 + +#define LE_AUDIO_MCS_SERV_SUPPORT 0 +#define LE_AUDIO_OTS_SERV_SUPPORT 0 + +#define LE_AUDIO_CAP_SUPPORT 0 +#define LE_AUDIO_BAP_SUPPORT 1 + +#define LE_AUDIO_PACS_CLIENT_SUPPORT 1 +#define LE_AUDIO_ASCS_CLIENT_SUPPORT 0 +#define LE_AUDIO_BASS_CLIENT_SUPPORT 1 +#define LE_AUDIO_MCS_CLIENT_SUPPORT 0 +#define LE_AUDIO_OTS_CLIENT_SUPPORT 0 + +#define LE_AUDIO_VCS_CLIENT_SUPPORT 0 +#define LE_AUDIO_VOCS_CLIENT_SUPPORT 0 +#define LE_AUDIO_AICS_CLIENT_SUPPORT 0 +#define LE_AUDIO_MICS_CLIENT_SUPPORT 0 + +#define LE_AUDIO_CSIS_CLIENT_SUPPORT 0 +#define LE_AUDIO_TBS_CLIENT_SUPPORT 0 +#define LE_AUDIO_TMAP_CLIENT_SUPPORT 0 +#define LE_AUDIO_HAS_CLIENT_SUPPORT 0 + +#define LE_AUDIO_BROADCAST_SOURCE_ROLE 0 +#define LE_AUDIO_BROADCAST_SINK_ROLE 0 +#define LE_AUDIO_SCAN_DELEGATOR_ROLE 0 +#define LE_AUDIO_BROADCAST_ASSISTANT_ROLE 1 + +#define LE_AUDIO_BASE_DATA_GENERATE (LE_AUDIO_BROADCAST_SOURCE_ROLE) +#define LE_AUDIO_BASE_DATA_PARSE (LE_AUDIO_BROADCAST_SINK_ROLE || LE_AUDIO_BROADCAST_ASSISTANT_ROLE) + +#endif diff --git a/inc/bluetooth/leaudio/ble_audio_group.h b/inc/bluetooth/leaudio/ble_audio_group.h new file mode 100644 index 0000000..67c0125 --- /dev/null +++ b/inc/bluetooth/leaudio/ble_audio_group.h @@ -0,0 +1,89 @@ +#ifndef _BLE_AUDIO_GROUP_H_ +#define _BLE_AUDIO_GROUP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "gap.h" +#include "gap_msg.h" + +typedef void *T_BLE_AUDIO_GROUP_HANDLE; +typedef void *T_BLE_AUDIO_DEV_HANDLE; + +typedef enum +{ + AUDIO_GROUP_MSG_BAP_STATE = 0x01, + AUDIO_GROUP_MSG_BAP_SESSION_REMOVE = 0x02, + AUDIO_GROUP_MSG_BAP_START_QOS_CFG = 0x04, + AUDIO_GROUP_MSG_BAP_CREATE_CIS = 0x05, + AUDIO_GROUP_MSG_BAP_START_METADATA_CFG = 0x06, + AUDIO_GROUP_MSG_BAP_SETUP_DATA_PATH = 0x07, + AUDIO_GROUP_MSG_BAP_REMOVE_DATA_PATH = 0x08, + AUDIO_GROUP_MSG_BAP_METADATA_UPDATE = 0x09, + AUDIO_GROUP_MSG_BAP_CIS_DISCONN = 0x0A, + + AUDIO_GROUP_MSG_DEV_CONN = 0x20, + AUDIO_GROUP_MSG_DEV_DISCONN = 0x21, +} T_AUDIO_GROUP_MSG; + +//AUDIO_GROUP_MSG_DEV_CONN +typedef struct +{ + T_BLE_AUDIO_DEV_HANDLE dev_handle; +} T_AUDIO_GROUP_MSG_DEV_CONN; + +//AUDIO_GROUP_MSG_DEV_DISCONN +typedef struct +{ + T_BLE_AUDIO_DEV_HANDLE dev_handle; + uint16_t cause; +} T_AUDIO_GROUP_MSG_DEV_DISCONN; + +#if 0 +typedef enum +{ + AUDIO_GROUP_RESULT_SUCCESS, + AUDIO_GROUP_RESULT_FAILED, + AUDIO_GROUP_RESULT_TIMEOUT_FAILED, + AUDIO_GROUP_RESULT_TIMEOUT_PARTIAL_SUCCESS, +} T_AUDIO_GROUP_RESULT; +#endif + +typedef struct +{ + bool is_used; + T_BLE_AUDIO_DEV_HANDLE dev_handle; + T_GAP_CONN_STATE conn_state; + T_GAP_REMOTE_ADDR_TYPE addr_type; + uint8_t bd_addr[6]; +} T_AUDIO_DEV_INFO; + +typedef T_APP_RESULT(*P_FUN_AUDIO_GROUP_CB)(T_AUDIO_GROUP_MSG msg, T_BLE_AUDIO_GROUP_HANDLE handle, + void *buf); + +T_BLE_AUDIO_GROUP_HANDLE ble_audio_group_allocate(void); +bool ble_audio_group_reg_cb(T_BLE_AUDIO_GROUP_HANDLE group_handle, P_FUN_AUDIO_GROUP_CB p_fun_cb); +bool ble_audio_group_release(T_BLE_AUDIO_GROUP_HANDLE group_handle); +T_BLE_AUDIO_DEV_HANDLE ble_audio_group_add_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle, + uint8_t *p_bd_addr, uint8_t addr_type); +bool ble_audio_group_remove_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle, + T_BLE_AUDIO_DEV_HANDLE dev_handle); +T_BLE_AUDIO_DEV_HANDLE ble_audio_group_find_dev(T_BLE_AUDIO_GROUP_HANDLE group_handle, + uint8_t *bd_addr, uint8_t addr_type); +T_BLE_AUDIO_DEV_HANDLE ble_audio_group_find_dev_by_conn_handle(T_BLE_AUDIO_GROUP_HANDLE + group_handle, + uint16_t conn_handle); +bool ble_audio_group_get_dev_info(T_BLE_AUDIO_GROUP_HANDLE group_handle, + T_BLE_AUDIO_DEV_HANDLE dev_handle, + T_AUDIO_DEV_INFO *p_info); +uint8_t ble_audio_group_get_used_dev_num(T_BLE_AUDIO_GROUP_HANDLE group_handle); +uint8_t ble_audio_group_get_dev_num(T_BLE_AUDIO_GROUP_HANDLE group_handle); +bool ble_audio_group_get_info(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t *p_dev_num, + T_AUDIO_DEV_INFO *p_dev_tbl); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/ble_audio_sync.h b/inc/bluetooth/leaudio/ble_audio_sync.h new file mode 100644 index 0000000..e9b9bd3 --- /dev/null +++ b/inc/bluetooth/leaudio/ble_audio_sync.h @@ -0,0 +1,126 @@ +#ifndef _BLE_AUDIO_SYNC_H_ +#define _BLE_AUDIO_SYNC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if (LE_AUDIO_BROADCAST_SINK_ROLE | LE_AUDIO_BROADCAST_ASSISTANT_ROLE) +#include "gap.h" +#include "gap_pa_sync.h" +#include "gap_past_recipient.h" +#include "ble_audio_def.h" +#include "base_data_parse.h" + +typedef void *T_BLE_AUDIO_SYNC_HANDLE; + +#define MSG_BLE_AUDIO_PA_SYNC_STATE 0x01 +#define MSG_BLE_AUDIO_PA_REPORT_INFO 0x02 +#define MSG_BLE_AUDIO_BASE_DATA_MODIFY_INFO 0x03 +#define MSG_BLE_AUDIO_PA_BIGINFO 0x04 + +#define MSG_BLE_AUDIO_SYNC_HANDLE_RELEASED 0x20 +#define MSG_BLE_AUDIO_ADDR_UPDATE 0x21 + +typedef enum +{ + BLE_AUDIO_ACTION_ROLE_IDLE = 0x00, + BLE_AUDIO_ACTION_ROLE_LOCAL_API = 0x01, +#if LE_AUDIO_BASS_SUPPORT + BLE_AUDIO_ACTION_ROLE_BASS = 0x02, +#endif +} T_BLE_AUDIO_ACTION_ROLE; + +typedef struct +{ + T_BASE_DATA_MAPPING *p_base_mapping; +} T_BLE_AUDIO_BASE_DATA_MODIFY_INFO; + +typedef enum +{ + BLE_AUDIO_PA_IDLE = 0x00, + BLE_AUDIO_PA_SYNC = 0x01, + BLE_AUDIO_PA_TERMINATE = 0x02, + BLE_AUDIO_PA_LOST = 0x03, +} T_BLE_AUDIO_PA_ACTION; + +typedef struct +{ + T_GAP_PA_SYNC_STATE sync_state; + T_BLE_AUDIO_PA_ACTION action; + T_BLE_AUDIO_ACTION_ROLE action_role; + uint16_t cause; +} T_BLE_AUDIO_PA_SYNC_STATE; + +typedef struct +{ + T_BLE_AUDIO_ACTION_ROLE action_role; +} T_BLE_AUDIO_SYNC_HANDLE_RELEASED; + +typedef struct +{ + uint8_t *advertiser_address; +} T_BLE_AUDIO_ADDR_UPDATE; + +typedef union +{ + T_BLE_AUDIO_PA_SYNC_STATE *p_pa_sync_state; + T_LE_PERIODIC_ADV_REPORT_INFO *p_le_periodic_adv_report_info; + T_BLE_AUDIO_BASE_DATA_MODIFY_INFO *p_base_data_modify_info; + + T_LE_BIGINFO_ADV_REPORT_INFO *p_le_biginfo_adv_report_info; + + T_BLE_AUDIO_SYNC_HANDLE_RELEASED *p_sync_handle_released; + T_BLE_AUDIO_ADDR_UPDATE *p_addr_update; +} T_BLE_AUDIO_SYNC_CB_DATA; + +typedef struct +{ + uint8_t advertiser_address_type; + uint8_t advertiser_address[GAP_BD_ADDR_LEN]; + uint8_t adv_sid; + uint8_t broadcast_id[BROADCAST_ID_LEN]; + //PA info + uint8_t sync_id; + T_GAP_PA_SYNC_STATE pa_state; + uint16_t pa_interval; + T_BASE_DATA_MAPPING *p_base_mapping; + bool big_info_received; + T_LE_BIGINFO_ADV_REPORT_INFO big_info; +} T_BLE_AUDIO_SYNC_INFO; + +typedef void(*P_FUN_BLE_AUDIO_SYNC_CB)(T_BLE_AUDIO_SYNC_HANDLE handle, uint8_t cb_type, + void *p_cb_data); + +T_BLE_AUDIO_SYNC_HANDLE ble_audio_sync_create(P_FUN_BLE_AUDIO_SYNC_CB cb_pfn, + uint8_t advertiser_address_type, + uint8_t *advertiser_address, uint8_t adv_sid, + uint8_t broadcast_id[BROADCAST_ID_LEN]); +bool ble_audio_sync_update_cb(T_BLE_AUDIO_SYNC_HANDLE handle, + P_FUN_BLE_AUDIO_SYNC_CB cb_pfn); +bool ble_audio_sync_update_addr(T_BLE_AUDIO_SYNC_HANDLE handle, + uint8_t *advertiser_address); + +T_BLE_AUDIO_SYNC_HANDLE ble_audio_sync_find(uint8_t advertiser_address_type, + uint8_t adv_sid, uint8_t broadcast_id[BROADCAST_ID_LEN]); +bool ble_audio_sync_get_info(T_BLE_AUDIO_SYNC_HANDLE handle, T_BLE_AUDIO_SYNC_INFO *p_info); +bool ble_audio_sync_realese(T_BLE_AUDIO_SYNC_HANDLE handle); + +bool ble_audio_pa_sync_establish(T_BLE_AUDIO_SYNC_HANDLE handle, uint8_t options, + uint8_t sync_cte_type, + uint16_t skip, uint16_t sync_timeout); +bool ble_audio_pa_terminate(T_BLE_AUDIO_SYNC_HANDLE handle); + +bool ble_audio_set_default_past_recipient_param( + T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_param); +bool ble_audio_set_past_recipient_param(uint16_t conn_handle, + T_GAP_PAST_RECIPIENT_PERIODIC_ADV_SYNC_TRANSFER_PARAM *p_param); + +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/bt_bond_mgr.h b/inc/bluetooth/leaudio/bt_bond_mgr.h new file mode 100644 index 0000000..d6e7c74 --- /dev/null +++ b/inc/bluetooth/leaudio/bt_bond_mgr.h @@ -0,0 +1,51 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +*/ + +#ifndef _BT_BOND_MGR_ +#define _BT_BOND_MGR_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef bool (*P_BT_BOND_CHECK)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle); + +typedef bool (*P_BT_BOND_GET_KEY)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle, + bool remote, uint8_t *p_key_len, uint8_t *p_key); + +typedef uint8_t (*P_BT_BOND_GET_MAX_NUM)(bool is_le); + +typedef bool (*P_BT_BOND_GET_ADDR)(bool is_le, uint8_t bond_idx, uint8_t *bd_addr, + uint8_t *p_bd_type, uint8_t *local_bd_addr, + uint8_t *p_local_bd_type); + +typedef bool (*P_BT_BOND_SET_CCCD_FLAG)(uint8_t *bd_addr, uint8_t bd_type, uint8_t *local_bd_addr, + uint8_t local_bd_type, + uint16_t cccd_handle, uint16_t flags); +typedef bool (*P_BT_BOND_CLEAR_CCCD_FLAG)(uint8_t *bd_addr, uint8_t bd_type, uint16_t conn_handle, + uint16_t cccd_handle); + +typedef bool (*P_BT_BOND_LE_RESOLVE_RPA)(uint8_t *unresolved_addr, uint8_t *identity_addr, + uint8_t *p_identity_addr_type); + +typedef struct +{ + P_BT_BOND_CHECK bond_check; + P_BT_BOND_GET_KEY bond_get_key; + P_BT_BOND_GET_MAX_NUM bond_get_max_num; + P_BT_BOND_GET_ADDR bond_get_addr; + P_BT_BOND_SET_CCCD_FLAG bond_set_cccd_flag; + P_BT_BOND_CLEAR_CCCD_FLAG bond_clear_cccd_flag; + P_BT_BOND_LE_RESOLVE_RPA bond_le_resolve_rpa; +} T_BT_BOND_MGR; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/inc/bluetooth/leaudio/bt_gatt_client.h b/inc/bluetooth/leaudio/bt_gatt_client.h new file mode 100644 index 0000000..fee3389 --- /dev/null +++ b/inc/bluetooth/leaudio/bt_gatt_client.h @@ -0,0 +1,192 @@ +#ifndef _BT_GATT_CLIENT_H_ +#define _BT_GATT_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "gap.h" +#include "profile_client.h" +#include "gap_conn_le.h" + + +typedef enum +{ + GATTC_STORAGE_STATE_IDLE = 0x00, + GATTC_STORAGE_STATE_DISCOVERY = 0x01, + GATTC_STORAGE_STATE_DONE = 0x02, + GATTC_STORAGE_STATE_FAILED = 0x03, +} T_GATTC_STORAGE_STATE; + +#define GATT_CLT_CONFIG_DISABLE 0x00 +#define GATT_CLT_CONFIG_NOTIFICATION 0x01 +#define GATT_CLT_CONFIG_INDICATION 0x02 +#define GATT_CLT_CONFIG_ALL 0x03 +#define ATTR_INSTANCE_NUM_MAX 20 + +typedef enum +{ + GATT_STORAGE_EVENT_SRV_TBL_GET_IND = 0x01, + GATT_STORAGE_EVENT_SRV_TBL_SET_IND = 0x02, +} T_GATT_STORAGE_EVENT; + +typedef enum +{ + GATT_DISCOV_MODE_CLOSED = 0x00, + GATT_DISCOV_MODE_REG_SRV = 0x01, + GATT_DISCOV_MODE_ALL = 0x02, +} T_GATT_DISCOV_MODE; + +//GATT_STORAGE_EVENT_SRV_TBL_GET_IND +typedef struct +{ + uint8_t addr[6]; + uint8_t remote_bd_type; + uint16_t data_len; + uint8_t *p_data; +} T_GATT_STORAGE_SRV_TBL_GET_IND; + +//GATT_STORAGE_EVENT_SRV_TBL_SET_IND +typedef struct +{ + uint8_t addr[6]; + uint8_t remote_bd_type; + uint16_t data_len; + uint8_t *p_data; +} T_GATT_STORAGE_SRV_TBL_SET_IND; + +typedef enum +{ + GATT_CLIENT_EVENT_DIS_DONE = 0x01, + GATT_CLIENT_EVENT_READ_RESULT = 0x02, + GATT_CLIENT_EVENT_WRITE_RESULT = 0x03, + GATT_CLIENT_EVENT_NOTIFY_IND = 0x04, + GATT_CLIENT_EVENT_CCCD_CFG = 0x05, + GATT_CLIENT_EVENT_DIS_ALL_STATE = 0x06, + GATT_CLIENT_EVENT_CONN_DEL = 0x07, +} T_GATT_CLIENT_EVENT; + +typedef struct +{ + bool is_uuid16; + uint8_t instance_id; + union + { + uint16_t uuid16; + uint8_t uuid128[16]; + } p; +} T_ATTR_UUID; + +typedef struct +{ + T_GATTC_STORAGE_STATE state; + bool load_form_ftl; +} T_GATT_CLIENT_DIS_ALL_DONE; + +typedef struct +{ + bool is_found; + bool load_form_ftl; + uint8_t srv_instance_num; +} T_GATT_CLIENT_DIS_DONE; + +typedef struct +{ + bool is_cccd_desc; + uint8_t srv_instance_id; + T_ATTR_UUID char_uuid; + uint16_t cause; + uint16_t handle; + uint16_t value_size; + uint8_t *p_value; +} T_GATT_CLIENT_READ_RESULT; + +typedef struct +{ + bool is_cccd_desc; + uint8_t srv_instance_id; + T_ATTR_UUID char_uuid; + uint16_t cause; + T_GATT_WRITE_TYPE type; + uint16_t handle; +} T_GATT_CLIENT_WRITE_RESULT; + +typedef struct +{ + uint8_t srv_instance_id; + T_ATTR_UUID char_uuid; + bool notify; + uint16_t handle; + uint16_t value_size; + uint8_t *p_value; +} T_GATT_CLIENT_NOTIFY_IND; + +typedef struct +{ + bool srv_cfg; + uint8_t srv_instance_id; + uint16_t cccd_data; + uint16_t cause; + T_ATTR_UUID uuid; +} T_GATT_CLIENT_CCCD_CFG; + +typedef union +{ + T_GATT_CLIENT_DIS_DONE dis_done; + T_GATT_CLIENT_READ_RESULT read_result; + T_GATT_CLIENT_WRITE_RESULT write_result; + T_GATT_CLIENT_NOTIFY_IND notify_ind; + T_GATT_CLIENT_CCCD_CFG cccd_cfg; +} T_GATT_CLIENT_DATA; + +typedef union +{ + T_GATT_CLIENT_DATA *p_gatt_data; +} T_GATTC_DATA; + +typedef struct +{ + uint8_t instance_num; + uint8_t instance_id[ATTR_INSTANCE_NUM_MAX]; +} T_ATTR_INSTANCE; + +typedef T_APP_RESULT(*P_FUN_GATT_CLIENT_CB)(uint16_t conn_handle, T_GATT_CLIENT_EVENT type, + void *p_data); +typedef T_APP_RESULT(*P_FUN_GATT_STORAGE_CB)(T_GATT_STORAGE_EVENT type, void *p_data); + +T_GAP_CAUSE gatt_client_start_discovery_all(uint16_t conn_handle, P_FUN_GATT_CLIENT_CB p_dis_cb); +T_GAP_CAUSE gatt_client_enable_srv_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + uint8_t cccd_cfg); +T_GAP_CAUSE gatt_client_enable_char_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + uint16_t char_uuid16, uint8_t cccd_cfg); +T_GAP_CAUSE gatt_client_enable_uuid128_char_cccd(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + uint8_t *p_uuid128, uint8_t cccd_cfg); +T_GAP_CAUSE gatt_client_read(uint16_t conn_handle, uint16_t handle, P_FUN_GATT_CLIENT_CB p_req_cb); +T_GAP_CAUSE gatt_client_read_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16, P_FUN_GATT_CLIENT_CB p_req_cb); +T_GAP_CAUSE gatt_client_write(uint16_t conn_handle, T_GATT_WRITE_TYPE write_type, + uint16_t handle, uint16_t length, uint8_t *p_data, P_FUN_GATT_CLIENT_CB p_req_cb); + +T_GAP_CAUSE gatt_spec_client_register(T_ATTR_UUID *p_srv_uuid, P_FUN_GATT_CLIENT_CB p_fun_cb); + +//find info about service +bool gatt_client_find_char_handle(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + T_ATTR_UUID *p_char_uuid, uint16_t *p_handle); +bool gatt_client_find_primary_srv_by_include(uint16_t conn_handle, T_ATTR_UUID *p_included_srv, + T_ATTR_UUID *p_primary_srv); +bool gatt_client_find_include_srv_by_primary(uint16_t conn_handle, T_ATTR_UUID *p_primary_srv, + T_ATTR_UUID *p_included_srv, + T_ATTR_INSTANCE *p_attr_instance); +uint8_t gatt_client_get_char_num(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + T_ATTR_UUID *p_char_uuid); +bool gatt_client_get_char_prop(uint16_t conn_handle, T_ATTR_UUID *p_srv_uuid, + T_ATTR_UUID *p_char_uuid, uint16_t *p_properties); + +bool gatt_client_init(T_GATT_DISCOV_MODE mode); +bool gatt_storage_register(P_FUN_GATT_STORAGE_CB p_fun_cb); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/cap.h b/inc/bluetooth/leaudio/cap.h new file mode 100644 index 0000000..ec21059 --- /dev/null +++ b/inc/bluetooth/leaudio/cap.h @@ -0,0 +1,86 @@ +#ifndef _CAP_H_ +#define _CAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ble_audio_group.h" +#include "csis_def.h" + +#if LE_AUDIO_CAP_SUPPORT +#define CAP_ACCEPTOR_ROLE 0x01 +#define CAP_INITIATOR_ROLE 0x02 +#define CAP_CAMMANDER_ROLE 0x04 + +#define GATT_UUID_CAS 0x1853 + +typedef struct +{ + uint8_t default_volume_settings; + uint8_t default_mute; + uint8_t default_mic_mute; +} T_CAP_DEFAULT_PARAM; + +typedef struct +{ + uint8_t cap_role; + bool cas_client; + bool csip_set_coordinator; + uint8_t csis_num; + struct + { + bool enable; + T_CSIS_SIRK_TYPE csis_sirk_type; + uint8_t csis_size; + uint8_t csis_rank; + uint8_t csis_feature; + uint8_t *csis_sirk; + } cas; + struct + { + bool vcp_volume_controller; + bool micp_mic_controller; + uint8_t default_volume_settings; + uint8_t default_mute; + uint8_t default_mic_mute; + } vcp_micp; + + bool ccp_call_control_client; + struct + { + bool ccp_call_control_server; + uint8_t tbs_num; + } tbs; + bool mcp_media_control_client; + struct + { + bool mcp_media_control_server; + uint8_t mcs_num; + uint8_t ots_num; + } mcs; +} T_CAP_INIT_PARAMS; + +typedef struct +{ + uint16_t conn_handle; + bool is_found; + bool load_form_ftl; + uint8_t srv_num; +} T_CAP_DIS_DONE; + +bool cap_change_volume_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t volume_setting); +bool cap_change_volume(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t volume_setting); +bool cap_change_mute_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t mute); +bool cap_change_mute(T_BLE_AUDIO_GROUP_HANDLE group_handle, uint8_t mute); +bool cap_change_mic_mute_by_address(uint8_t *bd_addr, uint8_t addr_type, uint8_t mute); +bool cap_change_input_gain_by_address(uint8_t *bd_addr, uint8_t addr_type, int8_t gain); +bool cap_init(T_CAP_INIT_PARAMS *p_param); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/codec_def.h b/inc/bluetooth/leaudio/codec_def.h new file mode 100644 index 0000000..73c052d --- /dev/null +++ b/inc/bluetooth/leaudio/codec_def.h @@ -0,0 +1,122 @@ +#ifndef _CODEC_DEF_H_ +#define _CODEC_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define TRANSPARENT_CODEC_ID 0x03 +#define LC3_CODEC_ID 0x06 +#define VENDOR_CODEC_ID 0xFF +#define CODEC_ID_LEN 5 + +/* Codec_Specific_Capabilities parameters*/ +//Codec Specific Capability Types +#define CODEC_CAP_TYPE_SUPPORTED_SAMPLING_FREQUENCIES 0x01 +#define CODEC_CAP_TYPE_SUPPORTED_FRAME_DURATIONS 0x02 +#define CODEC_CAP_TYPE_AUDIO_CHANNEL_COUNTS 0x03 +/*4 octets. +Octet 0-1: Minimum number of octets supported per codec frame +Octet 2-3: Maximum number of octets supported per codec frame*/ +#define CODEC_CAP_TYPE_SUPPORTED_OCTETS_PER_CODEC_FRAME 0x04 +#define CODEC_CAP_TYPE_MAX_SUPPORTED_FRAMES_PER_SDU 0x05 + +#define SAMPLING_FREQUENCY_8K 0x0001 +#define SAMPLING_FREQUENCY_11K 0x0002 +#define SAMPLING_FREQUENCY_16K 0x0004 +#define SAMPLING_FREQUENCY_22K 0x0008 +#define SAMPLING_FREQUENCY_24K 0x0010 +#define SAMPLING_FREQUENCY_32K 0x0020 +#define SAMPLING_FREQUENCY_44_1K 0x0040 +#define SAMPLING_FREQUENCY_48K 0x0080 +#define SAMPLING_FREQUENCY_88K 0x0100 +#define SAMPLING_FREQUENCY_96K 0x0200 +#define SAMPLING_FREQUENCY_176K 0x0400 +#define SAMPLING_FREQUENCY_192K 0x0800 +#define SAMPLING_FREQUENCY_384K 0x1000 +#define SAMPLING_FREQUENCY_MASK 0x1FFF + +#define FRAME_DURATION_7_5_MS_BIT 0x01 +#define FRAME_DURATION_10_MS_BIT 0x02 +#define FRAME_DURATION_PREFER_7_5_MS_BIT 0x10 +#define FRAME_DURATION_PREFER_10_MS_BIT 0x20 + +#define AUDIO_CHANNEL_COUNTS_1 0x01 +#define AUDIO_CHANNEL_COUNTS_2 0x02 +#define AUDIO_CHANNEL_COUNTS_3 0x04 +#define AUDIO_CHANNEL_COUNTS_4 0x08 +#define AUDIO_CHANNEL_COUNTS_5 0x10 +#define AUDIO_CHANNEL_COUNTS_6 0x20 +#define AUDIO_CHANNEL_COUNTS_7 0x40 +#define AUDIO_CHANNEL_COUNTS_8 0x80 + +//Config Codec operation +#define CODEC_CFG_TYPE_SAMPLING_FREQUENCY 0x01 +#define CODEC_CFG_TYPE_FRAME_DURATION 0x02 +#define CODEC_CFG_TYPE_AUDIO_CHANNEL_ALLOCATION 0x03 +#define CODEC_CFG_TYPE_OCTET_PER_CODEC_FRAME 0x04 +#define CODEC_CFG_TYPE_BLOCKS_PER_SDU 0x05 + +#define SAMPLING_FREQUENCY_CFG_8K 0x01 +#define SAMPLING_FREQUENCY_CFG_11K 0x02 +#define SAMPLING_FREQUENCY_CFG_16K 0x03 +#define SAMPLING_FREQUENCY_CFG_22K 0x04 +#define SAMPLING_FREQUENCY_CFG_24K 0x05 +#define SAMPLING_FREQUENCY_CFG_32K 0x06 +#define SAMPLING_FREQUENCY_CFG_44_1K 0x07 +#define SAMPLING_FREQUENCY_CFG_48K 0x08 +#define SAMPLING_FREQUENCY_CFG_88K 0x09 +#define SAMPLING_FREQUENCY_CFG_96K 0x0A +#define SAMPLING_FREQUENCY_CFG_176K 0x0B +#define SAMPLING_FREQUENCY_CFG_192K 0x0C +#define SAMPLING_FREQUENCY_CFG_384K 0x0D + +#define FRAME_DURATION_CFG_7_5_MS 0x00 +#define FRAME_DURATION_CFG_10_MS 0x01 + + + +#define CODEC_CAP_SUPPORTED_SAMPLING_FREQUENCIES_EXIST 0x0001 +#define CODEC_CAP_SUPPORTED_FRAME_DURATIONS_EXIST 0x0002 +#define CODEC_CAP_AUDIO_CHANNEL_COUNTS_EXIST 0x0004 +#define CODEC_CAP_SUPPORTED_OCTETS_PER_CODEC_FRAME_EXIST 0x0008 +#define CODEC_CAP_MAX_SUPPORTED_FRAMES_PER_SDU_EXIST 0x0010 + +#define CODEC_CFG_SAMPLING_FREQUENCY_EXIST 0x0001 +#define CODEC_CFG_FRAME_DURATION_EXIST 0x0002 +#define CODEC_CFG_AUDIO_CHANNEL_ALLOCATION_EXIST 0x0004 +#define CODEC_CFG_OCTET_PER_CODEC_FRAME_EXIST 0x0008 +#define CODEC_CFG_TYPE_BLOCKS_PER_SDU_EXIST 0x0010 + +typedef struct +{ + uint16_t type_exist; + uint16_t supported_sampling_frequencies; + uint8_t supported_frame_durations; + uint8_t audio_channel_counts; + uint8_t max_supported_codec_frames_per_sdu; + uint16_t min_octets_per_codec_frame; + uint16_t max_octets_per_codec_frame; +} T_CODEC_CAP; + +typedef struct +{ + uint16_t type_exist; + uint8_t frame_duration; + uint8_t sample_frequency; + uint8_t codec_frame_blocks_per_sdu; + uint16_t octets_per_codec_frame; + uint32_t audio_channel_allocation; + uint32_t presentation_delay; +} T_CODEC_CFG; + +uint8_t count_bits_1(uint32_t value); +bool codec_cap_parse(uint8_t len, uint8_t *p_data, T_CODEC_CAP *p_cap); +bool codec_cfg_parse(uint8_t len, uint8_t *p_data, T_CODEC_CFG *p_cfg); +bool codec_cfg_gen(uint8_t *p_len, uint8_t *p_data, T_CODEC_CFG *p_cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/codec_qos.h b/inc/bluetooth/leaudio/codec_qos.h new file mode 100644 index 0000000..82ea6dc --- /dev/null +++ b/inc/bluetooth/leaudio/codec_qos.h @@ -0,0 +1,101 @@ +#ifndef _CODEC_QOS_H_ +#define _CODEC_QOS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ble_audio_def.h" +#include "codec_def.h" + +typedef enum +{ + CODEC_CFG_ITEM_8_1 = 0, + CODEC_CFG_ITEM_8_2 = 1, + CODEC_CFG_ITEM_16_1 = 2, + CODEC_CFG_ITEM_16_2 = 3, + CODEC_CFG_ITEM_24_1 = 4, + CODEC_CFG_ITEM_24_2 = 5, + CODEC_CFG_ITEM_32_1 = 6, + CODEC_CFG_ITEM_32_2 = 7, + CODEC_CFG_ITEM_441_1 = 8, + CODEC_CFG_ITEM_441_2 = 9, + CODEC_CFG_ITEM_48_1 = 10, + CODEC_CFG_ITEM_48_2 = 11, + CODEC_CFG_ITEM_48_3 = 12, + CODEC_CFG_ITEM_48_4 = 13, + CODEC_CFG_ITEM_48_5 = 14, + CODEC_CFG_ITEM_48_6 = 15, + CODEC_CFG_ITEM_LC3_MAX, + + CODEC_CFG_ITEM_VENDOR = 0xff, +} T_CODEC_CFG_ITEM; + + +#define CODEC_CFG_ITEM_8_1_BIT (1 << CODEC_CFG_ITEM_8_1) +#define CODEC_CFG_ITEM_8_2_BIT (1 << CODEC_CFG_ITEM_8_2) +#define CODEC_CFG_ITEM_16_1_BIT (1 << CODEC_CFG_ITEM_16_1) +#define CODEC_CFG_ITEM_16_2_BIT (1 << CODEC_CFG_ITEM_16_2) +#define CODEC_CFG_ITEM_24_1_BIT (1 << CODEC_CFG_ITEM_24_1) +#define CODEC_CFG_ITEM_24_2_BIT (1 << CODEC_CFG_ITEM_24_2) +#define CODEC_CFG_ITEM_32_1_BIT (1 << CODEC_CFG_ITEM_32_1) +#define CODEC_CFG_ITEM_32_2_BIT (1 << CODEC_CFG_ITEM_32_2) +#define CODEC_CFG_ITEM_441_1_BIT (1 << CODEC_CFG_ITEM_441_1) +#define CODEC_CFG_ITEM_441_2_BIT (1 << CODEC_CFG_ITEM_441_2) +#define CODEC_CFG_ITEM_48_1_BIT (1 << CODEC_CFG_ITEM_48_1) +#define CODEC_CFG_ITEM_48_2_BIT (1 << CODEC_CFG_ITEM_48_2) +#define CODEC_CFG_ITEM_48_3_BIT (1 << CODEC_CFG_ITEM_48_3) +#define CODEC_CFG_ITEM_48_4_BIT (1 << CODEC_CFG_ITEM_48_4) +#define CODEC_CFG_ITEM_48_5_BIT (1 << CODEC_CFG_ITEM_48_5) +#define CODEC_CFG_ITEM_48_6_BIT (1 << CODEC_CFG_ITEM_48_6) + +#define SAMPLE_FREQ_8K_TABLE_MASK (CODEC_CFG_ITEM_8_1_BIT|CODEC_CFG_ITEM_8_2_BIT) +#define SAMPLE_FREQ_16K_TABLE_MASK (CODEC_CFG_ITEM_16_1_BIT|CODEC_CFG_ITEM_16_2_BIT) +#define SAMPLE_FREQ_24K_TABLE_MASK (CODEC_CFG_ITEM_24_1_BIT|CODEC_CFG_ITEM_24_2_BIT) +#define SAMPLE_FREQ_32K_TABLE_MASK (CODEC_CFG_ITEM_32_1_BIT|CODEC_CFG_ITEM_32_2_BIT) +#define SAMPLE_FREQ_441K_TABLE_MASK (CODEC_CFG_ITEM_441_1_BIT|CODEC_CFG_ITEM_441_2_BIT) +#define SAMPLE_FREQ_48K_TABLE_MASK (CODEC_CFG_ITEM_48_1_BIT|CODEC_CFG_ITEM_48_2_BIT| \ + CODEC_CFG_ITEM_48_3_BIT|CODEC_CFG_ITEM_48_4_BIT| \ + CODEC_CFG_ITEM_48_5_BIT|CODEC_CFG_ITEM_48_6_BIT) + +#define FREAM_DUIATION_7_5M_TALBLE_MASK (CODEC_CFG_ITEM_8_1_BIT|CODEC_CFG_ITEM_16_1_BIT| \ + CODEC_CFG_ITEM_24_1_BIT|CODEC_CFG_ITEM_32_1_BIT| \ + CODEC_CFG_ITEM_441_1_BIT|CODEC_CFG_ITEM_48_1_BIT| \ + CODEC_CFG_ITEM_48_3_BIT|CODEC_CFG_ITEM_48_5_BIT) +#define FREAM_DUIATION_10M_TALBLE_MASK (CODEC_CFG_ITEM_8_2_BIT|CODEC_CFG_ITEM_16_2_BIT| \ + CODEC_CFG_ITEM_24_2_BIT|CODEC_CFG_ITEM_32_2_BIT| \ + CODEC_CFG_ITEM_441_2_BIT|CODEC_CFG_ITEM_48_2_BIT| \ + CODEC_CFG_ITEM_48_4_BIT|CODEC_CFG_ITEM_48_6_BIT) + +typedef enum +{ + QOS_CFG_CIS_LOW_LATENCY, + QOS_CFG_CIS_HIG_RELIABILITY, + QOS_CFG_BIS_LOW_LATENCY, + QOS_CFG_BIS_HIG_RELIABILITY, +} T_QOS_CFG_TYPE; + +typedef struct +{ + uint32_t sdu_interval; + uint8_t framing; + uint16_t max_sdu; + uint8_t retransmission_number; + uint16_t max_transport_latency; + uint32_t presentation_delay; +} T_QOS_CFG_PREFERRED; + +bool codec_preferred_cfg_get(T_CODEC_CFG_ITEM item, T_CODEC_CFG *p_cfg); +bool qos_preferred_cfg_get(T_CODEC_CFG_ITEM item, T_QOS_CFG_TYPE type, T_QOS_CFG_PREFERRED *p_qos); +bool qos_cfg_find_by_codec_cfg(T_CODEC_CFG *p_cfg, uint8_t target_latency, + T_QOS_CFG_PREFERRED *p_qos); +bool get_max_sdu_len_by_codec_cfg(T_CODEC_CFG *p_cfg, uint16_t *p_max_len); +bool get_sdu_interval_by_codec_cfg(T_CODEC_CFG *p_cfg, uint32_t *p_sdu_int); +bool codec_cap_get_cfg_bits(uint32_t *p_cfg_bits, T_CODEC_CAP *p_cap); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/csis_def.h b/inc/bluetooth/leaudio/csis_def.h new file mode 100644 index 0000000..7752e7b --- /dev/null +++ b/inc/bluetooth/leaudio/csis_def.h @@ -0,0 +1,49 @@ +#ifndef _CSIS_DEF_H_ +#define _CSIS_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SET_MEMBER_LOCK_EXIST 0x01 +#define SET_MEMBER_SIZE_EXIST 0x02 +#define SET_MEMBER_RANK_EXIST 0x04 +#define SET_MEMBER_SIRK_NOTIFY_SUPPORT 0x10 +#define SET_MEMBER_SIZE_NOTIFY_SUPPORT 0x20 + +#define ATT_ERR_CSIS_LOCK_DENIED 0x80 +#define ATT_ERR_CSIS_LOCK_RELEASE_NOT_ALLOWED 0x81 +#define ATT_ERR_CSIS_INVALID_LOCK_VALUE 0x82 +#define ATT_ERR_CSIS_OOB_SIRK_ONLY 0x83 +#define ATT_ERR_CSIS_LOCK_ALREADY_GRANTED 0x84 + +//coordinated set identification service +#define GATT_UUID_CSIS 0x1846 + +#define CSIS_UUID_CHAR_SET_IRK 0x2B84 +#define CSIS_UUID_CHAR_SIZE 0x2B85 +#define CSIS_UUID_CHAR_LOCK 0x2B86 +#define CSIS_UUID_CHAR_RANK 0x2B87 + +#define CSI_SIRK_LEN 16 + +#define CSI_LOCK_DEFAULT_TIMEOUT 60000 +#define CSIP_DISCOVERY_TIMEOUT 10000 +typedef enum +{ + CSIS_NONE_LOCK = 0, + CSIS_UNLOCKED = 0x01, + CSIS_LOCKED = 0x02, +} T_CSIS_LOCK; + +typedef enum +{ + CSIS_SIRK_ENC = 0x00, + CSIS_SIRK_PLN = 0x01, +} T_CSIS_SIRK_TYPE; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/csis_rsi.h b/inc/bluetooth/leaudio/csis_rsi.h new file mode 100644 index 0000000..dd131fb --- /dev/null +++ b/inc/bluetooth/leaudio/csis_rsi.h @@ -0,0 +1,24 @@ +#ifndef _CSIS_RSI_H_ +#define _CSIS_RSI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +#define GAP_ADTYPE_RSI 0x2E + +#define CSI_RSI_LEN 6 + +#if (LE_AUDIO_CSIS_CLIENT_SUPPORT|LE_AUDIO_CSIS_SUPPORT) +bool csis_gen_rsi(const uint8_t *p_sirk, uint8_t *p_rsik); +bool csis_resolve_rsi(const uint8_t *p_sirk, uint8_t *p_rsik); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/metadata_def.h b/inc/bluetooth/leaudio/metadata_def.h new file mode 100644 index 0000000..673b3aa --- /dev/null +++ b/inc/bluetooth/leaudio/metadata_def.h @@ -0,0 +1,54 @@ +#ifndef _METADATA_DEF_H_ +#define _METADATA_DEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*The Preferred_Audio_Contexts LTV structure is typically included +in the Metadata field of PAC records exposed by Unicast Servers and Broadcast Sinks. */ +#define METADATA_TYPE_PREFERRED_AUDIO_CONTEXTS 0x01 + +/*The Streaming_Audio_Contexts LTV structure is typically included in a Metadata parameter value +when initiating the Enable or Update Metadata ASE Control operations for unicast Audio Streams, +or in the Metadata parameter value included in a BASE structure for broadcast Audio Streams.*/ +#define METADATA_TYPE_STREAMING_AUDIO_CONTEXTS 0x02 +/*Title and/or summary of Audio Stream content: UTF-8 format. */ +#define METADATA_TYPE_PROGRAM_INFO 0x03 +/*3-byte, lower case language code as defined in ISO 639-3. */ +#define METADATA_TYPE_LANGUAGE 0x04 +/*Array of CCID values. */ +#define METADATA_TYPE_CCCD_LIST 0x05 +/*Parental_Rating. */ +#define METADATA_TYPE_PARENTAL_RATING 0x06 +/*A UTF-8 formatted URL link used to present more information about Program_Info. */ +#define METADATA_TYPE_PROGRAM_INFO_URI 0x07 +/*Extended Metadata. */ +#define METADATA_TYPE_EXTENDED 0xFE +/*Vendor_Specific. */ +#define METADATA_TYPE_VENDOR_SPECIFIC 0xFF + + +//BAPS_Assigned_Numbers_v7, different with IOP +#define AUDIO_CONTEXT_UNSPECIFIED 0x0001 +#define AUDIO_CONTEXT_CONVERSATIONAL 0x0002 +#define AUDIO_CONTEXT_MEDIA 0x0004 +#define AUDIO_CONTEXT_GAME 0x0008 +#define AUDIO_CONTEXT_INSTRUCTIONAL 0x0010 +#define AUDIO_CONTEXT_VOICE_ASSISTANTS 0x0020 +#define AUDIO_CONTEXT_LIVE 0x0040 +#define AUDIO_CONTEXT_SOUND_EFFECTS 0x0080 +#define AUDIO_CONTEXT_NOTIFICATIONS 0x0100 +#define AUDIO_CONTEXT_RINGTONE 0x0200 +#define AUDIO_CONTEXT_ALERTS 0x0400 +#define AUDIO_CONTEXT_EMERGENCY_ALERT 0x0800 +#define AUDIO_CONTEXT_MASK 0x0FFF + +#define MCS_CCID_PRE_IDX 0x80 +#define TBS_CCID_PRE_IDX 0x40 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/pacs_client.h b/inc/bluetooth/leaudio/pacs_client.h new file mode 100644 index 0000000..4d829fd --- /dev/null +++ b/inc/bluetooth/leaudio/pacs_client.h @@ -0,0 +1,102 @@ +#ifndef _PACS_CLIENT_H_ +#define _PACS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum +{ + PACS_OP_SINK, + PACS_OP_SOURCE, + PACS_OP_ALL +} T_PACS_CCCD_OP_TYPE; + +typedef enum +{ + PACS_AUDIO_AVAILABLE_CONTEXTS, + PACS_AUDIO_SUPPORTED_CONTEXTS, + PACS_SINK_AUDIO_LOC, + PACS_SINK_PAC, + PACS_SOURCE_AUDIO_LOC, + PACS_SOURCE_PAC, +} T_PACS_TYPE; + +//LE_AUDIO_MSG_PACS_CLIENT_DIS_DONE +typedef struct +{ + uint16_t conn_handle; + bool is_found; + bool load_form_ftl; + uint8_t sink_pac_num; + uint8_t source_pac_num; + bool sink_loc_writable; + bool sink_loc_exist; + bool source_loc_writable; + bool source_loc_exist; +} T_PACS_CLIENT_DIS_DONE; + +//LE_AUDIO_MSG_PACS_CLIENT_CCCD +typedef struct +{ + uint16_t conn_handle; + T_PACS_CCCD_OP_TYPE type; + uint16_t cause; +} T_PACS_CLIENT_CCCD; + +//LE_AUDIO_MSG_PACS_CLIENT_WRITE_SINK_LOC_RESULT +//LE_AUDIO_MSG_PACS_CLIENT_WRITE_SOURCE_LOC_RESULT +typedef struct +{ + uint16_t conn_handle; + uint16_t cause; +} T_PACS_CLIENT_WRITE_RESULT; + +typedef struct +{ + bool is_complete; + uint16_t handle; + uint16_t pac_record_len; + uint8_t *p_record; +} T_PAC_CHAR_DATA; + +typedef struct +{ + uint16_t sink_contexts; + uint16_t source_contexts; +} T_AUDIO_CONTEXTS_DATA; + +typedef union +{ + T_AUDIO_CONTEXTS_DATA contexts_data; + uint32_t audio_locations; + T_PAC_CHAR_DATA pac_data; +} T_PACS_DATA; + +//LE_AUDIO_MSG_PACS_CLIENT_READ_RESULT +typedef struct +{ + uint16_t conn_handle; + T_PACS_TYPE type; + uint16_t cause; + T_PACS_DATA data; +} T_PACS_CLIENT_READ_RESULT; + +//LE_AUDIO_MSG_PACS_CLIENT_NOTIFY +typedef struct +{ + uint16_t conn_handle; + T_PACS_TYPE type; + T_PACS_DATA data; +} T_PACS_CLIENT_NOTIFY; + +bool pacs_read_char_value(uint16_t conn_handle, T_PACS_TYPE type); +bool pacs_enable_cccd(uint16_t conn_handle, T_PACS_CCCD_OP_TYPE type); +bool pacs_write_sink_audio_locations(uint16_t conn_handle, uint32_t sink_audio_location); +bool pacs_write_source_audio_locations(uint16_t conn_handle, uint32_t source_audio_location); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/leaudio/set_coordinator_client.h b/inc/bluetooth/leaudio/set_coordinator_client.h new file mode 100644 index 0000000..a7124bc --- /dev/null +++ b/inc/bluetooth/leaudio/set_coordinator_client.h @@ -0,0 +1,132 @@ +#ifndef _SET_COORDINATOR_TEST_H_ +#define _SET_COORDINATOR_TEST_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#if LE_AUDIO_CSIS_CLIENT_SUPPORT +#include "csis_rsi.h" +#include "csis_def.h" +#include "ble_audio_group.h" +#include "os_queue.h" + +#define CSIS_SIZE_UNKNOWN 0 + +#define CSIS_LOCK_FLAG 0x01 +#define CSIS_SIRK_FLAG 0x02 +#define CSIS_SIZE_FLAG 0x04 +#define CSIS_RANK_FLAG 0x08 + +typedef struct +{ + uint16_t conn_handle; + bool is_found; + bool load_form_ftl; + uint8_t srv_num; +} T_CSIS_CLIENT_DIS_DONE; + +typedef struct +{ + uint16_t conn_handle; + uint16_t cause; + T_BLE_AUDIO_GROUP_HANDLE group_handle; +} T_CSIS_MEMBER_LOCK_REQ_DONE; + +typedef struct +{ + uint16_t conn_handle; + uint16_t cause; + T_BLE_AUDIO_GROUP_HANDLE group_handle; +} T_CSIS_MEMBER_UNLOCK_REQ_DONE; + +typedef struct +{ + uint16_t conn_handle; + uint16_t srv_uuid; + uint8_t srv_instance_id; + T_BLE_AUDIO_GROUP_HANDLE group_handle; + uint8_t lock; +} T_CSIS_MEMBER_LOCK_STATE; + +typedef struct +{ + T_BLE_AUDIO_GROUP_HANDLE group_handle; +} T_CSIS_COOR_SET_DEL; + +typedef struct +{ + uint8_t set_size; + uint8_t size; + bool search_done; +} T_CSIS_SEARCH_RESULT; + +typedef struct +{ + T_BLE_AUDIO_GROUP_HANDLE group_handle; + T_BLE_AUDIO_DEV_HANDLE dev_handle; + uint8_t bd_addr[6]; + uint8_t addr_type; + uint16_t srv_uuid; + uint8_t rank; + uint8_t size; + uint8_t sirk[CSI_SIRK_LEN]; +} T_CSIS_SET_MEM_FOUND; + +typedef struct +{ + uint16_t cause; + uint16_t conn_handle; + T_BLE_AUDIO_GROUP_HANDLE group_handle; + T_BLE_AUDIO_DEV_HANDLE dev_handle; + uint8_t bd_addr[6]; + uint8_t addr_type; + uint16_t srv_uuid; + uint8_t srv_instance_id; + uint8_t char_exit; + uint8_t rank; + uint8_t size; + uint8_t sirk[CSI_SIRK_LEN]; +} T_CSIS_READ_RESULT; + +//LE_AUDIO_MSG_CSIS_CLIENT_SIRK_CHANGE +typedef struct +{ + T_BLE_AUDIO_GROUP_HANDLE group_handle; + uint8_t sirk[CSI_SIRK_LEN]; +} T_CSIS_SIRK_CHANGE; + +typedef struct +{ + uint16_t serv_uuid; + uint8_t srv_instance_id; + uint8_t dev_num; + uint8_t set_mem_size; + uint8_t sirk[CSI_SIRK_LEN]; +} T_CSIS_GROUP_INFO; + +void coordinator_read_csis_chars(uint16_t conn_handle, uint8_t instance_id); +bool csis_client_parse_ext_adv(uint8_t report_data_len, uint8_t *p_report_data, + uint8_t *p_bd_addr, uint8_t addr_type); +bool set_discover_members_state(T_BLE_AUDIO_GROUP_HANDLE group_handle); +bool csis_client_get_info(T_BLE_AUDIO_GROUP_HANDLE group_handle, T_CSIS_GROUP_INFO *p_info); +bool set_lock_of_coor_set(T_BLE_AUDIO_GROUP_HANDLE group_handle); +bool set_unlock_of_coor_set(T_BLE_AUDIO_GROUP_HANDLE group_handle); +T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_rsi(uint8_t *p_rsik); +T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_sirk(uint8_t *p_sirk); +T_BLE_AUDIO_GROUP_HANDLE coordinator_set_find_by_addr(uint8_t *bd_addr, uint8_t addr_type, + uint16_t serv_uuid); +T_BLE_AUDIO_DEV_HANDLE set_member_find_by_conn_handle(T_BLE_AUDIO_GROUP_HANDLE group_handle, + uint16_t conn_handle); +bool coordinator_or_member_find_by_addr(uint8_t *bd_addr, uint8_t addr_type, uint16_t serv_uuid, + T_BLE_AUDIO_GROUP_HANDLE *p_group_handle, T_BLE_AUDIO_DEV_HANDLE *p_dev_handle); +bool set_member_info_find_by_dev_handle(T_BLE_AUDIO_DEV_HANDLE *p_dev_handle, + T_CSIS_SET_MEM_FOUND *set_mem_info); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/profile/client/ams_client.h b/inc/bluetooth/profile/client/ams_client.h new file mode 100644 index 0000000..c1db535 --- /dev/null +++ b/inc/bluetooth/profile/client/ams_client.h @@ -0,0 +1,419 @@ +/** +***************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ams_client.h + * @brief + * @details + * @author + * @date + * @version v1.0 + * ************************************************************************************* +*/ + +#ifndef _AMS_CLIENT_H_ +#define _AMS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +#include +#include "profile_client.h" + + +/** @defgroup AMS_CLIENT AMS Client +* @brief AMS client +* @{ +*/ + + +/** @addtogroup AMS_CLIENT_Exported_Macros AMS Client Exported Macros + * @brief + * @{ + */ + +/** @brief Define links number. range: 0-4 */ +#define AMS_MAX_LINKS 4 + + +/** End of AMS_CLIENT_Exported_Macros +* @} +*/ + + + +/** @defgroup AMS_CLIENT_Exported_Types AMS Client Exported Types + * @brief + * @{ + */ + + +/** @brief AMS client remote command id*/ +typedef enum +{ + REMOTE_CMD_ID_PLAY = 0, + REMOTE_CMD_ID_PAUSE = 1, + REMOTE_CMD_ID_TOGGLE_PLAY_PAUSE = 2, + REMOTE_CMD_ID_NEXT_TRACK = 3, + REMOTE_CMD_ID_PREVIOUS_TRACK = 4, + REMOTE_CMD_ID_VOLUME_UP = 5, + REMOTE_CMD_ID_VOLUME_DOWN = 6, + REMOTE_CMD_ID_ADVANCE_REPEAT_MODE = 7, + REMOTE_CMD_ID_ADVANCE_SHUFFLE_MODE = 8, + REMOTE_CMD_ID_SKIP_FORWARD = 9, + REMOTE_CMD_ID_SKIP_BACKWARD = 10, + REMOTE_CMD_ID_LIKE_TRACK = 11, + REMOTE_CMD_ID_DISLIKE_TRACK = 12, + REMOTE_CMD_ID_BOOK_MARK_TRACK = 13, + REMOTE_CMD_ID_RESERVED = 255 +} T_AMS_REMOTE_CMD_ID; + +/** @brief AMS client entity id*/ +typedef enum +{ + ENTITY_ID_PLAYER = 0, + ENTITY_ID_QUEUE = 1, + ENTITY_ID_TRACK = 2, + ENTITY_ID_RESERVED = 255 +} T_AMS_ENTITY_ID; + +/** @brief AMS client entity player attribute id*/ +typedef enum +{ + PLAYER_ATTR_IDPLAYER_ATTR_ID_VOLUME_NAME = 0, + PLAYER_ATTR_ID_PLAYBACK_INFO = 1, + PLAYER_ATTR_ID_VOLUME = 2, + PLAYER_ATTR_ID_RESERVED = 255 +} T_AMS_ENTITY_PLAYER_ATTR_ID; + +/** @brief AMS client entity queue attribute id*/ +typedef enum +{ + QUEUE_ATTR_ID_INDEX = 0, + QUEUE_ATTR_ID_COUNT = 1, + QUEUE_ATTR_ID_SHUFFLE_MODE = 2, + QUEUE_ATTR_ID_REPEAT_MODE = 3, + QUEUE_ATTR_ID_RESERVED = 255 +} T_AMS_ENTITY_QUEUE_ATTR_ID; + +/** @brief AMS client entity track attribute id*/ +typedef enum +{ + TRACK_ATTR_ID_ARTIST = 0, + TRACK_ATTR_ID_ALBUM = 1, + TRACK_ATTR_ID_TITLE = 2, + TRACK_ATTR_ID_DURATION = 3, + TRACK_ATTR_ID_RESERVED = 255 +} T_AMS_ENTITY_TRACK_ATTR_ID; + +/** @brief AMS client entity attribute id*/ +typedef union +{ + T_AMS_ENTITY_PLAYER_ATTR_ID player_atrr_id; + T_AMS_ENTITY_QUEUE_ATTR_ID queue_attr_id; + T_AMS_ENTITY_TRACK_ATTR_ID track_attr_id; +} T_AMS_ENTITY_ATTR_ID; + +/** @brief AMS client entity attribute*/ +typedef struct +{ + T_AMS_ENTITY_ID entity_id; + T_AMS_ENTITY_ATTR_ID attr_id; +} T_AMS_ENTITY_ATTR; + + +/** @brief AMS client handle type*/ +typedef enum +{ + AMS_HDL_SRV_START, //!< service start handle + AMS_HDL_SRV_END, //!< service end handle + AMS_HDL_REMOTE_CMD_VALUE, //!< remote command characteristic value handle + AMS_HDL_REMOTE_CMD_CCCD, //!< remote command characteristic CCCD handle + AMS_HDL_ENTITY_UPD_VALUE, //!< entity update characteristic value handle + AMS_HDL_ENTITY_UPD_CCCD, //!< entity update characteristic CCCD handle + AMS_HDL_ENTITY_ATTR_VALUE, //!< entity attribute characteristic value handle + AMS_HDL_CACHE_LEN, //!< handle cache length +} T_AMS_HANDLE_TYPE; + + +/** @brief AMS client discovery state*/ +typedef enum +{ + AMS_DISC_IDLE, + AMS_DISC_START, + AMS_DISC_DONE, + AMS_DISC_FAILED +} T_AMS_DISC_STATE; + +/** @brief AMS client write type*/ +typedef enum +{ + AMS_WRITE_REMOTE_CMD_VALUE, + AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE, + AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE, + AMS_WRITE_ENTITY_UPD_VALUE, + AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE, + AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE, + AMS_WRITE_ENTITY_ATTR_VALUE +} T_AMS_WRTIE_TYPE; + +/** @brief AMS client write result*/ +typedef struct +{ + T_AMS_WRTIE_TYPE type; + uint16_t cause; +} T_AMS_WRITE_RESULT; + +/** @brief AMS client data type*/ +typedef enum +{ + AMS_NOTIFY_FROM_REMOTE_CMD, + AMS_NOTIFY_FROM_ENTITY_UPD, + AMS_NOTIFY_FROM_ENTITY_ATTR, +} T_AMS_NOTIFY_DATA_TYPE; + +/** @brief AMS client data type*/ +typedef enum +{ + AMS_READ_FROM_ENTITY_UPD, +} T_AMS_READ_DATA_TYPE; + + +/** @brief AMS client notification data*/ +typedef struct +{ + T_AMS_READ_DATA_TYPE type; + uint16_t cause; + uint16_t value_size; + uint8_t *p_value; +} T_AMS_READ_DATA; + +/** @brief AMS client notification data*/ +typedef struct +{ + T_AMS_NOTIFY_DATA_TYPE type; + uint16_t value_size; + uint8_t *p_value; +} T_AMS_NOTIFY_DATA; + + +/** @brief AMS client callback content*/ +typedef union +{ + T_AMS_DISC_STATE disc_state; + T_AMS_READ_DATA read_data; + T_AMS_WRITE_RESULT write_result; + T_AMS_NOTIFY_DATA notify_data; +} T_AMS_CB_CONTENT; + +/** @brief AMS client callback type*/ +typedef enum +{ + AMS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state + AMS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request result + AMS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail + AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server + AMS_CLIENT_CB_TYPE_DISCONNECT_INFO, //!< LE link disconnect + AMS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage +} T_AMS_CB_TYPE; + +/** @brief AMS client callback data*/ +typedef struct +{ + T_AMS_CB_TYPE cb_type; + T_AMS_CB_CONTENT cb_content; +} T_AMS_CB_DATA; + +/** @defgroup AMS_CLIENT_Exported_Functions AMS Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add ams client. + * + * @param[in] app_cb Callbackto notify client read/write/notify/indicate events. + * @param[in] link_num Initialize link number + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void ams_init(uint8_t link_num) + { + ams_client = ams_add_client(ams_client_cb, link_num); + } + * \endcode + */ +T_CLIENT_ID ams_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + + +/** + * @brief Used by application, to start the discovery procedure of AMS. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT test(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = ams_start_discovery(conn_id); + } + * \endcode + */ +bool ams_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to set the notifcation flag of remote command. + * @param[in] conn_id connection ID. + * @param[in] subscribe value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ams_subscribe_remote_cmd(uint8_t conn_id, bool subscribe); + +/** + * @brief Used by application, to set the notifcation flag of entity update. + * @param[in] conn_id connection ID. + * @param[in] subscribe value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ams_subscribe_entity_upd(uint8_t conn_id, bool subscribe); + +/** + * @brief Used by application, to send remote command. + * @param[in] conn_id connection ID. + * @param[in] cmd_id Remote Command ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_amscmd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t cmd_id = p_parse_value->dw_param[1]; + bool ret = ams_write_remote_cmd(conn_id, (T_AMS_REMOTE_CMD_ID)cmd_id); + } + * \endcode + */ +bool ams_write_remote_cmd(uint8_t conn_id, T_AMS_REMOTE_CMD_ID cmd_id); + +/** + * @brief Used by application, to write the Entity Update characteristic. + * + * The Entity Update characteristic is the characteristic by which an MR can inform the MS + * which entity/attribute pairs it is interested in, and be informed about changes on these whenever they occur. + * For example, the MR can be informed about the title of the currently loaded track, or the name of the active media app. + * + * @param[in] conn_id connection ID. + * @param[in] p_value entity/attribute pairs. + * @param[in] value_len value length of p_value. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_amswrite(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t type = p_parse_value->dw_param[1]; + bool ret = false; + + if (type == 0) + { + uint8_t cmd[3]; + cmd[0] = ENTITY_ID_TRACK; + cmd[1] = TRACK_ATTR_ID_TITLE; + cmd[2] = TRACK_ATTR_ID_DURATION; + ret = ams_write_entity_upd_cmd(conn_id, cmd, 3); + } + } + * \endcode + */ +bool ams_write_entity_upd_cmd(uint8_t conn_id, uint8_t *p_value, uint8_t value_len); + +/** + * @brief Used by application, to write the Entity Attribute characteristic. + * + * This characteristic should ideally only be used if the value of an entity/attribute pair was marked as truncated + * in the corresponding Entity Update notification, and the MR wants to display more of the associated value. + * + * @param[in] conn_id connection ID. + * @param[in] entity_attr Entity Attribute command. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_amswrite(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t type = p_parse_value->dw_param[1]; + bool ret = false; + + if (type == 1) + { + T_AMS_ENTITY_ATTR entity; + entity.entity_id = ENTITY_ID_TRACK; + entity.attr_id.track_attr_id = TRACK_ATTR_ID_TITLE; + ret = ams_write_entity_attr(conn_id, entity); + } + } + * \endcode + */ +bool ams_write_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr); + +/** + * @brief Used by application, to read the Entity Attribute characteristic. + * + * This characteristic should ideally only be used if the value of an entity/attribute pair was marked as truncated + * in the corresponding Entity Update notification, and the MR wants to display more of the associated value. + * + * @param[in] conn_id connection ID. + * @param[in] entity_attr Entity Attribute command. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_amsread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + T_AMS_ENTITY_ATTR entity; + bool ret; + entity.entity_id = ENTITY_ID_TRACK; + entity.attr_id.track_attr_id = TRACK_ATTR_ID_TITLE; + ret = ams_read_entity_attr(conn_id, entity); + } + * \endcode + */ +bool ams_read_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr); + + +/** + * @brief Get the handle for gatt characteristic + * @param[in] conn_id Connection ID. + * @param[in] handle_type Pre-defined Handle Type. + * @retval the handle value of a GATT characteristic. + */ +uint16_t ams_search_handle(uint8_t conn_id, T_AMS_HANDLE_TYPE handle_type); + + +/** @} End of AMS_CLIENT_Exported_Functions */ + +/** @} End of AMS_CLIENT */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/client/ancs_client.h b/inc/bluetooth/profile/client/ancs_client.h new file mode 100644 index 0000000..463f1a3 --- /dev/null +++ b/inc/bluetooth/profile/client/ancs_client.h @@ -0,0 +1,300 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ancs_client.h + * @brief Head file for using ANCS Client. + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _ANCS_CLIENT_H_ +#define _ANCS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include +#include +#include + + +/** @defgroup ANCS_CLIENT ANCS Client +* @brief ANCS client +* @{ +*/ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup ANCS_CLIENT_Exported_Macros ANCS Client Exported Macros + * @brief + * @{ + */ + +/** @brief Define links number. range: 0-4 */ +#define ANCS_MAX_LINKS 4 + + +/** End of ANCS_CLIENT_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup ANCS_CLIENT_Exported_Types ANCS Client Exported Types + * @brief + * @{ + */ + +/** @brief ANCS client handle type*/ +typedef enum +{ + HDL_ANCS_SRV_START, //!< start handle of ANCS + HDL_ANCS_SRV_END, //!< end handle of ANCS + HDL_ANCS_CONTROL_POINT, //!< control point characteristic value handle + HDL_ANCS_NOTIFICATION_SOURCE, //!< notification source characteristic value handle + HDL_ANCS_NOTIFICATION_SOURCE_CCCD, //!< notification source characteristic CCCD handle + HDL_ANCS_DATA_SOURCE, //!< data source characteristic value handle + HDL_ANCS_DATA_SOURCE_CCCD, //!< data source characteristic CCCD handle + HDL_ANCS_CACHE_LEN //!< handle cache length +} T_ANCS_HANDLE_TYPE; + +/** @brief ANCS client control command id*/ +typedef enum +{ + CP_CMD_ID_GET_NOTIFICATION_ATTR = 0, + CP_CMD_ID_GET_APP_ATTR = 1, + CP_CMD_ID_PERFORM_NOTIFICATION_ACTION = 2, + CP_CMD_ID_RESERVED = 255 +} T_ANCS_CP_CMD_ID; + +/** @brief ANCS client discovery state*/ +typedef enum +{ + DISC_ANCS_IDLE, + DISC_ANCS_START, + DISC_ANCS_DONE, + DISC_ANCS_FAILED +} T_ANCS_DISC_STATE; + +/** @brief ANCS client data type*/ +typedef enum +{ + ANCS_FROM_DATA_SOURCE, + ANCS_FROM_NOTIFICATION_SOURCE, +} T_ANCS_DATA_TYPE; + +/** @brief ANCS client notification data struct*/ +typedef struct +{ + T_ANCS_DATA_TYPE type; + uint16_t value_size; + uint8_t *p_value; +} T_ANCS_NOTIFY_DATA; + +/** @brief ANCS client write type*/ +typedef enum +{ + ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE, + ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE, + ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE, + ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE, + ANCS_WRITE_CONTROL_POINT, +} T_ANCS_WRTIE_TYPE; + +/** @brief ANCS client write result*/ +typedef struct +{ + T_ANCS_WRTIE_TYPE type; + uint16_t cause; +} T_ANCS_WRITE_RESULT; + +/** @brief ANCS client callback type*/ +typedef enum +{ + ANCS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + ANCS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO, + ANCS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_ANCS_CB_TYPE; + +/** @brief ANCS client callback content*/ +typedef union +{ + T_ANCS_DISC_STATE disc_state; + T_ANCS_NOTIFY_DATA notify_data; + T_ANCS_WRITE_RESULT write_result; +} T_ANCS_CB_CONTENT; + +/** @brief ANCS client callback data*/ +typedef struct +{ + T_ANCS_CB_TYPE cb_type; + T_ANCS_CB_CONTENT cb_content; +} T_ANCS_CB_DATA; +/** End of ANCS_CLIENT_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup ANCS_CLIENT_Exported_Functions ANCS Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add ancs client. + * + * @param[in] app_cb Callbackto notify client read/write/notify/indicate events. + * @param[in] link_num Initialize link number + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void ancs_init(uint8_t link_num) + { + ancs_client = ancs_add_client(ancs_client_cb, link_num); + } + * \endcode + */ +T_CLIENT_ID ancs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + + +/** + * @brief Used by application, to start the discovery procedure of ANCS. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_ancshdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_ANCS_CACHE_LEN]; + bool ret = ancs_get_hdl_cache(conn_id, hdl_cache, + sizeof(uint16_t) * HDL_ANCS_CACHE_LEN); + ...... + } + * \endcode + */ +bool ancs_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_ANCS_FLAG) + { + ancs_set_hdl_cache(conn_id, app_srvs_table.ancs_hdl_cache, sizeof(uint16_t) * HDL_ANCS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool ancs_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set the notifcation flag of notification source. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_set_notification_source_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to set the notifcation flag of data source. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_set_data_source_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to get the notifcation attribute. + * @param[in] conn_id connection ID. + * @param[in] notification_uid value to enable or disable notify. + * @param[in] p_attribute_ids Pointer to attribute ids. + * @param[in] attribute_ids_len Length of attribute ids. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_get_notification_attr(uint8_t conn_id, uint32_t notification_uid, + uint8_t *p_attribute_ids, uint8_t attribute_ids_len); +/** + * @brief Used by application, to get the app attribute. + * @param[in] conn_id connection ID. + * @param[in] p_app_identifier value to enable or disable notify. + * @param[in] p_attribute_ids Pointer to attribute ids. + * @param[in] attribute_ids_len Length of attribute ids. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_get_app_attr(uint8_t conn_id, char *p_app_identifier, uint8_t *p_attribute_ids, + uint8_t attribute_ids_len); + +/** + * @brief Used by application, to perfome the notication action. + * @param[in] conn_id Connection ID. + * @param[in] notification_uid Notification UUID. + * @param[in] action_id Action id. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_perform_notification_action(uint8_t conn_id, uint32_t notification_uid, + uint8_t action_id); + +/** + * @brief Get the handle for gatt characteristic + * @param[in] conn_id Connection ID. + * @param[in] handle_type Pre-defined Handle Type. + * @retval the handle value of a GATT characteristic. + */ +uint16_t ancs_search_handle(uint8_t conn_id, T_ANCS_HANDLE_TYPE handle_type); + +/** @} End of ANCS_CLIENT_Exported_Functions */ + +/** @} End of ANCS_CLIENT */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _ANCS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/bas_client.h b/inc/bluetooth/profile/client/bas_client.h new file mode 100644 index 0000000..7178131 --- /dev/null +++ b/inc/bluetooth/profile/client/bas_client.h @@ -0,0 +1,337 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bas_client.h + * @brief Head file for using battery service client. + * @details Battery service client data structs and external functions declaration. + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _BAS_CLIENT_H_ +#define _BAS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include +#include +#include + + + +/** @defgroup BAS_CLIENT Battery Service Client + * @brief BAS client + * @details + Application shall register bas client when initialization through @ref bas_add_client function. + + Application can start discovery battery service through @ref bas_start_discovery function. + + Application can read battery level characteristic value through @ref bas_read_battery_level function. + + Application can config and read the notification flag through @ref bas_set_notify and @ref bas_read_notify function. + + Application shall handle callback function registered by bas_add_client. + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (client_id == bas_client_id) + { + T_BAS_CLIENT_CB_DATA *p_bas_cb_data = (T_BAS_CLIENT_CB_DATA *)p_data; + switch (p_bas_cb_data->cb_type) + { + case BAS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_bas_cb_data->cb_content.disc_state) + { + case DISC_BAS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup BAS_CLIENT_Exported_Macros BAS Client Exported Macros + * @brief + * @{ + */ + +/** @brief Define links number. range: 0-4 */ +#define BAS_MAX_LINKS 4 + +/** End of BAS_CLIENT_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BAS_CLIENT__Exported_Types BAS Client Exported Types + * @brief + * @{ + */ + +/** @brief BAS client handle type*/ +typedef enum +{ + HDL_BAS_SRV_START, //!< start handle of battery service + HDL_BAS_SRV_END, //!< end handle of battery service + HDL_BAS_BATTERY_LEVEL, //!< battery level characteristic value handle + HDL_BAS_BATTERY_LEVEL_CCCD, //!< battery level characteristic CCCD handle + HDL_BAS_CACHE_LEN //!< handle cache length +} T_BAS_HANDLE_TYPE; + +/** @brief BAS client discovery state*/ +typedef enum +{ + DISC_BAS_IDLE, + DISC_BAS_START, + DISC_BAS_DONE, + DISC_BAS_FAILED +} T_BAS_DISC_STATE; + +/** @brief BAS client notification data struct*/ +typedef struct +{ + uint8_t battery_level; +} T_BAS_NOTIFY_DATA; + +/** @brief BAS client write type*/ +typedef enum +{ + BAS_WRITE_NOTIFY_ENABLE, + BAS_WRITE_NOTIFY_DISABLE, +} T_BAS_WRTIE_TYPE; + +/** @brief BAS client write result*/ +typedef struct +{ + T_BAS_WRTIE_TYPE type; + uint16_t cause; +} T_BAS_WRITE_RESULT; + +/** @brief BAS client read data */ +typedef union +{ + uint8_t battery_level; + bool notify; +} T_BAS_READ_DATA; + +/** @brief BAS client read type*/ +typedef enum +{ + BAS_READ_NOTIFY, + BAS_READ_BATTERY_LEVEL, +} T_BAS_READ_TYPE; + +/** @brief BAS client read result*/ +typedef struct +{ + T_BAS_READ_TYPE type; + T_BAS_READ_DATA data; + uint16_t cause; +} T_BAS_READ_RESULT; + +/** @brief BAS client callback type*/ +typedef enum +{ + BAS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + BAS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + BAS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + BAS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_BAS_CLIENT_CB_TYPE; + +/** @brief BAS client callback content*/ +typedef union +{ + T_BAS_DISC_STATE disc_state; + T_BAS_READ_RESULT read_result; + T_BAS_NOTIFY_DATA notify_data; + T_BAS_WRITE_RESULT write_result; +} T_BAS_CLIENT_CB_CONTENT; + +/** @brief BAS client callback data*/ +typedef struct +{ + T_BAS_CLIENT_CB_TYPE cb_type; + T_BAS_CLIENT_CB_CONTENT cb_content; +} T_BAS_CLIENT_CB_DATA; +/** End of BAS_CLIENT_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BAS_CLIENT_Exported_Functions BAS Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add bas client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID bas_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of battery service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = bas_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool bas_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to set the notification flag. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool notify = p_parse_value->dw_param[1]; + bool ret; + ret = bas_set_notify(conn_id, notify); + ...... + } + * \endcode + */ +bool bas_set_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to read the notification flag. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = false; + ret = bas_read_notify(conn_id); + ...... + } + * \endcode + */ +bool bas_read_notify(uint8_t conn_id); + +/** + * @brief Used by application, to read battery level. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = false; + ret = bas_read_battery_level(conn_id); + ...... + } + * \endcode + */ +bool bas_read_battery_level(uint8_t conn_id); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_BAS_CACHE_LEN]; + bool ret = bas_get_hdl_cache(conn_id, hdl_cache, + sizeof(uint16_t) * HDL_BAS_CACHE_LEN); + + ...... + } + * \endcode + */ +bool bas_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_BAS_FLAG) + { + bas_set_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool bas_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of BAS_CLIENT_Exported_Functions */ + +/** @} End of BAS_CLIENT */ + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BAS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/bls_client.h b/inc/bluetooth/profile/client/bls_client.h new file mode 100644 index 0000000..e7c9321 --- /dev/null +++ b/inc/bluetooth/profile/client/bls_client.h @@ -0,0 +1,418 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bls_client.h + * @brief Head file for using BLS Client. + * @details blood pressure service client data structs and external functions declaration. + * @author Herry + * @date 2017-12-05 + * @version v1.0 + * ************************************************************************************* + */ + + +#ifndef _BLS_CLIENT_H_ +#define _BLS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Add Includes here */ +#include +#include +#include +#include + + + +/** @defgroup BLS_CLIENT Blood pressure Service Client + * @brief BLS client + * @details + Application shall register bls client when initialization through @ref bls_add_client function. + + Application can start discovery blood pressure service through @ref bls_start_discovery function. + + Application can read blood pressure feature characteristic value through @ref bls_read_blp_feature function. + + Application can config the notification flag and the indication flag through @ref bls_write_notify_indicate. + + Application shall handle callback function registered by bls_add_client. + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (client_id == bls_cl_id) + { + T_BLS_CLIENT_CB_DATA *p_bls_cb_data = (T_BLS_CLIENT_CB_DATA *)p_data; + switch (p_bls_cb_data->cb_type) + { + case BLS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_bls_cb_data->cb_content.disc_state) + { + case DISC_BLS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup BLS_CLIENT_Exported_Macros BLS Client Exported Macros + * @brief + * @{ + */ + +/** @brief Define links number. range: 0-4 */ +#define BLS_MAX_LINKS 4 + +/** End of BLS_CLIENT_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BLS_CLIENT__Exported_Types BLS Client Exported Types + * @brief + * @{ + */ + +/** @brief BLS client handle type*/ +typedef enum +{ + HDL_BLS_SRV_START, //!< start handle of blood pressure service + HDL_BLS_SRV_END, //!< end handle of blood pressure service + HDL_BLS_BLP_MEASUREMENT, //!< blood pressure measurement characteristic value handle + HDL_BLS_BLP_MEASUREMENT_CCCD, //!< blood pressure measurement characteristic CCCD handle + HDL_BLS_INTERMEDIATE_CUFF_PRESSURE, //!< intermediate cuff pressure characteristic value handle + HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD, //!< intermediate cuff pressure characteristic CCCD handle + HDL_BLS_BLP_FEATURE, //!< blood pressure feature characteristic value handle + HDL_BLS_CACHE_LEN //!< handle cache length +} T_BLS_HANDLE_TYPE; + +/** @brief BLS client discovery state*/ +typedef enum +{ + DISC_BLS_IDLE, + DISC_BLS_START, + DISC_BLS_DONE, + DISC_BLS_FAILED +} T_BLS_DISC_STATE; + +typedef struct +{ + T_BLOOD_PRESSURE_MEASURMENT blood_presure_mesaurment; +} T_BLS_NOTIFY_INDICATE_DATA; + +/** @brief BLS client write type*/ +typedef enum +{ + BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_ENABLE, + BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_DISABLE, + BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_ENABLE, + BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_DISABLE +} T_BLS_WRTIE_TYPE; + +/** @brief BLS client write result*/ +typedef struct +{ + T_BLS_WRTIE_TYPE type; + uint16_t cause; +} T_BLS_WRITE_RESULT; + +/** @brief BLS client read data */ +typedef union +{ + uint16_t blood_pressure_feature; +} T_BLS_READ_DATA; + +/** @brief BLS client read type*/ +typedef enum +{ + BLS_READ_BLP_FEATURE, +} T_BLS_READ_TYPE; + +/** @brief BLS client read result*/ +typedef struct +{ + T_BLS_READ_TYPE type; + T_BLS_READ_DATA data; + uint16_t cause; +} T_BLS_READ_RESULT; + +/** @brief BLS client callback type*/ +typedef enum +{ + BLS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + BLS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + BLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + BLS_CLIENT_CB_TYPE_NIFY_INTER_CUFF_PRESS, + //!< Intermediate cuff pressure notification data received from server. + BLS_CLIENT_CB_TYPE_IND_BLOOD_PRESS_MEAS, + //!< Blood pressure measurement indication data received from server. + BLS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_BLS_CLIENT_CB_TYPE; + +/** @brief BLS client callback content*/ +typedef union +{ + T_BLS_DISC_STATE disc_state; + T_BLS_READ_RESULT read_result; + T_BLS_NOTIFY_INDICATE_DATA blp_meas_notify_indicate_data; + T_BLS_WRITE_RESULT write_result; +} T_BLS_CLIENT_CB_CONTENT; + +/** @brief BLS client callback data*/ +typedef struct +{ + T_BLS_CLIENT_CB_TYPE cb_type; + T_BLS_CLIENT_CB_CONTENT cb_content; +} T_BLS_CLIENT_CB_DATA; +/** End of BLS_CLIENT_Exported_Types*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BLS_CLIENT_Exported_Functions BLS Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add bls client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + bls_client_id = bls_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID bls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of blood pressure service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_blsdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = bls_start_discovery(conn_id); + ...... + } + + T_APP_RESULT app_handle_client_message(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + ...... + else if (client_id == bls_cl_id) + { + APP_PRINT_INFO0("app_handle_client_message: bls_cl_id"); + + T_BLS_CLIENT_CB_DATA *p_bls_cb_data = (T_BLS_CLIENT_CB_DATA *)p_data; + switch (p_bls_cb_data->cb_type) + { + case BLS_CLIENT_CB_TYPE_DISC_STATE: + if (p_bls_cb_data->cb_content.disc_state == DISC_STATE_SRV_DONE) + { + APP_PRINT_INFO0("app_handle_client_message: discovery service procedure done."); + } + else + { + APP_PRINT_INFO0("app_handle_client_message: discovery state send to application directly."); + } + break; + ...... + } + ...... + } + * \endcode + */ +bool bls_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read blood pressure feature. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_blsread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = false; + ret = bls_read_blp_feature(conn_id); + ...... + } + + T_APP_RESULT app_handle_client_message(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + ...... + else if (client_id == bls_cl_id) + { + APP_PRINT_INFO0("app_handle_client_message: bls_cl_id"); + + T_BLS_CLIENT_CB_DATA *p_bls_cb_data = (T_BLS_CLIENT_CB_DATA *)p_data; + switch (p_bls_cb_data->cb_type) + { + case BLS_CLIENT_CB_TYPE_READ_RESULT: + if (p_bls_cb_data->cb_content.read_result.type == BLS_READ_BLP_FEATURE) + { + APP_PRINT_INFO1("BLS_CLIENT_CB_TYPE_READ_RESULT blood pressure feature 0x%x", + p_bls_cb_data->cb_content.read_result.data.blood_pressure_feature); + } + break; + ...... + } + ...... + } + * \endcode + */ +bool bls_read_blp_feature(uint8_t conn_id); + +/** + * @brief Used by application, to set the notification flag and indication flag. + * @param[in] conn_id connection ID. + * @param[in] write_type Type of T_BLS_WRTIE_TYPE. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_blswrite(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t write_type = p_parse_value->dw_param[1]; + bool ret; + ret = bls_write_notify_indicate(conn_id, (T_BLS_WRTIE_TYPE)write_type); + ...... + } + + T_APP_RESULT app_handle_client_message(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + ...... + else if (client_id == bls_cl_id) + { + APP_PRINT_INFO0("app_handle_client_message: bls_cl_id"); + + T_BLS_CLIENT_CB_DATA *p_bls_cb_data = (T_BLS_CLIENT_CB_DATA *)p_data; + switch (p_bls_cb_data->cb_type) + { + case BLS_CLIENT_CB_TYPE_WRITE_RESULT: + switch (p_bls_cb_data->cb_content.write_result.type) + { + ...... + case BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_ENABLE: + APP_PRINT_INFO1("BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_ENABLE: write result 0x%x", + p_bls_cb_data->cb_content.write_result.cause); + break; + case BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_DISABLE: + APP_PRINT_INFO1("BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_DISABLE: write result 0x%x", + p_bls_cb_data->cb_content.write_result.cause); + break; + default: + break; + } + break; + + case BLS_CLIENT_CB_TYPE_NOTIF_RESULT: + #if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + case BLS_CLIENT_CB_TYPE_IND_RESULT: + #endif + { + T_BLOOD_PRESSURE_MEASURMENT blood_presure_mesaurment = + p_bls_cb_data->cb_content.blp_meas_notify_indicate_data.blood_presure_mesaurment; + + if (p_bls_cb_data->cb_type == BLS_CLIENT_CB_TYPE_IND_RESULT) + { + APP_PRINT_INFO0("BLS_CLIENT_CB_TYPE_IND_RESULT"); + } + else + { + APP_PRINT_INFO0("BLS_CLIENT_CB_TYPE_NOTIF_RESULT"); + } + + if (blood_presure_mesaurment.bp_meas_flag & BLS_FLAG_MEASUREMENT_UINT_BIT) + { + APP_PRINT_INFO5("blood pressure measurement bp_meas_flag 0x%x, bp_meas_value_unit %d, bp_meas_systolic_value %b, bp_meas_diastolic_value %b, bp_meas_diastolic_value %b", + blood_presure_mesaurment.bp_meas_flag, BLS_MEASUREMENT_VALUE_UNITS_KPA, + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_systolic_value), + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_diastolic_value), + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_map_value)); + } + else + { + APP_PRINT_INFO5("blood pressure measurement bp_meas_flag 0x%x, bp_meas_value_unit %d, bp_meas_systolic_value %b, bp_meas_diastolic_value %b, bp_meas_diastolic_value %b", + blood_presure_mesaurment.bp_meas_flag, BLS_MEASUREMENT_VALUE_UNITS_MMHG, + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_systolic_value), + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_diastolic_value), + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_compound_value.bp_meas_map_value)); + } + + if (blood_presure_mesaurment.bp_meas_flag & BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT) + { + APP_PRINT_INFO6("blood pressure measurement year %d, month %d, day %d, hours %d, minutes %d, seconds %d", + blood_presure_mesaurment.time_stamp.year, blood_presure_mesaurment.time_stamp.month, + blood_presure_mesaurment.time_stamp.day, blood_presure_mesaurment.time_stamp.hours, + blood_presure_mesaurment.time_stamp.minutes, blood_presure_mesaurment.time_stamp.seconds); + } + + if (blood_presure_mesaurment.bp_meas_flag & BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT) + { + APP_PRINT_INFO1("blood pressure measurement bp_meas_pulse_rate %b", + TRACE_BINARY(2, blood_presure_mesaurment.bp_meas_pulse_rate)); + } + + if (blood_presure_mesaurment.bp_meas_flag & BLS_FLAG_MEASUREMENT_USER_ID_BIT) + { + APP_PRINT_INFO1("blood pressure measurement bp_meas_user_id 0x%x", + blood_presure_mesaurment.bp_meas_user_id); + } + + if (blood_presure_mesaurment.bp_meas_flag & BLS_FLAG_MEASUREMENT_STATUS_BIT) + { + APP_PRINT_INFO1("blood pressure measurement bp_meas_status 0x%x", + blood_presure_mesaurment.bp_meas_status); + } + break; + } + + default: + break; + } + } + ...... + * \endcode + */ +bool bls_write_notify_indicate(uint8_t conn_id, T_BLS_WRTIE_TYPE write_type); + +/** @} End of BLS_CLIENT_Exported_Functions */ + +/** @} End of BLS_CLIENT */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/bluetooth/profile/client/dfu_client.h b/inc/bluetooth/profile/client/dfu_client.h new file mode 100644 index 0000000..fdc6d69 --- /dev/null +++ b/inc/bluetooth/profile/client/dfu_client.h @@ -0,0 +1,319 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dfu_client.h + * @brief Head file for using dfu service Client. + * @details Data structs and external functions declaration. + * @author bill + * @date 2018-4-17 + * @version v2.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _DFU_CLIENT_H_ +#define _DFU_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Add Includes here */ +#include "patch_header_check.h" +#include "profile_client.h" +#include "dfu_api.h" + +/** @defgroup DFU_Client DFU Service Client + * @brief DFU client + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup DFU_Client_Exported_Macros DFU Client Exported Macros + * @brief + * @{ + */ +/** @brief Define links number. range: 0-4 */ +#define DFU_MAX_LINKS 4 +/** End of DFU_Client_Exported_Macros * @} */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup DFU_Client_Exported_Types DFU Client Exported Types + * @brief + * @{ + */ +/** @brief Handle cache for intrested UUIDs */ +typedef enum +{ + HDL_DFU_SRV_START, // start handle of dfu service + HDL_DFU_SRV_END, // end handle of dfu service + HDL_DFU_DATA, + HDL_DFU_CP, + HDL_DFU_CP_CCCD, + HDL_DFU_CACHE_LEN +} T_DFU_HANDLE_TYPE; + +/** @brief used to inform app the discovery procedure is done or pending */ +typedef enum +{ + DISC_DFU_IDLE, + DISC_DFU_START, + DISC_DFU_DONE, + DISC_DFU_FAIL, +} T_DFU_DISC_STATE; + +/** @brief read request type, used by app to send read request */ +typedef enum +{ + DFU_READ_CP_CCCD +} T_DFU_READ_TYPE; + +/** @brief read content, used to inform app read response data content */ +typedef union +{ + bool dfu_cp_cccd; +} T_DFU_READ_DATA; + +/** @brief read data, used to inform app read response data */ +typedef struct +{ + T_DFU_READ_TYPE type; + T_DFU_READ_DATA data; + uint16_t cause; +} T_DFU_READ_RESULT; + +/** @brief write request result */ +typedef enum +{ + DFU_WRITE_CP, + DFU_WRITE_CP_CCCD, + DFU_WRITE_DATA +} T_DFU_WRITE_TYPE; + +typedef struct +{ + T_DFU_WRITE_TYPE type; + uint16_t cause; +} T_DFU_WRITE_RESULT; + +/** @brief notif/ind receive type */ +typedef enum +{ + DFU_RECEIVE_CP_NOTIFY, +} T_DFU_NOTIFY_INDICATE_TYPE; + +/** @brief notif/ind receive content */ +typedef struct +{ + uint16_t len; + uint8_t *pdata; +} T_DFU_NOTIFY_INDICATE_VAL; + +/** @brief The notif/ind data received by the client from the server */ +typedef struct +{ + T_DFU_NOTIFY_INDICATE_TYPE type; + T_DFU_NOTIFY_INDICATE_VAL value; +} T_DFU_NOTIFY_INDICATE_DATA; + +/** @brief Event type to inform app */ +typedef enum +{ + DFU_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + DFU_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + DFU_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + DFU_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_DFU_CLIENT_CB_TYPE; + +/** @brief Callback content sent to application from the client */ +typedef union +{ + T_DFU_DISC_STATE disc_state; + T_DFU_READ_RESULT read_result; + T_DFU_WRITE_RESULT write_result; + T_DFU_NOTIFY_INDICATE_DATA notif_ind_data; +} T_DFU_CLIENT_CB_CONTENT; + +/** @brief Callback data sent to application from the client, include type and content */ +typedef struct +{ + T_DFU_CLIENT_CB_TYPE cb_type; + T_DFU_CLIENT_CB_CONTENT cb_content; +} T_DFU_CLIENT_CB_DATA; + + +typedef enum +{ + DFU_FSM_WRITE_IDLE, + DFU_FSM_WRITE_CCCD_ENABLE, + DFU_FSM_WRITE_DFU_DATA, + DFU_FSM_WRITE_WAIT_WRITE_RESP +} T_DFU_CLIENT_FSM_WRITE; + +typedef enum +{ + DFU_CB_START, + DFU_CB_END, + DFU_CB_FAIL, + DFU_CB_MAX +} T_DFU_CB_TYPE; + +typedef enum +{ + DFU_SUCCESS, + DFU_FAIL_START_DFU, + DFU_FAIL_BUF_CHECK, + DFU_FAIL_VALIDATE_FW, +} T_DFU_FAIL_TYPE; + +typedef union +{ + T_DFU_FAIL_TYPE dfu_fail_reason; +} T_DFU_CB_DATA; + +/** Dfu service data to inform application */ +typedef struct +{ + uint8_t conn_id; + T_DFU_CB_TYPE type; + T_DFU_CB_DATA data; +} T_DFU_CLIENT_CB_MSG; + +typedef enum +{ + DFU_FEATURE_USER_DEFINED_DFU, + DFU_FEATURE_AUTO_COPY_DFU, + +} T_DFU_CLIENT_FEATURE_TYPE; + +typedef enum +{ + DFU_SET_FEATURE, + DFU_SET_MODE_VALUE, + DFU_SET_MAX_BUF_SIZE, + DFU_SET_DFU_IMG_ADDR, + DFU_SET_DFU_IMG_VER, + DFU_SET_NORMAL_OTA_FLAG, +} T_DFU_SET_CLIENT_CTX_TYPE; + +typedef struct +{ + T_IMG_CTRL_HEADER_FORMAT dfu_ctrl_header; + + T_OTA_MODE ota_mode; + T_DFU_CLIENT_FEATURE_TYPE dfu_feature; + T_DFU_CLIENT_FSM_WRITE dfu_fsm_write; + bool is_normal_ota; + + uint16_t mtu_size; + uint16_t max_buffer_size; + + uint32_t dfu_img_start_addr; + uint32_t dfu_img_version; + uint32_t dfu_img_total_length; + + uint32_t curr_offset; + uint32_t target_img_version; + + uint16_t dfu_buf_check_crc_val; + uint16_t dfu_buf_check_size; + + /*ctx used when enable or disable buffer check*/ + uint16_t dfu_pkt_num; + uint16_t dfu_pkt_counter; + uint16_t dfu_last_pkt_size; +} T_DFU_CTX; + + +typedef void (*P_FUN_DFU_CLIENT_INIT_APP_CB)(void); + +/** End of DFU_Client_Exported_Types * @} */ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DFU_Client_Exported_Functions DFU Client Exported Functions + * @{ + */ +bool dfu_encrypt(uint8_t image[16]); +uint16_t dfu_client_crc_cal(uint8_t *buf, uint32_t length, uint16_t checksum16); + +void dfu_client_set_dfu_ctx_value(T_DFU_SET_CLIENT_CTX_TYPE type, void *p_value); + +/** + * @brief start the service discovery + * + * contains the service/characteristic/cccd declaration + * @param[in] conn_id: the connection id + * @return the operatino result + */ +bool dfu_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to set the handles in Dfu handle cache. + * @param handle_type: handle types of this specific profile. + * @param handle_value: handle value to set. + * @retval true--set success. + * flase--set failed. + */ +bool dfu_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dfu_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param command: 0--disable the notification, 1--enable the notification. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_cp_cccd_set(uint8_t conn_id, bool command); + +/** + * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic. + * @param ctl_pnt_ptr: pointer of control point data to write. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_cp_write(uint8_t conn_id, uint8_t *pdata, uint16_t length); + +/** + * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic. + * @param ctl_pnt_ptr: pointer of control point data to write. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_data_write(uint8_t conn_id, uint8_t *pdata, uint16_t length); + +/** + * @brief add Dfu client to application. + * @param appCB: pointer of app callback function to handle specific client module data. + * @retval Client ID of the specific client module. + */ +T_CLIENT_ID dfu_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + + +/** @} End of DFU_Client_Exported_Functions */ + +/** @} End of DFU_Client */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DFU_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/dis_client.h b/inc/bluetooth/profile/client/dis_client.h new file mode 100644 index 0000000..a7578c1 --- /dev/null +++ b/inc/bluetooth/profile/client/dis_client.h @@ -0,0 +1,304 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dis_client.h + * @brief Head file for using DIS Client. + * @details dis data structs and external functions declaration. + * @author ken + * @date 2017-12-05 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _DIS_CLIENT_H_ +#define _DIS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + +/** @defgroup DIS_Client dis service client + * @brief dis service client + * @details + dis Profile is a customized BLE-based Profile. Dis ble service please refer to @ref DIS_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup DIS_Client_Exported_Macros DIS Client Exported Macros + * @brief + * @{ + */ +/** @defgroup DIS UUIDs + * @brief Dis BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_DEVICE_INFORMATION_SERVICE 0x180A + +#define GATT_UUID_CHAR_SYSTEM_ID 0x2A23 +#define GATT_UUID_CHAR_MODEL_NUMBER 0x2A24 +#define GATT_UUID_CHAR_SERIAL_NUMBER 0x2A25 +#define GATT_UUID_CHAR_FIRMWARE_REVISION 0x2A26 +#define GATT_UUID_CHAR_HARDWARE_REVISION 0x2A27 +#define GATT_UUID_CHAR_SOFTWARE_REVISION 0x2A28 +#define GATT_UUID_CHAR_MANUFACTURER_NAME 0x2A29 +#define GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST 0x2A2A +#define GATT_UUID_CHAR_PNP_ID 0x2A50 +/** @} End of DIS_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define DIS_MAX_LINKS 2 +/** End of DIS_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup DIS_Exported_Types DIS Client Exported Types + * @brief + * @{ + */ + +/** @brief DIS client handle type*/ +typedef enum +{ + HDL_DIS_SRV_START, //!< start handle of lls service + HDL_DIS_SRV_END, //!< end handle of lls service + HDL_DIS_SYSTEM_ID, //!< DIS system id read characteristic value handle + HDL_DIS_MODEL_NUMBER, //!< DIS model number read characteristic value handle + HDL_DIS_SERIAL_NUMBER, //!< DIS serial number read characteristic value handle + HDL_DIS_FIRMWARE_REVISION, //!< DIS firmware revision read characteristic value handle + HDL_DIS_HARDWARE_REVISION, //!< DIS hardware revision read characteristic value handle + HDL_DIS_SOFTWARE_REVISION, //!< DIS software revision read characteristic value handle + HDL_DIS_MANUFACTURER_NAME, //!< DIS manufacturer name read characteristic value handle + HDL_DIS_IEEE_CERTIF_DATA_LIST,//!< DIS ieee certif data list read characteristic value handle + HDL_DIS_PNP_ID, //!< DIS pnp id read characteristic value handle + HDL_DIS_CACHE_LEN //!< handle cache length +} T_DIS_HANDLE_TYPE; + +/** @brief DIS client discovery state*/ +typedef enum +{ + DISC_DIS_IDLE, + DISC_DIS_START, + DISC_DIS_DONE, + DISC_DIS_FAILED +} T_DIS_DISC_STATE; + +/** @brief dis client read type*/ +typedef enum +{ + DIS_READ_SYSTEM_ID, + DIS_READ_MODEL_NUMBER, + DIS_READ_SERIAL_NUMBER, + DIS_READ_FIRMWARE_REVISION, + DIS_READ_HARDWARE_REVISION, + DIS_READ_SOFTWARE_REVISION, + DIS_READ_MANUFACTURER_NAME, + DIS_READ_IEEE_CERTIF_DATA_LIST, + DIS_READ_PNP_ID +} T_DIS_READ_TYPE; + +/** @brief DIS client read value*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_DIS_READ_VALUE; + +/** @brief DIS client read data*/ +typedef union +{ + T_DIS_READ_VALUE v1_read; +// bool v3_notify_cccd; +// bool v4_indicate_cccd; +} T_DIS_READ_DATA; + +/** @brief DIS client read result*/ +typedef struct +{ + T_DIS_READ_TYPE type; + T_DIS_READ_DATA data; + uint16_t cause; +} T_DIS_READ_RESULT; + + +///** @brief LLS client write type*/ +//typedef enum +//{ +// LLS_WRITE_PARA, +//} T_LLS_WRTIE_TYPE; + +///** @brief LLS client write result*/ +//typedef struct +//{ +// T_LLS_WRTIE_TYPE type; +// uint16_t cause; +//} T_LLS_WRITE_RESULT; + +/** @brief LLS client notif/ind receive type*/ +//typedef enum +//{ +// LLS_KEY_NOTIFY, +//} T_LLS_NOTIF_IND_TYPE; + +///** @brief LLS client notif/ind receive data*/ +//typedef struct +//{ +// uint16_t value_size; +// uint8_t *p_value; +//} T_LLS_NOTIF_IND_VALUE; + +/** @brief LLS client notif/ind receive content*/ +//typedef struct +//{ +// T_LLS_NOTIF_IND_TYPE type; +// T_LLS_NOTIF_IND_VALUE data; +//} T_LLS_NOTIF_IND_DATA; + +/** @brief DIS client callback type*/ +typedef enum +{ + DIS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + DIS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + //LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + DIS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_DIS_CLIENT_CB_TYPE; + +/** @brief DIS client callback content*/ +typedef union +{ + T_DIS_DISC_STATE disc_state; + T_DIS_READ_RESULT read_result; + //T_DIS_WRITE_RESULT write_result; + //T_LLS_NOTIF_IND_DATA notif_ind_data; +} T_DIS_CLIENT_CB_CONTENT; + +/** @brief DIS client callback data*/ +typedef struct +{ + T_DIS_CLIENT_CB_TYPE cb_type; + T_DIS_CLIENT_CB_CONTENT cb_content; +} T_DIS_CLIENT_CB_DATA; + +/** End of DIS_Client_Exported_Types * @} */ + +/** @defgroup DIS_Client_Exported_Functions DIS Client Exported Functions + * @{ + */ + +/** + * @brief Add dis service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + dis_client_id = dis_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID dis_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of dis server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_read_by_handle(uint8_t conn_id, T_DIS_READ_TYPE read_type); + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_read_by_uuid(uint8_t conn_id, T_DIS_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool dis_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, +// T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dis_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dis_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of DIS_Client_Exported_Functions */ + +/** @} End of DIS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DIS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/gaps_client.h b/inc/bluetooth/profile/client/gaps_client.h new file mode 100644 index 0000000..b3dc3e5 --- /dev/null +++ b/inc/bluetooth/profile/client/gaps_client.h @@ -0,0 +1,276 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gaps_client.h + * @brief Head file for using GAP service client. + * @details GAP service client data structs and external functions declaration. + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GAPS_CLIENT_H_ +#define _GAPS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + + +/** @defgroup GAPS_Client GAP Service Client + * @brief GAP service client + * @details + Application shall register gaps client when initialization through @ref gaps_add_client function. + + Application can start discovery GAP service through @ref gaps_start_discovery function. + + Application can read GAP service referenced values through @ref gaps_read function. + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + if (client_id == gaps_client_id) + { + T_GAPS_CLIENT_CB_DATA *p_gaps_cb_data = (T_GAPS_CLIENT_CB_DATA *)p_data; + switch (p_gaps_cb_data->cb_type) + { + case GAPS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_gaps_cb_data->cb_content.disc_state) + { + case DISC_GAPS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/** @defgroup GAPS_Client_Exported_Macros GAPS Client Exported Macros + * @brief + * @{ + */ +/** @brief Define links number. range: 0-4 */ +#define GAPS_MAX_LINKS 4 + +/** @brief GAP service UUID */ +#define GATT_UUID_GAP 0x1800 +/** @brief Resolvable private address only characteristic UUID */ +#define GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY 0x2AC9 +/** End of GAPS_Client_Exported_Macros * @} */ + + +/** @defgroup GAPS_Client_Exported_Types GAPS Client Exported Types + * @brief + * @{ + */ +/** @brief GAPS client handle type */ +typedef enum +{ + HDL_GAPS_SRV_START, //!< start handle of gap service + HDL_GAPS_SRV_END, //!< end handle of gap service + HDL_GAPS_DEVICE_NAME, //!< device name value handle + HDL_GAPS_APPEARANCE, //!< appearance value handle + HDL_GAPS_CENTRAL_ADDR_RESOLUTION, //!< central address resolution value handle + HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY,//!< resolvable private address only value handle + HDL_GAPS_CACHE_LEN //!< handle cache length +} T_GAP_CLIENT_HANDLE_TYPE; + + +/** @brief GAPS client discovery state */ +typedef enum +{ + DISC_GAPS_IDLE, + DISC_GAPS_START, + DISC_GAPS_DONE, + DISC_GAPS_FAILED +} T_GAPS_DISC_STATE; + + +/** @brief GAPS client read type */ +typedef enum +{ + GAPS_READ_DEVICE_NAME, + GAPS_READ_APPEARANCE, + GAPS_READ_CENTRAL_ADDR_RESOLUTION, +} T_GAPS_READ_TYPE; + +/** @brief Device name value */ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_DEVICE_NAME; + +/** @brief GAPS client read content */ +typedef union +{ + uint16_t appearance; + T_DEVICE_NAME device_name; + uint8_t central_addr_res; +} T_GAPS_READ_DATA; + +/** @brief GAPS client read data, used to inform app read response data */ +typedef struct +{ + T_GAPS_READ_TYPE type; + T_GAPS_READ_DATA data; + uint16_t cause; +} T_GAPS_READ_RESULT; + + +/** @brief GAPS client callback type */ +typedef enum +{ + GAPS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + GAPS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + GAPS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_GAPS_CLIENT_CB_TYPE; + +/** @brief GAPS client callback content */ +typedef union +{ + T_GAPS_DISC_STATE disc_state; + T_GAPS_READ_RESULT read_result; +} T_GAPS_CLIENT_CB_CONTENT; + + +/** @brief GAPS client callback data */ +typedef struct +{ + T_GAPS_CLIENT_CB_TYPE cb_type; + T_GAPS_CLIENT_CB_CONTENT cb_content; +} T_GAPS_CLIENT_CB_DATA; + +/** End of GAPS_Client_Exported_Types * @} */ + +/** @defgroup GPAS_Client_Exported_Functions GAPS Client Exported Functions + * @brief + * @{ + */ +/** + * @brief Add gap service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID gaps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of GAP service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gapdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = gaps_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool gaps_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1]; + bool ret = gaps_read(conn_id, read_type); + ...... + } + * \endcode + */ +bool gaps_read(uint8_t conn_id, T_GAPS_READ_TYPE read_type); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in,out] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_GAPS_CACHE_LEN]; + uint8_t hdl_idx; + bool ret = gaps_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN); + ...... + } + * \endcode + */ +bool gaps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_GAPS_FLAG) + { + gaps_set_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool gaps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to check Resolvable Private Address Only Characteristics whether existing. + * @param[in] conn_id connection ID. + * @param[in,out] p_is_exist whether existing + * @retval true success. + * @retval false failed. + */ +bool gaps_check_resolvable_private_addr_only_char(uint8_t conn_id, bool *p_is_exist); + +/** @} End of GAPS_Client_Exported_Functions */ + +/** @} End of GAPS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GAPS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/gatts_client.h b/inc/bluetooth/profile/client/gatts_client.h new file mode 100644 index 0000000..073cb73 --- /dev/null +++ b/inc/bluetooth/profile/client/gatts_client.h @@ -0,0 +1,276 @@ +/** +***************************************************************************************** +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gatts_client.h + * @brief Head file for using GATT service client. + * @details GATT service client data structs and external functions declaration. + * @author + * @date 2019-05-27 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GATTS_CLIENT_H_ +#define _GATTS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + +/** @defgroup GATTS_Client GATT Service Client + * @brief GATT service client + * @details + Application shall register gatts client when initialization through @ref gatts_add_client function. + + Application can start discovery GATT service through @ref gatts_start_discovery function. + + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + if (client_id == gatts_client_id) + { + T_GATTS_CLIENT_CB_DATA *p_gatts_cb_data = (T_GATTS_CLIENT_CB_DATA *)p_data; + switch (p_gatts_cb_data->cb_type) + { + case GATTS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_gatts_cb_data->cb_content.disc_state) + { + case DISC_GATTS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/** @defgroup GATTS_Client_Exported_Macros GATTS Client Exported Macros + * @brief + * @{ + */ +/** @brief Define links number. range: 0-4 */ +#define GATTS_MAX_LINKS 4 + +/** @brief GATT service UUID */ +#define GATT_UUID_GATT 0x1801 +/** End of GATTS_Client_Exported_Macros * @} */ + +/** @defgroup GATTS_Client_Exported_Types GATTS Client Exported Types + * @brief + * @{ + */ +/** @brief GATTS client handle type */ +typedef enum +{ + HDL_GATTS_SRV_START, //!< start handle of gap service + HDL_GATTS_SRV_END, //!< end handle of gap service + HDL_GATTS_SERVICE_CHANGED, //!< service changed handle + HDL_GATTS_SERVICE_CHANGED_CCCD, //!< service changed CCCD handle + HDL_GATTS_CACHE_LEN, //!< handle cache length +} T_GATTS_CLIENT_HANDLE_TYPE; + +/** @brief GATTS client discovery state */ +typedef enum +{ + DISC_GATTS_IDLE, + DISC_GATTS_START, + DISC_GATTS_DONE, + DISC_GATTS_FAILED, +} T_GATTS_DISC_STATE; + +/** @brief Client Supported Features value */ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_CLIENT_SUPPORTED_FEATURES; + +/** @brief GATTS client read content */ +typedef union +{ + T_CLIENT_SUPPORTED_FEATURES client_supported_features; + uint8_t database_hash[GATTS_DATABASE_HASH_LEN]; +} T_GATTS_READ_DATA; + +/** @brief GATTS client write type*/ +typedef enum +{ + GATTS_WRITE_SERVICE_CHANGED_IND_ENABLE, + GATTS_WRITE_SERVICE_CHANGED_IND_DISABLE, + GATTS_WRITE_CLIENT_SUPPORTED_FEATURES, +} T_GATTS_WRTIE_TYPE; + +/** @brief GATTS client write result*/ +typedef struct +{ + T_GATTS_WRTIE_TYPE type; + uint16_t cause; +} T_GATTS_WRITE_RESULT; + +/** @brief GATTS client notif/ind receive type*/ +typedef enum +{ + GATTS_SERVICE_CHANGED_INDICATE, +} T_GATTS_NOTIF_IND_TYPE; + +/** @brief GATTS client notif/ind receive data */ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_GATTS_NOTIF_IND_VALUE; + +/** @brief GATTS client notif/ind receive content*/ +typedef struct +{ + T_GATTS_NOTIF_IND_TYPE type; + T_GATTS_NOTIF_IND_VALUE data; +} T_GATTS_NOTIF_IND_DATA; + +/** @brief GATTS client callback type */ +typedef enum +{ + GATTS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + GATTS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + GATTS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + GATTS_CLIENT_CB_TYPE_INVALID, //!< Invalid callback type, no practical usage. +} T_GATTS_CLIENT_CB_TYPE; + +/** @brief GATTS client callback content */ +typedef union +{ + T_GATTS_DISC_STATE disc_state; + T_GATTS_WRITE_RESULT write_result; + T_GATTS_NOTIF_IND_DATA notif_ind_data; +} T_GATTS_CLIENT_CB_CONTENT; + +/** @brief GATTS client callback data */ +typedef struct +{ + T_GATTS_CLIENT_CB_TYPE cb_type; + T_GATTS_CLIENT_CB_CONTENT cb_content; +} T_GATTS_CLIENT_CB_DATA; + +/** End of GATTS_Client_Exported_Types * @} */ + +/** @defgroup GATTS_Client_Exported_Functions GATTS Client Exported Functions + * @brief + * @{ + */ +/** + * @brief Add gatts service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + gatts_client_id = gatts_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID gatts_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of GATT service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gattsdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = gatts_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool gatts_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to set the indication flag of service changed characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind value to enable or disable indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_srvchgcccd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ind = p_parse_value->dw_param[1]; + bool ret; + ret = gatts_client_set_service_changed_ind(conn_id, ind); + ...... + } + * \endcode + */ +bool gatts_client_set_service_changed_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in,out] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gattshdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_GATTS_CACHE_LEN]; + uint8_t hdl_idx; + bool ret = gatts_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN); + ...... + } + * \endcode + */ +bool gatts_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_GATTS_FLAG) + { + gatts_set_hdl_cache(conn_id, app_srvs_table.gatts_hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool gatts_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of GATTS_Client_Exported_Functions */ + +/** @} End of GATTS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GATTS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/gcs_client.h b/inc/bluetooth/profile/client/gcs_client.h new file mode 100644 index 0000000..08ac0df --- /dev/null +++ b/inc/bluetooth/profile/client/gcs_client.h @@ -0,0 +1,626 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gcs_client.h + * @brief Head file for using General Common Services client. + * @details General common services client data structs and external functions declaration. + * @author jane + * @date 2018-12-13 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GCS_CLIENT_H_ +#define _GCS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + +/** @defgroup GCS_Client General Common Services Client + * @brief GCS service client + * @details + Application shall register gcs client when initialization through @ref gcs_add_client function. + * \code{.c} + T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", + client_id, conn_id); + if (client_id == gcs_client_id) + { + T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; + switch (p_gcs_cb_data->cb_type) + { + case GCS_CLIENT_CB_TYPE_DISC_RESULT: + ...... + } + } + * \endcode + * @{ + */ + +/** @defgroup GCS_Client_Exported_Macros GCS Client Exported Macros + * @brief + * @{ + */ +/** @brief Define maximum links number. range: 0-4 */ +#define GCS_MAX_LINKS 4 + +/** End of GCS_Client_Exported_Macros * @} */ + +/** @defgroup GCS_Client_Exported_Types GCS Client Exported Types + * @brief + * @{ + */ + +/** @brief Discovery result type.*/ +typedef enum +{ + GCS_ALL_PRIMARY_SRV_DISCOV, //!Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_gsrvdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + T_GAP_CAUSE cause = gcs_all_primary_srv_discovery(conn_id); + + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_ALL_PRIMARY_SRV_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_all_primary_srv_discovery(uint8_t conn_id); + +/** + * @brief Send discovery services by 128 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] p_uuid128 128 bit UUID. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + cause = gcs_by_uuid128_srv_discovery(conn_id, uuid128); + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_BY_UUID128_SRV_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_by_uuid128_srv_discovery(uint8_t conn_id, uint8_t *p_uuid128); + +/** + * @brief Send discovery services by 16 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] uuid16 16 bit UUID. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_srvuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + cause = gcs_by_uuid_srv_discovery(conn_id, uuid16); + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_BY_UUID_SRV_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_by_uuid_srv_discovery(uint8_t conn_id, uint16_t uuid16); + +/** + * @brief Send discovery characteristics request. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_chardis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t start_handle = p_parse_value->dw_param[1]; + uint16_t end_handle = p_parse_value->dw_param[2]; + + T_GAP_CAUSE cause = gcs_all_char_discovery(conn_id, start_handle, end_handle); + + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_ALL_CHAR_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_all_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send discovery characteristics request by caracteristic uuid. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] uuid16 16bit characteristic uuid to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + T_GAP_CAUSE cause = gcs_by_uuid_char_discovery(conn_id, start_handle, end_handle, + uuid16); + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_BY_UUID_CHAR_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_by_uuid_char_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16); +/** + * @brief Send discovery characteristics request by caracteristic uuid. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] p_uuid128 128bit characteristic uuid to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_charuuid(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + T_GAP_CAUSE cause = gcs_by_uuid128_char_discovery(conn_id, start_handle, + end_handle, + uuid128); + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_BY_UUID128_CHAR_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_by_uuid128_char_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint8_t *p_uuid128); +/** + * @brief Send discovery characteristics descriptor request. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_charddis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t start_handle = p_parse_value->dw_param[1]; + uint16_t end_handle = p_parse_value->dw_param[2]; + + T_GAP_CAUSE cause = gcs_all_char_descriptor_discovery(conn_id, start_handle, + end_handle); + return (T_USER_CMD_PARSE_RESULT)cause; + } + void gcs_handle_discovery_result(uint8_t conn_id, T_GCS_DISCOVERY_RESULT discov_result) + { + uint16_t i; + T_GCS_DISCOV_RESULT *p_result_table; + uint16_t properties; + switch (discov_result.discov_type) + { + case GCS_ALL_CHAR_DESC_DISCOV: + ...... + } + } + * \endcode + */ +T_GAP_CAUSE gcs_all_char_descriptor_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle); +/** + * @brief Read characteristic by handle request. + * @param[in] conn_id Connection ID + * @param[in] handle Request handle. + * @retval GAP_CAUSE_SUCCESS Read request success. + * @retval other Read request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_read(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t handle = p_parse_value->dw_param[1]; + T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS; + + if (p_parse_value->param_count <= 2) + { + cause = gcs_attr_read(conn_id, handle); + } + + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", + client_id, conn_id); + if (client_id == gcs_client_id) + { + T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; + switch (p_gcs_cb_data->cb_type) + { + case GCS_CLIENT_CB_TYPE_READ_RESULT: + APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", + p_gcs_cb_data->cb_content.read_result.cause, + p_gcs_cb_data->cb_content.read_result.handle, + p_gcs_cb_data->cb_content.read_result.value_size); + APP_PRINT_INFO1("READ VALUE: %b", + TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, + p_gcs_cb_data->cb_content.read_result.p_value)); + break; + ...... + } + } + return result; + } + * \endcode + */ +T_GAP_CAUSE gcs_attr_read(uint8_t conn_id, uint16_t handle); + +/** + * @brief Read characteristic by 16 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] uuid16 Request 16 bit UUID. + * @retval GAP_CAUSE_SUCCESS Read request success. + * @retval other Read request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + cause = gcs_attr_read_using_uuid16(conn_id, start_handle, end_handle, uuid16); + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", + client_id, conn_id); + if (client_id == gcs_client_id) + { + T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; + switch (p_gcs_cb_data->cb_type) + { + case GCS_CLIENT_CB_TYPE_READ_RESULT: + APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", + p_gcs_cb_data->cb_content.read_result.cause, + p_gcs_cb_data->cb_content.read_result.handle, + p_gcs_cb_data->cb_content.read_result.value_size); + APP_PRINT_INFO1("READ VALUE: %b", + TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, + p_gcs_cb_data->cb_content.read_result.p_value)); + break; + ...... + } + } + return result; + } + * \endcode + */ +T_GAP_CAUSE gcs_attr_read_using_uuid16(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, + uint16_t uuid16); +/** + * @brief Read characteristic by 128 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] p_uuid128 Request 128 bit UUID. + * @retval GAP_CAUSE_SUCCESS Read request success. + * @retval other Read request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_readu(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + cause = gcs_attr_read_using_uuid128(conn_id, start_handle, end_handle, uuid128); + return (T_USER_CMD_PARSE_RESULT)cause; + } + T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", + client_id, conn_id); + if (client_id == gcs_client_id) + { + T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; + switch (p_gcs_cb_data->cb_type) + { + case GCS_CLIENT_CB_TYPE_READ_RESULT: + APP_PRINT_INFO3("READ RESULT: cause 0x%4x, handle 0x%4x, value_len %d", + p_gcs_cb_data->cb_content.read_result.cause, + p_gcs_cb_data->cb_content.read_result.handle, + p_gcs_cb_data->cb_content.read_result.value_size); + APP_PRINT_INFO1("READ VALUE: %b", + TRACE_BINARY(p_gcs_cb_data->cb_content.read_result.value_size, + p_gcs_cb_data->cb_content.read_result.p_value)); + break; + ...... + } + } + return result; + } + * \endcode + */ +T_GAP_CAUSE gcs_attr_read_using_uuid128(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle, + uint8_t *p_uuid128); +/** + * @brief Confirm from application when receive indication from server. + * @param[in] conn_id Connection ID indicate which link is. + * @retval GAP_CAUSE_SUCCESS: Success. + * @retval other: Failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_indconf(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE ret; + uint8_t conn_id = p_parse_value->dw_param[0]; + ret = gcs_attr_ind_confirm(conn_id); + return (T_USER_CMD_PARSE_RESULT)ret; + } + * \endcode + */ +T_GAP_CAUSE gcs_attr_ind_confirm(uint8_t conn_id); + +/** + * @brief Write characteristic request. + * @param[in] conn_id Connection ID + * @param[in] write_type Type of write. + * @param[in] handle Attribute handle. + * @param[in] length Length of data to be written. + If write_type is GATT_WRITE_TYPE_REQ, range of length is from 0 to 512. + If write_type is GATT_WRITE_TYPE_CMD, range of length is from 0 to (mtu_size - 3). + uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id). + * @param[in] p_data Point to the data to be written. + * @retval GAP_CAUSE_SUCCESS: Write request success. + * @retval other: Write request failed. + * + * Example usage + * \code{.c} + T_USER_CMD_PARSE_RESULT cmd_write(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + ...... + + T_GAP_CAUSE ret = gcs_attr_write(conn_id, (T_GATT_WRITE_TYPE)write_type, handle, + length, data); + return (T_USER_CMD_PARSE_RESULT)ret; + } + T_APP_RESULT gcs_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO2("gcs_client_callback: client_id %d, conn_id %d", + client_id, conn_id); + if (client_id == gcs_client_id) + { + T_GCS_CLIENT_CB_DATA *p_gcs_cb_data = (T_GCS_CLIENT_CB_DATA *)p_data; + switch (p_gcs_cb_data->cb_type) + { + case GCS_CLIENT_CB_TYPE_WRITE_RESULT: + APP_PRINT_INFO3("WRITE RESULT: cause 0x%4x ,handle 0x%4x, type %d", + p_gcs_cb_data->cb_content.write_result.cause, + p_gcs_cb_data->cb_content.write_result.handle, + p_gcs_cb_data->cb_content.write_result.type); + break; + ...... + } + } + + return result; + } + * \endcode + */ +T_GAP_CAUSE gcs_attr_write(uint8_t conn_id, T_GATT_WRITE_TYPE write_type, uint16_t handle, + uint16_t length, uint8_t *p_data); + +/** + * @brief Add general services client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @param[in] config the discovery table number per link. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + gcs_client_id = gcs_add_client(gcs_client_callback, APP_MAX_LINKS, APP_MAX_DISCOV_TABLE_NUM); + } + * \endcode + */ +T_CLIENT_ID gcs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num, + uint16_t max_discov_table_size); + +/** @} End of GCS_Client_Exported_Functions */ + +/** @} End of GCS_Client */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GCS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/hids_client.h b/inc/bluetooth/profile/client/hids_client.h new file mode 100644 index 0000000..dfacd4a --- /dev/null +++ b/inc/bluetooth/profile/client/hids_client.h @@ -0,0 +1,355 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_client.h + * @brief Head file for using hid service client. + * @details HID client data structs and external functions declaration. + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HIDS_CLIENT_H_ +#define _HIDS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include +#include +#include + +/** @defgroup HIDS_CLIENT HID Service Client + * @brief HIDS client + * @details + Application shall register hid host when initialization through @ref hids_add_client function. + + Application can start discovery battery service through @ref hids_start_discovery function. + + Application shall handle callback function registered by hids_add_client. + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (client_id == hid_host_id) + { + T_HIDS_CLIENT_CB_DATA *p_hids_client_cb_data = (T_HIDS_CLIENT_CB_DATA *)p_data; + switch (p_hids_client_cb_data->cb_type) + { + case HIDS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_hids_client_cb_data->cb_content.disc_state) + { + case DISC_HIDS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup HIDS_CLIENT_Exported_Macros HOGP Client Exported Macros + * @brief + * @{ + */ +/** @brief Define links number. range: 0-4 */ +#define HIDS_CLIENT_MAX_LINKS 4 + +/** @brief Define report number. */ +#define HIDS_CLIENT_MAX_REPORT_NUM 10 + +/** @brief Bit field of HIDS read flag. */ +#define HIDS_READ_HID_INFO_BIT 0x01 +#define HIDS_READ_PROTOCOL_MODE_BIT 0x02 +#define HIDS_READ_REPORT_MAP_BIT 0x04 +#define HIDS_READ_REPORT_REF_BIT 0x08 + +/** @defgroup HID UUIDs + * @brief HID UUID definitions + * @{ + */ +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E + +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 // boot keyboard input report +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 // boot keyboard output report +#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33 // boot mouse input report + +/** @} End of Hid UUIDs */ + +/** End of HIDS_CLIENT_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HIDS_CLIENT__Exported_Types HOGP Client Exported Types + * @brief + * @{ + */ + +/** @brief HID host handle type*/ +typedef enum +{ + HDL_HIDS_SRV_START, //!< start handle of hid service + HDL_HIDS_SRV_END, //!< end handle of hid service + HDL_HIDS_CHAR_HID_INFO, //!< hid information characteristic value handle + HDL_HIDS_CHAR_REPORT_MAP, //!< report map characteristic value handle + HDL_HIDS_CHAR_HID_CONTROL_POINT, //!< hid control point characteristic value handle + HDL_HIDS_CHAR_PROTOCOL_MODE, //!< protocol mode characteristic value handle + HDL_HIDS_CACHE_LEN //!< handle cache length +} T_HIDS_CLIENT_HANDLE_TYPE; + +/** @brief HID host discovery state*/ +typedef enum +{ + DISC_HIDS_IDLE, + DISC_HIDS_START, + DISC_HIDS_DONE, + DISC_HIDS_FAILED +} T_HIDS_CLIENT_DISC_STATE; + +/** @brief HID host report type*/ +typedef enum +{ + HIDS_RESERVED_REPORT, + HIDS_INPUT_REPORT, + HIDS_OUTPUT_REPORT, + HIDS_FEATURE_REPORT, +} T_HIDS_REPORT_TYPE; + +/** @brief HID host report reference data*/ +typedef struct +{ + uint8_t report_id; + T_HIDS_REPORT_TYPE report_type; +} T_HIDS_REPORT_REF_DATA; + +/** @brief HID host report*/ +typedef struct +{ + uint16_t hdl_report_value; + uint16_t hdl_report_cccd; + uint16_t hdl_report_reference; + T_HIDS_REPORT_REF_DATA report_ref; +} T_HIDS_CLIENT_REPORT; + + +typedef struct +{ + uint8_t CountryCode; + uint8_t bFlags; + uint16_t BcdHID; +} HID_INFO_ATTRB; + +/** @brief HID host read type*/ +typedef enum +{ + HIDS_READ_PROTOCOL_MODE, + HIDS_READ_REPORT_MAP, + HIDS_READ_HID_INFO, +} T_HIDS_READ_TYPE; + +/** @brief HID host read value */ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_HIDS_READ_VALUE; + +#if 0 +/** @brief HID host read data */ +typedef union +{ + T_HIDS_READ_VALUE report_map; + T_HIDS_READ_VALUE report_ref; +} T_HIDS_READ_DATA; +#endif + +/** @brief HID host read result type */ +typedef enum +{ + HIDS_READ_RESULT_RESERVED, + HIDS_READ_RESULT_REPORT_MAP, +} T_HIDS_READ_RESULT_TYPE; + +/** @brief HID host read result */ +typedef struct +{ + T_HIDS_READ_RESULT_TYPE type; + uint16_t cause; +} T_HIDS_CLIENT_READ_RESULT; + +/** @brief HID host write type*/ +typedef enum +{ + HIDS_WRITE_REPORT, + HIDS_WRITE_ALL_REPORT_CCCD, + //HIDS_WRITE_PROTOCOL_MODE,//write command + //HIDS_WRITE_HID_CONTROL_POINT,//write command +} T_HIDS_WRTIE_TYPE; + +typedef struct +{ + uint8_t report_id; + uint16_t value_size; + uint8_t *p_value; +} T_HIDS_WRITE_REPORT_DATA; + +/** @brief HID host write result*/ +typedef struct +{ + T_HIDS_WRTIE_TYPE type; + uint16_t cause; + T_HIDS_REPORT_REF_DATA report_ref; //just used for HIDS_WRITE_REPORT +} T_HIDS_CLIENT_WRITE_RESULT; + +/** @brief HID host notification receive type*/ +typedef enum +{ + HIDS_REPORT_NOTIFY, +} T_HIDS_NOTIF_TYPE; + +/** @brief HID host notification receive data*/ +typedef struct +{ + uint8_t report_id; + uint16_t value_size; + uint8_t *p_value; +} T_HIDS_NOTIF_VALUE; + +/** @brief HID host notification receive content*/ +typedef struct +{ + T_HIDS_NOTIF_TYPE type; + T_HIDS_NOTIF_VALUE data; +} T_HIDS_CLIENT_NOTIF_DATA; + +/** @brief HOGP client callback type*/ +typedef enum +{ + HIDS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + HIDS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + HIDS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + HIDS_CLIENT_CB_TYPE_NOTIF_RESULT, //!< Notification or indication data received from server. + HIDS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_HIDS_CLIENT_CB_TYPE; + +/** @brief HOGP client callback content*/ +typedef union +{ + T_HIDS_CLIENT_DISC_STATE disc_state; + T_HIDS_CLIENT_READ_RESULT read_result; + T_HIDS_CLIENT_NOTIF_DATA notify_data; + T_HIDS_CLIENT_WRITE_RESULT write_result; +} T_HIDS_CLIENT_CB_CONTENT; + +/** @brief HOGP client callback data*/ +typedef struct +{ + T_HIDS_CLIENT_CB_TYPE cb_type; + T_HIDS_CLIENT_CB_CONTENT cb_content; +} T_HIDS_CLIENT_CB_DATA; + +/** @brief HID Host storage information block definition. */ +typedef struct +{ + uint8_t read_flags; + uint8_t protocol_mode; + uint8_t report_num; + HID_INFO_ATTRB hids_info; + uint16_t hdl_cache[HDL_HIDS_CACHE_LEN]; + T_HIDS_CLIENT_REPORT report[HIDS_CLIENT_MAX_REPORT_NUM]; +} T_HIDS_CLIENT_STORAGE_INFO; +/** End of HIDS_CLIENT_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HIDS_CLIENT_Exported_Functions HOGP Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add hid host to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + hids_client_client_id = hids_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID hids_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of battery service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hidhostdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = hids_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool hids_start_discovery(uint8_t conn_id); + +bool hids_write_report(uint8_t conn_id, uint8_t report_id, T_HIDS_REPORT_TYPE report_type, + uint16_t length, uint8_t *p_value, T_GATT_WRITE_TYPE type); + +bool hids_enable_all_cccd(uint8_t conn_id); + +bool hids_read_saved_data(uint8_t conn_id, T_HIDS_READ_TYPE read_type, T_HIDS_READ_VALUE *p_value); + +bool hids_get_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info); + +bool hids_set_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info); + +bool hids_read_report_map(uint8_t conn_id); + +bool hids_set_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value); + +void hids_print_infos(uint8_t conn_id); + +/** @} End of HIDS_CLEINT_Exported_Functions */ + +/** @} End of HIDS_CLEINT */ + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HIDS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/hrs_client.h b/inc/bluetooth/profile/client/hrs_client.h new file mode 100644 index 0000000..e346a14 --- /dev/null +++ b/inc/bluetooth/profile/client/hrs_client.h @@ -0,0 +1,366 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hrs_client.h + * @brief Head file for using heart rate service client. + * @details Heart rate service client data structs and external functions declaration. + * @author jane + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HRS_CLIENT_H_ +#define _HRS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include +#include +#include +#include + + + +/** @defgroup HRS_CLIENT Heart rate Service Client + * @brief HRS client + * @details + Application shall register hrs client when initialization through @ref hrs_add_client function. + + Application can start discovery heart rate service through @ref hrs_start_discovery function. + + Application can config and read the notification flag through @ref hrs_set_heart_rate_measurement_notify function. + + Application shall handle callback function registered by hrs_add_client. + * \code{.c} + T_APP_RESULT app_client_callback(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (client_id == hrs_client_id) + { + T_HRS_CLIENT_CB_DATA *p_hrs_cb_data = (T_HRS_CLIENT_CB_DATA *)p_data; + switch (p_hrs_cb_data->cb_type) + { + case HRS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_hrs_cb_data->cb_content.disc_state) + { + case DISC_HRS_DONE: + ...... + } + } + * \endcode + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @addtogroup HRS_CLIENT_Exported_Macros HRS Client Exported Macros + * @brief + * @{ + */ + +/** @brief Define links number. range: 0-4 */ +#define HRS_MAX_LINKS 4 + +/** End of HRS_CLIENT_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HRS_CLIENT__Exported_Types HRS Client Exported Types + * @brief + * @{ + */ + +/** @brief HRS client handle type*/ +typedef enum +{ + HDL_HRS_SRV_START, //!< start handle of heart rate service + HDL_HRS_SRV_END, //!< end handle of heart rate service + HDL_HRS_HEART_RATE_MEASUREMENT, //!< heart rate measurement characteristic handle + HDL_HRS_HEART_RATE_MEASUREMENT_CCCD, //!< Heart Rate Measurement characteristic CCCD handle + HDL_HRS_BODY_SENSOR_LOCATION,//!< body sensor location characteristic handle + HDL_HRS_CACHE_LEN //!< handle cache length +} T_HRS_HANDLE_TYPE; + +/** @brief HRS client discovery state*/ +typedef enum +{ + DISC_HRS_IDLE, + DISC_HRS_START, + DISC_HRS_DONE, + DISC_HRS_FAILED +} T_HRS_DISC_STATE; + +/** @brief HRS client read data */ +typedef union +{ + bool notify; +} T_HRS_READ_DATA; + +/** @brief HRS client read type*/ +typedef enum +{ + HRS_READ_NOTIFY, +} T_HRS_READ_TYPE; + +/** @brief HRS client read result*/ +typedef struct +{ + T_HRS_READ_TYPE type; + T_HRS_READ_DATA data; + uint16_t cause; +} T_HRS_READ_RESULT; + +/** @brief HRS client data type*/ +typedef enum +{ + HRS_FROM_HEART_RATE_MEASUREMENT, +} T_HRS_DATA_TYPE; + +/** @brief HRS client notification data struct*/ +typedef struct +{ + T_HRS_DATA_TYPE type; + uint16_t value_size; + uint8_t *p_value; +} T_HRS_NOTIFY_DATA; + +/** @brief HRS client write type*/ +typedef enum +{ + HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_ENABLE, + HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_DISABLE, +} T_HRS_WRTIE_TYPE; + +/** @brief HRS client write result*/ +typedef struct +{ + T_HRS_WRTIE_TYPE type; + uint16_t cause; +} T_HRS_WRITE_RESULT; + +/** @brief HRS client callback type*/ +typedef enum +{ + HRS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + HRS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + HRS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + HRS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + HRS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_HRS_CLIENT_CB_TYPE; + +/** @brief HRS client callback content*/ +typedef union +{ + T_HRS_DISC_STATE disc_state; + T_HRS_READ_RESULT read_result; + T_HRS_NOTIFY_DATA notify_data; + T_HRS_WRITE_RESULT write_result; +} T_HRS_CLIENT_CB_CONTENT; + +/** @brief HRS client callback data*/ +typedef struct +{ + T_HRS_CLIENT_CB_TYPE cb_type; + T_HRS_CLIENT_CB_CONTENT cb_content; +} T_HRS_CLIENT_CB_DATA; +/** End of HRS_CLIENT_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HRS_CLIENT_Exported_Functions HRS Client Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add hrs client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + hrs_client_id = hrs_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID hrs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of heart rate service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hrsdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = hrs_start_discovery(conn_id); + ...... + } + + T_APP_RESULT app_handle_client_message(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + ...... + else if (client_id == hrs_cl_id) + { + APP_PRINT_INFO0("app_handle_client_message: hrs_cl_id"); + + T_HRS_CLIENT_CB_DATA *p_hrs_cb_data = (T_HRS_CLIENT_CB_DATA *)p_data; + switch (p_hrs_cb_data->cb_type) + { + case HRS_CLIENT_CB_TYPE_DISC_STATE: + if (p_hrs_cb_data->cb_content.disc_state == DISC_STATE_SRV_DONE) + { + APP_PRINT_INFO0("app_handle_client_message: discovery service procedure done."); + } + else + { + APP_PRINT_INFO0("app_handle_client_message: discovery state send to application directly."); + } + break; + + ...... + } + ...... + } + * \endcode + */ +bool hrs_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to set the notification flag of heart rate measurement. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hrsmeascccd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool notify = p_parse_value->dw_param[1]; + bool ret; + ret = hrs_set_heart_rate_measurement_notify(conn_id, notify); + ...... + } + + T_APP_RESULT app_handle_client_message(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + ...... + else if (client_id == hrs_cl_id) + { + APP_PRINT_INFO0("app_handle_client_message: hrs_cl_id"); + + T_HRS_CLIENT_CB_DATA *p_hrs_cb_data = (T_HRS_CLIENT_CB_DATA *)p_data; + switch (p_hrs_cb_data->cb_type) + { + case HRS_CLIENT_CB_TYPE_WRITE_RESULT: + switch (p_hrs_cb_data->cb_content.write_result.type) + { + case HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_ENABLE: + APP_PRINT_INFO1("HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_ENABLE: write result 0x%x", + p_hrs_cb_data->cb_content.write_result.cause); + break; + case HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_DISABLE: + APP_PRINT_INFO1("HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_DISABLE: write result 0x%x", + p_hrs_cb_data->cb_content.write_result.cause); + break; + default: + break; + } + break; + + case HRS_CLIENT_CB_TYPE_NOTIF_IND_RESULT: + { + if (p_hrs_cb_data->cb_content.notify_data.type == HRS_FROM_HEART_RATE_MEASUREMENT) + { + T_HEART_RATE_MEASUREMENT_VALUE hrs_heart_rate_measurement_value; + uint8_t heart_rate_measurement_flag; + + LE_STREAM_TO_UINT8(heart_rate_measurement_flag, p_hrs_cb_data->cb_content.notify_data.p_value); + + memcpy(&hrs_heart_rate_measurement_value.flag, &heart_rate_measurement_flag, sizeof(uint8_t)); + + if (p_hrs_cb_data->cb_type == HRS_CLIENT_CB_TYPE_NOTIF_IND_RESULT) + { + APP_PRINT_INFO0("HRS_CLIENT_CB_TYPE_NOTIF_HEART_RATE_MEASUREMENT"); + } + + if (hrs_heart_rate_measurement_value.flag.heart_rate_value_format_bit) + { + LE_STREAM_TO_UINT16(hrs_heart_rate_measurement_value.heart_rate_measurement_value, + p_hrs_cb_data->cb_content.notify_data.p_value); + APP_PRINT_INFO3("heart rate measurement flag 0x%x, heart_rate_value_format %d, heart_rate_measurement_value 0x%x", + heart_rate_measurement_flag, Heart_Rate_Value_Format_UINT16, + hrs_heart_rate_measurement_value.heart_rate_measurement_value); + } + else + { + LE_STREAM_TO_UINT8(hrs_heart_rate_measurement_value.heart_rate_measurement_value, + p_hrs_cb_data->cb_content.notify_data.p_value); + APP_PRINT_INFO3("heart rate measurement flag 0x%x, heart_rate_value_format %d, heart_rate_measurement_value 0x%x", + heart_rate_measurement_flag, Heart_Rate_Value_Format_UINT8, + hrs_heart_rate_measurement_value.heart_rate_measurement_value); + } + + if (hrs_heart_rate_measurement_value.flag.energy_expended_status_bit) + { + LE_STREAM_TO_UINT16(hrs_heart_rate_measurement_value.energy_expended, + p_hrs_cb_data->cb_content.notify_data.p_value); + APP_PRINT_INFO1("heart rate measurement energy_expended 0x%x", + hrs_heart_rate_measurement_value.energy_expended); + } + + if (hrs_heart_rate_measurement_value.flag.rr_interval_bit) + { + LE_STREAM_TO_UINT16(hrs_heart_rate_measurement_value.rr_interval, + p_hrs_cb_data->cb_content.notify_data.p_value); + APP_PRINT_INFO1("heart rate measurement rr_interval 0x%x", + hrs_heart_rate_measurement_value.rr_interval); + } + } + } + break; + ...... + } + ...... + } + * \endcode + */ +bool hrs_set_heart_rate_measurement_notify(uint8_t conn_id, bool notify); + +/** @} End of HRS_CLIENT_Exported_Functions */ + +/** @} End of HRS_CLIENT */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HRS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/ias_client.h b/inc/bluetooth/profile/client/ias_client.h new file mode 100644 index 0000000..01211c5 --- /dev/null +++ b/inc/bluetooth/profile/client/ias_client.h @@ -0,0 +1,284 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ias_client.h + * @brief Head file for using Ias BLE Client. + * @details Ias data structs and external functions declaration. + * @author ken + * @date 2017-12-04 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _IAS_CLIENT_H_ +#define _IAS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + +/** @defgroup IAS_Client Ias service client + * @brief ias service client + * @details + Ias Profile is a customized BLE-based Profile. Ias ble service please refer to @ref IAS_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup IAS_Client_Exported_Macros IAS Client Exported Macros + * @brief + * @{ + */ +/** @defgroup IAS UUIDs + * @brief Ias BLE Profile UUID definitions + * @{ + */ + +#define GATT_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 +#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06 + +/** @} End of SIMP_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define IAS_MAX_LINKS 2 +/** End of IAS_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup IAS_Client_Exported_Types IAS Client Exported Types + * @brief + * @{ + */ + +/** @brief IAS client handle type*/ +typedef enum +{ + HDL_IAS_SRV_START, //!< start handle of simple ble service + HDL_IAS_SRV_END, //!< end handle of simple ble service + HDL_IAS_WRITE, //!< V2 write characteristic value handle + HDL_IAS_CACHE_LEN //!< handle cache length +} T_IAS_HANDLE_TYPE; + +/** @brief IAS client discovery state*/ +typedef enum +{ + DISC_IAS_IDLE, + DISC_IAS_START, + DISC_IAS_DONE, + DISC_IAS_FAILED +} T_IAS_DISC_STATE; + +///** @brief ias client read type*/ +//typedef enum +//{ +// IAS_READ_V1_READ, +// IAS_READ_V3_NOTIFY_CCCD, +// IAS_READ_V4_INDICATE_CCCD, +//} T_IAS_READ_TYPE; + +///** @brief IAS client read value*/ +//typedef struct +//{ +// uint16_t value_size; +// uint8_t *p_value; +//} T_IAS_READ_VALUE; + +///** @brief IAS client read data*/ +//typedef union +//{ +// T_IAS_READ_VALUE v1_read; +// bool v3_notify_cccd; +// bool v4_indicate_cccd; +//} T_IAS_READ_DATA; + +///** @brief IAS client read result*/ +//typedef struct +//{ +// T_IAS_READ_TYPE type; +// T_IAS_READ_DATA data; +// uint16_t cause; +//} T_IAS_READ_RESULT; + + +/** @brief IAS client write type*/ +typedef enum +{ + IAS_WRITE_ALERT, +} T_IAS_WRTIE_TYPE; + +/** @brief IAS client write result*/ +typedef struct +{ + T_IAS_WRTIE_TYPE type; + uint16_t cause; +} T_IAS_WRITE_RESULT; + +///** @brief IAS client notif/ind receive type*/ +//typedef enum +//{ +// IAS_V3_NOTIFY, +// IAS_V4_INDICATE, +//} T_IAS_NOTIF_IND_TYPE; + +///** @brief IAS client notif/ind receive data*/ +//typedef struct +//{ +// uint16_t value_size; +// uint8_t *p_value; +//} T_IAS_NOTIF_IND_VALUE; + +///** @brief IAS client notif/ind receive content*/ +//typedef struct +//{ +// T_IAS_NOTIF_IND_TYPE type; +// T_IAS_NOTIF_IND_VALUE data; +//} T_IAS_NOTIF_IND_DATA; + +/** @brief IAS client callback type*/ +typedef enum +{ + IAS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + //IAS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + IAS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + // IAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + IAS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_IAS_CLIENT_CB_TYPE; + +/** @brief IAS client callback content*/ +typedef union +{ + T_IAS_DISC_STATE disc_state; + //T_IAS_READ_RESULT read_result; + T_IAS_WRITE_RESULT write_result; + //T_IAS_NOTIF_IND_DATA notif_ind_data; +} T_IAS_CLIENT_CB_CONTENT; + +/** @brief IAS client callback data*/ +typedef struct +{ + T_IAS_CLIENT_CB_TYPE cb_type; + T_IAS_CLIENT_CB_CONTENT cb_content; +} T_IAS_CLIENT_CB_DATA; + +/** End of IAS_Client_Exported_Types * @} */ + +/** @defgroup IAS_Client_Exported_Functions IAS Client Exported Functions + * @{ + */ + +/** + * @brief Add ias service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + ias_client_id = ias_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID ias_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of ias server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ias_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool ias_client_read_by_handle(uint8_t conn_id, T_IAS_READ_TYPE read_type); + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool ias_client_read_by_uuid(uint8_t conn_id, T_IAS_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ias_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ias_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ias_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of IAS_Client_Exported_Functions */ + +/** @} End of IAS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _IAS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/ipss_client.h b/inc/bluetooth/profile/client/ipss_client.h new file mode 100644 index 0000000..3aa5348 --- /dev/null +++ b/inc/bluetooth/profile/client/ipss_client.h @@ -0,0 +1,74 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ipss_client.c + * @brief Source file for client of internet protocol support service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-05 + * @version v1.0 + * ************************************************************************************* + */ + + +#ifndef _IPSS_CLIENT_H_ +#define _IPSS_CLIENT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup IPSS_CLIENT Internet Protocol Support Service Client + * @brief Internet Protocol Support Service Client + * @details + + IPSS client is used to discover Internet Protocol Support Service, this file could be used if application need to find IPSS. + + Application shall register IPSS client when initialization through @ref ipss_add_client function. + + Application can start discovery IPSS service through @ref ipss_find_srv_dcl function. + + * @{ + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup IPSS_CLIENT_Exported_Functions Internet Protocol Support Service Client Exported Functions + * @brief + * @{ + */ + + +/** + * @brief add IPS service client. + * + * @param[in] p_func pointer of app callback function called by client. + * @return client id. + */ +uint8_t ipss_add_client(void *p_func); + +/** + * @brief discover IPS service by service uuid . + * + * @param[in] conn_id connection id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool ipss_find_srv_dcl(uint8_t conn_id); + +/** @} End of IPSS_CLIENT_Exported_Functions */ + +/** @} End of IPSS_CLIENT */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/bluetooth/profile/client/kns_client.h b/inc/bluetooth/profile/client/kns_client.h new file mode 100644 index 0000000..c2902f6 --- /dev/null +++ b/inc/bluetooth/profile/client/kns_client.h @@ -0,0 +1,289 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file kns_client.h + * @brief Head file for using KNS Client. + * @details kns data structs and external functions declaration. + * @author ken + * @date 2017-12-04 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _KNS_CLIENT_H_ +#define _KNS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + +/** @defgroup KNS_Client Kns service client + * @brief kns service client + * @details + kns Profile is a customized BLE-based Profile. Kns ble service please refer to @ref KNS_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup KNS_Client_Exported_Macros KNS Client Exported Macros + * @brief + * @{ + */ +/** @defgroup KNS UUIDs + * @brief Kns BLE Profile UUID definitions + * @{ + */ +//#define GATT_UUID_EXS 0xFFD0 +//#define GATT_UUID_CHAR_PARAM 0xFFD1 +//#define GATT_UUID_CHAR_KEY 0xFFD2 +extern uint8_t GATT_UUID128_KNS_SERVICE[16]; +#define GATT_UUID128_KNS 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD0, 0xFF, 0x00, 0x00, +#define GATT_UUID128_CHAR_PARAM 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD1, 0xFF, 0x00, 0x00, +#define GATT_UUID128_CHAR_KEY 0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD2, 0xFF, 0x00, 0x00, + +/** @} End of KNS_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define KNS_MAX_LINKS 2 +/** End of KNS_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup KNS_Exported_Types KNS Client Exported Types + * @brief + * @{ + */ + +/** @brief KNS client handle type*/ +typedef enum +{ + HDL_KNS_SRV_START, //!< start handle of kns service + HDL_KNS_SRV_END, //!< end handle of kns service + HDL_KNS_PARA, //!< KNS parameter read/write characteristic value handle + HDL_KNS_NOTIFY_KEY, //!< key notify characteristic value handle + HDL_KNS_NOTIFY_KEY_CCCD, //!< key notify characteristic CCCD handle + HDL_KNS_CACHE_LEN //!< handle cache length +} T_KNS_HANDLE_TYPE; + +/** @brief KNS client discovery state*/ +typedef enum +{ + DISC_KNS_IDLE, + DISC_KNS_START, + DISC_KNS_DONE, + DISC_KNS_FAILED +} T_KNS_DISC_STATE; + +/** @brief kns client read type*/ +typedef enum +{ + KNS_READ_PARAM, + KNS_READ_KEY_NOTIFY_CCCD, +} T_KNS_READ_TYPE; + +/** @brief KNS client read value*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_KNS_READ_VALUE; + +/** @brief KNS client read data*/ +typedef union +{ + T_KNS_READ_VALUE v1_read; + bool v3_notify_cccd; + bool v4_indicate_cccd; +} T_KNS_READ_DATA; + +/** @brief KNS client read result*/ +typedef struct +{ + T_KNS_READ_TYPE type; + T_KNS_READ_DATA data; + uint16_t cause; +} T_KNS_READ_RESULT; + + +/** @brief KNS client write type*/ +typedef enum +{ + KNS_WRITE_PARAM, + KNS_WRITE_KEY_NOTIFY_CCCD, +} T_KNS_WRTIE_TYPE; + +/** @brief KNS client write result*/ +typedef struct +{ + T_KNS_WRTIE_TYPE type; + uint16_t cause; +} T_KNS_WRITE_RESULT; + +/** @brief KNS client notif/ind receive type*/ +typedef enum +{ + KNS_KEY_NOTIFY, +} T_KNS_NOTIF_IND_TYPE; + +/** @brief KNS client notif/ind receive data*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_KNS_NOTIF_IND_VALUE; + +/** @brief KNS client notif/ind receive content*/ +typedef struct +{ + T_KNS_NOTIF_IND_TYPE type; + T_KNS_NOTIF_IND_VALUE data; +} T_KNS_NOTIF_IND_DATA; + +/** @brief KNS client callback type*/ +typedef enum +{ + KNS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + KNS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + KNS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + KNS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_KNS_CLIENT_CB_TYPE; + +/** @brief KNS client callback content*/ +typedef union +{ + T_KNS_DISC_STATE disc_state; + T_KNS_READ_RESULT read_result; + T_KNS_WRITE_RESULT write_result; + T_KNS_NOTIF_IND_DATA notif_ind_data; +} T_KNS_CLIENT_CB_CONTENT; + +/** @brief KNS client callback data*/ +typedef struct +{ + T_KNS_CLIENT_CB_TYPE cb_type; + T_KNS_CLIENT_CB_CONTENT cb_content; +} T_KNS_CLIENT_CB_DATA; + +/** End of KNS_Client_Exported_Types * @} */ + +/** @defgroup KNS_Client_Exported_Functions KNS Client Exported Functions + * @{ + */ + +/** + * @brief Add kns service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + kns_client_id = kns_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID kns_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of ias server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_read_by_handle(uint8_t conn_id, T_KNS_READ_TYPE read_type); + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_read_by_uuid(uint8_t conn_id, T_KNS_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of V2 write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool kns_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool kns_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of KNS_Client_Exported_Functions */ + +/** @} End of KNS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _KNS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/lls_client.h b/inc/bluetooth/profile/client/lls_client.h new file mode 100644 index 0000000..2bb9262 --- /dev/null +++ b/inc/bluetooth/profile/client/lls_client.h @@ -0,0 +1,279 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file lls_client.h + * @brief Head file for using LLS Client. + * @details lls data structs and external functions declaration. + * @author ken + * @date 2017-12-05 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _LLS_CLIENT_H_ +#define _LLS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + +/** @defgroup LLS_Client lls service client + * @brief lls service client + * @details + lls Profile is a customized BLE-based Profile. Lls ble service please refer to @ref LLS_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup LLS_Client_Exported_Macros LLS Client Exported Macros + * @brief + * @{ + */ +/** @defgroup LLS UUIDs + * @brief Lls BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_LINK_LOSS_SERVICE 0x1803 +#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06 +/** @} End of LLS_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define LLS_MAX_LINKS 2 +/** End of LLS_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup LLS_Exported_Types LLS Client Exported Types + * @brief + * @{ + */ + +/** @brief LLS client handle type*/ +typedef enum +{ + HDL_LLS_SRV_START, //!< start handle of lls service + HDL_LLS_SRV_END, //!< end handle of lls service + HDL_LLS_PARA, //!< LLS parameter read/write characteristic value handle + HDL_LLS_CACHE_LEN //!< handle cache length +} T_LLS_HANDLE_TYPE; + +/** @brief LLS client discovery state*/ +typedef enum +{ + DISC_LLS_IDLE, + DISC_LLS_START, + DISC_LLS_DONE, + DISC_LLS_FAILED +} T_LLS_DISC_STATE; + +/** @brief lls client read type*/ +typedef enum +{ + LLS_READ_PARA, +} T_LLS_READ_TYPE; + +/** @brief LLS client read value*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_LLS_READ_VALUE; + +/** @brief LLS client read data*/ +typedef union +{ + T_LLS_READ_VALUE v1_read; +// bool v3_notify_cccd; +// bool v4_indicate_cccd; +} T_LLS_READ_DATA; + +/** @brief LLS client read result*/ +typedef struct +{ + T_LLS_READ_TYPE type; + T_LLS_READ_DATA data; + uint16_t cause; +} T_LLS_READ_RESULT; + + +/** @brief LLS client write type*/ +typedef enum +{ + LLS_WRITE_PARA, +} T_LLS_WRTIE_TYPE; + +/** @brief LLS client write result*/ +typedef struct +{ + T_LLS_WRTIE_TYPE type; + uint16_t cause; +} T_LLS_WRITE_RESULT; + +/** @brief LLS client notif/ind receive type*/ +//typedef enum +//{ +// LLS_KEY_NOTIFY, +//} T_LLS_NOTIF_IND_TYPE; + +///** @brief LLS client notif/ind receive data*/ +//typedef struct +//{ +// uint16_t value_size; +// uint8_t *p_value; +//} T_LLS_NOTIF_IND_VALUE; + +/** @brief LLS client notif/ind receive content*/ +//typedef struct +//{ +// T_LLS_NOTIF_IND_TYPE type; +// T_LLS_NOTIF_IND_VALUE data; +//} T_LLS_NOTIF_IND_DATA; + +/** @brief LLS client callback type*/ +typedef enum +{ + LLS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + LLS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + LLS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_LLS_CLIENT_CB_TYPE; + +/** @brief LLS client callback content*/ +typedef union +{ + T_LLS_DISC_STATE disc_state; + T_LLS_READ_RESULT read_result; + T_LLS_WRITE_RESULT write_result; + //T_LLS_NOTIF_IND_DATA notif_ind_data; +} T_LLS_CLIENT_CB_CONTENT; + +/** @brief LLS client callback data*/ +typedef struct +{ + T_LLS_CLIENT_CB_TYPE cb_type; + T_LLS_CLIENT_CB_CONTENT cb_content; +} T_LLS_CLIENT_CB_DATA; + +/** End of LLS_Client_Exported_Types * @} */ + +/** @defgroup LLS_Client_Exported_Functions LLS Client Exported Functions + * @{ + */ + +/** + * @brief Add lls service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + lls_client_id = lls_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID lls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of lls server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_read_by_handle(uint8_t conn_id, T_LLS_READ_TYPE read_type); + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_read_by_uuid(uint8_t conn_id, T_LLS_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool lls_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool lls_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of LLS_Client_Exported_Functions */ + +/** @} End of LLS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _LLS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/ota_client.h b/inc/bluetooth/profile/client/ota_client.h new file mode 100644 index 0000000..dca4f21 --- /dev/null +++ b/inc/bluetooth/profile/client/ota_client.h @@ -0,0 +1,254 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ota_client.h + * @brief Head file for using ota service Client. + * @details Data structs and external functions declaration. + * @author + * @date + * @version + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _OTA_CLIENT_H_ +#define _OTA_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Add Includes here */ +#include "profile_client.h" +#include "dfu_api.h" + +/** @defgroup OTA_Client OTA Service Client + * @{ + */ + +/*============================================================================* +* Macros +*============================================================================*/ +/** @addtogroup OTA_Client_Exported_Macros OTA Client Exported Macros + * @brief + * @{ + */ +/** @defgroup OTA UUIDs + * @brief ota BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_OTA_SERVICE 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00 + +#define GATT_UUID_OTA_PROFILE + +#define GATT_UUID_CHAR_OTA 0xFFD1 //1, write +#define GATT_UUID_CHAR_MAC 0xFFD2 //2 +#define GATT_UUID_CHAR_PATCH 0xFFD3 //3 +#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4 +#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5 +#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6, write + +#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7 +#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8, write +#define GATT_UUID_CHAR_IMAGE_VERSION 0xFFE0 +/** @} End of OTA_UUIDs */ + + +#define OTA_WRITE_OTA_CMD_CHAR_VAL 0x01 +#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02 +#define OTA_WRITE_OTA_IMG_COUNTER_CHAR_VAL 0x03 + + +/** @brief Define links number. range: 0-4 */ +#define OTA_MAX_LINKS 4 +/** End of OTA_Client_Exported_Macros * @} */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup OTA_Client_Exported_Types OTA Client Exported Types + * @brief + * @{ + */ +/** @brief OTA client device info*/ +typedef struct _T_OTA_DEVICE_INFO +{ + uint8_t ictype; + uint8_t ota_version; + uint8_t secure_version; + T_OTA_MODE ota_mode; + + uint16_t max_buffer_size; + uint16_t rsvd; + + uint32_t img_indicator; +} T_OTA_DEVICE_INFO, *P_OTA_DEVICE_INFO; + +/** @brief OTA client handle type*/ +typedef enum +{ + HDL_OTA_SRV_START, //!< start handle of battery service + HDL_OTA_SRV_END, //!< end handle of battery service + HDL_OTA_CMD, //!< OTA CMD characteristic value handle + HDL_OTA_DEVICE_MAC, + HDL_OTA_PATCH_VER, + HDL_OTA_APP_VER, + HDL_OTA_PATCH_EXT_VER, + HDL_OTA_TEST_MODE, //!< OTA test mode characteristic handle + HDL_OTA_DEVICE_INFO, + HDL_OTA_IMG_COUNTER, //! + + +/** @defgroup SIMP_Client Simple BLE Service Client + * @brief Simple BLE service client + * @details + Simple BLE Profile is a customized BLE-based Profile. Simple ble service please refer to @ref SIMP_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SIMP_Client_Exported_Macros SIMP Client Exported Macros + * @brief + * @{ + */ +/** @defgroup SIMP_UUIDs SIMP UUIDs + * @brief Simple BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_SIMPLE_PROFILE 0xA00A +#define GATT_UUID_CHAR_SIMPLE_V1_READ 0xB001 +#define GATT_UUID_CHAR_SIMPLE_V2_WRITE 0xB002 +#define GATT_UUID_CHAR_SIMPLE_V3_NOTIFY 0xB003 +#define GATT_UUID_CHAR_SIMPLE_V4_INDICATE 0xB004 +/** @} End of SIMP_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define SIMP_MAX_LINKS 4 +/** End of SIMP_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SIMP_Client_Exported_Types SIMP Client Exported Types + * @brief + * @{ + */ + +/** @brief SIMP client handle type*/ +typedef enum +{ + HDL_SIMBLE_SRV_START, //!< start handle of simple ble service + HDL_SIMBLE_SRV_END, //!< end handle of simple ble service + HDL_SIMBLE_V1_READ, //!< V1 read characteristic value handle + HDL_SIMBLE_V2_WRITE, //!< V2 write characteristic value handle + HDL_SIMBLE_V3_NOTIFY, //!< V3 notify characteristic value handle + HDL_SIMBLE_V3_NOTIFY_CCCD, //!< V3 notify characteristic CCCD handle + HDL_SIMBLE_V4_INDICATE, //!< V4 indicate characteristic value handle + HDL_SIMBLE_V4_INDICATE_CCCD, //!< V4 indicate characteristic CCCD handle + HDL_SIMBLE_CACHE_LEN //!< handle cache length +} T_SIMP_HANDLE_TYPE; + +/** @brief SIMP client discovery state*/ +typedef enum +{ + DISC_SIMP_IDLE, + DISC_SIMP_START, + DISC_SIMP_DONE, + DISC_SIMP_FAILED +} T_SIMP_DISC_STATE; + +/** @brief SIMP client read type*/ +typedef enum +{ + SIMP_READ_V1_READ, + SIMP_READ_V3_NOTIFY_CCCD, + SIMP_READ_V4_INDICATE_CCCD, +} T_SIMP_READ_TYPE; + +/** @brief SIMP client read value*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_SIMP_READ_VALUE; + +/** @brief SIMP client read data*/ +typedef union +{ + T_SIMP_READ_VALUE v1_read; + bool v3_notify_cccd; + bool v4_indicate_cccd; +} T_SIMP_READ_DATA; + +/** @brief SIMP client read result*/ +typedef struct +{ + T_SIMP_READ_TYPE type; + T_SIMP_READ_DATA data; + uint16_t cause; +} T_SIMP_READ_RESULT; + + +/** @brief SIMP client write type*/ +typedef enum +{ + SIMP_WRITE_V2_WRITE, + SIMP_WRITE_V3_NOTIFY_CCCD, + SIMP_WRITE_V4_INDICATE_CCCD, +} T_SIMP_WRTIE_TYPE; + +/** @brief SIMP client write result*/ +typedef struct +{ + T_SIMP_WRTIE_TYPE type; + uint16_t cause; +} T_SIMP_WRITE_RESULT; + +/** @brief SIMP client notif/ind receive type*/ +typedef enum +{ + SIMP_V3_NOTIFY, + SIMP_V4_INDICATE, +} T_SIMP_NOTIF_IND_TYPE; + +/** @brief SIMP client notif/ind receive data*/ +typedef struct +{ + uint16_t value_size; + uint8_t *p_value; +} T_SIMP_NOTIF_IND_VALUE; + +/** @brief SIMP client notif/ind receive content*/ +typedef struct +{ + T_SIMP_NOTIF_IND_TYPE type; + T_SIMP_NOTIF_IND_VALUE data; +} T_SIMP_NOTIF_IND_DATA; + +/** @brief SIMP client callback type*/ +typedef enum +{ + SIMP_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + SIMP_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + SIMP_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + SIMP_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_SIMP_CLIENT_CB_TYPE; + +/** @brief SIMP client callback content*/ +typedef union +{ + T_SIMP_DISC_STATE disc_state; + T_SIMP_READ_RESULT read_result; + T_SIMP_WRITE_RESULT write_result; + T_SIMP_NOTIF_IND_DATA notif_ind_data; +} T_SIMP_CLIENT_CB_CONTENT; + +/** @brief SIMP client callback data*/ +typedef struct +{ + T_SIMP_CLIENT_CB_TYPE cb_type; + T_SIMP_CLIENT_CB_CONTENT cb_content; +} T_SIMP_CLIENT_CB_DATA; + +/** End of SIMP_Client_Exported_Types * @} */ + +/** @defgroup SIMP_Client_Exported_Functions SIMP Client Exported Functions + * @{ + */ + +/** + * @brief Add simple ble service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of Simple BLE server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_read_by_handle(uint8_t conn_id, T_SIMP_READ_TYPE read_type); + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_read_by_uuid(uint8_t conn_id, T_SIMP_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of V2 write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool simp_ble_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool simp_ble_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of SIMP_Client_Exported_Functions */ + +/** @} End of SIMP_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SIMPLE_BLE_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/client/tps_client.h b/inc/bluetooth/profile/client/tps_client.h new file mode 100644 index 0000000..24a790f --- /dev/null +++ b/inc/bluetooth/profile/client/tps_client.h @@ -0,0 +1,273 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file tps_client.h + * @brief Head file for using TPS Client. + * @details tps data structs and external functions declaration. + * @author ken + * @date 2017-12-05 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _TPS_CLIENT_H_ +#define _TPS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include + + +/** @defgroup TPS_Client tps service client + * @brief tps service client + * @details + tps Profile is a customized BLE-based Profile. Tps ble service please refer to @ref TPS_Service . + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup TPS_Client_Exported_Macros TPS Client Exported Macros + * @brief + * @{ + */ +/** @defgroup TPS UUIDs + * @brief Tps BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_TX_POWER_SERVICE 0x1804 +#define GATT_UUID_CHAR_TX_LEVEL 0x2A07 +/** @} End of TPS_UUIDs */ + +/** @brief Define links number. range: 0-4 */ +#define TPS_MAX_LINKS 2 +/** End of TPS_Client_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup TPS_Exported_Types TPS Client Exported Types + * @brief + * @{ + */ + +/** @brief TPS client handle type*/ +typedef enum +{ + HDL_TPS_SRV_START, //!< start handle of tps service + HDL_TPS_SRV_END, //!< end handle of tps service + HDL_TPS_PARA, //!< TPS parameter read/write characteristic value handle + HDL_TPS_CACHE_LEN //!< handle cache length +} T_TPS_HANDLE_TYPE; + +/** @brief TPS client discovery state*/ +typedef enum +{ + DISC_TPS_IDLE, + DISC_TPS_START, + DISC_TPS_DONE, + DISC_TPS_FAILED +} T_TPS_DISC_STATE; + +/** @brief tps client read type*/ +typedef enum +{ + TPS_READ_PARA, +} T_TPS_READ_TYPE; + + +/** @brief TPS client read data */ +typedef union +{ + uint8_t txpower_level; +} T_TPS_READ_DATA; + + +/** @brief TPS client read result*/ +typedef struct +{ + T_TPS_READ_TYPE type; + T_TPS_READ_DATA data; + uint16_t cause; +} T_TPS_READ_RESULT; + +/** @brief LLS client write type*/ +//typedef enum +//{ +// LLS_WRITE_PARA, +//} T_LLS_WRTIE_TYPE; + +///** @brief LLS client write result*/ +//typedef struct +//{ +// T_LLS_WRTIE_TYPE type; +// uint16_t cause; +//} T_LLS_WRITE_RESULT; + +/** @brief LLS client notif/ind receive type*/ +//typedef enum +//{ +// LLS_KEY_NOTIFY, +//} T_LLS_NOTIF_IND_TYPE; + +///** @brief LLS client notif/ind receive data*/ +//typedef struct +//{ +// uint16_t value_size; +// uint8_t *p_value; +//} T_LLS_NOTIF_IND_VALUE; + +/** @brief LLS client notif/ind receive content*/ +//typedef struct +//{ +// T_LLS_NOTIF_IND_TYPE type; +// T_LLS_NOTIF_IND_VALUE data; +//} T_LLS_NOTIF_IND_DATA; + +/** @brief TPS client callback type*/ +typedef enum +{ + TPS_CLIENT_CB_TYPE_DISC_STATE, //!< Discovery procedure state, done or pending. + TPS_CLIENT_CB_TYPE_READ_RESULT, //!< Read request's result data, responsed from server. + //LLS_CLIENT_CB_TYPE_WRITE_RESULT, //!< Write request result, success or fail. + //LLS_CLIENT_CB_TYPE_NOTIF_IND_RESULT, //!< Notification or indication data received from server. + TPS_CLIENT_CB_TYPE_INVALID //!< Invalid callback type, no practical usage. +} T_TPS_CLIENT_CB_TYPE; + +/** @brief TPS client callback content*/ +typedef union +{ + T_TPS_DISC_STATE disc_state; + T_TPS_READ_RESULT read_result; + //T_TPS_WRITE_RESULT write_result; + //T_LLS_NOTIF_IND_DATA notif_ind_data; +} T_TPS_CLIENT_CB_CONTENT; + +/** @brief TPS client callback data*/ +typedef struct +{ + T_TPS_CLIENT_CB_TYPE cb_type; + T_TPS_CLIENT_CB_CONTENT cb_content; +} T_TPS_CLIENT_CB_DATA; + +/** End of TPS_Client_Exported_Types * @} */ + +/** @defgroup TPS_Client_Exported_Functions TPS Client Exported Functions + * @{ + */ + +/** + * @brief Add tps service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + tps_client_id = tps_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID tps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num); + +/** + * @brief Used by application, to start the discovery procedure of ias server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool tps_start_discovery(uint8_t conn_id); + +/** + * @brief Used by application, to read power level from server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool tps_read_power_level(uint8_t conn_id); + + +//bool tps_client_read_by_handle(uint8_t conn_id, T_TPS_READ_TYPE read_type); + +///** +// * @brief Used by application, to read data from server by using UUIDs. +// * @param[in] conn_id connection ID. +// * @param[in] read_type one of characteristic that has the readable property. +// * @retval true send request to upper stack success. +// * @retval false send request to upper stack failed. +// */ +//bool tps_client_read_by_uuid(uint8_t conn_id, T_TPS_READ_TYPE read_type); + +/** + * @brief Used by application, to write data of write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool tps_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, +// T_GATT_WRITE_TYPE type); + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify); + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_set_v4_ind(uint8_t conn_id, bool ind); + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool tps_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool tps_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len); + +/** @} End of LLS_Client_Exported_Functions */ + +/** @} End of LLS_Client */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _KNS_CLIENT_H_ */ diff --git a/inc/bluetooth/profile/gatt.h b/inc/bluetooth/profile/gatt.h new file mode 100644 index 0000000..946597f --- /dev/null +++ b/inc/bluetooth/profile/gatt.h @@ -0,0 +1,275 @@ +#ifndef _GATT_H_ +#define _GATT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*============================================================================* +* Macros +*============================================================================*/ + +/** + + * \addtogroup GATT_SERVER_API GATT Server API + * + * \defgroup GATT_ATTRIBUTE GATT Attribute + * + * \brief GATT Attribute Definitions + * + * \ingroup GATT_SERVER_API + */ + +/** + * gatt.h + * + * \name GATT_DECLARATIONS_UUID + * \brief GATT declarations uuid. + * \anchor GATT_DECLARATIONS_UUID + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_UUID_PRIMARY_SERVICE 0x2800 /**< GATT Primary Service Declaration. */ +#define GATT_UUID_SECONDARY_SERVICE 0x2801 /**< GATT Secondary Service Declaration. */ +#define GATT_UUID_INCLUDE 0x2802 /**< GATT Include Declaration. */ +#define GATT_UUID_CHARACTERISTIC 0x2803 /**< GATT Characteristic Declaration. */ + +/** + * gatt.h + * + * \name GATT_DESCRIPTORS_UUID + * \brief GATT descriptors uuid. + * \anchor GATT_DESCRIPTORS_UUID + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_UUID_CHAR_EXTENDED_PROP 0x2900 /**< Characteristic Extended Properties. */ +#define GATT_UUID_CHAR_USER_DESCR 0x2901 /**< Characteristic User Description. */ +#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /**< Client Characteristic Configuration. */ +#define GATT_UUID_CHAR_SERVER_CONFIG 0x2903 /**< Server Characteristic Configuration. */ +#define GATT_UUID_CHAR_FORMAT 0x2904 /**< Characteristic Presentation Format. */ +#define GATT_UUID_CHAR_AGGR_FORMAT 0x2905 /**< Characteristic Aggregate Format. */ +#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /**< Valid Range. */ +#define GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE 0x2907 /**< External Report Reference. */ +#define GATT_UUID_CHAR_REPORT_REFERENCE 0x2908 /**< Report Reference. */ +#define GATT_UUID_CHAR_DESCRIPTOR_NUM_OF_DIGITALS 0x2909 /**< Number of Digitals. */ +#define GATT_UUID_CHAR_DESCRIPTOR_VALUE_TRIGGER_SETTING 0x290A /**< Value Trigger Setting. */ +#define GATT_UUID_CHAR_SENSING_CONFIGURATION 0x290B /**< Environmental Sensing Configuration. */ +#define GATT_UUID_CHAR_SENSING_MEASUREMENT 0x290C /**< Environmental Sensing Measurement. */ +#define GATT_UUID_CHAR_SENSING_TRIGGER_SETTING 0x290D /**< Environmental Sensing Trigger Setting. */ +#define GATT_UUID_CHAR_DESCRIPTOR_TIME_TRIGGER_SETTING 0x290E /**< Time Trigger Setting. */ + +/** + * gatt.h + * + * \name GATT_CHARACTERISTICS_UUID + * \brief GATT characteristics uuid. + * \anchor GATT_CHARACTERISTICS_UUID + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_UUID_CHAR_DEVICE_NAME 0x2A00 /**< Device Name. */ +#define GATT_UUID_CHAR_APPEARANCE 0x2A01 /**< Appearance. */ +#define GATT_UUID_CHAR_PER_PRIV_FLAG 0x2A02 /**< Peripheral Privacy Flag. */ +#define GATT_UUID_CHAR_RECONN_ADDRESS 0x2A03 /**< Reconnection Address. */ +#define GATT_UUID_CHAR_PER_PREF_CONN_PARAM 0x2A04 /**< Peripheral Preferred Connection Parameters. */ +#define GATT_UUID_CHAR_SERVICE_CHANGED 0x2A05 /**< Service Changed. */ +#define GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION 0x2AA6 /**< Central Address Resolution. */ +#define GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY 0x2AC9 /**< Resolvable Private Address Only. */ +#define GATT_UUID_CHAR_CLIENT_SUPPORTED_FEATURES 0x2B29 /**< Client Supported Features. */ +#define GATT_UUID_CHAR_DATABASE_HASH 0x2B2A /**< Database Hash. */ + +/** @brief GATT Service Client Supported Features length. variable length, 1 is used in Core Spec v5.2. */ +#define GATTS_CLIENT_SUPPORTED_FEATURES_LEN 1 + +/** @brief GATT Service Database Hash length. */ +#define GATTS_DATABASE_HASH_LEN 16 + +/** + * gatt.h + * + * \name GATT_SERVICE_UUID + * \brief GATT services uuid. + * \anchor GATT_SERVICE_UUID + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_UUID_GAP 0x1800 /**< Generic Access. */ +#define GATT_UUID_GATT 0x1801 /**< Generic Attribute. */ + +/** + * gatt.h + * + * \name GATT_ATTRIBUTE_PERMISSIONS + * \brief Attribute read/write permissions, encryption key size. + * \anchor GATT_ATTRIBUTE_PERMISSIONS + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_PERM_NONE 0x00 +#define GATT_PERM_ALL 0x01 /**< bits 0..1 (rd), 4..5 (wr), 8..9 (notif/ind) */ +#define GATT_PERM_AUTHEN_REQ 0x02 +#define GATT_PERM_AUTHEN_MITM_REQ 0x03 +#define GATT_PERM_AUTHOR_REQ 0x04 /**< bits 2 (rd), 6 (wr), 10 (notif/ind) */ +#define GATT_PERM_ENCRYPTED_REQ 0x08 /**< bits 3 (rd), 7 (wr), 11 (notif/ind) */ +#define GATT_PERM_AUTHEN_SC_REQ 0x00010000 + +/** @brief read (bits 0..3) */ +#define GATT_PERM_READ GATT_PERM_ALL +#define GATT_PERM_READ_AUTHEN_REQ GATT_PERM_AUTHEN_REQ +#define GATT_PERM_READ_AUTHEN_MITM_REQ GATT_PERM_AUTHEN_MITM_REQ +#define GATT_PERM_READ_AUTHOR_REQ GATT_PERM_AUTHOR_REQ +#define GATT_PERM_READ_ENCRYPTED_REQ GATT_PERM_ENCRYPTED_REQ +#define GATT_PERM_READ_AUTHEN_SC_REQ GATT_PERM_AUTHEN_SC_REQ + +#define GATT_PERM_READ_AUTHEN_GET(x) (x & 0x03) +#define GATT_PERM_READ_AUTHOR_GET(x) (x & 0x04) +#define GATT_PERM_READ_ENCRYPT_GET(x) (x & 0x08) +#define GATT_PERM_READ_AUTHEN_SC_GET(x) (x & 0x00010000) + +/** @brief write (bits 4..7) */ +#define GATT_PERM_WRITE (GATT_PERM_ALL << 4) +#define GATT_PERM_WRITE_AUTHEN_REQ (GATT_PERM_AUTHEN_REQ << 4) +#define GATT_PERM_WRITE_AUTHEN_MITM_REQ (GATT_PERM_AUTHEN_MITM_REQ << 4) +#define GATT_PERM_WRITE_AUTHOR_REQ (GATT_PERM_AUTHOR_REQ << 4) +#define GATT_PERM_WRITE_ENCRYPTED_REQ (GATT_PERM_ENCRYPTED_REQ << 4) +#define GATT_PERM_WRITE_AUTHEN_SC_REQ (GATT_PERM_AUTHEN_SC_REQ<<4) + +#define GATT_PERM_WRITE_AUTHEN_GET(x) ((x >> 4) & 0x03) +#define GATT_PERM_WRITE_AUTHOR_GET(x) ((x >> 4) & 0x04) +#define GATT_PERM_WRITE_ENCRYPT_GET(x) ((x >> 4) & 0x08) +#define GATT_PERM_WRITE_AUTHEN_SC_GET(x) ((x>>4) & 0x00010000) + +/** @brief notification/indication (bits 8..11) */ +#define GATT_PERM_NOTIF_IND (GATT_PERM_ALL << 8) +#define GATT_PERM_NOTIF_IND_AUTHEN_REQ (GATT_PERM_AUTHEN_REQ << 8) +#define GATT_PERM_NOTIF_IND_AUTHEN_MITM_REQ (GATT_PERM_AUTHEN_MITM_REQ << 8) +#define GATT_PERM_NOTIF_IND_AUTHOR_REQ (GATT_PERM_AUTHOR_REQ << 8) +#define GATT_PERM_NOTIF_IND_ENCRYPTED_REQ (GATT_PERM_ENCRYPTED_REQ << 8) +#define GATT_PERM_NOTIF_IND_AUTHEN_SC_REQ (GATT_PERM_AUTHEN_SC_REQ<<8) + +#define GATT_PERM_NOTIF_IND_AUTHEN_GET(x) ((x >> 8) & 0x03) +#define GATT_PERM_NOTIF_IND_AUTHOR_GET(x) ((x >> 8) & 0x04) +#define GATT_PERM_NOTIF_IND_ENCRYPT_GET(x) ((x >> 8) & 0x08) +#define GATT_PERM_NOTIF_IND_AUTHEN_SC_GET(x) ((x>>8) & 0x00010000) + +/** @brief key size - 1 (bits 12..15) */ +#define GATT_PERM_KEYSIZE(size) ((size-1) << 12) +#define GATT_PERM_KEYSIZE_GET(x, size) { \ + size = ((x >> 12) & 0x0F); \ + if ( size > 0 ) \ + size++; \ + } + +/** + * gatt.h + * + * \name GATT_CHARACTERISTIC_PROPERTIES + * \brief GATT characteristic properties. + * \anchor GATT_CHARACTERISTIC_PROPERTIES + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define GATT_CHAR_PROP_BROADCAST 0x01 /**< If set, permits broadcasts of the Characteristic Value using +Server Characteristic Configuration Descriptor. */ +#define GATT_CHAR_PROP_READ 0x02 /**< If set, permits reads of the Characteristic Value */ +#define GATT_CHAR_PROP_WRITE_NO_RSP 0x04 /**< If set, permit writes of the Characteristic Value without response */ +#define GATT_CHAR_PROP_WRITE 0x08 /**< If set, permits writes of the Characteristic Value with response */ +#define GATT_CHAR_PROP_NOTIFY 0x10 /**< If set, permits notifications of a Characteristic Value without acknowledgment */ +#define GATT_CHAR_PROP_INDICATE 0x20 /**< If set, permits indications of a Characteristic Value with acknowledgment */ +#define GATT_CHAR_PROP_WRITE_AUTHEN_SIGNED 0x40 /**< If set, permits signed writes to the Characteristic Value */ +#define GATT_CHAR_PROP_EXT_PROP 0x80 /**< If set, additional characteristic properties are defined in the Characteristic +Extended Properties Descriptor */ + +/** @brief GATT client characteristic configuration bit field */ +#define GATT_CLIENT_CHAR_CONFIG_DEFAULT 0x0000 /**< The Characteristic Value shall be neither indicated nor notified. */ +#define GATT_CLIENT_CHAR_CONFIG_NOTIFY 0x0001 /**< The Characteristic Value shall be notified. */ +#define GATT_CLIENT_CHAR_CONFIG_INDICATE 0x0002 /**< The Characteristic Value shall be indicated. */ +#define GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE 0x0003 /**< The Characteristic Value shall be both indicated and notified. */ + +#define GATT_CLIENT_CHAR_NOTIF_IND_DATA_PENGDING 0x8000 + +/** @brief GATT server characteristic configuration bit field */ +#define GATT_SERVER_CHAR_CONFIG_BROADCAST 0x0001 /**< The Characteristic Value shall be broadcast. */ + + +/** + * gatt.h + * + * \name GATT_UUID_SIZE + * \brief GATT uuid size. + * \anchor GATT_UUID_SIZE + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define UUID_16BIT_SIZE 2 /**< 16 bits UUID size. */ +#define UUID_128BIT_SIZE 16 /**< 128 bits UUID size. */ + +#define ATT_ATTRIBUTE_MAX_LENGTH 512 /**< Attribute Max length. */ + +#define HI_WORD(x) ((uint8_t)((x & 0xFF00) >> 8)) +#define LO_WORD(x) ((uint8_t)(x)) + + +/*--------------------------------------------------------------------------- + * GATT server attribute descriptor + *--------------------------------------------------------------------------*/ + +/** + * gatt.h + * + * \name GATT_ATTRIBUTE_FLAG + * \brief GATT attribute flag. + * \anchor GATT_ATTRIBUTE_FLAG + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +#define ATTRIB_FLAG_VOID 0x0000 /**< Attribute value neither supplied by application +nor included following 16bit UUID. Attribute value is pointed by p_value_context +and value_len shall be set to the length of attribute value. */ +#define ATTRIB_FLAG_UUID_128BIT 0x0001 /**< Attribute uses 128 bit UUID */ +#define ATTRIB_FLAG_VALUE_INCL 0x0002 /**< Attribute value is included following 16 bit UUID */ +#define ATTRIB_FLAG_VALUE_APPL 0x0004 /**< Application has to supply write value */ +#define ATTRIB_FLAG_ASCII_Z 0x0008 /**< Attribute value is ASCII_Z string */ +#define ATTRIB_FLAG_CCCD_APPL 0x0010 /**< Application will be informed about CCCD value is changed */ +#define ATTRIB_FLAG_CCCD_NO_FILTER 0x0020 /**< Application will be informed about CCCD value +when CCCD is write by client, no matter it is changed or not */ +#define ATTRIB_FLAG_INCLUDE_MULTI 0x0040 +#define ATTRIB_FLAG_LE 0x0800 /**< Used only for primary service declaration attributes if GATT over BLE is supported */ +#define ATTRIB_FLAG_SERVICE_ALLOW_APP 0x1000 /**< Used only for primary service declaration attributes if allowance of service is supplied by APP */ +/** + * gatt.h + * + * \name GATT_ATTRIBUTE_APPL + * \brief GATT attribute definition. + * \anchor GATT_ATTRIBUTE_APPL + */ +/** + * \ingroup GATT_ATTRIBUTE + */ +typedef struct +{ + uint16_t flags; /**< Attribute flags @ref GATT_ATTRIBUTE_FLAG */ + uint8_t type_value[2 + 14]; /**< 16 bit UUID + included value or 128 bit UUID */ + uint16_t value_len; /**< Length of value */ + void *p_value_context; /**< Pointer to value if @ref ATTRIB_FLAG_VALUE_INCL + and @ref ATTRIB_FLAG_VALUE_APPL not set */ + uint32_t permissions; /**< Attribute permission @ref GATT_ATTRIBUTE_PERMISSIONS */ +} T_ATTRIB_APPL; + +#ifdef __cplusplus +} +#endif + +#endif /* _GATT_H_ */ diff --git a/inc/bluetooth/profile/gatt_builtin_services.h b/inc/bluetooth/profile/gatt_builtin_services.h new file mode 100644 index 0000000..28130e3 --- /dev/null +++ b/inc/bluetooth/profile/gatt_builtin_services.h @@ -0,0 +1,276 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gatt_builtin_services.h + * @brief Head file for using builtin services, including GAP service and GATT service. + * @details GAPS data structs and external functions declaration. + * @author jane + * @date 2015-5-12 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _BUILTIN_SERVICES_H_ +#define _BUILTIN_SERVICES_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "upperstack_config.h" +#include "profile_server.h" + +/** @defgroup GAP_GATT_SERVICE GAP and GATT Inbox Services + * @brief GAP and GATT inbox services + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GAP_GATT_SERVICE_Exported_Macros GAP and GATT Service Exported Macros + * @brief + * @{ + */ + +/** @defgroup GAPS_Write_PROPERTY GAP Service Write Property + * @brief GAP service write property. + * @{ + */ +#define GAPS_PROPERTY_WRITE_DISABLE 0 +#define GAPS_PROPERTY_WRITE_ENABLE 1 +/** @} */ + + +/** @defgroup GAPS_WRITE_TYPE GAP and GATT Service Write Type + * @brief GAP and GATT Service Write Type. + * @{ + */ +#define GAPS_WRITE_DEVICE_NAME 1 +#define GAPS_WRITE_APPEARANCE 2 +#define GATT_SERVICE_CHANGE_CCCD_ENABLE 3 +#define GATT_SERVICE_CHANGE_CCCD_DISABLE 4 +#define GATT_SERVICE_WRITE_CLIENT_SUPPORTED_FEATURES 5 +/** @} */ + +/** @brief GATT Service Client Supported Features bit field. */ +#define GATTS_CLIENT_SUPPORTED_FEAUTRES_DEFAULT_VALUE 0x00 /**< Server shall not use any of the features associated with that bit when communicating with this client. */ +#define GATTS_CLIENT_SUPPORTED_FEAUTRES_ROBUST_CACHING_BIT 0x01 /**< The client supports robust caching. */ +#define GATTS_CLIENT_SUPPORTED_FEAUTRES_EATT_BEARER_BIT 0x02 /**< The client supports Enhanced ATT bearer. */ +#define GATTS_CLIENT_SUPPORTED_FEAUTRES_MULTI_NOTIF_BIT 0x04 /**< The client supports receiving ATT_MULTIPLE_HANDLE_VALUE_NTF PDUs. */ + +/** End of GAP_GATT_SERVICE_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GAP_GATT_SERVICE_Exported_Types GAP and GATT Service Exported Types + * @brief + * @{ + */ + +/** @brief GAPS parameter type */ +typedef enum +{ + GAPS_PARAM_DEVICE_NAME = 0x00, + GAPS_PARAM_APPEARANCE = 0x01, +#if F_BT_LE_PRIVACY_SUPPORT + GAPS_PARAM_CENTRAL_ADDRESS_RESOLUTION = 0x02, +#endif + GAPS_PARAM_DEVICE_NAME_PROPERTY = 0x03, + GAPS_PARAM_APPEARANCE_PROPERTY = 0x04, +} T_GAPS_PARAM_TYPE; + +/** @brief Builtin services data struct for notification data to application. */ +typedef struct +{ + uint8_t opcode; //!< ref: @ref GAPS_WRITE_TYPE + uint16_t len; + uint8_t *p_value; +} T_GAPS_UPSTREAM_MSG_DATA; + +/** @brief Builtin services callback data to inform application */ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + uint8_t conn_id; + T_GAPS_UPSTREAM_MSG_DATA msg_data; +} T_GAPS_CALLBACK_DATA; + +/** End of GAP_GATT_SERVICE_Exported_Types +* @} +*/ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GAP_GATT_SERVICE_Exported_Functions GAP and GATT Service Exported Functions + * @brief + * @{ + */ + +/** + * @brief Register callback to builtin services. + * + * @param[in] p_func Callback to notify app. + * @return none. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE; + uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE; + gaps_set_parameter(GAPS_PARAM_APPEARANCE_PROPERTY, sizeof(appearance_prop), &appearance_prop); + gaps_set_parameter(GAPS_PARAM_DEVICE_NAME_PROPERTY, sizeof(device_name_prop), &device_name_prop); + gatt_register_callback(gap_service_callback); + } + T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para; + APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id, + p_gap_data->msg_type); + if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + switch (p_gap_data->msg_data.opcode) + { + case GAPS_WRITE_DEVICE_NAME: + { + T_LOCAL_NAME device_name; + memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len); + device_name.local_name[p_gap_data->msg_data.len] = 0; + flash_save_local_name(&device_name); + } + break; + + case GAPS_WRITE_APPEARANCE: + { + uint16_t appearance_val; + T_LOCAL_APPEARANCE appearance; + + LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value); + appearance.local_appearance = appearance_val; + flash_save_local_appearance(&appearance); + } + break; + + default: + break; + } + } + else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION) + { + if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE) + { + APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE"); + } + } + return result; + } + * \endcode + */ +void gatt_register_callback(void *p_func); + +/** + * @brief Set GAP service parameter. + * + * @param[in] param_type parameter type to set: @ref T_GAPS_PARAM_TYPE + * @param[in] length value length to be set. + * @param[in] p_value value to set. + * @return parameter set result. + * @retval 0 false + * @retval 1 true + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE; + uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE; + gaps_set_parameter(GAPS_PARAM_APPEARANCE_PROPERTY, sizeof(appearance_prop), &appearance_prop); + gaps_set_parameter(GAPS_PARAM_DEVICE_NAME_PROPERTY, sizeof(device_name_prop), &device_name_prop); + gatt_register_callback(gap_service_callback); + } + * \endcode + */ +bool gaps_set_parameter(T_GAPS_PARAM_TYPE param_type, uint8_t length, void *p_value); + + +/** + * @brief Set the preferred connection parameter. + * + * @param[in] conn_interval_min Defines minimum value for the connection interval in the + following manner: + connIntervalmin = Conn_Interval_Min * 1.25 ms + Conn_Interval_Min range: 0x0006 to 0x0C80 + Value of 0xFFFF indicates no specific minimum. + Values outside the range (except 0xFFFF) are reserved for + future use. + * @param[in] conn_interval_max Defines maximum value for the connection interval in the + following manner: + connIntervalmax = Conn_Interval_Max * 1.25 ms + Conn_Interval_Max range: 0x0006 to 0x0C80 + Shall be equal to or greater than the Conn_Interval_Min. + Value of 0xFFFF indicates no specific maximum. + Values outside the range (except 0xFFFF) are reserved for + future use. + * @param[in] slave_latency Defines the slave latency for the connection in number of + connection events. + Slave latency range: 0x0000 to 0x01F3 + Values outside the range are reserved for future use. + * @param[in] supervision_timeout Defines the connection supervisor timeout multiplier as amultiple of 10ms. + Range: 0xFFFF indicates no specific value requested. + Range: 0x000A to 0x0C80 + Time = N * 10 ms + Time Range: 100 ms to 32 seconds + Values outside the range (except 0xFFFF) are reserved for + future use. + * @return none + */ +void gaps_set_peripheral_preferred_conn_param(uint16_t conn_interval_min, + uint16_t conn_interval_max, + uint16_t slave_latency, + uint16_t supervision_timeout); + +/** + * @brief Send service changed indication. + * + * @param[in] conn_id Connection id + * @param[in] start_handle Start of Affected Attribute Handle Range + * @param[in] end_handle End of Affected Attribute Handle Range + * @return parameter set result. + * @retval 0 false + * @retval 1 true + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + uint16_t start_handle = 0x05; + uint16_t end_handle = 0xFF; + gatts_service_changed_indicate(conn_id, start_handle, end_handle); + } + * \endcode + */ +bool gatts_service_changed_indicate(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle); + +/** End of GAP_GATT_SERVICE_Exported_Functions +* @} +*/ + +/** End of GAP_GATT_SERVICE +* @} +*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BUILTIN_SERVICES_H_ */ diff --git a/inc/bluetooth/profile/profile_client.h b/inc/bluetooth/profile/profile_client.h new file mode 100644 index 0000000..a25c800 --- /dev/null +++ b/inc/bluetooth/profile/profile_client.h @@ -0,0 +1,611 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file profile_client.h + * @brief Head file for profile client structure. + * @details Common data struct definition. + * @author ethan_su + * @date 2016-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef PROFILE_CLIENT_H +#define PROFILE_CLIENT_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#if F_BT_LE_GATT_CLIENT_SUPPORT +#include "gatt.h" +#include +#include "gap_le.h" + + +/** @defgroup GATT_CLIENT_API GATT Client API + * @brief GATT client API + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GATT_Client_Exported_Macros GATT Client Exported Macros + * @{ + */ +#define CLIENT_PROFILE_GENERAL_ID 0xff //!< General Client ID used by application, when directly calls the APIs of profile client layer. Distinguish with other specific client module. + +/** End of GATT_Client_Exported_Macros +* @} +*/ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GATT_Client_Exported_Types GATT Client Exported Types + * @{ + */ + +typedef uint8_t T_CLIENT_ID; //!< Client ID + +/* callback related data to inform application. */ + + +/** @brief Discovery state during discovery procedure.*/ +typedef enum +{ + DISC_STATE_IDLE, + DISC_STATE_SRV, + DISC_STATE_SRV_DONE, + DISC_STATE_RELATION, + DISC_STATE_RELATION_DONE, + DISC_STATE_CHAR, + DISC_STATE_CHAR_DONE, + DISC_STATE_CHAR_UUID16_DONE, + DISC_STATE_CHAR_UUID128_DONE, + DISC_STATE_CHAR_DESCRIPTOR, + DISC_STATE_CHAR_DESCRIPTOR_DONE, + DISC_STATE_FAILED +} T_DISCOVERY_STATE; + +/** @brief Discovery result type*/ +typedef enum +{ + DISC_RESULT_ALL_SRV_UUID16, + DISC_RESULT_ALL_SRV_UUID128, + DISC_RESULT_SRV_DATA, + DISC_RESULT_CHAR_UUID16, + DISC_RESULT_CHAR_UUID128, + DISC_RESULT_CHAR_DESC_UUID16, + DISC_RESULT_CHAR_DESC_UUID128, + DISC_RESULT_RELATION_UUID16, + DISC_RESULT_RELATION_UUID128, + DISC_RESULT_BY_UUID16_CHAR, + DISC_RESULT_BY_UUID128_CHAR, +} T_DISCOVERY_RESULT_TYPE; + +/** @brief GATT write type*/ +typedef enum +{ + GATT_WRITE_TYPE_REQ = 0x01, /**< ATT "Write Request" */ + GATT_WRITE_TYPE_CMD = 0x02, /**< ATT "Write Command" */ + GATT_WRITE_TYPE_SIGNED_CMD = 0x04 /**< ATT "Signed Write Command" */ +} T_GATT_WRITE_TYPE; + +typedef struct +{ + uint16_t att_handle; /**< The handle for the service declaration */ + uint16_t end_group_handle; /**< The handle of the last attribute + within the service definition */ + uint16_t uuid16; /**< 16 bit UUID */ +} T_GATT_SERVICE_ELEM16; + +typedef struct +{ + uint16_t att_handle; /**< The handle for the service declaration */ + uint16_t end_group_handle; + /**< The handle of the last attribute within the service definition */ + uint8_t uuid128[16]; /**< 128 bit UUID */ +} T_GATT_SERVICE_ELEM128; + + +typedef struct +{ + uint16_t att_handle; /**< The handle for the service declaration */ + uint16_t end_group_handle; + /**< The handle of the last attribute within the service definition */ +} T_GATT_SERVICE_BY_UUID_ELEM; + +/** @brief Characteristic declaration for 16 bit UUID.*/ +typedef struct +{ + uint16_t decl_handle; /**< Attribute handle */ + uint16_t properties; /**< Characteristic Properties, high nibble is reserved */ + uint16_t value_handle; /**< Characteristic Value Handle */ + uint16_t uuid16; /**< 16-bit Bluetooth UUID for Characteristic Value */ +} T_GATT_CHARACT_ELEM16; + +/** @brief Characteristic declaration for 128 bit UUID.*/ +typedef struct +{ + uint16_t decl_handle; /**< Attribute handle */ + uint16_t properties; /**< Characteristic Properties, high nibble is reserved */ + uint16_t value_handle; /**< Characteristic Value Handle */ + uint8_t uuid128[16]; /**< 128-bit UUID for Characteristic Value */ +} T_GATT_CHARACT_ELEM128; + +/** @brief Characteristic descriptor for 16 bit UUID.*/ +typedef struct +{ + uint16_t handle; /**< Attribute handle */ + uint16_t uuid16; /**< 16 bit UUID */ +} T_GATT_CHARACT_DESC_ELEM16; + +/** @brief Characteristic descriptor for 128 bit UUID.*/ +typedef struct +{ + uint16_t handle; /**< Attribute handle */ + uint8_t uuid128[16]; /**< 128 bit UUID */ +} T_GATT_CHARACT_DESC_ELEM128; + +/** @brief Relationship discovery for 16 bit UUID.*/ +typedef struct +{ + uint16_t decl_handle; + uint16_t att_handle; + uint16_t end_group_handle; + uint16_t uuid16; +} T_GATT_RELATION_ELEM16; + +/** @brief Relationship discovery for 128 bit UUID.*/ +typedef struct +{ + uint16_t decl_handle; + uint16_t att_handle; + uint16_t end_group_handle; + uint8_t uuid128[16]; +} T_GATT_RELATION_ELEM128; + +/** @brief Discovery result data*/ +typedef union +{ + T_GATT_SERVICE_ELEM16 *p_srv_uuid16_disc_data; + T_GATT_SERVICE_ELEM128 *p_srv_uuid128_disc_data; + T_GATT_SERVICE_BY_UUID_ELEM *p_srv_disc_data; + T_GATT_CHARACT_ELEM16 *p_char_uuid16_disc_data; + T_GATT_CHARACT_ELEM128 *p_char_uuid128_disc_data; + T_GATT_CHARACT_DESC_ELEM16 *p_char_desc_uuid16_disc_data; + T_GATT_CHARACT_DESC_ELEM128 *p_char_desc_uuid128_disc_data; + T_GATT_RELATION_ELEM16 *p_relation_uuid16_disc_data; + T_GATT_RELATION_ELEM128 *p_relation_uuid128_disc_data; +} T_DISCOVERY_RESULT_DATA; + +/** @defgroup General_cb_data General Client Callback Data + * @{ + */ +/** @brief The callback data of CLIENT_APP_CB_TYPE_DISC_STATE. + * + * Discovery procedure related data to inform application + */ +typedef struct +{ + T_DISCOVERY_STATE disc_state; +} T_DISC_STATE_CB_DATA; + +/** @brief The callback data of CLIENT_APP_CB_TYPE_DISC_RESULT. + * + * Discovery result data will be sent to upper through the callback + */ +typedef struct +{ + T_DISCOVERY_RESULT_TYPE result_type; + T_DISCOVERY_RESULT_DATA result_data; +} T_DISC_RESULT_CB_DATA; + + +/** @brief The callback type of T_CLIENT_APP_CB_DATA. + * + * Message data type, when data sent to app directly + */ +typedef enum +{ + CLIENT_APP_CB_TYPE_DISC_STATE, + CLIENT_APP_CB_TYPE_DISC_RESULT +} T_CLIENT_CB_TYPE; + +/** @brief The callback data of T_CLIENT_APP_CB_DATA. + * + * Client received data from server, when no specific client registered, will be sent to app directly + */ +typedef union +{ + T_DISC_STATE_CB_DATA disc_state_data; + T_DISC_RESULT_CB_DATA disc_result_data; +} T_CLIENT_CB_DATA; + +/** @brief The General Client Callback Data Struct. + * + * Callback data sent to application directly from client, include type and content + */ +typedef struct +{ + T_CLIENT_CB_TYPE cb_type; + T_CLIENT_CB_DATA cb_content; +} T_CLIENT_APP_CB_DATA; +/** End of General_cb_data + * @} + */ + + +/** @defgroup pfnSpecificClientAppCB_t1 General Client Callback Function Point Definition + * @{ function ponter used in each specific profile, to send events to application + */ +typedef T_APP_RESULT(*P_FUN_GENERAL_APP_CB)(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data); +/** End of pfnSpecificClientAppCB_t1 + * @} + */ + + +/** @defgroup Specific_cb Specific Client Callback Function Point Definition + * @{ Function ponter used in each specific client module, to send events to specific client module. + */ +typedef void (*P_FUN_DISCOVER_STATE_CB)(uint8_t conn_id, T_DISCOVERY_STATE discovery_state); +typedef void (*P_FUN_DISCOVER_RESULT_CB)(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data); +typedef void (*P_FUN_READ_RESULT_CB)(uint8_t conn_id, uint16_t cause, uint16_t handle, + uint16_t value_size, uint8_t *p_value); +typedef void (*P_FUN_WRITE_RESULT_CB)(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle, + uint16_t cause, uint8_t credits); +typedef T_APP_RESULT(*P_FUN_NOTIFY_IND_RESULT_CB)(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value); +typedef void (*P_FUN_DISCONNECT_CB)(uint8_t conn_id); +/** End of Specific_cb + * @} + */ + +/** @defgroup T_FUN_CLIENT_CBS Specific Client Callback Functions Struct + * @{ + */ +typedef struct +{ + P_FUN_DISCOVER_STATE_CB discover_state_cb; //!< Discovery state callback function pointer + P_FUN_DISCOVER_RESULT_CB discover_result_cb; //!< Discovery reault callback function pointer + P_FUN_READ_RESULT_CB read_result_cb; //!< Read response callback function pointer + P_FUN_WRITE_RESULT_CB write_result_cb; //!< Write result callback function pointer + P_FUN_NOTIFY_IND_RESULT_CB notify_ind_result_cb;//!< Notify Indication callback function pointer + P_FUN_DISCONNECT_CB disconnect_cb; //!< Disconnection callback function pointer +} T_FUN_CLIENT_CBS; +/** End of T_FUN_CLIENT_CBS * @} */ + +/** End of GATT_Client_Exported_Types +* @} +*/ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GATT_Client_Exported_Functions GATT Client Exported Functions + * @{ + */ +/** + * @brief Initialize parameters of GATT client. + * + * @param[in] client_num Set the number of clients that needs to register. + * @retval None + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + simple_ble_client_id = simp_ble_add_client(app_client_callback); + client_register_general_client_cb(app_client_callback); + } + * \endcode + */ +void client_init(uint8_t client_num); + +/** + * @brief Used by application, register general client callback. + * @param[in] p_fun_cb Fuction offered by application. + * @retval None + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + simple_ble_client_id = simp_ble_add_client(app_client_callback); + client_register_general_client_cb(app_client_callback); + } + * \endcode + */ +void client_register_general_client_cb(P_FUN_GENERAL_APP_CB p_fun_cb); + +/** + * @brief Used by specific client, register callback. + * @param[in,out] p_out_client_id Client ID generated for registered specific client module. + * @param[in] client_cbs Callback functions implemented in specific client module. + * @retval true Register successful. + * @retval false Register failed. + * + * Example usage + * \code{.c} + + T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) + { + uint16_t size; + if (link_num > SIMP_MAX_LINKS) + { + APP_PRINT_ERROR1("simp_ble_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&simp_client, &simp_ble_client_cbs)) + { + simp_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("simp_ble_add_client failed"); + return simp_client; + } + APP_PRINT_INFO1("simp_ble_add_client: simp_client %d", simp_client); + + simp_client_cb = app_cb; + simp_link_num = link_num; + size = simp_link_num * sizeof(T_SIMP_LINK); + simp_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return simp_client; + } + * \endcode + */ +bool client_register_spec_client_cb(T_CLIENT_ID *p_out_client_id, + const T_FUN_CLIENT_CBS *client_cbs); + +/** + * @brief Send discovery all primary services request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_all_primary_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id); + +/** + * @brief Send discovery services by 16 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] uuid16 16 bit UUID. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_by_uuid_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t uuid16); + +/** + * @brief Send discovery services by 128 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] p_uuid128 128 bit UUID. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_by_uuid128_srv_discovery(uint8_t conn_id, T_CLIENT_ID client_id, + uint8_t *p_uuid128); + +/** + * @brief Send discovery relationship services request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_relationship_discovery(uint8_t conn_id, T_CLIENT_ID client_id, + uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send discovery characteristics request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_all_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Send discovery characteristics request by caracteristic uuid. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] uuid16 16bit characteristic uuid to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_by_uuid_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id, + uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16); +/** + * @brief Send discovery characteristics request by caracteristic uuid. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] p_uuid128 128bit characteristic uuid to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_by_uuid128_char_discovery(uint8_t conn_id, T_CLIENT_ID client_id, + uint16_t start_handle, + uint16_t end_handle, uint8_t *p_uuid128); +/** + * @brief Send discovery characteristics descriptor request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @retval GAP_CAUSE_SUCCESS Discovery request success. + * @retval other Discovery request failed. + */ +T_GAP_CAUSE client_all_char_descriptor_discovery(uint8_t conn_id, T_CLIENT_ID client_id, + uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Read characteristic by handle request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] handle Request handle. + * @retval GAP_CAUSE_SUCCESS Read request success. + * @retval other Read request failed. + */ +T_GAP_CAUSE client_attr_read(uint8_t conn_id, T_CLIENT_ID client_id, uint16_t handle); + +/** + * @brief Read characteristic by 16 bit UUID request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] start_handle Start handle of range to be searched. + * @param[in] end_handle End handle of range to be searched. + * @param[in] uuid16 Request 16 bit UUID. + * @param[in] p_uuid128 Request 128 bit UUID. + * @retval GAP_CAUSE_SUCCESS Read request success. + * @retval other Read request failed. + */ +T_GAP_CAUSE client_attr_read_using_uuid(uint8_t conn_id, T_CLIENT_ID client_id, + uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16, uint8_t *p_uuid128); +/** + * @brief Write characteristic request. + * @param[in] conn_id Connection ID + * @param[in] client_id Client ID of specific client module. + * @param[in] write_type Type of write. + * @param[in] handle Attribute handle. + * @param[in] length Length of data to be written. + If write_type is GATT_WRITE_TYPE_REQ, range of length is from 0 to 512. + If write_type is GATT_WRITE_TYPE_CMD, range of length is from 0 to (mtu_size - 3). + If write_type is GATT_WRITE_TYPE_SIGNED_CMD, range of length is from 0 to (mtu_size - 15). + uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id). + * @param[in] p_data Point to the data to be written. + * @retval GAP_CAUSE_SUCCESS: Write request success. + * @retval other: Write request failed. + * + * Example usage + * \code{.c} + //if write_type is GATT_WRITE_TYPE_SIGNED_CMD, GAP_MSG_LE_GATT_SIGNED_STATUS_INFO will be notified to app + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA cb_data; + memcpy(&cb_data, p_cb_data, sizeof(T_LE_CB_DATA)); + APP_PRINT_TRACE1("app_gap_callback: cb_type = %d", cb_type); + switch (cb_type) + { + ... + case GAP_MSG_LE_GATT_SIGNED_STATUS_INFO: + APP_PRINT_INFO5("GAP_MSG_LE_GATT_SIGNED_STATUS_INFO:conn_id %d, cause 0x%x, update_local %d, local_sign_count %d,remote_sign_count %d", + cb_data.p_le_gatt_signed_status_info->conn_id, + cb_data.p_le_gatt_signed_status_info->cause, + cb_data.p_le_gatt_signed_status_info->update_local, + cb_data.p_le_gatt_signed_status_info->local_sign_count, + cb_data.p_le_gatt_signed_status_info->remote_sign_count); + break; + ... + } + } + * \endcode + */ +T_GAP_CAUSE client_attr_write(uint8_t conn_id, T_CLIENT_ID client_id, + T_GATT_WRITE_TYPE write_type, + uint16_t handle, uint16_t length, uint8_t *p_data); + +/** + * @brief Confirm from application when receive indication from server. + * @param[in] conn_id Connection ID indicate which link is. + * @retval true: Confirm OK. + * @retval false: Confirm failed. + */ +T_GAP_CAUSE client_attr_ind_confirm(uint8_t conn_id); + +/** + * @brief Get the header point of the notification data buffer. + * This function is used to get the header buffer point of the notification command data. + * This function only can be called in notify_ind_result_cb. + * + * @param[in] conn_id Connection id indicate which link is. + * @param[in,out] pp_buffer Pointer to the address of the buffer. + * @param[in,out] p_offset Pointer to the offset of the data. + * @return Buffer get result + * @retval true Success. + * @retval false Failed. + * + * Example usage + * \code{.c} + uint8_t *p_data_buf; + uint16_t data_offset; + static T_APP_RESULT simp_ble_client_notif_ind_result_cb(uint8_t conn_id, bool notify, + uint16_t handle, + uint16_t value_size, uint8_t *p_value) + { + ...... + client_get_notify_data_buffer(conn_id, &p_data_buf, &data_offset); + return APP_RESULT_NOT_RELEASE; + } + void release(void) + { + if(p_data_buf != NULL) + { + gap_buffer_free(p_data_buf); + p_data_buf = NULL; + } + } + * \endcode + */ +bool client_get_notify_data_buffer(uint8_t conn_id, uint8_t **pp_buffer, uint16_t *p_offset); + +/** + * @brief Send the exchange MTU request. + * This function is used to send the exchange MTU request. + * + * @param[in] conn_id Connection id indicate which link is. + * @retval GAP_CAUSE_SUCCESS: Write request success. + * @retval other: Write request failed. + * + * Example usage + * \code{.c} + uint8_t *p_data_buf; + uint16_t data_offset; + static T_USER_CMD_PARSE_RESULT cmd_send_mtu_req(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_GAP_CAUSE cause; + uint8_t conn_id = p_parse_value->dw_param[0]; + + cause = client_send_exchange_mtu_req(conn_id); + return (T_USER_CMD_PARSE_RESULT)cause; + } + * \endcode + */ +T_GAP_CAUSE client_send_exchange_mtu_req(uint8_t conn_id); + +/** End of GATT_Client_Exported_Functions +* @} +*/ + +/** End of GATT_CLIENT_API +* @} +*/ +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PROFILE_CLIENT_H */ + diff --git a/inc/bluetooth/profile/profile_server.h b/inc/bluetooth/profile/profile_server.h new file mode 100644 index 0000000..dd39e4a --- /dev/null +++ b/inc/bluetooth/profile/profile_server.h @@ -0,0 +1,594 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file profile_server.h + * @brief Head file for server structure. + * @details Common data struct definition. + * @author + * @date 2017-02-18 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef PROFILE_SERVER_H +#define PROFILE_SERVER_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "upperstack_config.h" +#if F_BT_LE_GATT_SERVER_SUPPORT +#include +#include "gatt.h" +#include "gap_le.h" + + +/** @defgroup GATT_SERVER_API GATT Server API + * @brief GATT Server API + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GATT_SERVER_Exported_Macros GATT Server Exported Macros + * @brief + * @{ + */ + +/** @defgroup General_Service_ID General Service ID + * @brief Service ID for general profile events. + * @{ + */ +#define SERVICE_PROFILE_GENERAL_ID 0xff +/** @} */ + +/** End of GATT_SERVER_Exported_Macros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GATT_SERVER_Exported_Types GATT Server Exported Types + * @brief + * @{ + */ + +typedef uint8_t T_SERVER_ID; //!< Service ID + +/** @brief GATT write data type*/ +typedef enum +{ + WRITE_REQUEST, /**< Write request. */ + WRITE_WITHOUT_RESPONSE, /**< Write without response. */ + WRITE_SIGNED_WITHOUT_RESPONSE, /**< Signed write without response. */ + WRITE_LONG, /**< Write long request. */ +} T_WRITE_TYPE; + +/** @brief GATT PDU type*/ +typedef enum +{ + GATT_PDU_TYPE_ANY = 0x00, /**< Any PDU type. */ + GATT_PDU_TYPE_NOTIFICATION = 0x01, /**< Notification PDU type. */ + GATT_PDU_TYPE_INDICATION = 0x02 /**< Indication PDU type. */ +} T_GATT_PDU_TYPE; + +/** @brief Event type to inform app*/ +typedef enum +{ + SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION = 1, /**< CCCD update event */ + SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE = 2, /**< client read event */ + SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE = 3, /**< client write event */ +} T_SERVICE_CALLBACK_TYPE; + +/** @brief service reg mode, only be used when: @ref GAP_INIT_STATE_STACK_READY*/ +typedef enum +{ + SERVICE_REG_MODE_ADD_TO_STACK = 0, /**< Default mode. Add service to stack. + When transition from SERVICE_REG_MODE_ADD_TO_TABLE to SERVICE_REG_MODE_ADD_TO_STACK, services in table have not been registered will be registered to stack. + When in this mode, only one new service can be added to table and registered to stack at one time */ + SERVICE_REG_MODE_ADD_TO_TABLE = 1, /**< Add services to table. */ +} T_SERVICE_REG_MODE; + +/** @defgroup GATT_SERVER_CB_DATA App Callback data + * @brief data for profile to inform application. + * @{ + */ +/** @brief Event ID */ +typedef enum +{ + PROFILE_EVT_SRV_REG_COMPLETE, /**< Services register complete event + when application calls server_add_service before calling gap_start_bt_stack. */ + PROFILE_EVT_SEND_DATA_COMPLETE, /**< Notification or indication data send complete event. */ + PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE, /**< Services register complete event + when application calls server_add_service after receiving @ref GAP_INIT_STATE_STACK_READY. */ + PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE, /**< Services clear complete event + when application calls server_clear_service after receiving @ref GAP_INIT_STATE_STACK_READY. */ +} T_SERVER_CB_TYPE; + +/** @brief The callback data of PROFILE_EVT_SRV_REG_COMPLETE */ +typedef enum +{ + GATT_SERVER_SUCCESS, + GATT_SERVER_FAIL +} T_SERVER_RESULT; + +/** @brief The callback data of PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE */ +typedef struct +{ + T_SERVER_RESULT result; + T_SERVER_ID service_id; + uint16_t cause; +} T_SERVER_REG_AFTER_INIT_RESULT; + +/** @brief The callback data of PROFILE_EVT_SEND_DATA_COMPLETE */ +typedef struct +{ + uint16_t credits; + uint8_t conn_id; + T_SERVER_ID service_id; + uint16_t attrib_idx; + uint16_t cause; +} T_SEND_DATA_RESULT; + +/** @brief The callback data of PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE */ +typedef struct +{ + uint16_t cause; + uint16_t svc_changed_char_cccd_handle; /**< 0x0000: Invalid handle. */ +} T_SERVER_CLEAR_SERVICE_AFTER_INIT_RESULT; + +/** @brief Service callback data */ +typedef union +{ + T_SERVER_RESULT service_reg_result; + T_SEND_DATA_RESULT send_data_result; + T_SERVER_REG_AFTER_INIT_RESULT server_reg_after_init_result; + T_SERVER_CLEAR_SERVICE_AFTER_INIT_RESULT clear_service_after_init_result; +} T_SERVER_CB_DATA; + +typedef struct +{ + T_SERVER_CB_TYPE eventId; /**< @brief EventId defined upper */ + T_SERVER_CB_DATA event_data; /**< @brief Event data */ +} T_SERVER_APP_CB_DATA; +/** @} End of GATT_SERVER_CB_DATA */ + + + +/** @defgroup P_FUN_WRITE_IND_POST_PROC TGATTDWriteIndPostProc + * @brief Call back function to execute some post procedure after handle write request from client. + * @{ + */ +typedef void (* P_FUN_WRITE_IND_POST_PROC)(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t length, + uint8_t *p_value); +/** @} End of P_FUN_WRITE_IND_POST_PROC */ + +/** @defgroup Specific_srv_cb Specific Service Callback Function Point Definition + * @{ Function ponter used in each specific service module, to send events to specific service module. + */ +typedef T_APP_RESULT(*P_FUN_GATT_READ_ATTR_CB)(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value); +typedef T_APP_RESULT(*P_FUN_GATT_WRITE_ATTR_CB)(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_post_proc); +typedef void (*P_FUN_GATT_CCCD_UPDATE_CB)(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t ccc_bits); +/** End of Specific_srv_cb + * @} + */ + +/** @defgroup P_FUN_SERVER_GENERAL_CB General Server Callback Function Point Definition + * @brief function ponter Type used to generate Call back, to send events to application. + * @{ + */ +typedef T_APP_RESULT(*P_FUN_SERVER_GENERAL_CB)(T_SERVER_ID service_id, void *p_para); +/** @} End of pfnAPPHandleInfoCB_t1 */ + + +/** @brief GATT service callbacks */ +typedef struct +{ + P_FUN_GATT_READ_ATTR_CB read_attr_cb; /**< Read callback function pointer. + Return value: @ref T_APP_RESULT. */ + P_FUN_GATT_WRITE_ATTR_CB write_attr_cb; /**< Write callback function pointer. + Return value: @ref T_APP_RESULT. */ + P_FUN_GATT_CCCD_UPDATE_CB cccd_update_cb; /**< Update cccd callback function pointer. */ +} T_FUN_GATT_SERVICE_CBS; + +/** End of GATT_SERVER_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GATT_SERVER_Exported_Functions GATT Server Exported Functions + * @brief + * @{ + */ + +/** + * @brief Initialize parameters of GATT Server. + * + * @param[in] service_num Set the number of services that needs to register. + * @retval None + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + server_init(1); + simp_srv_id = simp_ble_service_add_service(app_profile_callback); + server_register_app_cb(app_profile_callback); + } + * \endcode + */ +void server_init(uint8_t service_num); + +/** + * @brief Register builtin services including GAP and GATT service. + * + * If application does not need to register GAP and GATT service. + * Application shall call server_builtin_service_reg(false) before server_init(). + * + * @param[in] reg Whether to register builtin services. Default value is true. + * @retval None + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + server_builtin_service_reg(false); + server_init(1); + simp_srv_id = simp_ble_service_add_service(app_profile_callback); + server_register_app_cb(app_profile_callback); + } + * \endcode + */ +void server_builtin_service_reg(bool reg); + +/** + * @brief Register specific service without start handle + * + * Add specific service infomation to gatt_svc_table struct, will be registered to GATT later. + * + * @param[in,out] p_out_service_id Service ID of specific service. + * @param[in] p_database Database pointer of specific service. + * @param[in] length Length of Database of specific service. + * @param[in] srv_cbs Service callback functions of specific service. + * @retval true Add service success + * @retval false Add service failed + * + * Example usage + * \code{.c} + T_SERVER_ID bas_add_service(void *p_func) + { + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)bas_attr_tbl, + bas_attr_tbl_size, + bas_cbs)) + { + APP_PRINT_ERROR1("bas_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; + } + * \endcode + */ +bool server_add_service(T_SERVER_ID *p_out_service_id, uint8_t *p_database, uint16_t length, + const T_FUN_GATT_SERVICE_CBS srv_cbs); + +/** + * @brief Register specific service with start handle + * + * Add specific service infomation to gatt_svc_table struct, will be registered to GATT later. + * + * @param[in,out] p_out_service_id Service ID of specific service. + * @param[in] p_database Database pointer of specific service. + * @param[in] length Length of Database of specific service. + * @param[in] srv_cbs Service callback functions of specific service. + * @param[in] start_handle Start handle of this service. + * @retval true Add service success + * @retval false Add service failed + * + * Example usage + * \code{.c} + T_SERVER_ID bas_add_service(void *p_func) + { + T_SERVER_ID service_id; + if (false == server_add_service_by_start_handle(&service_id, + (uint8_t *)bas_attr_tbl, + bas_attr_tbl_size, + bas_cbs, 0x00f0)) + { + APP_PRINT_ERROR1("bas_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; + } + * \endcode + */ +bool server_add_service_by_start_handle(uint8_t *p_out_service_id, uint8_t *p_database, + uint16_t length, + const T_FUN_GATT_SERVICE_CBS srv_cbs, uint16_t start_handle); +/** + * @brief Register callback function to send events to application. + * + * @param[in] p_fun_cb Callback function. + * @retval None + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + server_init(1); + simp_srv_id = simp_ble_service_add_service(app_profile_callback); + server_register_app_cb(app_profile_callback); + } + * \endcode + */ +void server_register_app_cb(P_FUN_SERVER_GENERAL_CB p_fun_cb); + +/** + * @brief Confirm from application when receive read Request from client. + * @param[in] conn_id Connection id indicate which link is. + * @param[in] service_id Service ID. + * @param[in] attrib_index Attribute index of attribute to read confirm from application. + * @param[in] p_data Point to the readed value. + * @param[in] length The length of the data. + * @param[in] cause Cause for read confirm. @ref T_APP_RESULT + * @retval true: confirm from app OK. + * @retval false: confirm from app failed. + */ +bool server_attr_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint8_t *p_data, uint16_t length, T_APP_RESULT cause); +/** + * @brief Confirm from application when receive Execute Write Request from client. + * @param[in] conn_id Connection id indicate which link is. + * @param[in] cause Cause for execute write confirm. @ref T_APP_RESULT + * @param[in] handle Gatt attribute handle. + * @retval true: confirm from app OK. + * @retval false: confirm from app failed. + */ +bool server_exec_write_confirm(uint8_t conn_id, uint16_t cause, uint16_t handle); + +/** + * @brief Confirm from application when receive Write Request from client. + * @param[in] conn_id Connection id indicate which link is. + * @param[in] service_id Service ID. + * @param[in] attrib_index Attribute index of attribute to write confirm from application. + * @param[in] cause Write request app handle result, APP_RESULT_SUCCESS or other. @ref T_APP_RESULT + * @retval true: confirm from app OK. + * @retval false: confirm from app failed. + */ +bool server_attr_write_confirm(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_APP_RESULT cause); + +/** + * @brief Send characteristic value to peer device. + * + * @param[in] conn_id Connection id indicate which link is. + * @param[in] service_id Service ID. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] p_data Point to data to be sent. + * @param[in] data_len Length of value to be sent, range: 0~(mtu_size - 3). + uint16_t mtu_size is acquired by le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id). + * @param[in] type GATT pdu type. + * @return Data sent result + * @retval true Success. + * @retval false Failed. + * + * Example usage + * \code{.c} + bool bas_battery_level_value_notify(uint8_t conn_id, uint8_t service_id, uint8_t battery_level) + { + return server_send_data(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX, &battery_level, + sizeof(battery_level), GATT_PDU_TYPE_ANY); + } + * \endcode + */ +bool server_send_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint8_t *p_data, uint16_t data_len, T_GATT_PDU_TYPE type); + +uint16_t server_get_start_handle(T_SERVER_ID service_id); +/** + * @brief Get the header point of the write command data buffer. + * This function is used to get the buffer point of the write command data. + * This function only can be called in write_attr_cb. + * + * @param[in] conn_id Connection id indicate which link is. + * @param[in,out] pp_buffer Pointer to the address of the buffer. + * @param[in,out] p_offset Pointer to the offset of the data. + * @return Buffer get result + * @retval true Success. + * @retval false Failed. + * + * Example usage + * \code{.c} + uint8_t *p_data_buf; + uint16_t data_offset; + T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) + { + ...... + server_get_write_cmd_data_buffer(conn_id, &p_data_buf, &data_offset); + return APP_RESULT_NOT_RELEASE; + } + void release(void) + { + if(p_data_buf != NULL) + { + gap_buffer_free(p_data_buf); + p_data_buf = NULL; + } + } + * \endcode + */ +bool server_get_write_cmd_data_buffer(uint8_t conn_id, uint8_t **pp_buffer, uint16_t *p_offset); + +/** + * @brief Get the start handle of the service + * + * @param[in] service_id Service ID. + * @return Start handle + * @retval 0 Failed. + * @retval other Success. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t start_handle; + start_handle = server_get_start_handle(simp_srv_id); + } + * \endcode + */ +uint16_t server_get_start_handle(T_SERVER_ID service_id); + +/** + * @brief Clear service. + * + * NOTE: This function can only be used when: + * standby state (i.e., no link, not initiating, etc.), and @ref GAP_INIT_STATE_STACK_READY, and not add service + * + * If sending request operation is success, the result of clear service will be returned by callback depends on APP: + * Default or APP use server_cfg_use_ext_api(false): + * callback registered by @ref server_register_app_cb with eventId @ref PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE + * APP use server_cfg_use_ext_api(true): + * callback registered by @ref server_ext_register_app_cb with eventId @ref PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE + * + * If clear service operation is success and APP not clear bond info: + * APP clear CCCD except CCCD of Service Changed characteristic + * APP send Indication of Service Changed after reconnection + * + * @return Send request operation. + * @retval true Send request operation success. + * @retval false Send request operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + server_clear_service(); + } + + // Default or APP use server_cfg_use_ext_api(false): callback registered by @ref server_register_app_cb + T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data) + { + ...... + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_param->eventId) + { + case PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE: + APP_PRINT_INFO2("app_profile_callback: PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE, cause 0x%x, svc_changed_char_cccd_handle 0x%x", + p_param->event_data.clear_service_after_init_result.cause, + p_param->event_data.clear_service_after_init_result.svc_changed_char_cccd_handle); + ...... + break; + ...... + } + + // APP use server_cfg_use_ext_api(true): callback registered by @ref server_ext_register_app_cb + T_APP_RESULT app_profile_ext_callback(T_SERVER_ID service_id, void *p_data) + { + ...... + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_EXT_APP_CB_DATA *p_param = (T_SERVER_EXT_APP_CB_DATA *)p_data; + switch (p_param->eventId) + { + case PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE: + APP_PRINT_INFO2("app_profile_ext_callback: PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE, cause 0x%x, svc_changed_char_cccd_handle 0x%x", + p_param->event_data.clear_service_after_init_result.cause, + p_param->event_data.clear_service_after_init_result.svc_changed_char_cccd_handle); + ...... + break; + ...... + } + * \endcode + */ +bool server_clear_service(void); + +/** + * @brief Set service reg mode. + * + * NOTE: This function can only be used when: @ref GAP_INIT_STATE_STACK_READY, and not add service + * + * If mode is @ref SERVICE_REG_MODE_ADD_TO_TABLE, result is returned @retval. + * + * If mode is @ref SERVICE_REG_MODE_ADD_TO_STACK, result is returned @retval. + * If @retval is true, and p_num is not zero, the result of registering services + * will be returned by callback depends on APP: + * callback registered by @ref server_register_app_cb with eventId @ref PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE, + * When register single or multi services complete, return the last service id. + * + * @param[in] mode Service reg mode, @ref T_SERVICE_REG_MODE. + * @param[in,out] p_num Pointer to the num of services in table have not been registered to stack. + Only when mode is @ref SERVICE_REG_MODE_ADD_TO_STACK and @retval is true, the value is valid. + * @return Set mode result. + * @retval true Set mode success. + * @retval false Set mode failure. + * + * Example usage + * \code{.c} + void test(void) + { + bool ret = server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_TABLE, p_num); + + //add multiple service to table + bas_srv_id = bas_add_service(app_profile_callback); + hid_srv_id = hids_add_service(app_profile_callback); + ...... + ret = server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_STACK, p_num); + } + + T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data) + { + ...... + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data; + + switch (p_param->eventId) + { + //srv register result event. + case PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE: + APP_PRINT_INFO3("app_profile_callback: PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE: result %d, service id 0x%x, cause 0x%x", + p_param->event_data.server_reg_after_init_result.result, + //When register multi services complete, return the last service id. + p_param->event_data.server_reg_after_init_result.service_id, + p_param->event_data.server_reg_after_init_result.cause); + ...... + break; + ...... + } + * \endcode + */ +bool server_set_service_reg_mode(uint8_t mode, uint8_t *p_num); + +/** @} End of GATT_SERVER_Exported_Functions */ + +/** @} End of GATT_SERVER_API */ +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PROFILE_SERVER_H */ diff --git a/inc/bluetooth/profile/server/atvv_service.h b/inc/bluetooth/profile/server/atvv_service.h new file mode 100644 index 0000000..8ce2552 --- /dev/null +++ b/inc/bluetooth/profile/server/atvv_service.h @@ -0,0 +1,227 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file atvv_service.h + * @brief Head file for using ATV voice service. + * @details ATVV data structs and external functions declaration. + * @author Chenjie Jin + * @date 2017-12-8 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _ATVV_H_ +#define _ATVV_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + +/** @defgroup ATVV ATV Voice Service + * @brief ATV voice service + * @{ + */ + +/** @defgroup ATVV_Exported_Constants ATVV Exported Constants + * @brief macros that other .c files may use all defined here + * @{ + */ + +///@cond +#define ATVV_VERSION_1_0 0x0100 +#define ATVV_VERSION_0_4 0x0004 + +#define ATTV_CODEC_MASK_8K_ADPCM 0x0001 +#define ATTV_CODEC_MASK_16K_ADPCM 0x0002 +#define ATTV_CODEC_MASK_OPUS 0x0004 + +#define ATVV_CHAR_RX_DATA_LEN 20 +#define ATVV_CHAR_CTL_DATA_LEN 20 +#define ATVV_CHAR_WRITE_DATA_LEN 20 + +/** @brief ATVV related services UUIDs */ +#define GATT_UUID_ATV_CHAR_TX 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x02, 0x00, 0x5E, 0xAB +#define GATT_UUID_ATV_CHAR_RX 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x03, 0x00, 0x5E, 0xAB +#define GATT_UUID_ATV_CHAR_CTL 0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x04, 0x00, 0x5E, 0xAB + +/** @brief Index defines for Characteristic's value */ +#define GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX 2 +#define GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX 4 +#define GATT_SVC_ATVV_CHAR_RX_CCCD_INDEX 5 +#define GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX 7 +#define GATT_SVC_ATVV_CHAR_CTL_CCCD_INDEX 8 +///@endcond + +/** @} End of ATVV_Exported_Constants */ + +/** @defgroup ATVV_Exported_Types IAS Exported Types + * @brief types that other .c files may use all defined here + * @{ + */ +/* Add all public types here */ +/** @defgroup ATVV_Callback_Data ATTB Callback Data + * @brief ATVV data struct for notification data to application. + * @{ + */ + +/** @defgroup ATVV_Read_Info ATVV Read Info + * @brief Parameter for read characteristic value. + * @{ + */ +#define ATVV_READ_CHAR_RX_INDEX 1 +#define ATVV_READ_CHAR_CTL_INDEX 2 +/** @} */ + +/** @defgroup ATVV_Write_Info ATVV Write Info + * @brief Parameter for write characteristic value. + * @{ + */ +#define ATVV_WRITE_CHAR_TX_INDEX 1 +/** @} */ + +/** @defgroup ATVV_Notify_Indicate_Info ATVV Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define ATVV_CHAR_RX_NOTIFY_ENABLE 1 +#define ATVV_CHAR_RX_NOTIFY_DISABLE 2 +#define ATVV_CHAR_CTL_NOTIFY_ENABLE 3 +#define ATVV_CHAR_CTL_NOTIFY_DISABLE 4 + +/** @defgroup ATT MTU zie and Date length extantion + * @brief GATT client negotiate ATT MTU and send DLE + * @{ + */ +#define ATVV_DLE_AND_MTU_UPDATE_DISABLE 0 +#define ATVV_DLE_ENABLE_MTU_SIZE_UPDATE 1 + +/** Message content */ +typedef union +{ + struct + { + uint8_t len; + uint8_t *report; + } report_data; +} T_ATVV_WRITE_PARAMETER; + +/** @struct _TATVV_WRITE_MSG + * @brief write message + */ +typedef struct +{ + uint8_t write_type; /**< ref: @ref ATVV_RmC_Write_Info */ + T_ATVV_WRITE_PARAMETER write_parameter; +} T_ATVV_WRITE_MSG; + +typedef union _TATVV_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; /**< ref: @ref ATVV_RmC_Notify_Indicate_Info */ + uint8_t read_value_index; /**< ref: @ref ATVV_RmC_Read_Info */ + T_ATVV_WRITE_MSG write; +} T_ATVV_UPSTREAM_MSG_DATA; + +/** ATVV service data to inform application */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_ATVV_UPSTREAM_MSG_DATA msg_data; +} T_ATVV_CALLBACK_DATA; +/** @} */ + +typedef enum +{ + ATV_TX_OPCODE_GET_CAPS = 0x0A, + ATV_TX_OPCODE_MIC_OPEN = 0x0C, + ATV_TX_OPCODE_MIC_CLOSE = 0x0D, + ATV_TX_OPCODE_EXTEND = 0x0E, +} ATV_CHAR_TX_OPCODE; + +#define ATV_TX_OPCODE_GET_CAPS_LEN 5 +#define ATV_TX_OPCODE_MIC_OPEN_LEN 5 + +typedef enum +{ + ATV_CTL_OPCODE_AUDIO_STOP = 0x00, + ATV_CTL_OPCODE_AUDIO_START = 0x04, + ATV_CTL_OPCODE_DPAD_SELECT = 0x07, + ATV_CTL_OPCODE_START_SEARCH = 0x08, + ATV_CTL_OPCODE_AUDIO_SYNC = 0x0A, + ATV_CTL_OPCODE_GET_CAPS_RESP = 0x0B, + ATV_CTL_OPCODE_MIC_OPEN_ERROR = 0x0C, +} ATV_CHAR_CTL_CMD_OPCODE; + +typedef enum +{ + ATV_START_REASON_MIC_OPEN_REQUEST = 0x00, + ATV_START_REASON_PTT = 0x01, + ATV_START_REASON_HTT = 0x03, + ATV_START_REASON_INVALID = 0xFF +} ATV_AUDIO_START_REASON; + +typedef enum +{ + ATV_STOP_REASON_MIC_CLOSE_MESSAGE = 0x00, + ATV_STOP_REASON_HTT = 0x02, + ATV_STOP_REASON_AUDIO_START_COMMAND = 0x04, + ATV_STOP_REASON_AUDIO_TRANSFER_TIMEOUT = 0x08, + ATV_STOP_REASON_ATVV_CHAR_AUDIO_DISABLE = 0x10, + ATV_STOP_REASON_OTHERS = 0x80, +} ATV_AUDIO_STOP_REASON; + +typedef enum +{ + ATV_MIC_OPEN_ERROR_RESERVED = 0x0f01, + ATV_MIC_OPEN_ERROR_REMOTE_IS_NOT_ACTIVE = 0x0f02, + ATV_MIC_OPEN_ERROR_ATVV_CHAR_AUDIO_IS_DISABLE = 0x0f03, + ATV_MIC_OPEN_ERROR_PTT_HTT_IS_IN_PROGRESS = 0x0f80, + ATV_MIC_OPEN_ERROR_INTERNAL_ERROR = 0x0fff, +} ATV_MIC_OPEN_ERROR; + +typedef enum +{ + ATV_ASSISTANT_INTERACTION_MODEL_ON_REQUEST = 0x00, + ATV_ASSISTANT_INTERACTION_MODEL_PRESS_TO_TALK = 0x01, + ATV_ASSISTANT_INTERACTION_MODEL_HOLD_TO_TALK = 0x03, +} ATV_ASSISTANT_INTERACTION_MODEL; + +/** @} End of IAS_Exported_Types */ + +typedef struct +{ + uint16_t app_support_version; + uint16_t codec_support; + uint16_t codec_used; + uint8_t atv_start_reason; + uint8_t assistant_interaction_model; + uint8_t audio_consumption_mode; + uint8_t stream_id; + uint8_t char_rx_data_buff[ATVV_CHAR_RX_DATA_LEN]; + uint8_t char_ctl_data_buff[ATVV_CHAR_RX_DATA_LEN]; + uint8_t char_write_dat_buff[ATVV_CHAR_WRITE_DATA_LEN]; +} T_ATVV_GLOBAL_DATA; + +extern T_ATVV_GLOBAL_DATA atvv_global_data; + +/** @defgroup ATVV_Exported_Functions IAS Exported Functions + * @brief functions that other .c files may use all defined here. + * @{ + */ +uint8_t atvv_add_service(void *p_func); +/** @} End of ATVV_Exported_Functions */ + +/** @} End of ATVV */ + +#endif /* (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + diff --git a/inc/bluetooth/profile/server/bas.h b/inc/bluetooth/profile/server/bas.h new file mode 100644 index 0000000..7eee3d4 --- /dev/null +++ b/inc/bluetooth/profile/server/bas.h @@ -0,0 +1,230 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bas.h + * @brief Head file for using battery service. + * @details BAS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _BAS_H_ +#define _BAS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +/** @defgroup BAS Battery Service + * @brief Battery service + * @details + + The Battery Service exposes the state of a battery within a device. + + Battery Service generally makes up a profile with some other services, and it can provide the state of a battery within a device. + + The default supported feature provided by BAS is the notify property of battery level characteristic, + and the application developers can modify the feature supported by BAS according to their own requirements. + The specific configuration process can be achieved by modifying file @ref bas_config.h. + + * Example usage + * \code{.c} + + #define BAS_BATTERY_LEVEL_NOTIFY_SUPPORT 1 + + * \endcode + + Application shall register battery service when initialization through @ref bas_add_service function. + + Application can set the battery level of BAS through @ref bas_set_parameter function. + + Application can send the battery level value of BAS to the client with a notification through @ref bas_battery_level_value_notify function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup BAS_Exported_Macros BAS Exported Macros + * @brief + * @{ + */ + +#define BAS_READ_BATTERY_LEVEL 1 +#define BAS_NOTIFY_BATTERY_LEVEL_ENABLE 1 +#define BAS_NOTIFY_BATTERY_LEVEL_DISABLE 2 + +/** End of BAS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BAS_Exported_Types BAS Exported Types + * @brief + * @{ + */ + +/** +* @brief Battery service parameter type +*/ +typedef enum +{ + BAS_PARAM_BATTERY_LEVEL = 0x01, +} T_BAS_PARAM_TYPE; + +/** +* @brief set battery service parameter upstream message data +*/ +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; +} T_BAS_UPSTREAM_MSG_DATA; + +/** +* @brief set battery service parameter upstream callback data +*/ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_BAS_UPSTREAM_MSG_DATA msg_data; +} T_BAS_CALLBACK_DATA; + +/** End of BAS_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BAS_Exported_Functions BAS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add battery service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bas_id = bas_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID bas_add_service(void *p_func); + +/** + * @brief Set a battery service parameter. + * + * NOTE: You can call this function with a battery service parameter type and it will set the + * battery service parameter. Battery service parameters are defined in @ref T_BAS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Battery service parameter type: @ref T_BAS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + the parameter type and will be cast to the appropriate data type. + If param_type is set to @ref BAS_PARAM_BATTERY_LEVEL, p_value pointer to the current + charge level of a battery. Unit is org.bluetooth.unit.percentage. Minimum value is 0, + and maximum value is 100. 100% represents fully charged while 0% represents fully discharged. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 80; + bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level); + } + * \endcode + */ +bool bas_set_parameter(T_BAS_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value); + + +/** + * @brief Send notify battery level notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] battery_level The current charge level of a battery. + Unit is org.bluetooth.unit.percentage. Minimum value is 0, and maximum value is 100. + 100% represents fully charged while 0% represents fully discharged. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool bas_battery_level_value_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t battery_level); + + +/** + * @brief Confirm for read battery level value request. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] battery_level The current charge level of a battery. + Unit is org.bluetooth.unit.percentage. Minimum value is 0, and maximum value is 100. + 100% represents fully charged while 0% represents fully discharged. + + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_read_confirm(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool bas_battery_level_value_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t battery_level); + +/** @} End of BAS_Exported_Functions */ + +/** @} End of BAS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BAS_H_ */ diff --git a/inc/bluetooth/profile/server/bas_config.h b/inc/bluetooth/profile/server/bas_config.h new file mode 100644 index 0000000..6be3546 --- /dev/null +++ b/inc/bluetooth/profile/server/bas_config.h @@ -0,0 +1,39 @@ +#ifndef _BAS_CONFIG_H_ +#define _BAS_CONFIG_H_ + + +/** @defgroup BAS Battery Service + * @brief Battery service + * @{ + */ + + +/** @defgroup BAS_CONFIG Battery Service Config + * @brief Battery service configuration file + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup BAS_Common_Exported_Macros BAS Common Exported Macros + * @{ + */ + +/** @details + Set BAS_BATTERY_LEVEL_NOTIFY_SUPPORT to 1 to support Battery level notification feature, + otherwise set it to 0. +*/ +#define BAS_BATTERY_LEVEL_NOTIFY_SUPPORT 1 + + +/** @} End of BAS_Common_Exported_Macros */ + +/** @} End of BAS_CONFIG */ + +/** @} End of BAS */ + + + +#endif diff --git a/inc/bluetooth/profile/server/bcs.h b/inc/bluetooth/profile/server/bcs.h new file mode 100644 index 0000000..2cbce1f --- /dev/null +++ b/inc/bluetooth/profile/server/bcs.h @@ -0,0 +1,435 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rigbcs reserved. +***************************************************************************************** + * @file bcs.h + * @brief Variables and interfaces for using Body Composition Service. + * @details Body Composition Service data structs and functions. + * @author + * @date 2017-09-20 + * @version v1.0 + * ************************************************************************************* + */ + +/* define to prevent recursive inclusion */ +#ifndef _BCS_H_ +#define _BCS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "stdint.h" +#include "profile_server.h" +#include "rtl876x.h" + + +/** @defgroup BCS Body Composition Service + * @brief Body Composition service + * @details + + The Body Composition service exposes data related to body composition from a body composition analyzer intended for consumer healthcare and sports/fitness applications. + Application shall register Body Composition service when initialization through @ref bcs_add_service function. + + The Body Composition Feature characteristic shall be used to describe the supported features of the Server. + Application can set a body composition feature through @ref bcs_set_parameter function. + + The Body Composition Measurement characteristic is used to send body composition-related data to the Client. for display purposes while the measurement is in progress. + Application can send body composition measurement values through @ref bcs_body_composition_measurement_value_indicate function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup BCS_Exported_Macros BCS Exported Macros + * @brief + * @{ + */ + +#define GATT_UUID_BODY_COMPOSITION 0x181B +#define GATT_UUID_CHAR_BODY_COMPOSITION_FEATURE 0x2A9B +#define GATT_UUID_CHAR_BODY_COMPOSITION_MEASUREMENT 0x2A9C + +/** @brief The Maximum Length of Body Composition Measurement Value*/ +#define BCS_MEASUREMENT_VALUE_MAX_LEN 30 + +/** +* @brief Body Composition Feature field bit 11 to 14 +* bcs_Weight_measurement_resolution_bit +*/ +#define BCS_FEATURE_WEIGHT_MEAS_RES_NOT_SPECIFIED 0x00 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_5_KG_OR_1_LB 0x01 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_2_KG_OR_0_5_LB 0x02 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_1_KG_OR_0_2_LB 0x03 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_05_KG_OR_0_1_LB 0x04 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_02_KG_OR_0_05_LB 0x05 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_01_KG_OR_0_02_LB 0x06 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_005_KG_OR_0_01_LB 0x07 + +/** +* @brief Body Composition Feature field bit 15 to 17 +* bcs_height_measurement_resolution_bit +*/ +#define BCS_FEATURE_HEIGHT_MEAS_RES_NOT_SPECIFIED 0x00 +#define BCS_FEATURE_HEIGHT_MEAS_RES_0_01_METER_OR_1_INCH 0x01 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_005_METER_OR_5_INCH 0x02 +#define BCS_FEATURE_WEIGHT_MEAS_RES_0_001_METER_OR_0_1_INCH 0x03 + +/** @defgroup BCS_Notify_Indicate_Info BCS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define BCS_INDICATE_BODY_COMPOSITIONT_MEASUREMENT_ENABLE 1 +#define BCS_INDICATE_BODY_COMPOSITIONT_MEASUREMENT_DISABLE 2 +/** @} */ + +/** +* @brief Body Composition Measurement flags field +* bcs_measurement_units_bit +*/ +#define BCS_MEASUREMENT_UNITS_SI 0 /* Weight and Mass in units of kilogram (kg) and Height in units of meter */ +#define BCS_MEASUREMENT_UNITS_IMPERIAL 1 /* Weight and Mass in units of pound (lb) and Height in units of inch (in) */ + +#define BCS_MEASUREMENT_BODY_FAT_PCT_UNSUCCESS 0xffff /* body_fat_percentage field: measurement unsuccessful */ + +#define BCS_MEASUREMENT_USER_ID_UNKNOW 0xff /* user_id field: unknown user */ + +/** End of BCS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BCS_Exported_Types BCS Exported Types + * @brief + * @{ + */ + +/** +* @brief Body Composition parameter type +*/ +typedef enum +{ + BCS_PARAM_BODY_COMPOSITION_FEATURE +} T_BCS_PARAM_TYPE; + +/** +* @brief Body Composition Feature +*/ +typedef struct +{ + uint32_t bcs_feature_time_stamp_support_bit: 1; + uint32_t bcs_feature_multiple_users_support_bit: 1; + uint32_t bcs_feature_basal_metabolism_support_bit: 1; + uint32_t bcs_feature_muscle_percentage_support_bit: 1; + uint32_t bcs_feature_muscle_mass_support_bit: 1; + uint32_t bcs_feature_fat_free_mass_support_bit: 1; + uint32_t bcs_feature_soft_lean_mass_support_bit: 1; + uint32_t bcs_feature_body_water_mass_support_bit: 1; + uint32_t bcs_feature_impedance_support_bit: 1; + uint32_t bcs_feature_weight_support_bit: 1; + uint32_t bcs_feature_height_support_bit: 1; + uint32_t bcs_weight_measurement_resolution_bit: 4; + uint32_t bcs_height_measurement_resolution_bit: 3; + uint32_t rfu: 14; +} T_BODY_COMPOSITION_FEATURE; + +/** +* @brief Body Composition Measurement Flag +*/ +typedef struct +{ + uint16_t bcs_measurement_units_bit: 1; + uint16_t bcs_time_stamp_present_bit: 1; + uint16_t bcs_user_id_bit: 1; + uint16_t bcs_basal_metabolism_present_bit: 1; + uint16_t bcs_muscle_percentage_present_bit: 1; + uint16_t bcs_muscle_mass_present_bit: 1; + uint16_t bcs_fat_free_mass_present_bit: 1; + uint16_t bcs_soft_lean_mass_present_bit: 1; + uint16_t bcs_body_water_mass_present_bit: 1; + uint16_t bcs_impedance_present_bit: 1; + uint16_t bcs_weight_present_bit: 1; + uint16_t bcs_height_present_bit: 1; + uint16_t bcs_multiple_packet_measurement_bit: 1; + uint16_t rfu: 3; +} T_BODY_COMPOSITION_MEASUREMENT_FLAG; + +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} T_BCS_TIME_STAMP; + +typedef struct +{ + T_BODY_COMPOSITION_MEASUREMENT_FLAG bcs_measurement_flag; + uint16_t body_fat_percentage; + T_BCS_TIME_STAMP time_stamp; + uint8_t user_id; + uint16_t basal_metabolism; + uint16_t muscle_percentage; + uint16_t muscle_mass; + uint16_t fat_free_mass; + uint16_t soft_lean_mass; + uint16_t body_water_mass; + uint16_t impedance; + uint16_t weight; + uint16_t height; +} T_BCS_BODY_COMPOSITION_MEASUREMENT; + +/** +* @brief Body Composition service upper stream message data +*/ +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; +} T_BCS_UPSTREAM_MSG_DATA; + +/** +* @brief Body Composition service callback data +*/ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_BCS_UPSTREAM_MSG_DATA msg_data; +} T_BCS_CALLBACK_DATA; + +/** End of BCS_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BCS_Exported_Functions BCS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add body composition service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bcs_id = bcs_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t bcs_add_service(void *p_func); + + +/** + * @brief Set a body composition service parameter. + * + * NOTE: You can call this function with a body composition service parameter type and it will set the + * body composition service parameter. Body Composition service parameters are defined + * in @ref T_BCS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t", the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Body composition service parameter type: @ref T_BCS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint32_t bcs_body_composition_feature = 0x000007ff; + + bcs_set_parameter(BCS_PARAM_BODY_COMPOSITION_FEATURE, sizeof(bcs_body_composition_feature), + &bcs_body_composition_feature); + } + * \endcode + */ +bool bcs_set_parameter(T_BCS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send measurement value indication data . + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_value Pointer to data to indicate. + Type is @ref T_BCS_BODY_COMPOSITION_MEASUREMENT. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_BCS_BODY_COMPOSITION_MEASUREMENT bcs_meas_value = {0}; + uint8_t conn_id = 0; + uint16_t bcs_measurement_flag = 0x7f; + memcpy(&bcs_meas_value.bcs_measurement_flag, &bcs_measurement_flag, 2); + bcs_meas_value.body_fat_percentage = 20; + bcs_meas_value.time_stamp = (T_BCS_TIME_STAMP) {2017, 9, 20, 20, 6, 8}; + bcs_meas_value.user_id = 0; + bcs_meas_value.basal_metabolism = 50; + bcs_meas_value.muscle_percentage = 30; + bcs_meas_value.muscle_mass = 10; + bcs_meas_value.fat_free_mass = 10; + + bcs_body_composition_measurement_value_indicate(conn_id, bcs_id, + &bcs_meas_value); + } + * \endcode + */ +bool bcs_body_composition_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, + T_BCS_BODY_COMPOSITION_MEASUREMENT *p_data); + +/** + * @brief Send consecutive measurement value indications data. + * + * NOTE:If the measurement value indication data exceeds the current MTU size, + * the remaining optional fields shall be sent in the subsequent indication + * (also known as a 'continuation packet'). + * You shall call this function when processing the complete event callback + * of the first indication @ref PROFILE_EVT_SEND_DATA_COMPLETE after calling + * function @ref bcs_body_composition_measurement_value_indicate. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_value Pointer to data to indicate. + Type is @ref T_BCS_BODY_COMPOSITION_MEASUREMENT. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_BCS_BODY_COMPOSITION_MEASUREMENT bcs_meas_value = {0}; + uint8_t conn_id = 0; + uint16_t bcs_measurement_flag = 0x1fff; + memcpy(&bcs_meas_value.bcs_measurement_flag, &bcs_measurement_flag, 2); + bcs_meas_value.body_fat_percentage = 20; + bcs_meas_value.time_stamp = (T_BCS_TIME_STAMP) {2017, 9, 20, 20, 6, 8}; + bcs_meas_value.user_id = 0; + bcs_meas_value.basal_metabolism = 50; + bcs_meas_value.muscle_percentage = 30; + bcs_meas_value.muscle_mass = 10; + bcs_meas_value.fat_free_mass = 10; + bcs_meas_value.soft_lean_mass = 20; + bcs_meas_value.body_water_mass = 70; + bcs_meas_value.impedance = 10; + bcs_meas_value.weight = 100; + bcs_meas_value.height = 163; + + bcs_body_composition_measurement_value_indicate(conn_id, bcs_id, + &bcs_meas_value); + } + + T_APP_RESULT app_handle_bcs_notify_indicate_cb_message(T_SERVER_ID service_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_para->eventId) + { + case PROFILE_EVT_SEND_DATA_COMPLETE: + if (p_para->event_data.send_data_result.service_id == bcs_id) + { + uint8_t conn_id = p_para->event_data.send_data_result.conn_id; + uint8_t serv_id = p_para->event_data.send_data_result.service_id; + + if (bcs_measurement_value_consecutive_indicate(conn_id, serv_id)) + { + //data exceeds, send first indication complete + //sending second indication + app_bcs_measurement_value_consecutive_indicate = true; + APP_PRINT_INFO1("PROFILE_EVT_SEND_DATA_COMPLETE sending second indication app_bcs_measurement_value_consecutive_indicate %d", + app_bcs_measurement_value_consecutive_indicate); + } + else if (app_bcs_measurement_value_consecutive_indicate) + { + //data exceeds, send second indication complete + APP_PRINT_INFO1("PROFILE_EVT_SEND_DATA_COMPLETE send second indication complete app_bcs_measurement_value_consecutive_indicate %d", + app_bcs_measurement_value_consecutive_indicate); + app_bcs_measurement_value_consecutive_indicate = false; + } + else + { + //data doesn't exceed, send whole indication complete + APP_PRINT_INFO1("PROFILE_EVT_SEND_DATA_COMPLETE send only one indication app_bcs_measurement_value_consecutive_indicate %d", + app_bcs_measurement_value_consecutive_indicate); + } + } + + break; + + default: + break; + } + } + return result; + } + + T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_para->eventId) + { + case PROFILE_EVT_SEND_DATA_COMPLETE: + if (p_para->event_data.send_data_result.service_id == bcs_id) + { + return app_handle_bcs_notify_indicate_cb_message(service_id, p_para); + } + break; + + default: + break; + } + ... + } + } + * \endcode + */ +bool bcs_measurement_value_consecutive_indicate(uint8_t conn_id, T_SERVER_ID service_id); + +/** @} End of BCS_Exported_Functions */ + +/** @} End of BCS */ + + +#ifdef __cplusplus +} +#endif + +#endif // _BCS_H_ diff --git a/inc/bluetooth/profile/server/bls.h b/inc/bluetooth/profile/server/bls.h new file mode 100644 index 0000000..21dd733 --- /dev/null +++ b/inc/bluetooth/profile/server/bls.h @@ -0,0 +1,256 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bls.h + * @brief Head file for using blood pressure service. + * @details BLS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _BLS_H_ +#define _BLS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "bls_define.h" + +/** @defgroup Blood Pressure Service + * @brief Blood Pressure Service + * @details + + The Blood Pressure Service exposes blood pressure and other data related to a noninvasive blood pressure monitor + for consumer and professional healthcare applications. + + Blood Pressure Service generally makes up a profile with some other services, and it can provide the state of blood pressure. + + The default supported feature provided by BLS is the indicate property of blood pressure measurement characteristic, + the read property of blood pressure feature characteristic, and the application developers can modify the feature supported + by BLS according to their own requirements. + The specific configuration process can be achieved by modifying file @ref bls_define.h. + + * Example usage + * \code{.c} + + #define BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT 1 + + * \endcode + + Application shall register blood pressure service when initialization through @ref bls_add_service function. + + Application can set the blood pressure feature of BLS through @ref bls_set_parameter function. + + Application can send the blood pressure measurement value of BLS to the client with a indication through @ref bls_blood_pressure_measurement_value_indicate function. + + Application can send the intermediate cuff pressure value of BLS to the client with a notification through @ref bls_intermediate_cuff_pressure_value_notify function. + + * @{ + */ + +/*============================================================================* + * Macros + * + *============================================================================*/ +/** @defgroup BLS_Exported_Macros BLS Exported Macros + * @brief + * @{ + */ +#define BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_ENABLE 1 +#define BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_DISABLE 2 +#define BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_ENABLE 3 +#define BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_DISABLE 4 + +/** End of BLS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BLS_Exported_Types BLS Exported Types + * @brief + * @{ + */ + +/** +* @brief Blood pressure service parameter type +*/ +typedef enum +{ + BLS_PARAM_BLOOD_PRESUREE_FEATURE +} T_BLS_PARAM_TYPE; + +typedef union +{ + uint8_t notification_indification_index; +} T_BLS_UPSTREAM_MSG_DATA; + +/** +* @brief set blood pressure parameter upstream callback data +*/ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_BLS_UPSTREAM_MSG_DATA msg_data; +} T_BLS_CALLBACK_DATA; + +/** End of BLS_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BLS_Exported_Functions BLS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add blood pressure service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bls_id = bls_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID bls_add_service(void *p_func); + +/** + * @brief Set a blood pressure service parameter. + * + * NOTE: You can call this function with a blood pressure service parameter type and it will set the + * blood pressure service parameter. Blood pressure service parameters are defined in @ref T_BLS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must point to a data + * with type of "uint16_t". + * + * @param[in] param_type Blood pressure service parameter type: @ref T_BLS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. + * This is dependent on the parameter type and will be cast to the appropriate data type. + If param_type is set to @ref BLS_PARAM_BLOOD_PRESUREE_FEATURE, p_value pointer to the current + blood pressure feature. Type is org.bluetooth.characteristic.blood_pressure_feature. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t blood_pressure_feature = BLS_FEATURE_BODY_MOVEMENT_DETECTION_SUPPORT_BIT | + BLS_FEATURE_CUFF_FIT_DETECTION_SUPPORT_BIT; + bls_set_parameter(BLS_PARAM_BLOOD_PRESUREE_FEATURE, 2, &blood_pressure_feature); + } + * \endcode + */ +bool bls_set_parameter(T_BLS_PARAM_TYPE param_type, uint8_t length, void *p_value); + + +/** + * @brief Send blood pressure measurement value indication data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_value Pointer to data to indicate. + Type is org.bluetooth.characteristic.blood_pressure_measurement. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_BLOOD_PRESSURE_MEASURMENT bls_meas_value = {0}; + SFLOAT bls_measure_pulse_rate = {0x30, 0x00}; + + bls_meas_value.bp_meas_flag = (BLS_FLAG_MEASUREMENT_UINT_BIT | + BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT | + BLS_FLAG_MEASUREMENT_USER_ID_BIT | + BLS_FLAG_MEASUREMENT_STATUS_BIT); + bls_meas_value.time_stamp = (T_BLS_TIME_STAMP) {2017, 9, 20, 20, 6, 8}; + memcpy(&bls_meas_value.bp_meas_pulse_rate, &bls_measure_pulse_rate, 2); + bls_meas_value.bp_meas_user_id = 0; + bls_meas_value.bp_meas_status = (T_BLOOD_PRESSUREE_MEAS_STATUS) {0}; + + bls_blood_pressure_measurement_value_indicate(conn_id, bls_id, blp_meas_value); + } + * \endcode + */ +bool bls_blood_pressure_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, + T_BLOOD_PRESSURE_MEASURMENT *p_data); + + +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT +/** + * @brief Send intermediate cuff pressure value notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] blood pressure_level The current charge level of a blood pressure. + Type is org.bluetooth.characteristic.blood_pressure_measurement. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_BLOOD_PRESSURE_MEASURMENT bls_meas_value = {0}; + SFLOAT bls_measure_pulse_rate = {0x30, 0x00}; + + bls_meas_value.bp_meas_flag = (BLS_FLAG_MEASUREMENT_UINT_BIT | + BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT | + BLS_FLAG_MEASUREMENT_USER_ID_BIT | + BLS_FLAG_MEASUREMENT_STATUS_BIT); + bls_meas_value.time_stamp = (T_BLS_TIME_STAMP) {2017, 9, 20, 20, 6, 8}; + memcpy(&bls_meas_value.bp_meas_pulse_rate, &bls_measure_pulse_rate, 2); + bls_meas_value.bp_meas_user_id = 0; + bls_meas_value.bp_meas_status = (T_BLOOD_PRESSUREE_MEAS_STATUS) {0}; + + bls_intermediate_cuff_pressure_value_notify(conn_id, bls_id, blp_meas_value); + } + * \endcode + */ +bool bls_intermediate_cuff_pressure_value_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_BLOOD_PRESSURE_MEASURMENT *p_data); +#endif + +/** @} End of BLS_Exported_Functions */ + +/** @} End of BLS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _BLS_H_ */ diff --git a/inc/bluetooth/profile/server/bls_define.h b/inc/bluetooth/profile/server/bls_define.h new file mode 100644 index 0000000..ed192e4 --- /dev/null +++ b/inc/bluetooth/profile/server/bls_define.h @@ -0,0 +1,95 @@ +#ifndef _BLS_DEFINE_H_ +#define _BLS_DEFINE_H_ + + +/** @defgroup Blood Pressure Service define file + * @brief Blood pressure service define file + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup BLS_Common_Exported_Macros BLS Common Exported Macros + * @{ + */ + +/** @details + Set BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT to 1 to support intermediate cuff pressure characteristic, + otherwise set it to 0. +*/ +#define BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT 1 + +/** @brief service related UUIDs. */ + +#define GATT_UUID_BLOOD_PRESSURE 0x1810 +#define GATT_UUID_CHAR_BLP_MEASUREMENT 0x2A35 +#define GATT_UUID_CHAR_INTERMEDIATE_CUFF_PRESSURE 0x2A36 +#define GATT_UUID_CHAR_BLP_FEATURE 0x2A49 + + +#define BLS_MEASUREMENT_VALUE_MAX_LEN 25 + +#define BLS_MEASUREMENT_COMPOUND_VALUE_NAN 0x07ff +#define BLS_MEASUREMENT_USER_ID_UNKNOW 0xff + +#define BLS_MEASUREMENT_VALUE_UNITS_MMHG 0 +#define BLS_MEASUREMENT_VALUE_UNITS_KPA 1 + +#define BLS_FLAG_MEASUREMENT_UINT_BIT 0x01 +#define BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT 0x02 +#define BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT 0x04 +#define BLS_FLAG_MEASUREMENT_USER_ID_BIT 0x08 +#define BLS_FLAG_MEASUREMENT_STATUS_BIT 0x10 + +#define BLS_FEATURE_BODY_MOVEMENT_DETECTION_SUPPORT_BIT 0x01 +#define BLS_FEATURE_CUFF_FIT_DETECTION_SUPPORT_BIT 0x02 +#define BLS_FEATURE_IRREGULAR_PULSE_DETECTION_SUPPORT_BIT 0x04 +#define BLS_FEATURE_PULSE_RATE_RANGE_DETECTION_SUPPORT_BIT 0x08 +#define BLS_FEATURE_MEASUREMENT_POSITION_DETECTION_SUPPORT_BIT 0x10 +#define BLS_FEATURE_MULTIPLE_BOND_SUPPORT_BIT 0x20 + +typedef uint8_t SFLOAT[2]; /* 4 bit (MSB) exponent, 12 bit mantissa */ + +typedef struct +{ + SFLOAT bp_meas_systolic_value; + SFLOAT bp_meas_diastolic_value; + SFLOAT bp_meas_map_value; +} T_BLOOD_PRESSUREE_MEAS_COMPOUND_VALUE; + +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} T_BLS_TIME_STAMP; + +typedef struct +{ + uint16_t bp_meas_body_movement_detection_flag: 1; + uint16_t bp_meas_cuff_fit_detection_flag: 1; + uint16_t bp_meas_irregular_pulse_detection_flag: 1; + uint16_t bp_meas_pulse_rate_range_detection_flag: 2; + uint16_t bp_meas_measurement_position_detection_flag: 1; + uint16_t rfu: 10; +} T_BLOOD_PRESSUREE_MEAS_STATUS; + +typedef struct +{ + uint8_t bp_meas_flag; + T_BLOOD_PRESSUREE_MEAS_COMPOUND_VALUE bp_meas_compound_value; + T_BLS_TIME_STAMP time_stamp; + SFLOAT bp_meas_pulse_rate; + uint8_t bp_meas_user_id; + T_BLOOD_PRESSUREE_MEAS_STATUS bp_meas_status; +} T_BLOOD_PRESSURE_MEASURMENT; + +/** @} End of BLS_Common_Exported_Macros */ + +/** @} End of BLS_DEFINE */ + +#endif diff --git a/inc/bluetooth/profile/server/cscs.h b/inc/bluetooth/profile/server/cscs.h new file mode 100644 index 0000000..5439291 --- /dev/null +++ b/inc/bluetooth/profile/server/cscs.h @@ -0,0 +1,433 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file csc_service.h + * @brief Variables and interfaces for Cycling Speed and Cadence Service. + * @details CSC service data structs and functions. + * @author ethan_su + * @date 2017-10-13 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _CSCS_SERVICE_DEF_H +#define _CSCS_SERVICE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "cscs_config.h" + + +/** @defgroup CSCS Cycling Speed and Cadence Service + * @brief Cycling Speed and Cadence Service + * @details + + The Cycling Speed and Cadence (CSC) Service exposes speed-related data and/or + cadence-related data while using the Cycling Speed and Cadence sensor (Server). + CSC Measurement, CSC Measurement Client Characteristic Configuration descriptor and CSC Feature characteristic are mandatory + exposed in the Cycling Speed and Cadence Service. + if the Multiple Sensor Locations feature is supported, CSC Feature will be mandatory, otherwise optional. + if at least one SC Control Point procedure is supported, SC Control Point and SC Control Point Client + Characteristic Configuration Descriptor will be mandatory, otherwise excluded. + + The CSC Measurement characteristic is used to send speed-related data and/or cadence-related data. + The CSC Feature characteristic shall be used to describe the supported features of the Server. + The Sensor Location characteristic of the device may be used to describe the physical location of the Server when correctly fitted. + + If the SC Control Point is supported, profiles utilizing this service are required to ensure that the Client configures the + SC Control Point characteristic for indications (i.e. via the Client Characteristic Configuration descriptor) at the first connection. + + Application shall register Cycling Speed and Cadence service when initialization through @ref cscs_add_service function. + + Application can set the Cycling Speed and Cadence parameters through @ref cscs_set_parameter function. + + Application can send the measurement value through @ref cscs_meas_value_notify function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup CSCS_Exported_Constants CSC Exported Macros + * @brief + * @{ + */ + +/** @defgroup CSCS_Optional_Features CSC Optional Features + * @brief CSC Service optional features bit mask + * @{ + */ + +/** @defgroup CSCS_Measurement_Flags CSC Measurement Flags + * @brief CSC measurement 'Flags' present bit mask + * @{ + */ +#define CSCS_INC_WHEEL_REVOL_MASK (1) +#define CSCS_INC_CRANK_REVOL_MASK (1<<1) +#define CSCS_INC_ALL_PRESENTS (0x03) +/** @} */ + +/** @defgroup CSCS_Features CSC Features + * @brief CSC features bit mask + * @{ + */ +#define CSCS_SUPPORT_WHEEL_REVOL_MASK (1) +#define CSCS_SUPPORT_CRANK_REVOL_MASK (1<<1) +#define CSCS_SUPPORT_MULTI_SENSOR_MASK (1<<2) +#define CSCS_ALL_FEATURE_SUPPORTED (0x07) +/** @} */ + +/** @defgroup CSCS_Sensor_Location CSC Sensor Location + * @brief CSC supported sensor location bit mask + * @{ + */ +#define CSCS_SENS_LOC_OTHER_MASK (1) +#define CSCS_SENS_LOC_TOP_OF_SHOE_MASK (1<<1) +#define CSCS_SENS_LOC_IN_SHOE_MASK (1<<2) +#define CSCS_SENS_LOC_HIP_MASK (1<<3) +#define CSCS_SENS_LOC_FRONT_WHEEL_MASK (1<<4) +#define CSCS_SENS_LOC_LEFT_CRANK_MASK (1<<5) +#define CSCS_SENS_LOC_RIGHT_CRANK_MASK (1<<6) +#define CSCS_SENS_LOC_LEFT_PEDAL_MASK (1<<7) +#define CSCS_SENS_LOC_RIGHT_PEDAL_MASK (1<<8) +#define CSCS_SENS_LOC_FRONT_HUB_MASK (1<<9) +#define CSCS_SENS_LOC_REAR_DROPOUT_MASK (1<<10) +#define CSCS_SENS_LOC_CHAINSTAY_MASK (1<<11) +#define CSCS_SENS_LOC_REAR_WHEEL_MASK (1<<12) +#define CSCS_SENS_LOC_REAR_HUB_MASK (1<<13) +#define CSCS_SENS_LOC_CHEST_MASK (1<<14) +#define CSCS_ALL_SENS_LOC_SUPPORTED (0x7FFF) +/** @} */ + +/** @} End of CSCS_Optional_Features */ + +/** +* @brief CSC service parameter type +*/ +typedef enum +{ + CSCS_PARAM_CSCS_FEATURE = 0x01, + CSCS_PARAM_INC_FLAG = 0x11, + CSCS_PARAM_WHEEL_REVOL, + CSCS_PARAM_WHEEL_EVT_TIME, + CSCS_PARAM_CRANK_REVOL, + CSCS_PARAM_CRANK_EVT_TIME, + CSCS_PARAM_CTL_PNT_PROG_CLR = 0x17, + CSCS_PARAM_SENSOR_LOC = 0x21, +} T_CSCS_PARAM_TYPE; + + +/** @defgroup CSCS_Upstream_Message CSC Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ + +/** @defgroup CSCS_Read_Info CSC Read Info + * @brief Parameter for reading characteristic value. + * @{ + */ +#define CSCS_READ_CSCS_FEATURE 1 +#define CSCS_READ_SENSOR_LOCATION 2 +/** @} */ + +/** @defgroup CSCS_Notify_Indicate_Info CSC Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE 1 +#define CSCS_NOTIFY_INDICATE_MEASUREMENT_DISABLE 2 +#define CSCS_NOTIFY_INDICATE_SC_CP_ENABLE 3 +#define CSCS_NOTIFY_INDICATE_SC_CP_DISABLE 4 +/** @} */ + +/** @} End of CSCS_Upstream_Message */ + +/** @defgroup CSCS_Control_Point CSC Control Point + * @brief Control Point + * @{ + */ + +/** @defgroup CSCS_Control_Point_OpCodes CSC Control Point OpCodes + * @brief Control Point OpCodes + * @{ + */ +#define CSCS_CP_OPCODE_RESERVED 0x00 +#define CSCS_CP_OPCODE_SET_CUMULATIVE 0x01 +#define CSCS_CP_OPCODE_UPDATE_SENS_LOC 0x03 +#define CSCS_CP_OPCODE_REQ_SENS_LOC_LIST 0x04 +#define CSCS_CP_OPCODE_RSP_CODE 0x10 +/** @} */ + +/** @defgroup CSCS_Control_Point_Response_Codes CSC Control Point Response Codes + * @brief Control Point Response Codes + * @{ + */ +#define CSCS_CP_RSPCODE_RESERVED 0x00 +#define CSCS_CP_RSPCODE_SUCCESS 0x01 +#define CSCS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02 +#define CSCS_CP_RSPCODE_INVALID_PARAMETER 0x03 +#define CSCS_CP_RSPCODE_OPERATION_FAILED 0x04 +/** @} */ + +///@cond +/** @brief Judge CSC Control Point operation is available or not. */ +#define CSCS_CTL_PNT_OPERATE_ACTIVE(x) \ + ( (x == CSCS_CP_OPCODE_SET_CUMULATIVE) || \ + (x == CSCS_CP_OPCODE_UPDATE_SENS_LOC) || \ + (x == CSCS_CP_OPCODE_REQ_SENS_LOC_LIST) || \ + (x == CSCS_CP_OPCODE_RSP_CODE) ) +///@endcond + +/** @} End of CSCS_Control_Point */ + +/** + * @brief CSC sensor locations. + * + * All CSC sensor locations defined in spec. +*/ +typedef enum +{ + CSCS_SENSOR_LOC_OTHER = 0, + CSCS_SENSOR_LOC_TOP_OF_SHOE = 1, + CSCS_SENSOR_LOC_IN_SHOE = 2, + CSCS_SENSOR_LOC_HIP = 3, + CSCS_SENSOR_LOC_FRONT_WHEEL = 4, + CSCS_SENSOR_LOC_LEFT_CRANK = 5, + CSCS_SENSOR_LOC_RIGHT_CRANK = 6, + CSCS_SENSOR_LOC_LEFT_PEDAL = 7, + CSCS_SENSOR_LOC_RIGHT_PEDAL = 8, + CSCS_SENSOR_LOC_FRONT_HUB = 9, + CSCS_SENSOR_LOC_REAR_DROPOUT = 10, + CSCS_SENSOR_LOC_CHAINSTAY = 11, + CSCS_SENSOR_LOC_REAL_WHEEL = 12, + CSCS_SENSOR_LOC_REAL_HUB = 13, + CSCS_SENSOR_LOC_CHEST = 14, + CSCS_SENSOR_LOC_MAX +} T_CSCS_SENSOR_LOCATION; + +///@cond +/** @brief Error codes defined in CSC service. */ +#define CSCS_ERR_PROC_ALREADY_IN_PROG 0x80 +#define CSCS_ERR_CCCD_IMPROPERLY_CFG 0x81 + +/** @brief Max bytes of CSC Measurement data. */ +#define CSCS_MAX_MEASUREMENT_VALUE 11 +/** @brief Max bytes of CSC Control Point data. */ +#define CSCS_MAX_CTL_PNT_VALUE 18 +///@endcond + +/** @} End of CSCS_Exported_Constants */ + + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup CSCS_Exported_Types CSC Exported Types + * @brief + * @{ + */ + +/* Add all public types here */ +/** @defgroup CSCS_Callback_Data CSC Callback Data + * @brief CSC data struct for notification data to application. + * @{ + */ +typedef union +{ + uint8_t sensor_location_value; + uint32_t cumulative_value; + +} T_CSCS_CP_PARAMETER; + +typedef struct +{ + uint8_t opcode; //!< ref: @ref CSCS_Control_Point_OpCodes + T_CSCS_CP_PARAMETER cp_parameter; +} T_CSCS_WRITE_MSG; + +typedef union +{ + uint8_t notification_indification_index; //!< ref: @ref CSCS_Notify_Indicate_Info + uint8_t read_value_index; //!< ref: @ref CSCS_Read_Info + T_CSCS_WRITE_MSG write; +} T_CSCS_UPSTREAM_MSG_DATA; + +/** CSC service data to inform application */ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_CSCS_UPSTREAM_MSG_DATA msg_data; +} T_CSCS_CALLBACK_DATA; +/** @} */ + +/** @brief CSC measurement data, variable length during connection, max can reach 11 bytes */ +typedef struct +{ + uint8_t cur_length; /**< length of current CSC measurement data. */ + uint8_t value[CSCS_MAX_MEASUREMENT_VALUE];/**< value of current CSC measurement data. */ +} T_CSCS_MEASUREMENT; + +/** + * @brief CSC Control Point data, variable length during connection, max can reach 17 bytes. + * + * CSC Control Point data used to store the Control Point Command recieved from the client. +*/ +typedef struct +{ + uint8_t cur_length; /**< length of current CSC Control Point data, . */ + uint8_t + value[CSCS_MAX_CTL_PNT_VALUE]; /**< value of current CSC Control Point data, . */ +} T_CSCS_CONTROL_POINT; +/** @} End of CSCS_Exported_Types */ + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup CSCS_Exported_Functions CSC Exported Functions + * @brief + * @{ + */ + + +/** + * @brief Add cycling speed and cadence service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + cscs_id = cscs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID cscs_add_service(void *p_func); + +/** + * @brief Set a cycling speed and cadence service parameter. + * + * NOTE: You can call this function with a cycling speed and cadence service parameter type and it will set the + * cycling speed and cadence service parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Cycling speed and cadence service parameter type: @ref T_CSCS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + cscs_set_parameter(CSCS_PARAM_CTL_PNT_PROG_CLR, 0, NULL); + } + * \endcode + */ +bool cscs_set_parameter(T_CSCS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Get a cycling speed and cadence parameter. + * + * NOTE: You can call this function with a cycling speed and cadence parameter type and it will get a + * gulcose parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE. + * + * @param[in] param_type Cycling speed and cadence parameter type: @ref T_CSCS_PARAM_TYPE + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + int record_num; + gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num); + } + * \endcode + */ +bool cscs_get_parameter(T_CSCS_PARAM_TYPE param_type, void *p_value); + + +/** + * @brief Send measurement value notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + uint8_t conn_id = p_parse_value->dw_param[0]; + cscs_set_parameter(CSCS_PARAM_WHEEL_REVOL, sizeof(cscs_cul_value), &cscs_cul_value); + op_result = cscs_meas_value_notify(conn_id, cscs_id); + } + * \endcode + */ +bool cscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id); + + + +/** + * @brief Send control point indication. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] op_code Op code. + * @param[in] rsp_code Response code. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + */ +bool cscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code, + uint8_t rsp_code); + + + + +/** @} End of CSCS_Exported_Functions */ + +/** @} End of CSC */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _CSCS_DEF_H */ + diff --git a/inc/bluetooth/profile/server/cscs_config.h b/inc/bluetooth/profile/server/cscs_config.h new file mode 100644 index 0000000..7b0d3d6 --- /dev/null +++ b/inc/bluetooth/profile/server/cscs_config.h @@ -0,0 +1,40 @@ +#ifndef _CSCS_CONFIG_H_ +#define _CSCS_CONFIG_H_ + + + +/** @defgroup CSCS Cycling Speed and Cadence Service + * @brief Cycling Speed and Cadence Service + * @{ + */ + +/** @defgroup CSCS_CONFIG Cycling Speed and Cadence Service Config + * @brief Cycling Speed and Cadence service configuration file + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup CSCS_Common_Exported_Macros CSCS Common Exported Macros + * @{ + */ + +#define CSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT +#define CSCS_SC_CONTROL_POINT_SUPPORT + +/** @brief Index of each characteristic in CSC service database. */ +#define GATT_SVC_CSCS_MEASUREMENT_INDEX 2 +#define GATT_SVC_CSCS_FEATURE_INDEX 5 +#define GATT_SVC_CSCS_SENS_LOC_INDEX 7 +#define GATT_SVC_CSCS_CTL_PNT_INDEX 9 +#define GATT_SVC_CSCS_MEAS_CCCD_INDEX (GATT_SVC_CSCS_MEASUREMENT_INDEX + 1) +#define GATT_SVC_CSCS_CTL_PNT_CCCD_INDEX (GATT_SVC_CSCS_CTL_PNT_INDEX + 1) + +/** @} End of CSCS_Common_Exported_Macros */ + +/** @} End of CSCS_CONFIG */ + +/** @} End of CSCS */ + +#endif diff --git a/inc/bluetooth/profile/server/dfu_service.h b/inc/bluetooth/profile/server/dfu_service.h new file mode 100644 index 0000000..cd957bd --- /dev/null +++ b/inc/bluetooth/profile/server/dfu_service.h @@ -0,0 +1,118 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file dfu_service.h +* @brief +* @details +* @author ken_mei +* @date 02-09-2016 +* @version v1.0.0 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +#ifndef _DFU_SERVICE_H_ +#define _DFU_SERVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" +#include "patch_header_check.h" +#include "dfu_api.h" + +#define DFU_NOTIFY_ENABLE 1 +#define DFU_NOTIFY_DISABLE 2 + +/*attribut index*/ +#define INDEX_DFU_PACKET_VALUE 0x02 +#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04 +#define INDEX_DFU_CHAR_CCCD_INDEX 0x05 + + + +typedef struct _T_DFU_CTRL_POINT +{ + uint8_t opcode; + T_IMG_CTRL_HEADER_FORMAT start_dfu; /* start dfu trans first 12 bytes ctrl header*/ +} T_DFU_CTRL_POINT, * P_DFU_CTRL_POINT; + +typedef struct +{ + T_IMG_CTRL_HEADER_FORMAT ctrl_header; + uint32_t image_total_length; + uint32_t origin_image_version; + uint32_t cur_offset; + uint16_t mtu_size; + bool dfu_conn_para_update_in_progress; + uint16_t dfu_conn_interval; + uint16_t dfu_conn_lantency; +} T_DFU_PARA; + +typedef struct +{ + T_IMG_ID image_id; + uint32_t image_size; + uint32_t image_offset; +} T_TEMP_IMAGE_INFO; + +typedef enum +{ + DFU_FAIL_UPDATE_FLASH, + DFU_FAIL_SYSTEM_RESET_CMD, + DFU_FAIL_EXCEED_MAX_BUFFER_SIZE, + DFU_FAIL_EXCEED_IMG_TOTAL_LEN, + +} T_DFU_FAIL_REASON; + +typedef enum +{ + DFU_WRITE_ATTR_ENTER, + DFU_WRITE_ATTR_EXIT, + DFU_WRITE_START, + DFU_WRITE_DOING, + DFU_WRITE_END, + DFU_WRITE_FAIL, +} T_DFU_WRITE_OPCODE; + + +typedef struct +{ + uint8_t opcode; + uint8_t write_attrib_index; + uint16_t length; + uint8_t *p_value; +} T_DFU_WRITE_MSG; + +typedef union _TDFU_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; + T_DFU_WRITE_MSG write; +} T_DFU_UPSTREAM_MSG_DATA; + +/** Dfu service data to inform application */ +typedef struct _TDFU_CALLBACK_DATA +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_DFU_UPSTREAM_MSG_DATA msg_data; +} T_DFU_CALLBACK_DATA; + +extern uint8_t *p_ota_temp_buffer_head; +extern uint16_t g_ota_tmp_buf_used_size; +extern T_DFU_PARA g_dfu_para; +extern bool is_ota_procedure; + +extern void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code); +extern void dfu_service_handle_valid_fw(uint8_t conn_id); +extern uint8_t dfu_add_service(void *pFunc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/dis.h b/inc/bluetooth/profile/server/dis.h new file mode 100644 index 0000000..a56df39 --- /dev/null +++ b/inc/bluetooth/profile/server/dis.h @@ -0,0 +1,228 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dis.h + * @brief Head file for using device information service. + * @details DIS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _DEVICE_INFO_SERVICE_H_ +#define _DEVICE_INFO_SERVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +/** + * @defgroup DIS Device Information Service + * @brief Device information service + * @details + The Device Information Service exposes manufacturer and/or vendor information about a device. + This module implements the Device Information Service. + The Device Information Service may expose one or more of the characteristics. It can be + configured in file @ref dis_config.h. + + Application shall register device information service when initialization. + + * Sample code: + * \code{.c} + void app_le_profile_init(void) + { + dis_service_id = dis_add_service(app_profile_callback); + } + * \endcode + + When characteristic value was read, write or cccd updated by remote device, @ref app_profile_callback will be + called. + Application shall set dis parameter value by call @ref dis_set_parameter. + + * Sample code: + * \code{.c} + T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data) + { + ... + if (dis_service_id == service_id) + { + T_DIS_CALLBACK_DATA *p_dis_cb_data = (T_DIS_CALLBACK_DATA *)p_data; + switch (p_dis_cb_data->msg_type) + { + case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE: + { + if (p_dis_cb_data->msg_data.read_value_index == DIS_READ_MANU_NAME_INDEX) + { + const uint8_t dis_manufacture_name[] = "Realtek BT"; + dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME, + sizeof(dis_manufacture_name), + (void *)dis_manufacture_name); + } + else if (p_dis_cb_data->msg_data.read_value_index == DIS_READ_MODEL_NUM_INDEX) + { + const uint8_t dis_model_number[] = "Model Num 1.0"; + dis_set_parameter(DIS_PARAM_MODEL_NUMBER, + sizeof(dis_model_number), + (void *)dis_model_number); + } + ... + ... + + } + + break; + default: + break; + } + } + } + * \endcode + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup DIS_Exported_Macros DIS Exported Macros + * @brief + * @{ + */ + +/** @defgroup DIS_READ_INFO_INDEX DIS Read Informatio Index + * @brief Read characteristic value index. + * @{ + */ +#define DIS_READ_MANU_NAME_INDEX 1 +#define DIS_READ_MODEL_NUM_INDEX 2 +#define DIS_READ_SERIAL_NUM_INDEX 3 +#define DIS_READ_HARDWARE_REV_INDEX 4 +#define DIS_READ_FIRMWARE_REV_INDEX 5 +#define DIS_READ_SOFTWARE_REV_INDEX 6 +#define DIS_READ_SYSTEM_ID_INDEX 7 +#define DIS_READ_IEEE_CERT_STR_INDEX 8 +#define DIS_READ_PNP_ID_INDEX 9 +/** @} */ + +#define DIS_SYSTEM_ID_LENGTH 8 +#define DIS_PNP_ID_LENGTH 7 + +/** @} End of DIS_Exported_Macros */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup DIS_Exported_Types DIS Exported Types + * @brief + * @{ + */ +/** @defgroup DIS_PARAM_TYPE DIS parameter type +* @brief Type of parameters set/got from application. +* @{ +*/ +typedef enum +{ + DIS_PARAM_MANUFACTURER_NAME, + DIS_PARAM_MODEL_NUMBER, + DIS_PARAM_SERIAL_NUMBER, + DIS_PARAM_HARDWARE_REVISION, + DIS_PARAM_FIRMWARE_REVISION, + DIS_PARAM_SOFTWARE_REVISION, + DIS_PARAM_SYSTEM_ID, + DIS_PARAM_IEEE_DATA_LIST, + DIS_PARAM_PNP_ID +} T_DIS_PARAM_TYPE; +/** @} */ + +/** DIS upstream message data*/ +typedef union +{ + uint8_t read_value_index; +} T_DIS_UPSTREAM_MSG_DATA; + +/** DIS callback data*/ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + uint8_t conn_id; + T_DIS_UPSTREAM_MSG_DATA msg_data; +} T_DIS_CALLBACK_DATA; + +/** @} End of DIS_Exported_Types */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DIS_Exported_Functions DIS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Set a device information service parameter. + * + * NOTE: You can call this function with a device information service parameter type and it will set the + * device information service parameter. Device information service parameters are defined in @ref T_DIS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Device information service parameter type: @ref T_DIS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + const uint8_t dis_manufacture_name[] = "Realtek BT"; + dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME, + sizeof(dis_manufacture_name), + (void *)dis_manufacture_name); + } + * \endcode + */ +bool dis_set_parameter(T_DIS_PARAM_TYPE param_type, uint8_t length, void *p_value); + +/** + * @brief Add device information service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + dis_id = dis_add_service(app_handle_profile_message); + } + * \endcode + */ + +T_SERVER_ID dis_add_service(void *p_func); + +/** @} End of DIS_Exported_Functions */ + +/** @} End of DIS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEVICE_INFO_SERVICE_H_ */ diff --git a/inc/bluetooth/profile/server/dis_config.h b/inc/bluetooth/profile/server/dis_config.h new file mode 100644 index 0000000..3c36523 --- /dev/null +++ b/inc/bluetooth/profile/server/dis_config.h @@ -0,0 +1,155 @@ +#ifndef _DIS_CONFIG_H_ +#define _DIS_CONFIG_H_ + + + +/** @defgroup DIS Device Information Service + * @brief Device information service + * @{ + */ + + +/** @defgroup DIS_CONFIG Device Information Service Config + * @brief Device information service config + * @{ + */ + +/** @defgroup DIS_Common_Exported_Macros Device Information Service Config Common Exported Macros + * @{ + */ + + +/** @defgroup DIS_Config_Supported_Features Device Information Service Config Supported Features + * @brief + The Device Information Service may expose one or more of the characteristics, user can + config DIS_CHAR_XXX_SUPPORT to 1 to support it, otherwise set it to 0. + * @{ + */ + +/** @details + Set DIS_CHAR_MANUFACTURER_NAME_SUPPORT to 1 to support Manufacturer Name String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_MANUFACTURER_NAME_SUPPORT 1 + +/** @details + Set DIS_CHAR_MODEL_NUMBER_SUPPORT to 1 to support Model Number String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_MODEL_NUMBER_SUPPORT 1 + +/** @details + Set DIS_CHAR_SERIAL_NUMBER_SUPPORT to 1 to support Serial Number String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_SERIAL_NUMBER_SUPPORT 1 + +/** @details + Set DIS_CHAR_FIRMWARE_REVISION_SUPPORT to 1 to support Firmware Revision String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_FIRMWARE_REVISION_SUPPORT 1 + +/** @details + Set DIS_CHAR_HARDWARE_REVISION_SUPPORT to 1 to support Hardware Revision String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_HARDWARE_REVISION_SUPPORT 1 + +/** @details + Set DIS_CHAR_SOFTWARE_REVISION_SUPPORT to 1 to support Software Revision String characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_SOFTWARE_REVISION_SUPPORT 1 + + +/** @details + Set DIS_CHAR_SYSTEM_ID_SUPPORT to 1 to support System ID characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_SYSTEM_ID_SUPPORT 1 + + +/** @details + Set DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT to 1 to support IEEE 11073-20601 Regulatory Certification Data List characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT 1 + +/** @details + Set DIS_CHAR_PNP_ID_SUPPORT to 1 to support PnP ID characteristic, + otherwise set it to 0. +*/ +#define DIS_CHAR_PNP_ID_SUPPORT 1 +/** + * @} + */ + + + +/** @defgroup DIS_Config_Max_Char_Value_Length Device Information Service Config Supported Value Length + * @brief + The max length of characteristic value can be configured here. + * @{ + */ +#ifdef DIS_CHAR_MANUFACTURER_NAME_SUPPORT +#define DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH 20 /**< Max length of Manufacturer Name String characteristic value*/ +#endif + +#ifdef DIS_CHAR_MODEL_NUMBER_SUPPORT +#define DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH 20 /**< Max length of Model Number String characteristic value*/ +#endif + +#ifdef DIS_CHAR_SERIAL_NUMBER_SUPPORT +#define DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH 20 /**< Max length of Serial Number String characteristic value*/ +#endif + +#ifdef DIS_CHAR_FIRMWARE_REVISION_SUPPORT +#define DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Firmware Revision String characteristic value*/ +#endif + +#ifdef DIS_CHAR_HARDWARE_REVISION_SUPPORT +#define DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Hardware Revision String scharacteristic value*/ +#endif + +#ifdef DIS_CHAR_SOFTWARE_REVISION_SUPPORT +#define DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH 20 /**< Max length of Software Revision String characteristic value*/ +#endif + + +#ifdef DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT +#define DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH 30 /**< Max length of IEEE 11073-20601 Regulatory Certification Data List characteristic value*/ +#endif +/** + * @} + */ + + + +/** @defgroup DIS_Config_Char_Value_Index Device Information Service Config Characteristic Value Index + * @brief + Attribute index value of each characteristic shall be configured by characteristic supported. If some + * @{ + */ +#define GATT_SVC_DIS_MANU_NAME_INDEX 2 /**< Attribute index of Manufacturer Name String characteristic */ +#define GATT_SVC_DIS_MODEL_NUM_INDEX 4 /**< Attribute index of Model Number String characteristic */ +#define GATT_SVC_DIS_SERIAL_NUM_INDEX 6 /**< Attribute index of Serial Number String characteristic */ +#define GATT_SVC_DIS_HARDWARE_REV_INDEX 8 /**< Attribute index of Hardware Revision String characteristic */ +#define GATT_SVC_DIS_FIRMWARE_REV_INDEX 10 /**< Attribute index of Firmware Revision String characteristic */ +#define GATT_SVC_DIS_SOFTWARE_REV_INDEX 12 /**< Attribute index of Software Revision String characteristic */ +#define GATT_SVC_DIS_SYSTEM_ID_INDEX 14 /**< Attribute index of System ID characteristic */ +#define GATT_SVC_DIS_IEEE_CERT_STR_INDEX 16 /**< Attribute index of IEEE 11073-20601 Regulatory Certification Data List characteristic */ +#define GATT_SVC_DIS_PNP_ID_INDEX 18 /**< Attribute index of Pnp ID characteristic */ +/** + * @} + */ + + +/** @} End of DIS_Common_Exported_Macros */ + +/** @} End of DIS_CONFIG */ + +/** @} End of DIS */ + + +#endif diff --git a/inc/bluetooth/profile/server/ftms.h b/inc/bluetooth/profile/server/ftms.h new file mode 100644 index 0000000..a733664 --- /dev/null +++ b/inc/bluetooth/profile/server/ftms.h @@ -0,0 +1,568 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ftms.h + * @brief Head file for using Fitness Machine Service. + * @details FTMS data types and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _FTMS_H_ +#define _FTMS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "ftms_define.h" +#include "srv_uuid.h" + +/** @defgroup Fitness Machine Service + * @brief Fitness Machine Service + * @details + + The Fitness Machine Service (FTMS) exposes training-related data in the sports + and fitness environment, which allows a Client to collect training data while + a user is exercising with a fitness machine (Server). + The service may also expose the Fitness Machine Status characteristic to send + information to the Client about the status of the machine. + The Fitness Machine Control Point may also be exposed by the Server in order to + provide a mechanism to remotely control a fitness machine. + The types of fitness machines that are currently supported are listed below: + Treadmill + Step Climber + Rower + Indoor Bike + Cross Trainer + Stair Climber + + The Fitness Machine Feature characteristic shall be used to describe the supported features of the Server. + The Treadmill Data characteristic is used to send training-related data to the Client from a treadmill (Server). + The Step Climber Data characteristic is used to send training-related data to the Client from a step climber (Server). + The Rower Data characteristic is used to send training-related data to the Client from a rower (Server). + The Indoor Bike Data characteristic is used to send training-related data to the Client from an indoor bike (Server). + The Cross Trainer Data characteristic is used to send training-related data to the Client from a cross trainer (Server). + The Stair Climber Data characteristic is used to send training-related data to the Client from a stair climber (Server). + The Supported Speed Range characteristic shall be exposed by the Server if the Speed Target Setting feature is supported. + The Supported Inclination Range characteristic shall be exposed by the Server if the Inclination Target Setting feature is supported. + The Supported Resistance Level Range characteristic shall be exposed by the Server if the Resistance Control Target Setting feature is supported. + The Supported Power Range characteristic shall be exposed by the Server if the Power Target Setting feature is supported. + The Supported Heart Rate Range characteristic shall be exposed by the Server if the Heart Rate Target Setting feature is supported. + The Fitness Machine Control Point characteristic is used to request a specific function to be executed on the Server. + The Fitness Machine Status characteristic is used to send the status of the Server. + + The specific configuration process can be achieved by modifying file @ref ftms_config.h. + + Application shall register Fitness Machine service when initialization through @ref ftms_add_service function. + + Application can set the Fitness Machine parameters through @ref ftms_set_parameter function. + + Application can send the treadmill data through @ref ftms_treadmill_data_notify function. + + Application can send the step climber data through @ref ftms_step_climber_data_notify function. + + Application can send the rower data through @ref ftms_rower_data_notify function. + + Application can send the indoor bike data through @ref ftms_indoor_bike_data_notify function. + + Application can send the indoor bike data through @ref ftms_cross_trainer_data_notify function. + + Application can send the indoor bike data through @ref ftms_stair_climber_data_notify function. + + Application can send the fitness machine status through @ref ftms_status_notify function. + + Application can clear the fitness machine flags through @ref ftms_flags_clear function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup FTMS_Exported_Macros FTMS Exported Macros + * @brief + * @{ + */ + +#define FTMS_NOTIFY_INDICATE_TREADMILL_DATA_ENABLE 1 +#define FTMS_NOTIFY_INDICATE_TREADMILL_DATA_DISABLE 2 +#define FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_ENABLE 3 +#define FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_DISABLE 4 +#define FTMS_NOTIFY_INDICATE_ROWER_DATA_ENABLE 5 +#define FTMS_NOTIFY_INDICATE_ROWER_DATA_DISABLE 6 +#define FTMS_NOTIFY_INDICATE_INDOOR_BIKE_DATA_ENABLE 7 +#define FTMS_NOTIFY_INDICATE_INDOOR_BIKE_DATA_DISABLE 8 +#define FTMS_NOTIFY_INDICATE_FTMS_CP_ENABLE 9 +#define FTMS_NOTIFY_INDICATE_FTMS_CP_DISABLE 10 +#define FTMS_NOTIFY_INDICATE_FTMS_STATUS_ENABLE 11 +#define FTMS_NOTIFY_INDICATE_FTMS_STATUS_DISABLE 12 +#define FTMS_NOTIFY_INDICATE_TRAIN_STATUS_ENABLE 13 +#define FTMS_NOTIFY_INDICATE_TRAIN_STATUS_DISABLE 14 +#define FTMS_NOTIFY_INDICATE_CROSS_TRAINER_DATA_ENABLE 15 +#define FTMS_NOTIFY_INDICATE_CROSS_TRAINER_DATA_DISABLE 16 +#define FTMS_NOTIFY_INDICATE_STAIR_CLIMBER_DATA_ENABLE 17 +#define FTMS_NOTIFY_INDICATE_STAIR_CLIMBER_DATA_DISABLE 18 + +/** End of FTMS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FTMS_Exported_Types UDS Exported Types + * @brief + * @{ + */ + +/** +* @brief Fitness Machine Service parameter type +*/ + +typedef union +{ + uint16_t target_speed; /* opcode FTMS_CP_OPCODE_SET_TGT_SPEED*/ + int16_t target_inclination; /* opcode FTMS_CP_OPCODE_SET_TGT_INCLINATION*/ + int16_t target_resistance_level; /* opcode FTMS_CP_OPCODE_SET_TGT_RESISTANCE_LEVEL*/ + int16_t target_power; /* opcode FTMS_CP_OPCODE_SET_TGT_POWER*/ + uint8_t target_heart_rate; /* opcode FTMS_CP_OPCODE_SET_TGT_HEART_RATE*/ + uint8_t ctrl_information; /* opcode FTMS_CP_OPCODE_STOP_PAUSE*/ + uint16_t target_expended_energy; /* opcode FTMS_CP_OPCODE_SET_TGT_EXPEND_ENERGY*/ + uint16_t target_step_num; /* opcode FTMS_CP_OPCODE_SET_TGT_STEP_NUM*/ + uint16_t target_stride_num; /* opcode FTMS_CP_OPCODE_SET_TGT_STRIDE_NUM*/ + uint32_t target_distance; /* opcode FTMS_CP_OPCODE_SET_TGT_DISTANCE (uint24) */ + uint16_t target_training_time; /* opcode FTMS_CP_OPCODE_SET_TGT_TRAINING_TIME*/ + T_FTMS_TWO_ZONES_HR_TIME + target_two_zones_hr_time; /* opcode FTMS_CP_OPCODE_SET_TGT_TWO_HR_ZONES_TIME*/ + T_FTMS_THREE_ZONES_HR_TIME + target_three_zones_hr_time; /* opcode FTMS_CP_OPCODE_SET_TGT_THREE_HR_ZONES_TIME*/ + T_FTMS_FIVE_ZONES_HR_TIME + target_five_zones_hr_time; /* opcode FTMS_CP_OPCODE_SET_TGT_FIVE_HR_ZONES_TIME*/ + T_FTMS_INDOOR_BIKE_SIMULATION_PARAM + set_indoor_bike_simulation_param; /* opcode FTMS_CP_OPCODE_SET_INDOOR_BIKE_SIMULATION_PARAM*/ + uint16_t wheel_circumference; /* opcode FTMS_CP_OPCODE_SET_WHEEL_CIRCUMFERENCE */ + uint8_t ctrl_param; /* opcode FTMS_CP_OPCODE_SPIN_DOWN_CTRL */ + uint8_t spin_down_status_value; + uint16_t target_cadence; /* opcode FTMS_CP_OPCODE_SET_TGT_CADENCE*/ +} T_FTMS_CP_PARAMETER; + +typedef enum +{ + FTMS_PARAM_FTMS_FEATURE = 0x01, /* Set fitness machine feature */ + FTMS_PARAM_SUPPORT_SPEED_RANGE, /* Set supported speed range */ + FTMS_PARAM_SUPPORT_INCLINATION_RANGE, /* Set supported inclination range */ + FTMS_PARAM_SUPPORT_RESISTANCE_LEVEL_RANGE, /* Set supported resistance level range */ + FTMS_PARAM_SUPPORT_POWER_RANGE, /* Set supported power range */ + FTMS_PARAM_SUPPORT_HR_RANGE, /* Set supported heart rate range */ + FTMS_PARAM_TREADMILL_DATA_FLAG, /* Set treadmill data flag field */ + FTMS_PARAM_STEP_CLIMBER_DATA_FLAG, /* Set step climber data flag field */ + FTMS_PARAM_ROWER_DATA_FLAG, /* Set rower data flag field */ + FTMS_PARAM_INDOOR_BIKE_DATA_FLAG, /* Set indoor bike data flag field */ + FTMS_PARAM_CTL_PNT_PROG_CLR, /* Set control point opcode to reserved */ + FTMS_PARAM_SD_RESP_PARAM, /* Set spin down response parameter */ + FTMS_PARAM_CROSS_TRAINER_DATA_FLAG, /* Set cross trainer data flag field */ + FTMS_PARAM_STAIR_CLIMBER_DATA_FLAG /* Set stair climber data flag field */ +} T_FTMS_PARAM_TYPE; + +typedef struct +{ + uint8_t opcode; + T_FTMS_CP_PARAMETER cp_parameter; +} T_FTMS_WRITE_MSG; + +typedef struct +{ + uint8_t notification_indication_index; + T_FTMS_WRITE_MSG write; +} T_FTMS_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + uint16_t char_uuid; + T_SERVICE_CALLBACK_TYPE msg_type; + T_FTMS_UPSTREAM_MSG_DATA msg_data; +} T_FTMS_CALLBACK_DATA; + +/** End of FTMS_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup FTMS_Exported_Functions FTMS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add fitness machine service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + ftms_id = ftms_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID ftms_add_service(void *p_func); + +/** + * @brief Set a fitness machine service parameter. + * + * NOTE: You can call this function with a fitness machine service parameter type and it will set the + * fitness machine service parameter. Fitness machine service parameters are defined in @ref T_FTMS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must point to a data + * with type of "uint16_t". + * + * @param[in] param_type Fitness machine service parameter type: @ref T_FTMS_PARAM_TYPE + * @param[in] len Length of data to write. + * @param[in] p_value Pointer to data to write. + * This is dependent on the parameter type and will be cast to the appropriate data type. + If param_type is set to @ref FTMS_PARAM_FTMS_FEATURE, p_value pointer to the current + fitness machine feature. Type is org.bluetooth.characteristic.fitness_machine_feature. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_FTMS_FEATURE ftms_feature; + ftms_feature.features_field = FTMS_FEAT_ALL_FEATURE_SUPPORTED; + ftms_feature.target_setting_field = FTMS_TGT_SET_ALL_FEATURE_SUPPORTED; + ftms_set_parameter(FTMS_PARAM_FTMS_FEATURE, sizeof(T_FTMS_FEATURE), &ftms_feature); + } + * \endcode + */ +bool ftms_set_parameter(T_FTMS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send treadmill data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_treadmill_data Pointer to data to notify. + Type is org.bluetooth.characteristic.treadmill_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_TREADMILL_DATA ftms_treadmill_data = {350, 250, 1000, 15, 12, 100, 200, 10, 12, + 2400, 1200, 20, 87, 30, 1200, 6000, 50, + 2400}; + void test(uint8_t conn_id) + { + T_FTMS_TREADMILL_DATA data = {370, 260, 2000, 15, 12, 100, 200, 10, 12, 2800, 1200, + 20, 87, 30, 1250, 5950, 50, 2400}; + memcpy(&ftms_treadmill_data, &data, sizeof(T_FTMS_TREADMILL_DATA)); + ftms_treadmill_data_notify(conn_id, ftms_id, &ftms_treadmill_data); + } + * \endcode + */ +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT +bool ftms_treadmill_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_TREADMILL_DATA *p_treadmill_data); +#endif + +/** + * @brief Send step climber data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_step_climber_data Pointer to data to indicate. + Type is org.bluetooth.characteristic.step_climber_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_STEP_CLIMBER_DATA ftms_step_climber_data = {30, 3000, 50, 500, 100, 2400, 1200, + 20, 87, 30, 1200, 6000}; + void test(uint8_t conn_id) + { + T_FTMS_STEP_CLIMBER_DATA step_climber_data = {35, 3500, 50, 500, 100, 2800, 1200, + 20, 89, 30, 1250, 5950}; + memcpy(&ftms_step_climber_data, &step_climber_data, sizeof(T_FTMS_STEP_CLIMBER_DATA)); + ftms_step_climber_data_notify(conn_id, ftms_id, &ftms_step_climber_data); + } + * \endcode + */ +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT +bool ftms_step_climber_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_STEP_CLIMBER_DATA *p_step_climber_data); +#endif + +/** + * @brief Send rower data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_rower_data Pointer to data to indicate. + Type is org.bluetooth.characteristic.rower_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_ROWER_DATA ftms_rower_data = {20, 3000, 18, 1000, 10, 12, 350, 400, 20, 2400, + 1200, 20, 87, 30, 1200, 6000}; + void test(uint8_t conn_id) + { + T_FTMS_ROWER_DATA rower_data = {25, 3500, 18, 2000, 10, 12, 350, 400, 20, 2800, + 1200, 20, 89, 30, 1250, 5950}; + memcpy(&ftms_rower_data, &rower_data, sizeof(T_FTMS_ROWER_DATA)); + ftms_rower_data_notify(conn_id, ftms_id, &ftms_rower_data); + } + * \endcode + */ +#if FTMS_CHAR_ROWER_DATA_SUPPORT +bool ftms_rower_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_ROWER_DATA *p_rower_data); +#endif + +/** + * @brief Send indoor bike data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_indoor_bike_data Pointer to data to indicate. + Type is org.bluetooth.characteristic.indoor_bike_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_INDOOR_BIKE_DATA ftms_indoor_bike_data = {350, 250, 30, 35, 1000, 20, 350, 400, + 2400, 1200, 20, 87, 30, 1200, 6000}; + void test(uint8_t conn_id) + { + T_FTMS_INDOOR_BIKE_DATA indoor_bike_data = {380, 260, 30, 35, 2000, 20, 350, 400, + 2800, 1200, 20, 89, 30, 1250, 5950}; + memcpy(&ftms_indoor_bike_data, &indoor_bike_data, sizeof(T_FTMS_INDOOR_BIKE_DATA)); + ftms_indoor_bike_data_notify(conn_id, ftms_id, &ftms_indoor_bike_data); + } + * \endcode + */ +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT +bool ftms_indoor_bike_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_INDOOR_BIKE_DATA *p_indoor_bike_data); +#endif + +/** + * @brief Send indoor bike data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_cross_trainer_data Pointer to data to indicate. + Type is org.bluetooth.characteristic.cross_trainer_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_CROSS_TRAINER_DATA ftms_cross_trainer_data = {350, 250, 1000, 70, 65, 2000, 100, + 200, 15, 12, 20, 350, 400, 2400, + 1200, 20, 87, 30, 1200, 6000}; + void test(uint8_t conn_id) + { + T_FTMS_CROSS_TRAINER_DATA cross_trainer_data = {380, 260, 1000, 70, 65, 2000, 100, + 200, 15, 12, 20, 350, 400, 2400, + 1200, 20, 89, 30, 1250, 5950}; + memcpy(&ftms_cross_trainer_data, &cross_trainer_data, sizeof(T_FTMS_CROSS_TRAINER_DATA)); + cmd_ftms_cross_trainer_data_notify(conn_id, ftms_id, &ftms_cross_trainer_data); + } + * \endcode + */ +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT +bool ftms_cross_trainer_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_CROSS_TRAINER_DATA *p_cross_trainer_data); +#endif + +/** + * @brief Send indoor bike data notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] p_stair_climber_data Pointer to data to indicate. + Type is org.bluetooth.characteristic.stair_climber_data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_FTMS_STAIR_CLIMBER_DATA ftms_stair_climber_data = {30, 70, 65, 15, 20, 2400, 1200, 20, + 87, 30, 1200, 6000}; + void test(uint8_t conn_id) + { + T_FTMS_STAIR_CLIMBER_DATA stair_climber_data = {40, 70, 65, 15, 20, 2400, 1200, 20, + 89, 30, 1250, 5950}; + memcpy(&ftms_stair_climber_data, &stair_climber_data, sizeof(T_FTMS_STAIR_CLIMBER_DATA)); + ftms_stair_climber_data_notify(conn_id, ftms_id, &stair_climber_data); + } + * \endcode + */ +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT +bool ftms_stair_climber_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_STAIR_CLIMBER_DATA *p_stair_climber_data); +#endif + +/** + * @brief Send fitness machine control point indication data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] op_code Op code. + * @param[in] rsp_code Response code. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) + { + uint8_t op_code = FTMS_CP_OPCODE_REQUEST_CONTROL; + ftms_var.control_permission = true; + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); + } + * \endcode + */ +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT +bool ftms_ctl_pnt_indication(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, + uint8_t rsp_code); +#endif + +/** + * @brief Send fitness machine status notification data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] opcode Op code. + * @param[in] param Data to notify. + * @param[in] param_len Length of data to notify. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(uint8_t conn_id) + { + T_FTMS_CP_PARAMETER status_value; + uint8_t opcode = FTMS_STATUS_OP_TGT_SPEED_CHANGE; + uint16_t data_length = sizeof(uint16_t); + + status_value.target_speed = ftms_target_param.target_speed; + ftms_status_notify(conn_id, ftms_id, opcode, status_value, data_length); + } + * \endcode + */ +#if (FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT || FTMS_CHAR_FTMS_STATUS_SUPPORT) +bool ftms_status_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, + T_FTMS_CP_PARAMETER param, uint8_t param_len); +#endif + +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT +bool ftms_train_status_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t *p_data, uint16_t len, T_APP_RESULT cause); + +/** + * @brief Send fitness machine status notification data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] string_len Training status string length. + * @param[in] p_train_status_data Pointer to data to notify. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(uint8_t conn_id) + { + uint8_t string[25] = {'f', 't', 'm', 's', 't', 'r', 'a', 'i', 'n', 's', + 't', 'a', 't', 'u', 's'}; + uint16_t string_len = sizeof(string); + ftms_train_status.train_status_string = os_mem_zalloc(RAM_TYPE_DATA_ON, string_len); + memcpy(ftms_train_status.train_status_string, string, string_len); + ftms_train_status_notify(conn_id, ftms_id, string_len, &ftms_train_status); + } + * \endcode + */ +bool ftms_train_status_notify(uint8_t conn_id, T_SERVER_ID service_id, uint16_t string_len, + T_FTMS_TRAIN_STATUS *p_train_status_data); +#endif + +/** + * @brief Clear flags if procedure fail or disconnect. + * + * Example usage + * \code{.c} + void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) + { + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, gap_conn_state, new_state, disc_cause); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE)) + && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + + ftms_flags_clear(); + } + break; + } + } + * \endcode + */ +void ftms_flags_clear(void); + +/** @} End of FTMS_Exported_Functions */ + +/** @} End of FTMS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FTMS_H_ */ diff --git a/inc/bluetooth/profile/server/ftms_config.h b/inc/bluetooth/profile/server/ftms_config.h new file mode 100644 index 0000000..ea2ba07 --- /dev/null +++ b/inc/bluetooth/profile/server/ftms_config.h @@ -0,0 +1,121 @@ +#ifndef _FTMS_CONFIG_H_ +#define _FTMS_CONFIG_H_ + +/** @defgroup Fitness Machine Service configuration file + * @brief Fitness Machine Service configuration file + * @{ + */ +#include +#include + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup FTMS_Common_Exported_Macros FTMS Common Exported Macros + * @{ + */ + +/** @details + * +*/ +/** @details + Set FTMS_CHAR_TREADMILL_DATA_SUPPORT to 1 to support Treadmill Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_TREADMILL_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT to 1 to support Step Climber Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_ROWER_DATA_SUPPORT to 1 to support Rower Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_ROWER_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT to 1 to support Indoor Bike Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT to 1 to support Cross Trainer Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT to 1 to support Cross Trainer Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT 1 + +/** @details + Set FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT to 1 to support Indoor Bike Data characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_TRAINING_STATUS_SUPPORT 1 + +/** @details + Set FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT to 1 to support Supported Speed Range characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT 1 + +/** @details + Set FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT to 1 to support Supported Inclination Range + characteristic, otherwise set it to 0. +*/ +#define FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT 1 + +/** @details + Set FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT to 1 to support Supported Resistance Level + Range characteristic, otherwise set it to 0. +*/ +#define FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT 1 + +/** @details + Set FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT to 1 to support Supported Heart Rate Range characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT 1 + +/** @details + Set FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT to 1 to support Supported Power Range characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT 1 + +/** @details + Set FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT to 1 to support Fitness Machine Control Point characteristic, + otherwise set it to 0. +*/ +#define FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT 1 + +/** @details + If Fitness Machine Control Point characteristic is supported, set FTMS_CHAR_CP_SET_WHEEL_CIRCUMFERENCE_SUPPORT + to 1 to support Set Wheel Circumference opcode, otherwise set it to 0. +*/ +#define FTMS_CHAR_CP_SET_WHEEL_CIRCUMFERENCE_SUPPORT 1 + +/** @details + If Fitness Machine Control Point characteristic is supported, set FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + to 1 to support Spin Down Control opcode, otherwise set it to 0. +*/ +#define FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT 1 + +/** @details + When FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT is set to 0, set FTMS_CHAR_FTMS_STATUS_SUPPORT to 1 to + support Fitness Machine Control Point characteristic, otherwise set it to 0. +*/ +#define FTMS_CHAR_FTMS_STATUS_SUPPORT 1 + +/** @} End of FTMS_Common_Exported_Macros */ + +/** @} End of FTMS_CONFIG */ + +#endif /* _FTMS_CONFIG_H_ */ diff --git a/inc/bluetooth/profile/server/ftms_define.h b/inc/bluetooth/profile/server/ftms_define.h new file mode 100644 index 0000000..54562ee --- /dev/null +++ b/inc/bluetooth/profile/server/ftms_define.h @@ -0,0 +1,635 @@ +#ifndef _FTMS_DEFINE_H_ +#define _FTMS_DEFINE_H_ + +/** @defgroup Fitness Machine Service define file + * @brief Fitness Machine Service define file + * @{ + */ +#include +#include +#include "ftms_config.h" + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup FTMS_Common_Exported_Macros FTMS Common Exported Macros + * @{ + */ + +/** @details + * +*/ +/** @brief service related UUIDs. */ + +#define GATT_UUID_FITNESS_MACHINE 0x1826 +#define GATT_UUID_FITNESS_MACHINE_FEATURE 0x2ACC +#define GATT_UUID_TREADMILL_DATA 0x2ACD +#define GATT_UUID_CROSS_TRAINER_DATA 0x2ACE +#define GATT_UUID_STEP_CLIMBER_DATA 0x2ACF +#define GATT_UUID_STAIR_CLIMBER_DATA 0x2AD0 +#define GATT_UUID_ROWER_DATA 0x2AD1 +#define GATT_UUID_INDOOR_BIKE_DATA 0x2AD2 +#define GATT_UUID_TRAINING_STATUS 0x2AD3 +#define GATT_UUID_SUPPORT_SPEED_RANGE 0x2AD4 +#define GATT_UUID_SUPPORT_INCLINATION_RANGE 0x2AD5 +#define GATT_UUID_SUPPORT_RESISTANCE_LEVEL_RANGE 0x2AD6 +#define GATT_UUID_SUPPORT_HEART_RATE_RANGE 0x2AD7 +#define GATT_UUID_SUPPORT_POWER_RANGE 0x2AD8 +#define GATT_UUID_FTMS_CONTROL_POINT 0x2AD9 +#define GATT_UUID_FITNESS_MACHINE_STATUS 0x2ADA + +/** @defgroup FTMS_Control_Point FTMS Control Point + * @brief Control Point + * @{ + */ + +/** @defgroup FTMS_Control_Point_OpCodes FTMS Control Point OpCodes + * @brief Control Point OpCodes + * @{ + */ + +#define FTMS_CP_OPCODE_REQUEST_CONTROL 0x00 /* Request Control */ +#define FTMS_CP_OPCODE_RESET 0x01 /* Reset */ +#define FTMS_CP_OPCODE_SET_TGT_SPEED 0x02 /* Set Target Speed */ +#define FTMS_CP_OPCODE_SET_TGT_INCLINATION 0x03 /* Set Target Inclination */ +#define FTMS_CP_OPCODE_SET_TGT_RESISTANCE_LEVEL 0x04 /* Set Target Resistance Level */ +#define FTMS_CP_OPCODE_SET_TGT_POWER 0x05 /* Set Target Power */ +#define FTMS_CP_OPCODE_SET_TGT_HEART_RATE 0x06 /* Set Target Heart Rate */ +#define FTMS_CP_OPCODE_START_RESUME 0x07 /* Start or Resume */ +#define FTMS_CP_OPCODE_STOP_PAUSE 0x08 /* Stop or Pause */ +#define FTMS_CP_OPCODE_SET_TGT_EXPEND_ENERGY 0x09 /* Set Targeted Expended Energy */ +#define FTMS_CP_OPCODE_SET_TGT_STEP_NUM 0x0A /* Set Targeted Number of Steps */ +#define FTMS_CP_OPCODE_SET_TGT_STRIDE_NUM 0x0B /* Set Targeted Number of Strides */ +#define FTMS_CP_OPCODE_SET_TGT_DISTANCE 0x0C /* Set Targeted Distance */ +#define FTMS_CP_OPCODE_SET_TGT_TRAINING_TIME 0x0D /* Set Targeted Training Time */ +#define FTMS_CP_OPCODE_SET_TGT_TWO_HR_ZONES_TIME 0x0E /* Set Targeted Time in Two Heart Rate Zones */ +#define FTMS_CP_OPCODE_SET_TGT_THREE_HR_ZONES_TIME 0x0F /* Set Targeted Time in Three Heart Rate Zones */ +#define FTMS_CP_OPCODE_SET_TGT_FIVE_HR_ZONES_TIME 0x10 /* Set Targeted Time in Five Heart Rate Zones */ +#define FTMS_CP_OPCODE_SET_INDOOR_BIKE_SIMULATION_PARAM 0x11 /* Set Indoor Bike Simulation Parameters */ +#define FTMS_CP_OPCODE_SET_WHEEL_CIRCUMFERENCE 0x12 /* Set Wheel Circumference */ +#define FTMS_CP_OPCODE_SPIN_DOWN_CTRL 0x13 /* Spin Down Control */ +#define FTMS_CP_OPCODE_SET_TGT_CADENCE 0x14 /* Set Targeted Cadence */ +#define FTMS_CP_OPCODE_RESPONSE_CODE 0x80 /* Response Code */ +#define FTMS_CP_OPCODE_RESERVED 0xFF /* Reserved for Future Use */ +/** @} */ + +/** @defgroup FTMS_Control_Point_Response_Codes FTMS Control Point Response Codes + * @brief Control Point Response Codes + * @{ + */ + +#define FTMS_CP_RSPCODE_RESERVED 0x00 +#define FTMS_CP_RSPCODE_SUCCESS 0x01 +#define FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT 0x02 +#define FTMS_CP_RSPCODE_INVALID_PARAMETER 0x03 +#define FTMS_CP_RSPCODE_OPERATION_FAILED 0x04 +#define FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED 0x05 + +/** @} */ + +///@cond +/** @brief Judge FTMS Control Point operation is available or not. */ +#define FTMS_CTL_PNT_OPERATE_ACTIVE(x) \ + ( (x == FTMS_CP_OPCODE_REQUEST_CONTROL) || \ + (x == FTMS_CP_OPCODE_RESET) || \ + (x == FTMS_CP_OPCODE_SET_TGT_SPEED) || \ + (x == FTMS_CP_OPCODE_SET_TGT_INCLINATION) || \ + (x == FTMS_CP_OPCODE_SET_TGT_RESISTANCE_LEVEL) || \ + (x == FTMS_CP_OPCODE_SET_TGT_POWER) || \ + (x == FTMS_CP_OPCODE_SET_TGT_HEART_RATE) || \ + (x == FTMS_CP_OPCODE_START_RESUME) || \ + (x == FTMS_CP_OPCODE_STOP_PAUSE) || \ + (x == FTMS_CP_OPCODE_SET_TGT_EXPEND_ENERGY) || \ + (x == FTMS_CP_OPCODE_SET_TGT_STEP_NUM) || \ + (x == FTMS_CP_OPCODE_SET_TGT_STRIDE_NUM) || \ + (x == FTMS_CP_OPCODE_SET_TGT_DISTANCE) || \ + (x == FTMS_CP_OPCODE_SET_TGT_TRAINING_TIME) || \ + (x == FTMS_CP_OPCODE_SET_TGT_TWO_HR_ZONES_TIME) || \ + (x == FTMS_CP_OPCODE_SET_TGT_THREE_HR_ZONES_TIME) || \ + (x == FTMS_CP_OPCODE_SET_TGT_FIVE_HR_ZONES_TIME) || \ + (x == FTMS_CP_OPCODE_SET_INDOOR_BIKE_SIMULATION_PARAM) || \ + (x == FTMS_CP_OPCODE_SET_TGT_CADENCE) || \ + (x == FTMS_CP_OPCODE_RESPONSE_CODE) ) +///@endcond + +/** @defgroup FTMS_Status_OpCodes FTMS Status OpCodes + * @brief Status OpCodes + * @{ + */ + +#define FTMS_STATUS_OP_RESERVED 0x00 +#define FTMS_STATUS_OP_RESET 0x01 /* Reset */ +#define FTMS_STATUS_OP_STOP_PAUSE_BY_USER 0x02 /* Fitness Machine Stopped or Paused by the User */ +#define FTMS_STATUS_OP_STOP_BY_SAFETY_KEY 0x03 /* Fitness Machine Stopped by Safety Key */ +#define FTMS_STATUS_OP_START_RESUME_BY_USER 0x04 /* Fitness Machine Started or Resumed by the User */ +#define FTMS_STATUS_OP_TGT_SPEED_CHANGE 0x05 /* Target Speed Changed */ +#define FTMS_STATUS_OP_TGT_INCLINE_CHANGE 0x06 /* Target Incline Changed */ +#define FTMS_STATUS_OP_TGT_RESISTANCE_LEVEL_CHANGE 0x07 /* Target Resistance Level Changed */ +#define FTMS_STATUS_OP_TGT_POWER_CHANGE 0x08 /* Target Power Changed */ +#define FTMS_STATUS_OP_TGT_HR_CHANGE 0x09 /* Target Heart Rate Changed */ +#define FTMS_STATUS_OP_TGT_EXPEND_ENERGY_CHANGE 0x0A /* Targeted Expended Energy Changed */ +#define FTMS_STATUS_OP_TGT_STEP_NUM_CHANGE 0x0B /* Targeted Number of Steps Changed */ +#define FTMS_STATUS_OP_TGT_STRIDE_NUM_CHANGE 0x0C /* Targeted Number of Strides Changed */ +#define FTMS_STATUS_OP_TGT_DISTANCE_CHANGE 0x0D /* Targeted Distance Changed */ +#define FTMS_STATUS_OP_TGT_TRAIN_TIME_CHANGE 0x0E /* Targeted Training Time Changed */ +#define FTMS_STATUS_OP_TWO_HR_ZONE_TIME_CHANGE 0x0F /* Targeted Time in Two Heart Rate Zones Changed */ +#define FTMS_STATUS_OP_THREE_HR_ZONE_TIME_CHANGE 0x10 /* Targeted Time in Three Heart Rate Zones Changed */ +#define FTMS_STATUS_OP_FIVE_HR_ZONE_TIME_CHANGE 0x11 /* Targeted Time in Five Heart Rate Zones Changed */ +#define FTMS_STATUS_OP_IB_SIMULATE_PARAM_CHANGE 0x12 /* Indoor Bike Simulation Parameters Changed */ +#define FTMS_STATUS_OP_WHEEL_CIRCUMFERENCE_CHANGE 0x13 /* Wheel Circumference Changed */ +#define FTMS_STATUS_OP_SPIN_DOWN_STATUS 0x14 /* Spin Down Status */ +#define FTMS_STATUS_OP_TGT_CADENCE_CHANGE 0x15 /* Targeted Cadence Changed */ +#define FTMS_STATUS_OP_CONTROL_PERMISSION_LOST 0xFF /* Control Permission Lost */ + +/** @} */ + +/** @defgroup FTMS_Training_Status_Flags FTMS Training Status Flags + * @brief Training Status Flags + * @{ + */ + +#define FTMS_TS_STRING_PRESENT_MASK (1) /* Training Status String present */ +#define FTMS_TS_EXTENDED_STRING_PRESENT_MASK (1<<1) /* Extended String present */ + +/** @} */ + +/** @defgroup FTMS_Training_Status_Values FTMS Training Status Values + * @brief Training Status Values + * @{ + */ + +#define FTMS_TRAIN_STATUS_OTHER 0x00 /* Other */ +#define FTMS_TRAIN_STATUS_IDLE 0x01 /* Idle */ +#define FTMS_TRAIN_STATUS_WARMING_UP 0x02 /* Warming Up */ +#define FTMS_TRAIN_STATUS_LOW_INTENSITY_INTERVAL 0x03 /* Low Intensity Interval */ +#define FTMS_TRAIN_STATUS_HIGH_INTENSITY_INTERVAL 0x04 /* High Intensity Interval */ +#define FTMS_TRAIN_STATUS_RECOVERY_INTERVAL 0x05 /* Recovery Interval */ +#define FTMS_TRAIN_STATUS_ISOMETRIC 0x06 /* Isometric */ +#define FTMS_TRAIN_STATUS_HEART_RATE_CTRL 0x07 /* Heart Rate Control */ +#define FTMS_TRAIN_STATUS_FITNESS_TEST 0x08 /* Fitness Test */ +#define FTMS_TRAIN_STATUS_SPEED_OUT_CTRL_REGION_LOW 0x09 /* Speed Outside of Control Region - Low */ +#define FTMS_TRAIN_STATUS_SPEED_OUT_CTRL_REGION_HIGH 0x0A /* Speed Outside of Control Region - High */ +#define FTMS_TRAIN_STATUS_COOL_DOWN 0x0B /* Cool Down */ +#define FTMS_TRAIN_STATUS_WATT_CTRL 0x0C /* Watt Control */ +#define FTMS_TRAIN_STATUS_MANUAL_MODE 0x0D /* Manual Mode (Quick Start) */ +#define FTMS_TRAIN_STATUS_PRE_WORKOUT 0x0E /* Pre-Workout */ +#define FTMS_TRAIN_STATUS_POST_WORKOUT 0x0F /* Post-Workout */ +#define FTMS_TRAIN_STATUS_RESERVED 0xFF + +/** @} */ + +/** @defgroup FTMS_Feature_Field_Flag_Bit_Mask FTMS Feature Field Flag Bit Mask + * @brief FTMS feature field 'Flags' bit mask. + * @{ + */ + +#define FTMS_FEAT_AVERAGE_SPEED_SPT_MASK (1) /* Average Speed Supported */ +#define FTMS_FEAT_CADENCE_SPT_MASK (1<<1) /* Cadence Supported */ +#define FTMS_FEAT_TOTAL_DISTANCE_SPT_MASK (1<<2) /* Total Distance Supported */ +#define FTMS_FEAT_INCLINATION_SPT_MASK (1<<3) /* Inclination Supported */ +#define FTMS_FEAT_ELEVATION_GAIN_SPT_MASK (1<<4) /* Elevation Gain Supported */ +#define FTMS_FEAT_PACE_SPT_MASK (1<<5) /* Pace Supported */ +#define FTMS_FEAT_STEP_COUNT_SPT_MASK (1<<6) /* Step Count Supported */ +#define FTMS_FEAT_RESISTANCE_LEVEL_SPT_MASK (1<<7) /* Resistance Level Supported */ +#define FTMS_FEAT_STRIDE_COUNT_SPT_MASK (1<<8) /* Stride Count Supported */ +#define FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK (1<<9) /* Expended Energy Supported */ +#define FTMS_FEAT_HR_MEASUREMENT_SPT_MASK (1<<10) /* Heart Rate Measurement Supported */ +#define FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK (1<<11) /* Metabolic Equivalent Supported */ +#define FTMS_FEAT_ELAPSED_TIME_SPT_MASK (1<<12) /* Elapsed Time Supported */ +#define FTMS_FEAT_REMAIN_TIME_SPT_MASK (1<<13) /* Remaining Time Supported */ +#define FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK (1<<14) /* Power Measurement Supported */ +#define FTMS_FEAT_BELT_FORCE_POWER_OUTPUT_SPT_MASK (1<<15) /* Force on Belt and Power Output Supported */ +#define FTMS_FEAT_USER_DATA_RETENTION_SPT_MASK (1<<16) /* User Data Retention Supported */ +#define FTMS_FEAT_ALL_FEATURE_SUPPORTED (0x1FFFF) /* FTMS Support all features */ + +/** @} */ + +/** @defgroup FTMS_Target_Setting_Field_Flag_Bit_Mask FTMS Target Setting Field Flag Bit Mask + * @brief FTMS target setting field 'Flags' bit mask. + * @{ + */ + +#define FTMS_TGT_SET_SPEED_SPT_MASK (1) /* Speed Target Setting Supported */ +#define FTMS_TGT_SET_INCLINATION_SPT_MASK (1<<1) /* Inclination Target Setting Supported */ +#define FTMS_TGT_SET_RESISTANCE_SPT_MASK (1<<2) /* Resistance Target Setting Supported */ +#define FTMS_TGT_SET_POWER_SPT_MASK (1<<3) /* Power Target Setting Supported */ +#define FTMS_TGT_SET_HR_SPT_MASK (1<<4) /* Heart Rate Target Setting Supported */ +#define FTMS_TGT_EXPENDED_ENERGY_CONFIG_SPT_MASK (1<<5) /* Targeted Expended Energy Configuration Supported */ +#define FTMS_TGT_STEP_NUM_CONFIG_SPT_MASK (1<<6) /* Targeted Step Number Configuration Supported */ +#define FTMS_TGT_STRIDE_NUM_CONFIG_SPT_MASK (1<<7) /* Targeted Stride Number Configuration Supported */ +#define FTMS_TGT_DISTANCE_CONFIG_SPT_MASK (1<<8) /* Targeted Distance Configuration Supported */ +#define FTMS_TGT_TRAINING_TIME_CONFIG_SPT_MASK (1<<9) /* Targeted Training Time Configuration Supported */ +#define FTMS_TGT_TWO_HR_ZONES_TIME_CONFIG_SPT_MASK (1<<10) /* Targeted Time in Two Heart Rate Zones Configuration Supported */ +#define FTMS_TGT_THREE_HR_ZONES_CONFIG_SPT_MASK (1<<11) /* Targeted Time in Three Heart Rate Zones Configuration Supported */ +#define FTMS_TGT_FIVE_HR_ZONES_CONFIG_SPT_MASK (1<<12) /* Targeted Time in Five Heart Rate Zones Configuration Supported */ +#define FTMS_INDOOR_BIKE_SIMULATION_PARAM_SPT_MASK (1<<13) /* Indoor Bike Simulation Parameters Supported */ +#define FTMS_WHEEL_CIRCUMFERENCE_CONFIG_SPT_MASK (1<<14) /* Wheel Circumference Configuration Supported */ +#define FTMS_SPIN_DOWN_CTL_SPT_MASK (1<<15) /* Spin Down Control Supported */ +#define FTMS_TGT_CADENCE_CONFIG_SPT_MASK (1<<16) /* Targeted Cadence Configuration Supported */ +#define FTMS_TGT_SET_ALL_FEATURE_SUPPORTED (0x1FFFF) /* FTMS Support all features */ + +/** @} */ + +/** @defgroup FTMS_Treadmill_Data_Flag_Bit_Mask FTMS Treadmill Data Flag Bit Mask + * @brief FTMS treadmill data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT +#define FTMS_TM_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_TM_AVE_SPEED_PRESENT_MASK (1<<1) /* Average Speed Present */ +#define FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK (1<<2) /* Total Distance Present */ +#define FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK (1<<3) /* Inclination and Ramp Angle Setting Present */ +#define FTMS_TM_ELEVATION_GAIN_PRESENT_MASK (1<<4) /* Elevation Gain Present */ +#define FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK (1<<5) /* Instantaneous Pace Present */ +#define FTMS_TM_AVERAGE_PACE_PRESENT_MASK (1<<6) /* Average Pace Present */ +#define FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK (1<<7) /* Expended Energy Present */ +#define FTMS_TM_HEART_RATE_PRESENT_MASK (1<<8) /* Heart Rate Present */ +#define FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<9) /* Metabolic Equivalent Present */ +#define FTMS_TM_ELAPSED_TIME_PRESENT_MASK (1<<10) /* Elapsed Time Present */ +#define FTMS_TM_REMAIN_TIME_PRESENT_MASK (1<<11) /* Remaining Time Present */ +#define FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK (1<<12) /* Force on Belt and Power Output Present */ +#define FTMS_TM_SET_ALL_FEATURE_SUPPORT (0x1FFE) /* Support all treadmill data features */ +#define FTMS_TM_NO_MORE_DATA_PRESENT (0xFFFE) +#endif +/** @} */ + +/** @defgroup FTMS_Step_Climber_Data_Flag_Bit_Mask FTMS Step Climber Data Flag Bit Mask + * @brief FTMS step climber data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT +#define FTMS_STEPC_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK (1<<1) /* Step per Minute present */ +#define FTMS_STEPC_AVE_STEP_RATE_PRESENT_MASK (1<<2) /* Average Step Rate Present */ +#define FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK (1<<3) /* Positive Elevation Gain Present */ +#define FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK (1<<4) /* Expended Energy Present */ +#define FTMS_STEPC_HEART_RATE_PRESENT_MASK (1<<5) /* Heart Rate Present */ +#define FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<6) /* Metabolic Equivalent Present */ +#define FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK (1<<7) /* Elapsed Time Present */ +#define FTMS_STEPC_REMAIN_TIME_PRESENT_MASK (1<<8) /* Remaining Time Present */ +#define FTMS_STEPC_SET_ALL_FEATURE_SUPPORT (0x01FE) /* Support all step climber data features */ +#define FTMS_STEPC_NO_MORE_DATA_PRESENT (0xFFFE) +#endif +/** @} */ + +/** @defgroup FTMS_Rower_Data_Flag_Bit_Mask FTMS Rower Data Flag Bit Mask + * @brief FTMS rower data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_ROWER_DATA_SUPPORT +#define FTMS_RW_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK (1<<1) /* Average Stroke Rate present */ +#define FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK (1<<2) /* Total Distance Present */ +#define FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK (1<<3) /* Instantaneous Pace Present */ +#define FTMS_RW_AVE_PACE_PRESENT_MASK (1<<4) /* Average Pace Present */ +#define FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK (1<<5) /* Instantaneous Power Present */ +#define FTMS_RW_AVE_POWER_PRESENT_MASK (1<<6) /* Average Power Present */ +#define FTMS_RW_RESISTANCE_LEVEL_MASK (1<<7) /* Resistance Level */ +#define FTMS_RW_EXPEND_ENERGY_PRESENT_MASK (1<<8) /* Expended Energy Present */ +#define FTMS_RW_HEART_RATE_PRESENT_MASK (1<<9) /* Heart Rate Present */ +#define FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<10) /* Metabolic Equivalent Present */ +#define FTMS_RW_ELAPSED_TIME_PRESENT_MASK (1<<11) /* Elapsed Time Present */ +#define FTMS_RW_REMAIN_TIME_PRESENT_MASK (1<<12) /* Remaining Time Present */ +#define FTMS_RW_SET_ALL_FEATURE_SUPPORT (0x1FFE) /* Support all rower data features */ +#define FTMS_RW_NO_MORE_DATA_PRESENT (0xFFFE) +#endif +/** @} */ + +/** @defgroup FTMS_Indoor_Bike_Data_Flag_Bit_Mask FTMS Indoor Bike Data Flag Bit Mask + * @brief FTMS indoor bike data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT +#define FTMS_IB_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_IB_AVE_SPEED_PRESENT_MASK (1<<1) /* Average Speed present */ +#define FTMS_IB_INSTANTANEOUS_CADENCE_MASK (1<<2) /* Instantaneous Cadence */ +#define FTMS_IB_AVE_CADENCE_PRESENT_MASK (1<<3) /* Average Cadence present */ +#define FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK (1<<4) /* Total Distance Present */ +#define FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK (1<<5) /* Resistance Level Present */ +#define FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK (1<<6) /* Instantaneous Power Present */ +#define FTMS_IB_AVE_POWER_PRESENT_MASK (1<<7) /* Average Power Present */ +#define FTMS_IB_EXPEND_ENERGY_PRESENT_MASK (1<<8) /* Expended Energy Present */ +#define FTMS_IB_HEART_RATE_PRESENT_MASK (1<<9) /* Heart Rate Present */ +#define FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<10) /* Metabolic Equivalent Present */ +#define FTMS_IB_ELAPSED_TIME_PRESENT_MASK (1<<11) /* Elapsed Time Present */ +#define FTMS_IB_REMAIN_TIME_PRESENT_MASK (1<<12) /* Remaining Time Present */ +#define FTMS_IB_SET_ALL_FEATURE_SUPPORT (0x1FFE) /* Support all indoor bike data features */ +#define FTMS_IB_NO_MORE_DATA_PRESENT (0xFFFE) +#endif +/** @} */ + +/** @defgroup FTMS_Cross_Trainer_Data_Flag_Bit_Mask FTMS Cross Trainer Data Flag Bit Mask + * @brief FTMS cross trainer data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT +#define FTMS_CT_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_CT_AVE_SPEED_PRESENT_MASK (1<<1) /* Average Speed present */ +#define FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK (1<<2) /* Total Distance Present */ +#define FTMS_CT_STEP_COUNT_PRESENT_MASK (1<<3) /* Step Count Present */ +#define FTMS_CT_STRIDE_COUNT_PRESENT_MASK (1<<4) /* Stride Count Present */ +#define FTMS_CT_ELEVATION_GAIN_PRESENT_MASK (1<<5) /* Elevation Gain Present */ +#define FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK (1<<6) /* Inclination and Ramp Angle Setting Present */ +#define FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK (1<<7) /* Resistance Level Present */ +#define FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK (1<<8) /* Instantaneous Power Present */ +#define FTMS_CT_AVE_POWER_PRESENT_MASK (1<<9) /* Average Power Present */ +#define FTMS_CT_EXPEND_ENERGY_PRESENT_MASK (1<<10) /* Expended Energy Present */ +#define FTMS_CT_HEART_RATE_PRESENT_MASK (1<<11) /* Heart Rate Present */ +#define FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<12) /* Metabolic Equivalent Present */ +#define FTMS_CT_ELAPSED_TIME_PRESENT_MASK (1<<13) /* Elapsed Time Present */ +#define FTMS_CT_REMAIN_TIME_PRESENT_MASK (1<<14) /* Remaining Time Present */ +#define FTMS_CT_MOVEMENT_DIRECTION_MASK (1<<15) /* Movement Direction, 0 is Forward, 1 is Backward */ +#define FTMS_CT_SET_ALL_FEATURE_SUPPORT (0x00FFFE) /* Support all cross trainer data features */ +#define FTMS_CT_NO_MORE_DATA_PRESENT (0xFFFFFE) +#endif +/** @} */ + +/** @defgroup FTMS_Stair_Climber_Data_Flag_Bit_Mask FTMS Stair Climber Data Flag Bit Mask + * @brief FTMS stair climber data 'Flags' bit mask. + * @{ + */ +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT +#define FTMS_STAIRC_MORE_DATA_MASK (1) /* More Data */ +#define FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK (1<<1) /* Step per Minute present */ +#define FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK (1<<2) /* Average Step Rate Present */ +#define FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK (1<<3) /* Positive Elevation Gain Present */ +#define FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK (1<<4) /* Stride Count Present */ +#define FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK (1<<5) /* Expended Energy Present */ +#define FTMS_STAIRC_HEART_RATE_PRESENT_MASK (1<<6) /* Heart Rate Present */ +#define FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK (1<<7) /* Metabolic Equivalent Present */ +#define FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK (1<<8) /* Elapsed Time Present */ +#define FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK (1<<9) /* Remaining Time Present */ +#define FTMS_STAIRC_SET_ALL_FEATURE_SUPPORT (0x03FE) /* Support all indoor bike data features */ +#define FTMS_STAIRC_NO_MORE_DATA_PRESENT (0xFFFE) +#endif +/** @} */ + +/** @} End of FTMS_Common_Exported_Macros */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FTMS_Exported_Types FTMS Exported Types + * @brief + * @{ + */ + +/** +* @brief Fitness Machine Service parameter type +*/ + +typedef enum +{ + FTMS_CTRL_RESERVED = 0x00, + FTMS_CTRL_STOP, /* Control point write to initiate stop procedure */ + FTMS_CTRL_PAUSE /* Control point write to initiate pause procedure */ +} T_FTMS_CTRL_INFO; + +typedef struct +{ + uint16_t fat_burn_zone_time; /* Targeted time in fat burn zone */ + uint16_t fitness_zones_time; /* Targeted time in fitness zone */ +} T_FTMS_TWO_ZONES_HR_TIME; + +typedef struct +{ + uint16_t light_zone_time; /* Targeted time in light zone */ + uint16_t moderate_zone_time; /* Targeted time in moderate zone */ + uint16_t hard_zone_time; /* Targeted time in hard zone */ +} T_FTMS_THREE_ZONES_HR_TIME; + +typedef struct +{ + uint16_t very_light_zone_time; /* Targeted time in very light zone */ + uint16_t light_zone_time; /* Targeted time in light zone */ + uint16_t moderate_zone_time; /* Targeted time in moderate zone */ + uint16_t hard_zone_time; /* Targeted time in hard zone */ + uint16_t maximum_zone_time; /* Targeted time in maximum zone */ +} T_FTMS_FIVE_ZONES_HR_TIME; + +typedef struct +{ + int16_t wind_speed; /* Wind speed: Meters Per Second (mps) with a resolution of 0.001 */ + int16_t grade; /* Grade: Percentage with a resolution of 0.01 */ + uint8_t rolling_resistance_coefficient; /* Crr(Coefficient of rolling resistance): Unitless with a resolution of 0.001 */ + uint8_t wind_resistance_coefficient; /* Cw(Wind resistance coefficient): Kilogram per Meter(Kg/m) with a resolution of 0.01 */ +} T_FTMS_INDOOR_BIKE_SIMULATION_PARAM; + +typedef enum +{ + FTMS_SD_CTRL_RESERVED = 0x00, + FTMS_SD_CTRL_START, /* Write to start spin down control procedure */ + FTMS_SD_CTRL_IGNORE /* Write to ignore spin down control procedure */ +} T_FTMS_SPIN_DOWN_CTRL_PARAM; + +typedef struct +{ + uint16_t target_speed_low; /* km/h with a resolution of 0.01 km/h */ + uint16_t target_speed_high; /* km/h with a resolution of 0.01 km/h */ +} T_FTMS_SPIN_DOWN_RESP_PARAM; + +typedef enum +{ + FTMS_SD_STATUS_RESERVED = 0x00, /* Reserved for Future Use */ + FTMS_SD_REQ, /* Spin Down Requested */ + FTMS_SD_SUCCESS, /* Success */ + FTMS_SD_ERROR, /* Error */ + FTMS_SD_STOP_PEDAL /* Stop Pedaling */ +} T_FTMS_SPIN_DOWN_STATUS_VALUE; + +typedef struct +{ + uint32_t features_field; /* Fitness Machine Features */ + uint32_t target_setting_field; /* Target Setting Features */ +} T_FTMS_FEATURE; + +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT +typedef struct +{ + uint8_t flag; /* Training Status Flags */ + uint8_t train_status; /* Training Status */ + uint8_t *train_status_string; /* Training Status String (if present) */ +} T_FTMS_TRAIN_STATUS; +#endif + +#if FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT +typedef struct +{ + uint16_t min_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t max_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t min_speed_increment; /* Kilometer per hour with a resolution of 0.01 */ +} T_FTMS_SUPPORT_SPEED_RANGE; +#endif + +#if FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT +typedef struct +{ + int16_t min_inclination; /* Percent with a resolution of 0.1 */ + int16_t max_inclination; /* Percent with a resolution of 0.1 */ + uint16_t min_inclination_increment; /* Percent with a resolution of 0.1 */ +} T_FTMS_SUPPORT_INCLINATION_RANGE; +#endif + +#if FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT +typedef struct +{ + int16_t min_resistance_level; /* Unitless with a resolution of 0.1 */ + int16_t max_resistance_level; /* Unitless with a resolution of 0.1 */ + uint16_t min_resistance_level_increment; /* Unitless with a resolution of 0.1 */ +} T_FTMS_SUPPORT_RESISTANCE_LEVEL_RANGE; +#endif + +#if FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT +typedef struct +{ + int16_t min_power; /* Watt with a resolution of 1 */ + int16_t max_power; /* Watt with a resolution of 1 */ + uint16_t min_power_increment; /* Watt with a resolution of 1 */ +} T_FTMS_SUPPORT_POWER_RANGE; +#endif + +#if FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT +typedef struct +{ + uint8_t min_heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t max_heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t min_hr_increment; /* Beats per minute with a resolution of 1 */ +} T_FTMS_SUPPORT_HR_RANGE; +#endif + +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT +typedef struct +{ + uint16_t instantaneous_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t average_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint32_t total_distance; /* Meters with a resolution of 1 */ + int16_t inclination; /* Percent with a resolution of 0.1 */ + int16_t ramp_angle_set; /* Degree with a resolution of 0.1 */ + uint16_t positive_elevation_gain; /* Meters with a resolution of 0.1 */ + uint16_t negative_elevation_gain; /* Meters with a resolution of 0.1 */ + uint8_t instantaneous_pace; /* Kilometer per hour with a resolution of 0.01 */ + uint8_t average_pace; /* Kilometer per minute with a resolution of 0.1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint8_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ + int16_t force_on_belt; /* Newton with a resolution of 1 */ + int16_t power_output; /* Watts with a resolution of 1 */ +} T_FTMS_TREADMILL_DATA; +#endif + +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT +typedef struct +{ + uint16_t floor; /* Unitless with a resolution of 1 */ + uint16_t step_count; /* Unitless with a resolution of 1 */ + uint16_t step_per_minute; /* Step/minute with a resolution of 1 */ + uint16_t average_step_rate; /* Step/minute with a resolution of 1 */ + uint16_t positive_elevation_gain; /* Meters with a resolution of 1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint8_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ +} T_FTMS_STEP_CLIMBER_DATA; +#endif + +#if FTMS_CHAR_ROWER_DATA_SUPPORT +typedef struct +{ + uint8_t stroke_rate; /* stroke/minute with a resolution of 0.5 */ + uint16_t stroke_count; /* Unitless with a resolution of 1 */ + uint8_t average_stroke_rate; /* 1/minute with a resolution of 0.5 */ + uint32_t total_distance; /* Meters with a resolution of 1 (uint24) */ + uint16_t instantaneous_pace; /* Second with a resolution of 1 */ + uint16_t average_pace; /* Second with a resolution of 1 */ + int16_t instantaneous_power; /* Watts with a resolution of 1 */ + int16_t average_power; /* Watts with a resolution of 1 */ + int16_t resistance_level; /* Unitless with a resolution of 1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint8_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ +} T_FTMS_ROWER_DATA; +#endif + +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT +typedef struct +{ + uint16_t instantaneous_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t average_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t instantaneous_cadence; /* 1/minute with a resolution of 0.5 */ + uint16_t average_cadence; /* 1/minute with a resolution of 0.5 */ + uint32_t total_distance; /* Meters with a resolution of 1 (uint24) */ + int16_t resistance_level; /* Unitless with a resolution of 1 */ + int16_t instantaneous_power; /* Watts with a resolution of 1 */ + int16_t average_power; /* Watts with a resolution of 1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint8_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ +} T_FTMS_INDOOR_BIKE_DATA; +#endif + +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT +typedef struct +{ + uint16_t instantaneous_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint16_t average_speed; /* Kilometer per hour with a resolution of 0.01 */ + uint32_t total_distance; /* Meters with a resolution of 1 (uint24) */ + uint16_t step_per_minute; /* Step/minute with a resolution of 1 */ + uint16_t average_step_rate; /* Step/minute with a resolution of 1 */ + uint16_t stride_count; /* Unitless with a resolution of 0.1 */ + uint16_t positive_elevation_gain; /* Meters with a resolution of 1 */ + uint16_t negative_elevation_gain; /* Meters with a resolution of 1 */ + int16_t inclination; /* Percent with a resolution of 0.1 */ + int16_t ramp_angle_set; /* Degree with a resolution of 0.1 */ + int16_t resistance_level; /* Unitless with a resolution of 0.1 */ + int16_t instantaneous_power; /* Watts with a resolution of 1 */ + int16_t average_power; /* Watts with a resolution of 1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint8_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ +} T_FTMS_CROSS_TRAINER_DATA; +#endif + +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT +typedef struct +{ + uint16_t floors; /* Unitless with a resolution of 1 */ + uint16_t step_per_minute; /* Step/minute with a resolution of 1 */ + uint16_t average_step_rate; /* Step/minute with a resolution of 1 */ + uint16_t positive_elevation_gain; /* Meters with a resolution of 1 */ + uint16_t stride_count; /* Unitless with a resolution of 1 */ + uint16_t total_energy; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_hour; /* Kilo Calorie with a resolution of 1 */ + uint16_t energy_per_minute; /* Kilo Calorie with a resolution of 1 */ + uint8_t heart_rate; /* Beats per minute with a resolution of 1 */ + uint8_t metabolic_equivalent; /* Metabolic Equivalent with a resolution of 0.1 */ + uint16_t elapsed_time; /* Second with a resolution of 1 */ + uint16_t remain_time; /* Second with a resolution of 1 */ +} T_FTMS_STAIR_CLIMBER_DATA; +#endif + +/** End of UDS_Exported_Types +* @} +*/ + +/** @} End of FTMS_DEFINE */ + +#endif /* _FTMS_DEFINE_H_ */ diff --git a/inc/bluetooth/profile/server/ghss_gatt_srv.h b/inc/bluetooth/profile/server/ghss_gatt_srv.h new file mode 100644 index 0000000..7fa3ac1 --- /dev/null +++ b/inc/bluetooth/profile/server/ghss_gatt_srv.h @@ -0,0 +1,602 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ghss_gatt_svc.h + * @brief Head file for using Generic Health Sensor Service. + * @details GHSS data structs and external functions declaration developed based on bt_gatt_svc.h. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GHSS_GATT_SVC_H_ +#define _GHSS_GATT_SVC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "os_mem.h" +#include "os_queue.h" +#include "bt_gatt_svc.h" + + +/** @defgroup GHSS_GATT_SVC GHSS Device Information GATT Service + * @brief Generic Health Sensor Service + * @details + + The Generic Health Sensor (GHS) specifications define a protocol by which personal health device data can be exchanged over + a Bluetooth connection. + + GHSS communicates the semantic content contained in the Abstract Content Information Model (ACOM) defined in IEEE 11073-10206 + using the Generic Attribute Protocol (GATT). + + The default supported feature provided by GHSS is the notify and indicate property of the Live Health Observations characteristic, + the notify and indicate property of the Stored Health Observations characteristic, the write and indicate property of the RACP + characteristic, and the write and indicate property of the GHS Control Point characteristic. + + The specific configuration process can be achieved by modifying Macro @ref GHSS_SVC_FEATURE_SUPPORT. + + * Example usage + * \code{.c} + + #define GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT 1 + + * \endcode + + Applications shall register the Generic Health Sensor Service during initialization through the @ref ghss_reg_srv function. + + Applications can format GHSS Health Observation Body value length through the @ref ghss_format_health_obs_body_length function. + + Applications can format GHSS Health Observations value through the @ref ghss_format_health_obs_sending_value function. + + Applications can format GHSS Health Observations segments through the @ref ghss_format_health_obs_segment function. + + Applications can report Health Observations data with a notification or indication through the @ref ghss_send_health_obs_report function. + + Applications can report Control Point data with an indication through the @ref ghss_send_cp_report function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GHSS_GATT_Exported_Macros GHSS GATT Exported Macros + * @brief + * @{ + */ +/** @defgroup GHSS_SVC_FEATURE_SUPPORT + * @brief GHSS server feature support + * @{ + */ +/** @details + Set GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT to 1 to support Live Health Observations + characteristic with notify. + Set GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT to 1 to support Live Health Observations + characteristic with indicate. + Mandatory to support indications or notifications. Supporting both is also permitted. +*/ +#define GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT 1 +#define GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT 1 + +/** @details + Set GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT to 1 to support Stored Health Observations + characteristic with notify. + Set GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_NOTIFY_INDICATE_SUPPORT to 1 to support Stored Health + Observations characteristic with indicate. + Mandatory to support indications or notifications. Supporting both is also permitted. +*/ +#define GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT 1 +#define GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT 1 + +/** @} End of GHSS_SVC_FEATURE_SUPPORT */ + +/** @defgroup GHSS_SVC_UUID + * @brief GHSS service UUID + * @{ + */ +#define GATT_UUID_GENERIC_HEALTH_SENSOR 0x1840 + +#define GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS 0x2B8B +#define GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS 0x2BDD +#define GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT 0x2A52 +#define GATT_UUID_CHAR_GHS_CONTROL_POINT 0x2BF4 +/** @} End of GHSS_SVC_UUID */ + +/** @defgroup GHSS_SVC_ERR + * @brief GHSS service error code + * @{ + */ +#define ATT_ERR_GHS_COMMAND_NOT_SUPPORTED (ATT_ERR | 0x81) +/** @} End of GHSS_SVC_ERR */ + +/** @defgroup GHSS_SVC_CB_MSG + * @brief GHSS server callback messages + * @{ + */ +#define GATT_MSG_GHSS_SERVER_WRITE_IND 0x01 +#define GATT_MSG_GHSS_SERVER_CCCD_UPDATE 0x02 +/** @} End of GHSS_SVC_CB_MSG */ + +/** @defgroup GHSS_SVC_DEF + * @brief GHSS server define numerical value + * @{ + */ +#define GHSS_MAX_ROLLING_SEGMENT_COUNTER 63 /** The Rolling Segment Counter is incremented per segment during a connection. If the Rolling Segment Counter is equal to a value of 63, then the counter rolls over to 0 when it is next incremented. */ +/** @} End of GHSS_SVC_DEF */ + +/** End of GHSS_GATT_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GHSS_GATT_Exported_Types GHSS GATT Exported Types + * @brief + * @{ + */ +/** + * @brief P_FUN_GHSS_SERVER_APP_CB GHSS Server Callback Function Point Definition Function + * pointer used in GHSS server module, to send events to specific server module. + * The events @ref GHSS_SVC_CB_MSG. + */ +typedef T_APP_RESULT(*P_FUN_GHSS_SERVER_APP_CB)(uint8_t conn_id, uint8_t type, void *p_data); + +typedef enum +{ + GHSS_COMPONENT_TYPE_HOBV_COMPOUND_OBS, + GHSS_COMPONENT_TYPE_HOBV_OBS_BUNDLE, +} T_GHSS_COMPONENT_TYPE; + +/** @brief GHSS Record Access Control Point OpCodes. */ +typedef enum +{ + GHSS_RACP_OPCODE_RESERVED = 0, + GHSS_RACP_OPCODE_DELETE_RECS = 0x02, + GHSS_RACP_OPCODE_ABORT_OPERATION = 0x03, + GHSS_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04, + GHSS_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05, + GHSS_RACP_OPCODE_RESP_CODE = 0x06, + GHSS_RACP_OPCODE_COMB_REPORT_RECS = 0x07, + GHSS_RACP_OPCODE_COMB_REPORT_RESP = 0x08 +} T_GHSS_RACP_OPCODE; + +/** @brief Check GHSS Record Access Control Point operation is available or not. */ +#define GHSS_RACP_OPERATION_ACTIVE(x) \ + ((x >= GHSS_RACP_OPCODE_DELETE_RECS) && \ + (x <= GHSS_RACP_OPCODE_COMB_REPORT_RESP)) + +/** @brief GHSS Record Access Control Point Response Codes. */ +typedef enum +{ + GHSS_RACP_RESP_RESERVED = 0x00, + GHSS_RACP_RESP_SUCCESS = 0x01, + GHSS_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02, + GHSS_RACP_RESP_INVALID_OPERATOR = 0x03, + GHSS_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04, + GHSS_RACP_RESP_INVALID_OPERAND = 0x05, + GHSS_RACP_RESP_NO_RECS_FOUND = 0x06, + GHSS_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07, + GHSS_RACP_RESP_PROC_NOT_COMPLETED = 0x08, + GHSS_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09, + GHSS_RACP_RESP_SERVER_BUSY = 0x0A +} T_GHSS_RACP_RESP_CODES; + +/** @brief GHSS Record Access Control Point Operator. */ +typedef enum +{ + GHSS_RACP_OPERATOR_NULL = 0x00, + GHSS_RACP_OPERATOR_ALL_RECS = 0x01, + GHSS_RACP_OPERATOR_LT_EQ = 0x02, + GHSS_RACP_OPERATOR_GT_EQ = 0x03, + GHSS_RACP_OPERATOR_RANGE = 0x04, + GHSS_RACP_OPERATOR_FIRST = 0x05, + GHSS_RACP_OPERATOR_LAST = 0x06 +} T_GHSS_RACP_OPERATOR; + +/** @brief GHSS Record Access Control Point Operand Filter Type. */ +typedef enum +{ + GHSS_RACP_OPERAND_RFU = 0x00, + GHSS_RACP_OPERAND_REC_NUM = 0x01, + GHSS_RACP_OPERAND_TIME = 0x02, +} T_GHSS_RACP_OPERAND_FILTER_TYPE; + +/** @brief GHSS Record Access Control Point. */ +typedef struct +{ + T_GHSS_RACP_OPCODE opcode; + T_GHSS_RACP_OPERATOR operator; + uint8_t operand[18]; +} T_GHSS_RACP; + +/** @brief GHSS GHS Control Point OpCodes. */ +typedef enum +{ + GHSS_GHS_CP_OPCODE_RFU = 0, + GHSS_GHS_CP_OPCODE_START_SEND_LIVE_OBS = 0x01, + GHSS_GHS_CP_OPCODE_STOP_SEND_LIVE_OBS = 0x02, + GHSS_GHS_CP_OPCODE_SUCCESS = 0x80, +} T_GHSS_GHS_CP_OPCODE; + +typedef struct +{ + uint8_t first_segment: 1; + uint8_t last_segment: 1; + uint8_t rolling_segment_counter: 6; +} T_GHSS_HEALTH_OBS_SEG_HEADER; + +typedef enum +{ + GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION = 1, + GHSS_HOB_CLASS_TYPE_SIMPLE_DISCRETE_OBSERVATION, + GHSS_HOB_CLASS_TYPE_STRING_OBSERVATION, + GHSS_HOB_CLASS_TYPE_SAMPLE_ARRAY_OBSERVATION, + GHSS_HOB_CLASS_TYPE_COMPOUND_DISCRETE_EVENT_OBSERVATION, + GHSS_HOB_CLASS_TYPE_COMPOUND_STATE_EVENT_OBSERVATION, + GHSS_HOB_CLASS_TYPE_COMPOUND_OBSERVATION, + GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION, + GHSS_HOB_CLASS_TYPE_OBSERVATION_BUNDLE = 255, +} T_GHSS_HOB_CLASS_TYPE; + +typedef struct +{ + uint16_t observation_type_present: 1; + uint16_t time_stamp_present: 1; + uint16_t measurement_duration_present: 1; + uint16_t measurement_status_present: 1; + uint16_t observation_id_present: 1; + uint16_t patient_present: 1; + uint16_t supplemental_information_present: 1; + uint16_t derived_from_present: 1; + uint16_t is_member_of_present: 1; + uint16_t tlvs_present: 1; + uint16_t rfu: 6; +} T_GHSS_HOB_FLAGS; + +typedef struct +{ + uint8_t flags; + uint8_t time_value[6]; + uint8_t time_sync_source_type; + uint8_t tz_dst_offset; +} T_GHSS_HOB_TIME_STAMP; + +typedef struct +{ + uint16_t invalid: 1; + uint16_t questionable: 1; + uint16_t not_available: 1; + uint16_t calibrating: 1; + uint16_t test_data: 1; + uint16_t early_estimate: 1; + uint16_t manually_entered: 1; + uint16_t setting: 1; + uint16_t rfu: 6; + uint16_t threshold_error: 1; + uint16_t thresholding_disabled: 1; +} T_GHSS_HOB_MEAS_STATUS; + +typedef struct +{ + uint8_t count; + uint32_t *p_codes; +} T_GHSS_HOB_SUPPL_INFO; + +typedef struct +{ + uint8_t count; + uint32_t *p_obs_ids; +} T_GHSS_HOB_DERIVED_FROM; + +typedef struct +{ + uint8_t count; + uint32_t *p_mem_ids; +} T_GHSS_HOB_IS_MEM_OF; + +typedef struct +{ + uint32_t type; + uint16_t length; + uint8_t format_type; + void *p_encoded_value; +} T_GHSS_HOB_TLVS_VALUE; + +typedef struct +{ + uint8_t num_of_tlv_attr; + T_GHSS_HOB_TLVS_VALUE *p_tlvs_value; +} T_GHSS_HOB_TLVS; + +typedef struct +{ + uint16_t unit_code; + uint32_t value; //Change float to uint32_t for sending +} T_GHSS_HOBV_NUMERIC_OBS; + +typedef struct +{ + uint32_t value; +} T_GHSS_HOBV_SIMPLE_DISCRETE_OBS; + +typedef struct +{ + uint16_t length; + char *p_value; +} T_GHSS_HOBV_STRING_OBS; + +typedef struct +{ + uint16_t unit_code; + uint32_t scale_factor; //Change float to uint32_t for sending + uint32_t offset; //Change float to uint32_t for sending + uint32_t sample_period; //Change float to uint32_t for sending + uint8_t number_of_samples_per_period; + uint8_t bytes_per_period; + uint32_t number_of_samples; + void *p_sample; +} T_GHSS_HOBV_SAMPLE_ARRAY_OBS; + +typedef struct +{ + uint8_t number_of_components; + uint32_t *p_value; +} T_GHSS_HOBV_COMPOUND_DISCRETE_EVENT_OBS; + +typedef struct +{ + uint8_t size; + uint8_t *p_mask_bits; + uint8_t *p_state_event_mask_bits; + uint8_t *p_value; +} T_GHSS_HOBV_COMPOUND_STATE_EVENT_OBS; + +typedef struct +{ + uint32_t component_type; + T_GHSS_HOB_CLASS_TYPE component_value_type; //Only 1 - 6 + void *p_value; //Structure depends on component_value_type +} T_GHSS_HOBV_COMPOUND_OBS_COMPONENT; + +typedef struct +{ + uint8_t number_of_components; + T_GHSS_HOBV_COMPOUND_OBS_COMPONENT *p_component_value; +} T_GHSS_HOBV_COMPOUND_OBS; + +typedef struct +{ + uint8_t number_of_obs; + void *p_obs_bdl_value; // Structure @ref T_GHSS_HEALTH_OBS_BODY +} T_GHSS_HOBV_OBS_BUNDLE; + +/** @brief Structure depends on the Observation Class Type. */ +typedef union +{ + T_GHSS_HOBV_NUMERIC_OBS numeric_obs; + T_GHSS_HOBV_SIMPLE_DISCRETE_OBS simple_discrete_obs; + T_GHSS_HOBV_STRING_OBS string_obs; + T_GHSS_HOBV_SAMPLE_ARRAY_OBS sample_array_obs; + T_GHSS_HOBV_COMPOUND_DISCRETE_EVENT_OBS compound_discrete_event_obs; + T_GHSS_HOBV_COMPOUND_STATE_EVENT_OBS compound_state_event_obs; + T_GHSS_HOBV_COMPOUND_OBS compound_obs; + T_GHSS_HOB_TLVS tlv_encoded_obs; + T_GHSS_HOBV_OBS_BUNDLE obs_bundle; +} T_GHSS_HOB_VALUE; + +/** @brief Health Observation Body. */ +typedef struct +{ + T_GHSS_HOB_CLASS_TYPE obs_class_type; + T_GHSS_HOB_FLAGS flags; + uint32_t obs_type; + T_GHSS_HOB_TIME_STAMP time_stamp; + uint32_t meas_duration; //Change float to uint32_t for sending + T_GHSS_HOB_MEAS_STATUS meas_status; + uint32_t obs_id; + uint8_t patient; + T_GHSS_HOB_SUPPL_INFO suppl_info; + T_GHSS_HOB_DERIVED_FROM derived_from; + T_GHSS_HOB_IS_MEM_OF is_mem_of; + T_GHSS_HOB_TLVS tlvs; + T_GHSS_HOB_VALUE obs_value; +} T_GHSS_HEALTH_OBS_BODY; + +/** @brief Health Observation. */ +typedef struct +{ + T_GHSS_HEALTH_OBS_SEG_HEADER seg_header; + T_GHSS_HEALTH_OBS_BODY obs_body; +} T_GHSS_HEALTH_OBS; + +typedef enum +{ + GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS, + GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS, +} T_GHSS_OBS_REPORT_TYPE; + +typedef struct +{ + uint8_t obs_segment_len; + uint8_t *p_obs_segment; +} T_GHSS_REPORT_OBS_SEGMENT; + +typedef struct +{ + T_GHSS_OBS_REPORT_TYPE report_type; + bool is_notify; + T_GHSS_REPORT_OBS_SEGMENT obs_segment; +} T_GHSS_CHAR_OBS_REPORT; + +typedef enum +{ + GHSS_CP_REPORT_TYPE_RACP, + GHSS_CP_REPORT_TYPE_GHS_CP, +} T_GHSS_CP_REPORT_TYPE; + +typedef struct +{ + uint8_t racp_len; + T_GHSS_RACP *p_racp; +} T_GHSS_REPORT_RACP; + +typedef struct +{ + T_GHSS_CP_REPORT_TYPE report_type; + union + { + T_GHSS_REPORT_RACP report_racp; + T_GHSS_GHS_CP_OPCODE *p_ghs_cp; + } value; +} T_GHSS_CHAR_CP_REPORT; + +/** @brief GHSS server write data indication + * The message data for GATT_MSG_GHSS_SERVER_WRITE_IND. +*/ +typedef struct +{ + T_SERVER_ID service_id; + uint16_t char_uuid; + T_WRITE_TYPE write_type; + union + { + T_GHSS_RACP ghss_racp; + T_GHSS_GHS_CP_OPCODE ghss_ghs_cp; + } data; +} T_GHSS_SERVER_WRITE_IND; + +/** @brief GHSS server cccd data update info + * The message data for GATT_MSG_GHSS_SERVER_CCCD_UPDATE. +*/ +typedef struct +{ + T_SERVER_ID service_id; + uint16_t char_uuid; + uint16_t cccd_cfg; +} T_GHSS_SERVER_CCCD_UPDATE; + +/** End of GHSS_GATT_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GHSS_GATT_Exported_Functions GHSS GATT Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add Generic Health Sensor Service to the Host database. + * + * + * @param[in] app_cb Callback when service attribute was read, write or cccd update. + * @return Service id generated by the Host: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by Host. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(service_num); + ghss_id = ghss_reg_srv(app_ghss_handle_server_cb); + } + * \endcode + */ +T_SERVER_ID ghss_reg_srv(P_FUN_GHSS_SERVER_APP_CB app_cb); + +/** + * @brief Format GHSS Health Observation Body value length. + * + * + * @param[in] p_value GHSS Health Observation Body value. + * + * @return Total length of Health Observation Body. + */ +uint16_t ghss_format_health_obs_body_length(T_GHSS_HEALTH_OBS_BODY *p_value); + +/** + * @brief Format GHSS Health Observations value. + * + * @note When all segments of the Health Observations value have been sent complete, + * APP shall free the value memory. + * + * @param[in] type Report type @ref T_GHSS_OBS_REPORT_TYPE. + * @param[in] idx Report idx of Stored Health Observation Body. \n + * If type equals @ref GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS, this parameter is not effective. + * @param[in] p_value GHSS Health Observation Body value. + * @param[in,out] pp_temp_value Pointer to pointer of value needs to be sent. + * + * @return Total length of Health Observations value. + */ +uint16_t ghss_format_health_obs_sending_value(T_GHSS_OBS_REPORT_TYPE type, uint32_t idx, + T_GHSS_HEALTH_OBS_BODY *p_value, + uint8_t **pp_temp_value); + +/** + * @brief Format GHSS Health Observation segments. + * + * @note When segment has been sent, APP shall free the segment memory. + * + * @param[in] seg_count Current count of Health Observation segment needs to be sent. + * @param[in] seg_num The number of all segments need to be sent. + * @param[in] report_mtu Report MTU size. + * @param[in] rolling_seg_count Rolling Segment Counter. + * @param[in] value_len Total length of Health Observation value. + * @param[in] p_value Pointer to value needs to be sent. + * @param[in,out] pp_seg Pointer to pointer of segment needs to be sent. + * + * @return Length of segment needs to be sent. + */ +uint16_t ghss_format_health_obs_segment(uint8_t seg_count, uint8_t seg_num, uint16_t report_mtu, + uint8_t rolling_seg_count, uint16_t value_len, + uint8_t *p_value, uint8_t **pp_seg); + +/** + * @brief Report Health Observations data with a notification or indication. + * + * + * @param[in] conn_id Connection ID. + * @param[in] service_id Service ID. + * @param[in] report_data Report data @ref T_GHSS_CHAR_OBS_REPORT. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool ghss_send_health_obs_report(uint8_t conn_id, uint8_t service_id, + T_GHSS_CHAR_OBS_REPORT report_data); + +/** + * @brief Report Control Point data with an indication. + * + * + * @param[in] conn_id Connection ID. + * @param[in] service_id Service ID. + * @param[in] report_data Report data @ref T_GHSS_CHAR_CP_REPORT. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool ghss_send_cp_report(uint8_t conn_id, uint8_t service_id, T_GHSS_CHAR_CP_REPORT report_data); + +/** @} End of GHSS_GATT_Exported_Functions */ + +/** @} End of GHSS_GATT_SVC */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GHSS_GATT_SVC_H_ */ diff --git a/inc/bluetooth/profile/server/gls.h b/inc/bluetooth/profile/server/gls.h new file mode 100644 index 0000000..bc8a965 --- /dev/null +++ b/inc/bluetooth/profile/server/gls.h @@ -0,0 +1,638 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gls.h + * @brief Head file for using glucose service. + * @details Glusose data types and external functions declaration. + * @author bill + * @date 2017-6-8 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GLS_H +#define _GLS_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "gls_config.h" + + +/** @defgroup GLS Glucose Service + * @brief Glucose service + * @details + + The Glucose Service exposes glucose and other data related to a personal glucose sensor for + consumer healthcare applications and is not designed for clinical use. + Glucose Measurement, Glucose Measurement - Client Characteristic Configuration descriptor, + Glucose Feature, Record Access Control Point, Record Access Control Point - Client Characteristic Configuration descriptor + are mandatory exposed in the Glucose Service. + Glucose Measurement Context is optional, and if the Glucose Measurement Context characteristic is supported, + Glucose Measurement Context - Client Characteristic Configuration descriptor shall be mandatory. + + The Glucose Measurement characteristic shall be used to send glucose measurements. + The Glucose Measurement Context characteristic may be used to send additional contextual information relative to + a Glucose Measurement characteristic. + The Glucose Feature characteristic shall be used to describe the supported features of the Server. + For this service to operate, profiles or other applications utilizing this service will need to ensure that + the Client configures the Record Access Control Point (RACP) characteristic for indications. + The Client must perform a write to the Record Access Control Point to execute a desired procedure at the Server. + + Application shall register glucose service when initialization through @ref gls_add_service function. + + Application can set the glucose service parameters through @ref gls_set_parameter function. + + Application can send the glucose measurements through @ref gls_glc_measurement_notify function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ + +/** @defgroup GLS_Exported_Macros GLS Exported Macros + * @brief + * @{ + */ + +/** @defgroup GLS_Feature GLS Feature + * @brief glucose feature bits. + * @{ + */ +#define GLC_FEATURES_LOW_BATTERY 0x0001 +#define GLC_FEATURES_SENSOR_MALFUNCTION 0x0002 +#define GLC_FEATURES_SENSOR_SAMPLE_SIZE 0x0004 +#define GLC_FEATURES_SENSOR_STRIP_INS_ERROR 0x0008 +#define GLC_FEATURES_SENSOR_STRIP_TYPE_ERROR 0x0010 +#define GLC_FEATURES_SENSOR_RESULT_HIGH_LOW 0x0020 +#define GLC_FEATURES_SENSOR_TEMP_HIGH_LOW 0x0040 +#define GLC_FEATURES_SENSOR_READ_INTERRUPT 0x0080 +#define GLC_FEATURES_GENERAL_DEVICE_FAULT 0x0100 +#define GLC_FEATURES_TIME_FAULT 0x0200 +#define GLC_FEATURES_MULTIPLE_BOND 0x0400 + +/** GLC features supported: */ +#define GLC_FEATURES (GLC_FEATURES_LOW_BATTERY | \ + GLC_FEATURES_SENSOR_STRIP_INS_ERROR) +/** @} */ + +/** +* @brief Gulcose service parameter type +*/ +typedef enum +{ + /** glucose measurement parameters */ + GLS_PARAM_GLC_MS_FLAG = 0x01, + GLS_PARAM_GLC_MS_BASE_TIME, + GLS_PARAM_GLC_MS_TIME_OFFSET, + GLS_PARAM_GLC_MS_CONCENTRATION, + GLS_PARAM_GLC_MS_CONCENTRATION_UNITS, + GLS_PARAM_GLC_MS_TYPE_SAMPLE_LOCATION, + GLS_PARAM_GLC_MS_SENSOR_STATUS_ANNUNCIATION, + + /** glucose measurement context parameters */ + GLS_PARAM_GLC_MS_CT_FLAG, + GLS_PARAM_GLC_MS_CT_CARBOHYDRATE_ID, + GLS_PARAM_GLC_MS_CT_CARBOHYDRATE, + GLS_PARAM_GLC_MS_CT_MEAL, + GLS_PARAM_GLC_MS_CT_TESTER_HEALTH, + GLS_PARAM_GLC_MS_CT_EXERCISE_DURATION, + GLS_PARAM_GLC_MS_CT_EXERCISE_INTENSITY, + GLS_PARAM_GLC_MS_CT_MEDICATION_ID, + GLS_PARAM_GLC_MS_CT_MEDICATION, + GLS_PARAM_GLC_MS_CT_MEDICATION_UNITS, + GLS_PARAM_GLC_MS_CT_HbA1c, + + /** Parameters that can be get by application */ + GLS_PARAM_GLC_FEATURES, + GLS_PARAM_CTL_PNT_PROG_CLR, + GLS_PARAM_RECORD_NUM, + GLS_PARAM_RECORD_SEQ_NUM +} T_GLS_PARAM_TYPE; + + +/** @defgroup GLS_Upstream_Message GLS Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ + +/** @defgroup GLS_Read_Info GLS Read Info + * @brief Parameter for read characteristic value. + * @{ + */ +#define GLS_EVT_READ_FEATURE 0x01 +/** @} */ + +/** @defgroup GLS_Notify_Indicate_Info GLS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define GLS_EVT_GLC_MEASUREMENT_NOTIFY_ENABLE 0x01 +#define GLS_EVT_GLC_MEASUREMENT_NOTIFY_DISABLE 0x02 +#define GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_ENABLE 0x03 +#define GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_DISABLE 0x04 +#define GLS_EVT_GLC_RACP_INDICATE_ENABLE 0x05 +#define GLS_EVT_GLC_RACP_INDICATE_DISABLE 0x06 +/** @} */ + +/** @} End of GLS_Upstream_Message */ + +/** @defgroup GLS_Control_Point GLS Control Point + * @brief glucose record access control point + * @{ + */ + +/** @brief Glucose Record Access Control Point OpCodes. */ +typedef enum +{ + GLC_RACP_OPCODE_RESERVED = 0x00, + GLC_RACP_OPCODE_REPORT_RECS = 0x01, + GLC_RACP_OPCODE_DELETE_RECS = 0x02, + GLC_RACP_OPCODE_ABORT_OPERATION = 0x03, + GLC_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04, + GLC_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05, + GLC_RACP_OPCODE_RESP_CODE = 0x06 +} T_GLC_CTRL_POINT_OPCODE; + +/** @brief Check glucose Record Access Control Point operation is available or not. */ +#define GLC_RACP_OPERATION_ACTIVE(x) \ + ((x >= GLC_RACP_OPCODE_REPORT_RECS) && \ + (x <= GLC_RACP_OPCODE_RESP_CODE)) + +/** @brief Glucose Record Access Control Point Operator. */ +typedef enum +{ + GLC_RACP_OPERATOR_NULL = 0x00, + GLC_RACP_OPERATOR_ALL_RECS = 0x01, + GLC_RACP_OPERATOR_LT_EQ = 0x02, + GLC_RACP_OPERATOR_GT_EQ = 0x03, + GLC_RACP_OPERATOR_RANGE = 0x04, + GLC_RACP_OPERATOR_FIRST = 0x05, + GLC_RACP_OPERATOR_LAST = 0x06 +} T_GLC_CTRL_POINT_OPERATOR; + +/** @brief Filter Type values. */ +typedef enum +{ + GLC_RACP_FILTER_TYPE_RESERVED = 0x00, + GLC_RACP_FILTER_TYPE_SEQ_NBR = 0x01, + GLC_RACP_FILTER_TYPE_TIME = 0x02 +} T_GLC_CTRL_POINT_FILTER_TYPE; + +/** @brief Glucose Record Access Control Point Response Codes. */ +typedef enum +{ + GLC_RACP_RESP_RESERVED = 0x00, + GLC_RACP_RESP_SUCCESS = 0x01, + GLC_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02, + GLC_RACP_RESP_INVALID_OPERATOR = 0x03, + GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04, + GLC_RACP_RESP_INVALID_OPERAND = 0x05, + GLC_RACP_RESP_NO_RECS_FOUND = 0x06, + GLC_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07, + GLC_RACP_RESP_PROC_NOT_COMPLETED = 0x08, + GLC_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09 +} T_GLC_CTRL_POINT_RESP_CODES; + +/** @brief profile specific attribute protocol application error codes */ +#define GLC_ERR_PROC_ALREADY_IN_PROGRESS 0x80 +#define GLC_ERR_CCCD_IMPROPERLY_CONFIGURED 0x81 +/** @} */ + +/** @brief concentration unit */ +#define GLC_FLAGS_UNITS_MOL_L_ON 1 +#define GLC_FLAGS_UNITS_KG_L_ON 0 + +/** @brief medication unit */ +#define GLC_FLAGS_MEDICATION_UNITS_LITERS_ON 1 +#define GLC_FLAGS_MEDICATION_UNITS_KG_ON 0 + +/** GLC sensor status annunciation bits */ +#define GLC_SS_ANNUNC_LOW_BATTERY 0x0001 + +/** special short float values */ +#define SFLOAT_VALUE_NaN 0x07ff /**< not a number */ +#define SFLOAT_VALUE_NRes 0x0800 /**< not at this resolution */ +#define SFLOAT_VALUE_PlusINFINITY 0x07fe /**< + INFINITY */ +#define SFLOAT_VALUE_MinusINFINITY 0x0802 /**< - INFINITY */ +#define SFLOAT_VALUE_RFU 0x0801 /**< reserved for future use */ + +/** @brief RACP database parameters */ +#define GLC_RACP_DATABASE_SIZE (GLC_RACP_MAX_NBR_OF_STORED_RECS + 1) +#define GLC_RACP_INIT_SEQ_NBR_DEFAULT 0 + +/** @} End of GLS_Exported_Macros */ + + + +/*============================================================================* + * Types + *============================================================================*/ + +/** @defgroup GLS_Exported_Types GLS Exported Types + * @brief + * @{ + */ + +/* Add all public types here */ + +/** GLC measurement flag bits */ +typedef struct +{ + uint8_t time_offset: 1; /**< time offset */ + uint8_t con_ts_loc: 1; /**< concentration, time/sample location */ + uint8_t con_units: 1; /**< 0: kg/L, 1: mol/L */ + uint8_t ss_annuciation: 1; /**< sensor status annunciation */ + uint8_t ctxt_info_follows: 1; /**< context information */ + uint8_t rfu: 3; +} T_GLC_MEASUREMENT_FLAG; + +/** GLC measurement context flag bits */ +typedef struct +{ + uint8_t carbohydrate: 1; /**< Carbohydrates ID and field */ + uint8_t meal: 1; /**< Meal ID and field */ + uint8_t tester_health: 1; /**< Tester-Health field */ + uint8_t excercise: 1; /**< Exercise Duration and Intensity field */ + uint8_t medication: 1; /**< Medication ID and field */ + uint8_t medication_units: 1; /**< Medication units 0:kg, 1:liter */ + uint8_t hb_a1c: 1; /**< hb_a1c field */ + uint8_t ext_flags: 1; /**< extended flag */ +} T_GLC_MSR_CTXT_FLAG; + +typedef uint8_t TIMESTAMP[7]; +typedef uint8_t SFLOAT[2]; /* 4 bit (MSB) exponent, 12 bit mantissa */ + +typedef struct +{ + T_GLC_MEASUREMENT_FLAG flags; + uint16_t seq_num; + TIMESTAMP base_time; +#if (GLC_INCLUDE_TIME_OFFSET) + int16_t time_offset; //minutes +#endif +#if (GLC_INCLUDE_CONC_TS_LOC) + SFLOAT concentration; + uint8_t type_sample_location; +#endif +#if (GLC_INCLUDE_SS_ANNUNC) + uint16_t ss_annunciation; +#endif +} T_GLC_MEASUREMENT_VALUE; + +typedef struct +{ + T_GLC_MSR_CTXT_FLAG flags; + uint16_t seq_num; +#if (GLC_INCLUDE_EXT_FLAGS) + uint8_t ext_flags; +#endif +#if (GLC_INCLUDE_CARBOHYDRATE) + uint8_t carbohydrate_ID; + SFLOAT carbohydrate; +#endif +#if (GLC_INCLUDE_MEAL) + uint8_t meal; +#endif +#if (GLC_INCLUDE_TESTER_HEALTH) + uint8_t tester_health; +#endif +#if (GLC_INCLUDE_EXCERCISE) + uint16_t exercise_duration; + uint8_t exercise_intensity; +#endif +#if (GLC_INCLUDE_MEDICATION) + uint8_t medication_ID; + SFLOAT medication; +#endif +#if (GLC_INCLUDE_HbA1c) + SFLOAT hb_a1c; +#endif +} T_GLC_MEASUREMENT_CONTEXT; + +typedef struct +{ + T_GLC_CTRL_POINT_OPCODE op_code; + T_GLC_CTRL_POINT_OPERATOR op; /**< operator */ + uint8_t operand[18]; +} T_GLC_CONTROL_POINT; + +typedef struct +{ + T_GLC_MEASUREMENT_VALUE glc_measurement_value; +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + T_GLC_MEASUREMENT_CONTEXT glc_measurement_context; +#endif +} T_PATIENT_RECORD; + +typedef struct +{ + T_PATIENT_RECORD records[GLC_RACP_DATABASE_SIZE]; + uint8_t record_num; + /** + The tail points to an empty record who plays a role as a guard. + 1. empty tail == head + 2. one (tail - head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE == 1 + 3. full (head - tail + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE == 1 + */ + uint8_t head; + uint8_t tail; + uint16_t seq_num; /**< sequence number of latest record */ +} T_RECORD_DATA_BASE; + +typedef struct +{ + T_GLC_CONTROL_POINT ctrl_point; + uint8_t cp_length; /**< length of current operand of control point */ + T_RECORD_DATA_BASE record_db; +} T_GLC_RACP; + +/** Flags indicate CCCD */ +typedef struct +{ + uint8_t GLC_measurement_notify_enable: 1; + uint8_t GLC_measurement_context_notify_enable: 1; + uint8_t GLC_RACP_indicate_enable: 1; + uint8_t rfu: 5; +} T_GLC_NOTIFY_INDICATE_FLAG; + +/** @defgroup GLS_Callback_Data GLS Callback Data + * @brief GLS data struct for notification data to application. + * @{ + */ +typedef union +{ + uint8_t notify_indicate_index; + uint8_t read_value_index; + T_GLC_CONTROL_POINT write; +} T_GLS_UPSTREAM_MSG_DATA; + +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_GLS_UPSTREAM_MSG_DATA msg_data; +} T_GLS_CALLBACK_DATA; +/** @} */ + +/** @} End of GLS_Exported_Types */ + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup GLS_Exported_Functions GLS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add gulcose service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + gls_id = gls_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID gls_add_service(void *p_func); + + +/** + * @brief Set a GLS parameter. + * + * NOTE: You can call this function with a gulcose service parameter type and it will set the + * gulcose service parameter. Gulcose service parameters are defined in @ref T_GLS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Gulcose service parameter type: @ref T_GLS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GLC_MEASUREMENT_FLAG ms_flag = + { + 1, //time_offset + 1, //con_ts_loc + GLC_FLAGS_UNITS_MOL_L_ON, //con_units + 1, //ss_annuciation + 0, //ctxt_info_follows + 0 //rfu + }; + gls_set_parameter(GLS_PARAM_GLC_MS_FLAG, 1, &ms_flag); + } + * \endcode + */ +bool gls_set_parameter(T_GLS_PARAM_TYPE param_type, uint8_t len, void *p_value); + + +/** + * @brief Get a GLS parameter. + * + * NOTE: You can call this function with a gulcose parameter type and it will get a + * gulcose parameter. Gulcose parameters are defined in @ref T_GLS_PARAM_TYPE. + * + * @param[in] param_type Gulcose parameter type: @ref T_GLS_PARAM_TYPE + * @param[in,out] len Pointer to the location to get the length of data. + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + int record_num; + gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num); + } + * \endcode + */ +bool gls_get_parameter(T_GLS_PARAM_TYPE param_type, uint8_t *len, void *p_value); + + +/** + * @brief Send measurement notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index Index. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_glc_measurement_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index); + +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + +/** + * @brief Send measurement context notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index Index. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_glc_measurement_context_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index); +#endif + + +/** + * @brief Indicate control point data response to client from application + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] rsp_code Response code. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool gls_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code); + +/** + * @brief Indicate control point data number response to client from application + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] num Number of glucose records. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool gls_racp_num_response(uint8_t conn_id, T_SERVER_ID service_i, uint16_t num); + +/** + * @brief Prepare a new record in database. + * @return void. + * + */ +void gls_prepare_new_record(void); + + +/** + * @brief Push a new record into database. + * @return void. + * + */ +void gls_push_new_record(void); + +/** + * @brief Report records sub procedure. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_report_records_task(uint8_t conn_id, T_SERVER_ID service_id); + +/** + * @brief Calculate user facing time by adding basetime and timeoffset. + * + * + * @param[in] time_in Connection id. + * @param[in] time_offset Service id. + * @param[in] time_out Battery level value. + * @return void. + * + * Example usage + * \code{.c} + void test(void) + { + user_face_time(time, 30, time); + } + * \endcode + */ + +void user_face_time(TIMESTAMP time_in, int16_t time_offset, TIMESTAMP time_out); + +/** + * @brief Abort RACP procedure by app. + * + * @return void. + * + * Example usage + * \code{.c} + void test(void) + { + gls_abort_racp_procedure(); + } + * \endcode + */ +void gls_abort_racp_procedure(void); + +/** @} End of GLS_Exported_Functions */ + +/** @} End of GLS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* GLUCOSE_SERVICE_H */ diff --git a/inc/bluetooth/profile/server/gls_config.h b/inc/bluetooth/profile/server/gls_config.h new file mode 100644 index 0000000..8679776 --- /dev/null +++ b/inc/bluetooth/profile/server/gls_config.h @@ -0,0 +1,102 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gls_config.h + * @brief glucose service configuration file. + * @details Configure the optional characteristic and fields in the glucose service. + * @author bill + * @date 2017-6-8 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _GLS_CONFIG_H_ +#define _GLS_CONFIG_H_ + +/** @defgroup GLS Glucose Service + * @brief Glucose service + * @{ + */ + + +/** @defgroup GLS_CONFIG Glusose Service Config + * @brief Glusose service configuration file + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GLS_Common_Exported_Macros GLS Common Exported Macros + * @{ + */ + +/** @brief glucose maximum number of records in database */ +#define GLC_RACP_MAX_NBR_OF_STORED_RECS 10 + +/** @defgroup GLS_Optional_Characteristic GLS Optional Characteristic + * @brief glucose optional characteristic configuration + * @{ + */ +#define GLC_MEASUREMENT_CONTEXT_SUPPORT 1 +/** @} */ + +/** @defgroup GLS_Optional_Field GLS Optional Field + * @brief glucose optional field. + * @{ + */ +/** glucose measurement optional fields configuration */ +#define GLC_INCLUDE_TIME_OFFSET 1 +#define GLC_INCLUDE_CONC_TS_LOC 1 +#define GLC_INCLUDE_SS_ANNUNC 1 + +/** glucose measurement context optional fields configuration */ +#if (GLC_MEASUREMENT_CONTEXT_SUPPORT) +#define GLC_INCLUDE_CARBOHYDRATE 1 +#define GLC_INCLUDE_MEAL 1 +#define GLC_INCLUDE_TESTER_HEALTH 1 +#define GLC_INCLUDE_EXCERCISE 1 +#define GLC_INCLUDE_MEDICATION 1 +#define GLC_INCLUDE_HbA1c 1 +#define GLC_INCLUDE_EXT_FLAGS 0 + +#define GLC_MS_CTXT_INCLUDE_XXX (GLC_INCLUDE_CARBOHYDRATE + \ + GLC_INCLUDE_MEAL + \ + GLC_INCLUDE_TESTER_HEALTH + \ + GLC_INCLUDE_EXCERCISE + \ + GLC_INCLUDE_MEDICATION + \ + GLC_INCLUDE_HbA1c) +#if (GLC_MS_CTXT_INCLUDE_XXX == 0) +#error "Glucose measurement context characteristic value shall include at least one field, in addition to the Flags field and Sequence Number field!" +#endif +#endif +/** @} */ + +/** @defgroup GLS_Attribute_Index GLS Attribute Index + * @brief Index of each characteristic in service database + * @{ + */ +#define INDEX_OFFSET0 (0) +#define GLS_CHAR_GLC_MEASUREMENT_INDEX (INDEX_OFFSET0+0x02) +#define GLS_CHAR_GLC_MEASUREMENT_CCCD_INDEX (GLS_CHAR_GLC_MEASUREMENT_INDEX + 1) + +#if (GLC_MEASUREMENT_CONTEXT_SUPPORT) +#define GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX (INDEX_OFFSET0+0x05) +#define GLS_CHAR_GLC_MEASUREMENT_CONTEXT_CCCD_INDEX (GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX + 1) +#endif + +#define INDEX_OFFSET1 (INDEX_OFFSET0+GLC_MEASUREMENT_CONTEXT_SUPPORT*3) +#define GLS_CHAR_GLC_FEATURE_INDEX (INDEX_OFFSET1+0x05) +#define GLS_CHAR_GLC_RACP_INDEX (INDEX_OFFSET1+0x07) +#define GLS_CHAR_GLC_RACP_CCCD_INDEX (GLS_CHAR_GLC_RACP_INDEX + 1) +/** @} */ + + +/** @} End of GLS_Common_Exported_Macros */ + +/** @} End of GLS_CONFIG */ + +/** @} End of GLS */ +#endif diff --git a/inc/bluetooth/profile/server/hids.h b/inc/bluetooth/profile/server/hids.h new file mode 100644 index 0000000..80843d3 --- /dev/null +++ b/inc/bluetooth/profile/server/hids.h @@ -0,0 +1,283 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids.h + * @brief Head file for using Human Interface Device Service. + * @details HIDS data structs and external functions declaration. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _HIDS_H_ +#define _HIDS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" + +/** @defgroup HIDS Human Interface Device Service + * @brief Human Interface Device Service + * @details + + The HID Service exposes data and associated formatting for HID Devices and HID Hosts. + + Application shall register HID service when initialization through @ref hids_add_service function. + + Application can set the HID service through @ref hids_set_parameter function. + + Application can send report data of HID service to the client with a notification through @ref hids_send_report function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HIDS_Exported_Macros HIDS Exported Macros + * @brief + * @{ + */ + +/** @defgroup HIDS_Index HIDS Attribute Index + * @brief Index defines for Characteristic's value in HID Device + * @{ + */ +#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2) +#define GATT_SVC_HID_REPORT_INPUT_INDEX (4) +#define GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8) +#define GATT_SVC_HID_REPORT_FEATURE_INDEX (11) +#define GATT_SVC_HID_REPORT_MAP_INDEX (14) +#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1) +#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17) +#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1) +#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20) +#define GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX (22) +#define GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX+1) +#define GATT_SVC_HID_INFO_INDEX (25) +#define GATT_SVC_HID_CONTROL_POINT_INDEX (27) +/** @} */ + +/** End of HIDS_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HIDS_Exported_Types HIDS Exported Types + * @brief + * @{ + */ + +/** +* @brief Human Interface Device Service parameter type +*/ +typedef enum +{ + HID_PROTOCOL_MODE = 0x01, + HID_REPORT_INPUT, + HID_REPORT_OUTPUT, + HID_REPORT_FEATURE, + HID_REPORT_MAP, + HID_EXTERNAL_REPORT_REFER, + HID_BOOT_KB_IN_REPORT, + HID_BOOT_KB_OUT_REPORT, + HID_BOOT_MS_IN_REPORT, + HID_INFO, + HID_CONTROL_POINT, +} T_HIDS_PARAM_TYPE; + +/** +* @brief Human Interface Device Service information +*/ +typedef struct +{ + uint8_t b_country_code; + uint8_t flags; + uint16_t bcd_hid; +} T_HID_INFO; + +/** +* @brief Human Interface Device Service report type +*/ +typedef enum +{ + HID_INPUT_TYPE = 1, + HID_OUTPUT_TYPE = 2, + HID_FEATURE_TYPE = 3 +} T_PROFILE_HID_REPORT_TYPE; + +/** +* @brief Human Interface Device Service control point +*/ +typedef enum +{ + HID_SUSPEND = 0, + HID_EXIT_SUSPEND = 1, +} T_HID_CTL_POINT; + +/** +* @brief Human Interface Device Service protocol mode +*/ +typedef enum +{ + BOOT_PROTOCOL_MODE = 0, + REPORT_PROCOCOL_MODE = 1 +} T_HID_PROTOCOL_MODE; + +/** @defgroup HIDS_Upstream_Message HIDS Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ +typedef enum +{ + NOTIFY_ENABLE, + NOTIFY_DISABLE +} T_HID_NOTIFY; + +typedef union +{ + uint8_t voice_enable; + uint8_t protocol_mode; + uint8_t suspend_mode; + struct + { + uint8_t reportLen; + uint8_t *report; + } report_data; +} T_HID_WRITE_PARAMETER; + +typedef struct +{ + uint8_t write_type; + T_HID_WRITE_PARAMETER write_parameter; +} T_HID_WRITE_MSG; + +typedef struct +{ + uint8_t index; + T_HID_NOTIFY value; +} T_HID_NOT_IND_DATA; + +typedef union +{ + uint8_t read_value_index; + T_HID_WRITE_MSG write_msg; + T_HID_NOT_IND_DATA not_ind_data; +} T_HID_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_HID_UPSTREAM_MSG_DATA msg_data; +} T_HID_CALLBACK_DATA; + +/** @} End of HIDS_Upstream_Message */ + + +/** End of HIDS_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HIDS_Exported_Functions HIDS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func); + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len); + + +/** @} End of HIDS_Exported_Functions */ + +/** @} End of HIDS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/profile/server/hids_kb.h b/inc/bluetooth/profile/server/hids_kb.h new file mode 100644 index 0000000..6f55e23 --- /dev/null +++ b/inc/bluetooth/profile/server/hids_kb.h @@ -0,0 +1,281 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_kb.h + * @brief Head file for using Human Interface Device Service. + * @details HIDS data structs and external functions declaration. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _HIDS_KB_H_ +#define _HIDS_KB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" + +/** @defgroup HIDS_KB Human Interface Device Service of Keyboard + * @brief Human Interface Device Service + * @details + + The HID Service exposes data and associated formatting for HID Devices and HID Hosts. + + Application shall register HID service when initialization through @ref hids_add_service function. + + Application can set the HID service through @ref hids_set_parameter function. + + Application can send report data of HID service to the client with a notification through @ref hids_send_report function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Macros HIDS Keyboard Exported Macros + * @brief + * @{ + */ + +/** @defgroup HIDS_KB_Index HIDS Keyboard Attribute Index + * @brief Index defines for Characteristic's value in HID Device + * @{ + */ +#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2) +#define GATT_SVC_HID_REPORT_INPUT_INDEX (4) +#define GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8) +#define GATT_SVC_HID_REPORT_FEATURE_INDEX (11) +#define GATT_SVC_HID_REPORT_MAP_INDEX (14) +#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1) +#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17) +#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1) +#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20) +#define GATT_SVC_HID_INFO_INDEX (22) +#define GATT_SVC_HID_CONTROL_POINT_INDEX (24) +/** @} */ + +/** End of HIDS_KB_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Types HIDS Keyboard Exported Types + * @brief + * @{ + */ + +/** +* @brief Human Interface Device Service parameter type +*/ +typedef enum +{ + HID_PROTOCOL_MODE = 0x01, + HID_REPORT_INPUT, + HID_REPORT_OUTPUT, + HID_REPORT_FEATURE, + HID_REPORT_MAP, + HID_EXTERNAL_REPORT_REFER, + HID_BOOT_KB_IN_REPORT, + HID_BOOT_KB_OUT_REPORT, + HID_INFO, + HID_CONTROL_POINT, +} T_HIDS_PARAM_TYPE; + +/** +* @brief Human Interface Device Service information +*/ +typedef struct +{ + uint8_t b_country_code; + uint8_t flags; + uint16_t bcd_hid; +} T_HID_INFO; + +/** +* @brief Human Interface Device Service report type +*/ +typedef enum +{ + HID_INPUT_TYPE = 1, + HID_OUTPUT_TYPE = 2, + HID_FEATURE_TYPE = 3 +} T_PROFILE_HID_REPORT_TYPE; + +/** +* @brief Human Interface Device Service control point +*/ +typedef enum +{ + HID_SUSPEND = 0, + HID_EXIT_SUSPEND = 1, +} T_HID_CTL_POINT; + +/** +* @brief Human Interface Device Service protocol mode +*/ +typedef enum +{ + BOOT_PROTOCOL_MODE = 0, + REPORT_PROCOCOL_MODE = 1 +} T_HID_PROTOCOL_MODE; + +/** @defgroup HIDS_KB_Upstream_Message HIDS Keyboard Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ +typedef enum +{ + NOTIFY_ENABLE, + NOTIFY_DISABLE +} T_HID_NOTIFY; + +typedef union +{ + uint8_t voice_enable; + uint8_t protocol_mode; + uint8_t suspend_mode; + uint8_t output; + struct + { + uint8_t reportLen; + uint8_t *report; + } report_data; +} T_HID_WRITE_PARAMETER; + +typedef struct +{ + uint8_t write_type; + T_HID_WRITE_PARAMETER write_parameter; +} T_HID_WRITE_MSG; + +typedef struct +{ + uint8_t index; + T_HID_NOTIFY value; +} T_HID_NOT_IND_DATA; + +typedef struct +{ + uint8_t read_value_index; + T_HID_WRITE_MSG write_msg; + T_HID_NOT_IND_DATA not_ind_data; +} T_HID_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_HID_UPSTREAM_MSG_DATA msg_data; +} T_HID_CALLBACK_DATA; + +/** @} End of HIDS_KB_Upstream_Message */ + + +/** End of HIDS_KB_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Functions HIDS Keyboard Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func); + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len); + + +/** @} End of HIDS_KB_Exported_Functions */ + +/** @} End of HIDS_KB */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/profile/server/hids_ms.h b/inc/bluetooth/profile/server/hids_ms.h new file mode 100644 index 0000000..de69532 --- /dev/null +++ b/inc/bluetooth/profile/server/hids_ms.h @@ -0,0 +1,280 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_ms.h + * @brief Head file for using Human Interface Device Service. + * @details HIDS data structs and external functions declaration. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _HIDS_MS_H_ +#define _HIDS_MS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" + +/** @defgroup HIDS_MS Human Interface Device Service of Mouse + * @brief Human Interface Device Service + * @details + + The HID Service exposes data and associated formatting for HID Devices and HID Hosts. + + Application shall register HID service when initialization through @ref hids_add_service function. + + Application can set the HID service through @ref hids_set_parameter function. + + Application can send report data of HID service to the client with a notification through @ref hids_send_report function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HIDS_MS_Exported_Macros HIDS Mouse Exported Macros + * @brief + * @{ + */ + +/** @defgroup HIDS_MS_Index HIDS Mouse Attribute Index + * @brief Index defines for Characteristic's value in HID Device + * @{ + */ +#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2) +#define GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX (4) +#define GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX (8) +#define GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (12) +#define GATT_SVC_HID_REPORT_FEATURE_INDEX (15) +#define GATT_SVC_HID_REPORT_MAP_INDEX (18) +#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1) +#define GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX (21) +#define GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX+1) +#define GATT_SVC_HID_INFO_INDEX (24) +#define GATT_SVC_HID_CONTROL_POINT_INDEX (26) +/** @} */ + +/** End of HIDS_MS_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HIDS_MS_Exported_Types HIDS Mouse Exported Types + * @brief + * @{ + */ + +/** +* @brief Human Interface Device Service parameter type +*/ +typedef enum +{ + HID_PROTOCOL_MODE = 0x01, + HID_REPORT_INPUT, + HID_REPORT_OUTPUT, + HID_REPORT_FEATURE, + HID_REPORT_MAP, + HID_EXTERNAL_REPORT_REFER, + HID_BOOT_MS_IN_REPORT, + HID_INFO, + HID_CONTROL_POINT, +} T_HIDS_PARAM_TYPE; + +/** +* @brief Human Interface Device Service information +*/ +typedef struct +{ + uint8_t b_country_code; + uint8_t flags; + uint16_t bcd_hid; +} T_HID_INFO; + +/** +* @brief Human Interface Device Service report type +*/ +typedef enum +{ + HID_INPUT_TYPE = 1, + HID_OUTPUT_TYPE = 2, + HID_FEATURE_TYPE = 3 +} T_PROFILE_HID_REPORT_TYPE; + +/** +* @brief Human Interface Device Service control point +*/ +typedef enum +{ + HID_SUSPEND = 0, + HID_EXIT_SUSPEND = 1, +} T_HID_CTL_POINT; + +/** +* @brief Human Interface Device Service protocol mode +*/ +typedef enum +{ + BOOT_PROTOCOL_MODE = 0, + REPORT_PROCOCOL_MODE = 1 +} T_HID_PROTOCOL_MODE; + +/** @defgroup HIDS_MS_Upstream_Message HIDS Mouse Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ +typedef enum +{ + NOTIFY_ENABLE, + NOTIFY_DISABLE +} T_HID_NOTIFY; + +typedef union +{ + uint8_t voice_enable; + uint8_t protocol_mode; + uint8_t suspend_mode; + struct + { + uint8_t reportLen; + uint8_t *report; + } report_data; +} T_HID_WRITE_PARAMETER; + +typedef struct +{ + uint8_t write_type; + T_HID_WRITE_PARAMETER write_parameter; +} T_HID_WRITE_MSG; + +typedef struct +{ + uint8_t index; + T_HID_NOTIFY value; +} T_HID_NOT_IND_DATA; + +typedef union +{ + uint8_t read_value_index; + T_HID_WRITE_MSG write_msg; + T_HID_NOT_IND_DATA not_ind_data; +} T_HID_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_HID_UPSTREAM_MSG_DATA msg_data; +} T_HID_CALLBACK_DATA; + +/** @} End of HIDS_MS_Upstream_Message */ + + +/** End of HIDS_MS_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HIDS_MS_Exported_Functions HIDS Mouse Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func); + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len); + + +/** @} End of HIDS_MS_Exported_Functions */ + +/** @} End of HIDS_MS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/profile/server/hids_mulkb.h b/inc/bluetooth/profile/server/hids_mulkb.h new file mode 100644 index 0000000..7b468a9 --- /dev/null +++ b/inc/bluetooth/profile/server/hids_mulkb.h @@ -0,0 +1,284 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_kb.h + * @brief Head file for using Human Interface Device Service. + * @details HIDS data structs and external functions declaration. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _HIDS_KB_H_ +#define _HIDS_KB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" + +/** @defgroup HIDS_KB Human Interface Device Service of Keyboard + * @brief Human Interface Device Service + * @details + + The HID Service exposes data and associated formatting for HID Devices and HID Hosts. + + Application shall register HID service when initialization through @ref hids_add_service function. + + Application can set the HID service through @ref hids_set_parameter function. + + Application can send report data of HID service to the client with a notification through @ref hids_send_report function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Macros HIDS Keyboard Exported Macros + * @brief + * @{ + */ + +/** @defgroup HIDS_KB_Index HIDS Keyboard Attribute Index + * @brief Index defines for Characteristic's value in HID Device + * @{ + */ +#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (2) +#define GATT_SVC_HID_REPORT_KEYBOARD_INPUT_INDEX (4) +#define GATT_SVC_HID_REPORT_KEYBOARD_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_KEYBOARD_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_OUTPUT_INDEX (8) +#define GATT_SVC_HID_REPORT_CONSUMER_INPUT_INDEX (11) +#define GATT_SVC_HID_REPORT_CONSUMER_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_CONSUMER_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX (15) +#define GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX (GATT_SVC_HID_REPORT_VENDOR_INPUT_INDEX+1) +#define GATT_SVC_HID_REPORT_MAP_INDEX (19) +#define GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX (GATT_SVC_HID_REPORT_MAP_INDEX+1) +//#define GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX (17) +//#define GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX (GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX+1) +//#define GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX (20) +#define GATT_SVC_HID_INFO_INDEX (21) +#define GATT_SVC_HID_CONTROL_POINT_INDEX (23) +/** @} */ + +/** End of HIDS_KB_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Types HIDS Keyboard Exported Types + * @brief + * @{ + */ + +/** +* @brief Human Interface Device Service parameter type +*/ +typedef enum +{ + HID_PROTOCOL_MODE = 0x01, + HID_REPORT_INPUT, + HID_REPORT_OUTPUT, + HID_REPORT_FEATURE, + HID_REPORT_MAP, + HID_EXTERNAL_REPORT_REFER, + HID_BOOT_KB_IN_REPORT, + HID_BOOT_KB_OUT_REPORT, + HID_INFO, + HID_CONTROL_POINT, +} T_HIDS_PARAM_TYPE; + +/** +* @brief Human Interface Device Service information +*/ +typedef struct +{ + uint16_t bcd_hid; + uint8_t b_country_code; + uint8_t flags; +} T_HID_INFO; + +/** +* @brief Human Interface Device Service report type +*/ +typedef enum +{ + HID_INPUT_TYPE = 1, + HID_OUTPUT_TYPE = 2, + HID_FEATURE_TYPE = 3 +} T_PROFILE_HID_REPORT_TYPE; + +/** +* @brief Human Interface Device Service control point +*/ +typedef enum +{ + HID_SUSPEND = 0, + HID_EXIT_SUSPEND = 1, +} T_HID_CTL_POINT; + +/** +* @brief Human Interface Device Service protocol mode +*/ +typedef enum +{ + BOOT_PROTOCOL_MODE = 0, + REPORT_PROCOCOL_MODE = 1 +} T_HID_PROTOCOL_MODE; + +/** @defgroup HIDS_KB_Upstream_Message HIDS Keyboard Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ +typedef enum +{ + NOTIFY_ENABLE, + NOTIFY_DISABLE +} T_HID_NOTIFY; + +typedef union +{ + uint8_t voice_enable; + uint8_t protocol_mode; + uint8_t suspend_mode; + uint8_t output; + struct + { + uint8_t reportLen; + uint8_t *report; + } report_data; +} T_HID_WRITE_PARAMETER; + +typedef struct +{ + uint8_t write_type; + T_HID_WRITE_PARAMETER write_parameter; +} T_HID_WRITE_MSG; + +typedef struct +{ + uint8_t index; + T_HID_NOTIFY value; +} T_HID_NOT_IND_DATA; + +typedef struct +{ + uint8_t read_value_index; + T_HID_WRITE_MSG write_msg; + T_HID_NOT_IND_DATA not_ind_data; +} T_HID_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_HID_UPSTREAM_MSG_DATA msg_data; +} T_HID_CALLBACK_DATA; + +/** @} End of HIDS_KB_Upstream_Message */ + + +/** End of HIDS_KB_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HIDS_KB_Exported_Functions HIDS Keyboard Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func); + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len); + + +/** @} End of HIDS_KB_Exported_Functions */ + +/** @} End of HIDS_KB */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/inc/bluetooth/profile/server/hids_rmc.h b/inc/bluetooth/profile/server/hids_rmc.h new file mode 100644 index 0000000..ccd3986 --- /dev/null +++ b/inc/bluetooth/profile/server/hids_rmc.h @@ -0,0 +1,252 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_rmc.h + * @brief Head file for using Human Interface Device Service Remote Controller. + * @details HIDS RMC data structs and external functions declaration. + * @author Chenjie Jin + * @date 2018-5-7 + * @version v1.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HIDS_RMC_H +#define _HIDS_RMC_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "board.h" + +/** @defgroup HIDS_RmC HIDS Human Interface Device Service of Remote Controller + * @brief Human Interface Device Service Remote Controller + * @{ + */ + +/** @defgroup HIDS_RmC_Exported_Constants HIDS RmC Exported Constants + * @brief macros that other .c files may use all defined here + * @{ + */ + +/** @brief HIDS Report Id Definition. */ +#define HIDS_KB_REPORT_ID 1 +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD +#define HIDS_MM_KB_REPORT_ID 2 +#endif +#if (VOICE_ENC_TYPE == SW_MSBC_ENC) +#define HIDS_VOICE_REPORT_ID 0x5A // input and output +#elif (VOICE_ENC_TYPE == SW_SBC_ENC) +#define HIDS_VOICE_REPORT_ID 0x5B // input and output +#else +#define HIDS_VOICE_REPORT_ID 0x5A // input and output +#endif + + +/** @defgroup HIDS_RmC_Application_Parameters HIDS RmC Application Parameters + * @brief Type of parameters set/got from application. + * @{ + */ +#define HIDS_PARAM_PROTOCOL_MODE 1 +#define HIDS_PARAM_SUSPEND_MODE 2 +#define HIDS_PARAM_HID_INFO 3 +#define HIDS_PARAM_REPORT 4 +/** @} */ + +///@cond +/** @brief HIDS_RmC related UUIDs. */ +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_RECORD_ACCESS_POINT 0x2A52 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_BOOT_MOUSE_IN_REPORT 0x2A33 +#define GATT_UUID_CHAR_REPORT_REFERENCE 0x2908 +#define GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE 0x2907 + +///@endcond + +/** @defgroup HIDS_RmC_Attribute_Index HIDS RmC Attribute Index + * @brief Index defines for Characteristic's value in HID Device + * @{ + */ +#define GATT_SRV_HID_INDEX_MAX 23 +#define GATT_SVC_HID_INFO_INDEX (2) /**< @brief Index for HID Information chars's value */ +#define GATT_SVC_HID_CONTROL_POINT_INDEX (4) /**< @brief Index for HID Control Point chars's value */ +#define GATT_SVC_HID_PROTOCOL_MODE_INDEX (6) /**< @brief Index for HID Protocol Mode chars's value */ +#define GATT_SVC_HID_REPORT_MAP_INDEX (8) /**< @brief Index for HID Report Map chars's value */ + +#define GATT_SRV_HID_KB_INPUT_INDEX (10) +#define GATT_SRV_HID_KB_CCCD_INDEX (GATT_SRV_HID_KB_INPUT_INDEX + 1) + +#if SUPPORT_VOICE_FEATURE +#define GATT_SRV_HID_VOICE_INPUT_INDEX (14) +#define GATT_SRV_HID_VOICE_INPUT_CCCD_INDEX (GATT_SRV_HID_VOICE_INPUT_INDEX + 1) +#define GATT_SRV_HID_VOICE_OUTPUT_INDEX (18) +#endif + +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD +#if SUPPORT_VOICE_FEATURE +#define GATT_SRV_HID_MM_KB_INPUT_INDEX (21) +#define GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX (GATT_SRV_HID_MM_KB_INPUT_INDEX + 1) +#else +#define GATT_SRV_HID_MM_KB_INPUT_INDEX (14) +#define GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX (GATT_SRV_HID_MM_KB_INPUT_INDEX + 1) +#endif +#endif +/** @} */ + +/** @defgroup HIDS_RmC_Upstream_Message HIDS RmC Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ + +/** @defgroup HIDS_RmC_Read_Info HIDS RmC Read Info + * @brief Parameter for read characteristic value. + * @{ + */ +#define HIDS_READ_PARAM_PROTOCOL_MODE 1 +#define HIDS_READ_PARAM_SUSPEND_MODE 2 +#define HIDS_READ_PARAM_HID_INFO 3 +#define HIDS_READ_PARAM_REPORT 4 +/** @} */ + +/** @defgroup HIDS_RmC_Write_Info HIDS RmC Write Info + * @brief Parameter for write characteristic value. + * @{ + */ +#define HID_WRITE_VIOCE_CMD 1 +#define HID_WRITE_PROTOCOL_MODE 2 +#define HID_WRITE_SUSPEND_MODE 3 +#define HID_WRITE_OUTPUT 4 +#define HID_WRITE_INPUT_REPORT 5 +/** @} */ + +/** @defgroup HIDS_RmC_Notify_Indicate_Info HIDS RmC Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define HID_NOTIFY_INDICATE_KB_ENABLE 1 +#define HID_NOTIFY_INDICATE_KB_DISABLE 2 +#define HID_NOTIFY_INDICATE_VOICE_ENABLE 3 +#define HID_NOTIFY_INDICATE_VOICE_DISABLE 4 +#define HID_NOTIFY_INDICATE_MM_KB_ENABLE 5 +#define HID_NOTIFY_INDICATE_MM_KB_DISABLE 6 + +/** @} */ + +/** @} End of HIDS_RmC_Upstream_Message */ + +/** @} End of HIDS_RmC_Exported_Constants */ + +/** @defgroup HIDS_RmC_Exported_Types HIDS RmC Exported Types + * @brief types that other.c files may use all defined here + * @{ + */ + +/* Add all public types here */ + +/** @struct _HID_INFO_ATTRB hids_rmc.h "hids_rmc.h" + * @brief type define for value of HID information + */ +typedef struct _HID_INFO_ATTRB +{ + uint8_t CountryCode; + uint8_t bFlags; + uint16_t BcdHID; +} HID_INFO_ATTRB; + +/** @brief enum for TProfile_HIDReportType*/ +typedef enum +{ + HID_INPUT_TYPE = 1, /**< @enum Input report */ + HID_OUTPUT_TYPE = 2, /**< @enum Output report */ + HID_FEATURE_TYPE = 3 /**< @enum Feature report */ +} TProfile_HIDReportType; + +/** @struct _TProfile_REPORT_REFE_TABLE hids_rmc.h "hids_rmc.h" + * @brief type define for info reference to report data + */ +typedef struct _TProfile_REPORT_REFE_TABLE +{ + uint8_t report_size; /**< @brief report size according to value of Report Map value, byte */ + uint8_t report_id; /**< @brief report ID defined in value of Report Map Char, byte */ + uint8_t report_type; /**< @brief report Type(Input,Output,Feature), ref: @ref TProfile_HIDReportType */ +} TProfile_REPORT_REFE_TABLE; + +/** @defgroup HIDS_RmC_Callback_Data HIDS RmC Callback Data + * @brief HIDS RmC data struct for notification data to application. + * @{ + */ + +/** @brief value for HID protocol mode characteristic */ +enum TProfile_HID_PROTOCOL_MODE +{ + BOOT_PROTOCOL_MODE = 0, /**< @enum boot protocol mode */ + REPORT_PROCOCOL_MODE = 1 /**< @enum report protocol mode */ +}; + +typedef union _THID_WRITE_PARAMETER +{ + uint8_t voice_enable; + uint8_t protocol_mode; /**< ref: @ref TProfile_HID_PROTOCOL_MODE */ + uint8_t suspend_mode; + struct + { + uint8_t reportLen; + uint8_t *report; + } report_data; +} THID_WRITE_PARAMETER; + +/** @struct _THID_WRITE_MSG hids_rmc.h "hids_rmc.h" + * @brief write message + */ +typedef struct _THID_WRITE_MSG +{ + uint8_t write_type; /**< ref: @ref HIDS_RmC_Write_Info */ + THID_WRITE_PARAMETER write_parameter; +} THID_WRITE_MSG; + +typedef union _THID_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; /**< ref: @ref HIDS_RmC_Notify_Indicate_Info */ + uint8_t read_value_index; /**< ref: @ref HIDS_RmC_Read_Info */ + THID_WRITE_MSG write; +} THID_UPSTREAM_MSG_DATA; + +/** @struct _T_HID_CALLBACK_DATA hids_rmc.h "hids_rmc.h" + * @brief callback data + */ +typedef struct _T_HID_CALLBACK_DATA +{ + T_SERVICE_CALLBACK_TYPE msg_type; + THID_UPSTREAM_MSG_DATA msg_data; +} T_HID_CALLBACK_DATA; +/** @} End of HIDS_RmC_Callback_Data */ + +/** @} End of HIDS_RmC_Exported_Types */ + +/** @defgroup HIDS_RmC_Exported_Functions HIDS RmC Exported Functions + * @brief functions that other .c files may use all defined here + * @{ + */ +bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr); +uint8_t hids_add_service(void *p_func); +/** @} End of HIDS_RmC_Exported_Functions */ + +/** @} End of HIDS_RmC */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _HIDS_RMC_H */ diff --git a/inc/bluetooth/profile/server/hrs.h b/inc/bluetooth/profile/server/hrs.h new file mode 100644 index 0000000..8e7fa59 --- /dev/null +++ b/inc/bluetooth/profile/server/hrs.h @@ -0,0 +1,233 @@ +/***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hrs.h + * @brief Variables and interfaces for using Heart Rate Service. + * @details Heart Rate Service data structs and functions. + * @author + * @date 2017-09-21 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HRS_SERVICE_DEF_H +#define _HRS_SERVICE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "hrs_define.h" + +/** @defgroup HRS Heart Rate Service + * @brief Heart Rate Service + * @details + + The Heart Rate Service exposes heart rate and other data related to a heart rate sensor intended for fitness applications. + + Application shall register heart rate service when initialization through @ref hrs_add_service function. + + The Heart Rate Measurement characteristic is used to send a heart rate measurement. Included in the characteristic are a Flags field (for showing the presence of optional fields and features + supported), a heart rate measurement value field and, depending upon the contents of the Flags field, an Energy Expended field and an RR-Interval field. The RR-Interval represents the time between + two consecutive R waves in an Electrocardiogram (ECG) waveform. + Application can send heart rate measurement value through @ref hrs_heart_rate_measurement_value_notify function. + + The Body Sensor Location characteristic of the device is used to describe the intended location of the heart rate measurement for the device. + The value of the Body Sensor Location characteristic is static while in a connection. + + The Heart Rate Control Point characteristic is used to enable a Client to write control points to a Server to control behavior. + Support for this characteristic is mandatory if the Server supports the Energy Expended feature. + + Application can set heart rate measurement parameter and location of the heart rate measurement for the device through @ref hrs_set_parameter function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HRS_Exported_Macros HRS Exported Macros + * @brief + * @{ + */ + +/** @defgroup HRS_Notify_Indicate_Info HRS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_ENABLE 1 +#define HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_DISABLE 2 +/** @} */ + +/** End of HRS_Exported_Macros +* @} +*/ + + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HRS_Exported_Types HRS Exported Types + * @brief + * @{ + */ + +typedef enum +{ + HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG = 0x01, + HRS_HEART_RATE_MEASUREMENT_PARAM_MEASUREMENT_VALUE, + HRS_HEART_RATE_MEASUREMENT_PARAM_ENERGY_EXPENDED, + HRS_HEART_RATE_MEASUREMENT_PARAM_RR_INTERVAL, + HRS_BODY_SENSOR_LOCATION_PARAM_VALUE = 0x10, +} T_HRS_PARAM_TYPE; + +/** + * @brief HRS Control Point data, variable length during connection, max can reach 17 bytes. + * + * HRS Control Point data used to store the Control Point Command recieved from the client. +*/ + +typedef struct +{ + T_HRS_HEART_RATE_CP_OPCODE opcode; +} T_HRS_WRITE_MSG; + +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + T_HRS_WRITE_MSG write; +} T_HRS_UPSTREAM_MSG_DATA; + +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_HRS_UPSTREAM_MSG_DATA msg_data; +} T_HRS_CALLBACK_DATA; +/** End of HRS_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HRS_Exported_Functions HRS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add heart rate service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hrs_id = hrs_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t hrs_add_service(void *p_func); + + +/** + * @brief Set a heart rate service parameter. + * + * NOTE: You can call this function with a heart rate service parameter type and it will set the + * heart rate service parameter. Heart rate service parameters are defined + * in @ref T_HRS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Heart rate service parameter type: @ref T_HRS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag; + flag.heart_rate_value_format_bit = 1; + flag.sensor_contact_status_bits = 3; + if (p_parse_value->param_count >= 1) + { + flag.sensor_contact_status_bits = p_parse_value->dw_param[1]; + } + + flag.energy_expended_status_bit = 1; + flag.rr_interval_bit = 1; + flag.rfu = 0; + + hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag); + } + * \endcode + */ + +bool hrs_set_parameter(T_HRS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send heart rate measurement value notification data. + * Application shall call @ref hrs_set_parameter to set heart rate measurement value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + + T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag; + flag.heart_rate_value_format_bit = 1; + flag.sensor_contact_status_bits = 3; + if (p_parse_value->param_count >= 1) + { + flag.sensor_contact_status_bits = p_parse_value->dw_param[1]; + } + + flag.energy_expended_status_bit = 1; + flag.rr_interval_bit = 1; + flag.rfu = 0; + + hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag); + + op_result = hrs_heart_rate_measurement_value_notify(p_parse_value->dw_param[0], hrs_id); + } + * \endcode + */ +bool hrs_heart_rate_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id); + +/** @} End of HRS_Exported_Functions */ + +/** @} End of HRS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _HRS_SERVICE_DEF_H */ + diff --git a/inc/bluetooth/profile/server/hrs_define.h b/inc/bluetooth/profile/server/hrs_define.h new file mode 100644 index 0000000..cfd0f03 --- /dev/null +++ b/inc/bluetooth/profile/server/hrs_define.h @@ -0,0 +1,176 @@ +/***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hrs.h + * @brief Variables and interfaces for using Heart Rate Service. + * @details Heart Rate Service data structs and functions. + * @author + * @date 2017-09-21 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HRS_DEFINE_H +#define _HRS_DEFINE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +/** @defgroup HRS Heart Rate Service + * @brief Heart Rate Service + * @details + + The Heart Rate Service exposes heart rate and other data related to a heart rate sensor intended for fitness applications. + + Application shall register heart rate service when initialization through @ref hrs_add_service function. + + The Heart Rate Measurement characteristic is used to send a heart rate measurement. Included in the characteristic are a Flags field (for showing the presence of optional fields and features + supported), a heart rate measurement value field and, depending upon the contents of the Flags field, an Energy Expended field and an RR-Interval field. The RR-Interval represents the time between + two consecutive R waves in an Electrocardiogram (ECG) waveform. + Application can send heart rate measurement value through @ref hrs_heart_rate_measurement_value_notify function. + + The Body Sensor Location characteristic of the device is used to describe the intended location of the heart rate measurement for the device. + The value of the Body Sensor Location characteristic is static while in a connection. + + The Heart Rate Control Point characteristic is used to enable a Client to write control points to a Server to control behavior. + Support for this characteristic is mandatory if the Server supports the Energy Expended feature. + + Application can set heart rate measurement parameter and location of the heart rate measurement for the device through @ref hrs_set_parameter function. + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HRS_Exported_Macros HRS Exported Macros + * @brief + * @{ + */ +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +#define HRS_BODY_SENSOR_LOCATION_CHAR_SUPPORT +#define HRS_ENERGY_EXPENDED_FEATURE_SUPPORT + +#define HRS_HEART_RATE_MEASUREMENT_VALUE_INDEX 2//notify +#define HRS_BODY_SENSOR_LOCATION_VALUE_INDEX 5//read +#define HRS_HEART_RATE_CP_VALUE_INDEX 7//write + +#define HRS_HEART_RATE_MEASUREMENT_CCCD_INDEX 3 + +#define GATT_UUID_SERVICE_HEART_RATE 0x180D +#define GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT 0x2A37 +#define GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION 0x2A38 +#define GATT_UUID_CHAR_HRS_HEART_RATE_CP 0x2A39 + +#define HRS_CP_RSPCODE_RESERVED 0x00 +#define HRS_CP_RSPCODE_SUCCESS 0x01 +#define HRS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02 +#define HRS_CP_RSPCODE_INVALID_PARAMETER 0x03 +#define HRS_CP_RSPCODE_OPERATION_FAILED 0x04 + +#define HRS_CTL_PNT_OPERATE_ACTIVE(x) \ + (x == HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED) + +#define Heart_Rate_Value_Format_UINT8 0 +#define Heart_Rate_Value_Format_UINT16 1 + +#define HRS_HEART_RATE_MEASUREMENT_VALUE_MAX_LEN 7 + +/** @defgroup HRS_Read_Info HRS Read Info + * @brief Parameter for reading characteristic value. + * @{ + */ +#define HRS_READ_BODY_SENSOR_LOCATION_VALUE 1 +/** @} */ + +/** @defgroup HRS_Sensor_Location HRS Sensor Location + * @brief Body Sensor Location Value + * @{ + */ +#define BODY_SENSOR_LOCATION_VALUE_OTHER 0 +#define BODY_SENSOR_LOCATION_VALUE_CHEST 1 +#define BODY_SENSOR_LOCATION_VALUE_WRIST 2 +#define BODY_SENSOR_LOCATION_VALUE_FINGER 3 +#define BODY_SENSOR_LOCATION_VALUE_HAND 4 +#define BODY_SENSOR_LOCATION_VALUE_EAR_LOBE 5 +#define BODY_SENSOR_LOCATION_VALUE_FOOT 6 +/** @} */ + +#define HRS_MAX_CTL_PNT_VALUE 1 + +/** End of HRS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HRS_Exported_Types HRS Exported Types + * @brief + * @{ + */ +typedef enum +{ + HRS_HEART_RATE_CP_OPCODE_RESERVED = 0, + HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED = 1 +} T_HRS_HEART_RATE_CP_OPCODE; + +/** notification indification falg */ +typedef struct +{ + uint8_t heart_rate_measurement_notify_enable: 1; + uint8_t rfu: 7; +} HRS_NOTIFY_INDICATE_FLAG; + +/** Heart Rate Measurement Value Flag */ +typedef struct +{ + uint8_t heart_rate_value_format_bit: 1; + uint8_t sensor_contact_status_bits: 2; + uint8_t energy_expended_status_bit: 1; + uint8_t rr_interval_bit: 1; + uint8_t rfu: 3; +} T_HEART_RATE_MEASUREMENT_VALUE_FLAG; + +/** Heart Rate Measurement Value */ +typedef struct +{ + T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag; + uint16_t heart_rate_measurement_value; + uint16_t energy_expended; + uint16_t rr_interval; +} T_HEART_RATE_MEASUREMENT_VALUE; + +/** + * @brief HRS Control Point data, variable length during connection, max can reach 17 bytes. + * + * HRS Control Point data used to store the Control Point Command recieved from the client. +*/ +typedef struct +{ + uint8_t cur_length; /**< length of current CSC Control Point data . */ + uint8_t value[HRS_MAX_CTL_PNT_VALUE]; /**< value of current CSC Control Point data . */ +} T_HRS_CONTROL_POINT; + +/** End of HRS_Exported_Types +* @} +*/ + + +/** @} End of HRS_DEFINE */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _HRS_SERVICE_DEF_H */ + diff --git a/inc/bluetooth/profile/server/hts.h b/inc/bluetooth/profile/server/hts.h new file mode 100644 index 0000000..55e4277 --- /dev/null +++ b/inc/bluetooth/profile/server/hts.h @@ -0,0 +1,349 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hts.h + * @brief Variables and interfaces for using Health Thermometer Service. + * @details Health Thermometer Service data structs and functions. + * @author + * @date 2017-09-20 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _HTS_SERVICE_DEF_H +#define _HTS_SERVICE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "stdint.h" +#include "profile_server.h" +#include "rtl876x.h" + + +/** @defgroup HTS Health Thermometer Service + * @brief Health Thermometer Service + * @details + + The Health Thermometer Service exposes temperature and other data related to a thermometer used for healthcare applications. + Application shall register Health Thermometer Service when initialization through @ref hts_add_service function. + + The Temperature Measurement characteristic is used to send a temperature measurement. + Application can send a temperature measurement through @ref hts_measurement_value_indicate function. + + The Intermediate Temperature characteristic is used to send intermediate temperature values to a device + for display purposes while the measurement is in progress. + Application can send intermediate temperature values through @ref hts_intermediate_temperature_value_notify function. + + The Measurement Interval characteristic is used to enable and control the interval + between consecutive temperature measurements. + Application can send interval through @ref hts_measurement_interval_notify function. + + + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup HTS_Exported_Macros HTS Exported Macros + * @brief + * @{ + */ + +#define HTS_READ_TEMPERATURE_TYPE_VALUE 1 +#define HTS_READ_MEASUREMENT_INTERVAL_VALUE 2 +#define HTS_READ_VALID_RANGE_VALUE 3 + + +#define HTS_WRITE_MEASUREMENT_INTERVAL_VALUE 1 + +/** @defgroup HTS_Notify_Indicate_Info HTS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_ENABLE 1 +#define HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_DISABLE 2 +#define HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_ENABLE 3 +#define HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_DISABLE 4 +#define HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_ENABLE 5 +#define HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_DISABLE 6 +/** @} */ + +/** @defgroup HTS_Measurement_Flag HTS Measurement Flag + * @{ + */ +#define HTS_FLAG_MEASUREMENT_UINT_BIT BIT0 +#define HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT BIT1 +#define HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT BIT2 +/** @} */ + +/** End of HTS_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HTS_Exported_Types HTS Exported Types + * @brief + * @{ + */ + +/** +* @brief Health Thermometer parameter type +*/ +typedef enum +{ + HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG = 1, + HTS_PARAM_MEASUREMENT_TEMPERATUER_VALUE, + HTS_PARAM_MEASUREMENT_TIME_STAMP, + HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, + HTS_PARAM_MEASUREMENT_INTERVAL, + HTS_PARAM_VALID_RANGE +} T_HTS_PARAM_TYPE; + +/** +* @brief Health Thermometer temperature type +*/ +typedef enum +{ + HTS_TEMPERATURE_TYPE_ARMPIT = 1, + HTS_TEMPERATURE_TYPE_BODY, + HTS_TEMPERATURE_TYPE_EAR, + HTS_TEMPERATURE_TYPE_FINGER, + HTS_TEMPERATURE_TYPE_GASTRO_INTESTINAL_TRACT, + HTS_TEMPERATURE_TYPE_MOUTH, + HTS_TEMPERATURE_TYPE_RECTUM, + HTS_TEMPERATURE_TYPE_TOE, + HTS_TEMPERATURE_TYPE_TYMPANUM, + HTS_TEMPERATURE_TYPE_RESERVED, +} T_HTS_TEMPERATURE_TYPE; + +/** +* @brief Health Thermometer Measurement Value Flag +*/ +typedef struct +{ + uint8_t temp_value_units_bit: 1; + uint8_t temp_time_stamp_present_bit: 1; + uint8_t temp_type_present_bit: 1; + uint8_t rfu: 5; +} T_HEALTH_THERMOMETER_MEASUREMENT_VALUE_FLAG; + +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} T_TIME_STAMP; + +typedef struct +{ + uint16_t lower_value; + uint16_t upper_value; +} T_HTS_MEASUREMENT_INTERVAL_VALID_RANGE; + +typedef struct +{ + uint8_t write_index; + uint16_t measurement_interval; +} T_HTS_WRITE_MSG; + +/** +* @brief Health Thermometer Service upper stream message data +*/ +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + T_HTS_WRITE_MSG write; +} T_HTS_UPSTREAM_MSG_DATA; + +/** +* @brief Health Thermometer Service callback data +*/ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_HTS_UPSTREAM_MSG_DATA msg_data; +} T_HTS_CALLBACK_DATA; + +/** End of HTS_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HTS_Exported_Functions HTS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add health thermometer service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hts_id = hts_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t hts_add_service(void *p_func); + + +/** + * @brief Set a health thermometer service parameter. + * + * NOTE: You can call this function with a health thermometer service parameter type and it will set the + * health thermometer service parameter. Health thermometer service parameters are defined + * in @ref T_HTS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Health thermometer service parameter type: @ref T_HTS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_measure_time_stamp.seconds += hts_measurement_interval; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + } + * \endcode + */ + +bool hts_set_parameter(T_HTS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send measurement value indication data . + * Application shall call @ref hts_set_parameter to set intermediate temperature value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_measure_time_stamp.seconds += hts_measurement_interval; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + + hts_measurement_value_indicate(p_parse_value->dw_param[0], hts_id); + } + * \endcode + */ +bool hts_measurement_value_indicate(uint8_t conn_id, uint8_t service_id); + +/** + * @brief Send intermediate temperature notification data. + * Application shall call @ref hts_set_parameter to set intermediate temperature value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT + | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT + | HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + + hts_intermediate_temperature_value_notify(p_parse_value->dw_param[0], hts_id); + + return RESULT_SUCESS; + + } + * \endcode + */ +bool hts_intermediate_temperature_value_notify(uint8_t conn_id, uint8_t service_id); + + +/** + * @brief Send measurement interval notification data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] seconds Measurement interval. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t interval = 90; + hts_measurement_interval_notify(p_parse_value->dw_param[0], hts_id, interval); + } + * \endcode + */ +bool hts_measurement_interval_notify(uint8_t conn_id, uint8_t service_id, uint16_t seconds); + +/** @} End of HTS_Exported_Functions */ + +/** @} End of HTS */ + + +#ifdef __cplusplus +} +#endif + +#endif // _HTS_SERVICE_DEF_H + diff --git a/inc/bluetooth/profile/server/ias.h b/inc/bluetooth/profile/server/ias.h new file mode 100644 index 0000000..3e30cf3 --- /dev/null +++ b/inc/bluetooth/profile/server/ias.h @@ -0,0 +1,102 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ias.h + * @brief Head file for using immediate alert service. + * @details IAS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _IAS_H_ +#define _IAS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +/** @defgroup IAS Immediate Alert Service + * @brief Immediate alert service + * @details + + The Immediate Alert Service (IAS) exposes a control point to allow a peer device to cause the device to immediately alert. + + Immediate Alert Service contains an Alert Level characteristic, to which any value other than "No Alert" being written will trigger alarm in the device. + + Immediate Alert Service generally constitutes a profile collectively with other Services, such as Proximity or Find Me etc., which enables immediate alert in device. + + Application shall register Immediate Alert Service when initialization through @ref ias_add_service function. + + * @{ + */ +/*============================================================================* + * Types + *============================================================================*/ + +/** @defgroup IAS_Exported_Types IAS Exported Types + * @brief + * @{ + */ +/** Message content */ +typedef union +{ + uint8_t write_alert_level; +} T_IAS_UPSTREAM_MSG_DATA; + +/** IAS service data to inform application */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_IAS_UPSTREAM_MSG_DATA msg_data; +} T_IAS_CALLBACK_DATA; + +/** @} End of IAS_Exported_Types */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup IAS_Exported_Functions IAS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add immediate alert service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + ias_id = ias_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID ias_add_service(void *p_func); + +/** @} End of IAS_Exported_Functions */ + +/** @} End of IAS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif //_IAS_H + diff --git a/inc/bluetooth/profile/server/ipss.h b/inc/bluetooth/profile/server/ipss.h new file mode 100644 index 0000000..3589c3d --- /dev/null +++ b/inc/bluetooth/profile/server/ipss.h @@ -0,0 +1,77 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ipss.h + * @brief Head file for using internet protocol support service. + * @details HIDS data structs and external functions declaration. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _IPSS_H_ +#define _IPSS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup IPSS Internet Protocol Support Service + * @brief Internet Protocol Support Service + * @details + + The Internet Protocol Support Profile (IPSP) allows devices to discover and communicate to + other devices that support IPSP. The communication between the devices that support IPSP + is done using IPv6 packets over the Bluetooth Low Energy transport. + + Application shall register IPS service when initialization through @ref ipss_add_service function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup IPSS_Exported_Macros IPSS Exported Macros + * @brief + * @{ + */ +#define GATT_UUID_IPSS 0x1820 + +/** End of IPSS_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup IPSS_Exported_Functions IPSS Exported Functions + * @brief + * @{ + */ + +/** + * @brief add ipss service to application. + * + * @param[in] p_func pointer of app callback function called by profile. + * @return service id auto generated by profile layer. + * @retval service id + */ +uint8_t ipss_add_service(void *p_func); + +/** @} End of IPSS_Exported_Functions */ + +/** @} End of IPSS */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/bluetooth/profile/server/lls.h b/inc/bluetooth/profile/server/lls.h new file mode 100644 index 0000000..4036bbb --- /dev/null +++ b/inc/bluetooth/profile/server/lls.h @@ -0,0 +1,159 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file lls.h + * @brief Head file for using link loss service. + * @details LLS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _LLS_H_ +#define _LLS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + +/** @defgroup LLS Link Loss Service + * @brief Link loss service + * @details + + The Link Loss Service (LLS) defines behavior when a link is lost between two devices. + + The Link Loss Service uses the Alert Level characteristic to cause an alert in the device + when the link is lost. + + Link Loss Service generally constitutes a profile collectively with other Services, such + as Proximity or Find Me etc., which enables device to cause an alert when the link is lost. + + Application shall register link loss service when initialization through @ref lls_add_service function. + + Application can set LLS alert level value through @ref lls_set_parameter function. + + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup LLS_Exported_Macros LLS Service Exported Macros + * @brief + * @{ + */ + +/** @defgroup LLS_Read_Info LLS Read Info + * @brief Read characteristic value. + * @{ + */ +#define LLS_READ_ALERT_LEVEL 1 +/** @} */ + +/** @} End of LLS_Exported_Macros */ + +/*============================================================================* + * Types + *============================================================================*/ + +/** @defgroup LLS_Exported_Types LLS Exported Types + * @brief + * @{ + */ + +/** @defgroup LLS_PARAM_TYPE LLS Parameter Type +* @brief Type of parameters set from application. +* @{ +*/ +typedef enum +{ + LLS_PARAM_LINK_LOSS_ALERT_LEVEL +} T_LLS_PARAM_TYPE; +/** @} */ + +/** @defgroup LLS_Callback_Data LLS Callback Data + * @brief LLS data struct for notification data to application. + * @{ + */ +/** Message content: @ref T_LLS_CALLBACK_DATA */ +typedef union +{ + uint8_t read_value_index; + uint8_t write_alert_level; +} T_LLS_UPSTREAM_MSG_DATA; + +/** LLSdata service data to inform application */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_LLS_UPSTREAM_MSG_DATA msg_data; +} T_LLS_CALLBACK_DATA; +/** @} */ + +/** @} End of LLS_Exported_Types */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup LLS_Exported_Functions LLS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Set a link loss service parameter. + * + * NOTE: You can call this function with a link loss service parameter type and it will set the + * link loss service parameter. Link loss service parameters are defined in @ref T_LLS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Link loss service parameter type: @ref T_LLS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool lls_set_parameter(T_LLS_PARAM_TYPE param_type, uint8_t length, void *p_value); + +/** + * @brief Add link loss service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + lls_id = lls_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID lls_add_service(void *p_func); +/** @} End of LLS_Exported_Functions */ + +/** @} End of LLS*/ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/inc/bluetooth/profile/server/lns.h b/inc/bluetooth/profile/server/lns.h new file mode 100644 index 0000000..95ee94e --- /dev/null +++ b/inc/bluetooth/profile/server/lns.h @@ -0,0 +1,484 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file lns.h + * @brief Variables and interfaces for using Location And Navigation Service. + * @details Location And Navigation Service data structs and functions. + * @author ranhui + * @date 2017-09-20 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _LNS_SERVICE_DEF_H +#define _LNS_SERVICE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + +/** @defgroup LNS Location And Navigation Service + * @brief Location And Navigation service + * @details + + The Location and Navigation Service (LN Service) exposes location and navigation-related data from a + Location and Navigation sensor (Server) intended for outdoor activity applications. + + Application shall register LN Service when initialization through @ref lns_add_service function. + + The LN Feature characteristic shall be used to describe the supported features of the Server. + Reserved for Future Use (RFU) bits in the LN Feature characteristic value shall be set to 0. + + The Location and Speed characteristic is used to send location and speed related data. + + Application can send location and speed related data through @ref lns_location_and_speed_value_notify function. + + The Position Quality characteristic is used to send position quality-related data. + + If the LN Control Point is supported, profiles utilizing this service are required to ensure that the Client configures the LN Control Point characteristic for indications (i.e., via the Client + Characteristic Configuration descriptor) at the first connection. + Support for this characteristic is mandatory if the Server supports any of the features requiring control point procedures. + + The Navigation characteristic is used to send navigation-related data. + Application can send navigation-related data through @ref lns_navigation_value_notify function. + + Application can set the parameters of LNS through @ref lns_set_parameter function. + + + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup LNS_Exported_Macros LNS Exported Macros + * @brief + * @{ + */ + + +/** @defgroup LNS_LN_Feature LNS LN Feature + * @{ + */ +#define LN_FEATURE_INSTANTANEOUS_SPEED_SUPPORTED BIT0 +#define LN_FEATURE_TOTAL_DISTANCE_SUPPORTED BIT1 +#define LN_FEATURE_LOCATION_SUPPORTED BIT2 +#define LN_FEATURE_ELEVATION_SUPPORTED BIT3 +#define LN_FEATURE_HEADING_SUPPORTED BIT4 +#define LN_FEATURE_ROLLING_TIME_SUPPORTED BIT5 +#define LN_FEATURE_UTC_TIME_SUPPORTED BIT6 +#define LN_FEATURE_REMAINING_DISTANCE_SUPPORTED BIT7 +#define LN_FEATURE_REMAINING_VERTICAL_DISTANCE_SUPPORTED BIT8 +#define LN_FEATURE_ESTIMATED_TIME_OF_ARRIVAL_SUPPORTED BIT9 +#define LN_FEATURE_NUMBER_OF_BEACONS_IN_SOLUTION_SUPPORTED BIT10 +#define LN_FEATURE_NUMBER_OF_BEACONS_IN_VIEW_SUPPORTED BIT11 +#define LN_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED BIT12 +#define LN_FEATURE_ESTIMATED_HORIZONTAL_POSITION_ERROR_SUPPORTED BIT13 +#define LN_FEATURE_ESTIMATED_VERTICAL_POSITION_ERROR_SUPPORTED BIT14 +#define LN_FEATURE_HORIZONTAL_DILUTION_OF_PRECISION_SUPPORTED BIT15 +#define LN_FEATURE_VERTICAL_DILUTION_OF_PRECISION_SUPPORTED BIT16 +#define LN_FEATURE_LOCATION_AND_SPEED_CHARACTERISTIC_CONTENT_MASKING_SUPPORTED BIT17 +#define LN_FEATURE_FIX_RATE_SETTING_SUPPORTED BIT18 +#define LN_FEATURE_ELEVATION_SETTING_SUPPORTED BIT19 +#define LN_FEATURE_POSITION_STATUS_SUPPORTED BIT20 +#define LN_FEATURE_RFU BIT21 +/** @} */ + +#define LNS_READ_POSITION_QUALITY_VALUE 1 + +#define LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_ENABLE 1 +#define LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_DISABLE 2 +#define LNS_NOTIFY_INDICATE_CP_ENABLE 3 +#define LNS_NOTIFY_INDICATE_CP_DISABLE 4 +#define LNS_NOTIFY_INDICATE_NAVIGATION_ENABLE 5 +#define LNS_NOTIFY_INDICATE_NAVIGATION_DISABLE 6 + +#define LNS_MAX_CTL_PNT_VALUE 17 + +/** End of LNS_Exported_Macros +* @} +*/ + + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup LNS_Exported_Types LNS Exported Types + * @brief + * @{ + */ + +typedef enum +{ + LNS_LAS_PARAM_INC_FLAG = 0x01, + LNS_LAS_PARAM_INSTANTANEOUS_SPEED, + LNS_LAS_PARAM_TOTAL_DISTANCE, + LNS_LAS_PARAM_LOCATION_LATITUDE, + LNS_LAS_PARAM_LOCATION_LONGITUDE, + LNS_LAS_PARAM_ELEVATION, + LNS_LAS_PARAM_HEADING, + LNS_LAS_PARAM_ROLLING_TIME, + LNS_LAS_PARAM_UTC_TIME, + LNS_LAS_PARAM_POSITION_STATUS, + LNS_LAS_PARAM_SPEED_AND_DISTANCE_FORMAT, + LNS_LAS_PARAM_ELEVATION_SOURCE, + LNS_LAS_PARAM_HEADING_SOURCE, + + LNS_NAVIGATION_PARAM_INC_FLAG = 0x11, + LNS_NAVIGATION_PARAM_BEARING, + LNS_NAVIGATION_PARAM_HEADING, + LNS_NAVIGATION_PARAM_REMAINING_DISTANCE, + LNS_NAVIGATION_PARAM_REMAINING_VERTICAL_DISTANCE, + LNS_NAVIGATION_PARAM_ESTIMATED_TIME_OF_ARRIVAL, + LNS_NAVIGATION_PARAM_POSITION_STATUS, + LNS_NAVIGATION_PARAM_HEADING_SOURCE, + LNS_NAVIGATION_PARAM_NAVIGATION_INDICATOR_TYPE, + LNS_NAVIGATION_PARAM_WAYPOINT_REACHED, + LNS_NAVIGATION_PARAM_DESTINATION_REACHED, + + LNS_PQ_PARAM_INC_FLAG = 0x20, + LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_SOLUTION, + LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_VIEW, + LNS_PQ_PARAM_TIME_TO_FIRST_FIX, + LNS_PQ_PARAM_EHPE, + LNS_PQ_PARAM_EVPE, + LNS_PQ_PARAM_HDOP, + LNS_PQ_PARAM_VDOP, + + LNS_PARAM_LN_FEATURE_SUPPORT = 0x30, + + LNS_CP_PARA_NUMBER_OF_ROUTE = 0x41, + LNS_CP_PARA_NAME_OF_ROUTE, + + LNS_PARAM_CTL_PNT_PROG_CLR = 0x51, +} T_LNS_PARAM_TYPE; + +/* Add all public types here */ +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} T_DATE_TIME; + +/** Position Quality Value Flag */ +typedef struct +{ + uint16_t number_of_beacons_in_solution_present: 1; + uint16_t number_of_beacons_in_view_present: 1; + uint16_t time_to_first_fix_present: 1; + uint16_t ehpe_present: 1; + uint16_t evpe_present: 1; + uint16_t hdop_present: 1; + uint16_t vdop_present: 1; + uint16_t position_status: 2; + uint16_t rfu: 7; +} T_POSITION_QUALITY_VALUE_FLAG; + +/** Position Quality Value */ +typedef struct +{ + T_POSITION_QUALITY_VALUE_FLAG flag; + uint8_t number_of_beacons_in_solution; + uint8_t number_of_beacons_in_view; + uint16_t time_to_first_fix; + uint32_t ehpe; + uint32_t evpe; + uint8_t hdop; + uint8_t vdop; +} T_POSITION_QUALITY_VALUE; + +typedef struct +{ + uint8_t location_and_speed_notify_enable: 1; + uint8_t ln_cp_indicate_enable: 1; + uint8_t navigation_enable: 1; + uint8_t rfu: 5; +} T_LNS_NOTIFY_INDICATE_FLAG; + +typedef struct +{ + uint16_t instantaneous_speed_present: 1; + uint16_t total_distance_present: 1; + uint16_t location_present: 1; + uint16_t elevation_present: 1; + uint16_t heading_present: 1; + uint16_t rolling_time_present: 1; + uint16_t utc_time_present: 1; + uint16_t position_status: 2; + uint16_t speed_and_distance_format: 1; + uint16_t elevation_source: 2; + uint16_t heading_source: 1; + uint16_t rfu: 3; +} T_LOCATION_AND_SPEED_VALUE_FLAG; + +/** Location and Speed Value */ +typedef struct +{ + T_LOCATION_AND_SPEED_VALUE_FLAG flag; + uint16_t instantaneous_speed; + uint32_t total_distance; //uint24 + int32_t location_latitude; //sint32 + int32_t location_longitute; + int32_t elevation;//sint24 + uint16_t heading; + uint8_t rolling_time; + T_DATE_TIME utc_time; +} LOCATION_AND_SPEED_VALUE; + +/** Navigation Value */ +typedef struct +{ + uint16_t remaining_distance_present: 1; + uint16_t remaining_vertical_distance_present: 1; + uint16_t estimated_time_of_arrival_present: 1; + uint16_t position_status: 2; + uint16_t heading_source: 1; + uint16_t navigation_indicator_type: 1; + uint16_t waypoint_reached: 1; + uint16_t destination_reached: 1; + uint16_t rfus: 7; +} T_NAVIGATION_VALUE_FLAG; + +typedef struct +{ + T_NAVIGATION_VALUE_FLAG flag; + uint16_t bearing; + uint16_t heading; + uint32_t reamining_distance; + int32_t reamining_vertical_distance; + T_DATE_TIME estimated_time_of_arrival; +} T_NAVIGATION_VALUE; + +typedef enum +{ + LN_CP_OPCODE_RESERVED = 0, + LN_CP_OPCODE_SET_CUMULATIVE_VALUE = 1, + LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT = 2, + LN_CP_OPCODE_NAVIGATION_CONTROL = 3, + LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES = 4, + LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE = 5, + LN_CP_OPCODE_SELECT_ROUTE = 6, + LN_CP_OPCODE_SET_FIX_RATE = 7, + LN_CP_OPCODE_SET_ELEVATION = 8, + LN_CP_OPCODE_RESPONSE_CODE = 32 +} T_LN_CP_OPCODE; + + +/** + * @brief CSC Control Point data, variable length during connection, max can reach 17 bytes. + * + * CSC Control Point data used to store the Control Point Command recieved from the client. +*/ +typedef struct +{ + uint8_t cur_length; /**< length of current LNS Control Point data, . */ + uint8_t + value[LNS_MAX_CTL_PNT_VALUE]; /**< value of current LNS Control Point data, . */ +} T_LNS_CONTROL_POINT; + +/** @defgroup LNS_Callback_Data LNS Callback Data + * @brief LNS data struct for notification data to application. + * @{ + */ +typedef union +{ + uint32_t cumulative_total_distance; //uint24 + uint16_t mask_location_and_speed; + uint8_t navigation_control; + uint16_t number_of_desired_route; //request_name_of_route + uint16_t select_route_desired_route_number; + uint8_t set_fix_rate; + int32_t set_elevation; //sint24 +} T_LNS_CP_PARAMETER; + +typedef struct +{ + T_LN_CP_OPCODE opcode; + T_LNS_CP_PARAMETER cp_parameter; +} T_LNS_WRITE_MSG; + +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + T_LNS_WRITE_MSG write; +} T_LNS_UPSTREAM_MSG_DATA; + +/** LNS service data to inform application */ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_LNS_UPSTREAM_MSG_DATA msg_data; +} T_LNS_CALLBACK_DATA; +/** @} */ + +/** End of LNS_Exported_Types +* @} +*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup LNS_Exported_Functions LNS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add location and navigation service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + lns_id = lns_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t lns_add_service(void *p_func); + +/** + * @brief Set a Location And Navigation service parameter. + * + * NOTE: You can call this function with a Location And Navigation service parameter type and it will set the + * Location And Navigation service parameter. Location And Navigation service parameters are defined + * in @ref T_LNS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Location And Navigation service parameter type: @ref T_LNS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_LOCATION_AND_SPEED_VALUE_FLAG flag; + flag.instantaneous_speed_present = 1; + flag.total_distance_present = 1; + flag.location_present = 1; + flag.elevation_present = 1; + flag.heading_present = 1; + flag.rolling_time_present = 1; + flag.utc_time_present = 1; + flag.position_status = 1; + flag.speed_and_distance_format = 1; + flag.elevation_source = 1; + flag.heading_source = 1; + flag.rfu = 0; + + lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag); + } + * \endcode + */ +bool lns_set_parameter(T_LNS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Send location and speed value notification data. + * Application shall call @ref lns_set_parameter to set location and speed value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + T_LOCATION_AND_SPEED_VALUE_FLAG flag; + flag.instantaneous_speed_present = 1; + flag.total_distance_present = 1; + flag.location_present = 1; + flag.elevation_present = 1; + flag.heading_present = 1; + flag.rolling_time_present = 1; + flag.utc_time_present = 1; + flag.position_status = 1; + flag.speed_and_distance_format = 1; + flag.elevation_source = 1; + flag.heading_source = 1; + flag.rfu = 0; + + lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag); + + op_result = lns_location_and_speed_value_notify(p_parse_value->dw_param[0], lns_id); + } + * \endcode + */ +bool lns_location_and_speed_value_notify(uint8_t conn_id, T_SERVER_ID service_id); + +/** + * @brief Send navigation value notification data. + * Application shall call @ref lns_set_parameter to set navigation value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + + T_NAVIGATION_VALUE_FLAG flag; + flag.remaining_distance_present = 1; + flag.remaining_vertical_distance_present = 1; + flag.estimated_time_of_arrival_present = 1; + flag.position_status = 1; + flag.heading_source = 1; + flag.navigation_indicator_type = 1; + flag.waypoint_reached = 1; + flag.destination_reached = 1; + flag.rfus = 0; + + lns_set_parameter(LNS_NAVIGATION_PARAM_INC_FLAG, 2, &flag); + + op_result = lns_navigation_value_notify(p_parse_value->dw_param[0], lns_id); + + } + * \endcode + */ +bool lns_navigation_value_notify(uint8_t conn_id, T_SERVER_ID service_id); + +/** @} End of LNS_Exported_Functions */ + +/** @} End of LNS */ + +#ifdef __cplusplus +} +#endif + +#endif // _LNS_SERVICE_DEF_H + diff --git a/inc/bluetooth/profile/server/ota_service.h b/inc/bluetooth/profile/server/ota_service.h new file mode 100644 index 0000000..f4ab8b6 --- /dev/null +++ b/inc/bluetooth/profile/server/ota_service.h @@ -0,0 +1,142 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file ota_service.h +* @brief +* @details +* @author hunter_shuai +* @date 14-July-2015 +* @version v1.0.0 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +#ifndef _OTA_SERVICE_H_ +#define _OTA_SERVICE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" +#include "dfu_api.h" +/** @brief Demo Profile service related UUIDs. */ + +#define GATT_UUID_CHAR_OTA 0xFFD1 //1 +#define GATT_UUID_CHAR_MAC 0xFFD2 //2 +#define GATT_UUID_CHAR_PATCH 0xFFD3 //3 +#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4 +#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5 +#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6 + +#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7 +#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8 +#define GATT_UUID_CHAR_IMAGE_VERSION0 0xFFE0 //mandatory when OTA version >= 1 +#define GATT_UUID_CHAR_IMAGE_VERSION1 0xFFE1 +#define GATT_UUID_CHAR_IMAGE_VERSION2 0xFFE2 +#define GATT_UUID_CHAR_PROTOCOL_TYPE 0xFFF3 + +/** @brief Index of each characteristic in Demo Profile service database. */ +#define BLE_SERVICE_CHAR_OTA_INDEX 0x02 /**< attr write */ +#define BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX 0x04 /**< attr read */ +#define BLE_SERVICE_CHAR_PATCH_INDEX 0x06 /**< attr read */ +#define BLE_SERVICE_CHAR_APP_VERSION_INDEX 0x08 /**< attr read */ +#define BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX 0x0a /**< attr read */ +#define BLE_SERVICE_CHAR_TEST_MODE_INDEX 0x0c /**< attr write */ +#define BLE_SERVICE_CHAR_DEVICE_INFO_INDEX 0x0e /**< attr read */ +#define BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX 0x10 /**< attr write */ +#define BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX 0x12 /**< attr read */ +#define BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX 0x14 /**< attr read */ +#define BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX 0x16 /**< attr read */ +#define BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX 0x18 /**< attr read */ + +/** @brief OTA Read callback data type definition.*/ +#define OTA_READ_CHAR_MAC_ADDRESS_INDEX 0x01 +#define OTA_READ_CHAR_PATCH_INDEX 0x02 +#define OTA_READ_CHAR_APP_VERSION_INDEX 0x03 +#define OTA_READ_CHAR_PATCH_EXTENSION_INDEX 0x04 +#define OTA_READ_CHAR_DEVICE_INFO_INDEX 0x05 +#define OTA_READ_CHAR_IMAGE_VERSION_INDEX 0x06 +#define OTA_READ_CHAR_PROTOCOL_TYPE_INDEX 0x07 + + +/** @brief OTA Write callback data type definition.*/ +#define OTA_WRITE_CHAR_VAL 0x01 /**< switch ota mode write opcode */ +#define OTA_VALUE_ENTER 0x01 /**< switch ota mode write value */ + +/** @brief OTA Write callback data type definition.*/ +#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02 /**< test mode write opcode */ + +/** @brief OTA Write callback data type definition.*/ +#define OTA_WRITE_IMAGE_COUNT_VAL 0x02 /**< image count write opcode */ +#define OTA_VALUE_IMAGE_COUNT_APP_ONLY 0x01 +#define OTA_VALUE_IMAGE_COUNT_PATCH_ONLY 0x02 +#define OTA_VALUE_IMAGE_COUNT_APP_AND_PATCH 0x03 + +#define OTA_CHAR_IMAGE_COUNT_LEN 5 + +#define CHAR2SHORT(p) (((*(p)) & 0xff) + ((*((p)+1)) << 8)) + +typedef struct _T_DFU_DEVICE_INFO +{ + uint8_t ic_type; + uint8_t ota_version; + uint8_t secure_version; + T_OTA_MODE ota_mode; + + uint16_t max_buffer_size; + uint8_t temp_bank_size; //Unit:4K, 0x00:No Limitation of OTA Temp Buffer Size,Only available when Updating Multi Image at a time is supported. + uint8_t rsvd; + uint32_t img_indicator; + +} T_DFU_DEVICE_INFO, * P_DFU_DEVICE_INFO; + +typedef struct _T_OTA_UPDATE_IMAGE_INFO +{ + uint8_t image_count; + uint16_t update_patch_version; + uint16_t update_app_version; +} T_OTA_UPDATE_IMAGE_INFO; + +typedef struct _T_OTA_WRITE_MSG +{ + uint8_t opcode; + union + { + uint8_t value; + T_OTA_UPDATE_IMAGE_INFO update_image_info; + } u; +} T_OTA_WRITE_MSG; + +typedef union _T_OTA_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + T_OTA_WRITE_MSG write; +} T_OTA_UPSTREAM_MSG_DATA; + +/** + * @brief OTA servic data struct for notification data to application. + * + * OTA service data to inform application. +*/ +typedef struct _T_OTA_CALLBACK_DATA +{ + T_SERVICE_CALLBACK_TYPE msg_type; /**< @brief EventId defined upper */ + T_OTA_UPSTREAM_MSG_DATA msg_data; +} T_OTA_CALLBACK_DATA; + + +extern uint8_t ota_add_service(void *pFunc); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/plxs.h b/inc/bluetooth/profile/server/plxs.h new file mode 100644 index 0000000..85a40ce --- /dev/null +++ b/inc/bluetooth/profile/server/plxs.h @@ -0,0 +1,401 @@ +/** +***************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file plxs.h + * @brief Head file for using Pulse Oximeter Service . + * @details Pulse Oximeter Service data types and external functions declaration. + * @author danni + * @date 2018-12-27 + * @version v1.0 + * ************************************************************************************* + */ +/* Define to prevent recursive inclusion */ +#ifndef _PLXS_H +#define _PLXS_H +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" +#include "plxs_config.h" + +/** @defgroup PLXS Pulse Oximeter Service + * @brief Pulse Oximeter Service + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup PLXS_Exported_Macros PLXS Exported Macros + * @brief + * @{ + */ +#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_ENABLE 1 /**< spot check measurement indication cccd enable */ +#define PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_DISABLE 2 /**< spot check measurement indication cccd disable */ +#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_ENABLE 3 /**< continuous measurement notify cccd enable */ +#define PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_DISABLE 4 /**< continuous measurement notify cccd disable */ +#define PLXS_RACP_INDICATION_ENABLE 5 /**< racp indication cccd enable*/ +#define PLXS_RACP_INDICATION_DISABLE 6 /**< racp indication cccd disable*/ + +#define PLXS_SFLOAT_VALUE_NaN 0x07ff /**< not a number */ +#define PLXS_SFLOAT_VALUE_NRes 0x0800 /**< not at this resolution */ +#define PLXS_SFLOAT_VALUE_PlusINFINITY 0x07fe /**< + INFINITY */ +#define PLXS_SFLOAT_VALUE_MinusINFINITY 0x0802 /**< - INFINITY */ +#define PLXS_SFLOAT_VALUE_RFU 0x0801 /**< reserved for future use */ +/** @} End of PLXS_Exported_Macros */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup PLXS_Exported_Types PLXS Exported Types + * @brief + * @{ + */ +/** @brief define PLXS_TIMESTAMP type to store date time data,PLXS_TIMESTAMP[0] = LSO,PLXS_TIMESTAMP[6]=MSO*/ +typedef uint8_t PLXS_TIMESTAMP[7]; + +/** @brief define PLXS_SFLOAT type to store spo2,pr,Pulse Amplitude Index value,PLXS_SFLOAT[0] = LSO,PLXS_SFLOAT[1] = MSO*/ +typedef uint8_t PLXS_SFLOAT[2]; + +/** @brief plxs service parameter type*/ +typedef enum +{ + PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS = 0x01, + PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS, + PLXS_PARAM_FEATURE_FLAGS +} T_PLXS_PARAM_TYPE; + +/** @brief spot check measurement vaule indicate, continuous measurement vaule notify or racp procedure status */ +typedef enum +{ + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE = 0x00,/**< function plxs_spot_check_measurement_value_indicate() never be called and in initialization state*/ + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/ + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_indicate() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/ + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE,/**< function plxs_continuous_measurement_value_notify() never be called and in initialization state*/ + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING,/**< function plxs_continuous_measurement_value_notify() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/ + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE,/**< function plxs_continuous_measurement_value_notify() be called success, and PROFILE_EVT_SEND_DATA_COMPLETE was received*/ + PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE,/**< function plxs_spot_check_measurement_value_store_indicate() never be called and in initialization state*/ + PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING,/**< function plxs_spot_check_measurement_value_store_indicate() be called success, but PROFILE_EVT_SEND_DATA_COMPLETE was not received*/ + PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE,/**< function plxs_spot_check_measurement_value_store_indicate() be called success and PROFILE_EVT_SEND_DATA_COMPLETE was received*/ + PLXS_STATUS_NOT_SUPPORT,/**< status not supported*/ +} T_PLXS_DATA_SEND_STATUS; + +/** @brief APP Return Result List */ +typedef enum +{ + PLXS_APP_RESULT_SUCCESS = 0x00,/**< plx service return result success*/ + PLXS_APP_RESULT_PENDING,/**< if plx service return pending, means that report stored records procedure is in progress,please send data later*/ + PLXS_APP_RESULT_QUEUE_NULL,/**< plx service return result empty*/ + PLXS_APP_RESULT_NOT_SUPPORT,/**< plx service return result procedure not support*/ + PLXS_APP_RESULT_INVALID_VALUE_SIZE,/**< plx service return result invalid value size*/ + PLXS_APP_RESULT_INVALID_TYPE,/**< plx service return result invalid type*/ + PLXS_APP_RESULT_INVALID_OFFSET,/**< plx service return result invalid offset*/ + PLXS_APP_RESULT_POINTER_NULL,/**< plx service return result pointer is null*/ + PLXS_APP_RESULT_FAIL,/**< plx service return result fail for other reasons*/ + PLXS_APP_RESULT_CCCD_NOT_ENABLED/**< plx service return result cccd not enable*/ +} T_PLXS_APP_RESULT; + +/** @brief measurement status bits*/ +typedef struct +{ + uint16_t rfu: 5; + uint16_t measurement_ongoing: 1; + uint16_t early_estimated_data: 1; + uint16_t validated_data: 1; + uint16_t fully_qualified_data: 1; + uint16_t data_from_measurement_storage: 1; + uint16_t data_for_demonstration: 1; + uint16_t data_for_testing: 1; + uint16_t calibration_ongoing: 1; + uint16_t measurement_unavailable: 1; + uint16_t questionable_measurement_detected: 1; + uint16_t invalid_measurement_detected: 1; +} T_PLXS_MEASUREMENT_STATE; +/** @brief device and sensor status bits*/ +typedef struct +{ + uint8_t extended_display_update_ongoing: 1; + uint8_t equipment_malfunction_detected: 1; + uint8_t signal_processing_irregularity_detected: 1; + uint8_t inadequate_signal_detected: 1; + uint8_t poor_signal_detected: 1; + uint8_t low_perfusion_detected: 1; + uint8_t erratic_signal_detected: 1; + uint8_t nonPulsatile_signal_detected: 1; + uint8_t questionable_pulse_detected: 1; + uint8_t signal_analysis_ongoing: 1; + uint8_t sensor_interference_detected: 1; + uint8_t sensor_unconnected_to_user: 1; + uint8_t unknown_sensor_connected: 1; + uint8_t sensor_displaced: 1; + uint8_t sensor_malfunctioning: 1; + uint8_t sensor_disconnected: 1; + uint8_t rfu: 8; +} T_PLXS_DEVICE_AND_SENSOR_STATE; + +/** @brief typedef spot check measurement value*/ +typedef struct +{ + PLXS_SFLOAT spo2; + PLXS_SFLOAT pr; +#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT + PLXS_TIMESTAMP time; +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + T_PLXS_MEASUREMENT_STATE measurement_status; +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status; +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + PLXS_SFLOAT pulse_amplitude_index; +#endif +} T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE; + +/** @brief typedef spo2PR*/ +typedef struct +{ + PLXS_SFLOAT spo2; + PLXS_SFLOAT pr; +} T_SPO2PR; + +/**@brief typedef continuous measurement value*/ +typedef struct +{ + T_SPO2PR spo2pr_normal; + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT + T_SPO2PR spo2pr_fast; +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT + T_SPO2PR spo2pr_slow; +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + T_PLXS_MEASUREMENT_STATE measurement_status; +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + T_PLXS_DEVICE_AND_SENSOR_STATE device_and_sensor_status; +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + PLXS_SFLOAT pulse_amplitude_index; +#endif +} T_PLXS_CONTINUOUS_MEASUREMENT_VALUE; + +/** @brief typedef features value */ +typedef struct +{ + uint16_t supported_features; + +#if PLXS_MEASUREMENT_STATE_SUPPORT + uint16_t measurement_status_support_bits; +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + uint32_t device_and_sensor_status_support_bits; +#endif +} T_PLXS_FEATURES_VALUE; + +/** @} End of PLXS_Exported_Types */ + +/** @defgroup PLXS_Callback_Data PLXS Callback Data + * @brief PLXS data struct for notification data to application. + * @{ + */ +typedef union +{ + uint8_t notify_indicate_index; +} T_PLXS_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_PLXS_UPSTREAM_MSG_DATA msg_data; +} T_PLXS_CALLBACK_DATA; +/** @} End of PLXS_Callback_Data */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup PLXS_Exported_Functions PLXS Exported Functions + * @brief + * @{ + */ +/** + * @brief Add PLX service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void app_le_profile_init() + { + server_init(1); + plxs_srv_id = plxs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID plxs_add_service(void *p_func); +/** + * @brief get plxs parameters such as spot check measurement flags,continuous measurement flags or features supports @ref T_PLXS_PARAM_TYPE + * + * @param[in] param_type @ref T_PLXS_PARAM_TYPE + * @param[in,out] p_value get spot check measurement flags,continuous measurement flags or features supports + * @return plxs_get_parameter result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_PLXS_FEATURES_VALUE plxs_features; + plxs_get_parameter(PLXS_PARAM_FEATURE_FLAGS, &plxs_features); + if (p_parse_value->dw_param[0] == 1) + { + //both measurement status and device sensor status not support + plxs_features.supported_features = plxs_features.supported_features & 0xFFFC; + } + ...... + } + * \endcode + */ +T_PLXS_APP_RESULT plxs_get_parameter(T_PLXS_PARAM_TYPE param_type, void *p_value); +/** + * @brief send plxs spot check measurement characteristic indication + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] p_spot_check_measurement_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE + * @return plxs_spot_check_measurement_value_indicate result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + void test_plxs(void) + { + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value; + ......//plxs_spot_check_measure_value initialization + bool result = plxs_spot_check_measurement_value_indicate(conn_id,plxs_srv_id,&plxs_spot_check_measure_value); + if(result == PLXS_APP_RESULT_SUCCESS) + { + } + } + * \endcode + */ +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT +T_PLXS_APP_RESULT plxs_spot_check_measurement_value_indicate(uint8_t conn_id, uint8_t service_id, + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value); +#endif +/** + * @brief send plxs continuous measurement characteristic notification + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] plxs_continuous_measurement_value @ref T_PLXS_CONTINUOUS_MEASUREMENT_VALUE + * @return plxs_continuous_measurement_value_notify result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + void test_plxs(void) + { + ......//plxs_continuous_measurement_value initialization + bool result = plxs_continuous_measurement_value_notify( conn_id, plxs_srv_id,&plxs_continuous_measurement_value); + if(result == PLXS_APP_RESULT_SUCCESS) + { + PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify notify data send success!"); + } + } + * \endcode + */ +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT +T_PLXS_APP_RESULT plxs_continuous_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_PLXS_CONTINUOUS_MEASUREMENT_VALUE *p_plxs_continuous_measurement_value); +#endif + +/** + * @brief clear flags if procedure fail or disconnect + * + * Example usage + * \code{.c} + void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) + { + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, gap_conn_state, new_state, disc_cause); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + plxs_flags_clear();//when disconnect clear plxs flags + le_adv_start(); + } + break; + } + } + * \endcode + */ +void plxs_flags_clear(void); +/** + * @brief plxs check report data send procedure to enable flow control of notification or indication + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] attribute_index attribute_index + * + * Example usage + * \code{.c} + T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_para->eventId) + { + ...... + case PROFILE_EVT_SEND_DATA_COMPLETE: + ...... + else if (p_para->event_data.send_data_result.service_id == plxs_srv_id) + { + uint8_t conn_id = p_para->event_data.send_data_result.conn_id; + if (p_para->event_data.send_data_result.cause == GAP_SUCCESS) + { + plxs_check_report_data_send_procedure(conn_id, plxs_srv_id,p_para->event_data.send_data_result.attrib_idx); + } + else + { + APP_PRINT_ERROR1("PROFILE_EVT_SEND_DATA_COMPLETE failed,cause %x", p_para->event_data.send_data_result.cause); + } + } + break; + } + } + } + * \endcode + */ +void plxs_check_report_data_send_procedure(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attribute_index); +/** @} End of PLXS_Exported_Functions */ +/** @} End of PLXS */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PULSE_OXIMETER_SERVICE_H */ diff --git a/inc/bluetooth/profile/server/plxs_config.h b/inc/bluetooth/profile/server/plxs_config.h new file mode 100644 index 0000000..e214075 --- /dev/null +++ b/inc/bluetooth/profile/server/plxs_config.h @@ -0,0 +1,128 @@ +/** +***************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file plxs_config.h + * @brief Pulse Oximeter Service configuration file. + * @details Configure the optional characteristic and fields in the Pulse Oximeter Service. + * @author danni + * @date 2018-12-27 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion **/ +#ifndef _PLXS_CONFIG_H_ +#define _PLXS_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup PLXS Pulse Oximeter Service +* @brief Pulse Oximeter Service +* @{ +*/ + +/** @defgroup PLXS_Service_CONFIG PLXS Service Config +* @brief PLXS service configuration file +* @{ +*/ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup PLXS_Common_Exported_Macros PLXS Common Exported Macros + * @{ + */ +#define PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT 1 /**< if this value set to 1 means PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*/ +#define PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT is set to 1 then PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT and PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT must be set to 1*/ +#define PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< flags to show timestamp field support or not*/ +#define PLXS_DEVICE_CLOCK_NOT_SET (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT && 1) /**< flags to show clock set or not*/ + +#define PLXS_MEASUREMENT_STATE_SUPPORT 1 /**< flags to show measurement status field support or not*/ +#define PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT 1 /**< flags to show device and sensor status field support or not*/ +#define PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT 1 /**< flags to show pulse amplitude index field support or not*/ +#define PLXS_MULTIPLE_BONDS_SUPPORT 0 /**< flags to show multiple bonds field support or not*/ + +#define PLXS_CONTINUOUS_MEASUREMENT_SUPPORT 1 /**< if this value set to 1 means PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*/ +#define PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT && 1)/**< flags to show spo2pr fast measurement field support or not*/ +#define PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT && 1)/**< flags to show spo2pr slow measurement field support or not*/ + +#define PLXS_RACP_MAX_NBR_OF_STORED_RECS 30 /**< the maximun records to be stored*/ + +/** @brief The Measurement Status Support field*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT 0x0020 /**< Measurement Ongoing bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_EARLY_ESTIMATED_DATA_SUPPORT 0x0040 /**< Early Estimated Data bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_VALIDATED_DATA_SUPPORT 0x0080 /**< Validated Data bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT 0x0100 /**< Fully Qualified Data bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FROM_MEASUREMENT_STORAGE_SUPPORT 0x0200 /**< Data from Measurement Storage bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FOR_DEMONSTRATION_SUPPORT 0x0400 /**< Data for Demonstration bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_DATA_FOR_TEST_SUPPORT 0x0800 /**< Data for Testing bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_CALIBRATION_ONGOING_SUPPORT 0x1000 /**< Calibration Ongoing bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_MEASUREMENT_UNAVALIABLE_SUPPORT 0x2000 /**< Measurement Unavailable bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_QUESTIONABLE_MEASUREMENT_DETECTED_SUPPORT 0x4000 /**< Questionable Measurement Detected bit supported*/ +#define PLXS_FEATURES_MEASUREMENT_STATUS_INVALID_MEASUREMENT_DETECTED_SUPPORT 0x8000 /**< Invalid Measurement Detected bit supported*/ + +/** @brief define plx service features which measurement status are supported. this macro according user needs to add, + * for example: + * #define PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT|PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT + * means both support PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT and PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT,if you want add other supports, + * please @ref The Measurement Status Support field above + */ +#define PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS (PLXS_FEATURES_MEASUREMENT_STATUS_ONGOING_SUPPORT | PLXS_FEATURES_MEASUREMENT_STATUS_FULLY_QUALIFIED_DATA_SUPPORT) + +/** @brief Device and Sensor Status Support field*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT 0x000001 /**< Extended Display Update Ongoing bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_EQUIPMENT_MALFUNCTION_DETECTED_SUPPORT 0x000002 /**< Equipment Malfunction Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SIGNAL_PROCESSING_IRREGULARITY_DETECTED_SUPPORT 0x000004 /**< Signal Processing Irregularity Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_INADEQUATE_SIGNAL_DETECTED_SUPPORT 0x000008 /**< Inadequate Signal Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_POOR_SIGNAL_DETECTED_SUPPORT 0x000010 /**< Poor Signal Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_LOW_PERFUSION_DETECTED_SUPPORT 0x000020 /**< Low Perfusion Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_ERRATIC_SIGNAL_DETECTED_SUPPORT 0x000040 /**< Erratic Signal Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_NONPULSATILE_SIGNAL_DETECTED_SUPPORT 0x000080 /**< Nonpulsatile Signal Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_QUESTIONABLE_PULSE_DETECTED_SUPPORT 0x000100 /**< Questionable Pulse Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SIGNAL_ANALYSIS_ONGOING_SUPPORT 0x000200 /**< Signal Analysis Ongoing bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_INTERFERENCE_DETECTED_SUPPORT 0x000400 /**< Sensor Interference Detected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_UNCONNECTED_USER_SUPPORT 0x000800 /**< Sensor Unconnected to User bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_UNKNOWN_SENSOR_CONNECTED_SUPPORT 0x001000 /**< Unknown Sensor Connected bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISPLACED_SUPPORT 0x002000 /**< Sensor Displaced bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_MALFUNCTIONING_SUPPORT 0x004000 /**< Sensor Malfunctioning bit supported*/ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT 0x008000 /**< Sensor Disconnected bit supported*/ + +/** @brief define plx service features which device and sensor status are supported.according user needs to add, + * for example: + * #define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT|PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT + * means both support PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT and PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT,if you want add other supports, + * please @ref Device and Sensor Status Support field above + */ +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS (PLXS_FEATURES_DEVICE_SENSOR_STATUS_EXTENDED_DISPLAY_UPDATE_ONGOING_SUPPORT | PLXS_FEATURES_DEVICE_SENSOR_STATUS_SENSOR_DISCONNECTED_SUPPORT) + +/** @defgroup PLXS_Service_ATTI_INDEX PLXS Service attribute index +* @brief PLXS Service attribute index +* @{ +*/ +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT +#define PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX 0x02 +#define PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX 0x03 +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT +#define PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + 2 )//0x05 +#define PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + 3 )//0x06 +#endif + +#define PLXS_CHAR_FEATURE_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 2)//0x05//0x08 + +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT +#define PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 4)//0x07//0x0A +#define PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX ((PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT*3) + (PLXS_CONTINUOUS_MEASUREMENT_SUPPORT*3)+ 5)//0x08//0x0B +#endif +/** @} End of PLXS_Service_ATTI_INDEX */ +/** @} End of PLXS_Common_Exported_Macros */ +/** @} End of PLXS_Service_CONFIG */ +/** @} End of PLXS */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/inc/bluetooth/profile/server/rcu_dfu_service.h b/inc/bluetooth/profile/server/rcu_dfu_service.h new file mode 100644 index 0000000..02a522e --- /dev/null +++ b/inc/bluetooth/profile/server/rcu_dfu_service.h @@ -0,0 +1,256 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file dfu_service.h +* @brief +* @details +* @author ken_mei +* @date 02-09-2016 +* @version v1.0.0 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +#ifndef _DFU_SERVICE_H_ +#define _DFU_SERVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" +#include "flash_device.h" + +#define GATT_UUID128_DFU_PACKET 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x63, 0x00, 0x00 +#define GATT_UUID128_DFU_CONTROL_POINT 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0x87, 0x64, 0x00, 0x00 + +#define DFU_OPCODE_MIN 0x00 +#define DFU_OPCODE_START_DFU 0x01 +#define DFU_OPCODE_RECEIVE_FW_IMAGE_INFO 0x02 +#define DFU_OPCODE_VALID_FW 0x03 +#define DFU_OPCODE_ACTIVE_IMAGE_RESET 0x04 +#define DFU_OPCODE_SYSTEM_RESET 0x05 +#define DFU_OPCODE_REPORT_TARGET_INFO 0x06 +#define DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ 0x07 + +#define DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE 0x08 +#define DFU_OPCODE_BUFFER_CHECK_EN 0x09 /*report current ota function version information*/ +#define DFU_OPCODE_REPORT_BUFFER_CRC 0x0a /*report current buffer CRC*/ + +#define DFU_OPCODE_RECEIVE_IC_TYPE 0x0b +#define DFU_OPCODE_COPY_IMG 0x0c +#define DFU_OPCODE_MAX 0x0d + + +#define DFU_OPCODE_NOTIF 0x10 + +/*length of each control point procedure*/ +#define DFU_LENGTH_START_DFU (1+12) +#define DFU_LENGTH_RECEIVE_FW_IMAGE_INFO (1+2+4) +#define DFU_LENGTH_VALID_FW (1+2) +#define DFU_LENGTH_ACTIVE_IMAGE_RESET 0x01 +#define DFU_LENGTH_SYSTEM_RESET 0x01 +#define DFU_LENGTH_REPORT_TARGET_INFO (1+2) +#define DFU_LENGTH_PKT_RX_NOTIF_REQ (1+2) +#define DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ (1+2+2+2+2) + +#define DFU_NOTIFY_LENGTH_ARV 3 +#define DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO (3+2+4) +#define DFU_NOTIFY_LENGTH_PKT_RX_NOTIF (3+2) + + +#define INDEX_DFU_PACKET_VALUE 0x02 +#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04 + +#define DFU_OPCODE_MIN 0x00 +#define DFU_OPCODE_START_DFU 0x01 +#define DFU_OPCODE_RECEIVE_FW_IMAGE_INFO 0x02 +#define DFU_OPCODE_VALID_FW 0x03 +#define DFU_OPCODE_ACTIVE_IMAGE_RESET 0x04 +#define DFU_OPCODE_SYSTEM_RESET 0x05 +#define DFU_OPCODE_REPORT_TARGET_INFO 0x06 +#define DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ 0x07 +#define DFU_OPCODE_PKT_RX_NOTIFICATION_VOICE 0x08 +#define DFU_OPCODE_REPORT_FUNCTION_TYPE 0x09 /*report current ota function version information*/ +#define DFU_OPCODE_REPORT_BUFFER_SIZE 0x0a /*report current buffer size information*/ +//#define DFU_OPCODE_REPORT_BUFFER_CRC 0x0b /*report current buffer CRC*/ +#define DFU_OPCODE_INDICATE_BUFFER_IS_VALID 0x0c /*indicate current buffer data if valid*/ +//#define DFU_OPCODE_RECEIVE_IC_TYPE 0x0d + +//#define DFU_OPCODE_MAX 0x0e + +#define INDEX_DFU_PACKET_VALUE 0x02 +#define INDEX_DFU_CONTROL_POINT_CHAR_VALUE 0x04 +#define INDEX_DFU_CHAR_CCCD_INDEX 0x05 + +#define DFU_OPCODE_NOTIFICATION 0x10 +//------------------------DFU_LENGTH DEFINE------------------------------ + +#define DFU_ARV_SUCCESS 0x01 +#define DFU_ARV_FAIL_INVALID_PARAMETER 0x02 +#define DFU_ARV_FAIL_OPERATION 0x03 +#define DFU_ARV_FAIL_DATA_SIZE_EXCEEDS_LIMIT 0x04 +#define DFU_ARV_FAIL_CRC_ERROR 0x05 +#define DFU_ARV_FAIL_LENGTH_ERROR 0x06 +#define DFU_ARV_FAIL_PROG_ERROR 0x07 +#define DFU_ARV_FAIL_ERASE_ERROR 0x08 +#define DFU_ARV_FAIL_SYS_STATE_ERROR 0x09 + + +#define DFU_NOTIFY_LENGTH_FUNC_VERSION (1+1+1+2) +#define DFU_NOTIFY_LENGTH_BUFFER_SIZE (1+1+1+4) +#define DFU_NOTIFY_LENGTH_BUFFER_CRC (1+1+1+2) +#define DFU_NOTIFY_LENGTH_BUFFER_IS_VALID (1+1)/*opCode + valid flag*/ + +typedef struct _T_START_DFU_PARA +{ + uint8_t ic_type; + uint8_t secure_version; + union + { + uint16_t value; + struct + { + uint16_t xip: 1; // payload is executed on flash + uint16_t enc: 1; // all the payload is encrypted + uint16_t load_when_boot: 1; // load image when boot + uint16_t enc_load: 1; // encrypt load part or not + uint16_t enc_key_select: 3; // referenced to ENC_KEY_SELECT + uint16_t not_ready : 1; //for copy image in ota + uint16_t not_obsolete : 1; //for copy image in ota + uint16_t rsvd: 7; + }; + } ctrl_flag; + uint16_t signature; + uint16_t crc16; + uint32_t image_length; +} T_START_DFU_PARA; + +typedef struct _T_PKT_RX_NOTIF_REQ +{ + uint16_t packet_num; +} T_PKT_RX_NOTIF_REQ; + + +typedef struct _T_DFU_CTRL_POINT +{ + uint8_t opcode; + union + { + T_START_DFU_PARA start_dfu; + T_PKT_RX_NOTIF_REQ pkt_rx_notify_req; + } p; +} T_DFU_CTRL_POINT, * P_DFU_CTRL_POINT; + +/** +* @note: the definition of this struct is accordant with rom define, and if you +* change the order of members, it will cause crc error when ota complete. +*/ +typedef struct +{ + uint32_t origin_image_version; + + uint32_t nCurOffSet; + uint32_t image_total_length; + + uint8_t ic_type; + uint8_t secure_version; + union + { + uint16_t value; + struct + { + uint16_t xip: 1; // payload is executed on flash + uint16_t enc: 1; // all the payload is encrypted + uint16_t load_when_boot: 1; // load image when boot + uint16_t enc_load: 1; // encrypt load part or not + uint16_t enc_key_select: 3; // referenced to ENC_KEY_SELECT + uint16_t not_ready : 1; //for copy image in ota + uint16_t not_obsolete : 1; //for copy image in ota + uint16_t rsvd: 7; + }; + } ctrl_flag; + uint16_t signature; + uint16_t crc16; + uint32_t image_length; + + bool ota_conn_para_upd_in_progress; + uint8_t mtu_size; + bool is_dfu_progressing; +} TDFU_CB; + + +/*Notifications defined here*/ + +typedef struct _TNOTIFICATION_TARGET_IMAGE_INFO +{ + + uint16_t nOrigFwVersion; + uint32_t nImageUpdateOffset; +} TNOTIFICATION_TARGET_IMAGE_INFO; + +typedef struct _TNOTIFICATION_REPORT_PKT_NUM +{ + uint16_t PacketNum; +} TNOTIFICATION_REPORT_PKT_NUM; + +typedef struct _TNOTIFICATION_REPORT_OTA_FUNC +{ + uint16_t OtaFuncVersion; + uint32_t invalid; +} TNOTIFICATION_REPORT_OTA_FUNC; + + +typedef enum _TNOTIFICATION_REPORT_FUNC_VERSION +{ + NORMAL_FUNCTION = 0x0000, /*normal function*/ + IMAGE_CHECK_FUNCTION = 0x0001 /*image check function*/ +} TNOTIFICATION_REPORT_FUNC_VERSION; + +typedef enum _DFU_BUFFER_IS_VALID +{ + DFU_BUFFER_VALID = 0x00, + DFU_BUFFER_INVALID = 0x01 +} DFU_BUFFER_IS_VALID; + +typedef struct _DFUNotification +{ + uint8_t opCode; + uint8_t reqOpCode; + uint8_t respValue; + union + { + TNOTIFICATION_TARGET_IMAGE_INFO NotifyTargetImageInfo; + TNOTIFICATION_REPORT_PKT_NUM NotifyPktNum; + } p; +} TDFUNotification, * PDFUNotification; + +#define DFU_NOTIFY_ENABLE 1 +#define DFU_NOTIFY_DISABLE 2 +typedef union _TDFU_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; + uint8_t write_value_index; +} TDFU_UPSTREAM_MSG_DATA; +/** Dfu service data to inform application */ +typedef struct _TDFU_CALLBACK_DATA +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + TDFU_UPSTREAM_MSG_DATA msg_data; +} TDFU_CALLBACK_DATA; + +/*============================================================================* + * Dfu Interface API + *============================================================================*/ +extern uint8_t dfu_add_service(void *p_func); +extern bool dfu_check_working(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/rcu_ota_service.h b/inc/bluetooth/profile/server/rcu_ota_service.h new file mode 100644 index 0000000..a3bce93 --- /dev/null +++ b/inc/bluetooth/profile/server/rcu_ota_service.h @@ -0,0 +1,153 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file ota_service.h +* @brief +* @details +* @author hunter_shuai +* @date 14-July-2015 +* @version v1.0.0 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +#ifndef _OTA_SERVICE_H_ +#define _OTA_SERVICE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" +/** @brief Demo Profile service related UUIDs. */ + +#define GATT_UUID_CHAR_OTA 0xFFD1 //1 +#define GATT_UUID_CHAR_MAC 0xFFD2 //2 +#define GATT_UUID_CHAR_PATCH 0xFFD3 //3 +#define GATT_UUID_CHAR_APP_VERSION 0xFFD4 //4 +#define GATT_UUID_CHAR_PATCH_EXTENSION 0xFFD5 //5 +#define GATT_UUID_CHAR_TEST_MODE 0xFFD8 //6 + +#define GATT_UUID_CHAR_DEVICE_INFO 0xFFF1 //7 +#define GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE 0xFFF2 //8 +#define GATT_UUID_CHAR_IMAGE_VERSION 0xFFE0 + + +//vendor featture for some customers + +#define EFLASH_SAVE_OTA_PROCESSING_OFFSET 0x208 + + + + +/** @brief Index of each characteristic in Demo Profile service database. */ +#define BLE_SERVICE_CHAR_OTA_INDEX 0x02 +#define BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX 0x04 +#define BLE_SERVICE_CHAR_PATCH_INDEX 0x06 +#define BLE_SERVICE_CHAR_APP_VERSION_INDEX 0x08 +#define BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX 0x0a +#define BLE_SERVICE_CHAR_TEST_MODE_INDEX 0x0c +#define BLE_SERVICE_CHAR_DEVICE_INFO_INDEX 0x0e +#define BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX 0x10 +#define BLE_SERVICE_CHAR_IMAGE_VERSION_INDEX 0x12 + +/** @brief OTA Write callback data type definition.*/ +#define OTA_WRITE_CHAR_VAL 0x01 +#define OTA_WRITE_TEST_MODE_CHAR_VAL 0x02 + +/** @brief OTA Write callback data type definition.*/ +#define OTA_WRITE_CHAR_VAL 0x01 +#define OTA_VALUE_ENTER 0x01 + +#define OTA_WRITE_IMAGE_COUNT_VAL 0x02 +#define OTA_VALUE_IMAGE_COUNT_APP_ONLY 0x01 +#define OTA_VALUE_IMAGE_COUNT_PATCH_ONLY 0x02 +#define OTA_VALUE_IMAGE_COUNT_APP_AND_PATCH 0x03 + +typedef struct _TOTA_UPDATE_IMAGE_INFO +{ + uint8_t image_count; + uint16_t update_patch_version; + uint16_t update_app_version; +} TOTA_UPDATE_IMAGE_INFO; + +typedef struct _T_DFU_DEVICE_INFO +{ + uint8_t ictype; + uint8_t ota_version; + uint8_t secure_version; + + union + { + uint8_t value; + struct + { + uint8_t buffercheck: 1; // 1:support, 0:don't support + uint8_t aesflg: 1; // 1:aes encrypt when ota, 0:not encrypt + uint8_t aesmode: 1; // 1:all data is encrypted, 0:only encrypt 16byte + //uint8_t verify_algo: 1; // 1:sha256, 0:crc + uint8_t copy_img: 1; //1:support ,0:don't support + uint8_t multi_img: 1; //1:support(update multi img at a time) ,0:don't support(one img at a time) + uint8_t rsvd: 3; + }; + } mode; + + uint16_t maxbuffersize; + uint16_t res; + + uint32_t img_indicator; +} T_DFU_DEVICE_INFO, * P_DFU_DEVICE_INFO; + + +#define OTA_UPDATE_IMAGE_INFO_LEN 5 + +#define CHAR2SHORT(p) (((*(p)) & 0xff) + ((*((p)+1)) << 8)) + +typedef struct _TOTA_WRITE_MSG +{ + uint8_t opcode; + union + { + uint8_t value; + TOTA_UPDATE_IMAGE_INFO update_image_info; + } u; +} TOTA_WRITE_MSG; + +typedef union _TOTA_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + TOTA_WRITE_MSG write; +} TOTA_UPSTREAM_MSG_DATA; + +/** + * @brief OTA servic data struct for notification data to application. + * + * OTA service data to inform application. +*/ +typedef struct _TOTA_CALLBACK_DATA +{ + T_SERVICE_CALLBACK_TYPE msg_type; /**< @brief EventId defined upper */ + TOTA_UPSTREAM_MSG_DATA msg_data; +} TOTA_CALLBACK_DATA; + + +extern uint8_t ota_add_service(void *p_func); + +typedef enum _BANK_NUM +{ + BANK0 = 0, + BANK1 = 1, + BANK_UNKNOWN = 2 +} BANK_NUM; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/rscs.h b/inc/bluetooth/profile/server/rscs.h new file mode 100644 index 0000000..e34b72d --- /dev/null +++ b/inc/bluetooth/profile/server/rscs.h @@ -0,0 +1,446 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file rsc_service.h + * @brief Head file for using Running Speed and Cadence Service. + * @details RSC data structs and external functions declaration. + * @author ethan_su + * @date 2017-10-10 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _RSCS_SERVICE_DEF_H +#define _RSCS_SERVICE_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + + +/** @defgroup RSCS Running Speed and Cadence Service + * @brief Running Speed and Cadence Service + * @details + + The Running Speed and Cadence (RSC) Service exposes speed, cadence and other data related to fitness applications + such as the stride length and the total distance the user has traveled while using the Running Speed and Cadence sensor (Server). + + Application shall register Running Speed and Cadence service when initialization through @ref rscs_add_service function. + + The RSC Measurement characteristic is used to send speed and cadence measurements. Included in the characteristic value are + a Flags field (for showing the presence of optional fields and, if supported by the Server, whether the user is walking or running), + an Instantaneous Speed field, an Instantaneous Cadence field, depending upon the contents of the Flags field, an Instantaneous + Stride Length field and a Total Distance field. + + The Server measures the instantaneous speed at which the user is moving. The cadence represents the number of times per minute + the foot with the sensor hits the ground. The stride length represents the distance between two successive contacts of the same foot + to the ground and the total distance represents the distance the user has travelled with the sensor since the last reset of the total + distance. + + Application can set a running speed and cadence service parameter through @ref rscs_set_parameter function. + + Application can get a running speed and cadence service parameter through @ref rscs_get_parameter function. + + After set service parameter, running speed and cadence service can send notification data to client through @ref rscs_meas_value_notify function. + + Running speed and cadence service can indicate result of calibration to client through @ref rscs_calib_resutl_indicate function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup RSCS_Exported_Macros RSCS Exported Macros + * @brief + * @{ + */ + +/** @defgroup RSCS_Measurement_Flag_Bit_Mask RSC Measurement Flag Bit Mask + * @brief RSC measurement 'Flags' present bit mask. + * @{ + */ +#define RSCS_INC_STRIDE_LENGTH_MASK (1) /**< Instantaneous Stride Length Present. */ +#define RSCS_INC_TOTAL_DISTANCE_MASK (1<<1) /**< Total Distance Present. */ +#define RSCS_INC_RUNNING_STATUS_MASK (1<<2) /**< Walking or Running Status bits. */ +#define RSCS_INC_ALL_PRESENTS (0x07) +/** @} */ + +/** @defgroup RSCS_Feature_Bit_Mask RSC Feature Bit Mask + * @brief RSC features bit mask. + * @{ + */ +#define RSCS_SUPPORT_STRIDE_LENGTH_MASK (1) +#define RSCS_SUPPORT_TOTAL_DISTANCE_MASK (1<<1) +#define RSCS_SUPPORT_RUNNING_STATUS_MASK (1<<2) +#define RSCS_SUPPORT_CALIBRATE_MASK (1<<3) +#define RSCS_SUPPORT_MULTI_SENSOR_MASK (1<<4) +#define RSCS_ALL_FEATURE_SUPPORTED (0x1F) +/** @} */ + +/** @defgroup RSCS_Sensor_Location_Bit_Mask RSC Sensor Location Bit Mask + * @brief RSC supported sensor location bit mask. + * @{ + */ +#define RSCS_SENS_LOC_OTHER_MASK (1) +#define RSCS_SENS_LOC_TOP_OF_SHOE_MASK (1<<1) +#define RSCS_SENS_LOC_IN_SHOE_MASK (1<<2) +#define RSCS_SENS_LOC_HIP_MASK (1<<3) +#define RSCS_SENS_LOC_FRONT_WHEEL_MASK (1<<4) +#define RSCS_SENS_LOC_LEFT_CRANK_MASK (1<<5) +#define RSCS_SENS_LOC_RIGHT_CRANK_MASK (1<<6) +#define RSCS_SENS_LOC_LEFT_PEDAL_MASK (1<<7) +#define RSCS_SENS_LOC_RIGHT_PEDAL_MASK (1<<8) +#define RSCS_SENS_LOC_FRONT_HUB_MASK (1<<9) +#define RSCS_SENS_LOC_REAR_DROPOUT_MASK (1<<10) +#define RSCS_SENS_LOC_CHAINSTAY_MASK (1<<11) +#define RSCS_SENS_LOC_REAR_WHEEL_MASK (1<<12) +#define RSCS_SENS_LOC_REAR_HUB_MASK (1<<13) +#define RSCS_SENS_LOC_CHEST_MASK (1<<14) +#define RSCS_ALL_SENS_LOC_SUPPORTED (0x7FFF) +/** @} */ + +/** @defgroup RSCS_Control_Point_OpCodes RSC Control Point OpCodes + * @brief Control Point OpCodes + * @{ + */ +#define RSCS_CP_OPCODE_RESERVED 0x00 +#define RSCS_CP_OPCODE_SET_CUMULATIVE 0x01 +#define RSCS_CP_OPCODE_START_CALIBRATION 0x02 +#define RSCS_CP_OPCODE_UPDATE_SENS_LOC 0x03 +#define RSCS_CP_OPCODE_REQ_SENS_LOC_LIST 0x04 +#define RSCS_CP_OPCODE_RSP_CODE 0x10 +/** @} */ + +/** @defgroup RSCS_Control_Point_Response_Codes RSC Control Point Response Codes + * @brief Control Point Response Codes + * @{ + */ +#define RSCS_CP_RSPCODE_RESERVED 0x00 +#define RSCS_CP_RSPCODE_SUCCESS 0x01 +#define RSCS_CP_RSPCODE_OPCODE_UNSUPPORT 0x02 +#define RSCS_CP_RSPCODE_INVALID_PARAMETER 0x03 +#define RSCS_CP_RSPCODE_OPERATION_FAILED 0x04 +/** @} */ + +/** @defgroup RSCS_Error_Codes RSC Error Codes + * @brief Error codes defined in RSC spec + * @{ + */ +#define RSCS_ERR_PROC_ALREADY_IN_PROG 0x80 +#define RSCS_ERR_CCCD_IMPROPERLY_CFG 0x81 +/** @} */ + +/** @defgroup RSCS_Data_Length RSC Data Length + * @brief Max bytes of RSC Measurement data and RSC Control Point data + * @{ + */ +#define RSCS_MAX_MEASUREMENT_VALUE 10 +#define RSCS_MAX_CTL_PNT_VALUE 18 +/** @} */ + + +/** @defgroup RSCS_Read_Info RSC Read Info + * @brief Parameter for reading characteristic value. + * @{ + */ +#define RSCS_READ_RSCS_FEATURE 1 +#define RSCS_READ_SENSOR_LOCATION 2 +/** @} */ + +/** @defgroup RSCS_Notify_Indicate_Info RSCS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE 1 +#define RSCS_NOTIFY_INDICATE_MEASUREMENT_DISABLE 2 +#define RSCS_NOTIFY_INDICATE_SC_CP_ENABLE 3 +#define RSCS_NOTIFY_INDICATE_SC_CP_DISABLE 4 +/** @} */ + +/** End of RSCS_Exported_Macros +* @} +*/ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup RSCS_Exported_Types RSCS Exported Types + * @brief + * @{ + */ + +/** +* @brief RSC service parameter type +*/ +typedef enum +{ + RSCS_PARAM_CSCS_FEATURE = 0x01, + RSCS_PARAM_INC_FLAG, + RSCS_PARAM_SPEED, + RSCS_PARAM_CADENCE, + RSCS_PARAM_STRIDE_LENGTH, + RSCS_PARAM_TOTALDISTANCE, + RSCS_PARAM_CTL_PNT_PROG_CLR, + RSCS_PARAM_SENSOR_LOC, +} T_RSCS_PARAM_TYPE; + + +/** @defgroup RSCS_Sensor_Locations RSC Sensor Locations + * @brief All RSC sensor locations defined in spec + * @{ + */ +typedef enum +{ + RSCS_SENSOR_LOC_OTHER = 0, + RSCS_SENSOR_LOC_TOP_OF_SHOE = 1, + RSCS_SENSOR_LOC_IN_SHOE = 2, + RSCS_SENSOR_LOC_HIP = 3, + RSCS_SENSOR_LOC_FRONT_WHEEL = 4, + RSCS_SENSOR_LOC_LEFT_CRANK = 5, + RSCS_SENSOR_LOC_RIGHT_CRANK = 6, + RSCS_SENSOR_LOC_LEFT_PEDAL = 7, + RSCS_SENSOR_LOC_RIGHT_PEDAL = 8, + RSCS_SENSOR_LOC_FRONT_HUB = 9, + RSCS_SENSOR_LOC_REAR_DROPOUT = 10, + RSCS_SENSOR_LOC_CHAINSTAY = 11, + RSCS_SENSOR_LOC_REAL_WHEEL = 12, + RSCS_SENSOR_LOC_REAL_HUB = 13, + RSCS_SENSOR_LOC_CHEST = 14, + RSCS_SENSOR_LOC_MAX +} TRSCSensorLocation; +/** @} */ + +/** @defgroup RSCS_Measurement_Data RSC Measurement Data + * @brief RSC measurement data, variable length during connection, max can reach 10 bytes + * @{ + */ +typedef struct +{ + uint8_t cur_length; /**< length of current RSC measurement data. */ + uint8_t value[RSCS_MAX_MEASUREMENT_VALUE]; /**< value of current RSC measurement data. */ +} T_RSCS_MEASUREMENT; +/** @} */ + +/** @defgroup RSCS_Control_Point_Data RSC Control Point Data + * @brief RSC Control Point data, variable length during connection, max can reach 18 bytes + * @{ + */ +typedef struct +{ + uint8_t cur_length; /**< length of current RSC Control Point data, . */ + uint8_t value[RSCS_MAX_CTL_PNT_VALUE]; /**< value of current RSC Control Point data, . */ +} T_RSCS_CONTROL_POINT; +/** @} */ + + +/** @defgroup RSCS_Callback_Data RSCS Callback Data + * @brief RSC data struct for notification data to application. + * @{ + */ +typedef union +{ + uint8_t sensor_location_value; + uint32_t cumulative_value; +} T_RSCS_CP_PARAMETER; + +typedef struct +{ + uint8_t opcode; //!< ref: @ref RSCS_Control_Point_OpCodes + T_RSCS_CP_PARAMETER cp_parameter; +} T_RSCS_WRITE_MSG; + +typedef union +{ + uint8_t notification_indification_index; //!< ref: @ref RSCS_Notify_Indicate_Info + uint8_t read_value_index; //!< ref: @ref RSCS_Read_Info + T_RSCS_WRITE_MSG write; +} T_RSCS_UPSTREAM_MSG_DATA; + +/** RSC service data to inform application */ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_RSCS_UPSTREAM_MSG_DATA msg_data; +} T_RSCS_CALLBACK_DATA; +/** @} */ + +/** End of RSCS_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup RSCS_Exported_Functions RSCS Exported Functions + * @brief + * @{ + */ + + +/** + * @brief Add Running Speed and Cadence Service. + * + * @param[in] p_func Callback when service attribute was read/write. + * + * @return service id @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + rscs_id = rscs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID rscs_add_service(void *p_func); + + +/** + * @brief Set a Running Speed and Cadence Service parameter. + * + * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will set the + * Running Speed and Cadence Service parameter. Running Speed and Cadence Service parameters are defined + * in @ref T_RSCS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint32_t total_distance = p_parse_value->dw_param[0]; + bool op_result; + + op_result = rscs_set_parameter(RSCS_PARAM_TOTALDISTANCE, 4, (uint8_t*)&total_distance); + + if ( op_result ) + { + rscs_get_parameter( RSCS_PARAM_TOTALDISTANCE, &total_distance ); + data_uart_print("set total_distance = %d\r\n", total_distance); + } + else + { + data_uart_print("rscs_set_parameter total_distance failed\r\n"); + } + } + * \endcode + */ +bool rscs_set_parameter(T_RSCS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Get a Running Speed and Cadence Service parameter. + * + * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will get the + * parameter. Running Speed and Cadence Service parameters are defined in @ref T_RSCS_PARAM_TYPE. + * + * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE + * @param[in] p_value Pointer to data to read. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t bFlag; + + rscs_get_parameter(RSCS_PARAM_INC_FLAG, &bFlag); + } + * \endcode + */ +bool rscs_get_parameter(T_RSCS_PARAM_TYPE param_type, void *p_value); + +/** + * @brief Send Running Speed and Cadence Service value notification data. + * Application shall call @ref rscs_set_parameter to set value first, + * and then call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + uint8_t flag = RSCS_INC_ALL_PRESENTS; + + rscs_set_parameter(RSCS_PARAM_INC_FLAG, 1, &flag); + + op_result = rscs_meas_value_notify(p_parse_value->dw_param[0], rscs_id); + + if ( op_result ) + { + data_uart_print("Notify RSC measurement value succeed\r\n"); + } + else + { + data_uart_print("Notify RSC measurement value failed\r\n"); + } + + } + * \endcode + */ +bool rscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id); + +/** + * @brief Send Running Speed and Cadence Service value indication data, + * send indication of result of calibration to client. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] result calibration result. + * + * @return none; + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t result = p_parse_value->dw_param[1]; + rscs_calib_resutl_indicate(conn_id, rscs_id, result); + data_uart_print("cmd_rscs_calib_result_indicate result= %d\r\n", result); + } + * \endcode + */ +void rscs_calib_resutl_indicate(uint8_t conn_id, T_SERVER_ID service_id, bool result); + + +/** @} End of RSCS_Exported_Functions */ + + +/** @} End of RSCS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RSCS_DEF_H */ diff --git a/inc/bluetooth/profile/server/simple_ble_config.h b/inc/bluetooth/profile/server/simple_ble_config.h new file mode 100644 index 0000000..04b7fb7 --- /dev/null +++ b/inc/bluetooth/profile/server/simple_ble_config.h @@ -0,0 +1,63 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file simple_ble_config.h + * @brief This file includes common constants or types for Simple BLE service/client. + * And some optional feature may be defined in this file. + * @details + * @author Ethan + * @date 2016-02-18 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion **/ +#ifndef _SIMPLE_BLE_CONFIG_H_ +#define _SIMPLE_BLE_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @defgroup SIMP_Service Simple Ble Service + * @brief Simple BLE service + * @{ + */ + +/** @defgroup SIMP_Service_CONFIG SIMP Service Config + * @brief Simple BLE service configuration file + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SIMP_Common_Exported_Macros SIMP Service Config Exported Constants + * @brief + * @{ + */ + +/** @defgroup SIMP_UUIDs SIMP UUIDs + * @brief Simple BLE Profile UUID definitions + * @{ + */ +#define GATT_UUID_SIMPLE_PROFILE 0xA00A +#define GATT_UUID_CHAR_SIMPLE_V1_READ 0xB001 +#define GATT_UUID_CHAR_SIMPLE_V2_WRITE 0xB002 +#define GATT_UUID_CHAR_SIMPLE_V3_NOTIFY 0xB003 +#define GATT_UUID_CHAR_SIMPLE_V4_INDICATE 0xB004 +/** @} End of SIMP_UUIDs */ + +/** @} End of SIMP_Common_Exported_Macros */ + +/** @} End of SIMP_Service_CONFIG */ + +/** @} End of SIMP_Service */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/simple_ble_service.h b/inc/bluetooth/profile/server/simple_ble_service.h new file mode 100644 index 0000000..93d69b8 --- /dev/null +++ b/inc/bluetooth/profile/server/simple_ble_service.h @@ -0,0 +1,205 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file simple_ble_service.h + * @brief Demonstration of how to implement a self-definition service. + * @details Demonstration of different kinds of service interfaces. + * @author + * @date + * @version + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _SIMPLE_BLE_SERVICE_H_ +#define _SIMPLE_BLE_SERVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include +#include + + +/** @defgroup SIMP_Service Simple Ble Service + * @brief Simple BLE service + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SIMP_Service_Exported_Macros SIMP Service Exported Macros + * @brief + * @{ + */ + +/** @defgroup SIMP_Service_Application_Parameters SIMP Service Application Parameters + * @brief Type of parameters set/got from application. + * @{ + */ +typedef enum +{ + SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL = 0x01, +} T_SIMP_PARAM_TYPE; + +/** @} */ + + + +/** @defgroup SIMP_Service_Upstream_Message SIMP Service Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ + +/** @defgroup SIMP_Service_Read_Info SIMP Service Read Info + * @brief Parameter for reading characteristic value. + * @{ + */ +#define SIMP_READ_V1 1 +/** @} */ + +/** @defgroup SIMP_Service_Write_Info SIMP Service Write Info + * @brief Parameter for writing characteristic value. + * @{ + */ +#define SIMP_WRITE_V2 1 + +/** @} */ + +/** @defgroup SIMP_Service_Notify_Indicate_Info SIMP Service Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define SIMP_NOTIFY_INDICATE_V3_ENABLE 1 +#define SIMP_NOTIFY_INDICATE_V3_DISABLE 2 +#define SIMP_NOTIFY_INDICATE_V4_ENABLE 3 +#define SIMP_NOTIFY_INDICATE_V4_DISABLE 4 + + +/** @} */ + +#define SIMP_READ_V1_MAX_LEN 300 + +/** @} End of SIMP_Service_Upstream_Message */ + + + +/** @} End of SIMP_Service_Exported_Macros */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SIMP_Service_Exported_Types SIMP Service Exported Types + * @brief + * @{ + */ + +/** @defgroup TSIMP_WRITE_MSG TSIMP_WRITE_MSG + * @brief Simple BLE service written msg to application. + * @{ + */ +typedef struct +{ + uint8_t opcode; //!< ref: @ref SIMP_Service_Write_Info + T_WRITE_TYPE write_type; + uint16_t len; + uint8_t *p_value; +} TSIMP_WRITE_MSG; +/** @} End of TSIMP_WRITE_MSG */ + + +/** @defgroup TSIMP_UPSTREAM_MSG_DATA TSIMP_UPSTREAM_MSG_DATA + * @brief Simple BLE service callback message content. + * @{ + */ +typedef union +{ + uint8_t notification_indification_index; //!< ref: @ref SIMP_Service_Notify_Indicate_Info + uint8_t read_value_index; //!< ref: @ref SIMP_Service_Read_Info + TSIMP_WRITE_MSG write; +} TSIMP_UPSTREAM_MSG_DATA; +/** @} End of TSIMP_UPSTREAM_MSG_DATA */ + +/** @defgroup TSIMP_CALLBACK_DATA TSIMP_CALLBACK_DATA + * @brief Simple BLE service data to inform application. + * @{ + */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + TSIMP_UPSTREAM_MSG_DATA msg_data; +} TSIMP_CALLBACK_DATA; +/** @} End of TSIMP_CALLBACK_DATA */ + +/** @} End of SIMP_Service_Exported_Types */ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup SIMP_Service_Exported_Functions SIMP Service Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add simple BLE service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + */ +T_SERVER_ID simp_ble_service_add_service(void *p_func); + +/** + * @brief Set service related data from application. + * + * @param[in] param_type parameter type to set. + * @param[in] len value length to be set. + * @param[in] p_value value to set. + * @return parameter set result. + * @retval 0 false + * @retval 1 true + */ +bool simp_ble_service_set_parameter(T_SIMP_PARAM_TYPE param_type, uint16_t len, void *p_value); + +/** + * @brief send notification of simple notify characteristic value. + * + * @param[in] conn_id connection id + * @param[in] service_id service ID of service. + * @param[in] p_value characteristic value to notify + * @param[in] length characteristic value length to notify + * @return notification action result + * @retval 1 true + * @retval 0 false + */ +bool simp_ble_service_send_v3_notify(uint8_t conn_id, T_SERVER_ID service_id, + void *p_value, uint16_t length); +/** + * @brief send indication of simple indicate characteristic value. + * + * @param[in] conn_id connection id + * @param[in] service_id service ID of service. + * @param[in] p_value characteristic value to notify + * @param[in] length characteristic value length to notify + * @return notification action result + * @retval 1 true + * @retval 0 false + */ +bool simp_ble_service_send_v4_indicate(uint8_t conn_id, T_SERVER_ID service_id, + void *p_value, uint16_t length); + +/** @} End of SIMP_Service_Exported_Functions */ + +/** @} End of SIMP_Service */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _SIMPLE_BLE_SERVICE_H_ */ diff --git a/inc/bluetooth/profile/server/sps.h b/inc/bluetooth/profile/server/sps.h new file mode 100644 index 0000000..73a2c5d --- /dev/null +++ b/inc/bluetooth/profile/server/sps.h @@ -0,0 +1,219 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file sps.h + * @brief Head file for using scan parameters service. + * @details SPS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _SPS_H_ +#define _SPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +/** @defgroup SPS Scan Parameters Service + * @brief Scan parameters service + * @details + + The Scan Parameters Service enables a GATT Server device to expose a characteristic for the GATT Client + to write its scan interval and scan window on the GATT Server device, and enables a GATT Server to + request a refresh of the GATT Client scan interval and scan window.Scan Parameter Service makes up the + services of HID Device, together with HID Service. Its role is to implement the interaction of data + information when needing to change Scan parameters. + + Scan Parameter Service contains two Characteristics: one is scan interval and scan window, and it is used + to store Scan Parameters of the Client; the other is Scan Refresh, and it is used to notify the Client to + update the value of Scan parameter according to recent data by notification. + + The specific configuration can be achieved by modifying @ref sps_config.h. + + Application shall register scan parameter service when initialization through @ref sps_add_service function. + + Application can set the scan refresh value through @ref sps_set_parameter function. + + Application can notify refresh value to client through @ref sps_scan_interval_window_value_notify function. + + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SPS_Exported_Macros SPS Exported Macros + * @brief + * @{ + */ + +/** @defgroup SPS_Write_Info SPS Write Info + * @brief Parameter for writing characteristic value. + * @{ + */ +#define SPS_WRITE_SCAN_INTERVAL_WINDOW 1 +/** @} */ + +/** @defgroup SPS_Notify_Indicate_Info SPS Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define SPS_NOTIFY_INDICATE_SCAN_REFRESH_ENABLE 1 +#define SPS_NOTIFY_INDICATE_SCAN_REFRESH_DISABLE 2 +/** @} */ + +/** @} End of SPS_Exported_Macros */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SPS_Exported_Types SPS Exported Types + * @brief + * @{ + */ + +/** @defgroup SPS_PARAM_TYPE SPS Parameter Types +* @brief +* @{ +*/ +typedef enum +{ + SPS_PARAM_SCAN_REFRESH +} T_SPS_PARAM_TYPE; + +/** @} */ + +/** SPS scan interval window structure*/ +typedef struct +{ + uint16_t scan_interval; + uint16_t scan_window; +} T_SPS_SCAN_INTERVAL_WINDOW; + + +/** SPS write parameter*/ +typedef union +{ + T_SPS_SCAN_INTERVAL_WINDOW scan; +} T_SPS_WRITE_PARAMETER; + +/** SPS write message*/ +typedef struct +{ + uint8_t write_type; + T_SPS_WRITE_PARAMETER write_parameter; +} T_SPS_WRITE_MSG; + +/** SPS upstream message data*/ +typedef union +{ + uint8_t notification_indification_index; + T_SPS_WRITE_MSG write; +} T_SPS_UPSTREAM_MSG_DATA; + +/** SPS callback data*/ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_SPS_UPSTREAM_MSG_DATA msg_data; +} T_SPS_CALLBACK_DATA; + +/** @} End of SPS_Exported_Types */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup SPS_Exported_Functions SPS Exported Functions + * @brief + * @{ + */ + +/** + * @brief Set a scan paramter service parameter. + * + * NOTE: You can call this function with a scan paramter service parameter type and it will set the + * scan paramter service parameter. Scan paramter service parameters are defined in @ref T_SPS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Scan paramter service parameter type: @ref T_SPS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t refresh_value = 10; + sps_set_parameter(SPS_PARAM_SCAN_REFRESH, 1, &refresh_value); + } + * \endcode + */ +bool sps_set_parameter(T_SPS_PARAM_TYPE param_type, uint8_t len, void *p_value); + +/** + * @brief Add scan parameters service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + sps_id = sps_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID sps_add_service(void *p_func); + +/** + * @brief send notification. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID of service. + * @param[in] sps_refresh_value characteristic value to notify + * @return notification action result + * @retval 1 TRUE + * @retval 0 FALSE + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t sps_refresh_value = 10; + sps_scan_interval_window_value_notify(conn_id, sps_id, sps_refresh_value); + } + * \endcode + */ +bool sps_scan_interval_window_value_notify(uint8_t conn_id, uint8_t service_id, + uint8_t sps_refresh_value); +/** @} End of SPS_Exported_Functions */ + +/** @} End of SPS */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SPS_H_ */ + diff --git a/inc/bluetooth/profile/server/sps_config.h b/inc/bluetooth/profile/server/sps_config.h new file mode 100644 index 0000000..df477ba --- /dev/null +++ b/inc/bluetooth/profile/server/sps_config.h @@ -0,0 +1,35 @@ +#ifndef _SPS_CONFIG_H_ +#define _SPS_CONFIG_H_ + + +/** @defgroup SPS Scan Parameters Service + * @brief Scan parameters service + * @{ + */ + +/** @defgroup SPS_CONFIG Scan Parameters Service Config + * @brief Scan parameters service config + * @{ + */ + +/** @defgroup SPS_Exported_Macros SPS Exported Macros + * @brief + * @{ + */ + +/** @details + Set SPS_CHAR_SCAN_REFRESH_SUPPORT to 1 to support scan refresh characteristic, + otherwise set it to 0. +*/ +#define SPS_CHAR_SCAN_REFRESH_SUPPORT 1 + + +/** @} End of SPS_Common_Exported_Macros */ + +/** @} End of SPS_CONFIG */ + +/** @} End of SPS */ + + + +#endif diff --git a/inc/bluetooth/profile/server/tps.h b/inc/bluetooth/profile/server/tps.h new file mode 100644 index 0000000..2662dd4 --- /dev/null +++ b/inc/bluetooth/profile/server/tps.h @@ -0,0 +1,164 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file tps.h + * @brief Head file for using TX power service. + * @details TPS data structs and external functions declaration. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef _TPS_H_ +#define _TPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include "profile_server.h" + + +/** @defgroup TPS Tx Power Service + * @brief Tx power service + * @details + + The Tx Power service uses the Tx Power Level characteristic to expose the current transmit power level + of a device when in a connection.The Tx Power service contains only a Tx Power Level characteristic. + The Tx Power Service generally makes up a profile with some other services, such as Proximity, and its + role is to indicate a device's transmit power level when in a connection. + + Application shall register Tx Power service when initialization through @ref tps_add_service function. + + Application can set the TX power value through @ref tps_set_parameter function. + + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup TPS_Exported_Macros TPS Exported Macros + * @brief + * @{ + */ +/** @defgroup TPS_Read_Info TPS Read Info + * @brief Read characteristic value. + * @{ + */ +#define TPS_READ_TX_POWER_VALUE 1 +#define TPS_READ_FIRMWARE_VERSION 2 +#define TPS_READ_SYSTEM_ID 3 +#define TPS_READ_SERIAL_NUMBER 4 +/** @} */ +/** @} End of TPS_Exported_Macros */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup TPS_Exported_Types TPS Exported Types + * @brief + * @{ + */ +/* Add all public types here */ +/** @defgroup TPS_Application_Parameters TPS Application Parameters + * @brief Type of parameters set/got from application. + * @{ + */ +typedef enum +{ + TPS_PARAM_TX_POWER, + TPS_PARAM_SYSTEM_ID, + TSP_PARAM_FIRMWARE, + TPS_PARAM_SERIAL_NUMBER +} T_TPS_PARAM_TYPE; +/** @} */ + +/** @defgroup TPS_Upstream_Message TPS Upstream Message + * @brief TPS data struct for notification data to application. + * @{ + */ +/** Message content: @ref TPS_Upstream_Message */ +typedef union +{ + uint8_t read_value_index; +} T_TPS_UPSTREAM_MSG_DATA; + +/** TPS service data to inform application. */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_TPS_UPSTREAM_MSG_DATA msg_data; +} T_TPS_CALLBACK_DATA; +/** @} */ + +/** @} End of TPS_Exported_Types */ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup TPS_Exported_Functions TPS Exported Functions + * @{ + */ + +/** + * @brief Set a Tx power service parameter. + * + * NOTE: You can call this function with a tx power service parameter type and it will set the + * tx power service parameter. Tx power service parameters are defined in @ref T_TPS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Tx power service parameter type: @ref T_TPS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (example: data type of uint16 will be cast to + * uint16 pointer). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t tx_power = 0; + tps_set_parameter(TPS_PARAM_TX_POWER, 1, &tx_power); + } + * \endcode + */ +bool tps_set_parameter(T_TPS_PARAM_TYPE param_type, uint8_t len, void *p_value); + + +/** + * @brief Add tx power service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + tps_id = tps_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID tps_add_service(void *p_func); + +/** @} End of TPS_Exported_Functions */ + +/** @} End of TPS */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _TPS_H_ */ diff --git a/inc/bluetooth/profile/server/vendor_service.h b/inc/bluetooth/profile/server/vendor_service.h new file mode 100644 index 0000000..2f76295 --- /dev/null +++ b/inc/bluetooth/profile/server/vendor_service.h @@ -0,0 +1,80 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file vendor_service.h + * @brief Head file for using Vendor Service Remote Controller. + * @details Vendor service data structs and external functions declaration. + * @author Chenjie Jin + * @date 2018-5-7 + * @version v1.1 + * ************************************************************************************* + */ + +#ifndef _VENDOR_SERVICE_H_ +#define _VENDOR_SERVICE_H_ + +#include "profile_server.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** @brief Demo Profile service related UUIDs. */ + +#define GATT_UUID_CHAR_VENDOR_HANDSHAKE 0xA001 +#define GATT_UUID_CHAR_VENDOR_TEST_MODE 0xA002 + +/** @brief Index of each characteristic in Demo Profile service database. */ +#define BLE_SERVICE_CHAR_VENDOR_HANDSHAKE_INDEX 0x02 +#define GATT_SVC_VENDOR_HANDSHAKE_CHAR_CCCD_INDEX 0x03 +#define BLE_SERVICE_CHAR_VENDOR_TEST_MODE_INDEX 0x05 + +#define VENDOR_WRITE_HANDSHAKE 1 +#define VENDOR_WRITE_TEST_MODE 2 + +#define VENDOR_NOTIFY_ENABLE 1 +#define VENDOR_NOTIFY_DISABLE 2 + +/** Message content */ +typedef union +{ + struct + { + uint8_t len; + uint8_t *report; + } report_data; +} T_VENDOR_WRITE_PARAMETER; + +/** @struct _TATVV_WRITE_MSG + * @brief write message + */ +typedef struct +{ + uint8_t write_type; /**< ref: @ref Vendor_Write_Info */ + T_VENDOR_WRITE_PARAMETER write_parameter; +} T_VENDOR_WRITE_MSG; + +typedef union _TVENDOR_UPSTREAM_MSG_DATA +{ + uint8_t notification_indification_index; + T_VENDOR_WRITE_MSG write_msg; +} TVENDOR_UPSTREAM_MSG_DATA; + +/** Vendor service data to inform application */ +typedef struct _T_VENDOR_CALLBACK_DATA +{ + T_SERVICE_CALLBACK_TYPE msg_type; + TVENDOR_UPSTREAM_MSG_DATA msg_data; +} T_VENDOR_CALLBACK_DATA; + +extern uint8_t vendor_svc_handshake_values[16]; + +uint8_t vendor_svc_add_service(void *pFunc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/bluetooth/profile/server/voice_service.h b/inc/bluetooth/profile/server/voice_service.h new file mode 100644 index 0000000..88249d2 --- /dev/null +++ b/inc/bluetooth/profile/server/voice_service.h @@ -0,0 +1,155 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_rmc.h + * @brief Head file for using Voice Service. + * @details Voice service data structs and external functions declaration. + * @author Chenjie Jin + * @date 2019-6-27 + * @version v1.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _VOICE_SERVICE_H_ +#define _VOICE_SERVICE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Add Includes here */ +#include "profile_server.h" +#include "board.h" +#include "app_msg.h" + +/** @defgroup Voice_Service Voice Service + * @brief Voice Service based on GATT + * @{ + */ + +/** @defgroup Voice_Service_Exported_Constants Voice Service Exported Constants + * @brief macros that other .c files may use all defined here + * @{ + */ + +///@cond +/** @brief Voice_Service related UUIDs. */ +#define GATT_UUID_VOICE_CHAR_CTL 0x3A40 +#define GATT_UUID_VOICE_CHAR_DATA 0x3A41 +#define GATT_UUID_VOICE_CHAR_CMD 0x3A42 + +///@endcond + +/** @defgroup Voice_Service_Attribute_Index Voice Service Attribute Index + * @brief Index defines for Characteristic's value in Voice_Service + * @{ + */ +#define GATT_SRV_VOICE_CHAR_CTL_VALUE_INDEX 2 +#define GATT_SRV_VOICE_CHAR_DATA_VALUE_INDEX 4 +#define GATT_SRV_VOICE_CHAR_DATA_CCCD_INDEX 5 +#define GATT_SRV_VOICE_CHAR_CMD_VALUE_INDEX 7 +#define GATT_SRV_VOICE_CHAR_CMD_CCCD_INDEX 8 + +/** @} */ + +/** @defgroup Voice_Service_Upstream_Message Voice Service Upstream Message + * @brief Upstream message used to inform application. + * @{ + */ + +/** @defgroup Voice_Service_Read_Info Voice Service Read Info + * @brief Parameter for read characteristic value. + * @{ + */ +#define VOICE_SVC_READ_PARAM_VOICE_DATA 1 +#define VOICE_SVC_READ_PARAM_VOICE_CMD 2 +/** @} */ + +/** @defgroup Voice_Service_Write_Info Voice Service Write Info + * @brief Parameter for write characteristic value. + * @{ + */ +#define VOICE_SVC_WRITE_CHAR_CTL_INDEX 1 +/** @} */ + +/** @defgroup Voice_Service_Notify_Indicate_Info Voice Service Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define VOICE_NOTIFY_DATA_ENABLE 1 +#define VOICE_NOTIFY_DATA_DISABLE 2 +#define VOICE_NOTIFY_CMD_ENABLE 3 +#define VOICE_NOTIFY_CMD_DISABLE 4 +/** @} */ + +/** @} End of Voice_Service_Upstream_Message */ + +/** @} End of Voice_Service_Exported_Constants */ + +/** @defgroup Voice_Service_Exported_Types Voice Service Exported Types + * @brief types that other.c files may use all defined here + * @{ + */ + +/** Message content */ +typedef union +{ + struct + { + uint8_t len; + uint8_t *report; + } report_data; +} T_VOICE_WRITE_PARAMETER; + +/** @struct T_VOICE_WRITE_MSG + * @brief write message + */ +typedef struct +{ + uint8_t write_type; + T_VOICE_WRITE_PARAMETER write_parameter; +} T_VOICE_WRITE_MSG; + +/** @struct T_VOICE_UPSTREAM_MSG_DATA + * @brief upstream message + */ +typedef struct +{ + uint8_t notification_indification_index; + uint8_t read_value_index; + T_VOICE_WRITE_MSG write; +} T_VOICE_UPSTREAM_MSG_DATA; + +/** @struct T_VOICE_CALLBACK_DATA + * @brief callback data + */ +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_VOICE_UPSTREAM_MSG_DATA msg_data; +} T_VOICE_CALLBACK_DATA; + + +/** @} End of Voice_Service_Exported_Types */ + + + +/** @defgroup Voice_Service_Exported_Functions Voice Service Exported Functions + * @brief functions that other .c files may use all defined here. + * @{ + */ +uint8_t voice_service_add_service(void *pfn); +/** @} End of Voice_Service_Exported_Functions */ + +/** @} End of Voice_Service */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _VOICE_SERVICE_H_ */ diff --git a/inc/bluetooth/profile/server/wss.h b/inc/bluetooth/profile/server/wss.h new file mode 100644 index 0000000..fe7d653 --- /dev/null +++ b/inc/bluetooth/profile/server/wss.h @@ -0,0 +1,303 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file wss.h + * @brief Head file for using weight scale service. + * @details Weight scale data types and external functions declaration. + * @author Vera + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _WSS_H_ +#define _WSS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Add Includes here */ +#include "stdint.h" +#include "profile_server.h" + + + +/** @defgroup WSS Weight Scale Service + * @brief Weight Scale Service + * @details + + The Weight Scale (WS) Service exposes weight and related data from a weight scale (Server) intended for + consumer healthcare as well as sports/fitness applications. + + Weight Scale Feature and Weight Measurement are exposed in the Weight Scale Service. + Only one instance of each characteristic is permitted within this service. + The Weight Scale Feature characteristic shall be used to describe the supported features of the Server. + When read, the Weight Scale Feature characteristic returns a value that is used by a Client to determine + the supported features of the Server. + The Weight Measurement characteristic is used to send weight-related data to the Client. + Included in the characteristic value are a Flags field (for showing the presence of optional fields and + measurement units), a Weight field, and depending upon the contents of the Flags field, may include one or more optional fields. + + Application shall register weight scale service when initialization through @ref wss_add_service function. + + Application can set the weight scale service parameters through @ref wss_set_parameter function. + + Application can send the weight-related data of WSS to the client through @ref wss_measurement_indicate function. + + * @{ + */ + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup WSS_Exported_Macros WSS Exported Macros + * @brief + * @{ + */ + +/** +* @brief Weight scale service parameter type +*/ +typedef enum +{ + WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG = 0x01, + WSS_PARAM_MEASUREMENT_WEIGHT_VALUE, + WSS_PARAM_MEASUREMENT_TIME_STAMP, + WSS_PARAM_MEASUREMENT_USERID, + WSS_PARAM_MEASUREMENT_BMI, + WSS_PARAM_MEASUREMENT_HEIGHT_VALUE, + WSS_PARAM_FEATURE_READ_CHAR_VAL, +} T_WSS_PARAM_TYPE; + + +/** @defgroup WSS_Measurement_Flag WSS Measurement Flag + * @{ + */ +#define WSS_FLAG_MEASUREMENT_UINT_BIT BIT0 +#define WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT BIT1 +#define WSS_FLAG_MEASUREMENT_USERID_PRESNET_BIT BIT2 +#define WSS_FLAG_MEASUREMENT_BMI_PRESNET_BIT BIT3 + +/** @} */ + + + +/** @defgroup WSS_Service_Read_Info WSS Service Read Info + * @brief Parameter for reading characteristic value. + * @{ + */ +#define WEIGHT_SCALE_READ_FEATURE 1 +/** @} End of WSS_Service_Read_Info*/ + + + +/** @defgroup WSS_Service_Notify_Indicate_Info WSS Service Notify Indicate Info + * @brief Parameter for enable or disable notification or indication. + * @{ + */ +#define WSS_INDICATE_WEIGHT_MEASUREMENT_ENABLE 1 +#define WSS_INDICATE_WEIGHT_MEASUREMENT_DISABLE 2 +/** @} */ + +/** @} End of WSS_Exported_Macros */ + + +/*============================================================================* + * Types + *============================================================================*/ + +/** @defgroup WSS_Service_Exported_Types WSS Service Exported Types + * @brief + * @{ + */ + +/** @defgroup T_WSS_UPSTREAM_MSG_DATA TWS UPSTREAM MSG DATA + * @brief Weight scale service callback message content. + * @{ + */ +typedef union +{ + uint8_t notification_indication_index; //!< ref: @ref WSS_Service_Notify_Indicate_Info + uint8_t read_value_index; //!< ref: @ref WSS_Service_Read_Info +} T_WSS_UPSTREAM_MSG_DATA; +/** @} End of T_WSS_UPSTREAM_MSG_DATA */ + +/** @defgroup T_WSS_CALLBACK_DATA TWS CALLBACK DATA + * @brief Weight scale service data to inform application. + * @{ + */ +typedef struct +{ + T_SERVICE_CALLBACK_TYPE msg_type; + T_WSS_UPSTREAM_MSG_DATA msg_data; +} T_WSS_CALLBACK_DATA; +/** @} End of T_WSS_CALLBACK_DATA */ + + +/** @defgroup T_WEIGHT_SCALE_FEATURE_VALUE WEIGHT SCALE FEATURE VALUE + * @brief Weight Scale Feature Value. + * @{ + */ +typedef struct +{ + uint32_t time_stamp_supported: 1; + uint32_t multiple_users_supported: 1; + uint32_t bmi_supported: 1; + uint32_t weight_measurement_resolution: 4; + uint32_t height_measurement_resolution: 3; + uint32_t rfu: 22; +} T_WEIGHT_SCALE_FEATURE_VALUE; +/** @} End of T_WEIGHT_SCALE_FEATURE_VALUE */ + +/** @defgroup T_WEIGHT_MEASUREMENT_VALUE_FLAG WEIGHT MEASUREMENT VALUE FLAG + * @brief Weight Measurement Value Flag. + * @{ + */ +typedef struct +{ + uint8_t measurement_units: 1; + uint8_t time_stamp_present: 1; + uint8_t user_id_present: 1; + uint8_t bmi_and_height_present: 1; + uint8_t rfu: 4; +} T_WEIGHT_MEASUREMENT_VALUE_FLAG; +/** @} End of T_WEIGHT_MEASUREMENT_VALUE_FLAG */ + +/** @defgroup T_WSS_TIME_STAMP WSS TIME STAMP + * @brief Weight Scale Feature Time Stamp. + * @{ + */ +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} T_WSS_TIME_STAMP; +/** @} End of T_WSS_TIME_STAMP */ + +/** @defgroup T_WSS_MEASUREMENT WSS MEASUREMENT + * @brief Weight Measurement Value. + * @{ + */ +typedef struct +{ + T_WEIGHT_MEASUREMENT_VALUE_FLAG flag; + uint16_t weight_si_value; + uint16_t weight_imperial_value; + T_WSS_TIME_STAMP time_stamp; + uint8_t user_id; + uint16_t bmi; + uint16_t height_si_value; + uint16_t height_imperial_value; +} T_WSS_MEASUREMENT; +/** @} End of T_WSS_MEASUREMENT */ + +/** @} End of WSS_Service_Exported_Types */ + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** @defgroup WSS_Service_Exported_Functions WSS Service Exported Functions + * @brief + * @{ + */ + +/** + * @brief Add Weight scale service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + wss_id = wss_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID wss_add_service(void *p_func); + +/** + * @brief Set a weight scale service parameter. + * + * NOTE: You can call this function with a weight scale service parameter type and it will set the + * weight scale service parameter. Weight scale service parameters are defined in @ref T_WSS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Weight scale service parameter type: @ref T_WSS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint32_t weight_feature = 0x0000001f; + wss_set_parameter(WSS_PARAM_FEATURE_READ_CHAR_VAL, 4, &weight_feature); + } + * \endcode + */ +bool wss_set_parameter(T_WSS_PARAM_TYPE param_type, uint8_t len, void *p_value); + + +/** + * @brief Send measurement indication data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t wm_flag = WSS_FLAG_MEASUREMENT_UINT_BIT + | WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT + | WSS_FLAG_MEASUREMENT_USERID_PRESNET_BIT + | WSS_FLAG_MEASUREMENT_BMI_PRESNET_BIT; + + wss_set_parameter(WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG, sizeof(wm_flag), &wm_flag); + wss_set_parameter(WSS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(wss_measure_time_stamp), + &wss_measure_time_stamp); + wss_measurement_indicate(p_parse_value->dw_param[0], wss_id); + } + * \endcode + */ +bool wss_measurement_indicate(uint8_t conn_id, T_SERVER_ID service_id); +/** @} End of WSS_Service_Exported_Functions */ + +/** @} End of WSS */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* _WSS_H_ */ diff --git a/inc/os/freertos/FreeRTOS.h b/inc/os/freertos/FreeRTOS.h new file mode 100644 index 0000000..298561e --- /dev/null +++ b/inc/os/freertos/FreeRTOS.h @@ -0,0 +1,1278 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +#include /* READ COMMENT ABOVE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT +#define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) +#include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE +#error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES +#error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 +#error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION +#error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK +#error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK +#error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS +#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES +#define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet +#define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet +#define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete +#define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend +#define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil +#define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay +#define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay +#define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder +#define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder +#define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle +#define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 +#define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + +#ifndef INCLUDE_eTaskGetState +#define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR +#define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall +#define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState +#define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle +#define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 +#ifndef configMAX_CO_ROUTINE_PRIORITIES +#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. +#endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG +#define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES +#define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES +#define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS +#define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES +#define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API +#define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB +#define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN +#define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD +#define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 +#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT +#define configASSERT( x ) +#define configASSERT_DEFINED 0 +#else +#define configASSERT_DEFINED 1 +#endif + +#ifndef portMEMORY_BARRIER +#define portMEMORY_BARRIER() +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + +#ifndef configTIMER_TASK_PRIORITY +#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. +#endif /* configTIMER_TASK_PRIORITY */ + +#ifndef configTIMER_QUEUE_LENGTH +#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. +#endif /* configTIMER_QUEUE_LENGTH */ + +#ifndef configTIMER_TASK_STACK_DEPTH +#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. +#endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR +#define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB +#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK +#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB +#define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE +#define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) +#define vQueueAddToRegistry( xQueue, pcName ) +#define vQueueUnregisterQueue( xQueue ) +#define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE +#define portPOINTER_SIZE_TYPE uint32_t +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART +/* Used to perform any necessary initialisation - for example, open a file +into which trace is to be written. */ +#define traceSTART() +#endif + +#ifndef traceEND +/* Use to close a trace, for example close a file into which trace has been +written. */ +#define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN +/* Called after a task has been selected to run. pxCurrentTCB holds a pointer +to the task control block of the selected task. */ +#define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT +/* Called before stepping the tick count after waking from tickless idle +sleep. */ +#define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN +/* Called immediately before entering tickless idle. */ +#define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END +/* Called when returning to the Idle task after a tickless idle. */ +#define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT +/* Called before a task has been selected to run. pxCurrentTCB holds a pointer +to the task control block of the task being switched out. */ +#define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT +/* Called when a task attempts to take a mutex that is already held by a +lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task +that holds the mutex. uxInheritedPriority is the priority the mutex holder +will inherit (the priority of the task that is attempting to obtain the +muted. */ +#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT +/* Called when a task releases a mutex, the holding of which had resulted in +the task inheriting the priority of a higher priority task. +pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the +mutex. uxOriginalPriority is the task's configured (base) priority. */ +#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE +/* Task is about to block because it cannot read from a +queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore +upon which the read was attempted. pxCurrentTCB points to the TCB of the +task that attempted the read. */ +#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK +/* Task is about to block because it cannot read from a +queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore +upon which the read was attempted. pxCurrentTCB points to the TCB of the +task that attempted the read. */ +#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND +/* Task is about to block because it cannot write to a +queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore +upon which the write was attempted. pxCurrentTCB points to the TCB of the +task that attempted the write. */ +#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW +#define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS +#define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE +#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE +#define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE +#define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED +#define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX +#define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED +#define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE +#define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED +#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE +#define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED +#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE +#define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND +#define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED +#define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE +#define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK +#define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED +#define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR +#define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED +#define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR +#define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED +#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR +#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED +#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED +#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE +#define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE +#define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED +#define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE +#define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL +#define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY +#define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET +#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND +#define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME +#define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR +#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK +#define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE +#define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED +#define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND +#define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED +#define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED +#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC +#define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE +#define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE +#define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED +#define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK +#define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END +#define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK +#define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END +#define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS +#define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR +#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS +#define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR +#define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE +#define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL +#define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR +#define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD +#define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK +#define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE +#define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK +#define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT +#define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY +#define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR +#define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR +#define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED +#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED +#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE +#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE +#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET +#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND +#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND +#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED +#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR +#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE +#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE +#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED +#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR +#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS +#define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS +#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. +#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + +#ifndef portGET_RUN_TIME_COUNTER_VALUE +#ifndef portALT_GET_RUN_TIME_COUNTER_VALUE +#error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. +#endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ +#endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK +#define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT +#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API +#define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP +#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 +#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE +#define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING +#define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING +#define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING +#define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS +#define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT +#define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portALLOCATE_SECURE_CONTEXT +#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) +#endif + +#ifndef portDONT_DISCARD +#define portDONT_DISCARD +#endif + +#ifndef configUSE_TIME_SLICING +#define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS +#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID +#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY +#define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER +#define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY +#define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR +#define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP +#define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS +#define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configUSE_POSIX_ERRNO +#define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC +#define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION +/* Defaults to 0 for backward compatibility. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION +/* Defaults to 1 for backward compatibility. */ +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#ifndef configSTACK_DEPTH_TYPE +/* Defaults to uint16_t for backward compatibility, but can be overridden +in FreeRTOSConfig.h if uint16_t is too restrictive. */ +#define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE +/* Defaults to size_t for backward compatibility, but can be overridden +in FreeRTOSConfig.h if lengths will always be less than the number of bytes +in a size_t. */ +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) +#if( INCLUDE_vTaskSuspend != 1 ) +#error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 +#endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) +#error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) +#error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT +#define configINITIAL_TICK_COUNT 0 +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) +/* Either variables of tick type cannot be read atomically, or +portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when +the tick count is returned to the standard critical section macros. */ +#define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() +#define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() +#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() +#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else +/* The tick type can be read atomically, so critical sections used when the +tick count is returned can be defined away. */ +#define portTICK_TYPE_ENTER_CRITICAL() +#define portTICK_TYPE_EXIT_CRITICAL() +#define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 +#define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF +/* configPRINTF() was not defined, so define it away to nothing. To use +configPRINTF() then define it as follows (where MyPrintFunction() is +provided by the application writer): + +void MyPrintFunction(const char *pcFormat, ... ); +#define configPRINTF( X ) MyPrintFunction X + +Then call like a standard printf() function, but placing brackets around +all parameters so they are passed as a single parameter. For example: +configPRINTF( ("Value = %d", MyVariable) ); */ +#define configPRINTF( X ) +#endif + +#ifndef configMAX +/* The application writer has not provided their own MAX macro, so define +the following generic implementation. */ +#define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN +/* The application writer has not provided their own MAX macro, so define +the following generic implementation. */ +#define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 +#define eTaskStateGet eTaskGetState +#define portTickType TickType_t +#define xTaskHandle TaskHandle_t +#define xQueueHandle QueueHandle_t +#define xSemaphoreHandle SemaphoreHandle_t +#define xQueueSetHandle QueueSetHandle_t +#define xQueueSetMemberHandle QueueSetMemberHandle_t +#define xTimeOutType TimeOut_t +#define xMemoryRegion MemoryRegion_t +#define xTaskParameters TaskParameters_t +#define xTaskStatusType TaskStatus_t +#define xTimerHandle TimerHandle_t +#define xCoRoutineHandle CoRoutineHandle_t +#define pdTASK_HOOK_CODE TaskHookFunction_t +#define portTICK_RATE_MS portTICK_PERIOD_MS +#define pcTaskGetTaskName pcTaskGetName +#define pcTimerGetTimerName pcTimerGetName +#define pcQueueGetQueueName pcQueueGetName +#define vTaskGetTaskInfo vTaskGetInfo + +/* Backward compatibility within the scheduler code only - these definitions +are not really required but are included for completeness. */ +#define tmrTIMER_CALLBACK TimerCallbackFunction_t +#define pdTASK_CODE TaskFunction_t +#define xListItem ListItem_t +#define xList List_t + +/* For libraries that break the list data hiding, and access list structure +members directly (which is not supposed to be done). */ +#define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) +#error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT +#define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_MPU +#define configENABLE_MPU 0 +#endif + +/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_FPU +#define configENABLE_FPU 1 +#endif + +/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. +This is currently used in ARMv8M ports. */ +#ifndef configENABLE_TRUSTZONE +#define configENABLE_TRUSTZONE 1 +#endif + +/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on +the Secure Side only. */ +#ifndef configRUN_FREERTOS_SECURE_ONLY +#define configRUN_FREERTOS_SECURE_ONLY 0 +#endif + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using + * dynamically allocated RAM, in which case when any task is deleted it is known + * that both the task's stack and TCB need to be freed. Sometimes the + * FreeRTOSConfig.h settings only allow a task to be created using statically + * allocated RAM, in which case when any task is deleted it is known that neither + * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h + * settings allow a task to be created using either statically or dynamically + * allocated RAM, in which case a member of the TCB is used to record whether the + * stack and/or TCB were allocated statically or dynamically, so when a task is + * deleted the RAM that was allocated dynamically is freed again and no attempt is + * made to free the RAM that was allocated statically. + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a + * task to be created using either statically or dynamically allocated RAM. Note + * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with + * a statically allocated stack and a dynamically allocated TCB. + * + * The following table lists various combinations of portUSING_MPU_WRAPPERS, + * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and + * when it is possible to have both static and dynamic allocation: + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | + * | | | | | | Static Possible | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | + * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ + ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; +#endif + TickType_t xDummy2; + void *pvDummy3[ 4 ]; +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; +#endif +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; +#endif + TickType_t xDummy2; + void *pvDummy3[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; +#endif + UBaseType_t uxDummy2; + void *pvDummy3; + StaticMiniListItem_t xDummy4; +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; +#endif +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; +#if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; +#endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; +#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void *pxDummy8; +#endif +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; +#endif +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; +#endif +#if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; +#endif +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; +#endif +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; +#endif +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; +#endif +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; +#endif +#if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; +#endif +#if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; +#endif + +#if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; +#endif +#if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; +#endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; +#endif + +#if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; +#endif + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; +#endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + +#if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; +#endif + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; +#endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void *pvDummy5; + TaskFunction_t pvDummy6; +#if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; +#endif + uint8_t ucDummy8; + +} StaticTimer_t; + +/* +* In line with software engineering best practice, especially when supplying a +* library that is likely to change in future versions, FreeRTOS implements a +* strict data hiding policy. This means the stream buffer structure used +* internally by FreeRTOS is not accessible to application code. However, if +* the application writer wants to statically allocate the memory required to +* create a stream buffer then the size of the stream buffer object needs to be +* know. The StaticStreamBuffer_t structure below is provided for this purpose. +* Its size and alignment requirements are guaranteed to match those of the +* genuine structure, no matter which architecture is being used, and no matter +* how the values in FreeRTOSConfig.h are set. Its contents are somewhat +* obfuscated in the hope users will recognise that it would be unwise to make +* direct use of the structure members. +*/ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void *pvDummy2[ 3 ]; + uint8_t ucDummy3; +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; +#endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + diff --git a/inc/os/freertos/FreeRTOSConfig.h b/inc/os/freertos/FreeRTOSConfig.h new file mode 100644 index 0000000..a9574f2 --- /dev/null +++ b/inc/os/freertos/FreeRTOSConfig.h @@ -0,0 +1,168 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "rtl876x.h" +#include "mem_config.h" +#include "otp.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +#include +extern uint32_t SystemCpuClock; + +/* The following definition allows the startup files that ship with the IDE +to be used without modification when the chip used includes the PMU CM001 +errata. */ +#define WORKAROUND_PMU_CM001 0 + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCpuClock ) +#define configSYSTICK_CLOCK_HZ ( (OTP->systick_clk_src == CORE_CLOCK) ? configCPU_CLOCK_HZ : OTP->systick_ext_clk_freq ) +#define portNVIC_SYSTICK_CLK_BIT ( OTP->systick_clk_src << 2UL ) +#define configTICK_RATE_HZ ( ( TickType_t ) (OTP->os_tick_rate_HZ) ) //default: 1ms +#define configMAX_PRIORITIES ( 7 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) +#define USING_LIST_TIMER 1 +#define USING_LIST_TIMER_PROTECT 1 +#define DUMP_ALL_TIMER 1 +extern void vTimerCreateFailedHook(void); +#define traceTIMER_CREATE_FAILED() vTimerCreateFailedHook() + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 6 /* 63 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x07 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 0x02 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +extern void vAssertHandler(const char *pFuncName, uint32_t funcLine); +#define configASSERT( x ) if( ( x ) == 0 ) { vAssertHandler(__FUNCTION__, __LINE__); } + +/** @detailed vendor "#define" for FreeRTOS */ +/* use the handle of task to show stack usage */ +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. WORKAROUND_PMU_CM001 is defined at the top of this file. */ +#if WORKAROUND_PMU_CM001 == 1 +#define xPortPendSVHandler PendSV_Handler_Veneer +#else +#define xPortPendSVHandler PendSV_Handler +#endif +#define vPortSVCHandler SVC_Handler +#define xPortSysTickHandler SysTick_Handler + +#ifndef tracePORT_RAISE_BASE_PRI +#define tracePORT_RAISE_BASE_PRI() +#endif + +#ifndef tracePORT_SET_BASE_PRI +#define tracePORT_SET_BASE_PRI() +#endif + +#ifndef traceDISABLE_IRQ +#define traceDISABLE_IRQ() +#endif + +#ifndef traceENABLE_IRQ +#define traceENABLE_IRQ() +#endif + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/inc/os/freertos/croutine.h b/inc/os/freertos/croutine.h new file mode 100644 index 0000000..622fe09 --- /dev/null +++ b/inc/os/freertos/croutine.h @@ -0,0 +1,724 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void *CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)(CoRoutineHandle_t, UBaseType_t); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t + xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t + uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t + uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
    + BaseType_t xCoRoutineCreate(
    +                                 crCOROUTINE_CODE pxCoRoutineCode,
    +                                 UBaseType_t uxPriority,
    +                                 UBaseType_t uxIndex
    +                               );
    + * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
    + // Co-routine to be created.
    + void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + // This may not be necessary for const variables.
    + static const char cLedToFlash[ 2 ] = { 5, 6 };
    + static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
    +
    +     // Must start every co-routine with a call to crSTART();
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +         // This co-routine just delays for a fixed period, then toggles
    +         // an LED.  Two co-routines are created using this function, so
    +         // the uxIndex parameter is used to tell the co-routine which
    +         // LED to flash and how int32_t to delay.  This assumes xQueue has
    +         // already been created.
    +         vParTestToggleLED( cLedToFlash[ uxIndex ] );
    +         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
    +     }
    +
    +     // Must end every co-routine with a call to crEND();
    +     crEND();
    + }
    +
    + // Function that creates two co-routines.
    + void vOtherFunction( void )
    + {
    + uint8_t ucParameterToPass;
    + TaskHandle_t xHandle;
    +
    +     // Create two co-routines at priority 0.  The first is given index 0
    +     // so (from the code above) toggles LED 5 every 200 ticks.  The second
    +     // is given index 1 so toggles LED 6 every 400 ticks.
    +     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
    +     {
    +         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
    +     }
    + }
    +   
    + * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate(crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, + UBaseType_t uxIndex); + + +/** + * croutine. h + *
    + void vCoRoutineSchedule( void );
    + * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
    + // This idle task hook will schedule a co-routine each time it is called.
    + // The rest of the idle task will execute between co-routine calls.
    + void vApplicationIdleHook( void )
    + {
    +    vCoRoutineSchedule();
    + }
    +
    + // Alternatively, if you do not require any other part of the idle task to
    + // execute, the idle task hook can call vCoRoutineScheduler() within an
    + // infinite loop.
    + void vApplicationIdleHook( void )
    + {
    +    for( ;; )
    +    {
    +        vCoRoutineSchedule();
    +    }
    + }
    + 
    + * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule(void); + +/** + * croutine. h + *
    + crSTART( CoRoutineHandle_t xHandle );
    + * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
    + // Co-routine to be created.
    + void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + static int32_t ulAVariable;
    +
    +     // Must start every co-routine with a call to crSTART();
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +          // Co-routine functionality goes here.
    +     }
    +
    +     // Must end every co-routine with a call to crEND();
    +     crEND();
    + }
    + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
    + crEND();
    + * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
    + // Co-routine to be created.
    + void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + static int32_t ulAVariable;
    +
    +     // Must start every co-routine with a call to crSTART();
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +          // Co-routine functionality goes here.
    +     }
    +
    +     // Must end every co-routine with a call to crEND();
    +     crEND();
    + }
    + * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
    + crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
    + * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
    + // Co-routine to be created.
    + void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + // This may not be necessary for const variables.
    + // We are to delay for 200ms.
    + static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
    +
    +     // Must start every co-routine with a call to crSTART();
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +        // Delay for 200ms.
    +        crDELAY( xHandle, xDelayTime );
    +
    +        // Do something here.
    +     }
    +
    +     // Must end every co-routine with a call to crEND();
    +     crEND();
    + }
    + * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
    + crQUEUE_SEND(
    +                  CoRoutineHandle_t xHandle,
    +                  QueueHandle_t pxQueue,
    +                  void *pvItemToQueue,
    +                  TickType_t xTicksToWait,
    +                  BaseType_t *pxResult
    +             )
    + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
    + // Co-routine function that blocks for a fixed period then posts a number onto
    + // a queue.
    + static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + static BaseType_t xNumberToPost = 0;
    + static BaseType_t xResult;
    +
    +    // Co-routines must begin with a call to crSTART().
    +    crSTART( xHandle );
    +
    +    for( ;; )
    +    {
    +        // This assumes the queue has already been created.
    +        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
    +
    +        if( xResult != pdPASS )
    +        {
    +            // The message was not posted!
    +        }
    +
    +        // Increment the number to be posted onto the queue.
    +        xNumberToPost++;
    +
    +        // Delay for 100 ticks.
    +        crDELAY( xHandle, 100 );
    +    }
    +
    +    // Co-routines must end with a call to crEND().
    +    crEND();
    + }
    + * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ + { \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ + } + +/** + * croutine. h + *
    +  crQUEUE_RECEIVE(
    +                     CoRoutineHandle_t xHandle,
    +                     QueueHandle_t pxQueue,
    +                     void *pvBuffer,
    +                     TickType_t xTicksToWait,
    +                     BaseType_t *pxResult
    +                 )
    + * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
    + // A co-routine receives the number of an LED to flash from a queue.  It
    + // blocks on the queue until the number is received.
    + static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // Variables in co-routines must be declared static if they must maintain value across a blocking call.
    + static BaseType_t xResult;
    + static UBaseType_t uxLEDToFlash;
    +
    +    // All co-routines must start with a call to crSTART().
    +    crSTART( xHandle );
    +
    +    for( ;; )
    +    {
    +        // Wait for data to become available on the queue.
    +        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
    +
    +        if( xResult == pdPASS )
    +        {
    +            // We received the LED to flash - flash it!
    +            vParTestToggleLED( uxLEDToFlash );
    +        }
    +    }
    +
    +    crEND();
    + }
    + * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ + { \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ + } + +/** + * croutine. h + *
    +  crQUEUE_SEND_FROM_ISR(
    +                            QueueHandle_t pxQueue,
    +                            void *pvItemToQueue,
    +                            BaseType_t xCoRoutinePreviouslyWoken
    +                       )
    + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
    + // A co-routine that blocks on a queue waiting for characters to be received.
    + static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + char cRxedChar;
    + BaseType_t xResult;
    +
    +     // All co-routines must start with a call to crSTART().
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +         // Wait for data to become available on the queue.  This assumes the
    +         // queue xCommsRxQueue has already been created!
    +         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
    +
    +         // Was a character received?
    +         if( xResult == pdPASS )
    +         {
    +             // Process the character here.
    +         }
    +     }
    +
    +     // All co-routines must end with a call to crEND().
    +     crEND();
    + }
    +
    + // An ISR that uses a queue to send characters received on a serial port to
    + // a co-routine.
    + void vUART_ISR( void )
    + {
    + char cRxedChar;
    + BaseType_t xCRWokenByPost = pdFALSE;
    +
    +     // We loop around reading characters until there are none left in the UART.
    +     while( UART_RX_REG_NOT_EMPTY() )
    +     {
    +         // Obtain the character from the UART.
    +         cRxedChar = UART_RX_REG;
    +
    +         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
    +         // the first time around the loop.  If the post causes a co-routine
    +         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
    +         // In this manner we can ensure that if more than one co-routine is
    +         // blocked on the queue only one is woken by this ISR no matter how
    +         // many characters are posted to the queue.
    +         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
    +     }
    + }
    + * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
    +  crQUEUE_SEND_FROM_ISR(
    +                            QueueHandle_t pxQueue,
    +                            void *pvBuffer,
    +                            BaseType_t * pxCoRoutineWoken
    +                       )
    + * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
    + // A co-routine that posts a character to a queue then blocks for a fixed
    + // period.  The character is incremented each time.
    + static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
    + {
    + // cChar holds its value while this co-routine is blocked and must therefore
    + // be declared static.
    + static char cCharToTx = 'a';
    + BaseType_t xResult;
    +
    +     // All co-routines must start with a call to crSTART().
    +     crSTART( xHandle );
    +
    +     for( ;; )
    +     {
    +         // Send the next character to the queue.
    +         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
    +
    +         if( xResult == pdPASS )
    +         {
    +             // The character was successfully posted to the queue.
    +         }
    +         else
    +         {
    +            // Could not post the character to the queue.
    +         }
    +
    +         // Enable the UART Tx interrupt to cause an interrupt in this
    +         // hypothetical UART.  The interrupt will obtain the character
    +         // from the queue and send it.
    +         ENABLE_RX_INTERRUPT();
    +
    +         // Increment to the next character then block for a fixed period.
    +         // cCharToTx will maintain its value across the delay as it is
    +         // declared static.
    +         cCharToTx++;
    +         if( cCharToTx > 'x' )
    +         {
    +            cCharToTx = 'a';
    +         }
    +         crDELAY( 100 );
    +     }
    +
    +     // All co-routines must end with a call to crEND().
    +     crEND();
    + }
    +
    + // An ISR that uses a queue to receive characters to send on a UART.
    + void vUART_ISR( void )
    + {
    + char cCharToTx;
    + BaseType_t xCRWokenByPost = pdFALSE;
    +
    +     while( UART_TX_REG_EMPTY() )
    +     {
    +         // Are there any characters in the queue waiting to be sent?
    +         // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
    +         // is woken by the post - ensuring that only a single co-routine is
    +         // woken no matter how many times we go around this loop.
    +         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
    +         {
    +             SEND_CHARACTER( cCharToTx );
    +         }
    +     }
    + }
    + * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList(TickType_t xTicksToDelay, List_t *pxEventList); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList(const List_t *pxEventList); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/inc/os/freertos/deprecated_definitions.h b/inc/os/freertos/deprecated_definitions.h new file mode 100644 index 0000000..551c94f --- /dev/null +++ b/inc/os/freertos/deprecated_definitions.h @@ -0,0 +1,279 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT +#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" +typedef void (__interrupt __far *pxISR)(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT +#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" +typedef void (__interrupt __far *pxISR)(); +#endif + +#ifdef GCC_MEGA_AVR +#include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR +#include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT +#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT +#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT +#include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT +#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC +#include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL +#include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 +#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE +#include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx +#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 +#include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 +#include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 +#include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS +#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC +#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR +#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR +#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR +#include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR +#include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR +#include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC +#include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR +#include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S +#include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 +#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 +#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 +#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 +#include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 +#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM +#include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR +#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC +#include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE +#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 +#include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 +#include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC +#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR +#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 +#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 +#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE +#include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT +/* A short file name has to be used in place of the normal +FreeRTOSConfig.h when using the Borland compiler. */ +#include "frconfig.h" +#include "..\portable\BCC\16BitDOS\PC\prtmacro.h" +typedef void (__interrupt __far *pxISR)(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT +/* A short file name has to be used in place of the normal +FreeRTOSConfig.h when using the Borland compiler. */ +#include "frconfig.h" +#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" +typedef void (__interrupt __far *pxISR)(); +#endif + +#ifdef __GNUC__ +#ifdef __AVR32_AVR32A__ +#include "portmacro.h" +#endif +#endif + +#ifdef __ICCAVR32__ +#ifdef __CORE__ +#if __CORE__ == __AVR32A__ +#include "portmacro.h" +#endif +#endif +#endif + +#ifdef __91467D +#include "portmacro.h" +#endif + +#ifdef __96340 +#include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ +#include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ +#include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ +#include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ +#include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ +#include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ +#include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ +#include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + diff --git a/inc/os/freertos/event_groups.h b/inc/os/freertos/event_groups.h new file mode 100644 index 0000000..1e8716b --- /dev/null +++ b/inc/os/freertos/event_groups.h @@ -0,0 +1,766 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t *EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
    + EventGroupHandle_t xEventGroupCreate( void );
    + 
    + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
    +    // Declare a variable to hold the created event group.
    +    EventGroupHandle_t xCreatedEventGroup;
    +
    +    // Attempt to create the event group.
    +    xCreatedEventGroup = xEventGroupCreate();
    +
    +    // Was the event group created successfully?
    +    if( xCreatedEventGroup == NULL )
    +    {
    +        // The event group was not created because there was insufficient
    +        // FreeRTOS heap available.
    +    }
    +    else
    +    {
    +        // The event group was created.
    +    }
    +   
    + * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +EventGroupHandle_t xEventGroupCreate(void) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
    + EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
    + 
    + * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
    +    // StaticEventGroup_t is a publicly accessible structure that has the same
    +    // size and alignment requirements as the real event group structure.  It is
    +    // provided as a mechanism for applications to know the size of the event
    +    // group (which is dependent on the architecture and configuration file
    +    // settings) without breaking the strict data hiding policy by exposing the
    +    // real event group internals.  This StaticEventGroup_t variable is passed
    +    // into the xSemaphoreCreateEventGroupStatic() function and is used to store
    +    // the event group's data structures
    +    StaticEventGroup_t xEventGroupBuffer;
    +
    +    // Create the event group without dynamically allocating any memory.
    +    xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
    +   
    + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer) +PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupWaitBits(    EventGroupHandle_t xEventGroup,
    +                                        const EventBits_t uxBitsToWaitFor,
    +                                        const BaseType_t xClearOnExit,
    +                                        const BaseType_t xWaitForAllBits,
    +                                        const TickType_t xTicksToWait );
    + 
    + * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
    +   #define BIT_0    ( 1 << 0 )
    +   #define BIT_4    ( 1 << 4 )
    +
    +   void aFunction( EventGroupHandle_t xEventGroup )
    +   {
    +   EventBits_t uxBits;
    +   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
    +
    +        // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
    +        // the event group.  Clear the bits before exiting.
    +        uxBits = xEventGroupWaitBits(
    +                    xEventGroup,    // The event group being tested.
    +                    BIT_0 | BIT_4,  // The bits within the event group to wait for.
    +                    pdTRUE,         // BIT_0 and BIT_4 should be cleared before returning.
    +                    pdFALSE,        // Don't wait for both bits, either bit will do.
    +                    xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
    +
    +        if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
    +        {
    +            // xEventGroupWaitBits() returned because both bits were set.
    +        }
    +        else if( ( uxBits & BIT_0 ) != 0 )
    +        {
    +            // xEventGroupWaitBits() returned because just BIT_0 was set.
    +        }
    +        else if( ( uxBits & BIT_4 ) != 0 )
    +        {
    +            // xEventGroupWaitBits() returned because just BIT_4 was set.
    +        }
    +        else
    +        {
    +            // xEventGroupWaitBits() returned because xTicksToWait ticks passed
    +            // without either BIT_0 or BIT_4 becoming set.
    +        }
    +   }
    +   
    + * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, + const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
    + 
    + * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
    +   #define BIT_0    ( 1 << 0 )
    +   #define BIT_4    ( 1 << 4 )
    +
    +   void aFunction( EventGroupHandle_t xEventGroup )
    +   {
    +   EventBits_t uxBits;
    +
    +        // Clear bit 0 and bit 4 in xEventGroup.
    +        uxBits = xEventGroupClearBits(
    +                                xEventGroup,    // The event group being updated.
    +                                BIT_0 | BIT_4 );// The bits being cleared.
    +
    +        if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
    +        {
    +            // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
    +            // called.  Both will now be clear (not set).
    +        }
    +        else if( ( uxBits & BIT_0 ) != 0 )
    +        {
    +            // Bit 0 was set before xEventGroupClearBits() was called.  It will
    +            // now be clear.
    +        }
    +        else if( ( uxBits & BIT_4 ) != 0 )
    +        {
    +            // Bit 4 was set before xEventGroupClearBits() was called.  It will
    +            // now be clear.
    +        }
    +        else
    +        {
    +            // Neither bit 0 nor bit 4 were set in the first place.
    +        }
    +   }
    +   
    + * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
    +    BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
    + 
    + * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
    +   #define BIT_0    ( 1 << 0 )
    +   #define BIT_4    ( 1 << 4 )
    +
    +   // An event group which it is assumed has already been created by a call to
    +   // xEventGroupCreate().
    +   EventGroupHandle_t xEventGroup;
    +
    +   void anInterruptHandler( void )
    +   {
    +        // Clear bit 0 and bit 4 in xEventGroup.
    +        xResult = xEventGroupClearBitsFromISR(
    +                            xEventGroup,     // The event group being updated.
    +                            BIT_0 | BIT_4 ); // The bits being set.
    +
    +        if( xResult == pdPASS )
    +        {
    +            // The message was posted successfully.
    +        }
    +  }
    +   
    + * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) +BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear) PRIVILEGED_FUNCTION; +#else +#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
    + 
    + * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
    +   #define BIT_0    ( 1 << 0 )
    +   #define BIT_4    ( 1 << 4 )
    +
    +   void aFunction( EventGroupHandle_t xEventGroup )
    +   {
    +   EventBits_t uxBits;
    +
    +        // Set bit 0 and bit 4 in xEventGroup.
    +        uxBits = xEventGroupSetBits(
    +                            xEventGroup,    // The event group being updated.
    +                            BIT_0 | BIT_4 );// The bits being set.
    +
    +        if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
    +        {
    +            // Both bit 0 and bit 4 remained set when the function returned.
    +        }
    +        else if( ( uxBits & BIT_0 ) != 0 )
    +        {
    +            // Bit 0 remained set when the function returned, but bit 4 was
    +            // cleared.  It might be that bit 4 was cleared automatically as a
    +            // task that was waiting for bit 4 was removed from the Blocked
    +            // state.
    +        }
    +        else if( ( uxBits & BIT_4 ) != 0 )
    +        {
    +            // Bit 4 remained set when the function returned, but bit 0 was
    +            // cleared.  It might be that bit 0 was cleared automatically as a
    +            // task that was waiting for bit 0 was removed from the Blocked
    +            // state.
    +        }
    +        else
    +        {
    +            // Neither bit 0 nor bit 4 remained set.  It might be that a task
    +            // was waiting for both of the bits to be set, and the bits were
    +            // cleared as the task left the Blocked state.
    +        }
    +   }
    +   
    + * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
    +    BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
    + 
    + * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
    +   #define BIT_0    ( 1 << 0 )
    +   #define BIT_4    ( 1 << 4 )
    +
    +   // An event group which it is assumed has already been created by a call to
    +   // xEventGroupCreate().
    +   EventGroupHandle_t xEventGroup;
    +
    +   void anInterruptHandler( void )
    +   {
    +   BaseType_t xHigherPriorityTaskWoken, xResult;
    +
    +        // xHigherPriorityTaskWoken must be initialised to pdFALSE.
    +        xHigherPriorityTaskWoken = pdFALSE;
    +
    +        // Set bit 0 and bit 4 in xEventGroup.
    +        xResult = xEventGroupSetBitsFromISR(
    +                            xEventGroup,    // The event group being updated.
    +                            BIT_0 | BIT_4   // The bits being set.
    +                            &xHigherPriorityTaskWoken );
    +
    +        // Was the message posted successfully?
    +        if( xResult == pdPASS )
    +        {
    +            // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
    +            // switch should be requested.  The macro used is port specific and
    +            // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
    +            // refer to the documentation page for the port being used.
    +            portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    +        }
    +  }
    +   
    + * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) +BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, + BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; +#else +#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupSync(    EventGroupHandle_t xEventGroup,
    +                                    const EventBits_t uxBitsToSet,
    +                                    const EventBits_t uxBitsToWaitFor,
    +                                    TickType_t xTicksToWait );
    + 
    + * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
    + // Bits used by the three tasks.
    + #define TASK_0_BIT     ( 1 << 0 )
    + #define TASK_1_BIT     ( 1 << 1 )
    + #define TASK_2_BIT     ( 1 << 2 )
    +
    + #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
    +
    + // Use an event group to synchronise three tasks.  It is assumed this event
    + // group has already been created elsewhere.
    + EventGroupHandle_t xEventBits;
    +
    + void vTask0( void *pvParameters )
    + {
    + EventBits_t uxReturn;
    + TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
    +
    +     for( ;; )
    +     {
    +        // Perform task functionality here.
    +
    +        // Set bit 0 in the event flag to note this task has reached the
    +        // sync point.  The other two tasks will set the other two bits defined
    +        // by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
    +        // point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
    +        // for this to happen.
    +        uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
    +
    +        if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
    +        {
    +            // All three tasks reached the synchronisation point before the call
    +            // to xEventGroupSync() timed out.
    +        }
    +    }
    + }
    +
    + void vTask1( void *pvParameters )
    + {
    +     for( ;; )
    +     {
    +        // Perform task functionality here.
    +
    +        // Set bit 1 in the event flag to note this task has reached the
    +        // synchronisation point.  The other two tasks will set the other two
    +        // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
    +        // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
    +        // indefinitely for this to happen.
    +        xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
    +
    +        // xEventGroupSync() was called with an indefinite block time, so
    +        // this task will only reach here if the syncrhonisation was made by all
    +        // three tasks, so there is no need to test the return value.
    +     }
    + }
    +
    + void vTask2( void *pvParameters )
    + {
    +     for( ;; )
    +     {
    +        // Perform task functionality here.
    +
    +        // Set bit 2 in the event flag to note this task has reached the
    +        // synchronisation point.  The other two tasks will set the other two
    +        // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
    +        // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
    +        // indefinitely for this to happen.
    +        xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
    +
    +        // xEventGroupSync() was called with an indefinite block time, so
    +        // this task will only reach here if the syncrhonisation was made by all
    +        // three tasks, so there is no need to test the return value.
    +    }
    + }
    +
    + 
    + * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
    + 
    + * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
    +    EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
    + 
    + * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
    +    void xEventGroupDelete( EventGroupHandle_t xEventGroup );
    + 
    + * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete(EventGroupHandle_t xEventGroup) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback(void *pvEventGroup, const uint32_t ulBitsToSet) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback(void *pvEventGroup, + const uint32_t ulBitsToClear) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) +UBaseType_t uxEventGroupGetNumber(void *xEventGroup) PRIVILEGED_FUNCTION; +void vEventGroupSetNumber(void *xEventGroup, UBaseType_t uxEventGroupNumber) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + diff --git a/inc/os/freertos/list.h b/inc/os/freertos/list.h new file mode 100644 index 0000000..b89da5c --- /dev/null +++ b/inc/os/freertos/list.h @@ -0,0 +1,419 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H +#error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE +#define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) +/* Define the macros to do nothing. */ +#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE +#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE +#define listFIRST_LIST_INTEGRITY_CHECK_VALUE +#define listSECOND_LIST_INTEGRITY_CHECK_VALUE +#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) +#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) +#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) +#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) +#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) +#define listTEST_LIST_INTEGRITY( pxList ) +#else +/* Define macros that add new members into the list structures. */ +#define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; +#define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; +#define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; +#define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + +/* Define macros that set the new structure members to known values. */ +#define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE +#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE +#define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE +#define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + +/* Define macros that will assert if one of the structure members does not +contain its expected value. */ +#define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t + xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM *configLIST_VOLATILE + pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM *configLIST_VOLATILE + pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void *pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST *configLIST_VOLATILE + pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM + ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM *configLIST_VOLATILE pxNext; + struct xLIST_ITEM *configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t *configLIST_VOLATILE + pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t + xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ + { \ + List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ + } + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise(List_t *const pxList) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem(ListItem_t *const pxItem) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/os/freertos/message_buffer.h b/inc/os/freertos/message_buffer.h new file mode 100644 index 0000000..c102689 --- /dev/null +++ b/inc/os/freertos/message_buffer.h @@ -0,0 +1,799 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. + */ +typedef void *MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * +
    +MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
    +
    + * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: +
    +
    +void vAFunction( void )
    +{
    +MessageBufferHandle_t xMessageBuffer;
    +const size_t xMessageBufferSizeBytes = 100;
    +
    +    // Create a message buffer that can hold 100 bytes.  The memory used to hold
    +    // both the message buffer structure and the messages themselves is allocated
    +    // dynamically.  Each message added to the buffer consumes an additional 4
    +    // bytes which are used to hold the lengh of the message.
    +    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
    +
    +    if( xMessageBuffer == NULL )
    +    {
    +        // There was not enough heap memory space available to create the
    +        // message buffer.
    +    }
    +    else
    +    {
    +        // The message buffer was created successfully and can now be used.
    +    }
    +
    +
    + * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) + +/** + * message_buffer.h + * +
    +MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
    +                                                  uint8_t *pucMessageBufferStorageArea,
    +                                                  StaticMessageBuffer_t *pxStaticMessageBuffer );
    +
    + * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: +
    +
    +// Used to dimension the array used to hold the messages.  The available space
    +// will actually be one less than this, so 999.
    +#define STORAGE_SIZE_BYTES 1000
    +
    +// Defines the memory that will actually hold the messages within the message
    +// buffer.
    +static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
    +
    +// The variable used to hold the message buffer structure.
    +StaticMessageBuffer_t xMessageBufferStruct;
    +
    +void MyFunction( void )
    +{
    +MessageBufferHandle_t xMessageBuffer;
    +
    +    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
    +                                                 ucBufferStorage,
    +                                                 &xMessageBufferStruct );
    +
    +    // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
    +    // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
    +    // reference the created message buffer in other message buffer API calls.
    +
    +    // Other code that uses the message buffer can go here.
    +}
    +
    +
    + * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) + +/** + * message_buffer.h + * +
    +size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
    +                           const void *pvTxData,
    +                           size_t xDataLengthBytes,
    +                           TickType_t xTicksToWait );
    +
    + *
    + * Sends a discrete message to the message buffer.  The message can be any
    + * length that fits within the buffer's free space, and is copied into the
    + * buffer.
    + *
    + * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
    + * implementation (so also the message buffer implementation, as message buffers
    + * are built on top of stream buffers) assumes there is only one task or
    + * interrupt that will write to the buffer (the writer), and only one task or
    + * interrupt that will read from the buffer (the reader).  It is safe for the
    + * writer and reader to be different tasks or interrupts, but, unlike other
    + * FreeRTOS objects, it is not safe to have multiple different writers or
    + * multiple different readers.  If there are to be multiple different writers
    + * then the application writer must place each call to a writing API function
    + * (such as xMessageBufferSend()) inside a critical section and set the send
    + * block time to 0.  Likewise, if there are to be multiple different readers
    + * then the application writer must place each call to a reading API function
    + * (such as xMessageBufferRead()) inside a critical section and set the receive
    + * block time to 0.
    + *
    + * Use xMessageBufferSend() to write to a message buffer from a task.  Use
    + * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
    + * service routine (ISR).
    + *
    + * @param xMessageBuffer The handle of the message buffer to which a message is
    + * being sent.
    + *
    + * @param pvTxData A pointer to the message that is to be copied into the
    + * message buffer.
    + *
    + * @param xDataLengthBytes The length of the message.  That is, the number of
    + * bytes to copy from pvTxData into the message buffer.  When a message is
    + * written to the message buffer an additional sizeof( size_t ) bytes are also
    + * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
    + * on a 32-bit architecture, so on most 32-bit architecture setting
    + * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
    + * bytes (20 bytes of message data and 4 bytes to hold the message length).
    + *
    + * @param xTicksToWait The maximum amount of time the calling task should remain
    + * in the Blocked state to wait for enough space to become available in the
    + * message buffer, should the message buffer have insufficient space when
    + * xMessageBufferSend() is called.  The calling task will never block if
    + * xTicksToWait is zero.  The block time is specified in tick periods, so the
    + * absolute time it represents is dependent on the tick frequency.  The macro
    + * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
    + * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
    + * the task to wait indefinitely (without timing out), provided
    + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
    + * CPU time when they are in the Blocked state.
    + *
    + * @return The number of bytes written to the message buffer.  If the call to
    + * xMessageBufferSend() times out before there was enough space to write the
    + * message into the message buffer then zero is returned.  If the call did not
    + * time out then xDataLengthBytes is returned.
    + *
    + * Example use:
    +
    +void vAFunction( MessageBufferHandle_t xMessageBuffer )
    +{
    +size_t xBytesSent;
    +uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
    +char *pcStringToSend = "String to send";
    +const TickType_t x100ms = pdMS_TO_TICKS( 100 );
    +
    +    // Send an array to the message buffer, blocking for a maximum of 100ms to
    +    // wait for enough space to be available in the message buffer.
    +    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
    +
    +    if( xBytesSent != sizeof( ucArrayToSend ) )
    +    {
    +        // The call to xMessageBufferSend() times out before there was enough
    +        // space in the buffer for the data to be written.
    +    }
    +
    +    // Send the string to the message buffer.  Return immediately if there is
    +    // not enough space in the buffer.
    +    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
    +
    +    if( xBytesSent != strlen( pcStringToSend ) )
    +    {
    +        // The string could not be added to the message buffer because there was
    +        // not enough free space in the buffer.
    +    }
    +}
    +
    + * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) + +/** + * message_buffer.h + * +
    +size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
    +                                  const void *pvTxData,
    +                                  size_t xDataLengthBytes,
    +                                  BaseType_t *pxHigherPriorityTaskWoken );
    +
    + *
    + * Interrupt safe version of the API function that sends a discrete message to
    + * the message buffer.  The message can be any length that fits within the
    + * buffer's free space, and is copied into the buffer.
    + *
    + * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
    + * implementation (so also the message buffer implementation, as message buffers
    + * are built on top of stream buffers) assumes there is only one task or
    + * interrupt that will write to the buffer (the writer), and only one task or
    + * interrupt that will read from the buffer (the reader).  It is safe for the
    + * writer and reader to be different tasks or interrupts, but, unlike other
    + * FreeRTOS objects, it is not safe to have multiple different writers or
    + * multiple different readers.  If there are to be multiple different writers
    + * then the application writer must place each call to a writing API function
    + * (such as xMessageBufferSend()) inside a critical section and set the send
    + * block time to 0.  Likewise, if there are to be multiple different readers
    + * then the application writer must place each call to a reading API function
    + * (such as xMessageBufferRead()) inside a critical section and set the receive
    + * block time to 0.
    + *
    + * Use xMessageBufferSend() to write to a message buffer from a task.  Use
    + * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
    + * service routine (ISR).
    + *
    + * @param xMessageBuffer The handle of the message buffer to which a message is
    + * being sent.
    + *
    + * @param pvTxData A pointer to the message that is to be copied into the
    + * message buffer.
    + *
    + * @param xDataLengthBytes The length of the message.  That is, the number of
    + * bytes to copy from pvTxData into the message buffer.  When a message is
    + * written to the message buffer an additional sizeof( size_t ) bytes are also
    + * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
    + * on a 32-bit architecture, so on most 32-bit architecture setting
    + * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
    + * bytes (20 bytes of message data and 4 bytes to hold the message length).
    + *
    + * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
    + * have a task blocked on it waiting for data.  Calling
    + * xMessageBufferSendFromISR() can make data available, and so cause a task that
    + * was waiting for data to leave the Blocked state.  If calling
    + * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
    + * unblocked task has a priority higher than the currently executing task (the
    + * task that was interrupted), then, internally, xMessageBufferSendFromISR()
    + * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
    + * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
    + * context switch should be performed before the interrupt is exited.  This will
    + * ensure that the interrupt returns directly to the highest priority Ready
    + * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
    + * is passed into the function.  See the code example below for an example.
    + *
    + * @return The number of bytes actually written to the message buffer.  If the
    + * message buffer didn't have enough free space for the message to be stored
    + * then 0 is returned, otherwise xDataLengthBytes is returned.
    + *
    + * Example use:
    +
    +// A message buffer that has already been created.
    +MessageBufferHandle_t xMessageBuffer;
    +
    +void vAnInterruptServiceRoutine( void )
    +{
    +size_t xBytesSent;
    +char *pcStringToSend = "String to send";
    +BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
    +
    +    // Attempt to send the string to the message buffer.
    +    xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
    +                                            ( void * ) pcStringToSend,
    +                                            strlen( pcStringToSend ),
    +                                            &xHigherPriorityTaskWoken );
    +
    +    if( xBytesSent != strlen( pcStringToSend ) )
    +    {
    +        // The string could not be added to the message buffer because there was
    +        // not enough free space in the buffer.
    +    }
    +
    +    // If xHigherPriorityTaskWoken was set to pdTRUE inside
    +    // xMessageBufferSendFromISR() then a task that has a priority above the
    +    // priority of the currently executing task was unblocked and a context
    +    // switch should be performed to ensure the ISR returns to the unblocked
    +    // task.  In most FreeRTOS ports this is done by simply passing
    +    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
    +    // variables value, and perform the context switch if necessary.  Check the
    +    // documentation for the port in use for port specific instructions.
    +    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    +}
    +
    + * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
    +size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
    +                              void *pvRxData,
    +                              size_t xBufferLengthBytes,
    +                              TickType_t xTicksToWait );
    +
    + * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: +
    +void vAFunction( MessageBuffer_t xMessageBuffer )
    +{
    +uint8_t ucRxData[ 20 ];
    +size_t xReceivedBytes;
    +const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
    +
    +    // Receive the next message from the message buffer.  Wait in the Blocked
    +    // state (so not using any CPU processing time) for a maximum of 100ms for
    +    // a message to become available.
    +    xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
    +                                            ( void * ) ucRxData,
    +                                            sizeof( ucRxData ),
    +                                            xBlockTime );
    +
    +    if( xReceivedBytes > 0 )
    +    {
    +        // A ucRxData contains a message that is xReceivedBytes long.  Process
    +        // the message here....
    +    }
    +}
    +
    + * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) + + +/** + * message_buffer.h + * +
    +size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
    +                                     void *pvRxData,
    +                                     size_t xBufferLengthBytes,
    +                                     BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: +
    +// A message buffer that has already been created.
    +MessageBuffer_t xMessageBuffer;
    +
    +void vAnInterruptServiceRoutine( void )
    +{
    +uint8_t ucRxData[ 20 ];
    +size_t xReceivedBytes;
    +BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
    +
    +    // Receive the next message from the message buffer.
    +    xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
    +                                                  ( void * ) ucRxData,
    +                                                  sizeof( ucRxData ),
    +                                                  &xHigherPriorityTaskWoken );
    +
    +    if( xReceivedBytes > 0 )
    +    {
    +        // A ucRxData contains a message that is xReceivedBytes long.  Process
    +        // the message here....
    +    }
    +
    +    // If xHigherPriorityTaskWoken was set to pdTRUE inside
    +    // xMessageBufferReceiveFromISR() then a task that has a priority above the
    +    // priority of the currently executing task was unblocked and a context
    +    // switch should be performed to ensure the ISR returns to the unblocked
    +    // task.  In most FreeRTOS ports this is done by simply passing
    +    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
    +    // variables value, and perform the context switch if necessary.  Check the
    +    // documentation for the port in use for port specific instructions.
    +    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    +}
    +
    + * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
    +void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
    +
    + * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
    +BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
    +
    + * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
    +BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
    +
    + * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
    +BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
    +
    + * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) + + +/** + * message_buffer.h +
    +size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
    +
    + * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) +#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ + +/** + * message_buffer.h +
    + size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
    + 
    + * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * +
    +BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
    +BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ diff --git a/inc/os/freertos/mpu_prototypes.h b/inc/os/freertos/mpu_prototypes.h new file mode 100644 index 0000000..b96b75f --- /dev/null +++ b/inc/os/freertos/mpu_prototypes.h @@ -0,0 +1,210 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API functions. */ +BaseType_t MPU_xTaskCreate(TaskFunction_t pxTaskCode, const char *const pcName, + const uint16_t usStackDepth, void *const pvParameters, UBaseType_t uxPriority, + TaskHandle_t *const pxCreatedTask) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskCreateStatic(TaskFunction_t pxTaskCode, const char *const pcName, + const uint32_t ulStackDepth, void *const pvParameters, UBaseType_t uxPriority, + StackType_t *const puxStackBuffer, StaticTask_t *const pxTaskBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestricted(const TaskParameters_t *const pxTaskDefinition, + TaskHandle_t *pxCreatedTask) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestrictedStatic(const TaskParameters_t *const pxTaskDefinition, + TaskHandle_t *pxCreatedTask) FREERTOS_SYSTEM_CALL; +void MPU_vTaskAllocateMPURegions(TaskHandle_t xTask, + const MemoryRegion_t *const pxRegions) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelete(TaskHandle_t xTaskToDelete) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelay(const TickType_t xTicksToDelay) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelayUntil(TickType_t *const pxPreviousWakeTime, + const TickType_t xTimeIncrement) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet(const TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, + eTaskState eState) FREERTOS_SYSTEM_CALL; +void MPU_vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend(TaskHandle_t xTaskToSuspend) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume(TaskHandle_t xTaskToResume) FREERTOS_SYSTEM_CALL; +void MPU_vTaskStartScheduler(void) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspendAll(void) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskResumeAll(void) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetTickCount(void) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks(void) FREERTOS_SYSTEM_CALL; +char *MPU_pcTaskGetName(TaskHandle_t xTaskToQuery) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetHandle(const char *pcNameToQuery) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag(TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, + void *pvValue) FREERTOS_SYSTEM_CALL; +void *MPU_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, + BaseType_t xIndex) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCallApplicationTaskHook(TaskHandle_t xTask, + void *pvParameter) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle(void) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, + const UBaseType_t uxArraySize, uint32_t *const pulTotalRunTime) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetIdleRunTimeCounter(void) FREERTOS_SYSTEM_CALL; +void MPU_vTaskList(char *pcWriteBuffer) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetRunTimeStats(char *pcWriteBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, + eNotifyAction eAction, uint32_t *pulPreviousNotificationValue) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, + uint32_t *pulNotificationValue, TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskNotifyTake(BaseType_t xClearCountOnExit, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyStateClear(TaskHandle_t xTask) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskIncrementTick(void) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle(void) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState(TimeOut_t *const pxTimeOut) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, + TickType_t *const pxTicksToWait) FREERTOS_SYSTEM_CALL; +void MPU_vTaskMissedYield(void) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState(void) FREERTOS_SYSTEM_CALL; + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend(QueueHandle_t xQueue, const void *const pvItemToQueue, + TickType_t xTicksToWait, const BaseType_t xCopyPosition) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive(QueueHandle_t xQueue, void *const pvBuffer, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek(QueueHandle_t xQueue, void *const pvBuffer, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueSemaphoreTake(QueueHandle_t xQueue, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting(const QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable(const QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +void MPU_vQueueDelete(QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutex(const uint8_t ucQueueType) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutexStatic(const uint8_t ucQueueType, + StaticQueue_t *pxStaticQueue) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphore(const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic(const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder(QueueHandle_t xSemaphore) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueTakeMutexRecursive(QueueHandle_t xMutex, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive(QueueHandle_t pxMutex) FREERTOS_SYSTEM_CALL; +void MPU_vQueueAddToRegistry(QueueHandle_t xQueue, const char *pcName) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue(QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +const char *MPU_pcQueueGetName(QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreate(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, + const uint8_t ucQueueType) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreateStatic(const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, + const uint8_t ucQueueType) FREERTOS_SYSTEM_CALL; +QueueSetHandle_t MPU_xQueueCreateSet(const UBaseType_t uxEventQueueLength) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet(QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGenericReset(QueueHandle_t xQueue, BaseType_t xNewQueue) FREERTOS_SYSTEM_CALL; +void MPU_vQueueSetQueueNumber(QueueHandle_t xQueue, UBaseType_t uxQueueNumber) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueGetQueueNumber(QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; +uint8_t MPU_ucQueueGetQueueType(QueueHandle_t xQueue) FREERTOS_SYSTEM_CALL; + +/* MPU versions of timers.h API functions. */ +TimerHandle_t MPU_xTimerCreate(const char *const pcTimerName, const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, void *const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction) FREERTOS_SYSTEM_CALL; +TimerHandle_t MPU_xTimerCreateStatic(const char *const pcTimerName, + const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void *const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer) FREERTOS_SYSTEM_CALL; +void *MPU_pvTimerGetTimerID(const TimerHandle_t xTimer) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive(TimerHandle_t xTimer) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle(void) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void *pvParameter1, + uint32_t ulParameter2, TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +const char *MPU_pcTimerGetName(TimerHandle_t xTimer) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetReloadMode(TimerHandle_t xTimer, + const UBaseType_t uxAutoReload) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod(TimerHandle_t xTimer) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime(TimerHandle_t xTimer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerCreateTimerTask(void) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand(TimerHandle_t xTimer, const BaseType_t xCommandID, + const TickType_t xOptionalValue, BaseType_t *const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; + +/* MPU versions of event_group.h API functions. */ +EventGroupHandle_t MPU_xEventGroupCreate(void) FREERTOS_SYSTEM_CALL; +EventGroupHandle_t MPU_xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer) +FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBits(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, + TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits(EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, + const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +void MPU_vEventGroupDelete(EventGroupHandle_t xEventGroup) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxEventGroupGetNumber(void *xEventGroup) FREERTOS_SYSTEM_CALL; + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend(StreamBufferHandle_t xStreamBuffer, const void *pvTxData, + size_t xDataLengthBytes, TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive(StreamBufferHandle_t xStreamBuffer, void *pvRxData, + size_t xBufferLengthBytes, TickType_t xTicksToWait) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes(StreamBufferHandle_t xStreamBuffer) +FREERTOS_SYSTEM_CALL; +void MPU_vStreamBufferDelete(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferReset(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable(StreamBufferHandle_t xStreamBuffer) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel(StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreate(size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic(size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t *const pucStreamBufferStorageArea, + StaticStreamBuffer_t *const pxStaticStreamBuffer) FREERTOS_SYSTEM_CALL; + + + +#endif /* MPU_PROTOTYPES_H */ + diff --git a/inc/os/freertos/mpu_wrappers.h b/inc/os/freertos/mpu_wrappers.h new file mode 100644 index 0000000..8571f30 --- /dev/null +++ b/inc/os/freertos/mpu_wrappers.h @@ -0,0 +1,186 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + +/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is +included from queue.c or task.c to prevent it from having an effect within +those files. */ +#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + +/* Map standard tasks.h API functions to the MPU equivalents. */ +#define xTaskCreate MPU_xTaskCreate +#define xTaskCreateStatic MPU_xTaskCreateStatic +#define xTaskCreateRestricted MPU_xTaskCreateRestricted +#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions +#define vTaskDelete MPU_vTaskDelete +#define vTaskDelay MPU_vTaskDelay +#define vTaskDelayUntil MPU_vTaskDelayUntil +#define xTaskAbortDelay MPU_xTaskAbortDelay +#define uxTaskPriorityGet MPU_uxTaskPriorityGet +#define eTaskGetState MPU_eTaskGetState +#define vTaskGetInfo MPU_vTaskGetInfo +#define vTaskPrioritySet MPU_vTaskPrioritySet +#define vTaskSuspend MPU_vTaskSuspend +#define vTaskResume MPU_vTaskResume +#define vTaskSuspendAll MPU_vTaskSuspendAll +#define xTaskResumeAll MPU_xTaskResumeAll +#define xTaskGetTickCount MPU_xTaskGetTickCount +#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks +#define pcTaskGetName MPU_pcTaskGetName +#define xTaskGetHandle MPU_xTaskGetHandle +#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark +#define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 +#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag +#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag +#define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer +#define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer +#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook +#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle +#define uxTaskGetSystemState MPU_uxTaskGetSystemState +#define vTaskList MPU_vTaskList +#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats +#define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter +#define xTaskGenericNotify MPU_xTaskGenericNotify +#define xTaskNotifyWait MPU_xTaskNotifyWait +#define ulTaskNotifyTake MPU_ulTaskNotifyTake +#define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + +#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle +#define vTaskSetTimeOutState MPU_vTaskSetTimeOutState +#define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut +#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + +/* Map standard queue.h API functions to the MPU equivalents. */ +#define xQueueGenericSend MPU_xQueueGenericSend +#define xQueueReceive MPU_xQueueReceive +#define xQueuePeek MPU_xQueuePeek +#define xQueueSemaphoreTake MPU_xQueueSemaphoreTake +#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting +#define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable +#define vQueueDelete MPU_vQueueDelete +#define xQueueCreateMutex MPU_xQueueCreateMutex +#define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic +#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore +#define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic +#define xQueueGetMutexHolder MPU_xQueueGetMutexHolder +#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive +#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive +#define xQueueGenericCreate MPU_xQueueGenericCreate +#define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic +#define xQueueCreateSet MPU_xQueueCreateSet +#define xQueueAddToSet MPU_xQueueAddToSet +#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet +#define xQueueSelectFromSet MPU_xQueueSelectFromSet +#define xQueueGenericReset MPU_xQueueGenericReset + +#if( configQUEUE_REGISTRY_SIZE > 0 ) +#define vQueueAddToRegistry MPU_vQueueAddToRegistry +#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue +#define pcQueueGetName MPU_pcQueueGetName +#endif + +/* Map standard timer.h API functions to the MPU equivalents. */ +#define xTimerCreate MPU_xTimerCreate +#define xTimerCreateStatic MPU_xTimerCreateStatic +#define pvTimerGetTimerID MPU_pvTimerGetTimerID +#define vTimerSetTimerID MPU_vTimerSetTimerID +#define xTimerIsTimerActive MPU_xTimerIsTimerActive +#define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle +#define xTimerPendFunctionCall MPU_xTimerPendFunctionCall +#define pcTimerGetName MPU_pcTimerGetName +#define vTimerSetReloadMode MPU_vTimerSetReloadMode +#define xTimerGetPeriod MPU_xTimerGetPeriod +#define xTimerGetExpiryTime MPU_xTimerGetExpiryTime +#define xTimerGenericCommand MPU_xTimerGenericCommand + +/* Map standard event_group.h API functions to the MPU equivalents. */ +#define xEventGroupCreate MPU_xEventGroupCreate +#define xEventGroupCreateStatic MPU_xEventGroupCreateStatic +#define xEventGroupWaitBits MPU_xEventGroupWaitBits +#define xEventGroupClearBits MPU_xEventGroupClearBits +#define xEventGroupSetBits MPU_xEventGroupSetBits +#define xEventGroupSync MPU_xEventGroupSync +#define vEventGroupDelete MPU_vEventGroupDelete + +/* Map standard message/stream_buffer.h API functions to the MPU +equivalents. */ +#define xStreamBufferSend MPU_xStreamBufferSend +#define xStreamBufferReceive MPU_xStreamBufferReceive +#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes +#define vStreamBufferDelete MPU_vStreamBufferDelete +#define xStreamBufferIsFull MPU_xStreamBufferIsFull +#define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty +#define xStreamBufferReset MPU_xStreamBufferReset +#define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable +#define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable +#define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel +#define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate +#define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + + +/* Remove the privileged function macro, but keep the PRIVILEGED_DATA +macro so applications can place data in privileged access sections +(useful when using statically allocated objects). */ +#define PRIVILEGED_FUNCTION +#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) +#define FREERTOS_SYSTEM_CALL + +#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +/* Ensure API functions go in the privileged execution section. */ +#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) +#define PRIVILEGED_DATA __attribute__((section("privileged_data"))) +#define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) + +#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + +#define PRIVILEGED_FUNCTION +#define PRIVILEGED_DATA +#define FREERTOS_SYSTEM_CALL +#define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/inc/os/freertos/portable.h b/inc/os/freertos/portable.h new file mode 100644 index 0000000..ab43b55 --- /dev/null +++ b/inc/os/freertos/portable.h @@ -0,0 +1,189 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL +#include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 +#define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 +#define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 +#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 +#define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 +#define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 +#define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK +#error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS +#define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifndef portHAS_STACK_OVERFLOW_CHECKING +#define portHAS_STACK_OVERFLOW_CHECKING 0 +#endif + +#ifndef portARCH_NAME +#define portARCH_NAME NULL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" +#include "mem_types.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) +StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, + TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged) PRIVILEGED_FUNCTION; +#else +StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, + void *pvParameters, BaseType_t xRunPrivileged) PRIVILEGED_FUNCTION; +#endif +#else +#if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) +StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, + TaskFunction_t pxCode, void *pvParameters) PRIVILEGED_FUNCTION; +#else +StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxCode, + void *pvParameters) PRIVILEGED_FUNCTION; +#endif +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions(const HeapRegion_t *const pxHeapRegions) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc(RAM_TYPE ramType, size_t xSize) PRIVILEGED_FUNCTION; +void *pvPortMalloc_auto_type(size_t xWantedSize) PRIVILEGED_FUNCTION; +void vPortFree(void *pv) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks(void) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize(RAM_TYPE ramType) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize(RAM_TYPE ramType) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler(void) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler(void) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +struct xMEMORY_REGION; +void vPortStoreTaskMPUSettings(xMPU_SETTINGS *xMPUSettings, + const struct xMEMORY_REGION *const xRegions, StackType_t *pxBottomOfStack, + uint32_t ulStackDepth) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/inc/os/freertos/portmacro.h b/inc/os/freertos/portmacro.h new file mode 100644 index 0000000..180bcd7 --- /dev/null +++ b/inc/os/freertos/portmacro.h @@ -0,0 +1,116 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) +typedef uint16_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffff +#else +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do +not need to be guarded with a critical section. */ +#define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + + +/* Scheduler utilities. */ +extern void vPortYield(void); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +extern uint32_t rtlEnterCritical(void); +extern void rtlExitCritical(uint32_t ulSavedInterruptStatus); +extern uint32_t ulSetInterruptMaskFromISR(void); +extern void vClearInterruptMaskFromISR(uint32_t ulMask); + +#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vClearInterruptMaskFromISR( x ) +#define portDISABLE_INTERRUPTS() __disable_irq() +#define portENABLE_INTERRUPTS() __enable_irq() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/inc/os/freertos/projdefs.h b/inc/os/freertos/projdefs.h new file mode 100644 index 0000000..4bb7e78 --- /dev/null +++ b/inc/os/freertos/projdefs.h @@ -0,0 +1,124 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)(void *); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS +#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES +#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) +#define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else +#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ + + + diff --git a/inc/os/freertos/queue.h b/inc/os/freertos/queue.h new file mode 100644 index 0000000..967800b --- /dev/null +++ b/inc/os/freertos/queue.h @@ -0,0 +1,1676 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition *QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition *QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition *QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
    + QueueHandle_t xQueueCreate(
    +                              UBaseType_t uxQueueLength,
    +                              UBaseType_t uxItemSize
    +                          );
    + * 
    + * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + };
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1, xQueue2;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
    +    if( xQueue1 == 0 )
    +    {
    +        // Queue was not created and must not be used.
    +    }
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +    if( xQueue2 == 0 )
    +    {
    +        // Queue was not created and must not be used.
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
    + QueueHandle_t xQueueCreateStatic(
    +                              UBaseType_t uxQueueLength,
    +                              UBaseType_t uxItemSize,
    +                              uint8_t *pucQueueStorageBuffer,
    +                              StaticQueue_t *pxQueueBuffer
    +                          );
    + * 
    + * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + };
    +
    + #define QUEUE_LENGTH 10
    + #define ITEM_SIZE sizeof( uint32_t )
    +
    + // xQueueBuffer will hold the queue structure.
    + StaticQueue_t xQueueBuffer;
    +
    + // ucQueueStorage will hold the items posted to the queue.  Must be at least
    + // [(queue length) * ( queue item size)] bytes long.
    + uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
    +                            ITEM_SIZE     // The size of each item in the queue
    +                            &( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
    +                            &xQueueBuffer ); // The buffer that will hold the queue structure.
    +
    +    // The queue is guaranteed to be created successfully as no dynamic memory
    +    // allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
    + BaseType_t xQueueSendToToFront(
    +                                   QueueHandle_t    xQueue,
    +                                   const void       *pvItemToQueue,
    +                                   TickType_t       xTicksToWait
    +                               );
    + * 
    + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + uint32_t ulVar = 10UL;
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1, xQueue2;
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +
    +    // ...
    +
    +    if( xQueue1 != 0 )
    +    {
    +        // Send an uint32_t.  Wait for 10 ticks for space to become
    +        // available if necessary.
    +        if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
    +        {
    +            // Failed to post the message, even after 10 ticks.
    +        }
    +    }
    +
    +    if( xQueue2 != 0 )
    +    {
    +        // Send a pointer to a struct AMessage object.  Don't block if the
    +        // queue is already full.
    +        pxMessage = & xMessage;
    +        xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
    + BaseType_t xQueueSendToBack(
    +                                   QueueHandle_t    xQueue,
    +                                   const void       *pvItemToQueue,
    +                                   TickType_t       xTicksToWait
    +                               );
    + * 
    + * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + uint32_t ulVar = 10UL;
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1, xQueue2;
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +
    +    // ...
    +
    +    if( xQueue1 != 0 )
    +    {
    +        // Send an uint32_t.  Wait for 10 ticks for space to become
    +        // available if necessary.
    +        if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
    +        {
    +            // Failed to post the message, even after 10 ticks.
    +        }
    +    }
    +
    +    if( xQueue2 != 0 )
    +    {
    +        // Send a pointer to a struct AMessage object.  Don't block if the
    +        // queue is already full.
    +        pxMessage = & xMessage;
    +        xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
    + BaseType_t xQueueSend(
    +                              QueueHandle_t xQueue,
    +                              const void * pvItemToQueue,
    +                              TickType_t xTicksToWait
    +                         );
    + * 
    + * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + uint32_t ulVar = 10UL;
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1, xQueue2;
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +
    +    // ...
    +
    +    if( xQueue1 != 0 )
    +    {
    +        // Send an uint32_t.  Wait for 10 ticks for space to become
    +        // available if necessary.
    +        if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
    +        {
    +            // Failed to post the message, even after 10 ticks.
    +        }
    +    }
    +
    +    if( xQueue2 != 0 )
    +    {
    +        // Send a pointer to a struct AMessage object.  Don't block if the
    +        // queue is already full.
    +        pxMessage = & xMessage;
    +        xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
    + BaseType_t xQueueOverwrite(
    +                              QueueHandle_t xQueue,
    +                              const void * pvItemToQueue
    +                         );
    + * 
    + * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
    +
    + void vFunction( void *pvParameters )
    + {
    + QueueHandle_t xQueue;
    + uint32_t ulVarToSend, ulValReceived;
    +
    +    // Create a queue to hold one uint32_t value.  It is strongly
    +    // recommended *not* to use xQueueOverwrite() on queues that can
    +    // contain more than one value, and doing so will trigger an assertion
    +    // if configASSERT() is defined.
    +    xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
    +
    +    // Write the value 10 to the queue using xQueueOverwrite().
    +    ulVarToSend = 10;
    +    xQueueOverwrite( xQueue, &ulVarToSend );
    +
    +    // Peeking the queue should now return 10, but leave the value 10 in
    +    // the queue.  A block time of zero is used as it is known that the
    +    // queue holds a value.
    +    ulValReceived = 0;
    +    xQueuePeek( xQueue, &ulValReceived, 0 );
    +
    +    if( ulValReceived != 10 )
    +    {
    +        // Error unless the item was removed by a different task.
    +    }
    +
    +    // The queue is still full.  Use xQueueOverwrite() to overwrite the
    +    // value held in the queue with 100.
    +    ulVarToSend = 100;
    +    xQueueOverwrite( xQueue, &ulVarToSend );
    +
    +    // This time read from the queue, leaving the queue empty once more.
    +    // A block time of 0 is used again.
    +    xQueueReceive( xQueue, &ulValReceived, 0 );
    +
    +    // The value read should be the last value written, even though the
    +    // queue was already full when the value was written.
    +    if( ulValReceived != 100 )
    +    {
    +        // Error!
    +    }
    +
    +    // ...
    +}
    + 
    + * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
    + BaseType_t xQueueGenericSend(
    +                                    QueueHandle_t xQueue,
    +                                    const void * pvItemToQueue,
    +                                    TickType_t xTicksToWait
    +                                    BaseType_t xCopyPosition
    +                                );
    + * 
    + * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + uint32_t ulVar = 10UL;
    +
    + void vATask( void *pvParameters )
    + {
    + QueueHandle_t xQueue1, xQueue2;
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 uint32_t values.
    +    xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +
    +    // ...
    +
    +    if( xQueue1 != 0 )
    +    {
    +        // Send an uint32_t.  Wait for 10 ticks for space to become
    +        // available if necessary.
    +        if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
    +        {
    +            // Failed to post the message, even after 10 ticks.
    +        }
    +    }
    +
    +    if( xQueue2 != 0 )
    +    {
    +        // Send a pointer to a struct AMessage object.  Don't block if the
    +        // queue is already full.
    +        pxMessage = & xMessage;
    +        xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend(QueueHandle_t xQueue, const void *const pvItemToQueue, + TickType_t xTicksToWait, const BaseType_t xCopyPosition) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    + BaseType_t xQueuePeek(
    +                             QueueHandle_t xQueue,
    +                             void * const pvBuffer,
    +                             TickType_t xTicksToWait
    +                         );
    + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + QueueHandle_t xQueue;
    +
    + // Task to create a queue and post a value.
    + void vATask( void *pvParameters )
    + {
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +    if( xQueue == 0 )
    +    {
    +        // Failed to create the queue.
    +    }
    +
    +    // ...
    +
    +    // Send a pointer to a struct AMessage object.  Don't block if the
    +    // queue is already full.
    +    pxMessage = & xMessage;
    +    xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
    +
    +    // ... Rest of task code.
    + }
    +
    + // Task to peek the data from the queue.
    + void vADifferentTask( void *pvParameters )
    + {
    + struct AMessage *pxRxedMessage;
    +
    +    if( xQueue != 0 )
    +    {
    +        // Peek a message on the created queue.  Block for 10 ticks if a
    +        // message is not immediately available.
    +        if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
    +        {
    +            // pcRxedMessage now points to the struct AMessage variable posted
    +            // by vATask, but the item still remains on the queue.
    +        }
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek(QueueHandle_t xQueue, void *const pvBuffer, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    + BaseType_t xQueuePeekFromISR(
    +                                    QueueHandle_t xQueue,
    +                                    void *pvBuffer,
    +                                );
    + * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue, void *const pvBuffer) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    + BaseType_t xQueueReceive(
    +                                 QueueHandle_t xQueue,
    +                                 void *pvBuffer,
    +                                 TickType_t xTicksToWait
    +                            );
    + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
    + struct AMessage
    + {
    +    char ucMessageID;
    +    char ucData[ 20 ];
    + } xMessage;
    +
    + QueueHandle_t xQueue;
    +
    + // Task to create a queue and post a value.
    + void vATask( void *pvParameters )
    + {
    + struct AMessage *pxMessage;
    +
    +    // Create a queue capable of containing 10 pointers to AMessage structures.
    +    // These should be passed by pointer as they contain a lot of data.
    +    xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
    +    if( xQueue == 0 )
    +    {
    +        // Failed to create the queue.
    +    }
    +
    +    // ...
    +
    +    // Send a pointer to a struct AMessage object.  Don't block if the
    +    // queue is already full.
    +    pxMessage = & xMessage;
    +    xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
    +
    +    // ... Rest of task code.
    + }
    +
    + // Task to receive from the queue.
    + void vADifferentTask( void *pvParameters )
    + {
    + struct AMessage *pxRxedMessage;
    +
    +    if( xQueue != 0 )
    +    {
    +        // Receive a message on the created queue.  Block for 10 ticks if a
    +        // message is not immediately available.
    +        if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
    +        {
    +            // pcRxedMessage now points to the struct AMessage variable posted
    +            // by vATask.
    +        }
    +    }
    +
    +    // ... Rest of task code.
    + }
    + 
    + * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive(QueueHandle_t xQueue, void *const pvBuffer, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
    + * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
    + * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    void vQueueDelete( QueueHandle_t xQueue );
    + * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete(QueueHandle_t xQueue) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    + BaseType_t xQueueSendToFrontFromISR(
    +                                         QueueHandle_t xQueue,
    +                                         const void *pvItemToQueue,
    +                                         BaseType_t *pxHigherPriorityTaskWoken
    +                                      );
    + 
    + * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
    + void vBufferISR( void )
    + {
    + char cIn;
    + BaseType_t xHigherPrioritTaskWoken;
    +
    +    // We have not woken a task at the start of the ISR.
    +    xHigherPriorityTaskWoken = pdFALSE;
    +
    +    // Loop until the buffer is empty.
    +    do
    +    {
    +        // Obtain a byte from the buffer.
    +        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
    +
    +        // Post the byte.
    +        xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
    +
    +    } while( portINPUT_BYTE( BUFFER_COUNT ) );
    +
    +    // Now the buffer is empty we can switch context if necessary.
    +    if( xHigherPriorityTaskWoken )
    +    {
    +        taskYIELD ();
    +    }
    + }
    + 
    + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
    + BaseType_t xQueueSendToBackFromISR(
    +                                         QueueHandle_t xQueue,
    +                                         const void *pvItemToQueue,
    +                                         BaseType_t *pxHigherPriorityTaskWoken
    +                                      );
    + 
    + * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
    + void vBufferISR( void )
    + {
    + char cIn;
    + BaseType_t xHigherPriorityTaskWoken;
    +
    +    // We have not woken a task at the start of the ISR.
    +    xHigherPriorityTaskWoken = pdFALSE;
    +
    +    // Loop until the buffer is empty.
    +    do
    +    {
    +        // Obtain a byte from the buffer.
    +        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
    +
    +        // Post the byte.
    +        xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
    +
    +    } while( portINPUT_BYTE( BUFFER_COUNT ) );
    +
    +    // Now the buffer is empty we can switch context if necessary.
    +    if( xHigherPriorityTaskWoken )
    +    {
    +        taskYIELD ();
    +    }
    + }
    + 
    + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
    + BaseType_t xQueueOverwriteFromISR(
    +                              QueueHandle_t xQueue,
    +                              const void * pvItemToQueue,
    +                              BaseType_t *pxHigherPriorityTaskWoken
    +                         );
    + * 
    + * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
    +
    + QueueHandle_t xQueue;
    +
    + void vFunction( void *pvParameters )
    + {
    +    // Create a queue to hold one uint32_t value.  It is strongly
    +    // recommended *not* to use xQueueOverwriteFromISR() on queues that can
    +    // contain more than one value, and doing so will trigger an assertion
    +    // if configASSERT() is defined.
    +    xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
    +}
    +
    +void vAnInterruptHandler( void )
    +{
    +// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
    +BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    +uint32_t ulVarToSend, ulValReceived;
    +
    +    // Write the value 10 to the queue using xQueueOverwriteFromISR().
    +    ulVarToSend = 10;
    +    xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
    +
    +    // The queue is full, but calling xQueueOverwriteFromISR() again will still
    +    // pass because the value held in the queue will be overwritten with the
    +    // new value.
    +    ulVarToSend = 100;
    +    xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
    +
    +    // Reading from the queue will now return 100.
    +
    +    // ...
    +
    +    if( xHigherPrioritytaskWoken == pdTRUE )
    +    {
    +        // Writing to the queue caused a task to unblock and the unblocked task
    +        // has a priority higher than or equal to the priority of the currently
    +        // executing task (the task this interrupt interrupted).  Perform a context
    +        // switch so this interrupt returns directly to the unblocked task.
    +        portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
    +    }
    +}
    + 
    + * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
    + BaseType_t xQueueSendFromISR(
    +                                     QueueHandle_t xQueue,
    +                                     const void *pvItemToQueue,
    +                                     BaseType_t *pxHigherPriorityTaskWoken
    +                                );
    + 
    + * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
    + void vBufferISR( void )
    + {
    + char cIn;
    + BaseType_t xHigherPriorityTaskWoken;
    +
    +    // We have not woken a task at the start of the ISR.
    +    xHigherPriorityTaskWoken = pdFALSE;
    +
    +    // Loop until the buffer is empty.
    +    do
    +    {
    +        // Obtain a byte from the buffer.
    +        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
    +
    +        // Post the byte.
    +        xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
    +
    +    } while( portINPUT_BYTE( BUFFER_COUNT ) );
    +
    +    // Now the buffer is empty we can switch context if necessary.
    +    if( xHigherPriorityTaskWoken )
    +    {
    +        // Actual macro used here is port specific.
    +        portYIELD_FROM_ISR ();
    +    }
    + }
    + 
    + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
    + BaseType_t xQueueGenericSendFromISR(
    +                                           QueueHandle_t        xQueue,
    +                                           const    void    *pvItemToQueue,
    +                                           BaseType_t   *pxHigherPriorityTaskWoken,
    +                                           BaseType_t   xCopyPosition
    +                                       );
    + 
    + * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
    + void vBufferISR( void )
    + {
    + char cIn;
    + BaseType_t xHigherPriorityTaskWokenByPost;
    +
    +    // We have not woken a task at the start of the ISR.
    +    xHigherPriorityTaskWokenByPost = pdFALSE;
    +
    +    // Loop until the buffer is empty.
    +    do
    +    {
    +        // Obtain a byte from the buffer.
    +        cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
    +
    +        // Post each byte.
    +        xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
    +
    +    } while( portINPUT_BYTE( BUFFER_COUNT ) );
    +
    +    // Now the buffer is empty we can switch context if necessary.  Note that the
    +    // name of the yield function required is port specific.
    +    if( xHigherPriorityTaskWokenByPost )
    +    {
    +        taskYIELD_YIELD_FROM_ISR();
    +    }
    + }
    + 
    + * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR(QueueHandle_t xQueue, const void *const pvItemToQueue, + BaseType_t *const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR(QueueHandle_t xQueue, + BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
    + BaseType_t xQueueReceiveFromISR(
    +                                       QueueHandle_t    xQueue,
    +                                       void *pvBuffer,
    +                                       BaseType_t *pxTaskWoken
    +                                   );
    + * 
    + * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
    +
    + QueueHandle_t xQueue;
    +
    + // Function to create a queue and post some values.
    + void vAFunction( void *pvParameters )
    + {
    + char cValueToPost;
    + const TickType_t xTicksToWait = ( TickType_t )0xff;
    +
    +    // Create a queue capable of containing 10 characters.
    +    xQueue = xQueueCreate( 10, sizeof( char ) );
    +    if( xQueue == 0 )
    +    {
    +        // Failed to create the queue.
    +    }
    +
    +    // ...
    +
    +    // Post some characters that will be used within an ISR.  If the queue
    +    // is full then this task will block for xTicksToWait ticks.
    +    cValueToPost = 'a';
    +    xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
    +    cValueToPost = 'b';
    +    xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
    +
    +    // ... keep posting characters ... this task may block when the queue
    +    // becomes full.
    +
    +    cValueToPost = 'c';
    +    xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
    + }
    +
    + // ISR that outputs all the characters received on the queue.
    + void vISR_Routine( void )
    + {
    + BaseType_t xTaskWokenByReceive = pdFALSE;
    + char cRxedChar;
    +
    +    while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
    +    {
    +        // A character was received.  Output the character now.
    +        vOutputCharacter( cRxedChar );
    +
    +        // If removing the character from the queue woke the task that was
    +        // posting onto the queue cTaskWokenByReceive will have been set to
    +        // pdTRUE.  No matter how many times this loop iterates only one
    +        // task will be woken.
    +    }
    +
    +    if( cTaskWokenByPost != ( char ) pdFALSE;
    +    {
    +        taskYIELD ();
    +    }
    + }
    + 
    + * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *const pvBuffer, + BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR(const QueueHandle_t xQueue) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, + BaseType_t xCoRoutinePreviouslyWoken); +BaseType_t xQueueCRReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken); +BaseType_t xQueueCRSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait); +BaseType_t xQueueCRReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex(const uint8_t ucQueueType) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic(const uint8_t ucQueueType, + StaticQueue_t *pxStaticQueue) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore(const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic(const UBaseType_t uxMaxCount, + const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake(QueueHandle_t xQueue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder(QueueHandle_t xSemaphore) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR(QueueHandle_t xSemaphore) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive(QueueHandle_t xMutex, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive(QueueHandle_t xMutex) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) +void vQueueAddToRegistry(QueueHandle_t xQueue, + const char *pcQueueName) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) +void vQueueUnregisterQueue(QueueHandle_t xQueue) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) +const char *pcQueueGetName(QueueHandle_t xQueue) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +QueueHandle_t xQueueGenericCreate(const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, + const uint8_t ucQueueType) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +QueueHandle_t xQueueGenericCreateStatic(const UBaseType_t uxQueueLength, + const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, + const uint8_t ucQueueType) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore, + QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet, + const TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted(QueueHandle_t xQueue, TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset(QueueHandle_t xQueue, BaseType_t xNewQueue) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber(QueueHandle_t xQueue, UBaseType_t uxQueueNumber) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber(QueueHandle_t xQueue) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType(QueueHandle_t xQueue) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/inc/os/freertos/semphr.h b/inc/os/freertos/semphr.h new file mode 100644 index 0000000..b3d0b89 --- /dev/null +++ b/inc/os/freertos/semphr.h @@ -0,0 +1,1140 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
    vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
    + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
    +    // This is a macro so pass the variable in directly.
    +    vSemaphoreCreateBinary( xSemaphore );
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // The semaphore was created successfully.
    +        // The semaphore can now be used.
    +    }
    + }
    + 
    + * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateBinary( void )
    + * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
    +    // This is a macro so pass the variable in directly.
    +    xSemaphore = xSemaphoreCreateBinary();
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // The semaphore was created successfully.
    +        // The semaphore can now be used.
    +    }
    + }
    + 
    + * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
    + * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore = NULL;
    + StaticSemaphore_t xSemaphoreBuffer;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
    +    // The semaphore's data structures will be placed in the xSemaphoreBuffer
    +    // variable, the address of which is passed into the function.  The
    +    // function's parameter is not NULL, so the function will not attempt any
    +    // dynamic memory allocation, and therefore the function will not return
    +    // return NULL.
    +    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
    +
    +    // Rest of task code goes here.
    + }
    + 
    + * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
    xSemaphoreTake(
    + *                   SemaphoreHandle_t xSemaphore,
    + *                   TickType_t xBlockTime
    + *               )
    + * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    + // A task that creates a semaphore.
    + void vATask( void * pvParameters )
    + {
    +    // Create the semaphore to guard a shared resource.
    +    xSemaphore = xSemaphoreCreateBinary();
    + }
    +
    + // A task that uses the semaphore.
    + void vAnotherTask( void * pvParameters )
    + {
    +    // ... Do other things.
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // See if we can obtain the semaphore.  If the semaphore is not available
    +        // wait 10 ticks to see if it becomes free.
    +        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
    +        {
    +            // We were able to obtain the semaphore and can now access the
    +            // shared resource.
    +
    +            // ...
    +
    +            // We have finished accessing the shared resource.  Release the
    +            // semaphore.
    +            xSemaphoreGive( xSemaphore );
    +        }
    +        else
    +        {
    +            // We could not obtain the semaphore and can therefore not access
    +            // the shared resource safely.
    +        }
    +    }
    + }
    + 
    + * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
    + SemaphoreHandle_t xMutex = NULL;
    +
    + // A task that creates a mutex.
    + void vATask( void * pvParameters )
    + {
    +    // Create the mutex to guard a shared resource.
    +    xMutex = xSemaphoreCreateRecursiveMutex();
    + }
    +
    + // A task that uses the mutex.
    + void vAnotherTask( void * pvParameters )
    + {
    +    // ... Do other things.
    +
    +    if( xMutex != NULL )
    +    {
    +        // See if we can obtain the mutex.  If the mutex is not available
    +        // wait 10 ticks to see if it becomes free.
    +        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
    +        {
    +            // We were able to obtain the mutex and can now access the
    +            // shared resource.
    +
    +            // ...
    +            // For some reason due to the nature of the code further calls to
    +            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
    +            // code these would not be just sequential calls as this would make
    +            // no sense.  Instead the calls are likely to be buried inside
    +            // a more complex call structure.
    +            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
    +            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
    +
    +            // The mutex has now been 'taken' three times, so will not be
    +            // available to another task until it has also been given back
    +            // three times.  Again it is unlikely that real code would have
    +            // these calls sequentially, but instead buried in a more complex
    +            // call structure.  This is just for illustrative purposes.
    +            xSemaphoreGiveRecursive( xMutex );
    +            xSemaphoreGiveRecursive( xMutex );
    +            xSemaphoreGiveRecursive( xMutex );
    +
    +            // Now the mutex can be taken by other tasks.
    +        }
    +        else
    +        {
    +            // We could not obtain the mutex and can therefore not access
    +            // the shared resource safely.
    +        }
    +    }
    + }
    + 
    + * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
    xSemaphoreGive( SemaphoreHandle_t xSemaphore )
    + * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Create the semaphore to guard a shared resource.
    +    xSemaphore = vSemaphoreCreateBinary();
    +
    +    if( xSemaphore != NULL )
    +    {
    +        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
    +        {
    +            // We would expect this call to fail because we cannot give
    +            // a semaphore without first "taking" it!
    +        }
    +
    +        // Obtain the semaphore - don't block if the semaphore is not
    +        // immediately available.
    +        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
    +        {
    +            // We now have the semaphore and can access the shared resource.
    +
    +            // ...
    +
    +            // We have finished accessing the shared resource so can free the
    +            // semaphore.
    +            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
    +            {
    +                // We would not expect this call to fail because we must have
    +                // obtained the semaphore to get here.
    +            }
    +        }
    +    }
    + }
    + 
    + * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
    xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
    + * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
    + SemaphoreHandle_t xMutex = NULL;
    +
    + // A task that creates a mutex.
    + void vATask( void * pvParameters )
    + {
    +    // Create the mutex to guard a shared resource.
    +    xMutex = xSemaphoreCreateRecursiveMutex();
    + }
    +
    + // A task that uses the mutex.
    + void vAnotherTask( void * pvParameters )
    + {
    +    // ... Do other things.
    +
    +    if( xMutex != NULL )
    +    {
    +        // See if we can obtain the mutex.  If the mutex is not available
    +        // wait 10 ticks to see if it becomes free.
    +        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
    +        {
    +            // We were able to obtain the mutex and can now access the
    +            // shared resource.
    +
    +            // ...
    +            // For some reason due to the nature of the code further calls to
    +            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
    +            // code these would not be just sequential calls as this would make
    +            // no sense.  Instead the calls are likely to be buried inside
    +            // a more complex call structure.
    +            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
    +            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
    +
    +            // The mutex has now been 'taken' three times, so will not be
    +            // available to another task until it has also been given back
    +            // three times.  Again it is unlikely that real code would have
    +            // these calls sequentially, it would be more likely that the calls
    +            // to xSemaphoreGiveRecursive() would be called as a call stack
    +            // unwound.  This is just for demonstrative purposes.
    +            xSemaphoreGiveRecursive( xMutex );
    +            xSemaphoreGiveRecursive( xMutex );
    +            xSemaphoreGiveRecursive( xMutex );
    +
    +            // Now the mutex can be taken by other tasks.
    +        }
    +        else
    +        {
    +            // We could not obtain the mutex and can therefore not access
    +            // the shared resource safely.
    +        }
    +    }
    + }
    + 
    + * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
    + xSemaphoreGiveFromISR(
    +                          SemaphoreHandle_t xSemaphore,
    +                          BaseType_t *pxHigherPriorityTaskWoken
    +                      )
    + * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
    + \#define LONG_TIME 0xffff
    + \#define TICKS_TO_WAIT 10
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    + // Repetitive task.
    + void vATask( void * pvParameters )
    + {
    +    for( ;; )
    +    {
    +        // We want this task to run every 10 ticks of a timer.  The semaphore
    +        // was created before this task was started.
    +
    +        // Block waiting for the semaphore to become available.
    +        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
    +        {
    +            // It is time to execute.
    +
    +            // ...
    +
    +            // We have finished our task.  Return to the top of the loop where
    +            // we will block on the semaphore until it is time to execute
    +            // again.  Note when using the semaphore for synchronisation with an
    +            // ISR in this manner there is no need to 'give' the semaphore back.
    +        }
    +    }
    + }
    +
    + // Timer ISR
    + void vTimerISR( void * pvParameters )
    + {
    + static uint8_t ucLocalTickCount = 0;
    + static BaseType_t xHigherPriorityTaskWoken;
    +
    +    // A timer tick has occurred.
    +
    +    // ... Do other time functions.
    +
    +    // Is it time for vATask () to run?
    +    xHigherPriorityTaskWoken = pdFALSE;
    +    ucLocalTickCount++;
    +    if( ucLocalTickCount >= TICKS_TO_WAIT )
    +    {
    +        // Unblock the task by releasing the semaphore.
    +        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
    +
    +        // Reset the count so we release the semaphore again in 10 ticks time.
    +        ucLocalTickCount = 0;
    +    }
    +
    +    if( xHigherPriorityTaskWoken != pdFALSE )
    +    {
    +        // We can force a context switch here.  Context switching from an
    +        // ISR uses port specific syntax.  Check the demo task for your port
    +        // to find the syntax required.
    +    }
    + }
    + 
    + * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
    + xSemaphoreTakeFromISR(
    +                          SemaphoreHandle_t xSemaphore,
    +                          BaseType_t *pxHigherPriorityTaskWoken
    +                      )
    + * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateMutex( void )
    + * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
    +    // This is a macro so pass the variable in directly.
    +    xSemaphore = xSemaphoreCreateMutex();
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // The semaphore was created successfully.
    +        // The semaphore can now be used.
    +    }
    + }
    + 
    + * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
    + * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    + StaticSemaphore_t xMutexBuffer;
    +
    + void vATask( void * pvParameters )
    + {
    +    // A mutex cannot be used before it has been created.  xMutexBuffer is
    +    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
    +    // attempted.
    +    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
    +
    +    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
    +    // so there is no need to check it.
    + }
    + 
    + * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
    + * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    +
    + void vATask( void * pvParameters )
    + {
    +    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
    +    // This is a macro so pass the variable in directly.
    +    xSemaphore = xSemaphoreCreateRecursiveMutex();
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // The semaphore was created successfully.
    +        // The semaphore can now be used.
    +    }
    + }
    + 
    + * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
    + * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    + StaticSemaphore_t xMutexBuffer;
    +
    + void vATask( void * pvParameters )
    + {
    +    // A recursive semaphore cannot be used before it is created.  Here a
    +    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
    +    // The address of xMutexBuffer is passed into the function, and will hold
    +    // the mutexes data structures - so no dynamic memory allocation will be
    +    // attempted.
    +    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
    +
    +    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
    +    // so there is no need to check it.
    + }
    + 
    + * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) +#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
    + * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    +
    + void vATask( void * pvParameters )
    + {
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    +    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
    +    // The max value to which the semaphore can count should be 10, and the
    +    // initial value assigned to the count should be 0.
    +    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
    +
    +    if( xSemaphore != NULL )
    +    {
    +        // The semaphore was created successfully.
    +        // The semaphore can now be used.
    +    }
    + }
    + 
    + * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
    SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
    + * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
    + SemaphoreHandle_t xSemaphore;
    + StaticSemaphore_t xSemaphoreBuffer;
    +
    + void vATask( void * pvParameters )
    + {
    + SemaphoreHandle_t xSemaphore = NULL;
    +
    +    // Counting semaphore cannot be used before they have been created.  Create
    +    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
    +    // value to which the semaphore can count is 10, and the initial value
    +    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
    +    // passed in and will be used to hold the semaphore structure, so no dynamic
    +    // memory allocation will be used.
    +    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
    +
    +    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
    +    // is no need to check its value.
    + }
    + 
    + * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
    void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
    + * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
    TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
    + * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
    TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
    + * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + +/** + * semphr.h + *
    UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
    + * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + diff --git a/inc/os/freertos/stack_macros.h b/inc/os/freertos/stack_macros.h new file mode 100644 index 0000000..77da76e --- /dev/null +++ b/inc/os/freertos/stack_macros.h @@ -0,0 +1,132 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + +/* Only the current stack state is to be checked. */ +#define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + +/* Only the current stack state is to be checked. */ +#define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + +#define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if(os_cfg.checkForStackOverflow) \ + { \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + +#define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW +#define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + diff --git a/inc/os/freertos/stdint.readme b/inc/os/freertos/stdint.readme new file mode 100644 index 0000000..4414c29 --- /dev/null +++ b/inc/os/freertos/stdint.readme @@ -0,0 +1,27 @@ + +#ifndef FREERTOS_STDINT +#define FREERTOS_STDINT + +/******************************************************************************* + * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions + * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be + * built using compilers that do not provide their own stdint.h definition. + * + * To use this file: + * + * 1) Copy this file into the directory that contains your FreeRTOSConfig.h + * header file, as that directory will already be in the compilers include + * path. + * + * 2) Rename the copied file stdint.h. + * + */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long int32_t; +typedef unsigned long uint32_t; + +#endif /* FREERTOS_STDINT */ diff --git a/inc/os/freertos/stream_buffer.h b/inc/os/freertos/stream_buffer.h new file mode 100644 index 0000000..2ce031c --- /dev/null +++ b/inc/os/freertos/stream_buffer.h @@ -0,0 +1,860 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t *StreamBufferHandle_t; + + +/** + * message_buffer.h + * +
    +StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
    +
    + * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: +
    +
    +void vAFunction( void )
    +{
    +StreamBufferHandle_t xStreamBuffer;
    +const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
    +
    +    // Create a stream buffer that can hold 100 bytes.  The memory used to hold
    +    // both the stream buffer structure and the data in the stream buffer is
    +    // allocated dynamically.
    +    xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
    +
    +    if( xStreamBuffer == NULL )
    +    {
    +        // There was not enough heap memory space available to create the
    +        // stream buffer.
    +    }
    +    else
    +    {
    +        // The stream buffer was created successfully and can now be used.
    +    }
    +}
    +
    + * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) + +/** + * stream_buffer.h + * +
    +StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
    +                                                size_t xTriggerLevelBytes,
    +                                                uint8_t *pucStreamBufferStorageArea,
    +                                                StaticStreamBuffer_t *pxStaticStreamBuffer );
    +
    + * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: +
    +
    +// Used to dimension the array used to hold the streams.  The available space
    +// will actually be one less than this, so 999.
    +#define STORAGE_SIZE_BYTES 1000
    +
    +// Defines the memory that will actually hold the streams within the stream
    +// buffer.
    +static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
    +
    +// The variable used to hold the stream buffer structure.
    +StaticStreamBuffer_t xStreamBufferStruct;
    +
    +void MyFunction( void )
    +{
    +StreamBufferHandle_t xStreamBuffer;
    +const size_t xTriggerLevel = 1;
    +
    +    xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
    +                                               xTriggerLevel,
    +                                               ucBufferStorage,
    +                                               &xStreamBufferStruct );
    +
    +    // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
    +    // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
    +    // reference the created stream buffer in other stream buffer API calls.
    +
    +    // Other code that uses the stream buffer can go here.
    +}
    +
    +
    + * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
    +                          const void *pvTxData,
    +                          size_t xDataLengthBytes,
    +                          TickType_t xTicksToWait );
    +
    + * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: +
    +void vAFunction( StreamBufferHandle_t xStreamBuffer )
    +{
    +size_t xBytesSent;
    +uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
    +char *pcStringToSend = "String to send";
    +const TickType_t x100ms = pdMS_TO_TICKS( 100 );
    +
    +    // Send an array to the stream buffer, blocking for a maximum of 100ms to
    +    // wait for enough space to be available in the stream buffer.
    +    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
    +
    +    if( xBytesSent != sizeof( ucArrayToSend ) )
    +    {
    +        // The call to xStreamBufferSend() times out before there was enough
    +        // space in the buffer for the data to be written, but it did
    +        // successfully write xBytesSent bytes.
    +    }
    +
    +    // Send the string to the stream buffer.  Return immediately if there is not
    +    // enough space in the buffer.
    +    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
    +
    +    if( xBytesSent != strlen( pcStringToSend ) )
    +    {
    +        // The entire string could not be added to the stream buffer because
    +        // there was not enough free space in the buffer, but xBytesSent bytes
    +        // were sent.  Could try again to send the remaining bytes.
    +    }
    +}
    +
    + * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend(StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
    +                                 const void *pvTxData,
    +                                 size_t xDataLengthBytes,
    +                                 BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: +
    +// A stream buffer that has already been created.
    +StreamBufferHandle_t xStreamBuffer;
    +
    +void vAnInterruptServiceRoutine( void )
    +{
    +size_t xBytesSent;
    +char *pcStringToSend = "String to send";
    +BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
    +
    +    // Attempt to send the string to the stream buffer.
    +    xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
    +                                           ( void * ) pcStringToSend,
    +                                           strlen( pcStringToSend ),
    +                                           &xHigherPriorityTaskWoken );
    +
    +    if( xBytesSent != strlen( pcStringToSend ) )
    +    {
    +        // There was not enough free space in the stream buffer for the entire
    +        // string to be written, ut xBytesSent bytes were written.
    +    }
    +
    +    // If xHigherPriorityTaskWoken was set to pdTRUE inside
    +    // xStreamBufferSendFromISR() then a task that has a priority above the
    +    // priority of the currently executing task was unblocked and a context
    +    // switch should be performed to ensure the ISR returns to the unblocked
    +    // task.  In most FreeRTOS ports this is done by simply passing
    +    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
    +    // variables value, and perform the context switch if necessary.  Check the
    +    // documentation for the port in use for port specific instructions.
    +    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    +}
    +
    + * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR(StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
    +                             void *pvRxData,
    +                             size_t xBufferLengthBytes,
    +                             TickType_t xTicksToWait );
    +
    + * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: +
    +void vAFunction( StreamBuffer_t xStreamBuffer )
    +{
    +uint8_t ucRxData[ 20 ];
    +size_t xReceivedBytes;
    +const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
    +
    +    // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
    +    // Wait in the Blocked state (so not using any CPU processing time) for a
    +    // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
    +    // available.
    +    xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
    +                                           ( void * ) ucRxData,
    +                                           sizeof( ucRxData ),
    +                                           xBlockTime );
    +
    +    if( xReceivedBytes > 0 )
    +    {
    +        // A ucRxData contains another xRecievedBytes bytes of data, which can
    +        // be processed here....
    +    }
    +}
    +
    + * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive(StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
    +                                    void *pvRxData,
    +                                    size_t xBufferLengthBytes,
    +                                    BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: +
    +// A stream buffer that has already been created.
    +StreamBuffer_t xStreamBuffer;
    +
    +void vAnInterruptServiceRoutine( void )
    +{
    +uint8_t ucRxData[ 20 ];
    +size_t xReceivedBytes;
    +BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
    +
    +    // Receive the next stream from the stream buffer.
    +    xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
    +                                                  ( void * ) ucRxData,
    +                                                  sizeof( ucRxData ),
    +                                                  &xHigherPriorityTaskWoken );
    +
    +    if( xReceivedBytes > 0 )
    +    {
    +        // ucRxData contains xReceivedBytes read from the stream buffer.
    +        // Process the stream here....
    +    }
    +
    +    // If xHigherPriorityTaskWoken was set to pdTRUE inside
    +    // xStreamBufferReceiveFromISR() then a task that has a priority above the
    +    // priority of the currently executing task was unblocked and a context
    +    // switch should be performed to ensure the ISR returns to the unblocked
    +    // task.  In most FreeRTOS ports this is done by simply passing
    +    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
    +    // variables value, and perform the context switch if necessary.  Check the
    +    // documentation for the port in use for port specific instructions.
    +    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    +}
    +
    + * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR(StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t *const pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
    +
    + * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
    +
    + * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel(StreamBufferHandle_t xStreamBuffer, + size_t xTriggerLevel) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR(StreamBufferHandle_t xStreamBuffer, + BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
    +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
    +
    + * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR(StreamBufferHandle_t xStreamBuffer, + BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate(size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer) PRIVILEGED_FUNCTION; + +StreamBufferHandle_t xStreamBufferGenericCreateStatic(size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t *const pucStreamBufferStorageArea, + StaticStreamBuffer_t *const pxStaticStreamBuffer) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) +void vStreamBufferSetStreamBufferNumber(StreamBufferHandle_t xStreamBuffer, + UBaseType_t uxStreamBufferNumber) PRIVILEGED_FUNCTION; +UBaseType_t uxStreamBufferGetStreamBufferNumber(StreamBufferHandle_t xStreamBuffer) +PRIVILEGED_FUNCTION; +uint8_t ucStreamBufferGetStreamBufferType(StreamBufferHandle_t xStreamBuffer) PRIVILEGED_FUNCTION; +#endif + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( STREAM_BUFFER_H ) */ diff --git a/inc/os/freertos/task.h b/inc/os/freertos/task.h new file mode 100644 index 0000000..4a60198 --- /dev/null +++ b/inc/os/freertos/task.h @@ -0,0 +1,2468 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V10.2.0" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 2 +#define tskKERNEL_VERSION_BUILD 0 + +/* MPU region parameters passed in ulParameters + * of MemoryRegion_t struct. */ +#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) +#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +typedef void *TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)(void *); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char *const + pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + configSTACK_DEPTH_TYPE usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t *const pxTaskBuffer; +#endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t + xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char + *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState + eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t + uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t + uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + configSTACK_DEPTH_TYPE + usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
    + BaseType_t xTaskCreate(
    +                              TaskFunction_t pvTaskCode,
    +                              const char * const pcName,
    +                              configSTACK_DEPTH_TYPE usStackDepth,
    +                              void *pvParameters,
    +                              UBaseType_t uxPriority,
    +                              TaskHandle_t *pvCreatedTask
    +                          );
    + * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
    + // Task to be created.
    + void vTaskCode( void * pvParameters )
    + {
    +     for( ;; )
    +     {
    +         // Task code goes here.
    +     }
    + }
    +
    + // Function that creates a task.
    + void vOtherFunction( void )
    + {
    + static uint8_t ucParameterToPass;
    + TaskHandle_t xHandle = NULL;
    +
    +     // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
    +     // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
    +     // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
    +     // the new task attempts to access it.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
    +     configASSERT( xHandle );
    +
    +     // Use the handle to delete the task.
    +     if( xHandle != NULL )
    +     {
    +         vTaskDelete( xHandle );
    +     }
    + }
    +   
    + * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +BaseType_t xTaskCreate(TaskFunction_t pxTaskCode, + const char *const + pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void *const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t *const pxCreatedTask) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
    + TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
    +                                 const char * const pcName,
    +                                 uint32_t ulStackDepth,
    +                                 void *pvParameters,
    +                                 UBaseType_t uxPriority,
    +                                 StackType_t *pxStackBuffer,
    +                                 StaticTask_t *pxTaskBuffer );
    + * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and a handle to the created task is returned. If either + * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and + * NULL is returned. + * + * Example usage: +
    +
    +    // Dimensions the buffer that the task being created will use as its stack.
    +    // NOTE:  This is the number of words the stack will hold, not the number of
    +    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
    +    // then 400 bytes (100 * 32-bits) will be allocated.
    +    #define STACK_SIZE 200
    +
    +    // Structure that will hold the TCB of the task being created.
    +    StaticTask_t xTaskBuffer;
    +
    +    // Buffer that the task being created will use as its stack.  Note this is
    +    // an array of StackType_t variables.  The size of StackType_t is dependent on
    +    // the RTOS port.
    +    StackType_t xStack[ STACK_SIZE ];
    +
    +    // Function that implements the task being created.
    +    void vTaskCode( void * pvParameters )
    +    {
    +        // The parameter value is expected to be 1 as 1 is passed in the
    +        // pvParameters value in the call to xTaskCreateStatic().
    +        configASSERT( ( uint32_t ) pvParameters == 1UL );
    +
    +        for( ;; )
    +        {
    +            // Task code goes here.
    +        }
    +    }
    +
    +    // Function that creates a task.
    +    void vOtherFunction( void )
    +    {
    +        TaskHandle_t xHandle = NULL;
    +
    +        // Create the task without using any dynamic memory allocation.
    +        xHandle = xTaskCreateStatic(
    +                      vTaskCode,       // Function that implements the task.
    +                      "NAME",          // Text name for the task.
    +                      STACK_SIZE,      // Stack size in words, not bytes.
    +                      ( void * ) 1,    // Parameter passed into the task.
    +                      tskIDLE_PRIORITY,// Priority at which the task is created.
    +                      xStack,          // Array to use as the task's stack.
    +                      &xTaskBuffer );  // Variable to hold the task's data structure.
    +
    +        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
    +        // been created, and xHandle will be the task's handle.  Use the handle
    +        // to suspend the task.
    +        vTaskSuspend( xHandle );
    +    }
    +   
    + * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode, + const char *const + pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void *const pvParameters, + UBaseType_t uxPriority, + StackType_t *const puxStackBuffer, + StaticTask_t *const pxTaskBuffer) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
    + BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
    + * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
    +// Create an TaskParameters_t structure that defines the task to be created.
    +static const TaskParameters_t xCheckTaskParameters =
    +{
    +    vATask,     // pvTaskCode - the function that implements the task.
    +    "ATask",    // pcName - just a text name for the task to assist debugging.
    +    100,        // usStackDepth - the stack size DEFINED IN WORDS.
    +    NULL,       // pvParameters - passed into the task function as the function parameters.
    +    ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
    +    cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
    +
    +    // xRegions - Allocate up to three separate memory regions for access by
    +    // the task, with appropriate access permissions.  Different processors have
    +    // different memory alignment requirements - refer to the FreeRTOS documentation
    +    // for full information.
    +    {
    +        // Base address                 Length  Parameters
    +        { cReadWriteArray,              32,     portMPU_REGION_READ_WRITE },
    +        { cReadOnlyArray,               32,     portMPU_REGION_READ_ONLY },
    +        { cPrivilegedOnlyAccessArray,   128,    portMPU_REGION_PRIVILEGED_READ_WRITE }
    +    }
    +};
    +
    +int main( void )
    +{
    +TaskHandle_t xHandle;
    +
    +    // Create a task from the const structure defined above.  The task handle
    +    // is requested (the second parameter is not NULL) but in this case just for
    +    // demonstration purposes as its not actually used.
    +    xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
    +
    +    // Start the scheduler.
    +    vTaskStartScheduler();
    +
    +    // Will only get here if there was insufficient memory to create the idle
    +    // and/or timer task.
    +    for( ;; );
    +}
    +   
    + * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +BaseType_t xTaskCreateRestricted(const TaskParameters_t *const pxTaskDefinition, + TaskHandle_t *pxCreatedTask) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
    + BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
    + * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
    +// Create an TaskParameters_t structure that defines the task to be created.
    +// The StaticTask_t variable is only included in the structure when
    +// configSUPPORT_STATIC_ALLOCATION is set to 1.  The PRIVILEGED_DATA macro can
    +// be used to force the variable into the RTOS kernel's privileged data area.
    +static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
    +static const TaskParameters_t xCheckTaskParameters =
    +{
    +    vATask,     // pvTaskCode - the function that implements the task.
    +    "ATask",    // pcName - just a text name for the task to assist debugging.
    +    100,        // usStackDepth - the stack size DEFINED IN WORDS.
    +    NULL,       // pvParameters - passed into the task function as the function parameters.
    +    ( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
    +    cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
    +
    +    // xRegions - Allocate up to three separate memory regions for access by
    +    // the task, with appropriate access permissions.  Different processors have
    +    // different memory alignment requirements - refer to the FreeRTOS documentation
    +    // for full information.
    +    {
    +        // Base address                 Length  Parameters
    +        { cReadWriteArray,              32,     portMPU_REGION_READ_WRITE },
    +        { cReadOnlyArray,               32,     portMPU_REGION_READ_ONLY },
    +        { cPrivilegedOnlyAccessArray,   128,    portMPU_REGION_PRIVILEGED_READ_WRITE }
    +    }
    +
    +    &xTaskBuffer; // Holds the task's data structure.
    +};
    +
    +int main( void )
    +{
    +TaskHandle_t xHandle;
    +
    +    // Create a task from the const structure defined above.  The task handle
    +    // is requested (the second parameter is not NULL) but in this case just for
    +    // demonstration purposes as its not actually used.
    +    xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
    +
    +    // Start the scheduler.
    +    vTaskStartScheduler();
    +
    +    // Will only get here if there was insufficient memory to create the idle
    +    // and/or timer task.
    +    for( ;; );
    +}
    +   
    + * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) +BaseType_t xTaskCreateRestrictedStatic(const TaskParameters_t *const pxTaskDefinition, + TaskHandle_t *pxCreatedTask) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
    + void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
    + * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
    +// Define an array of MemoryRegion_t structures that configures an MPU region
    +// allowing read/write access for 1024 bytes starting at the beginning of the
    +// ucOneKByte array.  The other two of the maximum 3 definable regions are
    +// unused so set to zero.
    +static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
    +{
    +    // Base address     Length      Parameters
    +    { ucOneKByte,       1024,       portMPU_REGION_READ_WRITE },
    +    { 0,                0,          0 },
    +    { 0,                0,          0 }
    +};
    +
    +void vATask( void *pvParameters )
    +{
    +    // This task was created such that it has access to certain regions of
    +    // memory as defined by the MPU configuration.  At some point it is
    +    // desired that these MPU regions are replaced with that defined in the
    +    // xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
    +    // for this purpose.  NULL is used as the task handle to indicate that this
    +    // function should modify the MPU regions of the calling task.
    +    vTaskAllocateMPURegions( NULL, xAltRegions );
    +
    +    // Now the task can continue its function, but from this point on can only
    +    // access its stack and the ucOneKByte array (unless any other statically
    +    // defined or shared regions have been declared elsewhere).
    +}
    +   
    + * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions(TaskHandle_t xTask, + const MemoryRegion_t *const pxRegions) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskDelete( TaskHandle_t xTask );
    + * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
    + void vOtherFunction( void )
    + {
    + TaskHandle_t xHandle;
    +
    +     // Create the task, storing the handle.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    +
    +     // Use the handle to delete the task.
    +     vTaskDelete( xHandle );
    + }
    +   
    + * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete(TaskHandle_t xTaskToDelete) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
    void vTaskDelay( const TickType_t xTicksToDelay );
    + * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay(const TickType_t xTicksToDelay) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
    + * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
    + // Perform an action every 10 ticks.
    + void vTaskFunction( void * pvParameters )
    + {
    + TickType_t xLastWakeTime;
    + const TickType_t xFrequency = 10;
    +
    +     // Initialise the xLastWakeTime variable with the current time.
    +     xLastWakeTime = xTaskGetTickCount ();
    +     for( ;; )
    +     {
    +         // Wait for the next cycle.
    +         vTaskDelayUntil( &xLastWakeTime, xFrequency );
    +
    +         // Perform action here.
    +     }
    + }
    +   
    + * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil(TickType_t *const pxPreviousWakeTime, + const TickType_t xTimeIncrement) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
    + * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
    + * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
    + void vAFunction( void )
    + {
    + TaskHandle_t xHandle;
    +
    +     // Create a task, storing the handle.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    +
    +     // ...
    +
    +     // Use the handle to obtain the priority of the created task.
    +     // It was created with tskIDLE_PRIORITY, but may have changed
    +     // it itself.
    +     if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
    +     {
    +         // The task has changed it's priority.
    +     }
    +
    +     // ...
    +
    +     // Is our priority higher than the created task?
    +     if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
    +     {
    +         // Our priority (obtained using NULL handle) is higher.
    +     }
    + }
    +   
    + * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
    + * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR(const TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    eTaskState eTaskGetState( TaskHandle_t xTask );
    + * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
    + * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
    + void vAFunction( void )
    + {
    + TaskHandle_t xHandle;
    + TaskStatus_t xTaskDetails;
    +
    +    // Obtain the handle of a task from its name.
    +    xHandle = xTaskGetHandle( "Task_Name" );
    +
    +    // Check the handle is not NULL.
    +    configASSERT( xHandle );
    +
    +    // Use the handle to obtain further information about the task.
    +    vTaskGetInfo( xHandle,
    +                  &xTaskDetails,
    +                  pdTRUE, // Include the high water mark in xTaskDetails.
    +                  eInvalid ); // Include the task state in xTaskDetails.
    + }
    +   
    + * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, + eTaskState eState) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
    + * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
    + void vAFunction( void )
    + {
    + TaskHandle_t xHandle;
    +
    +     // Create a task, storing the handle.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    +
    +     // ...
    +
    +     // Use the handle to raise the priority of the created task.
    +     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
    +
    +     // ...
    +
    +     // Use a NULL handle to raise our priority to the same value.
    +     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
    + }
    +   
    + * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskSuspend( TaskHandle_t xTaskToSuspend );
    + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
    + void vAFunction( void )
    + {
    + TaskHandle_t xHandle;
    +
    +     // Create a task, storing the handle.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    +
    +     // ...
    +
    +     // Use the handle to suspend the created task.
    +     vTaskSuspend( xHandle );
    +
    +     // ...
    +
    +     // The created task will not run during this period, unless
    +     // another task calls vTaskResume( xHandle ).
    +
    +     //...
    +
    +
    +     // Suspend ourselves.
    +     vTaskSuspend( NULL );
    +
    +     // We cannot get here unless another task calls vTaskResume
    +     // with our handle as the parameter.
    + }
    +   
    + * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend(TaskHandle_t xTaskToSuspend) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskResume( TaskHandle_t xTaskToResume );
    + * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
    + void vAFunction( void )
    + {
    + TaskHandle_t xHandle;
    +
    +     // Create a task, storing the handle.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
    +
    +     // ...
    +
    +     // Use the handle to suspend the created task.
    +     vTaskSuspend( xHandle );
    +
    +     // ...
    +
    +     // The created task will not run during this period, unless
    +     // another task calls vTaskResume( xHandle ).
    +
    +     //...
    +
    +
    +     // Resume the suspended task ourselves.
    +     vTaskResume( xHandle );
    +
    +     // The created task will once again get microcontroller processing
    +     // time in accordance with its priority within the system.
    + }
    +   
    + * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
    + * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
    void vTaskStartScheduler( void );
    + * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
    + void vAFunction( void )
    + {
    +     // Create at least one task before starting the kernel.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
    +
    +     // Start the real time kernel with preemption.
    +     vTaskStartScheduler ();
    +
    +     // Will not get here unless a task calls vTaskEndScheduler ()
    + }
    +   
    + * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskEndScheduler( void );
    + * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
    + void vTaskCode( void * pvParameters )
    + {
    +     for( ;; )
    +     {
    +         // Task code goes here.
    +
    +         // At some point we want to end the real time kernel processing
    +         // so call ...
    +         vTaskEndScheduler ();
    +     }
    + }
    +
    + void vAFunction( void )
    + {
    +     // Create at least one task before starting the kernel.
    +     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
    +
    +     // Start the real time kernel with preemption.
    +     vTaskStartScheduler ();
    +
    +     // Will only get here when the vTaskCode () task has called
    +     // vTaskEndScheduler ().  When we get here we are back to single task
    +     // execution.
    + }
    +   
    + * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskSuspendAll( void );
    + * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
    + void vTask1( void * pvParameters )
    + {
    +     for( ;; )
    +     {
    +         // Task code goes here.
    +
    +         // ...
    +
    +         // At some point the task wants to perform a long operation during
    +         // which it does not want to get swapped out.  It cannot use
    +         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
    +         // operation may cause interrupts to be missed - including the
    +         // ticks.
    +
    +         // Prevent the real time kernel swapping out the task.
    +         vTaskSuspendAll ();
    +
    +         // Perform the operation here.  There is no need to use critical
    +         // sections as we have all the microcontroller processing time.
    +         // During this time interrupts will still operate and the kernel
    +         // tick count will be maintained.
    +
    +         // ...
    +
    +         // The operation is complete.  Restart the kernel.
    +         xTaskResumeAll ();
    +     }
    + }
    +   
    + * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    BaseType_t xTaskResumeAll( void );
    + * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
    + void vTask1( void * pvParameters )
    + {
    +     for( ;; )
    +     {
    +         // Task code goes here.
    +
    +         // ...
    +
    +         // At some point the task wants to perform a long operation during
    +         // which it does not want to get swapped out.  It cannot use
    +         // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
    +         // operation may cause interrupts to be missed - including the
    +         // ticks.
    +
    +         // Prevent the real time kernel swapping out the task.
    +         vTaskSuspendAll ();
    +
    +         // Perform the operation here.  There is no need to use critical
    +         // sections as we have all the microcontroller processing time.
    +         // During this time interrupts will still operate and the real
    +         // time kernel tick count will be maintained.
    +
    +         // ...
    +
    +         // The operation is complete.  Restart the kernel.  We want to force
    +         // a context switch - but there is no point if resuming the scheduler
    +         // caused a context switch already.
    +         if( !xTaskResumeAll () )
    +         {
    +              taskYIELD ();
    +         }
    +     }
    + }
    +   
    + * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll(void) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
    TickType_t xTaskGetTickCount( void );
    + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount2(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    TickType_t xTaskGetTickCount( void );
    + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    TickType_t xTaskGetTickCountFromISR( void );
    + * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    uint16_t uxTaskGetNumberOfTasks( void );
    + * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    char *pcTaskGetName( TaskHandle_t xTaskToQuery );
    + * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName(TaskHandle_t xTaskToQuery) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
    TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
    + * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle(const char *pcNameToQuery) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
    UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
    + * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task.h + *
    configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
    + * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG +#if configUSE_APPLICATION_TASK_TAG == 1 +/** + * task.h + *
    void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
    + * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ +void vTaskSetApplicationTaskTag(TaskHandle_t xTask, + TaskHookFunction_t pxHookFunction) PRIVILEGED_FUNCTION; + +/** + * task.h + *
    void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
    + * + * Returns the pxHookFunction value assigned to the task xTask. Do not + * call from an interrupt service routine - call + * xTaskGetApplicationTaskTagFromISR() instead. + */ +TaskHookFunction_t xTaskGetApplicationTaskTag(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/** + * task.h + *
    void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );
    + * + * Returns the pxHookFunction value assigned to the task xTask. Can + * be called from an interrupt service routine. + */ +TaskHookFunction_t xTaskGetApplicationTaskTagFromISR(TaskHandle_t xTask) PRIVILEGED_FUNCTION; +#endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + +/* Each task contains an array of pointers that is dimensioned by the +configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The +kernel does not use the pointers itself, so the application writer can use +the pointers for any purpose they wish. The following two functions are +used to set and query a pointer respectively. */ +void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, + void *pvValue) PRIVILEGED_FUNCTION; +void *pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, + BaseType_t xIndex) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
    BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
    + * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook(TaskHandle_t xTask, void *pvParameter) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle(void) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
    +    // This example demonstrates how a human readable table of run time stats
    +    // information is generated from raw data provided by uxTaskGetSystemState().
    +    // The human readable table is written to pcWriteBuffer
    +    void vTaskGetRunTimeStats( char *pcWriteBuffer )
    +    {
    +    TaskStatus_t *pxTaskStatusArray;
    +    volatile UBaseType_t uxArraySize, x;
    +    uint32_t ulTotalRunTime, ulStatsAsPercentage;
    +
    +        // Make sure the write buffer does not contain a string.
    +        *pcWriteBuffer = 0x00;
    +
    +        // Take a snapshot of the number of tasks in case it changes while this
    +        // function is executing.
    +        uxArraySize = uxTaskGetNumberOfTasks();
    +
    +        // Allocate a TaskStatus_t structure for each task.  An array could be
    +        // allocated statically at compile time.
    +        pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
    +
    +        if( pxTaskStatusArray != NULL )
    +        {
    +            // Generate raw status information about each task.
    +            uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
    +
    +            // For percentage calculations.
    +            ulTotalRunTime /= 100UL;
    +
    +            // Avoid divide by zero errors.
    +            if( ulTotalRunTime > 0 )
    +            {
    +                // For each populated position in the pxTaskStatusArray array,
    +                // format the raw data as human readable ASCII data
    +                for( x = 0; x < uxArraySize; x++ )
    +                {
    +                    // What percentage of the total run time has the task used?
    +                    // This will always be rounded down to the nearest integer.
    +                    // ulTotalRunTimeDiv100 has already been divided by 100.
    +                    ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
    +
    +                    if( ulStatsAsPercentage > 0UL )
    +                    {
    +                        sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
    +                    }
    +                    else
    +                    {
    +                        // If the percentage is zero here then the task has
    +                        // consumed less than 1% of the total run time.
    +                        sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
    +                    }
    +
    +                    pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
    +                }
    +            }
    +
    +            // The array is no longer needed, free the memory it consumes.
    +            vPortFree( pxTaskStatusArray );
    +        }
    +    }
    +    
    + */ +UBaseType_t uxTaskGetSystemState(TaskStatus_t *const pxTaskStatusArray, + const UBaseType_t uxArraySize, uint32_t *const pulTotalRunTime) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    void vTaskList( char *pcWriteBuffer );
    + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList(char *pcWriteBuffer) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
    void vTaskGetRunTimeStats( char *pcWriteBuffer );
    + * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats(char *pcWriteBuffer) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** +* task. h +*
    TickType_t xTaskGetIdleRunTimeCounter( void );
    +* +* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS +* must both be defined as 1 for this function to be available. The application +* must also then provide definitions for +* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() +* to configure a peripheral timer/counter and return the timers current count +* value respectively. The counter should be at least 10 times the frequency of +* the tick count. +* +* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total +* accumulated execution time being stored for each task. The resolution +* of the accumulated time value depends on the frequency of the timer +* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. +* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total +* execution time of each task into a buffer, xTaskGetIdleRunTimeCounter() +* returns the total execution time of just the idle task. +* +* @return The total run time of the idle task. This is the amount of time the +* idle task has actually been executing. The unit of time is dependent on the +* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +* portGET_RUN_TIME_COUNTER_VALUE() macros. +* +* \defgroup xTaskGetIdleRunTimeCounter xTaskGetIdleRunTimeCounter +* \ingroup TaskUtils +*/ +TickType_t xTaskGetIdleRunTimeCounter(void) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
    + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, + uint32_t *pulPreviousNotificationValue) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
    BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
    + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, + eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, + BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
    BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
    + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, + uint32_t *pulNotificationValue, TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
    + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
    void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
    + *
    + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
    + * to be available.
    + *
    + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
    + * "notification value", which is a 32-bit unsigned integer (uint32_t).
    + *
    + * A version of xTaskNotifyGive() that can be called from an interrupt service
    + * routine (ISR).
    + *
    + * Events can be sent to a task using an intermediary object.  Examples of such
    + * objects are queues, semaphores, mutexes and event groups.  Task notifications
    + * are a method of sending an event directly to a task without the need for such
    + * an intermediary object.
    + *
    + * A notification sent to a task can optionally perform an action, such as
    + * update, overwrite or increment the task's notification value.  In that way
    + * task notifications can be used to send data to a task, or be used as light
    + * weight and fast binary or counting semaphores.
    + *
    + * vTaskNotifyGiveFromISR() is intended for use when task notifications are
    + * used as light weight and faster binary or counting semaphore equivalents.
    + * Actual FreeRTOS semaphores are given from an ISR using the
    + * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
    + * a task notification is vTaskNotifyGiveFromISR().
    + *
    + * When task notifications are being used as a binary or counting semaphore
    + * equivalent then the task being notified should wait for the notification
    + * using the ulTaskNotificationTake() API function rather than the
    + * xTaskNotifyWait() API function.
    + *
    + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
    + *
    + * @param xTaskToNotify The handle of the task being notified.  The handle to a
    + * task can be returned from the xTaskCreate() API function used to create the
    + * task, and the handle of the currently running task can be obtained by calling
    + * xTaskGetCurrentTaskHandle().
    + *
    + * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
    + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
    + * task to which the notification was sent to leave the Blocked state, and the
    + * unblocked task has a priority higher than the currently running task.  If
    + * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
    + * should be requested before the interrupt is exited.  How a context switch is
    + * requested from an ISR is dependent on the port - see the documentation page
    + * for the port in use.
    + *
    + * \defgroup xTaskNotifyWait xTaskNotifyWait
    + * \ingroup TaskNotifications
    + */
    +void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
    +                            BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION;
    +
    +/**
    + * task. h
    + * 
    uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
    + * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit, + TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * task. h + *
    BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
    + * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick(void) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList(List_t *const pxEventList, + const TickType_t xTicksToWait) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList(List_t *pxEventList, const TickType_t xItemValue, + const TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted(List_t *const pxEventList, TickType_t xTicksToWait, + const BaseType_t xWaitIndefinitely) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList(const List_t *const pxEventList) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList(ListItem_t *pxEventListItem, + const TickType_t xItemValue) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +portDONT_DISCARD void vTaskSwitchContext(void) PRIVILEGED_FUNCTION; + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue(void) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle(void) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState(TimeOut_t *const pxTimeOut) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut(TimeOut_t *const pxTimeOut, + TickType_t *const pxTicksToWait) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield(void) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState(void) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit(TaskHandle_t const pxMutexHolder) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout(TaskHandle_t const pxMutexHolder, + UBaseType_t uxHighestPriorityWaitingTask) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber(TaskHandle_t xTask) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber(TaskHandle_t xTask, const UBaseType_t uxHandle) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick(const TickType_t xTicksToJump) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus(void) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount(void) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critial + * section. + */ +void vTaskInternalSetTimeOutState(TimeOut_t *const pxTimeOut) PRIVILEGED_FUNCTION; + +extern PRIVILEGED_DATA volatile TickType_t xTickCount; +extern PRIVILEGED_DATA volatile UBaseType_t uxPendedTicks; +extern PRIVILEGED_DATA volatile UBaseType_t uxSchedulerSuspended; + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + diff --git a/inc/os/freertos/timers.h b/inc/os/freertos/timers.h new file mode 100644 index 0000000..dc0ca7e --- /dev/null +++ b/inc/os/freertos/timers.h @@ -0,0 +1,1316 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H +#error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + +typedef enum +{ + tmrLIST_CURRENT_TIMER_LIST, + tmrLIST_OVERFLOW_TIMER_LIST, + tmrLIST_CURRENT_TASK_LIST, + tmrLIST_OVERFLOW_TASK_LIST, +} tmrListType_t; + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +typedef void *TimerHandle_t; + + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)(TimerHandle_t xTimer); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)(void *, uint32_t); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +TimerHandle_t xTimerCreate(const char *const + pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void *const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) +TimerHandle_t xTimerCreateStatic(const char *const + pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void *const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID(const TimerHandle_t xTimer) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer) PRIVILEGED_FUNCTION; +BaseType_t xTimerIsTimerActiveFromISR(TimerHandle_t xTimer) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle(void) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ +#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void *pvParameter1, + uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void *pvParameter1, + uint32_t ulParameter2, TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char *pcTimerGetName(TimerHandle_t xTimer) +PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); + * + * Updates a timer to be either an autoreload timer, in which case the timer + * automatically resets itself each time it expires, or a one shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +void vTimerSetReloadMode(TimerHandle_t xTimer, const UBaseType_t uxAutoReload) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod(TimerHandle_t xTimer) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask(void) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand(TimerHandle_t xTimer, const BaseType_t xCommandID, + const TickType_t xOptionalValue, BaseType_t *const pxHigherPriorityTaskWoken, + const TickType_t xTicksToWait) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) +void vTimerSetTimerNumber(TimerHandle_t xTimer, UBaseType_t uxTimerNumber) PRIVILEGED_FUNCTION; +UBaseType_t uxTimerGetTimerNumber(TimerHandle_t xTimer) PRIVILEGED_FUNCTION; +#endif + +void vTimerGetNextTimeoutItem(ListItem_t **pxListItem, UBaseType_t *puxListNum, + tmrListType_t xListType); +BaseType_t xTimerGetAutoReload(TimerHandle_t handle); + +void dumpAllUsedTimer(void); + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/inc/os/os_mem.h b/inc/os/os_mem.h new file mode 100644 index 0000000..63e7c9f --- /dev/null +++ b/inc/os/os_mem.h @@ -0,0 +1,281 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_MEM_H_ +#define _OS_MEM_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Memory Memory Management + * + * \brief Allocate, free, and peek memory functions. + * \details The Memory Management function group allows to allocate, free, and peek heap + * memory in the system.\n + * + * \ingroup OS + */ + + +void *os_mem_alloc_intern(RAM_TYPE ram_type, size_t size, + const char *p_func, uint32_t file_line); + +void *os_mem_zalloc_intern(RAM_TYPE ram_type, size_t size, + const char *p_func, uint32_t file_line); + +void *os_mem_aligned_alloc_intern(RAM_TYPE ram_type, size_t size, uint8_t alignment, + const char *p_func, uint32_t file_line); + +/** + * os_mem.h + * + * \brief Allocate a memory block with required size. + * + * \param[in] ram_type RAM type for allocation. + * \arg \c RAM_TYPE_DATA_ON Data ON RAM type. + * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type. + * + * \param[in] size Required memory size. + * + * \return The address of the allocated memory block. If the address is NULL, the + * memory allocation failed. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t mem_size = 0x1000; + * void *p_mem = NULL; + * + * p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size); + * if (p_mem != NULL) + * { + * // Memory allocation successed, and free it. + * os_mem_free(p_mem); + * } + * else + * { + * // Memory allocation failed. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +#define os_mem_alloc(ram_type, size) \ + os_mem_alloc_intern(ram_type, size, __func__, __LINE__) + +/** + * os_mem.h + * + * \brief Allocate and clear a memory block with required size. + * + * \param[in] ram_type RAM type for allocation. + * \arg \c RAM_TYPE_DATA_ON Data ON RAM type. + * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type. + * + * \param[in] size Required memory size. + * + * \return The address of the allocated memory block. If the address is NULL, the + * memory allocation failed. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t mem_size = 0x1000; + * void *p_mem = NULL; + * + * p_mem = os_mem_zalloc(RAM_TYPE_DATA_ON, mem_size); + * if (p_mem != NULL) + * { + * // Memory allocation successed, and free it. + * os_mem_free(p_mem); + * } + * else + * { + * // Memory allocation failed. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +#define os_mem_zalloc(ram_type, size) \ + os_mem_zalloc_intern(ram_type, size, __func__, __LINE__) + +/** + * os_mem.h + * + * \brief Allocate an aligned memory block with required size. + * + * \param[in] ram_type RAM type for allocation. + * \arg \c RAM_TYPE_DATA_ON Data ON RAM type. + * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type. + * + * \param[in] size Required memory size. + * + * \param[in] alignment memory alignment in 2^N bytes. If alignment is 0, use + * system default memory alignment. The aligned memory block + * must use os_mem_aligned_free() API function to free. + * + * \return The address of the allocated memory block. If the address is NULL, the + * memory allocation failed. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t mem_size = 0x1000; + * uint8_t mem_alignment = 16; + * void *p_mem = NULL; + * + * p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment); + * if (p_mem != NULL) + * { + * // Aligned memory allocation successed, and free it. + * os_mem_aligned_free(p_mem); + * } + * else + * { + * // Aligned memory allocation failed. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +#define os_mem_aligned_alloc(ram_type, size, alignment) \ + os_mem_aligned_alloc_intern(ram_type, size, alignment, __func__, __LINE__) + +/** + * os_mem.h + * + * \brief Free a memory block that had been allocated. + * + * \param[in] p_block The address of memory block being freed. + * + * \return None. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t mem_size = 0x1000; + * void *p_mem = NULL; + * + * p_mem = os_mem_alloc(RAM_TYPE_DATA_ON, mem_size); + * if (p_mem != NULL) + * { + * // Memory allocation successed, and free it. + * os_mem_free(p_mem); + * } + * else + * { + * // Memory allocation failed. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +void os_mem_free(void *p_block); + +/** + * os_mem.h + * + * \brief Free an aligned memory block that had been allocated. + * + * \param[in] p_block The address of memory block being freed. + * + * \return None. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t mem_size = 0x1000; + * uint8_t mem_alignment = 16; + * void *p_mem = NULL; + * + * p_mem = os_mem_aligned_alloc(RAM_TYPE_DATA_ON, mem_size, mem_alignment); + * if (p_mem != NULL) + * { + * // Aligned memory allocation successed, and free it. + * os_mem_aligned_free(p_mem); + * } + * else + * { + * // Aligned memory allocation failed. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +void os_mem_aligned_free(void *p_block); + +/** + * os_mem.h + * + * \brief Peek the unused memory size of the specified RAM type. + * + * \param[in] ram_type RAM type for allocation. + * \arg \c RAM_TYPE_DATA_ON Data ON RAM type. + * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type. + * + * \return The unused memory size in btyes. + * + * Example usage + * \code{.c} + * int test(void) + * { + * size_t unused_data_on; + * size_t unused_data_off; + * + * // Peek unused DATA ON memory size. + * unused_size = os_mem_peek(RAM_TYPE_DATA_ON); + * + * // Peek unused buffer on memory size. + * unused_size = os_mem_peek(RAM_TYPE_BUFFER_ON); + * + * return 0; + * } + * \endcode + * + * \ingroup Memory + */ +size_t os_mem_peek(RAM_TYPE ram_type); + +/* internal functions */ +void os_mem_check_heap_usage(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_MEM_H_ */ diff --git a/inc/os/os_msg.h b/inc/os/os_msg.h new file mode 100644 index 0000000..5547014 --- /dev/null +++ b/inc/os/os_msg.h @@ -0,0 +1,432 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_MSG_H_ +#define _OS_MSG_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Message Message Queue + * + * \brief Exchange messages between tasks in a FIFO-like operation. + * \details The Message Queue function group allows to control, send, receive, or wait for message. + * Message transmission is a basic communication model between tasks that one task sends + * data explicitly, while another task receives it. The operation is more like some + * kind of I/O rather than a direct access to information to be shared. The data to be + * passed can be any type.\n + * + * \image html OS-message-queue-overview.jpg "Message Queue Overview" width=617px height=321px + * + * \ingroup OS + */ + + +bool os_msg_queue_create_intern(void **pp_handle, uint32_t msg_num, uint32_t msg_size, + const char *p_func, uint32_t file_line); + +bool os_msg_queue_delete_intern(void *p_handle, const char *p_func, uint32_t file_line); + +bool os_msg_queue_peek_intern(void *p_handle, uint32_t *p_msg_num, + const char *p_func, uint32_t file_line); + +bool os_msg_send_intern(void *p_handle, void *p_msg, uint32_t wait_ms, + const char *p_func, uint32_t file_line); + +bool os_msg_recv_intern(void *p_handle, void *p_msg, uint32_t wait_ms, + const char *p_func, uint32_t file_line); + +bool os_msg_peek_intern(void *p_handle, void *p_msg, uint32_t wait_ms, + const char *p_func, uint32_t file_line); + +/** + * os_msg.h + * + * \brief Creates a message queue instance. This allocates the storage required by the + * new queue and passes back a handle for the queue. + * + * \param[out] pp_handle Used to pass back a handle by which the message queue + * can be referenced. + * + * \param[in] msg_num The maximum number of items that the queue can contain. + * + * \param[in] msg_size The number of bytes each item in the queue will require. Items + * are queued by copy, not by reference, so this is the number of + * bytes that will be copied for each posted item. Each item on the + * queue must be the same size. + * + * \return The status of the message queue creation. + * \retval true Message queue was created successfully. + * \retval false Message queue was failed to create. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * int test(void) + * { + * void *p_handle = NULL; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Delete the message queue. + * os_msg_queue_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_queue_create(pp_handle, msg_num, msg_size) \ + os_msg_queue_create_intern(pp_handle, msg_num, msg_size, __func__, __LINE__) + +/** + * os_msg.h + * + * \brief Delete the specified message queue, and free all the memory allocated for + * storing of items placed on the queue. + * + * \param[in] p_handle The handle to the message queue being deleted. + * + * \return The status of the message queue deletion. + * \retval true Message queue was deleted successfully. + * \retval false Message queue was failed to delete. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * int test(void) + * { + * void *p_handle = NULL; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Delete the message queue. + * os_msg_queue_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_queue_delete(p_handle) \ + os_msg_queue_delete_intern(p_handle, __func__, __LINE__) + +/** + * os_msg.h + * + * \brief Peek the number of items sent and resided on the message queue. + * + * \param[in] p_handle The handle to the message queue being peeked. + * + * \param[out] p_msg_num Used to pass back the number of items residing on the message queue. + * + * \return The status of the message queue peek. + * \retval true Message queue was peeked successfully. + * \retval false Message queue was failed to peek. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t msg_num; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Peek the number of items sent on this message queue. + * os_msg_queue_peek(p_handle, &msg_num); + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_queue_peek(p_handle, p_msg_num) \ + os_msg_queue_peek_intern(p_handle, p_msg_num, __func__, __LINE__) + +/** + * os_msg.h + * + * \brief Send an item to the back of the specified message queue. The item is + * queued by copy, not by reference. + * + * \param[in] p_handle The handle to the message queue on which the item is to be sent. + * + * \param[in] p_msg Pointer to the item that is to be sent on the queue. The referenced + * item rather than pointer itself will be copied on the queue. + * + * \param[in] wait_ms The maximum amount of time in milliseconds that the task should + * block waiting for the item to sent on the queue. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the item sent. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of the message item sent. + * \retval true Message item was sent successfully. + * \retval false Message item was failed to send. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * int test(void) + * { + * void *p_handle = NULL; + * struct test_msg msg; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Send the item to this message queue. + * msg.id = 1; + * msg.data[0] = 0; + * os_msg_send(p_handle, &msg, 0); + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_send(p_handle, p_msg, wait_ms) \ + os_msg_send_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) + +/** + * os_msg.h + * + * \brief Receive an item from the specified message queue. The item is received by + * copy rather than by reference, so a buffer of adequate size must be provided. + * + * \param[in] p_handle The handle to the message queue from which the item is to be received. + * + * \param[out] p_msg Pointer to the buffer into which the received item will be copied. + * item rather than pointer itself will be copied on the queue. + * + * \param[in] wait_ms The maximum amount of time in milliseconds that the task should + * block waiting for an item to be received from the queue. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the item received. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of the message item received. + * \retval true Message item was received successfully. + * \retval false Message item was failed to receive. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * void *p_handle = NULL; + * + * void send_msg(void) + * { + * struct test_msg msg; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Send the item to this message queue. + * msg.id = 1; + * msg.data[0] = 0; + * os_msg_send(p_handle, &msg, 0); + * + * return 0; + * } + * + * void receive_msg(void) + * { + * struct test_msg msg; + * + * // Receive the message queue item. + * if (os_msg_recv(p_handle, &msg, 0) == true) + * { + * // Message item received successfully. + * } + * else + * { + * // Message item failed to receive. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_recv(p_handle, p_msg, wait_ms) \ + os_msg_recv_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) + +/** + * os_msg.h + * + * \brief Receive but not remove an item from the specified message queue. The item is + * received by copy rather than by reference, so a buffer of adequate size must + * be provided. + * + * \param[in] p_handle The handle to the message queue on which the item is to be peeked. + * + * \param[out] p_msg Pointer to the buffer into which the received item will be copied. + * item rather than pointer itself will be copied on the queue. + * + * \param[in] wait_ms The maximum amount of time in milliseconds that the task should + * block waiting for an item to be received from the queue. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the item received. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of the message item received. + * \retval true Message item was received successfully. + * \retval false Message item was failed to receive. + * + * Example usage + * \code{.c} + * struct test_msg + * { + * uint8_t id; + * uint8_t data[16]; + * } + * + * #define MSG_NUM 10 + * + * void *p_handle = NULL; + * + * void send_msg(void) + * { + * struct test_msg msg; + * + * // Create a queue capable of containing 10 items of structure test_msg. + * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) + * { + * // Message queue created successfully. + * } + * else + * { + * // Message queue failed to create. + * return -1; + * } + * + * // Send the item to this message queue. + * msg.id = 1; + * msg.data[0] = 0; + * os_msg_send(p_handle, &msg, 0); + * + * return 0; + * } + * + * void peek_msg(void) + * { + * struct test_msg msg; + * + * // Peek the message queue item. + * if (os_msg_peek(p_handle, &msg, 0) == true) + * { + * // Message item peeked successfully. + * } + * else + * { + * // Message item failed to peek. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Message + */ +#define os_msg_peek(p_handle, p_msg, wait_ms) \ + os_msg_peek_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_MSG_H_ */ diff --git a/inc/os/os_pool.h b/inc/os/os_pool.h new file mode 100644 index 0000000..fcb8424 --- /dev/null +++ b/inc/os/os_pool.h @@ -0,0 +1,362 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_POOL_H_ +#define _OS_POOL_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Pool Pool Management + * + * \brief Manage task-safe and fixed-size blocks of dynamic memory. + * \details Memory pools are fixed-size blocks of memory that are task-safe. They operate much + * faster than the dynamically allocated heap and do not suffer from fragmentation. + * Being task-safe, they can be accessed from tasks and ISRs alike.\n + * Shared memory is one of the basic models to exchange information between tasks. + * Using memory pools for exchanging data, you can share more complex objects between + * taks if compared to the Message Queue. Memory pool management functions are used to + * define and manage such fixed-sized memory pools.\n + * + * \image html OS-pool-overview.jpg "Memory Pool Overview" width=601px height=481px + * + * \ingroup OS + */ + + +/** + * os_pool.h + * + * \brief The invalid pool handle. Valid pool handles should be less than OS_POOL_INVALID_HANDLE. + * + * \ingroup Pool + */ +#define OS_POOL_INVALID_HANDLE 0xFF + +bool os_pool_create_intern(uint8_t *p_handle, RAM_TYPE ram_type, uint16_t buf_size, + uint16_t buf_count, const char *p_func, uint32_t file_line); + +bool os_pool_extend_intern(uint8_t handle, uint16_t buf_size, uint16_t buf_count, + const char *p_func, uint32_t file_line); + +bool os_pool_delete_intern(uint8_t handle, const char *p_func, uint32_t file_line); + +void *os_buffer_get_intern(uint8_t handle, uint16_t buf_size, + const char *p_func, uint32_t file_line); + +bool os_buffer_put_intern(void *p_buf, const char *p_func, uint32_t file_line); + +/** + * os_pool.h + * + * \brief Creates and initialize a memory pool. + * + * \param[out] p_handle Used to pass back a handle by which the memory pool + * can be referenced. + * + * \param[in] ram_type RAM type for the memory pool buffer. + * \arg \c RAM_TYPE_DATA_ON Data ON RAM type. + * \arg \c RAM_TYPE_DATA_OFF Data OFF RAM type. + * \arg \c RAM_TYPE_BUFFER_ON BUFFER ON RAM type. + * \arg \c RAM_TYPE_BUFFER_OFF BUFFER OFF RAM type. + * + * \param[in] buf_size The pool buffer size in bytes. + * + * \param[in] buf_count The number of pool buffers allocated. + * + * \return The status of the memory pool creation. + * \retval true Pool was created successfully. + * \retval false Pool was failed to create. + * + * Example usage + * \code{.c} + * #define BUF_SIZE 0x40 + * #define BUF_NUM 16 + * + * int test(void) + * { + * uint8_t handle; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +#define os_pool_create(p_handle, ram_type, buf_size, buf_count) \ + os_pool_create_intern(p_handle, ram_type, buf_size, buf_count, __func__, __LINE__) + +/** + * os_pool.h + * + * \brief Extend a set of buffers to the created memory pool. The extended pool + * buffers have the same RAM type with the created buffers. + * + * \param[in] handle The handle of the created memory pool. + * + * \param[in] buf_size The pool buffer size in bytes. + * + * \param[in] buf_count The number of pool buffers allocated. + * + * \return The status of the memory pool extension. + * \retval true Pool was extended successfully. + * \retval false Pool was failed to extend. + * + * Example usage + * \code{.c} + * #define BUF_SIZE1 0x40 + * #define BUF_NUM1 16 + * #define BUF_SIZE2 0x20 + * #define BUF_NUM2 8 + * + * int test(void) + * { + * uint8_t handle; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes. + * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2); + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +#define os_pool_extend(handle, buf_size, buf_count) \ + os_pool_extend_intern(handle, buf_size, buf_count, __func__, __LINE__) + +/** + * os_pool.h + * + * \brief Delete a memory pool. + * + * \param[in] handle The handle of the memory pool to be deleted. + * + * \return The status of the memory pool deletion. + * \retval true Pool was deleted successfully. + * \retval false Pool was failed to delete. + * + * Example usage + * \code{.c} + * #define BUF_SIZE 0x40 + * #define BUF_NUM 16 + * + * int test(void) + * { + * uint8_t handle; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE, BUF_NUM) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * // Delete the memory pool. + * os_pool_delete(handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +#define os_pool_delete(handle) os_pool_delete_intern(handle, __func__, __LINE__) + +/** + * os_pool.h + * + * \brief Allocate a pool buffer from the specified memory pool. The allocated pool + * buffer size may be larger than the required size. + * + * \param[in] handle The handle of the created memory pool. + * + * \param[in] buf_size The pool buffer size in bytes. + * + * \return The address of the allocated pool buffer. If the address is NULL, + * the buffer allocation failed. + * + * Example usage + * \code{.c} + * #define BUF_SIZE1 0x40 + * #define BUF_NUM1 16 + * #define BUF_SIZE2 0x20 + * #define BUF_NUM2 8 + * + * int test(void) + * { + * uint8_t handle; + * void *p_buf; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes. + * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2); + * + * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will + * // give a buffer in 0x40 bytes. + * p_buf = os_buffer_get(handle, 0x30); + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +#define os_buffer_get(handle, buf_size) \ + os_buffer_get_intern(handle, buf_size, __func__, __LINE__) + +/** + * os_pool.h + * + * \brief Free and return the pool buffer to the specified memory pool. + * + * \param[in] p_buf The address of the pool buffer allocated by os_buffer_get() + * API function. + * + * \return The status of the pool buffer freeing. + * \retval true Pool was freed successfully. + * \retval false Pool was failed to free. + * + * Example usage + * \code{.c} + * #define BUF_SIZE1 0x40 + * #define BUF_NUM1 16 + * #define BUF_SIZE2 0x20 + * #define BUF_NUM2 8 + * + * int test(void) + * { + * uint8_t handle; + * void *p_buf; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes. + * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2); + * + * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will + * // give a buffer in 0x40 bytes. + * p_buf = os_buffer_get(handle, 0x30); + * + * // Free the pool buffer by the address. + * os_buffer_put(p_buf); + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +#define os_buffer_put(p_buf) \ + os_buffer_put_intern(p_buf, __func__, __LINE__) + +/** + * os_pool.h + * + * \brief Dump the pool buffers of the specified memory pool. + * + * \param[in] handle The handle of the memory pool buffer to be dumped. If the + * memory pool handle is invalid, all created memory pools + * will be dumped. + * + * \return None. + * + * Example usage + * \code{.c} + * #define BUF_SIZE1 0x40 + * #define BUF_NUM1 16 + * #define BUF_SIZE2 0x20 + * #define BUF_NUM2 8 + * + * int test(void) + * { + * uint8_t handle; + * void *p_buf; + * + * // Create a memory pool capable of containing 16 buffers. + * if (os_pool_create(&handle, RAM_TYPE_DATA_ON, BUF_SIZE1, BUF_NUM1) == true) + * { + * // Memory pool created successfully. + * } + * else + * { + * // Memory pool failed to create. + * return -1; + * } + * + * // Extend the memory pool to have extra 8 buffers each in 0x20 bytes. + * os_pool_extend(handle, BUF_SIZE2, BUF_NUM2); + * + * // Allocate a pool buffer in 0x30 bytes. While, the memory pool will + * // give a buffer in 0x40 bytes. + * p_buf = os_buffer_get(handle, 0x30); + * + * // Dump the memory pool. + * os_pool_dump(handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Pool + */ +void os_pool_dump(uint8_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_POOL_H_ */ diff --git a/inc/os/os_queue.h b/inc/os/os_queue.h new file mode 100644 index 0000000..f6547a1 --- /dev/null +++ b/inc/os/os_queue.h @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_QUEUE_H_ +#define _OS_QUEUE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Queue List Queue + * + * \brief Initialize and manage List Queue functions. + * \details List Queue is designed as a FIFO-like list, which can enqueue, dequeue and peek + * the list. While, List Queue also keeps these functionalities such as deleting + * and inserting the speicified list item.\n + * + * \image html OS-queue-overview.jpg "List Queue Overview" width=466px height=256px + * + * \ingroup OS + */ + + +/** + * os_queue.h + * + * \brief The element structure of List Queue. + * + * \ingroup Queue + */ +typedef struct t_os_queue_elem +{ + struct t_os_queue_elem *p_next; /**< Pointer to next list queue element. */ +} T_OS_QUEUE_ELEM; + +/** + * os_queue.h + * + * \brief The header structure of List Queue. + * + * \ingroup Queue + */ +typedef struct t_os_queue +{ + T_OS_QUEUE_ELEM *p_first; /**< Pointer to the first queue element. */ + T_OS_QUEUE_ELEM *p_last; /**< Pointer to the last queue element. */ + uint16_t count; /**< The queue element count. */ + uint16_t flags; /**< The flags for customer usage. */ +} T_OS_QUEUE; + +/** + * os_queue.h + * + * \brief Initialize the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \return None. + * + * Example usage + * \code{.c} + * T_OS_QUEUE test_queue; + * + * int test(void) + * { + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * } + * \endcode + * + * \ingroup Queue + */ +void os_queue_init(T_OS_QUEUE *p_queue); + +/** + * os_queue.h + * + * \brief Enqueue an element to the back of the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \param[in] p_elem The list queue element being enqueued. + * + * \return None. + * + * Example usage + * \code{.c} + * struct test_item + * { + * struct test_item *p_next; // Pointer to the next item, must be the first field. + * uint32_t id; + * uint8_t data[10]; + * } + * + * T_OS_QUEUE test_queue; + * + * struct test_item a_item; + * + * int test(void) + * { + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * + * // Enqueue the item. + * os_queue_in(&test_queue, &a_item); + * } + * \endcode + * + * \ingroup Queue + */ +void os_queue_in(T_OS_QUEUE *p_queue, void *p_elem); + +/** + * os_queue.h + * + * \brief Dequeue an element from the front of the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \return The first element from the list queue. If the returned address is + * NULL, the list queue is empty. + * + * Example usage + * \code{.c} + * struct test_item + * { + * struct test_item *p_next; // Pointer to the next item, must be the first field. + * uint32_t id; + * uint8_t data[10]; + * } + * + * T_OS_QUEUE test_queue; + * + * struct test_item a_item; + * + * int test(void) + * { + * struct test_item *p_item; + * + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * + * // Enqueue the item. + * os_queue_in(&test_queue, &a_item); + * + * // Then dequeue the item from the list queue. + * p_item = os_queue_out(&test_queue); + * } + * \endcode + * + * \ingroup Queue + */ +void *os_queue_out(T_OS_QUEUE *p_queue); + +/** + * os_queue.h + * + * \brief Peek an element from the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \return The first element from the list queue. If the returned address is + * NULL, the list queue is empty. + * + * Example usage + * \code{.c} + * struct test_item + * { + * struct test_item *p_next; // Pointer to the next item, must be the first field. + * uint32_t id; + * uint8_t data[10]; + * } + * + * T_OS_QUEUE test_queue; + * + * struct test_item a_item; + * + * int test(void) + * { + * struct test_item *p_item; + * + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * + * // Enqueue the item. + * os_queue_in(&test_queue, &a_item); + * + * // Peek but not remove the item from the list queue. + * p_item = os_queue_peek(&test_queue); + * } + * \endcode + * + * \ingroup Queue + */ +void *os_queue_peek(T_OS_QUEUE *p_queue); + +/** + * os_queue.h + * + * \brief Insert an element to the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \param[in] p_elem The element which the new element to be inserted behind. + * + * \param[in] p_new_elem The inserted element. + * + * \return None. + * + * Example usage + * \code{.c} + * struct test_item + * { + * struct test_item *p_next; // Pointer to the next item, must be the first field. + * uint32_t id; + * uint8_t data[10]; + * } + * + * T_OS_QUEUE test_queue; + * + * struct test_item item1; + * struct test_item item2; + * struct test_item item3; + * + * int test(void) + * { + * struct test_item *p_item; + * + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * + * // Enqueue the item 1. + * os_queue_in(&test_queue, &item1); + * + * // Enqueue the item 2. + * os_queue_in(&test_queue, &item2); + * + * // Insert the item 3 behind item 1 but before item 2. + * os_queue_insert(&test_queue, &item1, &item3); + * } + * \endcode + * + * \ingroup Queue + */ +void os_queue_insert(T_OS_QUEUE *p_queue, void *p_elem, void *p_new_elem); + +/** + * os_queue.h + * + * \brief Delete an element from the list queue. + * + * \param[in] p_queue Pointer to the list queue header. + * + * \param[in] p_elem The element to be deleted from the list queue. + * + * \return The status of queue element deletion. + * \retval true Queue element was deleted successfully. + * \retval false Queue element was failed to delete when the queue is empty + * or the being deleted queue element is not belonged to the queue. + * + * Example usage + * \code{.c} + * struct test_item + * { + * struct test_item *p_next; // Pointer to the next item, must be the first field. + * uint32_t id; + * uint8_t data[10]; + * } + * + * T_OS_QUEUE test_queue; + * + * struct test_item item1; + * struct test_item item2; + * struct test_item item3; + * + * int test(void) + * { + * struct test_item *p_item; + * + * // Initialize the queue before operating it. + * os_queue_init(&test_queue); + * + * // Enqueue the item 1. + * os_queue_in(&test_queue, &item1); + * + * // Enqueue the item 2. + * os_queue_in(&test_queue, &item2); + * + * // Enqueue the item 3. + * os_queue_in(&test_queue, &item3); + * + * // Then delete the item 2. + * os_queue_delete(&test_queue, &item12); + * } + * \endcode + * + * \ingroup Queue + */ +bool os_queue_delete(T_OS_QUEUE *p_queue, void *p_elem); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_QUEUE_H_ */ diff --git a/inc/os/os_sched.h b/inc/os/os_sched.h new file mode 100644 index 0000000..a509b20 --- /dev/null +++ b/inc/os/os_sched.h @@ -0,0 +1,314 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_SCHED_H_ +#define _OS_SCHED_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Schedule Kernel Scheduler + * + * \brief Manage the kernel scheduler functions. + * + * \ingroup OS + */ + + +/** + * os_sched.h + * + * \brief Delay current task for a given period in milliseconds. + * + * \param[in] ms The amout of timer in milliseconds that the current task + * should block. + * + * \return None. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * os_delay(100); + * + * // Do something here per 100ms. + * } + * } + * \endcode + * + * \ingroup Schedule + */ +void os_delay(uint32_t ms); + +/** + * os_sched.h + * + * \brief Get the time in milliseconds since os_sched_start() API function was called. + * + * \param None + * + * \return The time in milliseconds. Note the time represented by a 32-bit integer + * may be overflowed. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * uint32_t last_time; + * + * // Get the last timestamp. + * last_time = os_sys_time_get(); + * + * for (;;) + * { + * // Wait for the next cycle. + * os_delay(100); + * + * // Do something here per 100ms. + * } + * } + * \endcode + * + * \ingroup Schedule + */ +uint64_t os_sys_time_get(void); + +/** + * os_sched.h + * + * \brief Get the system tick since os_sched_start() API function was called. + * + * \param None + * + * \return The time in system tick. Note the tick represented by a 32-bit integer + * may be overflowed. + * + * Example usage + * \code{.c} + +* #define portTICK_PERIOD_MS 10 + + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * uint32_t beg_tick; + * uint32_t end_tick; + * uint32_t time; + * + * beg_tick = os_sys_tick_get(); + * + * // Do something here + * + * end_tick = os_sys_tick_get(); + * + * //get correct passed time in milliseconds + * time = (end_tick - beg_tick) * portTICK_PERIOD_MS; + * } + * \endcode + * + * \ingroup Schedule + */ +uint64_t os_sys_tick_get(void); + +/** + * os_sched.h + * + * \brief Start the RTOS kernel scheduler. + * + * \param None + * + * \return The status of starting kernel scheduler. + * \retval true Scheduler was started successfully. + * \retval false Scheduler was failed to start. + * + * Example usage + * \code{.c} + * int test(void) + * { + * // Create at least one task before starting kernel scheduler. + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Start the kernel scheduler. + * os_sched_start(); + * + * // Will not get here unless a task calls os_sched_stop(). + * } + * \endcode + * + * \ingroup Schedule + */ +bool os_sched_start(void); + +/** + * os_sched.h + * + * \brief Stop the RTOS kernel scheduler. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) stops. + * + * \param None + * + * \return The status of stopping kernel scheduler. + * \retval true Scheduler was stopped successfully. + * \retval false Scheduler was failed to stop. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * + * // At some point we want to end the real time kernel processing. + * os_sched_stop(); + * } + * } + * + * int test(void) + * { + * // Create at least one task before starting kernel scheduler. + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Start the kernel scheduler. + * os_sched_start(); + * + * // Will not get here unless a task calls os_sched_stop(). + * } + * \endcode + * + * \ingroup Schedule + */ +bool os_sched_stop(void); + +/** + * os_sched.h + * + * \brief Suspends the kernel scheduler without disabling interrupts. Context + * switches will not occur while the scheduler is suspended. After calling + * os_sched_suspend(), the calling task will continue to execute without + * risk of being swapped out until a call to os_sched_resume() has been made. + * + * \param None + * + * \return The status of suspending kernel scheduler. + * \retval true Scheduler was suspended successfully. + * \retval false Scheduler was failed to suspend. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * + * // At some point the task wants to perform a long operation, and do not + * // want to get swapped out. + * os_sched_suspend(); + * + * // The long operation. + * + * // The operation is completed, and resume the scheduler. + * os_sched_resume(); + * } + * } + * \endcode + * + * \ingroup Schedule + */ +bool os_sched_suspend(void); + +/** + * os_sched.h + * + * \brief Resume the kernel scheduler after it was suspended by a call + * to os_sched_suspend(). + * + * \param None + * + * \return The status of resuming kernel scheduler. + * \retval true Scheduler was resumed successfully. + * \retval false Scheduler was failed to resume. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * + * // At some point the task wants to perform a long operation, and do not + * // want to get swapped out. + * os_sched_suspend(); + * + * // The long operation. + * + * // The operation is completed, and resume the scheduler. + * os_sched_resume(); + * } + * } + * \endcode + * + * \ingroup Schedule + */ +bool os_sched_resume(void); + +/* internal function */ +bool os_sched_is_start(void); + +typedef enum +{ + SCHEDULER_SUSPENDED = 0, + SCHEDULER_NOT_STARTED = 1, + SCHEDULER_RUNNING = 2 +} SCHEDULER_STATE; + +SCHEDULER_STATE os_sched_state_get(void); + +void os_systick_handler(void); + +uint64_t os_sys_tick_increase(uint32_t tick_increment); + +void os_vector_table_update(void); + +void os_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_SCHED_H_ */ diff --git a/inc/os/os_sync.h b/inc/os/os_sync.h new file mode 100644 index 0000000..f52be52 --- /dev/null +++ b/inc/os/os_sync.h @@ -0,0 +1,475 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_SYNC_H_ +#define _OS_SYNC_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Synchronization Inter-Task Communication + * + * \brief Manage Inter-task communication functions. + * \details Tasks need to communicate with each other or access shared resources together. + * There are many ways to exchange data between tasks, for example using shared + * data, polling loops and message passing.\n + * Many resources can be considered as serially-reusable. This means that they + * can be used repeatedly by different tasks, but only by one task at a time.\n + * The following mechanisms are available to the user:\n + * \arg Lock + * \arg Semaphore + * \arg Mutex + * + * \ingroup OS + */ + + +/** + * os_sync.h + * + * \brief Enter the critical region. Disable preemptive context switch and interrupts. + * + * \param None + * + * \return Interrupt mask flag. + * + * Example usage + * \code{.c} + * int test(void) + * { + * uint32_t s; + * + * // Enter the critical section. + * s = os_lock(); + * // Allow only one task or ISR to operate the list. + * list_add(p_list, &item); + * // Exit the critical section and restore ISR mask flag. + * os_unlock(s); + * } + * \endcode + * + * \ingroup Synchronization + */ +uint32_t os_lock(void); + +/** + * os_sync.h + * + * \brief Exit the critical region. Enable preemptive context switch and interrupts. + * + * \param[in] s Interrupt mask flag to be restored. + * + * \return None. + * + * Example usage + * \code{.c} + * int test(void) + * { + * uint32_t s; + * + * // Enter the critical section. + * s = os_lock(); + * // Allow only one task or ISR to operate the list. + * list_add(p_list, &item); + * // Exit the critical section and restore ISR mask flag. + * os_unlock(s); + * } + * \endcode + * + * \ingroup Synchronization + */ +void os_unlock(uint32_t s); + +/** + * os_sync.h + * + * \brief Create a counting semaphore. + * + * \details Semaphores are used to manage and protect access to shared resources. A semaphore + * can be used to permit a fixed number of task to access a pool of shared resources. + * Using semaphores.\n + * A semaphore object should be initialized to the maximum number of available tokens. + * This number of available resources is specified as parameter of the os_sem_create() + * function. Each time a semaphore token is obtained with os_sem_take(), the semaphore + * count is decremented. When the semaphore count is 0, no semaphore token can be obtained. + * The task that tries to obtain the semaphore token needs to wait until the next token + * is free. Semaphores are released with os_sem_give() incrementing the semaphore count. + * + * \image html OS-semaphore-overview.jpg "Semaphore Overview" width=496px height=346px + * + * \param[out] pp_handle Used to pass back the created semaphore handle. + * + * \param[in] init_count The count value assigned to the semaphore when created. + * + * \param[in] max_count The maximum count value that can be reached. If the max_count is 1, + * a binary semaphore is being created. + * + * \return The status of the semaphore creation. + * \retval true Semaphore was created successfully. + * \retval false Semaphore was failed to create. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle; + * + * // Create a semaphore with initial value 0 and maximum value 10. + * if (os_sem_create(&p_handle, 0, 10) == true) + * { + * // Semaphore created successfully. + * } + * else + * { + * // Semaphore failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_sem_create(void **pp_handle, uint32_t init_count, uint32_t max_count); + +/** + * os_sync.h + * + * \brief Delete a semaphore. + * + * \param[in] p_handle The handle of the semaphore to be deleted. + * + * \return The status of the semaphore deletion. + * \retval true Semaphore was deleted successfully. + * \retval false Semaphore was failed to delete. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle; + * + * // Create a semaphore with initial value 0 and maximum value 10. + * if (os_sem_create(&p_handle, 0, 10) == true) + * { + * // Semaphore created successfully. + * } + * else + * { + * // Semaphore failed to create. + * return -1; + * } + * + * // Delete the created semaphore. + * os_sem_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_sem_delete(void *p_handle); + +/** + * os_sync.h + * + * \brief Take a semaphore. + * + * \param[in] p_handle The handle of the semaphore to be taken. + * + * \param[in] wait_ms The time in milliseconds to wait for the semaphore to become + * available. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the semaphore taken. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of the semaphore taking. + * \retval true Semaphore was taken successfully. + * \retval false Semaphore was failed to take. + * + * Example usage + * \code{.c} + * void *p_handle = NULL; + * + * // One task creates a semaphore. + * void task1(void *p_param) + * { + * // Create a full binary semaphore. + * os_sem_create(&p_handle, 1, 1); + * } + * + * // Anohter task uses the semaphore. + * void task2(void *p_param) + * { + * // See if we can obtain the semaphore. If the semaphore is + * // not available, wait for 100ms. + * if (os_sem_take(p_handle, 100) == true) + * { + * // Access the share resource. + * + * // Finish accessing the share resource, then release the semaphore. + * os_sem_give(p_handle); + * } + * else + * { + * // Could not access the share resource. + * } + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_sem_take(void *p_handle, uint32_t wait_ms); + +/** + * os_sync.h + * + * \brief Give a semaphore. + * + * \param[in] p_handle The handle of the semaphore to be given. + * + * \return The status of the semaphore giving. + * \retval true Semaphore was given successfully. + * \retval false Semaphore was failed to give. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * + * // Create an empty binary semaphore. + * os_sem_create(&p_handle, 0, 1); + * + * // Obtaining the empty semaphore immediately will be failed. + * if (os_sem_take(p_handle, 0) == false) + * { + * // Failed. + * } + * + * // Give the sempahore + * if (os_sem_give(p_hanel) == true) + * { + * // Now we can take the semaphore. + * os_sem_take(p_handle, 0); + * + * // Again taking the binary semaphore will be failed. + * os_sem_take(p_handle, 0); + * } + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_sem_give(void *p_handle); + +/** + * os_sync.h + * + * \brief Create a mutex. + * + * \details Mutex (Mutual Exclusion) is used to protect a shared resource that can be accessed + * only by one task at a time.\n + * A mutex is a special version of a binary empty semaphore. The advantage of a mutex + * is that it introduces task ownership. When a task acquires a mutex and becomes its + * owner, subsequent mutex acquires from that task will succeed immediately. Thus, mutex + * acquires/releases can be nested.\n + * + * \image html OS-mutex-overview.jpg "Mutex Overview" width=451px height=196px + * + * \param[out] pp_handle Used to pass back the created mutex handle. + * + * \return The status of the mutex creation. + * \retval true Mutex was created successfully. + * \retval false Mutex was failed to create. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * + * // Create a mutex. + * if (os_mutex_create(&p_handle) == true) + * { + * // The mutex created successfully. + * // Now it can be used. + * } + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_mutex_create(void **pp_handle); + +/** + * os_sync.h + * + * \brief Delete a mutex. + * + * \param[in] p_handle The handle of the mutex to be deleted. + * + * \return The status of the Mutex deletion. + * \retval true Mutex was deleted successfully. + * \retval false Mutex was failed to delete. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle; + * + * // Create a mutex. + * if (os_mutex_create(&p_handle) == true) + * { + * // Mutex created successfully. + * } + * else + * { + * // Mutex failed to create. + * return -1; + * } + * + * // Delete the created mutex. + * os_mutex_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_mutex_delete(void *p_handle); + +/** + * os_sync.h + * + * \brief Take a mutex. + * + * \param[in] p_handle The handle of the mutex to be taken. + * + * \param[in] wait_ms The time in milliseconds to wait for the mutex to become + * available. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the mutex taken. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of the mutex taking. + * \retval true Mutex was taken successfully. + * \retval false Mutex was failed to take. + * + * Example usage + * \code{.c} + * void *p_handle = NULL; + * + * // One task creates a mutex. + * void task1(void *p_param) + * { + * // Create a mutex. + * os_mutex_create(&p_handle); + * } + * + * // Anohter task uses the mutex. + * void task2(void *p_param) + * { + * // See if we can obtain the mutex. If the mutex is + * // not available, wait for 100ms. + * if (os_mutex_take(p_handle, 100) == true) + * { + * // Access the share resource. + * + * // In real code, recursive calls of mutex may occur. + * os_mutex_take(p_handle, 100); + * os_mutex_take(p_handle, 200); + * + * // The mutex has now been 'taken' three times, so will not be + * // available to another task until it has also been given back + * // three times. + * os_mutex_give(p_handle); + * os_mutex_give(p_handle); + * os_mutex_give(p_handle); + * + * // Finish accessing the share resource, then release the semaphore. + * // Now the mutex can be taken by other tasks. + * } + * else + * { + * // Could not access the share resource. + * } + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_mutex_take(void *p_handle, uint32_t wait_ms); + +/** + * os_sync.h + * + * \brief Give a mutex. + * + * \param[in] p_handle The handle of the mutex to be given. + * + * \return The status of the mutex giving. + * \retval true Mutex was given successfully. + * \retval false Mutex was failed to give. + * + * Example usage + * \code{.c} + * void *p_handle = NULL; + * + * // One task creates a mutex. + * void task1(void *p_param) + * { + * // Create a mutex. + * os_mutex_create(&p_handle); + * } + * + * // Anohter task uses the mutex. + * void task2(void *p_param) + * { + * // See if we can obtain the mutex. If the mutex is + * // not available, wait for 100ms. + * if (os_mutex_take(p_handle, 100) == true) + * { + * // Access the share resource. + * + * // In real code, recursive calls of mutex may occur. + * os_mutex_take(p_handle, 100); + * os_mutex_take(p_handle, 200); + * + * // The mutex has now been 'taken' three times, so will not be + * // available to another task until it has also been given back + * // three times. + * os_mutex_give(p_handle); + * os_mutex_give(p_handle); + * os_mutex_give(p_handle); + * + * // Finish accessing the share resource, then release the semaphore. + * // Now the mutex can be taken by other tasks. + * } + * else + * { + * // Could not access the share resource. + * } + * } + * \endcode + * + * \ingroup Synchronization + */ +bool os_mutex_give(void *p_handle); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_SYNC_H_ */ diff --git a/inc/os/os_task.h b/inc/os/os_task.h new file mode 100644 index 0000000..fa4bc9e --- /dev/null +++ b/inc/os/os_task.h @@ -0,0 +1,566 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_TASK_H_ +#define _OS_TASK_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF APIs + * \defgroup Task Task Management + * + * \brief Define, create, and control task functions. + * \details The Task Management function group allows to create, delete, and control tasks + * in the system.\n + * Tasks can be in the following states:\n + * \arg RUNNING: The task that is currently running is in the RUNNING state. + * Only one task at a time can be in this state. + * \arg READY: Tasks which are ready to run are in the READY state. Once the + * RUNNING task has terminated or is WAITING, the next + * READY task with the highest priority becomes the RUNNING task. + * \arg WAITING: Tasks that are waiting for an event to occur are in the WAITING state. + * \arg INACTIVE: Tasks that are not created or terminated are in the INACTIVE state. + * These Tasks typically consume no system resources. + * + * \image html OS-task-state-transition.jpg "Task State Transition" width=526px height=526px + * + * \ingroup OS + */ + + +/** + * os_task.h + * + * \brief Create a new task and add it to the list of tasks that are ready to run. + * + * \param[out] pp_handle Used to pass back a handle by which the created task + * can be referenced. + * + * \param[in] p_name A descriptive name for the task. + * + * \param[in] p_routine Pointer to task routine function that must be implemented + * to never return. + * + * \param[in] p_param Pointer parameter passed to the task routine function. + * + * \param[in] stack_size The size of the task stack that is specified as the number + * of bytes. + * + * \param[in] priority The priority at which the task should run. Higher priority + * task has higher priority value. + * + * \return The status of the task creation. + * \retval true Task was created successfully and added to task ready list. + * \retval false Task was failed to create. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * } + * } + * + * // Task to be created. + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t task_param; + * + * if (os_task_create(&p_handle, "task", task_routine, + * &task_param, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Use the handle to delete the task. + * os_task_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_create(void **pp_handle, const char *p_name, void (*p_routine)(void *), + void *p_param, uint16_t stack_size, uint16_t priority); + +/** + * os_task.h + * + * \brief Remove a task from RTOS's task management. The task being deleted will be removed + * from RUNNING, READY or WAITING state. + * + * \param[in] p_handle The handle of the task to be deleted. + * + * \return The status of the task deletion. + * \retval true Task was deleted successfully. + * \retval false Task was failed to delete. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * } + * } + * + * // Task to be created and deleted. + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t task_param; + * + * if (os_task_create(&p_handle, "task", task_routine, + * &task_param, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Use the handle to delete the task. + * os_task_delete(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_delete(void *p_handle); + +/** + * os_task.h + * + * \brief Suspend the task. The suspended task will not be scheduled and never get + * any microcontroller processing time. + * + * \param[in] p_handle The handle of the task to be suspended. + * + * \return The status of the task suspension. + * \retval true Task was suspended successfully. + * \retval false Task was failed to suspend. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * } + * } + * + * // Task to be created and suspended. + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t task_param; + * + * if (os_task_create(&p_handle, "task", task_routine, + * &task_param, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Use the handle to suspend the created task. + * os_task_suspend(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_suspend(void *p_handle); + +/** + * os_task.h + * + * \brief Resume the suspended task. + * + * \param[in] p_handle The handle of the task to be resumed. + * + * \return The status of the task resume. + * \retval true Task was resumed successfully. + * \retval false Task was failed to resume. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Task code goes here. + * } + * } + * + * // Task to be suspended and resumed. + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t task_param; + * + * if (os_task_create(&p_handle, "task", task_routine, + * &task_param, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Use the handle to suspend the created task. + * os_task_suspend(p_handle); + * + * // Resume the suspended task by ourselves. + * os_task_resume(p_handle); + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_resume(void *p_handle); + +/** + * os_task.h + * + * \brief Force a context swith and pass control to the next task that is in + * READY state. + * + * \param None + * + * \return The status of the task resume. + * \retval true Task was yielded successfully. + * \retval false Task was failed to yield. + * + * Example usage + * \code{.c} + * // Task routine implementation. + * void task_routine(void *p_param) + * { + * for (;;) + * { + * // Force a context switch + * os_task_yield(); + * } + * } + * + * // Task to be created. + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t task_param; + * + * if (os_task_create(&p_handle, "task", task_routine, + * &task_param, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_yield(void); + +/** + * os_task.h + * + * \brief Get the handle of the current running task. + * + * \param[out] pp_handle Used to pass back a handle by which the current task + * can be referenced. + * + * \return The status of getting the current task handle. + * \retval true Task handle was got successfully. + * \retval false Task handle was failed to get. + * + * Example usage + * \code{.c} + * // Get current task handle. + * int test(void) + * { + * void *p_handle = NULL; + * + * os_task_handle_get(&p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_handle_get(void **pp_handle); + +/** + * os_task.h + * + * \brief Get the priority of the specified task. + * + * \param[in] p_handle The handle of the task to be queried. Passing a NULL handle + * means querying the priority of the current task. + * + * \param[out] p_priority Used to pass back the priority of the task. + * + * \return The status of getting the task priority. + * \retval true Task priority was got successfully. + * \retval false Task priority was failed to get. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * uint16_t priority; + * + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Get the task priority. + * os_task_priority_get(p_handle, &priority); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_priority_get(void *p_handle, uint16_t *p_priority); + +/** + * os_task.h + * + * \brief Set the priority of the specified task. + * + * \param[in] p_handle The handle of the task for which the priority is being set. + * Passing a NULL handle means setting the priority of the + * current task. + * + * \param[in] priority The priority to which the task will be set. + * + * \return The status of setting the task priority. + * \retval true Task priority was set successfully. + * \retval false Task priority was failed to set. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * uint16_t priority; + * + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Use the handle to raise the created task priority. + * os_task_priority_set(p_handle, TASK_PRIORITY + 1); + * + * // Use a NULL handle to raise the current task priority. + * os_task_priority_set(NULL, TASK_PRIORITY + 1); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_priority_set(void *p_handle, uint16_t priority); + +/** + * os_task.h + * + * \brief Send a notification signal to the specified task. + * + * The notification signal sent to a task will remain pending until it is + * cleared by the task calling os_task_signal_recv(). If the task was already + * in the WAITING state to wait for the singal, then the task will be removed + * from WAITING state and the signal cleared. + * + * \param[in] p_handle The handle of the task to which the signal is sent. + * + * \param[in] signal The signal to be sent. + * + * \return The status of sending the signal. + * \retval true Task signal was sent successfully. + * \retval false Task signal was failed to send. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t signal; + * + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Send signal to the created task. + * singal = 1; + * os_task_signal_send(p_handle, signal); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ + +#if (BUILE_OS_COMMON == 0) + +bool os_task_signal_send(void *p_handle, uint32_t signal); + +/** + * os_task.h + * + * \brief Wait for a notification signal. + * + * \param[out] p_signal Used to pass back the received signal. + * + * \param[in] wait_ms The timeout in milliseconds to wait for the signal. + * \arg \c 0 No blocking and return immediately. + * \arg \c 0xFFFFFFFF Block infinitely until the signal received. + * \arg \c others The timeout value in milliseconds. + * + * \return The status of receiving the signal. + * \retval true Task signal was received successfully. + * \retval false Task signal was failed to receive. + * + * Example usage + * \code{.c} + * int test(void) + * { + * uint32_t signal; + * + * // Block to wait for the signal sent from other tasks. + * os_task_signal_recv(&signal, 0xFFFFFFFF); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_signal_create(void *p_handle, uint32_t count); +bool os_task_signal_recv(uint32_t *p_signal, uint32_t wait_ms); +bool os_task_signal_take(uint32_t p_signal, uint32_t wait_ms); +bool os_task_signal_give(void *p_handle); +/** + * os_task.h + * + * \brief Clear the signal of the specified task. + * + * \param[in] p_handle The handle of the task to which the signal is clear. + * + * \return The status of clearing the signal. + * \retval true Task signal was cleared successfully. + * \retval false Task signal was failed to clear. + * + * Example usage + * \code{.c} + * int test(void) + * { + * void *p_handle = NULL; + * uint32_t signal; + * + * if (os_task_create(&p_handle, "task", task_routine, + * NULL, STACK_SIZE, TASK_PRIORITY) == true) + * { + * // Task created successfully. + * } + * else + * { + * // Task failed to create. + * return -1; + * } + * + * // Send signal to the created task. + * singal = 1; + * os_task_signal_send(p_handle, signal); + * + * // Clear signal of the created task. + * os_task_signal_clear(p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Task + */ +bool os_task_signal_clear(void *p_handle); + +#endif + +/* internal function */ +void os_task_status_dump(void); + +void os_task_dlps_return_idle_task(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_TASK_H_ */ diff --git a/inc/os/os_timer.h b/inc/os/os_timer.h new file mode 100644 index 0000000..c1c52a3 --- /dev/null +++ b/inc/os/os_timer.h @@ -0,0 +1,517 @@ +/** + * Copyright (c) 2015, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _OS_TIMER_H_ +#define _OS_TIMER_H_ + +#include +#include +//#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup OS OSIF + * \defgroup Timer Timer Management + * + * \brief Create and control software timer and timer callback functions. + * \details The Timer Management function group allows to create, delete, and control software + * timers in the system. The software timers can be configured as one-short or periodic + * timers. When a timer expires, a callback function associated with the timer is + * executed.\n + * Timers can be in the following two states:\n + * \arg Dormant The timer first enters Dormant or Inactive state when created. + * If a one-short timer expires but not restarts yet, or is stopped the timer + * will be tranformed from Active state into Dormant state. + * \arg Active The timer enters Active state If the timer starts or restarts. When + * expired, the callback function associcated with the timer will be executed. + * + * \image html OS-timer-state-transition.jpg "Software Timer State Transition" width=617px height=321px + * + * \ingroup OS + */ + + +/** + * os_timer.h + * + * \brief Get the ID assigned to the timer when created. + * + * \param[in] pp_handle Pointer to the created timer handle. + * + * \param[out] p_timer_id Used to pass back the ID assigned to the timer. + * + * \return The status of the timer id getting. + * \retval true Timer ID was got successfully. + * \retval false Timer ID was failed to get. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_id_get(void **pp_handle, uint32_t *p_timer_id); + +/** + * os_timer.h + * + * \brief Create a new software timer instance. This allocates the storage required by + * the new timer, initializes the new timers internal state, and returns a handle + * by which the new timer can be referenced. + * + * \param[out] pp_handle Used to pass back a handle by which the created timer + * can be referenced. + * + * \param[in] p_timer_name A descriptive name for the timer. + * + * \param[in] timer_id An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to + * identify which timer expired when the same callback function is + * assigned to more than one timer. + * + * \param[in] interval_ms The timer period in milliseconds. + * + * \param[in] reload Used to set the timer as a periodic or one-shot timer. + * \arg \c true Create a periodic timer. + * \arg \c false Create a one-shot timer. + * + * \param[in] p_timer_callback The function to call when the timer expires. Callback functions + * must have the prototype defined as 'void callback(void *)'. + * + * \return The status of the timer creation. + * \retval true Timer was created successfully. + * \retval false Timer was failed to create. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_create(void **pp_handle, const char *p_timer_name, uint32_t timer_id, + uint32_t interval_ms, bool reload, void (*p_timer_callback)()); + +/** + * os_timer.h + * + * \brief Start a timer that was previously created using the os_timer_create() API + * function. If the timer had already been started and was in the active state, + * then os_timer_create() has equivalent functionality to the os_timer_create() + * API function. + * + * \param[in] pp_handle Pointer to the created timer handle. + * + * \return The status of the timer starting. + * \retval true Timer was started successfully. + * \retval false Timer was failed to start. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_start(void **pp_handle); + +/** + * os_timer.h + * + * \brief Restart a timer that was previously created using the os_timer_create() API + * function. If the timer had already been started and was already in the active + * state, then os_timer_start() will cause the timer to re-evaluate its expiry + * time so that it is relative to when os_timer_start() was called. If the timer + * was in the dormant state then os_timer_start() has equivalent functionality to + * the os_timer_start() API function. + * + * \param[in] pp_handle Pointer to the created timer handle. + * + * \param[in] interval_ms The timer period in milliseconds. + * + * \return The status of the timer restarting. + * \retval true Timer was restarted successfully. + * \retval false Timer was failed to restart. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Restart the specified timer. + * os_timer_restart(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_restart(void **pp_handle, uint32_t interval_ms); + +/** + * os_timer.h + * + * \brief Stop a timer that was previously started using either of the os_timer_start(), + * os_timer_restart() API functions. Stopping a timer ensures the timer is not in + * the active state. + * + * \param[in] pp_handle Pointer to the handle of timer being stopped. + * + * \return The status of the timer stopping. + * \retval true Timer was stopped successfully. + * \retval false Timer was failed to stop. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created and stopped. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * // Stop the timer before expiration. + * os_timer_stop(&p_handle); + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_stop(void **pp_handle); + +/** + * os_timer.h + * + * \brief Delete a timer that was previously created using the os_timer_create() + * API function. + * + * \param[in] pp_handle Pointer to the handle of timer being deleted. + * + * \return The status of the timer deletion. + * \retval true Timer was deleted successfully. + * \retval false Timer was failed to delete. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created and deleted. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_delete(void **pp_handle); + +/** + * os_timer.h + * + * \brief Dump all current used timers in system. + * + * \param None + * + * \return The status of the timer dump. + * \retval true Timer was dumped successfully. + * \retval false Timer was failed to dump. + * + * Example usage + * \code{.c} + * // Timer callback function. + * void timer_callback(void *p_handle) + * { + * uint32_t timer_id; + * + * // Which timer expired? + * os_timer_id_get(&p_handle, &timer_id); + * + * if (timer_id == TIMER_ID) + * { + * // Delete the specified timer. + * os_timer_delete(&p_handle); + * } + * } + * + * #define TIMER_ID 1 + * + * // Timer to be created and dumped. + * int test(void) + * { + * void *p_handle = NULL; + * + * if (os_timer_create(&p_handle, "timer", TIMER_ID, + * INTERVAL_MS, false, timer_callback) == true) + * { + * // Timer created successfully, start the timer. + * os_timer_start(&p_handle); + * } + * else + * { + * // Timer failed to create. + * return -1; + * } + * + * // Dump all used timers. + * os_timer_dump(); + * + * return 0; + * } + * \endcode + * + * \ingroup Timer + */ +bool os_timer_dump(void); + +/** + * os_timer.h + * + * \brief get a timer state + * + * \param[in] pp_handle Pointer to the created timer handle. + * \param[out] p_timer_state Used to pass back the timer state. + * \arg \c 1 Timer is active. + * \arg \c 0 Timer is not active or timer is not created. + * + * \retval true Timer state was got successfully. + * \retval false Timer state was failed to get. + * \note A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Example usage + * \code{.c} + * // This function assumes the timer has already been created. + * void vAFunction( void *p_handle ) + * { + * uint32_t timer_state; + * os_timer_state_get(&p_handle,&timer_state); + * if(timer_state) + * { + * // Timer is active, do something. + * } + * else + * { + * //Timer is not active, do something else. + * } + * } + * \endcode + * + * \ingroup Timer + */ + +typedef void (*PendedFunctionOS_t)(void *para1, uint32_t para2); + +bool os_timer_state_get(void **pp_handle, uint32_t *p_timer_state); + +/* internal function */ +void os_timer_init(void); + +bool os_timer_number_get(void **pp_handle, uint32_t *p_timer_num); +bool os_timer_pendcall(PendedFunctionOS_t xFunctionToPend, void *para1, uint32_t para2, + uint32_t xTicksToWait); +uint32_t os_timer_next_timeout_value_get(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _OS_TIMER_H_ */ diff --git a/inc/os/readme b/inc/os/readme new file mode 100644 index 0000000..e69de29 diff --git a/inc/os/system_trace/system_trace.h b/inc/os/system_trace/system_trace.h new file mode 100644 index 0000000..b749bca --- /dev/null +++ b/inc/os/system_trace/system_trace.h @@ -0,0 +1,41 @@ +/****************************************************************************************************//** + * @file system_trace.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _SYSTEM_TRACE_H_ +#define _SYSTEM_TRACE_H_ + +#include "app_section.h" +#include "trace_heap.h" +#include "trace_stack.h" +#include "trace_timer.h" +#include "trace_queue.h" +#include "trace_dlps.h" +#include "trace_task_hang.h" +#include "trace_hardfault.h" +#include "trace_wdg_timeout.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern HEAP_INFO heap_info[TRACE_HEAP_TYPE_NUM]; +extern STACK_INFO stack_info; +extern TIMER_INFO timer_info; +extern QUEUE_INFO queue_info[MAX_QUEUE_OBJECTS_NUM]; + +extern void system_trace_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_SYSTEM_TRACE_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_common.h b/inc/os/system_trace/trace_common.h new file mode 100644 index 0000000..6266575 --- /dev/null +++ b/inc/os/system_trace/trace_common.h @@ -0,0 +1,55 @@ +/****************************************************************************************************//** + * @file trace_common.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_COMMON_H_ +#define _TRACE_COMMON_H_ + +#include +#include + +#ifndef NULL +#define NULL (void *)0 +#endif + +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +//typedef uint32_t size_t; +typedef portSTACK_TYPE StackType_t; +typedef unsigned long UBaseType_t; + +typedef struct tskTaskControlBlock +{ + uint32_t *pxTopOfStack; + uint32_t xGenericListItem[5]; + uint32_t xEventListItem[5]; + uint32_t uxPriority; + uint32_t *pxStack; + char pcTaskName[ 12 ]; + uint32_t uxTCBNumber; + uint32_t uxTaskNumber; + uint32_t uxBasePriority; + uint32_t uxMutexesHeld; +} TCB_t; + +typedef bool (*BOOL_PATCH_FUNC)(); + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_COMMON_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_config.h b/inc/os/system_trace/trace_config.h new file mode 100644 index 0000000..72cd996 --- /dev/null +++ b/inc/os/system_trace/trace_config.h @@ -0,0 +1,41 @@ +/****************************************************************************************************//** + * @file trace_config.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_CONFIG_H_ +#define _TRACE_CONFIG_H_ + +#define TRACE_HEAP_EN 1 +#define TRACE_STACK_EN 1 +#define TRACE_TIMER_EN 1 +#define TRACE_QUEUE_EN 1 +#define DEBUG_TASK_HANG_EN 1 +#define DEBUG_DLPS_ERROR_EN 1 +#define TRACE_HARDFAULT 1 +#define TRACE_WDG_TIMEOUT 1 +#define TRACE_TASK_HANG_USE_WDG_ISR 1 +/******************* CONFIGURATION *******************/ +#define TRACE_PERIOD_TIME ( 10 * 1000 ) + +/******************* QUEUE CONFIGURATION *******************/ +#define QUEUE_OBJECTS_NUM ( 3 ) +//#define TRACE_QUEUE_PERIOD_TIME ( 10 * 1000 ) + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_CONFIG_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_cpu_loading.h b/inc/os/system_trace/trace_cpu_loading.h new file mode 100644 index 0000000..178a091 --- /dev/null +++ b/inc/os/system_trace/trace_cpu_loading.h @@ -0,0 +1,27 @@ +/****************************************************************************************************//** + * @file trace_cpu_loading.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_CPU_LOADING_H_ +#define _TRACE_CPU_LOADING_H_ + +#include "trace_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_CPU_LOADING_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_dlps.h b/inc/os/system_trace/trace_dlps.h new file mode 100644 index 0000000..701e305 --- /dev/null +++ b/inc/os/system_trace/trace_dlps.h @@ -0,0 +1,32 @@ +/****************************************************************************************************//** + * @file trace_dlps.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_DLPS_H_ +#define _TRACE_DLPS_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef bool (*TRACE_DLPS_USER_CB)(); + +bool trace_dlps_init(uint32_t trace_period_time_ms, uint32_t trace_total_time_ms, + TRACE_DLPS_USER_CB trace_dlps_user_cb); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_DLPS_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_hardfault.h b/inc/os/system_trace/trace_hardfault.h new file mode 100644 index 0000000..94c9931 --- /dev/null +++ b/inc/os/system_trace/trace_hardfault.h @@ -0,0 +1,123 @@ +/****************************************************************************************************//** + * @file trace_hardfault.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + ****************************************************************************************************/ + +#ifndef TRACE_HARDFAULT_H +#define TRACE_HARDFAULT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "trace_common.h" +#include "trace_port_config.h" + +typedef struct +{ + uint32_t stacked_r0; + uint32_t stacked_r1; + uint32_t stacked_r2; + uint32_t stacked_r3; + uint32_t stacked_r4; + uint32_t stacked_r5; + uint32_t stacked_r6; + uint32_t stacked_r7; + uint32_t stacked_r8; + uint32_t stacked_r9; + uint32_t stacked_r10; + uint32_t stacked_r11; + uint32_t stacked_r12; + uint32_t stacked_lr; + uint32_t stacked_pc; + uint32_t stacked_psr; + uint32_t old_sp; + uint32_t msp; + uint32_t cfsr; + uint32_t bus_fault_address; + uint32_t memmanage_fault_address; + + uint32_t PRIMASK; + uint32_t BASEPRI; + uint32_t EXC_RETURN; + + uint32_t HFSR; + uint32_t DFSR; + uint32_t AFSR; +} T_HARDFAULT_RECORD; + +/******** magic pattern for hardfault record ********/ +#define HARDFAULT_PATTERN_BEG (0xbeefface) +#define HARDFAULT_PATTERN_END (0xbabeface) +#define HARDFAULT_PATTERN_MID (0xdcabface) + +extern bool patch_hardfault_save_to_flash_init(void); + +/************Dump info: ********* +*********Part0: beg pattern******************* +4: PATTERN_BEG +*********Part1: hardfault register record**** +sizeof(*record): hardfault reg info +4: PATTERN_MID +*********Part2: Current task stack**** +1024: current task stack +4: PATTERN_MID +16: bottom of current task stack +4: PATTERN_MID +*********Part3: specific task stack**** +task stack size0: task stack0 +4: PATTERN_MID +16: bottom of task stack0 +4: PATTERN_MID +task stack size1: task stack1 +4: PATTERN_MID +16: bottom of task stack1 +4: PATTERN_MID +....... +task stack size n: task stack n +4: PATTERN_MID +16: bottom of task stack n +4: PATTERN_MID +**********Part4: end pattern******************* +4: PATTERN_END +*********************************/ + +/** + * extern void *app_task_handle; + * TCB_t *pxTimerTCB =(TCB_t *)xTimerTaskHandle; + * TCB_t *pxLowerTCB =(TCB_t *)low_task_handle; + * TCB_t *pxUpperTCB =(TCB_t *)upperstack_handle; + * TCB_t *pxAppTCB =(TCB_t *)app_task_handle; +*/ +/** + * @brief Initializes trace_hardfault save to flash including critical task stack + * @param dump_task_stack_num: number of task + * @return if it is successfully initialized , return true + + * For example + hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024); + @param 2: dump two task stack + @param low_task_handle: lowstack task handler value + @param 1024: dump task stack size + @param app_task_handle: upperstack task handler value + @param 1024: dump task stack size + @note if need dump app task, must call this api after app task created!!! + Upperstack handler address is different when used different upperstack img! + */ +void hardfault_save_to_flash_init(uint32_t dump_task_stack_num, ...); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/os/system_trace/trace_heap.h b/inc/os/system_trace/trace_heap.h new file mode 100644 index 0000000..f53ca67 --- /dev/null +++ b/inc/os/system_trace/trace_heap.h @@ -0,0 +1,44 @@ +/****************************************************************************************************//** + * @file trace_heap.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_HEAP_H_ +#define _TRACE_HEAP_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _BLOCK_SIZE_LIST +{ + uint32_t number; + uint32_t size[TRACE_HEAP_MAX_NUMBER_IN_BLOCK_LIST]; +} BLOCK_SIZE_LIST; + +typedef struct _HEAP_INFO +{ + uint32_t total_size; + uint32_t curr_remain_size; + uint32_t minimum_ever_free_size; + //BLOCK_SIZE_LIST used_size_list; + BLOCK_SIZE_LIST free_size_list; +} HEAP_INFO; + +extern void trace_heap(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_HEAP_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_port_config.h b/inc/os/system_trace/trace_port_config.h new file mode 100644 index 0000000..0aa813c --- /dev/null +++ b/inc/os/system_trace/trace_port_config.h @@ -0,0 +1,66 @@ +/****************************************************************************************************//** + * @file trace_port_config.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_PORT_CONFIG_H_ +#define _TRACE_PORT_CONFIG_H_ + +#include "mem_config.h" +#include "otp.h" +#include "rtl876x_ic_type.h" + +/******************* CPU CONFIGURATION *******************/ +#if (IC_TYPE == IC_TYPE_BEE3) +#define PLATFORM_SUPPORT_CM4_INSTRUCTIONS 0 +#elif (IC_TYPE == IC_TYPE_SBEE2) +#define PLATFORM_SUPPORT_CM4_INSTRUCTIONS 1 +#endif + + +/******************* OS CONFIGURATION *******************/ +#define MAX_TASK_COUNT_FOR_DEBUG ( 12 ) +#define configMAX_TASK_NAME_LEN ( 10 ) + +/******************* HEAP CONFIGURATION *******************/ + +/* Bee2 has 2 types: data and buffer */ +#define TRACE_HEAP_TYPE_NUM ( 2 ) +#define TRACE_HEAP_MAX_NUMBER_IN_BLOCK_LIST ( 16 ) + +/******************* STACK CONFIGURATION *******************/ + +#define MAIN_STACK_START_ADDRESS ( DATA_RAM_START_ADDR + DATA_RAM_ROM_GLOBAL_SIZE ) //the bottom of stack + +/******************* TIMER CONFIGURATION *******************/ + +#define MAX_TIMER_NUM ( otp.os_cfg.timerMaxNumber ) + + +/******************* QUEUE CONFIGURATION *******************/ + +#define MAX_QUEUE_OBJECTS_NUM ( 8 ) + +/******************* DLPS CONFIGURATION *******************/ + + + + +/******************* CONFIGURATION END*******************/ +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_PORT_CONFIG_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_queue.h b/inc/os/system_trace/trace_queue.h new file mode 100644 index 0000000..035e889 --- /dev/null +++ b/inc/os/system_trace/trace_queue.h @@ -0,0 +1,38 @@ +/****************************************************************************************************//** + * @file trace_queue.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_QUEUE_H_ +#define _TRACE_QUEUE_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _QUEUE_INFO +{ + uint16_t capacity_num; + uint16_t curr_num_in_queue; + uint16_t maximum_ever_num_in_queue; + uint16_t reserved; +} QUEUE_INFO; + +extern bool trace_queue_init(uint32_t queue_num, ...); +extern void trace_queue(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_QUEUE_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_stack.h b/inc/os/system_trace/trace_stack.h new file mode 100644 index 0000000..ce9f113 --- /dev/null +++ b/inc/os/system_trace/trace_stack.h @@ -0,0 +1,44 @@ +/****************************************************************************************************//** + * @file trace_stack.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_STACK_H_ +#define _TRACE_STACK_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _TASK_STACK_INFO_BLOCK +{ + uint32_t task_id; + uint32_t minimum_ever_remain_size; + char task_name[configMAX_TASK_NAME_LEN]; +} TASK_STACK_INFO_BLOCK_t; + + +typedef struct _STACK_INFO +{ + uint32_t task_number; + TASK_STACK_INFO_BLOCK_t task_stack_info[MAX_TASK_COUNT_FOR_DEBUG]; + uint32_t main_stack_minimum_ever_remain_size; +} STACK_INFO; + +extern void trace_task_stack(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_STACK_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_task_hang.h b/inc/os/system_trace/trace_task_hang.h new file mode 100644 index 0000000..ffe12f7 --- /dev/null +++ b/inc/os/system_trace/trace_task_hang.h @@ -0,0 +1,29 @@ +/****************************************************************************************************//** + * @file trace_task_hang.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_TASK_HANG_H_ +#define _TRACE_TASK_HANG_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern bool trace_task_hang_init(uint32_t queue_num, ...); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_TASK_HANG_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_task_schedule.h b/inc/os/system_trace/trace_task_schedule.h new file mode 100644 index 0000000..7ee9f49 --- /dev/null +++ b/inc/os/system_trace/trace_task_schedule.h @@ -0,0 +1,27 @@ +/****************************************************************************************************//** + * @file trace_task_schedule.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_TASK_SCHEDULE_H_ +#define _TRACE_TASK_SCHEDULE_H_ + +#include "trace_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_TASK_SCHEDULE_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_timer.h b/inc/os/system_trace/trace_timer.h new file mode 100644 index 0000000..8230b72 --- /dev/null +++ b/inc/os/system_trace/trace_timer.h @@ -0,0 +1,36 @@ +/****************************************************************************************************//** + * @file trace_timer.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + *******************************************************************************************************/ +#ifndef _TRACE_TIMER_H_ +#define _TRACE_TIMER_H_ + +#include "trace_common.h" +#include "trace_port_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _TIMER_INFO +{ + uint16_t curr_used_num; + uint16_t minimum_ever_remain_num; +} TIMER_INFO; + +extern bool trace_timer_init(void); +extern void trace_timer(void); + +#ifdef __cplusplus +} +#endif + +#endif /*_TRACE_TIMER_H_*/ + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/os/system_trace/trace_wdg_timeout.h b/inc/os/system_trace/trace_wdg_timeout.h new file mode 100644 index 0000000..42efcd1 --- /dev/null +++ b/inc/os/system_trace/trace_wdg_timeout.h @@ -0,0 +1,47 @@ +/****************************************************************************************************//** + * @file trace_wdg_timeout.h + * + * @brief + * + * @version v0.1 + * @date 2018-11-05 + * + * @note + ****************************************************************************************************/ + +#ifndef TRACE_WDG_TIMEOUT_H +#define TRACE_WDG_TIMEOUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "trace_common.h" +#include "trace_port_config.h" + +/******** magic pattern for wdg timeout reason record ********/ +#define WDG_TIMEOUT_PATTERN_BEG (0xfdcebaef) +#define WDG_TIMEOUT_PATTERN_END (0xfcaebaef) + +/************Dump info: ********* +4: beg pattern(value=0xfdcebaef) +4: reset reason(value=0x1) +4: lr +4: pc +4: sp +80: current TCB +512 or less: task callstck +4: end pattern(value=0xfcaebaef) +*********************************/ +extern void patch_wdg_timeout_reason_save_to_flash_init(void); + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/peripheral/readme b/inc/peripheral/readme new file mode 100644 index 0000000..e69de29 diff --git a/inc/peripheral/rtl876x_3wire_spi.h b/inc/peripheral/rtl876x_3wire_spi.h new file mode 100644 index 0000000..7a7062b --- /dev/null +++ b/inc/peripheral/rtl876x_3wire_spi.h @@ -0,0 +1,566 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_3wire_spi.h +* \brief The header file of the peripheral 3-wire SPI driver. +* \details This file provides all 3-wire SPI firmware functions. +* \author elliot chen +* \date 2016-12-13 +* \version v1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876x_3WIRE_SPI_H_ +#define _RTL876x_3WIRE_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup SPI3WIRE SPI 3WIRE + * + * \brief Manage the SPI 3WIRE peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup THREE_WIRE_SPI_Exported_Types Init Params Struct + * + * \ingroup SPI3WIRE + */ + +/** + * \brief THREE_WIRE_SPI init structure definition. + * \ingroup THREE_WIRE_SPI_Exported_Types + */ +typedef struct +{ + uint32_t SPI3WIRE_SysClock; /**< Specifies system clock. */ + uint32_t SPI3WIRE_Speed; /**< Specifies 3-wire SPI clock. */ + uint32_t SPI3WIRE_Mode; /**< Specifies 3-wire SPI operation mode. + This parameter can be a value of \ref THREE_WIRE_SPI_Mode */ + uint32_t SPI3WIRE_ReadDelay; /**< Specifies the delay time from the end of address phase to the start of read data phase. + This parameter can be a value of 0x0 to 0x1f, delay time = (SPI3WIRE_ReadDelay+1)/(2*SPI3WIRE_Speed) */ + uint32_t SPI3WIRE_OutputDelay; /**< Specifies SPI output delay 1T or not. + This parameter can be a value of \ref THREE_WIRE_SPI_OE_Delay_Config */ + uint32_t SPI3WIRE_ExtMode; /**< Specifies extended timing window for SPI output enable = 0. */ +} SPI3WIRE_InitTypeDef; + +/*============================================================================* + * Register Definitions + *============================================================================*/ + +/* Peripheral: SPI3WIRE */ +/* Description: SPI3WIRE register defines */ + +/* Register: CFGR ------------------------------------------------------------*/ +/* Description: SPI3WIRE configuration register. Offset: 0x30. Address: 0x40004030. */ + +/* CFGR[31] :SPI3WIRE_SSI_EN. 0x1: enable SPI3WIRE mode. 0x0: disable SPI3WIRE mode. */ +#define SPI3WIRE_SSI_EN_Pos (31UL) +#define SPI3WIRE_SSI_EN_Msk (0x1UL << SPI3WIRE_SSI_EN_Pos) +#define SPI3WIRE_SSI_EN_CLR (~SPI3WIRE_SSI_EN_Msk) +/* CFGR[30] :SPI3WIRE_SSI_CS_EN. 0x1: enable CS signal. 0x0: disable CS signal. */ +#define SPI3WIRE_SSI_CS_EN_Pos (30UL) +#define SPI3WIRE_SSI_CS_EN_Msk (0x1UL << SPI3WIRE_SSI_CS_EN_Pos) +#define SPI3WIRE_SSI_CS_EN_CLR (~SPI3WIRE_SSI_CS_EN_Msk) +/* CFGR[29] :SPI3WIRE_SSI_END_EXT_EN. 0x1: extend mode. 0x0: normal mode. */ +/* Note: Using this control bit can extend the timing window for SPI output enable = 0, The extend time is 1/(2*SPI_CLK) */ +#define SPI3WIRE_SSI_END_EXT_EN_Pos (29UL) +#define SPI3WIRE_SSI_END_EXT_EN_Msk (0x1UL << SPI3WIRE_SSI_END_EXT_EN_Pos) +#define SPI3WIRE_SSI_END_EXT_EN_CLR (~SPI3WIRE_SSI_END_EXT_EN_Msk) +/* CFGR[28] :SPI3WIRE_SSI_OE_DLY_EN. 0x1: enable. 0x0: disable. */ +/* Note: Extend 1T of ssi_OE(output-> intput switch delay 4T->5T ) */ +#define SPI3WIRE_SSI_OE_DLY_EN_Pos (28UL) +#define SPI3WIRE_SSI_OE_DLY_EN_Msk (0x1UL << SPI3WIRE_SSI_OE_DLY_EN_Pos) +#define SPI3WIRE_SSI_OE_DLY_EN_CLR (~SPI3WIRE_SSI_OE_DLY_EN_Msk) +/* CFGR[21] :SPI3WIRE_SSI_RESYNC_TIME. */ +/* output n*T low pulse, write 1 to 0x38 bit[31] to output;The T time is 1/(2*ssi_CLK) */ +#define SPI3WIRE_SSI_RESYNC_TIME_Pos (21UL) +#define SPI3WIRE_SSI_RESYNC_TIME_Msk (0xfUL << SPI3WIRE_SSI_RESYNC_TIME_Pos) +#define SPI3WIRE_SSI_RESYNC_TIME_CLR (~SPI3WIRE_SSI_RESYNC_TIME_Msk) +/* CFGR[20] :SPI3WIRE_SSI_BURST_READ_EN. 0x1: enable burst read. 0x0: disable. */ +#define SPI3WIRE_SSI_BURST_READ_EN_Pos (20UL) +#define SPI3WIRE_SSI_BURST_READ_EN_Msk (0x1UL << SPI3WIRE_SSI_BURST_READ_EN_Pos) +#define SPI3WIRE_SSI_BURST_READ_EN_CLR (~SPI3WIRE_SSI_BURST_READ_EN_Msk) +/* CFGR[16] :SPI3WIRE_SSI_BURST_READ_NUM. The total number of read data bytes in burst mode */ +#define SPI3WIRE_SSI_BURST_READ_NUM_Pos (16UL) +#define SPI3WIRE_SSI_BURST_READ_NUM_Msk (0xfUL << SPI3WIRE_SSI_BURST_READ_NUM_Pos) +#define SPI3WIRE_SSI_BURST_READ_NUM_CLR (~SPI3WIRE_SSI_BURST_READ_NUM_Msk) +/* CFGR[8] :SPI3WIRE_SSI_DIV_NUM. The divider number to generate 2x SPI_CLK */ +#define SPI3WIRE_SSI_DIV_NUM_Pos (8UL) +#define SPI3WIRE_SSI_DIV_NUM_Msk (0xffUL << SPI3WIRE_SSI_DIV_NUM_Pos) +#define SPI3WIRE_SSI_DIV_NUM_CLR (~SPI3WIRE_SSI_DIV_NUM_Msk) +/* CFGR[3] :SPI3WIRE_SSI_DLY_CYCLE. The delay time from the end of address phase to the start of read data phase. */ +#define SPI3WIRE_SSI_DLY_CYCLE_Pos (3UL) +#define SPI3WIRE_SSI_DLY_CYCLE_Msk (0x1fUL << SPI3WIRE_SSI_DLY_CYCLE_Pos) +#define SPI3WIRE_SSI_DLY_CYCLE_CLR (~SPI3WIRE_SSI_DLY_CYCLE_Msk) +/* CFGR[1] :SPI3WIRE_SSI_INT_MASK. 0x1: mask. 0x0: no mask. */ +#define SPI3WIRE_SSI_INT_MASK_Pos (1UL) +#define SPI3WIRE_SSI_INT_MASK_Msk (0x1UL << SPI3WIRE_SSI_INT_MASK_Pos) +#define SPI3WIRE_SSI_INT_MASK_CLR (~SPI3WIRE_SSI_INT_MASK_Msk) +/* CFGR[0] :SPI3WIRE_SSI_INT_EN. 0x1: enable. 0x0: disable. */ +#define SPI3WIRE_SSI_INT_EN_Pos (0UL) +#define SPI3WIRE_SSI_INT_EN_Msk (0x1UL << SPI3WIRE_SSI_INT_EN_Pos) +#define SPI3WIRE_SSI_INT_EN_CLR (~SPI3WIRE_SSI_INT_EN_Msk) + +/* Register: CR ------------------------------------------------------------*/ +/* Description: SPI3WIRE control register. Offset: 0x34. Address: 0x40004034. */ + +/* CR[15] :SPI3WIRE_RW_MODE. 0x1: write mode. 0x0: read mode. */ +#define SPI3WIRE_RW_MODE_Pos (15UL) +#define SPI3WIRE_RW_MODE_Msk (0x1UL << SPI3WIRE_RW_MODE_Pos) +#define SPI3WIRE_RW_MODE_CLR (~SPI3WIRE_RW_MODE_Msk) +/* CR[8] :SPI3WIRE_ADDRESS. */ +#define SPI3WIRE_ADDRESS_Pos (8UL) +#define SPI3WIRE_ADDRESS_Msk (0x7fUL << SPI3WIRE_ADDRESS_Pos) +#define SPI3WIRE_ADDRESS_CLR (~SPI3WIRE_ADDRESS_Msk) +/* CR[0] :SPI3WIRE_DATA. write data ; in read mode, this data byte is useless */ +#define SPI3WIRE_DATA_Pos (0UL) +#define SPI3WIRE_DATA_Msk (0xffUL << SPI3WIRE_ADDRESS_Pos) +#define SPI3WIRE_DATA_CLR (~SPI3WIRE_ADDRESS_Msk) + +/* Register: INTCR ------------------------------------------------------------*/ +/* Description: SPI3WIRE interrupt clear register. Offset: 0x38. Address: 0x40004038. */ + +/* INTCR[31] :SPI3WIRE_RESYNV_EN. 0x1: trriger resync signal. 0x0: disable resync signal. */ +#define SPI3WIRE_RESYNV_EN_Pos (30UL) +#define SPI3WIRE_RESYNV_EN_Msk (0x1UL << SPI3WIRE_RESYNV_EN_Pos) +#define SPI3WIRE_RESYNV_EN_CLR (~SPI3WIRE_RESYNV_EN_Msk) +/* INTCR[2] :SPI3WIRE_RD_DATA_CLEAR. 0x1: write clear. */ +#define SPI3WIRE_RD_DATA_CLEAR_Pos (2UL) +#define SPI3WIRE_RD_DATA_CLEAR_Msk (0x1UL << SPI3WIRE_RD_DATA_CLEAR_Pos) +/* INTCR[1] :SPI3WIRE_RD_NUM_CLEAR. 0x1: write clear. */ +#define SPI3WIRE_RD_NUM_CLEAR_Pos (1UL) +#define SPI3WIRE_RD_NUM_CLEAR_Msk (0x1UL << SPI3WIRE_RD_NUM_CLEAR_Pos) +/* INTCR[0] :SPI3WIRE_INT_CLEAR. 0x1: write clear. */ +#define SPI3WIRE_INT_CLEAR_Pos (0UL) +#define SPI3WIRE_INT_CLEAR_Msk (0x1UL << SPI3WIRE_INT_CLEAR_Pos) + +#define SPI3WIRE_FIFO_INT_ALL_CLR (SPI3WIRE_RD_DATA_CLEAR_Msk | \ + SPI3WIRE_RD_NUM_CLEAR_Msk | \ + SPI3WIRE_INT_CLEAR_Msk) + +/* Register: SR ------------------------------------------------------------*/ +/* Description: SPI3WIRE status register. Offset: 0x3C. Address: 0x4000403C. */ + +/* SR[6] :SPI3WIRE_RESYNV_BUSY. 0x1: Resync busy. 0x0: Resync idle. */ +#define SPI3WIRE_RESYNV_BUSY_Pos (6UL) +#define SPI3WIRE_RESYNV_BUSY_Msk (0x1UL << SPI3WIRE_RESYNV_BUSY_Pos) +#define SPI3WIRE_RESYNV_BUSY_CLR (~SPI3WIRE_RESYNV_BUSY_Msk) +/* SR[5] :SPI3WIRE_INT_STATUS. 0x1: Interrupt. 0x0: No interrupt. */ +#define SPI3WIRE_INT_STATUS_Pos (5UL) +#define SPI3WIRE_INT_STATUS_Msk (0x1UL << SPI3WIRE_INT_STATUS_Pos) +#define SPI3WIRE_INT_STATUS_CLR (~SPI3WIRE_INT_STATUS_Msk) +/* SR[4] :SPI3WIRE_BUSY. 0x1: Busy. 0x0:Idle. */ +#define SPI3WIRE_BUSY_Pos (4UL) +#define SPI3WIRE_BUSY_Msk (0x1UL << SPI3WIRE_BUSY_Pos) +#define SPI3WIRE_BUSY_CLR (~SPI3WIRE_BUSY_Msk) +/* SR[0] :SPI3WIRE_RDATA_NUM. The total number of data byte in each SPI read transaction */ +#define SPI3WIRE_RDATA_NUM_Pos (0UL) +#define SPI3WIRE_RDATA_NUM_Msk (0xfUL << SPI3WIRE_RDATA_NUM_Pos) +#define SPI3WIRE_RDATA_NUM_CLR (~SPI3WIRE_RDATA_NUM_Msk) + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup THREE_WIRE_SPI_Exported_Constants Macro Definitions + * + * \ingroup SPI3WIRE + */ + +/** + * \defgroup THREE_WIRE_SPI_Mode 3WIRE SPI Mode + * \{ + * \ingroup THREE_WIRE_SPI_Exported_Constants + */ +#define SPI3WIRE_2WIRE_MODE ((uint32_t)(0 << SPI3WIRE_SSI_CS_EN_Pos)) +#define SPI3WIRE_3WIRE_MODE ((uint32_t)(1 << SPI3WIRE_SSI_CS_EN_Pos)) +/** \} */ +#define IS_SPI3WIRE_MODE(MODE) ((MODE) == SPI3WIRE_2WIRE_MODE || (MODE) == SPI3WIRE_3WIRE_MODE) + +/** + * \defgroup THREE_WIRE_SPI_OE_Delay_Config 3WIRE SPI OE Delay Config + * \{ + * \ingroup THREE_WIRE_SPI_Exported_Constants + */ +#define SPI3WIRE_OE_DELAY_NONE ((uint32_t)(0 << SPI3WIRE_SSI_OE_DLY_EN_Pos)) +#define SPI3WIRE_OE_DELAY_1T ((uint32_t)(1 << SPI3WIRE_SSI_OE_DLY_EN_Pos)) +/** \} */ +#define IS_SPI3WIRE_OE_DELAY_CFG(CFG) ((CFG) == SPI3WIRE_OE_DELAY_1T || (CFG) == SPI3WIRE_OE_DELAY_NONE) + +/** + * \defgroup THREE_WIRE_SPI_End_Extend_Mode 3WIRE SPI End Extend Mode + * \{ + * \ingroup THREE_WIRE_SPI_Exported_Constants + */ +#define SPI3WIRE_NORMAL_MODE ((uint32_t)(0 << SPI3WIRE_SSI_END_EXT_EN_Pos)) +#define SPI3WIRE_EXTEND_MODE ((uint32_t)(1 << SPI3WIRE_SSI_END_EXT_EN_Pos)) +/** \} */ +#define IS_SPI3WIRE_END_EXTEND_MODE(MODE) ((MODE) == SPI3WIRE_EXTEND_MODE || (MODE) == SPI3WIRE_NORMAL_MODE) + +/** + * \brief THREE_WIRE_SPI_Read_Cycle_Delay + */ +#define IS_SPI3WIRE_READ_CYCLE_DELAY(DELAY) (DELAY <= 0x1f) + +/** + * \defgroup THREE_WIRE_SPI_FLAG 3WIRE SPI FLAG + * \{ + * \ingroup THREE_WIRE_SPI_Exported_Constants + */ +#define SPI3WIRE_FLAG_BUSY ((uint32_t)SPI3WIRE_BUSY_Msk) +#define SPI3WIRE_FLAG_INT_IND ((uint32_t)SPI3WIRE_INT_STATUS_Msk) +#define SPI3WIRE_FLAG_RESYNC_BUSY ((uint32_t)SPI3WIRE_RESYNV_BUSY_Msk) +/** \} */ +#define IS_SPI3WIRE_FLAG(FLAG) (((FLAG) == SPI3WIRE_FLAG_BUSY) || \ + ((FLAG) == SPI3WIRE_FLAG_INT_IND) || \ + ((FLAG) == SPI3WIRE_FLAG_RESYNC_BUSY)) + +/** + * \defgroup THREE_WIRE_SPI_Interrupt_Definition 3WIRE SPI Interrupt Definition + * \{ + * \ingroup THREE_WIRE_SPI_Exported_Constants + */ +#define SPI3WIRE_INT_BIT ((uint32_t)SPI3WIRE_SSI_INT_EN_Msk) +/** \} */ +#define IS_SPI3WIRE_INT(INT) ((INT) == SPI3WIRE_INT_BIT) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup THREE_WIRE_SPI_Exported_Functions Peripheral APIs + * \{ + * \ingroup SPI3WIRE + */ + +/** + * \brief Deinitializes the 3WIRE SPI peripheral registers to their default reset values. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi3wire_init(void) + * { + * SPI3WIRE_DeInit(); + * } + * \endcode + */ +void SPI3WIRE_DeInit(void); + +/** + * \brief Initializes the 3-wire SPI peripheral according to the specified + * parameters in SPI3WIRE_InitStruct + * \param[in] SPI3WIRE_InitStruct: Pointer to a SPI3WIRE_InitTypeDef structure that + * contains the configuration information for the specified 3-wire SPI peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi3wire_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE); + * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct; + * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct); + * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 2000000; + * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_3WIRE_MODE; + * SPI3WIRE_InitStruct.SPI3WIRE_ReadDelay = 0x1f; + * SPI3WIRE_InitStruct.SPI3WIRE_OutputDelay = SPI3WIRE_OE_DELAY_1T; + * SPI3WIRE_InitStruct.SPI3WIRE_ExtMode = SPI3WIRE_EXTEND_MODE; + * SPI3WIRE_Init(&SPI3WIRE_InitStruct); + * } + * \endcode + */ +void SPI3WIRE_Init(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct); + +/** + * \brief Fills each SPI3WIRE_InitStruct member with its default value. + * \param[in] SPI3WIRE_InitStruct: Pointer to an SPI3WIRE_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi3wire_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE); + * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct; + * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct); + * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000; + * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000; + * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE; + * SPI3WIRE_Init(SPI3WIRE); + * } + * \endcode + */ +void SPI3WIRE_StructInit(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct); + +/** + * \brief Enables or disables the specified SPI3WIRE peripheral. + * \param[in] NewState: New state of the SPI3WIRE peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi3wire_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE); + * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct; + * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct); + * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000; + * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000; + * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE; + * SPI3WIRE_Init(SPI3WIRE); + * SPI3WIRE_Cmd(ENABLE); + * } + * \endcode + */ +void SPI3WIRE_Cmd(FunctionalState NewState); + +/** + * \brief Enables or disables the specified SPI3WIRE interrupts. + * \param[in] SPI3WIRE_INT: Specifies the SPI3WIRE interrupts sources to be enabled or disabled. + * This parameter can be only be the following value: + * \arg SPI3WIRE_INT_BIT: Enable SPI3WIRE interrupt. + * \param[in] newState: New state of the specified SPI3WIRE interrupts. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi3wire_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, ENABLE); + * SPI3WIRE_InitTypeDef SPI3WIRE_InitStruct; + * SPI3WIRE_StructInit(&SPI3WIRE_InitStruct); + * SPI3WIRE_InitStruct.SPI3WIRE_SysClock = 20000000; + * SPI3WIRE_InitStruct.SPI3WIRE_Speed = 800000; + * SPI3WIRE_InitStruct.SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE; + * SPI3WIRE_Init(SPI3WIRE); + * SPI3WIRE_INTConfig(SPI3WIRE_INT_BIT, ENABLE); + * } + * \endcode + */ +void SPI3WIRE_INTConfig(uint32_t SPI3WIRE_INT, FunctionalState newState); + +/** + * \brief Configure resync signal time value. + * \param[in] value: Resync signal time value whose uint is 1/(2*SPI3WIRE_Speed). + * This parameter can be only be the following value: 0x0 to 0xf. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * SPI3WIRE_SetResyncTime(10); + * } + * \endcode + */ +void SPI3WIRE_SetResyncTime(uint32_t value); + +/** + * \brief Send resync signal or not. Must send when SPI3WIRE is disable. + * \param[in] NewState: New state of the SPI3WIRE peripheral. + * This parameter can be only be the following value: + * \arg ENABLE: Trigger resync signal. + * \arg DISABLE: Disable resync signal. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * SPI3WIRE_ResyncSignalCmd(ENABLE); + * } + * \endcode + */ +void SPI3WIRE_ResyncSignalCmd(FunctionalState NewState); + +/** + * \brief Get total number of data byte in each SPI reading. + * \param[in] None. + * \return The total number of data byte in each SPI reading. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * uint8_t data_len = 0; + * data_len = SPI3WIRE_GetRxDataLen(); + * } + * \endcode + */ +uint8_t SPI3WIRE_GetRxDataLen(void); + +/** + * \brief Clear read data number status. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * SPI3WIRE_ClearRxDataLen(); + * } + * \endcode + */ +void SPI3WIRE_ClearRxDataLen(void); + +/** + * \brief Clear all read data registers. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * SPI3WIRE_ClearRxFIFO(); + * } + * \endcode + */ +void SPI3WIRE_ClearRxFIFO(void); + +/** + * \brief Start to write data. + * \param[in] address: Write address. + * \param[in] data: Write data. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * uint8_t address = 0x10; + * uint8_t data = 0x10; + * SPI3WIRE_StartWrite(address, data); + * } + * \endcode + */ +void SPI3WIRE_StartWrite(uint8_t address, uint8_t data); + +/** + * \brief Start read. + * \param[in] address: Read address. + * \param[in] len: Number of data to read. This value can be 0x1 to 0xf. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * uint8_t address = 0x10; + * uint8_t len = 0x1; + * SPI3WIRE_StartRead(address, len); + * } + * \endcode + */ +void SPI3WIRE_StartRead(uint8_t address, uint32_t len); + +/** + * \brief Read data. + * \param[in] pBuf: Buffer to store read datas. + * \param[in] readNum: Read number. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * uint8_t data_buf[10] = {0}; + * uint8_t data_len = 10; + * SPI3WIRE_ReadBuf(data_buf, data_len); + * } + * \endcode + */ +void SPI3WIRE_ReadBuf(uint8_t *pBuf, uint8_t readNum); + +/** + * \brief Check whether the specified 3-wire SPI flag is set. + * \param[in] SPI3WIRE_FLAG: Specify flags to check. + * This parameter can be one of the following values: + * \arg SPI3WIRE_FLAG_BUSY: 3-wire SPI is busy. + * \arg SPI3WIRE_FLAG_INT_IND: There is 3-wire SPI interrupt. + * \arg SPI3WIRE_FLAG_RESYNC_BUSY: Resync busy or not. + * \return The new state of the specified 3-wire SPI flag. + * \retval SET: The specified 3-wire SPI flag state is pending. + * \retval RESET: The specified 3-wire SPI flag state is not pending. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * FlagStatus flag_status = RESET; + * flag_status = SPI3WIRE_GetFlagStatus(SPI3WIRE_FLAG_BUSY); + * } + * \endcode + */ +FlagStatus SPI3WIRE_GetFlagStatus(uint32_t SPI3WIRE_FLAG); + +/** + * \brief Clear the 3-wire SPI interrupt pending bit. + * \param[in] SPI3WIRE_INT: Specify the 3-wire SPI interrupt source to enable or disable. + * This parameter can only be the following values: + * \arg SPI3WIRE_INT_BIT: Enable 3-wire SPI interrupt source. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi3wire_demo(void) + * { + * SPI3WIRE_ClearINTPendingBit(SPI3WIRE_INT_BIT); + * } + * \endcode + */ + +void SPI3WIRE_ClearINTPendingBit(uint32_t SPI3WIRE_INT); + +/** \} */ /* End of group THREE_WIRE_SPI_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL8762_3WIRE_SPI_H_ */ + + +/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_adc.h b/inc/peripheral/rtl876x_adc.h new file mode 100644 index 0000000..5845016 --- /dev/null +++ b/inc/peripheral/rtl876x_adc.h @@ -0,0 +1,926 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_adc.h +* \brief The header file of the peripheral ADC driver. +* \details This file provides all ADC firmware functions. +* \author yuan +* \date 2020-05-28 +* \version v2.1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_ADC_H_ +#define _RTL876X_ADC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup ADC ADC + * + * \brief Manage the ADC peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" +#include "rtl876x_alias.h" +#include "platform_utils.h" +#include "adc_lib.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup ADC_Exported_Types Init Params Struct + * + * \ingroup ADC + */ + +/** + * \brief ADC init structure definition. + * + * \ingroup ADC_Exported_Types + */ +typedef struct +{ + uint32_t ADC_SampleTime; /**< Specifies the ADC sample clock, adc_sample_period = (n+1) cycles from 10MHz. + This parameter can be a value of 0 to 16383. */ + uint32_t ADC_ConvertTime; /**< Specifies the ADC Sample convert time. + This parameter can be a value of \ref ADC_Convert_Time*/ + uint32_t ADC_DataWriteToFifo; /**< Enable or disable writing ADC sampling data to FIFO in one shot mode. + This parameter can be a value of \ref ADC_Data_Write_To_Fifo*/ + uint32_t ADC_FifoThdLevel; /**< Specifies the ADC FIFO threshold to trigger \ref ADC_INT_FIFO_THD interrupt. + This parameter can be a value of 0 to 31. */ + uint32_t ADC_WaterLevel; /**< Specifies the ADC FIFO burst size to trigger GDMA. + This parameter can be a value of 0 to 31. */ + uint32_t ADC_FifoOverWriteEn; /**< Specifies if over write FIFO when FIFO overflow. + This parameter can be a value of \ref ADC_Over_Write_Enable. */ + uint32_t ADC_DataLatchEdge; /**< Specifies ADC data latch edge. + This parameter can be a value of \ref ADC_Latch_Data_Edge. */ + uint16_t ADC_SchIndex[16]; /**< Specifies ADC mode and channel for schedule table. + This parameter can be a value of \ref ADC_Schedule_Table. */ + uint16_t ADC_Bitmap; /**< Specifies the schedule table channel map. + This parameter can be a value of 16-bit map. */ + uint32_t ADC_DataAlign; /**< ADC data MSB or LSB aligned. */ + uint32_t ADC_DataMinusEn; /**< Enable or disable function that adc data latched minus the given offset before writes to reg/FIFO. */ + uint32_t ADC_DataMinusOffset; /**< Offset to be minused from adc data latched. */ + uint32_t ADC_DataAvgSel; /**< Number of data for calculate average. + This parameter can be a value of \ref ADC_Data_Avg_Num. */ + uint32_t ADC_DataAvgEn; /**< Enable the calculation for average result of the one-shot data. + This parameter can be a value of \ref ADC_Data_Avg_En. */ + uint32_t ADC_PowerOnMode; /**< Specifies ADC power on mode. + This parameter can be a value of \ref ADC_Power_On_Mode. */ + uint32_t ADC_PowerAlwaysOnEn; /**< Specifies the power always on. + This parameter can be a value of \ref ADC_Power_Always_On_Cmd. */ + uint32_t ADC_DataLatchDly; /**< Specifies delay of ck_ad to latch data.*/ + uint32_t ADC_RG2X0Dly; /**< Specifies the power on delay time selection of RG2X_AUXADC[0]. + This parameter can be a value of \ref ADC_RG2X_0_Delay_Time */ + uint32_t ADC_RG0X1Dly; /**< Specifies the power on delay time selection of RG0X_AUXADC[1]. + This parameter can be a value of \ref ADC_RG0X_1_Delay_Time */ + uint32_t ADC_RG0X0Dly; /**< Specifies the power on delay time selection of RG0X_AUXADC[0]. + This parameter can be a value of \ref ADC_RG0X_0_Delay_Time */ +} ADC_InitTypeDef; + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup ADC_Exported_Constants Macro Definitions + * \ingroup ADC + */ + +#define MAX_ADC_SCH_NUM 8 + +#define IS_ADC_PERIPH(PERIPH) ((PERIPH) == ADC) + +/** \defgroup ADC_Data_Write_To_Fifo Write DATA To FIFO + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_DATA_WRITE_TO_FIFO_DISABLE ((uint32_t)(0 << 27)) +#define ADC_DATA_WRITE_TO_FIFO_ENABLE ((uint32_t)(1 << 27)) +/** \} */ + +#define IS_ADC_DATA_WRITE_TO_FIFO_CMD(CMD) (((CMD) == ADC_DATA_WRITE_TO_FIFO_DISABLE) || ((CMD) == ADC_DATA_WRITE_TO_FIFO_ENABLE)) + +/** + * \def ADC_FIFO_Threshold ADC FIFO Threshold + */ +#define IS_ADC_FIFO_THRESHOLD(THD) ((THD) <= 0x3F) + +/** + * \def ADC_Burst_Size ADC Burst Size + */ +#define IS_ADC_WATER_LEVEL_CONFIG(CONFIG) ((CONFIG) <= 0x3F) + +/** + * \defgroup ADC_Over_Write_Enable ADC FIFO Over Write + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_FIFO_OVER_WRITE_DISABLE ((uint32_t)(0 << 13)) +#define ADC_FIFO_OVER_WRITE_ENABLE ((uint32_t)(1 << 13)) +/** \} */ + +#define IS_ADC_OVERWRITE_MODE(MODE) (((MODE) == ADC_FIFO_OVER_WRITE_DISABLE) || ((MODE) == ADC_FIFO_OVER_WRITE_ENABLE)) + +/** + * \defgroup ADC_Latch_Data_Edge ADC Latch Data Edge + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_LATCH_DATA_Positive ((uint32_t)(0 << 2)) +#define ADC_LATCH_DATA_Negative ((uint32_t)(1 << 2)) +/** \} */ + +#define IS_ADC_LATCH_DATA_EDGE(EDGE) (((EDGE) == ADC_LATCH_DATA_Positive) || ((EDGE) == ADC_LATCH_DATA_Negative)) + +/** + * \defgroup ADC_Operation_Mode ADC Operation Mode + * \{ + * \ingroup ADC_Exported_Constants + */ + +#define ADC_CONTINUOUS_MODE ((uint32_t)(1 << 0)) +#define ADC_ONE_SHOT_MODE ((uint32_t)(1 << 1)) +/** \} */ + +#define IS_ADC_SAMPLE_MODE(MODE) (((MODE) == ADC_CONTINUOUS_MODE) || ((MODE) == ADC_ONE_SHOT_MODE)) + +/** + * \defgroup ADC_Interrupts_Definition ADC Interrupts Definition + * \{ + * \ingroup ADC_Exported_Constants + */ + +#define ADC_INT_FIFO_RD_REQ ((uint32_t)(1 << 0)) +#define ADC_INT_FIFO_RD_ERR ((uint32_t)(1 << 1)) +#define ADC_INT_FIFO_THD ((uint32_t)(1 << 2)) +#define ADC_INT_FIFO_OVERFLOW ((uint32_t)(1 << 3)) +#define ADC_INT_ONE_SHOT_DONE ((uint32_t)(1 << 4)) +/** \} */ + +//#define IS_ADC_INT(INT) ((((INT) & 0xFFFFFFE0) == 0x00) && ((INT) != 0x00)) + +#define IS_ADC_INT(INT) (((INT) == ADC_INT_FIFO_RD_REQ) || ((INT) == ADC_INT_FIFO_RD_ERR)\ + || ((INT) == ADC_INT_FIFO_THD) || ((INT) == ADC_INT_FIFO_OVERFLOW)\ + || ((INT) == ADC_INT_ONE_SHOT_DONE)) + +/** + * \defgroup ADC_Schedule_Table ADC Channel and Mode + * \{ + * \ingroup ADC_Exported_Constants + */ +#define EXT_SINGLE_ENDED(index) ((uint16_t)((0x00 << 3) | (index))) +#define EXT_DIFFERENTIAL(index) ((uint16_t)((0x01 << 3) | (index))) +#define INTERNAL_VBAT_MODE ((uint16_t)((0x02 << 3) | 0x00)) +#define EXT_CTC(index) ((uint16_t)((0x03 << 3) | (index))) +/** \} */ + +#define SCHEDULE_TABLE(index) (index) +#define IS_ADC_SCHEDULE_INDEX_CONFIG(CONFIG) ((((CONFIG) & 0xFFE0) == 0) && ((((~(CONFIG)) & (0x18)) != 0)\ + || ((CONFIG) == INTERNAL_VBAT_MODE))) + +/** + * \defgroup ADC_Data_Avg_Num ADC Data Averge Num + * \{ + * \brief Number of raw data for calculate average. + * \ingroup ADC_Exported_Constants + */ + +#define ADC_DATA_AVERAGE_OF_2 ((uint32_t)(0 << 25)) +#define ADC_DATA_AVERAGE_OF_4 ((uint32_t)(1 << 25)) +#define ADC_DATA_AVERAGE_OF_8 ((uint32_t)(2 << 25)) +#define ADC_DATA_AVERAGE_OF_16 ((uint32_t)(3 << 25)) +#define ADC_DATA_AVERAGE_OF_32 ((uint32_t)(4 << 25)) +#define ADC_DATA_AVERAGE_OF_64 ((uint32_t)(5 << 25)) +#define ADC_DATA_AVERAGE_OF_128 ((uint32_t)(6 << 25)) +#define ADC_DATA_AVERAGE_OF_256 ((uint32_t)(7 << 25)) +/** \} */ + +#define IS_ADC_DATA_AVG_NUM(NUM) (((NUM) == ADC_DATA_AVERAGE_OF_2) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_4) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_8) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_16) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_32) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_64) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_128) ||\ + ((NUM) == ADC_DATA_AVERAGE_OF_256)) + +/** + * \defgroup ADC_Data_Avg_En ADC Data Average Enable + * \brief Enable the calculation for average result of the one-shot mode. + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_DATA_AVERAGE_DISABLE ((uint32_t)(0 << 24)) +#define ADC_DATA_AVERAGE_ENABLE ((uint32_t)(1 << 24)) +/** \} */ + +#define IS_ADC_DATA_AVG_EN(CMD) (((CMD) == ADC_DATA_AVERAGE_DISABLE) || ((CMD) == ADC_DATA_AVERAGE_ENABLE)) + +/** + * \defgroup ADC_Power_On_Mode ADC Power On Mode + * \{ + * \ingroup ADC_Exported_Constants + */ + +#define ADC_POWER_ON_AUTO ((uint32_t)(0 << 19)) +#define ADC_POWER_ON_MANUAL ((uint32_t)(1 << 19)) +/** \} */ + +#define IS_ADC_POWER_ON_MODE(MODE) (((MODE) == ADC_POWER_ON_AUTO) || ((MODE) == ADC_POWER_ON_MANUAL)) + +/** + * \brief ADC set power on procedure. + */ +#define IS_ADC_POWER_ON_PROCEDURE(CONFIG) (((CONFIG) == ADC_POWERON_VBAT) || ((CONFIG) == ADC_POWERON_VA11)\ + || ((CONFIG) == ADC_POWERON_RG1X_AUXADC_12) || ((CONFIG) == ADC_POWERON_RG2X_AUXADC_3))\ +|| ((CONFIG) == ADC_POWERON_ERC_VA11) || ((CONFIG) == ADC_POWERON_RG2X_AUXADC_0))\ +|| ((CONFIG) == ADC_POWERON_VA18) || ((CONFIG) == ADC_POWERON_RG0X_AUXADC_1))\ +|| ((CONFIG) == ADC_POWERON_RG0X_AUXADC_0))) + +/** + * \defgroup ADC_RG2X_0_Delay_Time ADC RG2X_0 Delay Time + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_RG2X_0_DELAY_10_US ((uint32_t)(0 << 4)) +#define ADC_RG2X_0_DELAY_20_US ((uint32_t)(1 << 4)) +#define ADC_RG2X_0_DELAY_40_US ((uint32_t)(2 << 4)) +#define ADC_RG2X_0_DELAY_80_US ((uint32_t)(3 << 4)) +/** \} */ + +#define IS_ADC_RG2X_0_DELAY_TIME(TIME) (((TIME) == ADC_RG2X_0_DELAY_10_US) || ((TIME) == ADC_RG2X_0_DELAY_20_US)\ + || ((TIME) == ADC_RG2X_0_DELAY_40_US) || ((TIME) == ADC_RG2X_0_DELAY_80_US)) + +/** + * \defgroup ADC_RG0X_1_Delay_Time ADC RG0X_1 Delay Time + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_RG0X_1_DELAY_20_US ((uint32_t)(0 << 2)) +#define ADC_RG0X_1_DELAY_40_US ((uint32_t)(1 << 2)) +#define ADC_RG0X_1_DELAY_80_US ((uint32_t)(2 << 2)) +#define ADC_RG0X_1_DELAY_160_US ((uint32_t)(3 << 2)) +/** \} */ + +#define IS_ADC_RG0X_1_DELAY_TIME(TIME) (((TIME) == ADC_RG0X_1_DELAY_20_US) || ((TIME) == ADC_RG0X_1_DELAY_40_US)\ + || ((TIME) == ADC_RG0X_1_DELAY_80_US) || ((TIME) == ADC_RG0X_1_DELAY_160_US)) + +/** + * \defgroup ADC_RG0X_0_Delay_Time ADC RG0X_0 Delay Time + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_RG0X_0_DELAY_30_US ((uint32_t)(0 << 0)) +#define ADC_RG0X_0_DELAY_60_US ((uint32_t)(1 << 0)) +#define ADC_RG0X_0_DELAY_120_US ((uint32_t)(2 << 0)) +#define ADC_RG0X_0_DELAY_240_US ((uint32_t)(3 << 0)) +/** \} */ + +#define IS_ADC_RG0X_0_DELAY_TIME(TIME) (((TIME) == ADC_RG0X_0_DELAY_30_US) || ((TIME) == ADC_RG0X_0_DELAY_60_US)\ + || ((TIME) == ADC_RG0X_0_DELAY_120_US) || ((TIME) == ADC_RG0X_0_DELAY_240_US)) + +/** + * \defgroup ADC_Data_Minus_En ADC Data Minus Enable + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_DATA_MINUS_DISABLE (uint32_t)(0 << 31) +#define ADC_DATA_MINUS_ENABLE (uint32_t)(1 << 31) +/** \} */ + +#define IS_ADC_DATA_MINUS_CMD(CMD) (((CMD) == ADC_DATA_MINUS_DISABLE) || ((CMD) == ADC_DATA_MINUS_ENABLE)) + +/** + * \defgroup ADC_Data_Align ADC Data Align + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_DATA_ALIGN_LSB (uint32_t)(0 << 30) +#define ADC_DATA_ALIGN_MSB (uint32_t)(1 << 30) +/** \} */ + +#define IS_ADC_DATA_ALIGN(DATA_ALIGN) (((DATA_ALIGN) == ADC_DATA_ALIGN_LSB) || ((DATA_ALIGN) == ADC_DATA_ALIGN_MSB)) + +/** + * \defgroup ADC_Timer_Trigger_En ADC Timer Trigger En + * \brief ADC trigger one-shot mode with timer7. + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_TIMER_TRIGGER_DISABLE ((uint32_t)(0 << 29)) +#define ADC_TIMER_TRIGGER_ENABLE ((uint32_t)(1 << 29)) +/** \} */ + +#define IS_ADC_TIMER_TRIGGER_CMD(CMD) (((CMD) == ADC_TIMER_TRIGGER_DISABLE) || ((CMD) == ADC_TIMER_TRIGGER_ENABLE)) + +/** + * \defgroup ADC_Power_Always_On_Cmd ADC Power Always On Cmd + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_POWER_ALWAYS_ON_DISABLE ((uint32_t)(0 << 15)) +#define ADC_POWER_ALWAYS_ON_ENABLE ((uint32_t)(1 << 15)) +/** \} */ + +#define IS_ADC_POWER_ALWAYS_ON(CMD) (((CMD) == ADC_POWER_ALWAYS_ON_DISABLE) || ((CMD) == ADC_POWER_ALWAYS_ON_ENABLE)) + +/** + * \defgroup ADC_Convert_Time ADC Convert Time + * \{ + * \ingroup ADC_Exported_Constants + */ +#define ADC_CONVERT_TIME_500NS ((uint32_t)(0 << 30)) +/** \} */ + +#define IS_ADC_CONVERT_TIME(TIME) ((TIME) == ADC_CONVERT_TIME_500NS) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * rtl876x_adc.h + * + * \brief Deinitializes the ADC peripheral registers to their + * default reset values(turn off ADC clock). + * \details + * \param[in] ADCx: Specify ADC peripheral, can only be ADC. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_adc_init(void) + * { + * //Turn off the clock. + * ADC_DeInit(ADC); + * } + * \endcode + */ +void ADC_DeInit(ADC_TypeDef *ADCx); + +/** + * rtl876x_adc.h + * \brief Initializes the ADC peripheral according to the specified + * parameters in the ADC_InitStruct + * \param[in] ADCx: selected ADC peripheral. + * \param[in] ADC_InitStruct: pointer to a ADC_InitTypeDef structure that + * contains the configuration information for the specified ADC peripheral + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_adc_init(void) + * { + * //Turn on the clock. + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1); + * ADC_InitStruct.ADC_Bitmap = 0x03; + * //Add other initialization parameters that need to be configured here. + * ADC_Init(ADC, &ADC_InitStruct); + * } + * \endcode + */ +void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct); + +/** + * rtl876x_adc.h + * \brief Fills each ADC_InitStruct member with its default value. + * \param[in] ADC_InitStruct: Pointer to an ADC_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_adc_init(void) + * { + * //Turn on the clock. + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1); + * ADC_InitStruct.ADC_Bitmap = 0x03; + * //Add other initialization parameters that need to be configured here. + * ADC_Init(ADC, &ADC_InitStruct); + * } + * \endcode + * \callgraph + * + */ +void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct); + +/** + * rtl876x_adc.h + * \brief Enables or disables the ADC peripheral. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] adcMode: ADC operation mode selection. + This parameter can be one of the following values: + * \arg ADC_ONE_SHOT_MODE: One shot mode. + * \arg ADC_CONTINUOUS_MODE: Continuous sampling mode. + * \param[in] NewState: New state of the ADC peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_adc_init(void) + * { + * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * + * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * } + * + * void driver_adc_init(void) + * { + * //open clock + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + * + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1); + * ADC_InitStruct.ADC_Bitmap = 0x03; + * //Add other initialization parameters here. + * ADC_Init(ADC, &ADC_InitStruct); + * + * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + * } + * + * void adc_demo(void) + * { + * board_adc_init(); + * driver_adc_init(); + * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE); + * } + * \endcode + */ +void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Enables or disables the specified ADC interrupts. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] ADC_IT: Specify the ADC interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg ADC_INT_FIFO_RD_REQ : FIFO read request. + * \arg ADC_INT_FIFO_RD_ERR : FIFO read error. + * \arg ADC_INT_FIFO_THD : ADC FIFO size > thd. + * \arg ADC_INT_FIFO_OVERFLOW : ADC FIFO overflow. + * \arg ADC_INT_ONE_SHOT_DONE : ADC one shot mode done. + * \param[in] newState: New state of the specified ADC interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_adc_init(void) + * { + * //open clock + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + * + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1); + * ADC_InitStruct.ADC_Bitmap = 0x03; + * //Add other initialization parameters here. + * ADC_Init(ADC, &ADC_InitStruct); + * + * ADC_INTConfig(ADC, ADC_INT_FIFO_RD_ERR, ENABLE); + * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + * } + * \endcode + * + */ +void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Read ADC data according to specific channel. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] index: Can be 0 to 15. + * \return The 12-bit converted ADC raw data. + * + * Example usage + * \code{.c} + * + * void board_adc_init(void) + * { + * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * + * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * } + * + * void driver_adc_init(void) + * { + * //open clock + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + * + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_SchIndex[1] = EXT_SINGLE_ENDED(1); + * ADC_InitStruct.ADC_Bitmap = 0x03; + * //Add other initialization parameters here. + * ADC_Init(ADC, &ADC_InitStruct); + * + * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + * } + * + * void adc_demo(void) + * { + * board_adc_init(); + * driver_adc_init(); + * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE); + * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET); + * uint16_t raw_data_0 = ADC_ReadRawData(ADC, 0); + * uint16_t raw_data_1 = ADC_ReadRawData(ADC, 1); + * } + * \endcode + */ +uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index); + +/** + * rtl876x_adc.h + * \brief Get ADC average data from ADC schedule table0. + * \param[in] ADCx: Specify ADC peripheral. + * \param[out] OutBuf: Buffer to save data read from ADC FIFO. + * \return The 12-bit converted ADC raw data. + * \callgraph + * + * Example usage + * \code{.c} + * + * void board_adc_init(void) + * { + * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * } + * + * void driver_adc_init(void) + * { + * //open clock + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + * + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_Bitmap = 0x01; + * ADC_InitStruct.ADC_DataAvgEn = ADC_DATA_AVERAGE_ENABLE; + * ADC_InitStruct.ADC_DataAvgSel = ADC_DATA_AVERAGE_OF_2; + * //Add other initialization parameters here. + * ADC_Init(ADC, &ADC_InitStruct); + * + * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + * } + * + * void adc_demo(void) + * { + * board_adc_init(); + * driver_adc_init(); + * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE); + * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET); + * uint16_t raw_data = 0; + * raw_data = ADC_ReadAvgRawData(ADC); + * } + * \endcode + * + */ +uint16_t ADC_ReadAvgRawData(ADC_TypeDef *ADCx); + +/** + * rtl876x_adc.h + * \brief Read one byte data from ADC FIFO. + * \param[in] ADCx: selected ADC peripheral. + * \return adc FIFO data. + * + * Example usage + * \code{.c} + * + * void board_adc_init(void) + * { + * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_LOW); + * } + * + * void driver_adc_init(void) + * { + * //open clock + * RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + * + * ADC_InitTypeDef ADC_InitStruct; + * ADC_StructInit(&ADC_InitStruct); + * ADC_InitStruct.ADC_SchIndex[0] = EXT_SINGLE_ENDED(0); + * ADC_InitStruct.ADC_Bitmap = 0x01; + * ADC_InitStruct.ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE; + * ADC_Init(ADC, &ADC_InitStruct); + * + * ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + * } + * + * void adc_demo(void) + * { + * board_adc_init(); + * driver_adc_init(); + * ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE); + * while(ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET); + * uint16_t raw_data = 0; + * raw_data = ADC_ReadFIFO(ADC); + * } + * \endcode + */ +uint16_t ADC_ReadFIFO(ADC_TypeDef *ADCx); + +/** + * rtl876x_adc.h + * \brief Get data from ADC FIFO. + * \param[in] ADCx: Specify ADC peripheral. + * \param[out] outBuf: Buffer to save data read from ADC FIFO. + * \param[in] num: Number of data to be read. + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * //ADC already start + * uint16_t raw_data[32] = {0}; + * uint8_t data_len = ADC_GetFIFODataLen(ADC); + * ADC_ReadFIFOData(ADC,raw_data,data_len); + * } + * \endcode + * + */ +void ADC_ReadFIFOData(ADC_TypeDef *ADCx, uint16_t *outBuf, uint16_t num); + +/** + * rtl876x_adc.h + * \brief Get ADC fifo data number. + * \param[in] ADCx: selected ADC peripheral. + * \return Current data number in ADC FIFO. + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * //ADC already start + * uint16_t raw_data[32] = {0}; + * uint8_t data_len = ADC_GetFIFODataLen(ADC); + * ADC_ReadFIFOData(ADC,raw_data,data_len); + * } + * \endcode + * + */ +uint8_t ADC_GetFIFODataLen(ADC_TypeDef *ADCx); + +/** + * rtl876x_adc.h + * \brief Config ADC schedule table. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] adcMode: ADC operation mode. + * This parameter can be one of the following values: + * \arg EXT_SINGLE_ENDED(index) + * \arg EXT_DIFFERENTIAL(index) + * \arg INTERNAL_VBAT_MODE + * \param[in] Index: Schedule table index. + * \return None. + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_SchIndexConfig(ADC,INTERNAL_VBAT_MODE,0); + * } + * \endcode + * + */ +void ADC_SchIndexConfig(ADC_TypeDef *ADCx, uint8_t adcMode, uint16_t Index); + +/** + * \brief Same as function ADC_SchIndexConfig, this function is version bee2. + */ +void ADC_SchTableConfig(ADC_TypeDef *ADCx, uint16_t Index, uint8_t adcMode); + +/** + * rtl876x_adc.h + * \brief Config adc schedule table. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] channelMap: ADC channel map. + * \param[in] NewState: New state of the ADC peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * uint16_t bit_map = 0x03; + * ADC_BitMapConfig(ADC,bit_map,ENABLE); + * } + * \endcode + */ +void ADC_BitMapConfig(ADC_TypeDef *ADCx, uint16_t bitMap, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Power on ADC manually. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] NewState: New state of the ADC power on. + * This parameter can be: ENABLE or DISABLE. If enabled, ADC power will always be on until disabled. + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_ManualPowerOnCmd(ADC,ENABLE); + * } + * \endcode + */ +void ADC_ManualPowerOnCmd(ADC_TypeDef *ADCx, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Enbale or disable stop FIFO from writing data. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] NewState: New state of the ADC FIFO write. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_WriteFIFOCmd(ADC, ENABLE); + * } + * \endcode + */ +void ADC_WriteFIFOCmd(ADC_TypeDef *ADCx, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Config ADC bypass resistor. + * \param[in] channelNum: External channel number, can be 0~7. + * \param[in] NewState: Specifies whether the channel enables bypass mode. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * \note The input voltage of channel pin using bypass mode cannot exceed 0.9V! + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_BypassCmd(0,ENABLE); + * } + * \endcode + */ +void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState); + +/** + * rtl876x_adc.h + * \brief Check whether the specified ADC interrupt flag is set. + * \param[in] ADCx: selected ADC peripheral. + * \param[in] ADC_INT_FLAG: Specifies the interrupt flag to check. + * This parameter can be one of the following values: + * \arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt. + * \arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt. + * \arg ADC_INT_FIFO_THD: FIFO larger than threshold interrupt. + * \arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt. + * \arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt. + * + * \return The new state of ADC_INT (SET or RESET). + * \retval SET. + * \retval RESET. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ITStatus int_status = RESET; + * int_status = ADC_GetINTStatus(ADC,ADC_INT_FIFO_OVERFLOW); + * } + * \endcode + */ +ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT); + +/** + * rtl876x_adc.h + * \brief Clear the ADC interrupt pending bit. + * \param[in] ADCx: Specify ADC peripheral. + * \param[in] ADC_INT: Specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * \arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt. + * \arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt. + * \arg ADC_INT_FIFO_THD: FIFO larger than threshold interrupt. + * \arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt. + * \arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt. + * + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_ClearINTPendingBit(ADC,ADC_INT_FIFO_OVERFLOW); + * } + * \endcode + */ +void ADC_ClearINTPendingBit(ADC_TypeDef *ADCx, uint32_t ADC_INT); + +/** + * rtl876x_adc.h + * \brief Clear ADC FIFO. + * \param[in] ADCx: Specify ADC peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * ADC_ClearFIFO(ADC); + * } + * \endcode + */ +__STATIC_INLINE void ADC_ClearFIFO(ADC_TypeDef *ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + ADCx->CR |= BIT26; +} + +/** + * rtl876x_adc.h + * \brief Get all adc interrupt flag status. + * \param[in] ADCx: Specify ADC peripheral. + * \return All ADC interrupt status. + * + * Example usage + * \code{.c} + * + * void adc_demo(void) + * { + * uint8_t all_flag_status = 0; + * all_flag_status = ADC_GetAllFlagStatus(ADC); + * } + * \endcode + * + */ +__STATIC_INLINE uint8_t ADC_GetAllFlagStatus(ADC_TypeDef *ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + return ((uint8_t)(((ADCx->INTCR) & (0x1f << 16)) >> 16)); +} + +/** \} */ /* End of Group ADC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_ADC_H_ */ + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/ + + + diff --git a/inc/peripheral/rtl876x_alias.h b/inc/peripheral/rtl876x_alias.h new file mode 100644 index 0000000..18ab33b --- /dev/null +++ b/inc/peripheral/rtl876x_alias.h @@ -0,0 +1,145 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_alias.h +* \brief The header file of all peripherals internal alias. +* \details To be compatible with the previous driver,create an alias file for the previous driver. +* \author yuan +* \date 2020-06-19 +* \version v2.1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_ALIAS_H_ +#define _RTL876X_ALIAS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \cond private + * \brief To be compatible with the previous driver. + * \defgroup ADC_InitTypeDef_Alias ADC Init TypeDef Alias + * \{ + */ +#define ADC_One_Shot_Mode ADC_ONE_SHOT_MODE +#define schIndex ADC_SchIndex +#define bitmap ADC_Bitmap +#define adcSamplePeriod ADC_SampleTime +#define PowerAlwaysOnEn ADC_PowerAlwaysOnEn +#define dataWriteToFifo ADC_DataWriteToFifo +#define timerTriggerEn ADC_TimerTriggerEn + +/** + * \} + * \endcond + */ + +/** + * \cond private + * \brief To be compatible with the previous driver. + * \defgroup ADC_API_Alias ADC API Alias + * \{ + */ +#define ADC_ReadByScheduleIndex ADC_ReadRawData +#define ADC_ReadFifoData ADC_ReadFIFO +#define ADC_GetFifoData ADC_ReadFIFOData +#define ADC_GetFifoLen ADC_GetFIFODataLen +#define ADC_SchTableSet ADC_BitMapConfig +#define ADC_PowerAlwaysOnCmd ADC_ManualPowerOnCmd +#define ADC_FifoWriteCmd ADC_WriteFIFOCmd +#define ADC_AnalogCircuitConfig ADC_PowerSupplyConfig +#define ADC_GetIntFlagStatus ADC_GetINTStatus +#define ADC_ClearFifo ADC_ClearFIFO +#define ADC_GetIntStatus ADC_GetAllFlagStatus + +/** + * \} + * \endcond + */ + +/** + * \cond private + * \brief To be compatible with the previous driver. + * \defgroup RTC_API_Alias RTC API Alias + * \{ + */ +#define RTC_SetComp RTC_SetCompValue +#define RTC_RunCmd RTC_Cmd +#define RTC_INT_CMP1 RTC_INT_COMP1 + +/** + * \} + * \endcond + */ + +/** + * \cond private + * \brief To be compatible with the previous driver. + * \defgroup UART_InitTypeDef_Alias UART Init TypeDef Alias + * \{ + */ +#define ovsr_adj UART_OvsrAdj +#define div UART_Div +#define ovsr UART_Ovsr +#define wordLen UART_WordLen +#define parity UART_Parity +#define stopBits UART_StopBits +#define autoFlowCtrl UART_HardwareFlowControl +#define txTriggerLevel UART_TxThdLevel +#define rxTriggerLevel UART_RxThdLevel +#define dmaEn UART_DmaEn +#define idle_time UART_IdleTime +#define TxWaterlevel UART_TxWaterLevel +#define RxWaterlevel UART_RxWaterLevel +#define TxDmaEn UART_TxDmaEn +#define RxDmaEn UART_RxDmaEn + +#define UART_INT_LINE_STS UART_INT_RX_LINE_STS +#define UART_INT_ID_RX_TMEOUT UART_INT_ID_RX_DATA_TIMEOUT +#define UART_FLAG_THR_EMPTY UART_FLAG_TX_FIFO_EMPTY +#define UART_FLAG_THR_TSR_EMPTY UART_FLAG_TX_EMPTY +#define UART_FLAG_RX_DATA_RDY UART_FLAG_RX_DATA_AVA + +/** + * \} + * \endcond + */ + +/** + * \cond private + * \brief To be compatible with the previous driver. + * \defgroup UART_API_Alias UART API Alias + * \{ + */ +#define UART_GetFlagState UART_GetFlagStatus +#define UART_ChangeBaudRate UART_SetBaudRate +#define UART_ChangeParams UART_SetParams +#define UART_ClearTxFifo UART_ClearTxFIFO +#define UART_ClearRxFifo UART_ClearRxFIFO +#define UART_GetTxFIFOLen UART_GetTxFIFODataLen +#define UART_GetRxFIFOLen UART_GetRxFIFODataLen + +/** + * \} + * \endcond + */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_ALIAS_H_ */ + + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/ + + + diff --git a/inc/peripheral/rtl876x_aon_wdg.h b/inc/peripheral/rtl876x_aon_wdg.h new file mode 100644 index 0000000..1a94114 --- /dev/null +++ b/inc/peripheral/rtl876x_aon_wdg.h @@ -0,0 +1,146 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file rtl876x_aon_wdg.h +* @brief header file of aon watch dog driver. +* @details +* @author Serval Li +* @date 2017-06-27 +* @version v0.1 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_AON_WDG_H_ +#define _RTL876X_AON_WDG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup IO Peripheral Drivers + * + * @defgroup AON_WATCH_DOG AON_WATCH_DOG + * @brief AON Watch Dog driver module + * \ingroup IO + * @{ + */ + +/** @defgroup AON_WATCH_DOG_Exported_Types Watch Dog Exported Types + * @{ + */ +typedef enum +{ + AON_WDT_RESET_ALL_EXCEPT_AON = 0, + AON_WDT_RESET_ALL = 1 +} T_AON_WDG_MODE; + +/** @defgroup AON_WATCH_DOG_Exported_Functions AON Watch Dog Exported Functions + * @{ + */ + +/** + * @brief AON Watchdog Config. + * @param reset_level: 0, Reset whole chip except partial AON and RTC. 1, Reset whole chip. + * @param comp: Set period in ms. + * @param cnt_ctl: 0, Stop count in low power mode; 1, Continue count in low power mode. + * @param cnt_reload: 0, Not reload counter when exit low power mode + 1, Reload counter when exit low power mode. + * @retval none. + */ +void AON_WDG_Config(T_AON_WDG_MODE reset_level, uint32_t comp, uint8_t cnt_ctl, uint8_t cnt_reload); + +/** + * @brief Config Reset Level. + * @param reset_level: 0, Reset whole chip except partial AON and RTC. 1, Reset whole chip. + * @retval none. + */ +void AON_WDG_ConfigResetLevel(uint8_t reset_level); + +/** + * @brief Config Period. + * @param comp: Set period in ms. + * @retval none. + */ +void AON_WDG_ConfigComp(uint32_t comp); + +/** + * @brief Config wheather continue count in low power mode or not. + * @param cnt_ctl: 0, Stop count in low power mode; 1, Continue count in low power mode. + * @retval none. + */ +void AON_WDG_ConfigCntCtl(uint8_t cnt_ctl); + +/** + * @brief Config wheather reload counter when exit low power mode or not. + * @param cnt_reload: 0, Not reload counter when exit low power mode + 1, Reload counter when exit low power mode. + * @retval none. + */ +void AON_WDG_ConfigCntReload(uint8_t cnt_reload); + +/** + * @brief AON Watch Dog Timer Enable. + */ +void AON_WDG_Enable(void); + +/** + * @brief AON Watch Dog Timer Disable. + */ +void AON_WDG_Disable(void); + +/** + * @brief AON Watch Dog Timer Restart. + */ +void AON_WDG_Restart(void); + +/** + * @brief AON Watch Dog System Reset. + */ +void AON_WDG_SystemReset(void); + +/** + * @brief AON Watch Dog init. + * reset_level: 0, Reset whole chip except partial AON and RTC. 1, Reset whole chip. + * timeout_second: timeout period in seconds, max value is 262s + * Note: Power down mode, aon wdg clock source may varify from 450Hz to 2.3KHz + */ +static inline void aon_wdg_init(T_AON_WDG_MODE reset_level, uint8_t timeout_second) +{ + uint32_t comp = (timeout_second * 1000) & 0x3FFFF; //only 18 bit + AON_WDG_Config(reset_level, comp, 1, 1); +} + +/** + * @brief AON Watch Dog enable. + */ +static inline void aon_wdg_enable(void) +{ + AON_WDG_Enable(); +} + +/** + * @brief AON Watch Dog counter is clear and disable. + */ +static inline void aon_wdg_disable(void) +{ + AON_WDG_Restart(); + AON_WDG_Disable(); +} + +/** + * @brief Is AON Watch Dog enable. + */ +bool AON_WDG_IsEnable(void); + + +/** @} */ /* End of group AON_WATCH_DOG_Exported_Functions */ +/** @} */ /* End of group AON_WATCH_DOG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_AON_WDG_H_ */ diff --git a/inc/peripheral/rtl876x_bitfields.h b/inc/peripheral/rtl876x_bitfields.h new file mode 100644 index 0000000..9c4fd84 --- /dev/null +++ b/inc/peripheral/rtl876x_bitfields.h @@ -0,0 +1,523 @@ +/* Copyright (c) 2015 Realtek Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Realtek Semiconductor. + * Terms and conditions of usage are described in detail in Realtek + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + */ +#ifndef __RTL876X_BITS_H +#define __RTL876X_BITS_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#include + +/* Peripheral: KEYSCAN */ +/* Description: Key Scan. */ + + +/* Register: RTL_KEYSCAN_CR0 */ +/* Description: Control register 0. */ + +/* Bit 31 : Keyscan clock enable */ +#define KEYSCAN_CR0_CLKEN_Pos (31UL) /*!< Position of clock enable field. */ +#define KEYSCAN_CR0_CLKEN_Msk (0x1UL << KEYSCAN_CR0_CLKEN_Pos) /*!< Bit mask of clock enable field. */ +#define KEYSCAN_CR0_CLKEN_Disabled (0UL) /*!< Clock disabled. */ +#define KEYSCAN_CR0_CLKEN_Enabled (1UL) /*!< Clock enabled. */ + +/* Bit 8 : Column selection */ +#define KEYSCAN_CR0_COLSEL_Pos (8UL) /*!< Position of column selection field. */ +#define KEYSCAN_CR0_COLSEL_Msk (0xFFFFFUL << KEYSCAN_CR0_COLSEL_Pos) /*!< Bit mask of column selection field. */ + +/* Bit 5 : Row number */ +#define KEYSCAN_CR0_ROWNUM_Pos (5UL) /*!< Position of row number field. */ +#define KEYSCAN_CR0_ROWNUM_Msk (0x07UL << KEYSCAN_CR0_ROWNUM_Pos) /*!< Bit mask of row number field. */ + + +/* Bit 0 : Column number */ +#define KEYSCAN_CR0_COLNUM_Pos (0UL) /*!< Position of column number field. */ +#define KEYSCAN_CR0_COLNUM_Msk (0x1FUL << KEYSCAN_CR0_COLNUM_Pos) /*!< Bit mask of column number field. */ + +/* Register: RTL_KEYSCAN_CR1 */ +/* Description: Control register 1. */ + +/* Bit 27 : Post guard time for column*/ +#define KEYSCAN_CR1_POSTGUARD_Pos (27UL) /*!< Position of post guard time field. */ +#define KEYSCAN_CR1_POSTGUARD_Msk (0x07UL << KEYSCAN_CR1_POSTGUARD_Pos) /*!< Bit mask of post guard time field. */ + +/* Bit 24 : Pre guard time for column */ +#define KEYSCAN_CR1_PREGUARD_Pos (24UL) /*!< Position pre guard time field. */ +#define KEYSCAN_CR1_PREGUARD_Msk (0x07UL << KEYSCAN_CR1_PREGUARD_Pos) /*!< Bit mask of pre guard time field. */ + +/* Bit 16 : Row selection */ +#define KEYSCAN_CR1_ROWSEL_Pos (16UL) /*!< Position of row selection field. */ +#define KEYSCAN_CR1_ROWSEL_Msk (0xFFUL << KEYSCAN_CR1_ROWSEL_Pos) /*!< Bit mask of row selection field. */ + +/* Bit 8 : Detection period */ +#define KEYSCAN_CR1_DETECTPERIOD_Pos (8UL) /*!< Position of detection period field. */ +#define KEYSCAN_CR1_DETECTPERIOD_Msk (0x07UL << KEYSCAN_CR1_DETECTPERIOD_Pos) /*!< Bit mask of detection period field. */ +#define KEYSCAN_CR1_DETECTPERIOD_Disabled (0UL) /*!< Detection disabled. */ +#define KEYSCAN_CR1_DETECTPERIOD_Enabled (1UL) /*!< Detection enabled. */ + +/* Bit 7 : Debouncing enable */ +#define KEYSCAN_CR1_DEBOUNCEN_Pos (7UL) /*!< Position of debouncing enable field. */ +#define KEYSCAN_CR1_DEBOUNCEN_Msk (0x01UL << KEYSCAN_CR1_DEBOUNCEN_Pos) /*!< Bit mask of debouncing enable field. */ +#define KEYSCAN_CR1_DEBOUNCEN_Disabled (0UL) /*!< Debouncing disabled. */ +#define KEYSCAN_CR1_DEBOUNCEN_Enabled (1UL) /*!< Debouncing enabled. */ + +/* Bit 2 : Timeout period */ +#define KEYSCAN_CR1_TOPERIOD_Pos (2UL) /*!< Position of timeout period field. */ +#define KEYSCAN_CR1_TOPERIOD_Msk (0x03UL << KEYSCAN_CR1_TOPERIOD_Pos) /*!< Bit mask of timeout period field. */ + +/* Bit 0 : Wait period */ +#define KEYSCAN_CR1_WAITPERIOD_Pos (0UL) /*!< Position of wait period field. */ +#define KEYSCAN_CR1_WAITPERIOD_Msk (0x03UL << KEYSCAN_CR1_WAITPERIOD_Pos) /*!< Bit mask of wait period field. */ + + +/* Register: RTL_KEYSCAN_CR2 */ +/* Description: Control register 2. */ + +/* Bit 27 : Program debouncing time enable */ +#define KEYSCAN_CR2_DEBEN_Pos (27UL) /*!< Position of program debouncing time enable field. */ +#define KEYSCAN_CR2_DEBEN_Msk (0x1UL << KEYSCAN_CR2_DEBEN_Pos) /*!< Bit mask of program debouncing time enable field. */ +#define KEYSCAN_CR2_DEBEN_Disabled (0UL) /*!< Clock disabled. */ +#define KEYSCAN_CR2_DEBEN_Enabled (1UL) /*!< Clock enabled. */ + +/* Bit 16 : Debouncing time*/ +#define KEYSCAN_CR2_DEBTIME_Pos (16UL) /*!< Position of debouncing time field. */ +#define KEYSCAN_CR2_DEBTIME_Msk (0x3FFUL << KEYSCAN_CR2_DEBTIME_Pos) /*!< Bit mask of debouncing time field. */ + +/* Bit 15 : FIFO clear */ +#define KEYSCAN_CR2_FIFOCLEAR_Pos (15UL) /*!< Position of FIFO clear field. */ +#define KEYSCAN_CR2_FIFOCLEAR_Msk (0x1UL << KEYSCAN_CR2_FIFOCLEAR_Pos) /*!< Bit mask of FIFO clear field. */ + +/* Bit 14 : Force scan fsm idle */ +#define KEYSCAN_CR2_FSMIDLE_Pos (14UL) /*!< Position of force scan fsm idle field. */ +#define KEYSCAN_CR2_FSMIDLE_Msk (0x1UL << KEYSCAN_CR2_FSMIDLE_Pos) /*!< Bit mask of force scan fsm idle field. */ + +/* Bit 13 : FIFO flag clear1 */ +#define KEYSCAN_CR2_FIFOFLAGCLR1_Pos (13UL) /*!< Position of FIFO flag clear1 field. */ +#define KEYSCAN_CR2_FIFOFLAGCLR1_Msk (0x1UL << KEYSCAN_CR2_FIFOFLAGCLR1_Pos) /*!< Bit mask of FIFO flag clear1 field. */ + +/* Bit 12 : FIFO flag clear2 */ +#define KEYSCAN_CR2_FIFOFLAGCLR2_Pos (12UL) /*!< Position of FIFO flag clear2 field. */ +#define KEYSCAN_CR2_FIFOFLAGCLR2_Msk (0x1UL << KEYSCAN_CR2_FIFOFLAGCLR2_Pos) /*!< Bit mask of FIFO flag clear2 field. */ + +/* Bit 7 : Key scan trigger type */ +#define KEYSCAN_CR2_TRIGTYPE_Pos (7UL) /*!< Position of ey scan trigger type field. */ +#define KEYSCAN_CR2_TRIGTYPE_Msk (0x1UL << KEYSCAN_CR2_TRIGTYPE_Pos) /*!< Bit mask of key scan trigger type field. */ +#define KEYSCAN_CR2_TRIGTYPE_EDGE (0UL) /*!< Edge trigger */ +#define KEYSCAN_CR2_TRIGTYPE_LEVEL (1UL) /*!< Level trigger */ + +/* Bit 6 : FIFO overflow control */ +#define KEYSCAN_CR2_FIFOOVCTL_Pos (6UL) /*!< Position of FIFO overflow control field. */ +#define KEYSCAN_CR2_FIFOOVCTL_Msk (0x1UL << KEYSCAN_CR2_FIFOOVCTL_Pos) /*!< Bit mask of FIFO overflow control field. */ +#define KEYSCAN_CR2_FIFOOVCTL_DISCARDNEW (0UL) /*!< Discard all the new scan data when FIFO is full. */ +#define KEYSCAN_CR2_FIFOOVCTL_DISCARDOLD (1UL) /*!< Discard the last scan data when FIFO is full. */ + +/* Bit 0 : Scan key limit */ +#define KEYSCAN_CR2_KEYLIMIT_Pos (0UL) /*!< Position of scan key limit field. */ +#define KEYSCAN_CR2_KEYLIMIT_Msk (0x1FUL << KEYSCAN_CR2_KEYLIMIT_Pos) /*!< Bit mask of scan key limit field. */ + + +/* Register: RTL_KEYSCAN_INTCR */ +/* Description: Interrupt Control Register */ + +/* Bit 15 : Interrupt mask */ +#define KEYSCAN_INTCR_INTMSK_Pos (15UL) /*!< Position of interrupt mask field. */ +#define KEYSCAN_INTCR_INTMSK_Msk (0x1UL << KEYSCAN_INTCR_INTMSK_Pos) /*!< Bit mask of interrupt mask field. */ + +/* Bit 14 : Int3 clear */ +#define KEYSCAN_INTCR_INT3CLR_Pos (14UL) /*!< Position of Int3 clear field. */ +#define KEYSCAN_INTCR_INT3CLR_Msk (0x1UL << KEYSCAN_INTCR_INT3CLR_Pos) /*!< Bit mask of Int3 clear field. */ + +/* Bit 13 : Int2 clear */ +#define KEYSCAN_INTCR_INT2CLR_Pos (13UL) /*!< Position of Int2 clear field. */ +#define KEYSCAN_INTCR_INT2CLR_Msk (0x1UL << KEYSCAN_INTCR_INT2CLR_Pos) /*!< Bit mask of Int2 clear field. */ + +/* Bit 12 : Int1 clear */ +#define KEYSCAN_INTCR_INT1CLR_Pos (12UL) /*!< Position of Int1 clear field. */ +#define KEYSCAN_INTCR_INT1CLR_Msk (0x1UL << KEYSCAN_INTCR_INT1CLR_Pos) /*!< Bit mask of Int1 clear field. */ + +/* Bit 11 : Interrupt control mode */ +#define KEYSCAN_INTCR_INTCTLMODE_Pos (11UL) /*!< Position of interrupt control mode field. */ +#define KEYSCAN_INTCR_INTCTLMODE_Msk (0x1UL << KEYSCAN_INTCR_INTCTLMODE_Pos) /*!< Bit mask of interrupt control mode field. */ +#define KEYSCAN_INTCR_INTCTLMODE_HW (0UL) /*!< HW control interrupt mode */ +#define KEYSCAN_INTCR_INTCTLMODE_SW (1UL) /*!< SW control interrupt mode */ + +/* Bit 10 : Enable/Disable interrupt in SW control mode */ +#define KEYSCAN_INTCR_SWINTEN_Pos (10UL) /*!< Position of Enable/Disable interrupt in SW control mode field. */ +#define KEYSCAN_INTCR_SWINTEN_Msk (0x1UL << KEYSCAN_INTCR_SWINTEN_Pos) /*!< Bit mask of Enable/Disable interrupt in SW control mode field. */ + +/* Bit 8 : Interrupt timeout period */ +#define KEYSCAN_INTCR_INTTOPERIOD_Pos (8UL) /*!< Position of Interrupt timeout period field. */ +#define KEYSCAN_INTCR_INTTOPERIOD_Msk (0x3UL << KEYSCAN_INTCR_INTTOPERIOD_Pos) /*!< Bit mask of Interrupt timeout period field. */ + +/* Bit 4 : Interrupt threshold */ +#define KEYSCAN_INTCR_INTTHRESHOLD_Pos (4UL) /*!< Position of ey Interrupt threshold field. */ +#define KEYSCAN_INTCR_INTTHRESHOLD_Msk (0x07UL << KEYSCAN_INTCR_INTTHRESHOLD_Pos) /*!< Bit mask of key Interrupt threshold field. */ + +/* Bit 2 : Int3 enable */ +#define KEYSCAN_INTCR_INT3EN_Pos (2UL) /*!< Position of Int3 enable field. */ +#define KEYSCAN_INTCR_INT3EN_Msk (0x1UL << KEYSCAN_INTCR_INT3EN_Pos) /*!< Bit mask of Int3 enable field. */ + +/* Bit 1 : Int2 enable */ +#define KEYSCAN_INTCR_INT2EN_Pos (1UL) /*!< Position of Int2 enable field. */ +#define KEYSCAN_INTCR_INT2EN_Msk (0x1UL << KEYSCAN_INTCR_INT2EN_Pos) /*!< Bit mask of Int2 enable field. */ + +/* Bit 0 : Int1 enable */ +#define KEYSCAN_INTCR_INT1EN_Pos (0UL) /*!< Position of Int1 enable field. */ +#define KEYSCAN_INTCR_INT1EN_Msk (0x1UL << KEYSCAN_INTCR_INT1EN_Pos) /*!< Bit mask of Int1 enable field. */ + + +/* Register: RTL_KEYSCAN_FIFODATA */ +/* Description: . */ + +/* Bit 5 : Row index */ +#define KEYSCAN_FIFODATA_ROWINDEX_Pos (5UL) /*!< Position of row index field. */ +#define KEYSCAN_FIFODATA_ROWINDEX_Msk (0x1FUL << KEYSCAN_FIFODATA_ROWINDEX_Pos) /*!< Bit mask of row index field. */ + +/* Bit 0 : Column index */ +#define KEYSCAN_FIFODATA_COLINDEX_Pos (0UL) /*!< Position of column index field. */ +#define KEYSCAN_FIFODATA_COLINDEX_Msk (0x7UL << KEYSCAN_FIFODATA_COLINDEX_Pos) /*!< Bit mask of column index field. */ + + +/* Register: RTL_KEYSCAN_STATUS */ +/* Description: . */ + +/* Bit 8 : FIFO offset */ +#define KEYSCAN_STATUS_FIFOOFFSET_Pos (8UL) /*!< Position of FIFO offset field. */ +#define KEYSCAN_STATUS_FIFOOFFSET_Msk (0x1FUL << KEYSCAN_STATUS_FIFOOFFSET_Pos) /*!< Bit mask of FIFO offset field. */ + +/* Bit 7 : FIFO reject flag */ +#define KEYSCAN_STATUS_FIFOREJECT_Pos (7UL) /*!< Position of FIFO reject flag. */ +#define KEYSCAN_STATUS_FIFOREJECT_Msk (0x1UL << KEYSCAN_STATUS_FIFOREJECT_Pos) /*!< Bit mask of FIFO reject flag. */ + +/* Bit 6 : FIFO overflow flag */ +#define KEYSCAN_STATUS_FIFOOVERFLOW_Pos (5UL) /*!< Position of FIFO overflow flag field. */ +#define KEYSCAN_STATUS_FIFOOVERFLOW_Msk (0x1UL << KEYSCAN_STATUS_FIFOOVERFLOW_Pos) /*!< Bit mask of FIFO overflow flag field. */ + +/* Bit 5 : FIFO full flag */ +#define KEYSCAN_STATUS_FIFOFULL_Pos (5UL) /*!< Position of FIFO full flag field. */ +#define KEYSCAN_STATUS_FIFOFULL_Msk (0x1UL << KEYSCAN_STATUS_FIFOFULL_Pos) /*!< Bit mask of FIFO full flag field. */ + +/* Bit 4 : FIFO empty flag */ +#define KEYSCAN_STATUS_FIFOEMPTY_Pos (4UL) /*!< Position of FIFO empty flag field. */ +#define KEYSCAN_STATUS_FIFOEMPTY_Msk (0x1UL << KEYSCAN_STATUS_FIFOEMPTY_Pos) /*!< Bit mask of FIFO empty flag field. */ + +/* Bit 0 : Current state */ +#define KEYSCAN_STATUS_CURSTATE_Pos (0UL) /*!< Position of Current state field. */ +#define KEYSCAN_STATUS_CURSTATE_Msk (0x7UL << KEYSCAN_STATUS_CURSTATE_Pos) /*!< Bit mask of Current state field. */ + + +/****************************************************************************************************************/ +/* Peripheral: System Block Control */ +/* Description: System Block Control. */ + +/* Register: REG_SYS_CLK_SEL */ +/* Description: REG_SYS_CLK_SEL. */ + +/* Bit 31 : r_SYS_CKE_SPLL. Clock enable of 40MHz and divider */ +#define SYSBLK_SYSCLK_CLKEN_SPLL_Pos (31UL) /*!< Position of */ +#define SYSBLK_SYSCLK_CLKEN_SPLL_Msk (0x1UL << SYSBLK_SYSCLK_CLKEN_SPLL_Pos) /*!< Bit mask of */ + +/* Bit 30 : r_SYS_40M_SEL. 0: from 40M RCOSC 1: from PLL */ +#define SYSBLK_SYSCLK_SRCSEL_Pos (30UL) /*!< Position of . */ +#define SYSBLK_SYSCLK_SRCSEL_Msk (0x1UL << SYSBLK_SYSCLK_SRCSEL_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_SYS_CKSL_CPU. CPU clock select 0: 40MHz 1: 20MHz 2: 10MHz 3: 5MHz 4: 53MHz 5: 26.5MHz Others: reserved */ +#define SYSBLK_SYSCLK_CPUCLK_Pos (0UL) /*!< Position of */ +#define SYSBLK_SYSCLK_CPUCLK_Msk (0x7UL << SYSBLK_SYSCLK_CPUCLK_Pos) /*!< Bit mask of */ + + +/* Register: REG_SOC_FUNC_EN */ +/* Description: REG_SOC_FUNC_EN. */ + +/* Bit 16 : BIT_SOC_GTIMER_EN. 1: enable GTIMER IP and GTIMER register */ +#define SYSBLK_GTIMER_EN_Pos (16UL) /*!< Position of */ +#define SYSBLK_GTIMER_EN_Msk (0x1UL << SYSBLK_GTIMER_EN_Pos) /*!< Bit mask of */ + +/* Bit 13 : BIT_SOC_GDMA0_EN. 1: Enable GDMA block */ +#define SYSBLK_GDMA0_EN_Pos (13UL) /*!< Position of . */ +#define SYSBLK_GDMA0_EN_Msk (0x1UL << SYSBLK_GDMA0_EN_Pos) /*!< Bit mask of */ + +/* Bit 12 : BIT_SOC_LOG_UART_EN. 1: enable log UART; 0: disable log UART */ +#define SYSBLK_LOGUART_EN_Pos (12UL) /*!< Position of . */ +#define SYSBLK_LOGUART_EN_Msk (0x1UL << SYSBLK_LOGUART_EN_Pos) /*!< Bit mask of */ + +/* Bit 5 : BIT_SOC_eFLASH_EN. 1. enable eflash controller */ +#define SYSBLK_EFLASH_EN_Pos (5UL) /*!< Position of . */ +#define SYSBLK_EFLASH_EN_Msk (0x1UL << SYSBLK_EFLASH_EN_Pos) /*!< Bit mask of */ + +/* Bit 4 : BIT_SOC_FLASH_EN. 1: enaable flash controller */ +#define SYSBLK_EXTFLASH_EN_Pos (4UL) /*!< Position of . */ +#define SYSBLK_EXTFLASH_EN_Msk (0x1UL << SYSBLK_EXTFLASH_EN_Pos) /*!< Bit mask of */ + +/* Bit 2 : BIT_SOC_BTBUS_EN. 1: enable BT function */ +#define SYSBLK_BTBUS_EN_Pos (2UL) /*!< Position of . */ +#define SYSBLK_BTBUS_EN_Msk (0x1UL << SYSBLK_BTBUS_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_SOC_PERI_FUNC0_EN */ +/* Description: REG_SOC_PERI_FUNC0_EN. */ + +/* Bit 24 : BIT_PERI_SPI2W_EN. 1: enable 2-wire/3-wire SPI interface */ +#define SYSBLK_SPI2W_EN_Pos (24UL) /*!< Position of */ +#define SYSBLK_SPI2W_EN_Msk (0x1UL << SYSBLK_SPI2W_EN_Pos) /*!< Bit mask of */ + +/* Bit 19 : BIT_PERI_KEYSCAN_EN. 1: enable KEYSCAN interface */ +#define SYSBLK_KEYSCAN_EN_Pos (19UL) /*!< Position of . */ +#define SYSBLK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_KEYSCAN_EN_Pos) /*!< Bit mask of */ + +/* Bit 18 : BIT_PERI_QDECODE_EN. 1: enable QDECODE interface */ +#define SYSBLK_QDECODE_EN_Pos (18UL) /*!< Position of . */ +#define SYSBLK_QDECODE_EN_Msk (0x1UL << SYSBLK_QDECODE_EN_Pos) /*!< Bit mask of */ + +/* Bit 17 : BIT_PERI_I2C1_EN. 1: enable I2C1 interface */ +#define SYSBLK_I2C1_EN_Pos (17UL) /*!< Position of . */ +#define SYSBLK_I2C1_EN_Msk (0x1UL << SYSBLK_I2C1_EN_Pos) /*!< Bit mask of */ + +/* Bit 16 : BIT_PERI_I2C0_EN. 1: enable I2C0 interface */ +#define SYSBLK_I2C0_EN_Pos (16UL) /*!< Position of . */ +#define SYSBLK_I2C0_EN_Msk (0x1UL << SYSBLK_I2C0_EN_Pos) /*!< Bit mask of */ + +/* Bit 10 : BIT_PERI_IR_EN. 1: enable IR interface */ +#define SYSBLK_IR_EN_Pos (10UL) /*!< Position of . */ +#define SYSBLK_IR_EN_Msk (0x1UL << SYSBLK_IR_EN_Pos) /*!< Bit mask of */ + +/* Bit 9 : BIT_PERI_SPI1_EN. 1: enable SPI1 interface */ +#define SYSBLK_SPI1_EN_Pos (9UL) /*!< Position of . */ +#define SYSBLK_SPI1_EN_Msk (0x1UL << SYSBLK_SPI1_EN_Pos) /*!< Bit mask of */ + +/* Bit 8 : BIT_PERI_SPI0_EN. 1: enable SPI0 interface */ +#define SYSBLK_SPI0_EN_Pos (8UL) /*!< Position of . */ +#define SYSBLK_SPI0_EN_Msk (0x1UL << SYSBLK_SPI0_EN_Pos) /*!< Bit mask of */ + +/* Bit 1 : BIT_PERI_UART1_EN. 1; enable UART1 interface ( DATA Uart1) */ +#define SYSBLK_UART1_EN_Pos (1UL) /*!< Position of . */ +#define SYSBLK_UART1_EN_Msk (0x1UL << SYSBLK_UART1_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_PERI_UART0_EN. 1; enable UART0 interface ( DATA Uart) */ +#define SYSBLK_UART0_EN_Pos (0UL) /*!< Position of . */ +#define SYSBLK_UART0_EN_Msk (0x1UL << SYSBLK_UART0_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_SOC_PERI_FUNC1_EN */ +/* Description: REG_SOC_PERI_FUNC1_EN. */ + +/* Bit 8 : BIT_PERI_GPIO_EN. 1: enable DW GPIO */ +#define SYSBLK_GPIO_EN_Pos (8UL) /*!< Position of */ +#define SYSBLK_GPIO_EN_Msk (0x1UL << SYSBLK_GPIO_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_PERI_ADC_EN. 1: enable ADC */ +#define SYSBLK_ADC_EN_Pos (0UL) /*!< Position of . */ +#define SYSBLK_ADC_EN_Msk (0x1UL << SYSBLK_ADC_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_PESOC_CLK_CTRL */ +/* Description: REG_PESOC_CLK_CTRL. */ + +/* Bit 25 : BIT_SOC_SLPCK_GPIO_EN */ +#define SYSBLK_SLPCK_GPIO_EN_Pos (25UL) /*!< Position of */ +#define SYSBLK_SLPCK_GPIO_EN_Msk (0x1UL << SYSBLK_SLPCK_GPIO_EN_Pos) /*!< Bit mask of */ + +/* Bit 24 : BIT_SOC_ACTCK_GPIO_EN */ +#define SYSBLK_ACTCK_GPIO_EN_Pos (24UL) /*!< Position of */ +#define SYSBLK_ACTCK_GPIO_EN_Msk (0x1UL << SYSBLK_ACTCK_GPIO_EN_Pos) /*!< Bit mask of */ + +/* Bit 17 : BIT_SOC_SLPCK_GDMA0_EN */ +#define SYSBLK_SLPCK_GDMA0_EN_Pos (17UL) /*!< Position of */ +#define SYSBLK_SLPCK_GDMA0_EN_Msk (0x1UL << SYSBLK_SLPCK_GDMA0_EN_Pos) /*!< Bit mask of */ + +/* Bit 16 : BIT_SOC_ACTCK_GDMA0_EN */ +#define SYSBLK_ACTCK_GDMA0_EN_Pos (16UL) /*!< Position of */ +#define SYSBLK_ACTCK_GDMA0_EN_Msk (0x1UL << SYSBLK_ACTCK_GDMA0_EN_Pos) /*!< Bit mask of */ + +/* Bit 15 : BIT_SOC_SLPCK_TIMER_EN */ +#define SYSBLK_SLPCK_TIMER_EN_Pos (15UL) /*!< Position of */ +#define SYSBLK_SLPCK_TIMER_EN_Msk (0x1UL << SYSBLK_SLPCK_TIMER_EN_Pos) /*!< Bit mask of */ + +/* Bit 14 : BIT_SOC_ACTCK_TIMER_EN */ +#define SYSBLK_ACTCK_TIMER_EN_Pos (14UL) /*!< Position of */ +#define SYSBLK_ACTCK_TIMER_EN_Msk (0x1UL << SYSBLK_ACTCK_TIMER_EN_Pos) /*!< Bit mask of */ + +/* Bit 13 : BIT_SOC_SLPCK_LOG_UART_EN */ +#define SYSBLK_SLPCK_LOGUART_EN_Pos (13UL) /*!< Position of */ +#define SYSBLK_SLPCK_LOGUART_EN_Msk (0x1UL << SYSBLK_SLPCK_LOGUART_EN_Pos) /*!< Bit mask of */ + +/* Bit 12 : BIT_SOC_ACTCK_LOG_UART_EN */ +#define SYSBLK_ACTCK_LOGUART_EN_Pos (12UL) /*!< Position of */ +#define SYSBLK_ACTCK_LOGUART_EN_Msk (0x1UL << SYSBLK_ACTCK_LOGUART_EN_Pos) /*!< Bit mask of */ + +/* Bit 11 : BIT_SOC_SLPCK_UART1_DATA_EN */ +#define SYSBLK_SLPCK_UART1DATA_EN_Pos (11UL) /*!< Position of */ +#define SYSBLK_SLPCK_UART1DATA_EN_Msk (0x1UL << SYSBLK_SLPCK_UART1DATA_EN_Pos) /*!< Bit mask of */ + +/* Bit 10 : BIT_SOC_ACTCK_UART1_DATA_EN */ +#define SYSBLK_ACTCK_UART1DATA_EN_Pos (10UL) /*!< Position of */ +#define SYSBLK_ACTCK_UART1DATA_EN_Msk (0x1UL << SYSBLK_ACTCK_UART1DATA_EN_Pos) /*!< Bit mask of */ + +/* Bit 9 : BIT_SOC_SLPCK_FLASH_EN */ +#define SYSBLK_SLPCK_FLASH_EN_Pos (9UL) /*!< Position of */ +#define SYSBLK_SLPCK_FLASH_EN_Msk (0x1UL << SYSBLK_SLPCK_FLASH_EN_Pos) /*!< Bit mask of */ + +/* Bit 8 : BIT_SOC_ACTCK_FLASH_EN */ +#define SYSBLK_ACTCK_FLASH_EN_Pos (8UL) /*!< Position of */ +#define SYSBLK_ACTCK_FLASH_EN_Msk (0x1UL << SYSBLK_ACTCK_FLASH_EN_Pos) /*!< Bit mask of */ + +/* Bit 7 : BIT_SOC_SLPCK_VENDOR_REG_EN */ +#define SYSBLK_SLPCK_VENDORREG_EN_Pos (7UL) /*!< Position of */ +#define SYSBLK_SLPCK_VENDORREG_EN_Msk (0x1UL << SYSBLK_SLPCK_VENDORREG_EN_Pos) /*!< Bit mask of */ + +/* Bit 6 : BIT_SOC_ACTCK_VENDOR_REG_EN */ +#define SYSBLK_ACTCK_VENDORREG_EN_Pos (6UL) /*!< Position of */ +#define SYSBLK_ACTCK_VENDORREG_EN_Msk (0x1UL << SYSBLK_ACTCK_VENDORREG_EN_Pos) /*!< Bit mask of */ + +/* Bit 3 : BIT_CKE_EFC. Embedded flash controller clock enable */ +#define SYSBLK_EFLASH_CLK_EN_Pos (3UL) /*!< Position of */ +#define SYSBLK_EFLASH_CLK_Msk (0x1UL << SYSBLK_EFLASH_CLK_EN_Pos) /*!< Bit mask of */ + +/* Bit 1 : BIT_CKE_CORDIC. CORDIC clock enable */ +#define SYSBLK_CODEC_CLK_EN_Pos (1UL) /*!< Position of */ +#define SYSBLK_CODEC_CLK_EN_Msk (0x1UL << SYSBLK_CODEC_CLK_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_CKE_HWSPI. HWSPI clock enable */ +#define SYSBLK_HWSPI_CLK_EN_Pos (0UL) /*!< Position of */ +#define SYSBLK_HWSPI_CLK_EN_Msk (0x1UL << SYSBLK_HWSPI_CLK_EN_Pos) /*!< Bit mask of */ +#define SYSBLK_ADC_EN_Msk (0x1UL << SYSBLK_ADC_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_PESOC_PERI_CLK_CTRL0 */ +/* Description: REG_PESOC_PERI_CLK_CTRL0. */ + +/* Bit 21 : BIT_SOC_SLPCK_IR_EN. 1: IR clock enable when CPU sleep command */ +#define SYSBLK_SLPCK_IR_EN_Pos (21UL) /*!< Position of */ +#define SYSBLK_SLPCK_IR_EN_Msk (0x1UL << SYSBLK_SLPCK_IR_EN_Pos) /*!< Bit mask of */ + +/* Bit 20 : BIT_SOC_ACTCK_IR_EN */ +#define SYSBLK_ACTCK_IR_EN_Pos (20UL) /*!< Position of */ +#define SYSBLK_ACTCK_IR_EN_Msk (0x1UL << SYSBLK_ACTCK_IR_EN_Pos) /*!< Bit mask of */ + +/* Bit 19 : BIT_SOC_SLPCK_SPI1_EN */ +#define SYSBLK_SLPCK_SPI1_EN_Pos (19UL) /*!< Position of */ +#define SYSBLK_SLPCK_SPI1_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI1_EN_Pos) /*!< Bit mask of */ + +/* Bit 18 : BIT_SOC_ACTCK_SPI1_EN */ +#define SYSBLK_ACTCK_SPI1_EN_Pos (18UL) /*!< Position of */ +#define SYSBLK_ACTCK_SPI1_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI1_EN_Pos) /*!< Bit mask of */ + +/* Bit 17 : BIT_SOC_SLPCK_SPI0_EN */ +#define SYSBLK_SLPCK_SPI0_EN_Pos (17UL) /*!< Position of */ +#define SYSBLK_SLPCK_SPI0_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI0_EN_Pos) /*!< Bit mask of */ + +/* Bit 16 : BIT_SOC_ACTCK_SPI0_EN */ +#define SYSBLK_ACTCK_SPI0_EN_Pos (16UL) /*!< Position of */ +#define SYSBLK_ACTCK_SPI0_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI0_EN_Pos) /*!< Bit mask of */ + +/* Bit 3 : BIT_SOC_SLPCK_UART1_HCI_EN */ +#define SYSBLK_SLPCK_UART1HCI_EN_Pos (3UL) /*!< Position of */ +#define SYSBLK_SLPCK_UART1HCI_EN_Msk (0x1UL << SYSBLK_SLPCK_UART1HCI_EN_Pos) /*!< Bit mask of */ + +/* Bit 2 : BIT_SOC_ACTCK_UART1_HCI_EN */ +#define SYSBLK_ACTCK_UART1HCI_EN_Pos (2UL) /*!< Position of */ +#define SYSBLK_ACTCK_UART1HCI_EN_Msk (0x1UL << SYSBLK_ACTCK_UART1HCI_EN_Pos) /*!< Bit mask of */ + +/* Bit 1 : BIT_SOC_SLPCK_UART0_DATA_EN */ +#define SYSBLK_SLPCK_UART0DATA_EN_Pos (1UL) /*!< Position of */ +#define SYSBLK_SLPCK_UART0DATA_EN_Msk (0x1UL << SYSBLK_SLPCK_UART0DATA_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_SOC_ACTCK_UART0_DATA_EN */ +#define SYSBLK_ACTCK_UART0DATA_EN_Pos (0UL) /*!< Position of */ +#define SYSBLK_ACTCK_UART0DATA_EN_Msk (0x1UL << SYSBLK_ACTCK_UART0DATA_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_PESOC_PERI_CLK_CTRL1 */ +/* Description: REG_PESOC_PERI_CLK_CTRL1. */ + +/* Bit 31 : r_CODEC_CLK_10M_EN. Codec 10MHz clock source enable */ +#define SYSBLK_CODEC_CLK10M_EN_Pos (31UL) /*!< Position of */ +#define SYSBLK_CODEC_CLK10M_EN_Msk (0x1UL << SYSBLK_CODEC_CLK10M_EN_Pos) /*!< Bit mask of */ + +/* Bit 30 : r_CODEC_CLK_40M_EN */ +#define SYSBLK_CODEC_CLK40M_EN_Pos (30UL) /*!< Position of */ +#define SYSBLK_CODEC_CLK40M_EN_Msk (0x1UL << SYSBLK_CODEC_CLK40M_EN_Pos) /*!< Bit mask of */ + +/* Bit 25 : BIT_SOC_SLPCK_ADC_EN */ +#define SYSBLK_SLPCK_ADC_EN_Pos (25UL) /*!< Position of */ +#define SYSBLK_SLPCK_ADC_EN_Msk (0x1UL << SYSBLK_SLPCK_ADC_EN_Pos) /*!< Bit mask of */ + +/* Bit 24 : BIT_SOC_ACTCK_ADC_EN */ +#define SYSBLK_ACTCK_ADC_EN_Pos (24UL) /*!< Position of */ +#define SYSBLK_ACTCK_ADC_EN_Msk (0x1UL << SYSBLK_ACTCK_ADC_EN_Pos) /*!< Bit mask of */ + +/* Bit 17 : BIT_SOC_SLPCK_SPI_3WIRE_EN */ +#define SYSBLK_SLPCK_SPI2WIRE_EN_Pos (17UL) /*!< Position of */ +#define SYSBLK_SLPCK_SPI2WIRE_EN_Msk (0x1UL << SYSBLK_SLPCK_SPI2WIRE_EN_Pos) /*!< Bit mask of */ + +/* Bit 16 : BIT_SOC_ACTCK_SPI_3WIRE_EN */ +#define SYSBLK_ACTCK_SPI2WIRE_EN_Pos (16UL) /*!< Position of */ +#define SYSBLK_ACTCK_SPI2WIRE_EN_Msk (0x1UL << SYSBLK_ACTCK_SPI2WIRE_EN_Pos) /*!< Bit mask of */ + +/* Bit 7 : BIT_SOC_SLPCK_KEYSCAN_EN */ +#define SYSBLK_SLPCK_KEYSCAN_EN_Pos (7UL) /*!< Position of */ +#define SYSBLK_SLPCK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_SLPCK_KEYSCAN_EN_Pos) /*!< Bit mask of */ + +/* Bit 6 : BIT_SOC_ACTCK_KEYSCAN_EN */ +#define SYSBLK_ACTCK_KEYSCAN_EN_Pos (6UL) /*!< Position of */ +#define SYSBLK_ACTCK_KEYSCAN_EN_Msk (0x1UL << SYSBLK_ACTCK_KEYSCAN_EN_Pos) /*!< Bit mask of */ + +/* Bit 5 : BIT_SOC_SLPCK_QDECODE_EN */ +#define SYSBLK_SLPCK_QDECODE_EN_Pos (5UL) /*!< Position of */ +#define SYSBLK_SLPCK_QDECODE_EN_Msk (0x1UL << SYSBLK_SLPCK_QDECODE_EN_Pos) /*!< Bit mask of */ + +/* Bit 4 : BIT_SOC_ACTCK_QDECODE_EN */ +#define SYSBLK_ACTCK_QDECODE_EN_Pos (4UL) /*!< Position of */ +#define SYSBLK_ACTCK_QDECODE_EN_Msk (0x1UL << SYSBLK_ACTCK_QDECODE_EN_Pos) /*!< Bit mask of */ + +/* Bit 3 : BIT_SOC_SLPCK_I2C1_EN */ +#define SYSBLK_SLPCK_I2C1_EN_Pos (3UL) /*!< Position of */ +#define SYSBLK_SLPCK_I2C1_EN_Msk (0x1UL << SYSBLK_SLPCK_I2C1_EN_Pos) /*!< Bit mask of */ + +/* Bit 2 : BIT_SOC_ACTCK_I2C1_EN */ +#define SYSBLK_ACTCK_I2C1_EN_Pos (2UL) /*!< Position of */ +#define SYSBLK_ACTCK_I2C1_EN_Msk (0x1UL << SYSBLK_ACTCK_I2C1_EN_Pos) /*!< Bit mask of */ + +/* Bit 1 : BIT_SOC_SLPCK_I2C0_EN */ +#define SYSBLK_SLPCK_I2C0_EN_Pos (1UL) /*!< Position of */ +#define SYSBLK_SLPCK_I2C0_EN_Msk (0x1UL << SYSBLK_SLPCK_I2C0_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_SOC_ACTCK_I2C0_EN */ +#define SYSBLK_ACTCK_I2C0_EN_Pos (0UL) /*!< Position of */ +#define SYSBLK_ACTCK_I2C0_EN_Msk (0x1UL << SYSBLK_ACTCK_I2C0_EN_Pos) /*!< Bit mask of */ + + +/* Register: REG_PESOC_COM_CLK_CTRL1 */ +/* Description: REG_PESOC_COM_CLK_CTRL1. */ + +/* Bit 1 : BIT_SOC_SLPCK_BTBUS_EN. 1: BTBUS clock enable when CPU sleep mode */ +#define SYSBLK_SLPCK_BTBUS_EN_Pos (1UL) /*!< Position of */ +#define SYSBLK_SLPCK_BTBUS_EN_Msk (0x1UL << SYSBLK_SLPCK_BTBUS_EN_Pos) /*!< Bit mask of */ + +/* Bit 0 : BIT_SOC_ACTCK_BTBUS_EN. 1: BTBUS clock enable in CPU run mode */ +#define SYSBLK_ACTCK_BTBUS_EN_Pos (0UL) /*!< Position of */ +#define SYSBLK_ACTCK_BTBUS_EN_Msk (0x1UL << SYSBLK_ACTCK_BTBUS_EN_Pos) /*!< Bit mask of */ + + +/****************************************************************************************************************/ +/* Peripheral: Quad Decoder */ +/* Description: Quad Decoder */ + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/peripheral/rtl876x_captouch.h b/inc/peripheral/rtl876x_captouch.h new file mode 100644 index 0000000..7c82a07 --- /dev/null +++ b/inc/peripheral/rtl876x_captouch.h @@ -0,0 +1,895 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_captouch.h +* \brief The header file of the peripheral CAP TOUCH driver. +* \details This file provides all CAP TOUCH firmware functions. +* \author Yuan +* \date 2020-11-11 +* \version v1.0.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_CAPTOUCH_H_ +#define _RTL876X_CAPTOUCH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup CTC CAP TOUCH CONTROLLER + * \brief Manage the CAP TOUCH peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Registers Definitions + *============================================================================*/ + +/* Peripheral: CTC */ +/* Description: Cap touch register defines */ + +/* Register: CR */ +/* Description: CTC Control Register 0. Offset: 0x00. Address: 0x40007000. */ + +/* CR[8] :CTC_BASELINE_INI. Baseline initial function enable. 0x1: Enable. 0x0: Disable. */ +#define CTC_BASELINE_INI_Pos (8UL) +#define CTC_BASELINE_INI_Msk (0x1UL << CTC_BASELINE_INI_Pos) +#define CTC_BASELINE_INI_CLR (~(CTC_BASELINE_INI_Msk)) + +/* CR[6:5] :CTC_DEBOUNCE_TIME. De-bounce time setting. 0x1: Enable. 0x0: Disable. */ +#define CTC_DEBOUNCE_TIME_Pos (5UL) +#define CTC_DEBOUNCE_TIME_Msk (0x03UL << CTC_DEBOUNCE_TIME_Pos) +#define CTC_DEBOUNCE_TIME_CLR (~(CTC_DEBOUNCE_TIME_Msk)) + +/* CR[4] :CTC_DEBOUNCE_EN. De-bounce function control. 0x1: Enable. 0x0: Disable. */ +#define CTC_DEBOUNCE_EN_Pos (4UL) +#define CTC_DEBOUNCE_EN_Msk (0x1UL << CTC_DEBOUNCE_EN_Pos) +#define CTC_DEBOUNCE_EN_CLR (~(CTC_DEBOUNCE_EN_Msk)) + +/* CR[0] :CTC_CT_EN. Cap touch function control. 0x1: Enable. 0x0: Disable. */ +#define CTC_CT_EN_Pos (0UL) +#define CTC_CT_EN_Msk (0x1UL << CTC_CT_EN_Pos) +#define CTC_CT_EN_Clr (~(CTC_CT_EN_Msk)) + +/* Register: SCAN_PERIOD */ +/* Description: Scan period Register 0. Offset: 0x04. Address: 0x40007004. */ + +/* SCAN_PERIOD[18:16] :CTC_SAMPLE_AVE. ADC Sampled number for average function. */ +#define CTC_SAMPLE_AVE_Pos (16UL) +#define CTC_SAMPLE_AVE_Msk (0x7UL << CTC_SAMPLE_AVE_Pos) +#define CTC_SAMPLE_AVE_Clr (~(CTC_SAMPLE_AVE_Msk)) + +/* SCAN_PERIOD[11:0] :CTC_SCAN_INTERVAL. Scan interval setting. */ +#define CTC_SCAN_INTERVAL_Pos (0UL) +#define CTC_SCAN_INTERVAL_Msk (0xFFFUL << CTC_SCAN_INTERVAL_Pos) +#define CTC_SCAN_INTERVAL_Clr (~(CTC_SCAN_INTERVAL_Msk)) + +/* Register: ETC_CR */ +/* Description: ETC Register 0. Offset: 0x08. Address: 0x40007008. */ + +/* ETC_CR[15:12] :CTC_BASELINE_UPDATE_STEP. Baseline update step every time for all channel. Default: 0001. */ +#define CTC_BASELINE_UPDATE_STEP_Pos (12UL) +#define CTC_BASELINE_UPDATE_STEP_Msk (0xFUL << CTC_BASELINE_UPDATE_STEP_Pos) +#define CTC_BASELINE_UPDATE_STEP_Clr (~(CTC_BASELINE_UPDATE_STEP_Msk)) + +/* ETC_CR[11:8] :CTC_BASELINE_UPD_WT_FACTOR. Baseline update weight factor for all channels. */ +#define CTC_BASELINE_UPD_WT_FACTOR_Pos (8UL) +#define CTC_BASELINE_UPD_WT_FACTOR_Msk (0xFUL << CTC_BASELINE_UPD_WT_FACTOR_Pos) +#define CTC_BASELINE_UPD_WT_FACTOR_Clr (~(CTC_BASELINE_UPD_WT_FACTOR_Msk)) + +/* ETC_CR[7:1] :CTC_ETC_UPDATE_INTERVAL. ETC update interval between 2 scan period(sleep time )for all channel. */ +#define CTC_ETC_UPDATE_INTERVAL_Pos (1UL) +#define CTC_ETC_UPDATE_INTERVAL_Msk (0x7FUL << CTC_ETC_UPDATE_INTERVAL_Pos) +#define CTC_ETC_UPDATE_INTERVAL_Clr (~(CTC_ETC_UPDATE_INTERVAL_Msk)) + +/* ETC_CR[0] :CTC_ETC_EN. Environmental cap tracking calibration function. 0x1: Enable. 0x0: Disable. */ +#define CTC_ETC_EN_Pos (0UL) +#define CTC_ETC_EN_Msk (0x1UL << CTC_ETC_EN_Pos) +#define CTC_ETC_EN_Clr (~(CTC_ETC_EN_Msk)) + +/* Register: SNR_INF */ +/* Description: Scan period Register 0. Offset: 0x0C. Address: 0x4000700C. */ + +/* SNR_INF[31] :CTC_SNR_UPDATE_MODE. SNR update mode. */ +#define CTC_SNR_UPDATE_MODE_Pos (31UL) +#define CTC_SNR_UPDATE_MODE_Msk (0x1UL << CTC_SNR_UPDATE_MODE_Pos) +#define CTC_SNR_UPDATE_MODE_Clr (~(CTC_SNR_UPDATE_MODE_Msk)) + +/* Register: CTC_GUARD_CNT */ +/* Description: Guard counter Register. Offset: 0x1C. Address: 0x4000701C. */ + +/* CTC_GUARD_CNT[20:16] :CTC_DLY_GUARD_INTERVAL. Delay guard interval,1 unit for 32k clock period (31.25us). */ +#define CTC_DLY_GUARD_INTERVAL_Pos (16UL) +#define CTC_DLY_GUARD_INTERVAL_Msk (0x1FUL << CTC_DLY_GUARD_INTERVAL_Pos) +#define CTC_DLY_GUARD_INTERVAL_Clr (~(CTC_DLY_GUARD_INTERVAL_Msk)) + +/* CTC_GUARD_CNT[4:0] :CTC_ADV_GUARD_INTERVAL. Advanced guard interval,1 unit for 32k clock period (31.25us). */ +#define CTC_ADV_GUARD_INTERVAL_Pos (0UL) +#define CTC_ADV_GUARD_INTERVAL_Msk (0x1FUL << CTC_ADV_GUARD_INTERVAL_Pos) +#define CTC_ADV_GUARD_INTERVAL_Clr (~(CTC_ADV_GUARD_INTERVAL_Msk)) + +/*============================================================================* + * Constants + *============================================================================*/ +/** + * \defgroup CTC_Exported_Constants Macro Definitions + * \ingroup CTC + */ + +#define IS_CTC_PERIPH(PERIPH) ((PERIPH) == CTC) +#define IS_CTC_CHANNEL(CH) (((CH) == CTC_Channel0)\ + ||((CH) == CTC_Channel1)) + +/* CTC private defines */ +#define CTC_ANA_ADC_REG0X_LPAD *((volatile uint32_t *)0x40007400UL) +#define CTC_ANA_ADC_REG1X_LPAD *((volatile uint32_t *)0x40007404UL) +#define CTC_ANA_ADC_REG0X_LPSD *((volatile uint32_t *)0x40007408UL) +#define CTC_ANA_ADC_TIME_SET *((volatile uint32_t *)0x4000740CUL) +#define CTC_ANA_ADC_POWER_SEQ *((volatile uint32_t *)0x40007410UL) + +#define CTC_CLOCK_SOURCE_1M 1000000 +#define CTC_CLOCK_SOURCE_40M 40000000 + +typedef enum +{ + CTC_SLOW_MODE = 0, + CTC_FAST_MODE = 1 +} E_CTC_MODE; + +#define IS_CTC_MODE(mode) (((mode) == CTC_SLOW_MODE) || ((mode) == CTC_FAST_MODE)) + +typedef enum +{ + CTC_TOUCH_JUDGEMENT_DIFFEENCE = 0, + CTC_TOUCH_JUDGEMENT_ABSOLUTE = 1, +} E_CTC_TOUCH_JUDGEMENT_MODE; + +#define IS_CTC_TOUCH_JUDGEMENT_MODE(mode) (((mode) == CTC_TOUCH_JUDGEMENT_DIFFEENCE) || ((mode) == CTC_TOUCH_JUDGEMENT_ABSOLUTE)) + +/** + * \defgroup CTC_BaselineIni_Enable CTC BaselineIni Enable + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_BASELINEINI_DISABLE 0x00 +#define CTC_BASELINEINI_ENABLE 0x01 +/** \} */ + +/** + * \defgroup CTC_Debounce_Times CTC Debounce Times + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_DEBOUNCE_TIMES_2 0x00 +#define CTC_DEBOUNCE_TIMES_3 0x01 +#define CTC_DEBOUNCE_TIMES_4 0x02 +#define CTC_DEBOUNCE_TIMES_5 0x03 +/** \} */ + +/** + * \defgroup CTC_Interrupts_Definition CTC Interrupts Definition + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_DEBOUNCE_DISABLE 0x00 +#define CTC_DEBOUNCE_ENABLE 0x01 +/** \} */ + +/** + * \defgroup CTC_Enable CTC Enable + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_DISABLE 0x00 +#define CTC_ENABLE 0x01 +/** \} */ + +/** + * \defgroup CTC_Sample_Time CTC Sample Time + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_SAMPLE_TIME_AVE_4 0x00 +#define CTC_SAMPLE_TIME_AVE_8 0x01 +#define CTC_SAMPLE_TIME_AVE_16 0x02 +#define CTC_SAMPLE_TIME_AVE_32 0x03 +#define CTC_SAMPLE_TIME_AVE_64 0x04 +#define CTC_SAMPLE_TIME_AVE_128 0x05 +#define CTC_SAMPLE_TIME_AVE_256 0x06 +#define CTC_SAMPLE_TIME_AVE_512 0x07 +/** \} */ + +/** + * \defgroup CTC_Scan_Interval CTC Scan Interval + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_SCAN_INTERVAL_60ms 0x3C +#define CTC_SCAN_INTERVAL_100ms 0x64 +#define CTC_SCAN_INTERVAL_140ms 0x8C +#define CTC_SCAN_INTERVAL_180ms 0xB4 +#define CTC_SCAN_INTERVAL_220ms 0xDC +#define CTC_SCAN_INTERVAL_260ms 0x104 +#define CTC_SCAN_INTERVAL_300ms 0x12C +#define CTC_SCAN_INTERVAL_480ms 0x1E0 +/** \} */ + +/** + * \defgroup CTC_Interrupts_Definition CTC Interrupts Definition + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_INT_FALSE_TOUCH_CH1 BIT20 +#define CTC_INT_FALSE_TOUCH_CH0 BIT19 +#define CTC_INT_N_NOISE_THD BIT18 +#define CTC_INT_FIFO_OVERFLOW BIT17 +#define CTC_INT_P_NOISE_THD BIT16 +#define CTC_INT_TOUCH_RELEASE_CH1 BIT9 +#define CTC_INT_TOUCH_RELEASE_CH0 BIT8 +#define CTC_INT_TOUCH_PRESS_CH1 BIT1 +#define CTC_INT_TOUCH_PRESS_CH0 BIT0 +/** \} */ + +#define IS_CTC_INT(INT) (((INT) == CTC_INT_FALSE_TOUCH_CH1) || \ + ((INT) == CTC_INT_FALSE_TOUCH_CH0) || \ + ((INT) == CTC_INT_N_NOISE_THD) || \ + ((INT) == CTC_INT_FIFO_OVERFLOW) || \ + ((INT) == CTC_INT_P_NOISE_THD) || \ + ((INT) == CTC_INT_TOUCH_RELEASE_CH1) || \ + ((INT) == CTC_INT_TOUCH_RELEASE_CH0) || \ + ((INT) == CTC_INT_TOUCH_PRESS_CH1) || \ + ((INT) == CTC_INT_TOUCH_PRESS_CH0)) + +/** + * \defgroup CTC_MBIAS_Current CTC MBIAS Current + * \{ + * \ingroup CTC_Exported_Constants + */ +#define CTC_MBIAS_0p25uA (1UL << 0) +#define CTC_MBIAS_0p5uA (1UL << 1) +#define CTC_MBIAS_1uA (1UL << 2) +#define CTC_MBIAS_2uA (1UL << 3) +#define CTC_MBIAS_4uA (1UL << 4) +#define CTC_MBIAS_8uA (1UL << 5) +/** \} */ + +#define IS_CTC_MBIAS(mbias) (((mbias) == CTC_MBIAS_0p25uA) ||\ + ((mbias) == CTC_MBIAS_0p5uA) ||\ + ((mbias) == CTC_MBIAS_1uA ) ||\ + ((mbias) == CTC_MBIAS_2uA ) ||\ + ((mbias) == CTC_MBIAS_4uA ) ||\ + ((mbias) == CTC_MBIAS_8uA )) + +/** + * \defgroup CTC_FS_Match_Count CTC FS Match Count + * \{ + * \ingroup CTC_Exported_Constants + */ +typedef enum +{ + CTC_FS_Match_Cnt_No_Switch = 0x0, + CTC_FS_Match_Cnt_1DB = 0x01, + CTC_FS_Match_Cnt_2DB = 0x02, + CTC_FS_Match_Cnt_3DB = 0x03, + CTC_FS_Match_Cnt_4DB = 0x04 +} E_CTC_MODE_SWITCH; +/** \} */ + +#define IS_CTC_FS_Match(cnt) (((cnt) == CTC_FS_Match_Cnt_No_Switch) ||\ + ((cnt) == CTC_FS_Match_Cnt_1DB) ||\ + ((cnt) == CTC_FS_Match_Cnt_2DB ) ||\ + ((cnt) == CTC_FS_Match_Cnt_3DB ) ||\ + ((cnt) == CTC_FS_Match_Cnt_4DB )) + +#define CTC_CH_MAX 2 + +/** + * \defgroup CTC_Channel CTC Channel + * \{ + * \ingroup CTC_Exported_Constants + */ +typedef enum +{ + CTC_CH0 = 0, + CTC_CH1 = 1, +} E_CTC_CH; +/** \} */ + +/** + * \cond private + * \defgroup CTC_FS_TOUCH_CNT_TYPE CTC FS Touch Count + * \{ + */ +typedef union _FS_TOUCH_CNT01_TYPE +{ + uint32_t d32; + struct + { + uint32_t TOUCH_ACTIVE_CNT0: 10; + uint32_t RSVD: 6; + uint32_t TOUCH_ACTIVE_CNT1: 10; + uint32_t RSVD2: 6; + }; +} FS_TOUCH_CNT01_TYPE; + +typedef union _FS_TOUCH_CNT23_TYPE +{ + uint32_t d32; + struct + { + uint32_t TOUCH_ACTIVE_CNT2: 10; + uint32_t RSVD: 6; + uint32_t TOUCH_ACTIVE_CNT3: 10; + uint32_t RSVD2: 6; + }; +} FS_TOUCH_CNT23_TYPE; + +/* combine 0x158 & 0x15C for API usage */ +typedef union _FS_TOUCH_CNT_TYPE +{ + uint16_t d16[4]; + struct + { + FS_TOUCH_CNT01_TYPE fs_touch_cnt_01; + FS_TOUCH_CNT23_TYPE fs_touch_cnt_23; + }; +} FS_TOUCH_CNT_TYPE; +/** + * \} + * \endcond + */ + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup CTC_Exported_Types Init Params Struct + * + * \ingroup CTC + */ + +/** + * \brief CTC init structure definition. + * + * \ingroup CTC_Exported_Types + */ +typedef struct +{ + uint16_t CTC_BaselineIniEn; /**< Baseline initial function enable, HW will clear this bit to "0" after baseline initial. */ + uint8_t CTC_DebounceTime; /**< Debounce time setting.*/ + uint8_t CTC_DebounceEn; /**< Debounce function control: "0":disable; "1": enable.*/ + uint32_t CTC_SampleTime; /**< ADC sample time, active time. sample_time = 2^(CTC_SampleTime+2)*131072;unit is 131.072KHz; + sample number=4~512.Default: 110, sample number=256. */ + uint16_t CTC_ScanInterval; /**< Scan interval :Sleep time between 2 scan burst for all channels, range: 0~4095ms; code: 0~4095(0~0xFFF), unit is 1.024KHz cycle. (1/32 32.768KHz). + When this register set to 0 or 1, HW will scan continuously and has no sleep time; Recommend value: 60~480ms; Default: 0X3c(60ms).*/ + uint16_t CTC_BaselineUpdateStep; /**< Baseline update step every time for all channel. + This parameter can be a value of \ref ENHTIM_Clock_Divider*/ + uint16_t CTC_BaselineWeightFactor; /**< Baseline update weight factor for all channels; Factor=2 ^ (BASELINE_WT_FACTOR); Default: 0010. + This parameter can be a value of DISABLE or ENABLE */ + uint8_t CTC_ETCScanInterval; /**< ETC update interval between 2 scan period(sleep time )for all channel: + Interval=(ETC_SCAN_INTERVAL+1)*Scan period; (1~128). Default: 0x2; (Update every scan period). */ + uint8_t CTC_ETCEn; /**< Environmental cap tracking calibration function: "0":disable; "1": enable. + This parameter can be a value of DISABLE or ENABLE */ + uint32_t CTC_SNRUpdateMode; /**< Specifies SNR update mode. + This parameter default to 0x0, which is update SNR_noise data or touch data based on touch status*/ + uint8_t CTC_ScanChannel; /**< Specifies scan channel control. + This parameter default to 0x0000. */ + uint8_t CTC_ScanChannelSwitchMode; /**< Specifies the scan channel switch control. + This parameter default to 1, which is auto switch to next channel.*/ + uint32_t CTC_DelayGuardInterval; /**< Delay guard interval 1 unit for 32k clock period (31.25us).*/ + uint32_t CTC_AdvancedGuardInterval; /**< Delay guard interval 1 unit for 32k clock period (31.25us).*/ + uint32_t CTC_FastMatchCnt; /**< Enter Fast mode when the Debounce time matches FS_MATCH_CNT. + This parameter can be a value of \ref CTC_FS_Match_Coun. */ + uint32_t CTC_FastScanInerval; /**< Specifies the scan Interval under Fast mode,range: 0~4095ms; + This parameter can be a range of 0~0xFFF;*/ + uint32_t CTC_FalseTouchCnt; /**< Specifies the false touch detection after enter Fast mode (1 unit for 1scan). + This parameter can be a a range of 0~0x3FF. */ + uint32_t CTC_FalseAlarmCnt; /**< Specifies the false alarm detection after enter Fast mode (1 unit for 1scan). + This parameter can be a a range of 0~0xF.*/ + uint32_t CTC_ReleaseActiveCnt; /**< Specifies the determine counter value when leave Fast mode after touch release. + This parameter can be a a range of 0~0x3FF.*/ +} CTC_InitTypeDef; + +/** + * \brief CTC channel init structure definition. + * + * \ingroup CTC_Exported_Types + */ +typedef struct +{ + uint8_t CTC_ChannelEn; /**< Cap Sensor activity control of channelx. + This parameter can be a value of ENABLE or DISABLE. */ + uint16_t CTC_BaselineData; /**< Specifies digital baseline data of channelx. + This parameter can be 0x0 ~ 0xFFF. */ + uint16_t CTC_DifferenceTouchThd;/**< Difference threshold data of touch judgement for channelx. + This parameter can be 0x0 ~ 0xFFF. */ + uint16_t CTC_AbsoluteTouchThd; /**< Specifies absolute threshold data of touch judgement for channelx. + This parameter can be 0x0 ~ 0xFFF. */ + uint32_t CTC_PNoiseThd; /**< The environmental pasitive noise threshold: the positive maximum capacitance change of raw data that is still considered an environmental change. + This parameter can be 0x0 ~ 0xFF. */ + uint32_t CTC_NNoiseThd; /**< The environmental negative noise threshold: the negative maximum capacitance change of raw data that is still considered an environmental change. + This parameter can be 0x0 ~ 0xFF. */ + uint8_t CTC_MBias; /**< Specifies Channelx mbias current tuning(sensitivity tuning) Touch bias current [5:0]: 8uA/4Ua/2uA/1uA/0.5uA/0.25uA. + This parameter can be a value of \ref CTC_MBIAS_Current. */ +} CTC_ChannelInitTypeDef; + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup CTC_Exported_Functions Peripheral APIs + * \{ + * \ingroup CTC + */ + +/** + * \brief Deinitialize the Cap Touch peripheral registers to their default reset values. + * \return None. + */ +void CTC_DeInit(void); + +/** + * \brief Enable the CTC peripheral IP clock and function. + * \param clock_source: CTC peripheral clock source. + * This parameter can be one of the following values. + * \arg CTC_CLOCK_SOURCE_1M: 1M clock source + * \arg CTC_CLOCK_SOURCE_40M: 40M clock source + * \return None. + */ +void CTC_RCCConfig(uint32_t clock_source); + +/** + * \brief Initializes the CTC peripheral according to + * the specified parameters in the CTC_InitStruct. + * \param[in] CTCx: CTC peripheral. + * \param[in] CTC_InitStruct: Pointer to a CTC_InitTypeDef structure that contains + * the configuration information for the specified CTC peripheral. + * \return None. + */ +void CTC_Init(CTC_TypeDef *CTCx, CTC_InitTypeDef *CTC_InitStruct); + +/** + * \brief Initializes the specified channel. + * \param CTC_Channelx: specified channel + * \param CTC_ChannelInitStruct: pointer to a CTC_ChannelInitTypeDef structure that + * contains the configuration information for the specified CTC channel. + * \return None + */ +void CTC_ChannelInit(CTC_ChannelTypeDef *CTC_Channelx, + CTC_ChannelInitTypeDef *CTC_ChannelInitStruct); + +/** + * \brief Fills each CTC_InitStruct member with its default value. + * \param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized. + * \return None. + */ +void CTC_StructInit(CTC_InitTypeDef *CTC_InitStruct); + +/** + * \brief Fills each CTC_InitStruct member with its default value. + * \param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized. + * \return None. + */ +void CTC_ChannelStructInit(CTC_ChannelInitTypeDef *CTC_ChannelInitStruct); + +/** + * \brief Enable or disable the specified Cap Touch interrupt. + * \param[in] CTCx: The Cap Touch peripheral. + * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt. + * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt + * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt. + * \param NewState: New state of the Cap Touch interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None + */ +void CTC_INTConfig(uint32_t CTC_INT, FunctionalState NewState); + +/** + * \brief Enables or disables the specified Cap Touch peripheral. + * \param ENHTIMx: Cap Touch peripheral. + * \param NewState: New state of the Cap Touch peripheral. + * This parameter can be: ENABLE or DISABLE. + * \retutn None. + */ +void CTC_Cmd(CTC_TypeDef *CTCx, FunctionalState NewState); + +/** + * \brief Enable or disable system wake up of CTC. + * \param NewState: new state of the wake up function. + * This parameter can be: ENABLE or DISABLE. + * \return None + */ +void CTC_SystemWakeupConfig(E_CTC_CH channel, FunctionalState NewState); + +/** + * \brief Set CTC Scan interval for slow mode or fast mode. + * \param scan_interval: scan interval in units of 1s/1.024KHz (= 0.9765625 ms) + * Configurable range: 0x0~0xFFF (0~4095) + * Note that slow mode interval should not be lower then fast mode interval, + * Fast mode interval should be greater then total guard time for auxADC + * \param CTCMode: CTC_SLOW_MODE or CTC_FAST_MODE. + * \return ture: success, false: interval is out of range. + */ +bool CTC_SetScanInterval(uint16_t scan_interval, E_CTC_MODE CTCMode); + +/** + * \brief Get touch active count from specified channel under fast mode. + * \param channel: specified channel + * \return touch active count + */ +uint16_t CTC_GetChannelTouchCount(E_CTC_CH channel); + +/** + * \brief Get Cap Touch baseline init status. + * \return Cap Touch enable status. 1: Baseline initial, 0: Baseline initial done. + */ +__STATIC_INLINE FlagStatus CTC_GetBaselineInistatus(void) +{ + return (FlagStatus)((CTC->CR & BIT8) >> 8); +} + +/** + * \brief Get Cap Touch enable status. + * \return Cap Touch enable status. 1: Running, 0: Non-runnung. + */ +__STATIC_INLINE bool CTC_IsRunning(void) +{ + return (CTC->CR & BIT0); +} + +/** + * \brief Read Cap Touch mode. + * \retval Cap Touch mode. 1: Fast mode, 0: Slow mode + */ +__STATIC_INLINE bool CTC_IsFastMode(void) +{ + return (CTC_FAST->TOUCH_SR & BIT8) >> 8; +} + +/** + * \brief Check legality of specified channel. + * \param channel: specified channel. + * \return 1: Allowed, 0: Not allowed. + */ +__STATIC_INLINE bool CTC_IsChannelAllowed(E_CTC_CH channel) +{ + return (channel <= CTC_CH_MAX); +} + +/** + * \brief Set relative touch threshold for related channel. + * \param channel: specified channel + * \param threshold: related threshold value. + * \return None + */ +__STATIC_INLINE void CTC_SetCHDifferenceThd(CTC_ChannelTypeDef *CTC_Channelx, uint16_t threshold) +{ + /* Check the parameters */ +// configASSERT(CTC_IsChAllowed(channel)); +// configASSERT(threshold <= 4095); +// configASSERT(!CTC_IsRunning()); + + CTC_Channelx->CR |= (uint32_t)threshold << 16; +} + +/** + * \brief Get absolute threshold of touch judgement for specified channel. + * \param channel: specified channel + * \param threshold: Threshold value + * \return None + */ +__STATIC_INLINE void CTC_SetCHAbsoluteThd(CTC_ChannelTypeDef *CTC_Channelx, uint16_t threshold) +{ + /* Check the parameters */ +// configASSERT(CTC_IsChAllowed(channel)); +// configASSERT(threshold <= 4095); +// configASSERT(!CTC_IsRunning()); + + CTC_Channelx->TOUCH_TH |= threshold & 0xFFF; +} + +/** + * \brief Set P noise threshold for related channel. + * \param channel: specified channel + * \param p_noise_threshold: Pnoise Threshold value. + * \retval None + */ +__STATIC_INLINE void CTC_SetCHPNoiseThd(CTC_ChannelTypeDef *CTC_Channelx, uint8_t p_noise_threshold) +{ + /* Check the parameters */ +// configASSERT(CTC_IsChAllowed(channel)); +// configASSERT(p_noise_threshold <= 255); +// configASSERT(!CTC_IsRunning()); + + CTC_Channelx->TOUCH_TH |= (uint32_t)p_noise_threshold << 16; +} + +/** + * \brief Set N noise threshold for related channel. + * \param channel: specified channel + * \param n_noise_threshold: Nnoise Threshold value. + * \return None + */ +__STATIC_INLINE void CTC_SetCHNNoiseThd(CTC_ChannelTypeDef *CTC_Channelx, uint8_t n_noise_threshold) +{ + /* Check the parameters */ +// configASSERT(CTC_IsChAllowed(channel)); +// configASSERT(n_noise_threshold <= 255); +// configASSERT(!CTC_IsRunning()); + + CTC_Channelx->TOUCH_TH |= (uint32_t)n_noise_threshold << 24; +} + +/** + * \brief Set mbias current for specified channel. + * \param channel: specified channel + * \param mbias: mbias value, relate current = 0.25*mbias. + * \return None. + */ +__STATIC_INLINE void CTC_SetChannelMbias(CTC_ChannelTypeDef *CTC_Channelx, uint8_t mbias) +{ +// /* Check the parameters */ +// configASSERT(CTC_IsChAllowed(channel)); +// configASSERT(mbias < 64); +// configASSERT(!CTC_IsRunning()); + + CTC_Channelx->MBIAS |= mbias & 0x3F; +} + +/** + * \brief Get status for specified channel. + * \param channel: specified channel + * \return channel enable status. + */ +__STATIC_INLINE FlagStatus CTC_GetChannelStatus(CTC_ChannelTypeDef *CTC_Channelx) +{ + return (FlagStatus)(CTC_Channelx->CR & 0x1); +} + +/** + * \brief Get Baseline data from specified channel. + * \param channel: Specified channel. + * \return Baseline data. + */ +__STATIC_INLINE uint16_t CTC_GetChannelBaseline(CTC_ChannelTypeDef *CTC_Channelx) +{ + return ((CTC_Channelx->CR & 0xFFF0) >> 4); +} + +/** + * \brief Get relative threshold of touch judgement for specified channel. + * \param channel: specified channel + * \return Difference threshold of specified channel. + */ +__STATIC_INLINE uint16_t CTC_GetCHDifferenceThd(CTC_ChannelTypeDef *CTC_Channelx) +{ + return ((CTC_Channelx->CR >> 16) & 0xFFF); +} + +/** + * \brief Get Absolute threshold of touch judgement for specified channel. + * \param channel: specified channel + * \return Difference threshold of specified channel. + */ +__STATIC_INLINE uint16_t CTC_GetCHAbsoluteThd(CTC_ChannelTypeDef *CTC_Channelx) +{ + return (CTC_Channelx->TOUCH_TH & 0xFFF); +} + +/** + * \brief Get positive noise threshold for specified channel. + * \param CTC_Channelx: specified channel + * \return Noise threshold of specified channel. + */ +__STATIC_INLINE uint8_t CTC_GetCHPNoiseThd(CTC_ChannelTypeDef *CTC_Channelx) +{ + return ((CTC_Channelx->TOUCH_TH >> 16) & 0xFF); +} + +/** + * \brief Get negative noise threshold for specified channel. + * \param CTC_Channelx: specified channel + * \return Noise threshold of specified channel. + */ +__STATIC_INLINE uint8_t CTC_GetCHNNoiseThd(CTC_ChannelTypeDef *CTC_Channelx) +{ + return ((CTC_Channelx->TOUCH_TH >> 24) & 0xFF); +} + +/** + * \brief Get ave data from specified channel. + * \param channel: specified channel + * \retval Average data + */ +__STATIC_INLINE uint16_t CTC_GetChannelAveData(CTC_ChannelTypeDef *CTC_Channelx) +{ + return (CTC_Channelx->DATA & 0xFFF); +} + +/** + * \brief Get Cap Touch status under fast mode. + * \param[in] channel: Specifies the Cap Touch channel. + * This parameter can be one of the following values: + * \arg CTC_CH3: Channel 3. + * \arg CTC_CH2: Channel 2. + * \arg CTC_CH1: Channel 1. + * \arg CTC_CH0: Channel 0. + * \return The new state of the Cap Touch channel(SET or RESET). bit4~bit0 each bit represent one channel. + * \retval SET: tounch. + * \retval RESET: un-tounch. + */ +__STATIC_INLINE FlagStatus CTC_GetChannelTouchStatus(E_CTC_CH channel) +{ + if (CTC_IsFastMode()) + { + return (FlagStatus)((CTC_FAST->TOUCH_SR & 0xF) >> (uint8_t)channel); + } + else + { + return RESET; + } +} + +/** + * \brief Check whether the Cap Touch interrupt has occurred or not. + * \param[in] CTCx: The Cap Touch peripheral. + * \param[in] CTC_INT: Specifies the Cap Touch interrupt has occurred or not. + * This parameter can be any combination of the following values: + * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt. + * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt + * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel 1 release interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel 0 release interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH1: Channel 1 press interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH0: Channel 0 press interrupt. + * \return The new state of the CTC_INT(SET or RESET). + * + * Example usage + * \code{.c} + * + * void cap_touch_demo(void) + * { + * ITStatus int_status = CTC_GetINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH1); + * } + * \endcode + */ +__STATIC_INLINE ITStatus CTC_GetINTStatus(CTC_TypeDef *CTCx, uint32_t CTC_INT) +{ + /* Check the parameters */ + assert_param(IS_CTC_ALL_PERIPH(CTCx)); + + ITStatus itstatus = RESET; + + if (CTCx->INT_SR & (CTC_INT)) + { + itstatus = SET; + } + + return itstatus; +} + +/** + * \brief Get CTC Raw Interrupt (without hardware mask) Status. + * \param[in] CTCx: The Cap Touch peripheral. + * \param[in] CTC_INT: Specifies the Cap Touch interrupt has occurred or not. + * This parameter can be any combination of the following values: + * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt. + * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt + * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel 1 release interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel 0 release interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH1: Channel 1 press interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH0: Channel 0 press interrupt. + * \return Raw interrupt status of the CTC_INT(SET or RESET). + * + * Example usage + * \code{.c} + * + * void cap_touch_demo(void) + * { + * ITStatus int_status = CTC_GetRawINTStatus(CTC, CTC_INT_TOUCH_PRESS_CH1); + * } + * \endcode + */ +__STATIC_INLINE ITStatus CTC_GetRawINTStatus(CTC_TypeDef *CTCx, uint32_t CTC_INT) +{ + /* Check the parameters */ + assert_param(IS_CTC_ALL_PERIPH(CTCx)); + + ITStatus itstatus = RESET; + + if (CTCx->RAW_INT_SR & (CTC_INT)) + { + itstatus = SET; + } + + return itstatus; +} + +/** + * \brief Clear CTC interrupt. + * \param[in] CTCx: The Cap Touch peripheral. + * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt. + * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt + * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void cap_touch_demo(void) + * { + * CTC_ClearINTPendingBit(CTC, CTC_INT_TOUCH_PRESS_CH0); + * } + * \endcode + */ +__STATIC_INLINE void CTC_ClearINTPendingBit(CTC_TypeDef *CTCx, uint32_t CTC_INT) +{ + /* Check the parameters */ + assert_param(IS_CTC_ALL_PERIPH(CTCx)); + + /* Clear the IT */ + CTCx->INT_SCLR |= CTC_INT; +} + +/** + * \brief Clear ALL CTC interrupt. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void cap_touch_demo(void) + * { + * CTC_ClearAllINT(); + * } + * \endcode + */ +__STATIC_INLINE void CTC_ClearAllINT(void) +{ + /* Clear the IT */ + CTC->INT_CLR |= BIT0; +} +/** \} */ /* End of group CODEC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_CAPTOUCH_H_ */ + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/peripheral/rtl876x_codec.h b/inc/peripheral/rtl876x_codec.h new file mode 100644 index 0000000..99475f8 --- /dev/null +++ b/inc/peripheral/rtl876x_codec.h @@ -0,0 +1,719 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_codec.h +* \brief The header file of the peripheral CODEC driver. +* \details This file provides all CODEC firmware functions. +* \author Yuan +* \date 2020-11-16 +* \version v2.1.1 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_CODEC_H_ +#define _RTL876X_CODEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup CODEC CODEC + * + * \brief Manage the CODEC peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup CODEC_Exported_Types Init Params Struct + * + * \ingroup CODEC + */ + +/** + * \brief CODEC init structure definition. + * + * \ingroup CODEC_Exported_Types + */ +typedef struct +{ + /* Basic parameters section */ + uint32_t CODEC_SampleRate; /*!< Specifies the sample rate. */ + uint32_t CODEC_DmicClock; /*!< Specifies the dmic clock. */ + uint32_t CODEC_I2SFormat; /*!< Specifies the I2S Tx/Rx format of codec port. */ + uint32_t CODEC_I2SDataWidth; /*!< Specifies the I2S Tx/Rx data width of codec port. */ + uint32_t CODEC_I2SChSequence; /*!< Specifies the I2S Tx/Rx channel sequence. */ + uint32_t CODEC_MicBIAS; /*!< Specifies the MICBIAS voltage. */ + uint32_t CODEC_MicBstGain; /*!< Specifies the MICBST gain. */ + uint32_t CODEC_MicBstMode; /*!< Specifies the MICBST mode. */ + + /* MIC channel 0 initialization parameters section */ + uint32_t CODEC_Ch0Mute; /*!< Specifies the channel 0 dmic mute status. */ + uint32_t CODEC_Ch0MicType; /*!< Specifies the channel 0 mic type, which can be dmic or amic. */ + uint32_t CODEC_Ch0DmicDataLatch; /*!< Specifies the channel 0 dmic data latch type. */ + uint32_t CODEC_Ch0AdGain; /*!< Specifies the channel 0 ADC digital volume. */ + uint32_t CODEC_Ch0BoostGain; /*!< Specifies the channel 0 boost gain. */ + uint32_t CODEC_Ch0ZeroDetTimeout; /*!< Specifies the channel 0 zero detection timeout mode control. */ + +} CODEC_InitTypeDef; + +/*============================================================================* + * Register Defines + *============================================================================*/ + +/* Peripheral: CODEC */ +/* Description: CODEC register defines */ + +/* Register: ANA_CR0 ----------------------------------------------------------*/ +/* Description: Control register 0. Offset: 0x00. Address: 0x40022000UL. */ + +/* ANA_CR0[10]: ADC_ANA_POW. 0x1: Powen on. 0x0: Power down. */ +#define CODEC_ADC_ANA_POW_POS (10) +#define CODEC_ADC_ANA_POW_MSK (0x1 << CODEC_ADC_ANA_POW_POS) +#define CODEC_ADC_ANA_POW_CLR (~CODEC_ADC_ANA_POW_MSK) +/* ANA_CR0[9]: DTSDM_CLK_EN. 0x1: Powen on. 0x0: Power down. */ +#define CODEC_DTSDM_CLK_EN_POS (9) +#define CODEC_DTSDM_CLK_EN_MSK (0x1 << CODEC_DTSDM_CLK_EN_POS) +#define CODEC_DTSDM_CLK_EN_CLR (~CODEC_DTSDM_CLK_EN_MSK) +/* ANA_CR0[0]: DAC_ADDACK_POW. 0x1: Powen on. 0x0: Power down. */ +#define CODEC_DAC_ADDACK_POW_POS (0) +#define CODEC_DAC_ADDACK_POW_MSK (0x1 << CODEC_DAC_ADDACK_POW_POS) +#define CODEC_DAC_ADDACK_POW_CLR (~CODEC_DAC_ADDACK_POW_MSK) + +/* Register: ANA_CR1 ----------------------------------------------------------*/ +/* Description: Control register 1. Offset: 0x04. Address: 0x40022004UL. */ + +/* ANA_CR1[27:26]: VREF_SEL. */ +#define CODEC_VREF_SEL_POS (26) +#define CODEC_VREF_SEL_MSK (0x3 << CODEC_VREF_SEL_POS) +#define CODEC_VREF_SEL_CLR (~CODEC_VREF_SEL_MSK) +#define CODEC_VREF_SEL_DEFALUT_MSK (0x2 << CODEC_VREF_SEL_POS) +/* ANA_CR1[25]: MICBST_POW. */ +#define CODEC_MICBST_POW_POS (25) +#define CODEC_MICBST_POW_MSK (0x1 << CODEC_MICBST_POW_POS) +#define CODEC_MICBST_POW_CLR (~CODEC_MICBST_POW_MSK) +/* ANA_CR1[21:20]: MICBST_MUTE. */ +#define CODEC_MICBST_MUTE_POS (20) +#define CODEC_MICBST_MUTE_MSK (0x3 << CODEC_MICBST_MUTE_POS) +#define CODEC_MICBST_MUTE_CLR (~CODEC_MICBST_MUTE_MSK) +#define CODEC_MICBST_MUTE_MIC_MSK (0x2 << CODEC_MICBST_MUTE_POS) +/* ANA_CR1[17:16]: MICBST_GAIN. */ +#define CODEC_MICBST_GAIN_POS (16) +#define CODEC_MICBST_GAIN_MSK (0x3 << CODEC_MICBST_GAIN_POS) +#define CODEC_MICBST_GAIN_CLR (~CODEC_MICBST_GAIN_MSK) +/* ANA_CR1[15]: MICBST_VREF_POW. */ +#define CODEC_MICBST_VREF_POW_POS (15) +#define CODEC_MICBST_VREF_POW_MSK (0x1 << CODEC_MICBST_VREF_POW_POS) +#define CODEC_MICBST_VREF_POW_CLR (~CODEC_MICBST_VREF_POW_MSK) +/* ANA_CR1[14]: MICBST_ENDFL. */ +#define CODEC_MICBST_ENDFL_POS (14) +#define CODEC_MICBST_ENDFL_MSK (0x1 << CODEC_MICBST_ENDFL_POS) +#define CODEC_MICBST_ENDFL_CLR (~CODEC_MICBST_ENDFL_MSK) +/* ANA_CR1[13:11]: MICBIAS_VSET. */ +#define CODEC_MICBIAS_VSET_POS (11) +#define CODEC_MICBIAS_VSET_MSK (0x7 << CODEC_MICBIAS_VSET_POS) +#define CODEC_MICBIAS_VSET_CLR (~CODEC_MICBIAS_VSET_MSK) +/* ANA_CR1[10]: MICBIAS_POW. 0x1: Powen on. 0x0: Power down. */ +#define CODEC_MICBIAS_POW_POS (10) +#define CODEC_MICBIAS_POW_MSK (0x1 << CODEC_MICBIAS_POW_POS) +#define CODEC_MICBIAS_POW_CLR (~CODEC_MICBIAS_POW_MSK) +/* ANA_CR1[9]: MICBIAS_ENCHX. */ +#define CODEC_MICBIAS_ENCHX_POS (9) +#define CODEC_MICBIAS_ENCHX_MSK (0x1 << CODEC_MICBIAS_ENCHX_POS) +#define CODEC_MICBIAS_ENCHX_CLR (~CODEC_MICBIAS_ENCHX_MSK) + +/* Register: ANA_CR2 ----------------------------------------------------------*/ +/* Description: Control register 2. Offset: 0x08. Address: 0x40022008UL. */ + +/* ANA_CR2[15]: MICBIAS_LIMIT. */ +#define CODEC_MICBIAS_LIMIT_POS (15) +#define CODEC_MICBIAS_LIMIT_MSK (0x1 << CODEC_MICBIAS_LIMIT_POS) +#define CODEC_MICBIAS_LIMIT_CLR (~CODEC_MICBIAS_LIMIT_MSK) +#define CODEC_MICBIAS_LIMIT_DEFALUT_MSK (0) + +/* ANA_CR2[14]: MICBIAS_POWSHDT. */ +#define CODEC_MICBIAS_POWSHDT_POS (14) +#define CODEC_MICBIAS_POWSHDT_MSK (0x1 << CODEC_MICBIAS_POWSHDT_POS) +#define CODEC_MICBIAS_POWSHDT_CLR (~CODEC_MICBIAS_POWSHDT_MSK) +#define CODEC_MICBIAS_POWSHDT_DEFALUT_MSK (0) + +/* ANA_CR2[13:12]: MICBIAS_OCSEL. */ +#define CODEC_MICBIAS_OCSEL_POS (12) +#define CODEC_MICBIAS_OCSEL_MSK (0x3 << CODEC_MICBIAS_OCSEL_POS) +#define CODEC_MICBIAS_OCSEL_CLR (~CODEC_MICBIAS_OCSEL_MSK) +#define CODEC_MICBIAS_OCSEL_DEFALUT_MSK (0x1 << CODEC_MICBIAS_OCSEL_POS) + +/* ANA_CR2[11:8]: MICBIAS_COUNT. */ +#define CODEC_MICBIAS_COUNT_POS (8) +#define CODEC_MICBIAS_COUNT_MSK (0xF << CODEC_MICBIAS_COUNT_POS) +#define CODEC_MICBIAS_COUNT_CLR (~CODEC_MICBIAS_COUNT_MSK) +#define CODEC_MICBIAS_COUNT_DEFALUT_MSK (0x1 << CODEC_MICBIAS_COUNT_POS) + +/* Register: CR0 --------------------------------------------------------------*/ +/* Description: audio Control register. Offset: 0x100. Address: 0x4002_2100UL. */ + +/* CR0[0]: AUDIO_IP_EN. */ +#define CODEC_AUDIO_IP_EN_POS (0) +#define CODEC_AUDIO_IP_EN_MSK (0x1 << CODEC_AUDIO_IP_EN_POS) +#define CODEC_AUDIO_IP_EN_CLR (~CODEC_AUDIO_IP_EN_MSK) + +/* Register: ANA_CR1 -----------------------------------------------------------*/ +/* Description: analog Control register. Offset: 0x104. Address: 0x4002_2104UL. */ + +/* ANA_CR1[3]: CKX_MICBIAS_EN. */ +#define CODEC_CKX_MICBIAS_EN_POS (3) +#define CODEC_CKX_MICBIAS_EN_MSK (0x1 << CODEC_CKX_MICBIAS_EN_POS) +#define CODEC_CKX_MICBIAS_EN_CLR (~CODEC_CKX_MICBIAS_EN_MSK) + +/* Register: CLK_CR1 ----------------------------------------------------------*/ +/* Description: clock Control register. Offset: 0x108. Address: 0x4002_2108UL. */ + +/* CLK_CR1[12]: AD_FILTER_CH0_CLK. 0x1: Enable clock. 0x0: Disable clock. */ +#define CODEC_AD_FILTER_CH0_CLK_POS (12) +#define CODEC_AD_FILTER_CH0_CLK_MSK (0x1 << CODEC_AD_FILTER_CH0_CLK_POS) +#define CODEC_AD_FILTER_CH0_CLK_CLR (~CODEC_AD_FILTER_CH0_CLK_MSK) +/* CLK_CR1[11]: AD_ANA_CLK_EN. 0x1: Enable ADC analog clock. 0x0: Disable ADC analog clock. */ +#define CODEC_AD_ANA_CLK_EN_POS (11) +#define CODEC_AD_ANA_CLK_EN_MSK (0x1 << CODEC_AD_ANA_CLK_EN_POS) +#define CODEC_AD_ANA_CLK_EN_CLR (~CODEC_AD_ANA_CLK_EN_MSK) +/* CLK_CR1[10]: AD_FIFO_CLK_EN. 0x1: Enable ADC FIFO clock. 0x0: Disable ADC FIFO clock. */ +#define CODEC_AD_FIFO_CLK_EN_POS (10) +#define CODEC_AD_FIFO_CLK_EN_MSK (0x1 << CODEC_AD_FIFO_CLK_EN_POS) +#define CODEC_AD_FIFO_CLK_EN_CLR (~CODEC_AD_FIFO_CLK_EN_MSK) +/* CLK_CR1[6]: AD_CH0_CLK. 0x1: Enable clock. 0x0: Disable clock. */ +#define CODEC_AD_CH0_CLK_POS (6) +#define CODEC_AD_CH0_CLK_MSK (0x1 << CODEC_AD_CH0_CLK_POS) +#define CODEC_AD_CH0_CLK_CLR (~CODEC_AD_CH0_CLK_MSK) + +/* Register: CLK_CR2 ----------------------------------------------------------*/ +/* Description: clock Control register. Offset: 0x10C. Address: 0x4002_210CUL. */ + +/* CLK_CR2[4]: DMIC1_CLK_SRC. 0x1: 8M. 0x0: 10M. */ +#define CODEC_DMIC1_CLK_SRC_POS (4) +#define CODEC_DMIC1_CLK_SRC_MSK (0x1 << CODEC_DMIC1_CLK_SRC_POS) +#define CODEC_DMIC1_CLK_SRC_CLR (~CODEC_DMIC1_CLK_SRC_MSK) +/* CLK_CR2[3]: DMIC1_CLK_EN. 0x1: Enable clock. 0x0: Disable clock. */ +#define CODEC_DMIC1_CLK_EN_POS (3) +#define CODEC_DMIC1_CLK_EN_MSK (0x1 << CODEC_DMIC1_CLK_EN_POS) +#define CODEC_DMIC1_CLK_EN_CLR (~CODEC_DMIC1_CLK_EN_MSK) +/* CLK_CR2[2:0]: DMIC1_CLK_SEL. */ +#define CODEC_DMIC1_CLK_SEL_POS (0) +#define CODEC_DMIC1_CLK_SEL_MSK (0x7 << CODEC_DMIC1_CLK_SEL_POS) +#define CODEC_DMIC1_CLK_SEL_CLR (~CODEC_DMIC1_CLK_SEL_MSK) + +/* Register: CLK_CR3 ----------------------------------------------------------*/ +/* Description: clock Control register. Offset: 0x110. Address: 0x4002_2110UL. */ + +/* CLK_CR3[13:12]: AD_LPF_CLK_SEL. */ +#define CODEC_AD_LPF_CLK_SEL_POS (12) +#define CODEC_AD_LPF_CLK_SEL_MSK (0x3 << CODEC_AD_LPF_CLK_SEL_POS) +#define CODEC_AD_LPF_CLK_SEL_CLR (~CODEC_AD_LPF_CLK_SEL_MSK) +//#define CODEC_AD_LPF_CLK_SEL_DEFAULT (~CODEC_AD_LPF_CLK_SEL_MSK) + +/* CLK_CR3[10]: ADC_LATCH_PHASE. */ +#define CODEC_ADC_LATCH_PHASE_POS (10) +#define CODEC_ADC_LATCH_PHASE_MSK (0x1 << CODEC_ADC_LATCH_PHASE_POS) +#define CODEC_ADC_LATCH_PHASE_CLR (~CODEC_ADC_LATCH_PHASE_MSK) + +/* CLK_CR3[9]: AD_ANA_CLK_SEL. */ +#define CODEC_AD_ANA_CLK_SEL_POS (9) +#define CODEC_AD_ANA_CLK_SEL_MSK (0x1 << CODEC_AD_ANA_CLK_SEL_POS) +#define CODEC_AD_ANA_CLK_SEL_CLR (~CODEC_AD_ANA_CLK_SEL_MSK) + +/* CLK_CR3[8]: ANA_CLK_RATE. */ +#define CODEC_ANA_CLK_RATE_POS (8) +#define CODEC_ANA_CLK_RATE_MSK (0x1 << CODEC_ANA_CLK_RATE_POS) +#define CODEC_ANA_CLK_RATE_CLR (~CODEC_ANA_CLK_RATE_MSK) + +/* CLK_CR3[3:0]: SAMPLE_RATE. */ +#define CODEC_SAMPLE_RATE_POS (0) +#define CODEC_SAMPLE_RATE_MSK (0xF << CODEC_SAMPLE_RATE_POS) +#define CODEC_SAMPLE_RATE_CLR (~CODEC_SAMPLE_RATE_MSK) + +/* Register: I2S_CTRL -------------------------------------------------------*/ +/* Description: I2S Control register. Offset: 0x11C. Address: 0x4002_211CUL. */ + +/* I2S_CTRL[19:18]: I2S_RX_CH. */ +#define CODEC_I2S_RX_CH_POS (18) +#define CODEC_I2S_RX_CH_MSK (0x3 << CODEC_I2S_RX_CH_POS) +#define CODEC_I2S_RX_CH_CLR (~CODEC_I2S_RX_CH_MSK) +/* I2S_CTRL[15:14]: I2S_RX_DATA_LEN. */ +#define CODEC_I2S_RX_DATA_LEN_POS (14) +#define CODEC_I2S_RX_DATA_LEN_MSK (0x3 << CODEC_I2S_RX_DATA_LEN_POS) +#define CODEC_I2S_RX_DATA_LEN_CLR (~CODEC_I2S_RX_DATA_LEN_MSK) +/* I2S_CTRL[11:10]: I2S_RX_DATA_FORMAT. */ +#define CODEC_I2S_RX_DATA_FORMAT_POS (10) +#define CODEC_I2S_RX_DATA_FORMAT_MSK (0x3 << CODEC_I2S_RX_DATA_FORMAT_POS) +#define CODEC_I2S_RX_DATA_FORMAT_CLR (~CODEC_I2S_RX_DATA_FORMAT_MSK) +/* I2S_CTRL[2]: I2S_SELF_LPBK. */ +#define CODEC_I2S_SELF_LPBK_POS (2) +#define CODEC_I2S_SELF_LPBK_MSK (0x1 << CODEC_I2S_SELF_LPBK_POS) +#define CODEC_I2S_SELF_LPBK_CLR (~CODEC_I2S_SELF_LPBK_MSK) +/* I2S_CTRL[1]: I2S_INV_SCLK. */ +#define CODEC_I2S_INV_SCLK_POS (1) +#define CODEC_I2S_INV_SCLK_MSK (0x1 << CODEC_I2S_INV_SCLK_POS) +#define CODEC_I2S_INV_SCLK_CLR (~CODEC_I2S_INV_SCLK_MSK) +/* I2S_CTRL[0]: AUDIO_RST_N. 0x1: Powen on. 0x0: Power down. */ +#define CODEC_AUDIO_RST_N_POS (0) +#define CODEC_AUDIO_RST_N_MSK (0x1 << CODEC_AUDIO_RST_N_POS) +#define CODEC_AUDIO_RST_N_CLR (~CODEC_AUDIO_RST_N_MSK) + +/* Register: ADC0_CTRL0 -------------------------------------------------------*/ +/* Description: ADC0 Control register. Offset: 0x120. Address: 0x4002_2120UL. */ + +/* ADC0_CTRL0[19:17]: ADC0_DCHPF_FC_SEL. */ +#define CODEC_ADC0_DCHPF_FC_SEL_POS (17) +#define CODEC_ADC0_DCHPF_FC_SEL_MSK (0x7 << CODEC_ADC0_DCHPF_FC_SEL_POS) +#define CODEC_ADC0_DCHPF_FC_SEL_CLR (~CODEC_ADC0_DCHPF_FC_SEL_MSK) + +/* ADC0_CTRL0[16]: ADC0_DCHPF_EN. 0x1: enable. 0x0: disable. */ +#define CODEC_ADC0_DCHPF_EN_POS (16) +#define CODEC_ADC0_DCHPF_EN_MSK (0x1 << CODEC_ADC0_DCHPF_EN_POS) +#define CODEC_ADC0_DCHPF_EN_CLR (~CODEC_ADC0_DCHPF_EN_MSK) + +/* ADC0_CTRL0[15]: AMIC_DMIC_CH0_SEL. 0x1: ADC path. 0x0: DMIC path. */ +#define CODEC_AMIC_DMIC_CH0_SEL_POS (15) +#define CODEC_AMIC_DMIC_CH0_SEL_MSK (0x1 << CODEC_AMIC_DMIC_CH0_SEL_POS) +#define CODEC_AMIC_DMIC_CH0_SEL_CLR (~CODEC_AMIC_DMIC_CH0_SEL_MSK) + +/* ADC0_CTRL0[14:13]: ADC_CH0_BOOST_GAIN. */ +#define CODEC_ADC_CH0_BOOST_GAIN_POS (13) +#define CODEC_ADC_CH0_BOOST_GAIN_MSK (0x3 << CODEC_ADC_CH0_BOOST_GAIN_POS) +#define CODEC_ADC_CH0_BOOST_GAIN_CLR (~CODEC_ADC_CH0_BOOST_GAIN_MSK) + +/* ADC0_CTRL0[12]: ADC_CH0_AD_MUTE. */ +#define CODEC_ADC_CH0_AD_MUTE_POS (12) +#define CODEC_ADC_CH0_AD_MUTE_MSK (0x1 << CODEC_ADC_CH0_AD_MUTE_POS) +#define CODEC_ADC_CH0_AD_MUTE_CLR (~CODEC_ADC_CH0_AD_MUTE_MSK) + +/* ADC0_CTRL0[11:10]: ADC_CH0_ZDET_TOUT. */ +#define CODEC_ADC_CH0_ZDET_TOUT_POS (10) +#define CODEC_ADC_CH0_ZDET_TOUT_MSK (0x3 << CODEC_ADC_CH0_ZDET_TOUT_POS) +#define CODEC_ADC_CH0_ZDET_TOUT_CLR (~CODEC_ADC_CH0_ZDET_TOUT_MSK) + +/* ADC0_CTRL0[9:8]: ADC_CH0_ZDET_FUN. 0x1: ADC path. 0x0: DMIC path. */ +#define CODEC_ADC_CH0_ZDET_FUN_POS (8) +#define CODEC_ADC_CH0_ZDET_FUN_MSK (0x3 << CODEC_ADC_CH0_ZDET_FUN_POS) +#define CODEC_ADC_CH0_ZDET_FUN_CLR (~CODEC_ADC_CH0_ZDET_FUN_MSK) +#define CODEC_ADC_CH0_ZDET_FUN_DEFAULT_MSK (0x1 << CODEC_ADC_CH0_ZDET_FUN_POS) + +/* ADC0_CTRL0[7:6]: ADC0_AD_LPF1ST_FC_SEL. */ +#define CODEC_ADC0_AD_LPF1ST_FC_SEL_POS (6) +#define CODEC_ADC0_AD_LPF1ST_FC_SEL_MSK (0x3 << CODEC_ADC0_AD_LPF1ST_FC_SEL_POS) +#define CODEC_ADC0_AD_LPF1ST_FC_SEL_CLR (~CODEC_ADC0_AD_LPF1ST_FC_SEL_MSK) + +/* ADC0_CTRL0[5]: ADC0_AD_LPF1ST_EN. 0x1: enable. 0x0: disable. */ +#define CODEC_ADC0_AD_LPF1ST_EN_POS (5) +#define CODEC_ADC0_AD_LPF1ST_EN_MSK (0x1 << CODEC_ADC0_AD_LPF1ST_EN_POS) +#define CODEC_ADC0_AD_LPF1ST_EN_CLR (~CODEC_ADC0_AD_LPF1ST_EN_MSK) + +/* ADC0_CTRL0[4]: ADC0_AD_LPF2ND_EN. 0x1: enable. 0x0: disable. */ +#define CODEC_ADC0_AD_LPF2ND_EN_POS (4) +#define CODEC_ADC0_AD_LPF2ND_EN_MSK (0x1 << CODEC_ADC0_AD_LPF2ND_EN_POS) +#define CODEC_ADC0_AD_LPF2ND_EN_CLR (~CODEC_ADC0_AD_LPF2ND_EN_MSK) + +/* ADC0_CTRL0[1:0]: ADC0_DMIC_SRC_SEL. */ +#define CODEC_ADC0_DMIC_SRC_SEL_POS (0) +#define CODEC_ADC0_DMIC_SRC_SEL_MSK (0x3 << CODEC_ADC0_DMIC_SRC_SEL_POS) +#define CODEC_ADC0_DMIC_SRC_SEL_CLR (~CODEC_ADC0_DMIC_SRC_SEL_MSK) + +#define CODEC_ADC0_CTRL0_REG_DEFAULT_MSK ((0x2 << 17) | (0x01 << 16) | (0x01 << 10) | (0x02 << 8) | (0x03 <<4)) + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup CODEC_Exported_Constants Macro Definitions + * + * \ingroup CODEC + */ + +#define IS_CODEC_PERIPH(PERIPH) ((PERIPH) == CODEC) + +/** + * \defgroup MICBST_Gain MICBST Gain + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define MICBST_Gain_0dB ((uint32_t)(0x0)) +#define MICBST_Gain_20dB ((uint32_t)(0x1 << CODEC_MICBST_GAIN_POS)) +#define MICBST_Gain_30dB ((uint32_t)(0x2 << CODEC_MICBST_GAIN_POS)) +#define MICBST_Gain_40dB ((uint32_t)(0x3 << CODEC_MICBST_GAIN_POS)) +/** \} */ +#define IS_MICBST_GAIN(GAIN) (((GAIN) == MICBST_Gain_0dB) || \ + ((GAIN) == MICBST_Gain_20dB) || \ + ((GAIN) == MICBST_Gain_30dB) || \ + ((GAIN) == MICBST_Gain_40dB)) + +/** + * \defgroup MICBST_Mode MICBST Mode + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define MICBST_Mode_Single ((uint32_t)(0x0)) +#define MICBST_Mode_Differential ((uint32_t)CODEC_MICBST_ENDFL_MSK) +/** \} */ +#define IS_MICBST_MODE(MODE) (((MODE) == MICBST_Mode_Single) || \ + ((MODE) == MICBST_Mode_Differential)) + +/** + * \defgroup CODEC_MIC_BIAS_Config CODEC MIC BIAS Config + * \{ + * \ingroup CODEC_Exported_Constants + */ + +#define MICBIAS_VOLTAGE_1_507 ((uint32_t)(0x00)) +#define MICBIAS_VOLTAGE_1_62 ((uint32_t)(0x01 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_1_705 ((uint32_t)(0x02 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_1_8 ((uint32_t)(0x03 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_1_906 ((uint32_t)(0x04 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_2_025 ((uint32_t)(0x05 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_2_16 ((uint32_t)(0x06 << CODEC_MICBIAS_VSET_POS)) +#define MICBIAS_VOLTAGE_2_314 ((uint32_t)(0x07 << CODEC_MICBIAS_VSET_POS)) +/** \} */ + +#define IS_MICBIAS_CONFIG(CONFIG) (((CONFIG) == MICBIAS_VOLTAGE_1_507) || ((CONFIG) == MICBIAS_VOLTAGE_1_62) || \ + ((CONFIG) == MICBIAS_VOLTAGE_1_705) || ((CONFIG) == MICBIAS_VOLTAGE_1_8) || \ + ((CONFIG) == MICBIAS_VOLTAGE_1_906) || ((CONFIG) == MICBIAS_VOLTAGE_2_025) || \ + ((CONFIG) == MICBIAS_VOLTAGE_2_16) || ((CONFIG) == MICBIAS_VOLTAGE_2_314)) + +/** + * \defgroup Sample_Rate_Definition Sample Rate Definition + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define SAMPLE_RATE_48KHz ((uint32_t)(0x00 << CODEC_SAMPLE_RATE_POS)) +#define SAMPLE_RATE_32KHz ((uint32_t)(0x03 << CODEC_SAMPLE_RATE_POS)) +#define SAMPLE_RATE_16KHz ((uint32_t)(0x05 << CODEC_SAMPLE_RATE_POS)) +#define SAMPLE_RATE_8KHz ((uint32_t)(0x07 << CODEC_SAMPLE_RATE_POS)) +#define SAMPLE_RATE_44_1KHz ((uint32_t)(0x08 << CODEC_SAMPLE_RATE_POS)) +/** \} */ + +#define IS_SAMPLE_RATE(RATE) (((RATE) == SAMPLE_RATE_16KHz) || \ + ((RATE) == SAMPLE_RATE_8KHz) || \ + ((RATE) == SAMPLE_RATE_32KHz) || \ + ((RATE) == SAMPLE_RATE_48KHz) || \ + ((RATE) == SAMPLE_RATE_44_1KHz))) + +/** + * \defgroup CODEC_I2S_CH CODEC I2S CH + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define CODEC_I2S_CH_L_R ((uint32_t)(0x00)) +#define CODEC_I2S_CH_R_L ((uint32_t)(0x01 << CODEC_I2S_RX_CH_POS)) +#define CODEC_I2S_CH_L_L ((uint32_t)(0x02 << CODEC_I2S_RX_CH_POS)) +#define CODEC_I2S_CH_R_R ((uint32_t)(0x03 << CODEC_I2S_RX_CH_POS)) +/** \} */ + +#define IS_CODEC_I2S_CH(CH) (((CH) == CODEC_I2S_CH_L_R) || \ + ((CH) == CODEC_I2S_CH_R_L) || \ + ((CH) == CODEC_I2S_CH_L_L) || \ + ((CH) == CODEC_I2S_CH_R_R)) + +/** + * \defgroup I2S_Data_Width I2S Data Width + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define CODEC_I2S_DataWidth_16Bits ((uint32_t)(0x00)) +#define CODEC_I2S_DataWidth_24Bits ((uint32_t)(0x02 << CODEC_I2S_RX_DATA_LEN_POS) +#define CODEC_I2S_DataWidth_8Bits ((uint32_t)(0x03 << CODEC_I2S_RX_DATA_LEN_POS) +/** \} */ +#define IS_CODEC_I2S_DATA_WIDTH(WIDTH) (((WIDTH) == CODEC_I2S_DataWidth_16Bits) || \ + ((WIDTH) == CODEC_I2S_DataWidth_24Bits) || \ + ((WIDTH) == CODEC_I2S_DataWidth_8Bits)) + +/** + * \defgroup I2S_Data_Format I2S Data Format + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define CODEC_I2S_DataFormat_I2S ((uint32_t)(0x00)) +#define CODEC_I2S_DataFormat_LeftJustified ((uint32_t)(0x01 << CODEC_I2S_RX_DATA_FORMAT_POS) +#define CODEC_I2S_DataFormat_PCM_A ((uint32_t)(0x02 << CODEC_I2S_RX_DATA_FORMAT_POS) +#define CODEC_I2S_DataFormat_PCM_B ((uint32_t)(0x03 << CODEC_I2S_RX_DATA_FORMAT_POS) +/** \} */ + +#define IS_CODEC_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == CODEC_I2S_DataFormat_I2S) || \ + ((FORMAT) == CODEC_I2S_DataFormat_LeftJustified) || \ + ((FORMAT) == CODEC_I2S_DataFormat_PCM_A) || \ + ((FORMAT) == CODEC_I2S_DataFormat_PCM_B)) + +/** + * \defgroup DMIC_Clock_Type_Definition DMIC Clock Type Definition + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define DMIC_Clock_5MHz ((uint32_t)(0x0)) +#define DMIC_Clock_2500KHz ((uint32_t)(0x01 << CODEC_DMIC1_CLK_SEL_POS)) +#define DMIC_Clock_1250KHz ((uint32_t)(0x02 << CODEC_DMIC1_CLK_SEL_POS)) +#define DMIC_Clock_625KHz ((uint32_t)(0x03 << CODEC_DMIC1_CLK_SEL_POS)) +#define DMIC_Clock_312500Hz ((uint32_t)(0x04 << CODEC_DMIC1_CLK_SEL_POS)) +/** \} */ + +#define IS_CODEC_DMIC_CLOCK(CLOCK) (((CLOCK) == DMIC_Clock_5MHz) || ((CLOCK) == DMIC_Clock_2500KHz) || \ + ((CLOCK) == DMIC_Clock_1250KHz) || ((CLOCK) == DMIC_Clock_625KHz) || \ + ((CLOCK) == DMIC_Clock_312500Hz)) + +/** + * \defgroup CODEC_Ch0_Mic_Type CODEC Ch0 Mic Type + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define CODEC_CH0_AMIC (CODEC_AMIC_DMIC_CH0_SEL_MSK) +#define CODEC_CH0_DMIC (0) +/** \} */ + +#define IS_CODEC_CH0_MIC_TYPE(TYPE) (((TYPE) == CODEC_CH0_AMIC) || ((TYPE) == CODEC_CH0_DMIC)) + +/** + * \defgroup Ch0_Boost_Gain Ch0 Boost Gain + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define Ch0_Boost_Gain_0dB ((uint32_t)(0x0)) +#define Ch0_Boost_Gain_12dB ((uint32_t)(0x1 << CODEC_ADC_CH0_BOOST_GAIN_POS)) +#define Ch0_Boost_Gain_24dB ((uint32_t)(0x2 << CODEC_ADC_CH0_BOOST_GAIN_POS)) +#define Ch0_Boost_Gain_36dB ((uint32_t)(0x3 << CODEC_ADC_CH0_BOOST_GAIN_POS)) +/** \} */ + +#define IS_CH0_BOOST_GAIN(GAIN) (((GAIN) == Ch0_Boost_Gain_0dB) || \ + ((GAIN) == Ch0_Boost_Gain_12dB) || \ + ((GAIN) == Ch0_Boost_Gain_24dB) || \ + ((GAIN) == Ch0_Boost_Gain_36dB)) + +/** + * \defgroup CODEC_Ch0_Mute CODEC Ch0 Mute + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define CODEC_CH0_MUTE (CODEC_ADC_CH0_AD_MUTE_MSK) +#define CODEC_CH0_UNMUTE (0) +/** \} */ + +#define IS_CODEC_CH0_MIC_MUTE(MUTE) (((MUTE) == CODEC_CH0_MUTE) || ((MUTE) == CODEC_CH0_UNMUTE)) + +/** + * \defgroup Ch0_ADC_Zero_Detection_Timeout Ch0 ADC Zero Detection Timeout + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define Ch0_ADC_Zero_DetTimeout_1024_16_Sample ((uint32_t)(0x00)) +#define Ch0_ADC_Zero_DetTimeout_1024_32_Sample ((uint32_t)(0x01 << CODEC_ADC_CH0_ZDET_TOUT_POS)) +#define Ch0_ADC_Zero_DetTimeout_1024_64_Sample ((uint32_t)(0x02 << CODEC_ADC_CH0_ZDET_TOUT_POS)) +#define Ch0_ADC_Zero_DetTimeout_64_Sample ((uint32_t)(0x03 << CODEC_ADC_CH0_ZDET_TOUT_POS)) +/** \} */ + +#define IS_CH0_ADC_ZERO_DET_TIMEOUT(TIMEOUT) (((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_16_Sample) || \ + ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_32_Sample) || \ + ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_1024_64_Sample) || \ + ((TIMEOUT) == Ch0_ADC_Zero_DetTimeout_64_Sample)) + +/** + * \defgroup DMIC_Data_Latch_Edge DMIC Data Latch Edge + * \{ + * \ingroup CODEC_Exported_Constants + */ +#define DMIC_Ch0_Falling_Latch ((uint32_t)(0x01 << CODEC_ADC0_DMIC_SRC_SEL_MSK)) +#define DMIC_Ch0_Rising_Latch ((uint32_t)(0x00)) +/** \} */ + +#define IS_DMIC_CH0_LATCH_EDGE(EDGE) (((EDGE) == DMIC_Ch0_Rising_Latch) || ((EDGE) == DMIC_Ch0_Falling_Latch)) + +/** + * \def CODEC_Ad_Gain Codec Ad Gain + */ + +#define IS_AD_GAIN(GAIN) (((GAIN)<= 0x7F)) + +/** + * \def CODEC_Da_Gain Codec Da Gain + */ +#define IS_DA_GAIN(GAIN) (((GAIN)<= 0xFF)) + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup CODEC_Exported_Functions Peripheral APIs + * \{ + * \ingroup CODEC + */ + +void CODEC_AnalogCircuitInit(void); + +/** + * \brief Deinitializes the CODEC peripheral registers to their default reset values(turn off CODEC clock). + * \param[in] CODECx: CODEC peripheral selected . + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_codec_init(void) + * { + * CODEC_DeInit(CODEC); + * } + * \endcode + */ +void CODEC_DeInit(CODEC_TypeDef *CODECx); + +/** + * \brief Initializes the CODEC peripheral according to the specified + * parameters in the CODEC_InitStruct. + * \param[in] CODECx: CODEC peripheral selected. + * \param[in] CODEC_InitStruct: Pointer to a CODEC_InitTypeDef structure that + * contains the configuration information for the specified CODEC peripheral + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_codec_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE); + * + * CODEC_InitTypeDef CODEC_InitStruct; + + * CODEC_StructInit(&CODEC_InitStruct); + * CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_AMIC; + * CODEC_InitStruct.CODEC_MicBstMode = MICBST_Mode_Differential; + * CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz; + * CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S; + * CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits; + * CODEC_Init(CODEC, &CODEC_InitStruct); + * } + * \endcode + */ +void CODEC_Init(CODEC_TypeDef *CODECx, CODEC_InitTypeDef *CODEC_InitStruct); + +/** + * \brief Fills each CODEC_InitStruct member with its default value. + * \param[in] CODEC_InitStruct: Pointer to a CODEC_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_codec_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, ENABLE); + * + * CODEC_InitTypeDef CODEC_InitStruct; + + * CODEC_StructInit(&CODEC_InitStruct); + * CODEC_InitStruct.CODEC_Ch0MicType = CODEC_CH0_AMIC; + * CODEC_InitStruct.CODEC_MicBstMode = MICBST_Mode_Differential; + * CODEC_InitStruct.CODEC_SampleRate = SAMPLE_RATE_16KHz; + * CODEC_InitStruct.CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S; + * CODEC_InitStruct.CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits; + * CODEC_Init(CODEC, &CODEC_InitStruct); + * } + * \endcode + */ +void CODEC_StructInit(CODEC_InitTypeDef *CODEC_InitStruct); + +/** + * \brief Enable or disable mic_bias output. + * \param[in] CODECx: CODEC peripheral selected. + * \param[in] NewState: New state of MICBIAS. + * This parameter can be: ENABLE or DISABLE. + * \return none. + * + * Example usage + * \code{.c} + * + * void codec_demo(void) + * { + * CODEC_MICBIASCmd(CODEC, ENABLE); + * } + * \endcode + */ +void CODEC_MICBIASCmd(CODEC_TypeDef *CODECx, FunctionalState NewState); + +/** + * \brief Reset CODEC. + * \param[in] CODECx: CODEC peripheral selected. + * \return None. + * + * Example usage + * \code{.c} + * + * void codec_demo(void) + * { + * CODEC_Reset(CODEC); + * } + * \endcode + */ +__STATIC_INLINE void CODEC_Reset(CODEC_TypeDef *CODECx) +{ + /* Check the parameters */ + assert_param(IS_CODEC_PERIPH(CODECx)); + + /* CODEC IP reset */ + CODECx->CR0 &= CODEC_AUDIO_IP_EN_CLR;; + CODECx->CR0 = CODEC_AUDIO_IP_EN_MSK;; +} + +/** + * \brief Config MIC BIAS Vref voltage. + * \param[in] CODECx: CODEC peripheral selected. + * \param[in] data: New value of MIC BIAS. + * This parameter can be one of the following values: + * \arg MICBIAS_VOLTAGE_1_507: Vref voltage is 1.507V. + * \arg MICBIAS_VOLTAGE_1_62: Vref voltage is 1.62V. + * \arg MICBIAS_VOLTAGE_1_705: Vref voltage is 1.705V. + * \arg MICBIAS_VOLTAGE_1_8: Vref voltage is 1.8V. + * \arg MICBIAS_VOLTAGE_1_906: Vref voltage is 1.906V. + * \arg MICBIAS_VOLTAGE_2_025: Vref voltage is 2.025V. + * \arg MICBIAS_VOLTAGE_2_16: Vref voltage is 2.16V. + * \arg MICBIAS_VOLTAGE_2_314: Vref voltage is 2.314V. + * \return None. + * + * Example usage + * \code{.c} + * + * void codec_demo(void) + * { + * CODEC_SetMICBIAS(CODEC, MICBIAS_VOLTAGE_1_507); + * } + * \endcode + */ +__STATIC_INLINE void CODEC_SetMICBIAS(CODEC_TypeDef *CODECx, uint16_t data) + +{ + /* Check the parameters */ + assert_param(IS_CODEC_PERIPH(CODECx)); + assert_param(IS_MICBIAS_CONFIG(data)); + + CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_POW_CLR; + CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_VSET_CLR; + CODEC_ANA->ANA_CR1 |= data; +} + +/** \} */ /* End of group CODEC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_CODEC_H_ */ + + +/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_enh_tim.h b/inc/peripheral/rtl876x_enh_tim.h new file mode 100644 index 0000000..be4877c --- /dev/null +++ b/inc/peripheral/rtl876x_enh_tim.h @@ -0,0 +1,918 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_enh_tim.h +* \brief The header file of the peripheral Enhance ENHTIMER driver. +* \details This file provides all Enhance ENHTIMER firmware functions. +* \author Yuan +* \date 2020-10-19 +* \version v1.0.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_ENH_TIM_H_ +#define _RTL876X_ENH_TIM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup ENHTIM ENHTIM + * \brief Manage the ENHTIM peripheral functions. + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Constants + *============================================================================*/ + +/* ENHTIM private defines */ +#define ENHTIM_PWM_DEADZONE_CR *((volatile uint32_t *)0x40000368UL) +#define ENHTIM_LATCH_COUNT_CR *((volatile uint32_t *)0x40006028UL) + +/** + * \defgroup ENHTIM_Exported_Constants Macro Definitions + * \ingroup ENHTIM + */ +#define IS_ENHTIM_ALL_PERIPH(PERIPH) (((PERIPH) == ENH_TIM0) || \ + ((PERIPH) == ENH_TIM1)) + +/** + * \defgroup ENHTIM_Clock_Source ENHTIM Clock Source + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_TIMER_TOGGLE_OUTPUT ((uint16_t)0x1) +#define ENHTIM_DIVIDER_CLOCK ((uint16_t)0x0) +/** \} */ +#define IS_ENHTIM_CLOCK_SOURCE(src) (((src) == ENHTIM_TIMER_TOGGLE_OUTPUT) || \ + ((src) == ENHTIM_DIVIDER_CLOCK)) + +/** + * \defgroup ENHTIM_Latch_Count_En ENHTIM Latch Count Enable + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_LATCH_COUNT_ENABLE ((uint16_t)0x1) +#define ENHTIM_LATCH_COUNT_DISABLE ((uint16_t)0x0) +/** \} */ +#define IS_ENHTIM_LATCH_COUNT_En(mode) (((mode) == ENHTIM_LATCH_COUNT_ENABLE) || \ + ((mode) == ENHTIM_LATCH_COUNT_DISABLE)) + +/** + * \defgroup ENHTIM_LATCH_TRIGGER_Mode Latch Count Trigger Mode + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_LATCH_TRIGGER_BOTH_EDGE ((uint16_t)0x02) +#define ENHTIM_LATCH_TRIGGER_FALLING_EDGE ((uint16_t)0x01) +#define ENHTIM_LATCH_TRIGGER_RISING_EDGE ((uint16_t)0x00) +/** \} */ +#define IS_ENHTIM_LATCH_TRIGGER_Mode(mode) (((mode) == ENHTIM_LATCH_TRIGGER_BOTH_EDGE) || \ + ((mode) == ENHTIM_LATCH_TRIGGER_FALLING_EDGE) || \ + ((mode) == ENHTIM_LATCH_TRIGGER_RISING_EDGE)) + +/** + * \defgroup ENHTIM_PWM_En ENHTIM PWM Output Enable + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_PWM_ENABLE ((uint16_t)0x08) +#define ENHTIM_PWM_DISABLE ((uint16_t)0x00) +/** \} */ +#define IS_ENHTIM_PWM_En(mode) (((mode) == ENHTIM_PWM_ENABLE) || \ + ((mode) == ENHTIM_PWM_DISABLE)) + +/** + * \defgroup ENHTIM_PWM_Polarity ENHTIM PWM Polarity + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_PWM_START_WITH_HIGH ((uint16_t)0x04) +#define ENHTIM_PWM_START_WITH_LOW ((uint16_t)0x00) +/** \} */ +#define IS_ENHTIM_PWM_POLARITY(pola) (((pola) == ENHTIM_PWM_START_WITH_HIGH) || \ + ((pola) == ENHTIM_PWM_START_WITH_LOW)) + +/** + * \defgroup ENHTIM_Mode ENHTIM Mode + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_MODE_PWM_MANUAL ((uint16_t)0x02) /*!< User define pwm manual mode. */ +#define ENHTIM_MODE_PWM_AUTO ((uint16_t)0x01) /*!< User define pwm auto mode. */ +#define ENHTIM_MODE_FreeRun ((uint16_t)0x00) /*!< User define freerun mode. */ +/** \} */ +#define IS_ENHTIM_MODE(mode) (((mode) == ENHTIM_MODE_PWM_MANUAL) || \ + ((mode) == ENHTIM_MODE_PWM_AUTO) || \ + ((mode) == ENHTIM_MODE_UserDefine)) + +/** + * \defgroup ENHTIM_Interrupts_Definition ENHTIM Interrupts Definition + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_INT_TIM (0x00) +#define ENHTIM_INT_LATCH_CNT2_FIFO_FULL (0x40) +#define ENHTIM_INT_LATCH_CNT2_FIFO_THD (0x42) +#define ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY (0x01) /*!< Empty interrupt flag bit but no interrupt */ +/** \} */ + +#define IS_ENHTIM_INT(INT) (((INT) == ENHTIM_INT_TIM) || \ + ((INT) == ENHTIM_INT_LATCH_CNT2_FIFO_FULL) || \ + ((INT) == ENHTIM_INT_LATCH_CNT2_FIFO_THD)) + +/** + * \defgroup ENHTIM_FIFO_Flag ENHTIM FIFO Flag + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY BIT(19) +#define ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY BIT(17) +#define ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY BIT(3) +#define ENHTIM_FLAG_TIM1_CCR_FIFO_FULL BIT(2) +#define ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY BIT(1) +#define ENHTIM_FLAG_TIM0_CCR_FIFO_FULL BIT(0) +/** \} */ +#define IS_ENHTIM_CCR_FIFO_FLAG(flag) (((flag) == ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY) || \ + ((flag) == ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY) || \ + ((flag) == ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY) || \ + ((flag) == ENHTIM_FLAG_TIM1_CCR_FIFO_FULL) || \ + ((flag) == ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY) || \ + ((flag) == ENHTIM_FLAG_TIM0_CCR_FIFO_FULL) )) + +/** + * \defgroup PWM_DeadZone_En PWM DeadZone enable + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_PWM_DEADZONE_ENABLE ((uint16_t)0x1) +#define ENHTIM_PWM_DEADZONE_DISABLE ((uint16_t)0x0) +/** \} */ +#define IS_ENHTIM_PWM_DEADZONE_EN(mode) (((mode) == ENHTIM_PWM_DEADZONE_ENABLE) || \ + ((mode) == ENHTIM_PWM_DEADZONE_DISABLE)) + +/** + * \defgroup PWM_DeadZone_En PWM DeadZone enable + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_PWM_DZCLKSRCE_ENHTIM ((uint32_t)0x80000) +#define ENHTIM_PWM_DZCLKSRCE_5M ((uint32_t)0x10000) +#define ENHTIM_PWM_DZCLKSRCE_32K ((uint32_t)0x0) +/** \} */ +#define IS_ENHTIM_PWM_DEADZONE_EN(mode) (((mode) == ENHTIM_PWM_DEADZONE_ENABLE) || \ + ((mode) == ENHTIM_PWM_DEADZONE_DISABLE)) + +/** + * \defgroup ENHTIM_PWM_DeadZone_Stop_State ENHTIM PWM DeadZone Stop State + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_PWM_STOP_AT_HIGH ((uint16_t)0x1) +#define ENHTIM_PWM_STOP_AT_LOW ((uint16_t)0x0) +/** \} */ + +/** + * \defgroup ENHTIM_FIFO_Clear_Flag ENHTIM FIFO Clear Flag + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +#define ENHTIM_FIFO_CLR_CCR (0) +#define ENHTIM_FIFO_CLR_CNT2 (24) +/** \} */ + +/** + * \defgroup ENHTIM_Clock_Divider ENHTIM Clock Divider + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +typedef enum +{ + ENHTIM_CLOCK_DIVIDER_1 = 0x00, + ENHTIM_CLOCK_DIVIDER_125 = 0x03, + ENHTIM_CLOCK_DIVIDER_2 = 0x04, + ENHTIM_CLOCK_DIVIDER_4 = 0x05, + ENHTIM_CLOCK_DIVIDER_8 = 0x06, + ENHTIM_CLOCK_DIVIDER_40 = 0x07, +} E_ENHTIM_CLKDIV; +/** \} */ + +/** + * \defgroup ENHTIM_Latch_Channel_Count ENHTIM Latch Channel Order Number + * \{ + * \ingroup ENHTIM_Exported_Constants + */ +typedef enum +{ + LATCH_CNT_0 = 0, + LATCH_CNT_1 = 1, + LATCH_CNT_2 = 2, +} E_ENHTIM_LATCHCNT; +/** \} */ + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup ENHTIM_Exported_Types Init Params Struct + * + * \ingroup ENHTIM + */ + +/** + * \brief ENHTIM init structure definition. + * + * \ingroup ENHTIM_Exported_Types + */ +typedef struct +{ + uint16_t ENHTIM_ClockSource; /*!< Specifies the ENHTIM clock source.*/ + E_ENHTIM_CLKDIV ENHTIM_ClockDiv; /*!< Specifies the clock source div. + This parameter can be a value of \ref ENHTIM_Clock_Divider*/ + uint16_t ENHTIM_Mode; /*!< Specifies the counter mode. + This parameter can be a value of \ref ENHTIM_Mode. */ + uint16_t ENHTIM_PWMOutputEn; /*!< Enbale EnhtimerN PWM oupput. + This parameter can be a value of \ref ENHTIM_PWM_En */ + uint16_t ENHTIM_PWMStartPolarity; /*!< EnhtimerN toggle output polarity for user-define PWM mode. + This parameter can be a value of \ref ENHTIM_PWMStartPolarity. */ + uint16_t ENHTIM_LatchCountEn[3]; /*!< Specifies enbale EnhtimerN Latch_cnt. + This parameter can be a value of DISABLE or ENABLE */ + uint16_t ENHTIM_LatchCountTrigger[3]; /*!< Specifies EnhtimerN counter latch trigger mode. + This parameter can be a value of \ref ENHTIM_LatchCountTrigger. */ + uint16_t ENHTIM_LatchCount2Thd; /*!< Specifies EnhtimerN latched counter fifo threshold. + This parameter ranges from 1 to 4. */ + uint16_t ENHTIM_LatchTriggerPad; /*!< User-defined GPIO trigger latch pin.*/ + uint16_t ENHTIM_TimerGPIOTriggerEn; /*!< Timer GPIO trigger enable. + This parameter can be a value of DISABLE or ENABLE */ + uint16_t ENHTIM_BTGPIOTriggerEn; /*!< Bluetooth GPIO trigger enable. + This parameter can be a value of DISABLE or ENABLE */ + uint32_t ENHTIM_MaxCount; /*!< Specifies the Enhtimer max counter value for user-define PWM mode. + This parameter leagel value range is from 0 ~ 2^32-2. */ + uint32_t ENHTIM_CCValue; /*!< Specifies the Enhtimer capture/compare value for user-define PWM mode.*/ + uint16_t ENHTIM_PWMDeadZoneEn; /*!< PWM Deadzone enable, pwm0_pn: timer2, pwm1_pn:timer3 + This parameter can be a value of ENABLE or DISABLE. */ + uint32_t ENHTIM_PWMDeadZoneClockSource; /*!< Specifies ENHTIM Source depend.timer3 depend timer2 ,timer5 depend timer4, timer7 depend timer6. + This parameter can be a value of ENABLE or DISABLE */ + uint16_t ENHTIM_PWMStopStateP; /*!< Specifies the PWM P stop state. + This parameter can be a value of \ref PWMDeadZone_Stop_state. */ + uint16_t ENHTIM_PWMStopStateN; /*!< Specifies the PWM N stop state. + This parameter can be a value of \ref PWMDeadZone_Stop_state. */ + uint32_t ENHTIM_DeadZoneSize; /*!< Size of deadzone time, DeadzoneTime=deadzonesize/32000 or 32768. + This parameter must range from 1 to 0xff. */ +} ENHTIM_InitTypeDef; + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup ENHTIM_Exported_Functions Peripheral APIs + * \{ + * \ingroup ENHTIM + */ + +/** + * \brief Initialize the ENHTIMx unit peripheral according to + * the specified parameters in ENHTIM_InitStruct. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIM peripheral. + * \param[in] ENHTIM_InitStruct: pointer to a ENHTIM_InitTypeDef structure + * that contains the configuration information for the specified ENHTIM peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_enhance_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * ENHTIM_InitTypeDef ENHTIM_InitStruct; + * ENHTIM_StructInit(&ENHTIM_InitStruct); + * + * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE; + * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1 ; + * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine; + * ENHTIM_Init(ENHTIMER_NUM, &ENHTIM_InitStruct); + * } + * \endcode + */ +void ENHTIM_Init(ENHTIM_TypeDef *ENHTIMx, ENHTIM_InitTypeDef *ENHTIM_TimeBaseInitStruct); + +/** + * \brief Fills each ENHTIM_InitStruct member with its default value. + * \param[in] ENHTIM_TimeBaseInitStruct: Pointer to a ENHTIM_TimeBaseInitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_enhance_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE); + * + * ENHTIM_TimeBaseInitTypeDef ENHTIM_InitStruct; + * ENHTIM_StructInit(&ENHTIM_InitStruct); + * + * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE; + * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1; + * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine; + * ENHTIM_TimeBaseInit(ENH_TIM0, &ENHTIM_InitStruct); + * } + * \endcode + */ +void ENHTIM_StructInit(ENHTIM_InitTypeDef *ENHTIM_InitStruct); + +/** + * \brief Enables or disables the specified ENHTIM peripheral. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] NewState: New state of the ENHTIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_enhance_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE); + * + * ENHTIM_InitTypeDef ENHTIM_InitStruct; + * ENHTIM_StructInit(&ENHTIM_InitStruct); + * + * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE; + * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1; + * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine; + * ENHTIM_Init(ENH_TIM0, &ENHTIM_InitStruct); + * ENHTIM_Cmd(ENH_TIM0, ENABLE); + * } + * \endcode + */ +void ENHTIM_Cmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState); + +/** + * \brief Mask or unmask the latch count2 fifo interrupt. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] NewState: New state of the specified ENHTIMx peripheral latch count2 fifo interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None. + */ +void ENHTIM_LCFIFOMaskConfig(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState); + +/** + * \brief Enables or disables ENHTIMx interrupt. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source. + * \param[in] NewState: New state of the ENHTIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_enhance_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * ENHTIM_InitTypeDef ENHTIM_InitStruct; + * ENHTIM_StructInit(&ENHTIM_InitStruct); + * + * ENHTIM_InitStruct.ENHTIM_PWM_En = PWM_DISABLE; + * ENHTIM_InitStruct.ENHTIM_Period = 1000000 - 1; + * ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_Mode_UserDefine; + * ENHTIM_Init(ENH_TIM0, &ENHTIM_InitStruct); + * ENHTIM_ClearINT(ENH_TIM0); + * ENHTIM_INTConfig(ENH_TIM0, ENABLE); + */ +void ENHTIM_INTConfig(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT, FunctionalState NewState); + +/** + * \brief Read ENHTIMx latch counter2 fifo data. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] length: Latch count2 fifo length, max 4. + * \pBuf[out] pBuf: FIFO data out buffer. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0); + * } + * \endcode + */ +void ENHTIM_ReadLatchCount2FIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t *pBuf, uint8_t length); + +/** + * \brief Check whether the ENHTIM interrupt has occurred or not. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return The new state of the specified ENHTIMx peripheral + * latch count2 fifo interrupt(SET or RESET). + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ITStatus int_status = ENHTIM_GetLCMaskINTStatus(ENH_TIM0); + * } + * \endcode + */ +ITStatus ENHTIM_GetLCFIFOMaskStatus(ENHTIM_TypeDef *ENHTIMx); + +/** + * \brief Check whether the ENHTIM interrupt has occurred or not. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source. + * \return The new state of the ENHTIM_INT(SET or RESET). + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_TIM); + * } + * \endcode + */ +ITStatus ENHTIM_GetINTStatus(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT); + +/** + * \brief Clear ENHTIMx interrupt. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_TIM); + * } + * \endcode + */ +void ENHTIM_ClearINTPendingBit(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT); + +/** + * \brief Get ENHTIMx current value when timer is running. + * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return The counter value. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint32_t cur_value = ENHTIM_GetCurrentValue(ENH_TIM0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t ENHTIM_GetCurrentCount(ENHTIM_TypeDef *ENHTIMx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + return ENHTIMx->CUR_CNT; +} + +/** + * \brief Set Max Count value. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] count: EnhtimerN max counter value for user-define PWM mode (leagel value range is from 0 ~ + * 2^32-2). + * \note If it needs a dynamic change of MAX_CNT value, MAX_CNT has a minimum value limit. + * Ex. cpu_clk = 40MHz, ETIMER_CLK = 40MHz, then MAX_CNT should larger than 10. + * Ex. cpu_clk = 40MHz, ETIMER_CLK = 32kHz, then MAX_CNT should larger than 4. + * If in the state where ENHTIM is disabled, there is no such limitation. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_SetMaxCount(ENH_TIM0, 0x10000); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_SetMaxCount(ENHTIM_TypeDef *ENHTIMx, uint32_t count) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + if (count > 0xFFFFFFFE) + { + count = 0xFFFFFFFE; + } + ENHTIMx->MAX_CNT = count; +} + +/** + * \brief Set ENHTIMx capture/compare value for user-define PWM manual mode. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] value: EnhtimerN CCR value. + * \note If it needs a dynamic change of CCR value, CCR value has a minimum value limit. + * Ex. cpu_clk = 40MHz, ETIMER_CLK = 40MHz, then CCR value should larger than 10. + * Ex. cpu_clk = 40MHz, ETIMER_CLK = 32kHz, then CCR value should larger than 4. + * If in the state where ENHTIM is disabled, there is no such limitation. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_SetCCValue(ENH_TIM0, 0x1000); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_SetCCValue(ENHTIM_TypeDef *ENHTIMx, uint32_t value) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + ENHTIMx->CCR = value; +} + +/** + * \brief Set ENHTIMx capture/compare value for user-define PWM auto mode. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] value: . + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_WriteCCFIFO(ENH_TIM0,0x10000); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_WriteCCFIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t value) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + ENHTIMx->CCR_FIFO = value; +} + +///** +// * \brief Check whether the specified ENHTIM CCR FIFO flag is set. +// * \param[in] ENHTIM_FLAG: Specifies the flag to check. +// * This parameter can be one of the following values: +// * \arg ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. +// * \arg ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY: FIFO full or not. If SET, CCR FIFO is full. +// * \return The new state of ENHTIM_FLAG (SET or RESET). +// * +// * Example usage +// * \code{.c} +// * +// * void enhance_timer_demo(void) +// * { +// * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY); +// * } +// * \endcode +// */ +//__STATIC_INLINE FlagStatus ENHTIM_GetLCFIFOFlagStatus(uint32_t ENHTIM_FLAG) +//{ +// /* Check the parameters */ +// assert_param(IS_ENHTIM_LC_FIFO_FLAG(ENHTIM_FLAG)); + +// FlagStatus bitstatus = RESET; + +// if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG) +// { +// bitstatus = SET; +// } + +// return bitstatus; +//} + +///** +// * \brief Check whether the specified ENHTIM CCR FIFO flag is set. +// * \param[in] ENHTIM_FLAG: Specifies the flag to check. +// * This parameter can be one of the following values: +// * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. +// * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full. +// * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. +// * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full. +// * \return The new state of ENHTIM_FLAG (SET or RESET). +// * +// * Example usage +// * \code{.c} +// * +// * void enhance_timer_demo(void) +// * { +// * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY); +// * } +// * \endcode +// */ +//__STATIC_INLINE FlagStatus ENHTIM_GetCCRFIFOFlagStatus(uint32_t ENHTIM_FLAG) +//{ +// /* Check the parameters */ +// assert_param(IS_ENHTIM_CCR_FIFO_FLAG(ENHTIM_FLAG)); + +// FlagStatus bitstatus = RESET; + +// if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG) +// { +// bitstatus = SET; +// } + +// return bitstatus; +//} + +/** + * \brief Check whether the specified ENHTIM CCR FIFO flag is set. + * \param[in] ENHTIM_FLAG: Specifies the flag to check. + * This parameter can be one of the following values: + * \arg ENHTIM_FLAG_TIM1_LC_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. + * \arg ENHTIM_FLAG_TIM0_LC_FIFO_EMPTY: FIFO full or not. If SET, CCR FIFO is full. + * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. + * \arg ENHTIM_FLAG_TIM1_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full. + * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_EMPTY: FIFO empty or not. If SET, CCR FIFO is empty. + * \arg ENHTIM_FLAG_TIM0_CCR_FIFO_FULL: FIFO full or not. If SET, CCR FIFO is full. + * \return The new state of ENHTIM_FLAG (SET or RESET). + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * FlagStatus flag_status = ENHTIM_GetCCRFIFOFlagStatus(ENHTIM_FLAG_FIFO_EMPTY); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus ENHTIM_GetFIFOFlagStatus(uint32_t ENHTIM_FLAG) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_FIFO_FLAG(ENHTIM_FLAG)); + + FlagStatus bitstatus = RESET; + + if (ENH_TIM_SHARE->FIFO_SR2 & ENHTIM_FLAG) + { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * \brief Enable ENHTIMx latch counter. + * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value. + * This parameter can be one of follow. + * \arg LATCH_COUNT_0: Enhance timer latch count 0. + * \arg LATCH_COUNT_1: Enhance timer latch count 1. + * \arg LATCH_COUNT_2: Enhance timer latch count 2. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint32_t cur_value = ENHTIM_LatchCountEnable(ENH_TIM0, LATCH_COUNT_2); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_LatchCountEnable(ENHTIM_TypeDef *ENHTIMx, E_ENHTIM_LATCHCNT LatchCntIdx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + ENHTIMx->CR |= BIT(LatchCntIdx + 10); +} + +/** + * \brief Disable ENHTIMx latch counter. + * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value. + * This parameter can be one of follow. + * \arg LATCH_COUNT_0: Enhance timer latch count 0. + * \arg LATCH_COUNT_1: Enhance timer latch count 1. + * \arg LATCH_COUNT_2: Enhance timer latch count 2. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint32_t cur_value = ENHTIM_LatchCountDisable(ENH_TIM0, LATCH_COUNT_2); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_LatchCountDisable(ENHTIM_TypeDef *ENHTIMx, + E_ENHTIM_LATCHCNT LatchCntIdx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + ENHTIMx->CR &= ~BIT(LatchCntIdx + 10); +} + +/** + * \brief Get ENHTIMx latch count value. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] LatchCntIdx: E_ENHTIM_LATCHCNT enum value. + * This parameter can be one of follow. + * \arg LATCH_COUNT_0: Enhance timer latch count 0. + * \arg LATCH_COUNT_1: Enhance timer latch count 1. + * \arg LATCH_COUNT_2: Enhance timer latch count 2. + * \return The latch counter value. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint32_t count_value = ENHTIM_GetLatchCountValue(ENH_TIM0, LATCH_COUNT_0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t ENHTIM_GetLatchCount(ENHTIM_TypeDef *ENHTIMx, + E_ENHTIM_LATCHCNT LatchCntIdx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t count = 0; + count = *(volatile uint32_t *)(&(ENHTIMx->LATCH_CNT0) + LatchCntIdx); + return count; +} + +/** + * \brief Get ENHTIMx latch counter2 fifo length. + * \param[in] ENHTIMx: where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return FIFO data length. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t ENHTIM_GetLatchCount2FIFOLength(ENHTIM_TypeDef *ENHTIMx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + return (uint8_t)(((*((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_FIFO_LEVEL0) + enhtim_id))) >> 16) & + 0x1F); +} + +/** + * \brief Clear capture/compare or latch count2 fifo. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] FIFO_CLR: Specifies the FIFO type which to be clear. + * This parameter can be one of the following values: + * \arg ENHTIM_FIFO_CLR_CCR: Enhance Timer CCR FIFO clear flag. + * \arg ENHTIM_FIFO_CLR_CNT2: Enhance Timer latch count2 FIFO clear flag. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_ClearFIFO(ENH_TIM0, ENHTIM_FIFO_CLR_CCR); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_ClearFIFO(ENHTIM_TypeDef *ENHTIMx, uint8_t FIFO_CLR) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + ENH_TIM_SHARE->FIFO_CLR |= (BIT(FIFO_CLR + enhtim_id)); +} + +/** + * \brief ENHTIM PWM complementary output emergency stop. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_PWMDeadZoneEMStop(); + * } + * \endcode + */ +__STATIC_INLINE void ENHTIM_PWMDeadZoneEMStop(void) +{ + ENHTIM_PWM_DEADZONE_CR |= BIT(8); +} + +/** + * \brief Get ENHTIM PWM output status. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return ENHTIM PWM output status(SET or RESET). + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * FlagStatus status = ENHTIM_GetPWMOutputState(ENH_TIM0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus ENHTIM_GetPWMOutputState(ENHTIM_TypeDef *ENHTIMx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + uint32_t status = ENHTIM_LATCH_COUNT_CR & (0x1 << (enhtim_id + 6)); + return (FlagStatus)(status >> (enhtim_id + 6)); +} + +///** +// * \brief Check whether the ENHTIM interrupt has occurred or not. +// * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. +// * \return The new state of the ENHTIM_IT(SET or RESET). +// * +// * Example usage +// * \code{.c} +// * +// * void enhance_timer_demo(void) +// * { +// * ITStatus int_status = ENHTIM_GetINTStatus(ENH_TIM0); +// * } +// * \endcode +// */ +//__STATIC_INLINE uint32_t ENHTIM_GetAllINTStatus(void) +//{ +// return ENH_TIM_SHARE->MASK_INT_SR; +//} + +/** + * \brief Enable or disable bypass dead zone function of PWM complementary output. + * After enabling, PWM_P = ~PWM_N. + * \param[in] ENHTIMx: ENHTIM0. + * \param[in] NewState: New state of the ENHTIMx peripheral. + * \ref DISABLE: Disable bypass dead zone function. + * \ref ENABLE: Enable bypass dead zone function. + * \note To use this function, need to configure the corresponding enhtimer. + * ENHTIMx can be only ENHTIM0. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_pwm_init(void) + * { + * ENHTIM_PWMDZBypassCmd(ENHTIM0, ENABLE); + * } + * \endcode + */ +void ENHTIM_PWMDZBypassCmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState); + +/** \} */ /* End of group ENHTIM_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /*_RTL876X_ENH_TIM_H_*/ + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/peripheral/rtl876x_gdma.h b/inc/peripheral/rtl876x_gdma.h new file mode 100644 index 0000000..41a47fa --- /dev/null +++ b/inc/peripheral/rtl876x_gdma.h @@ -0,0 +1,970 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_gdma.h +* \brief The header file of the peripheral GDMA driver. +* \details This file provides all GDMA firmware functions. +* \author yuan +* \date 2019-11-14 +* \version v1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_GDMA_H_ +#define _RTL876X_GDMA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup GDMA GDMA + * + * \brief Manage the GDMA peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup GDMA_Exported_Types Init Params Struct + * + * \ingroup GDMA + */ + +/** + * \brief GDMA init structure definition. + * + * \ingroup GDMA_Exported_Types + */ +typedef struct +{ + uint8_t GDMA_ChannelNum; /*!< Specifies channel number for GDMA. */ + uint8_t GDMA_DIR; /*!< Specifies if the peripheral is the source or destination. + This parameter can be a value of \ref GDMA_Data_Transfer_Direction. */ + uint32_t GDMA_BufferSize; /*!< Specifies the buffer size(<=4095), in data unit, of the specified Channel. + The data unit is equal to the configuration set in DMA_PeripheralDataSize + or DMA_MemoryDataSize members depending in the transfer direction. */ + uint8_t GDMA_SourceInc; /*!< Specifies whether the source address register is incremented or not. + This parameter can be a value of \ref GDMA_Source_Incremented_Mode */ + uint8_t GDMA_DestinationInc; /*!< Specifies whether the destination address register is incremented or not. + This parameter can be a value of \ref GDMA_Destination_Incremented_Mode. */ + uint32_t GDMA_SourceDataSize; /*!< Specifies the source data width. + This parameter can be a value of \ref GDMA_Data_Size */ + uint32_t GDMA_DestinationDataSize; /*!< Specifies the Memory data width. + This parameter can be a value of \ref GDMA_Data_Size */ + uint32_t GDMA_SourceMsize; /*!< Specifies the number of data items to be transferred. + This parameter can be a value of \ref GDMA_Msize */ + uint32_t GDMA_DestinationMsize; /*!< Specifies the number of data items to be transferred. + This parameter can be a value of \ref GDMA_Msize */ + uint32_t GDMA_SourceAddr; /*!< Specifies the source base address for GDMA Channelx. */ + uint32_t GDMA_DestinationAddr; /*!< Specifies the destination base address for GDMA Channelx. */ + uint32_t GDMA_ChannelPriority; /*!< Specifies the software priority for the GDMA Channelx. */ + uint32_t GDMA_Multi_Block_Mode; /*!< Specifies the multi block transfer mode. + This parameter can be a value of \ref GDMA_Multiblock_Mode. */ + uint32_t GDMA_Multi_Block_Struct; /*!< Pointer to the first struct of LLI. */ + uint8_t GDMA_Multi_Block_En; /*!< Enable or disable multi-block function. */ + uint8_t GDMA_SourceHandshake; /*!< Specifies the handshake index in source. + This parameter can be a value of \ref GDMA_Handshake_Type. */ + uint8_t GDMA_DestHandshake; /*!< Specifies the handshake index in Destination. + This parameter can be a value of \ref GDMA_Handshake_Type. */ +} GDMA_InitTypeDef; + +/** + * \brief GDMA link list item structure definition. + * + * \ingroup GDMA_Exported_Types + */ +typedef struct +{ + __IO uint32_t SAR; + __IO uint32_t DAR; + __IO uint32_t LLP; + __IO uint32_t CTL_LOW; + __IO uint32_t CTL_HIGH; +} GDMA_LLIDef; + + + +#define DMA_CH_BASE(ChNum) ((GDMA_ChannelTypeDef *) (GDMA_CHANNEL_REG_BASE + ChNum * 0x0058)) +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup GDMA_Exported_Constants Macro Definitions + * + * \ingroup GDMA + */ + +#define IS_GDMA_ALL_PERIPH(PERIPH) (((PERIPH) == GDMA_Channel0) || \ + ((PERIPH) == GDMA_Channel1) || \ + ((PERIPH) == GDMA_Channel2) || \ + ((PERIPH) == GDMA_Channel3)) + +#define IS_GDMA_ChannelNum(NUM) ((NUM) < 4) + +/** + * \defgroup GDMA_Handshake_Type GDMA Handshake Type + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define GDMA_Handshake_UART0_TX (0) +#define GDMA_Handshake_UART0_RX (1) +#define GDMA_Handshake_ENH_TIM0 (2) +#define GDMA_Handshake_ENH_TIM1 (3) +#define GDMA_Handshake_SPI0_TX (4) +#define GDMA_Handshake_SPI0_RX (5) +#define GDMA_Handshake_SPI1_TX (6) +#define GDMA_Handshake_SPI1_RX (7) +#define GDMA_Handshake_I2C0_TX (8) +#define GDMA_Handshake_I2C0_RX (9) +#define GDMA_Handshake_I2C1_TX (10) +#define GDMA_Handshake_I2C1_RX (11) +#define GDMA_Handshake_ADC (12) +#define GDMA_Handshake_AES_TX (13) +#define GDMA_Handshake_AES_RX (14) +#define GDMA_Handshake_UART1_TX (15) +#define GDMA_Handshake_I2S0_TX (16) +#define GDMA_Handshake_I2S0_RX (17) +#define GDMA_Handshake_SPIC0_TX (20) +#define GDMA_Handshake_SPIC0_RX (21) +#define GDMA_Handshake_UART1_RX (23) +#define GDMA_Handshake_TIM0 (24) +#define GDMA_Handshake_TIM1 (25) +#define GDMA_Handshake_TIM2 (26) +#define GDMA_Handshake_IR_TX (27) +#define GDMA_Handshake_IR_RX (28) +#define GDMA_Handshake_TIM3 (29) +#define GDMA_Handshake_TIM4 (30) +#define GDMA_Handshake_TIM5 (31) +/** \} */ + +#define IS_GDMA_TransferType(Type) (((Type) == GDMA_Handshake_UART0_TX) || \ + ((Type) == GDMA_Handshake_UART0_RX) || \ + ((Type) == GDMA_Handshake_ENH_TIM0) || \ + ((Type) == GDMA_Handshake_ENH_TIM1) || \ + ((Type) == GDMA_Handshake_SPI0_TX) || \ + ((Type) == GDMA_Handshake_SPI0_RX) || \ + ((Type) == GDMA_Handshake_SPI1_TX) || \ + ((Type) == GDMA_Handshake_SPI1_RX) || \ + ((Type) == GDMA_Handshake_I2C0_TX) || \ + ((Type) == GDMA_Handshake_I2C0_RX) || \ + ((Type) == GDMA_Handshake_I2C1_TX) || \ + ((Type) == GDMA_Handshake_I2C1_RX) || \ + ((Type) == GDMA_Handshake_ADC) || \ + ((Type) == GDMA_Handshake_AES_TX) || \ + ((Type) == GDMA_Handshake_AES_RX) || \ + ((Type) == GDMA_Handshake_UART1_TX) || \ + ((Type) == GDMA_Handshake_I2S0_TX) || \ + ((Type) == GDMA_Handshake_I2S0_RX) || \ + ((Type) == GDMA_Handshake_SPIC0_TX) || \ + ((Type) == GDMA_Handshake_SPIC0_RX) ||\ + ((Type) == GDMA_Handshake_UART1_RX) || \ + ((Type) == GDMA_Handshake_IR_TX) ||\ + ((Type) == GDMA_Handshake_IR_RX) ||\ + ((Type) == GDMA_Handshake_TIM0) ||\ + ((Type) == GDMA_Handshake_TIM1) ||\ + ((Type) == GDMA_Handshake_TIM2) ||\ + ((Type) == GDMA_Handshake_TIM3) ||\ + ((Type) == GDMA_Handshake_TIM4) ||\ + ((Type) == GDMA_Handshake_TIM5)) + +/** + * \defgroup GDMA_Data_Size GDMA Data Size + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define GDMA_DataSize_Byte ((uint32_t)0x00000000) +#define GDMA_DataSize_HalfWord ((uint32_t)0x00000001) +#define GDMA_DataSize_Word ((uint32_t)0x00000002) +/** \} */ + +#define IS_GDMA_DATA_SIZE(SIZE) (((SIZE) == GDMA_DataSize_Byte) || \ + ((SIZE) == GDMA_DataSize_HalfWord) || \ + ((SIZE) == GDMA_DataSize_Word)) + +/** + * \defgroup GDMA_Msize GDMA Msize + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define GDMA_Msize_1 ((uint32_t)0x00000000) +#define GDMA_Msize_4 ((uint32_t)0x00000001) +#define GDMA_Msize_8 ((uint32_t)0x00000002) +#define GDMA_Msize_16 ((uint32_t)0x00000003) +#define GDMA_Msize_32 ((uint32_t)0x00000004) +#define GDMA_Msize_64 ((uint32_t)0x00000005) +#define GDMA_Msize_128 ((uint32_t)0x00000006) +#define GDMA_Msize_256 ((uint32_t)0x00000007) +/** \} */ +#define IS_GDMA_MSIZE(SIZE) (((SIZE) == GDMA_Msize_1) || \ + ((SIZE) == GDMA_Msize_4) || \ + ((SIZE) == GDMA_Msize_8) || \ + ((SIZE) == GDMA_Msize_16) || \ + ((SIZE) == GDMA_Msize_32) || \ + ((SIZE) == GDMA_Msize_64) || \ + ((SIZE) == GDMA_Msize_128) || \ + ((SIZE) == GDMA_Msize_256)) + +/** + * \defgroup GDMA_Data_Transfer_Direction GDMA Data Transfer Direction + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define GDMA_DIR_MemoryToMemory ((uint32_t)0x00000000) +#define GDMA_DIR_MemoryToPeripheral ((uint32_t)0x00000001) +#define GDMA_DIR_PeripheralToMemory ((uint32_t)0x00000002) +#define GDMA_DIR_PeripheralToPeripheral ((uint32_t)0x00000003) +/** \} */ + +#define IS_GDMA_DIR(DIR) (((DIR) == GDMA_DIR_MemoryToMemory) || \ + ((DIR) == GDMA_DIR_MemoryToPeripheral) || \ + ((DIR) == GDMA_DIR_PeripheralToMemory) ||\ + ((DIR) == GDMA_DIR_PeripheralToPeripheral)) + +/** + * \defgroup GDMA_Source_Incremented_Mode GDMA Source Incremented Mode + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define DMA_SourceInc_Inc ((uint32_t)0x00000000) +#define DMA_SourceInc_Dec ((uint32_t)0x00000001) +#define DMA_SourceInc_Fix ((uint32_t)0x00000002) +/** \} */ + +#define IS_GDMA_SourceInc(STATE) (((STATE) == DMA_SourceInc_Inc) || \ + ((STATE) == DMA_SourceInc_Dec) || \ + ((STATE) == DMA_SourceInc_Fix)) + +/** + * \defgroup GDMA_Destination_Incremented_Mode GDMA Destination Incremented Mode + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define DMA_DestinationInc_Inc ((uint32_t)0x00000000) +#define DMA_DestinationInc_Dec ((uint32_t)0x00000001) +#define DMA_DestinationInc_Fix ((uint32_t)0x00000002) +/** \} */ + +#define IS_GDMA_DestinationInc(STATE) (((STATE) == DMA_DestinationInc_Inc) || \ + ((STATE) == DMA_DestinationInc_Dec) || \ + ((STATE) == DMA_DestinationInc_Fix)) + +/** + * \defgroup DMA_Interrupts_Definition DMA Interrupts Definition + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define GDMA_INT_Transfer ((uint32_t)0x00000001) +#define GDMA_INT_Block ((uint32_t)0x00000002) +#define GDMA_INT_SrcTransfer ((uint32_t)0x00000004) +#define GDMA_INT_DstTransfer ((uint32_t)0x00000008) +#define GDMA_INT_Error ((uint32_t)0x00000010) +/** \} */ + +#define IS_GDMA_CONFIG_IT(IT) ((((IT) & 0xFFFFFE00) == 0x00) && ((IT) != 0x00)) + +/** + * \defgroup GDMA_Multiblock_Mode GDMA Multi-block Mode + * \{ + * \ingroup GDMA_Exported_Constants + */ +#define AUTO_RELOAD_WITH_CONTIGUOUS_SAR (BIT31) +#define AUTO_RELOAD_WITH_CONTIGUOUS_DAR (BIT30) +#define AUTO_RELOAD_TRANSFER (BIT30 | BIT31) +#define LLI_WITH_CONTIGUOUS_SAR (BIT27) +#define LLI_WITH_AUTO_RELOAD_SAR (BIT27 | BIT30) +#define LLI_WITH_CONTIGUOUS_DAR (BIT28) +#define LLI_WITH_AUTO_RELOAD_DAR (BIT28 | BIT31) +#define LLI_TRANSFER (BIT27 | BIT28) +/** \} */ + +#define IS_GDMA_MULTIBLOCKMODE(MODE) (((MODE) == AUTO_RELOAD_WITH_CONTIGUOUS_SAR) || ((MODE) == AUTO_RELOAD_WITH_CONTIGUOUS_DAR)\ + ||((MODE) == AUTO_RELOAD_TRANSFER) || ((MODE) == LLI_WITH_CONTIGUOUS_SAR)\ + ||((MODE) == LLI_WITH_AUTO_RELOAD_SAR) || ((MODE) == LLI_WITH_CONTIGUOUS_DAR)\ + ||((MODE) == LLI_WITH_AUTO_RELOAD_DAR) || ((MODE) == LLI_TRANSFER)) + +/** + * \def GDMA_Multiblock_Select_Bit Multi-Block Select Bit + * + */ +#define AUTO_RELOAD_SELECTED_BIT (uint32_t)(0xC0000000) +#define LLP_SELECTED_BIT (uint32_t)(0x18000000) + +/** + * \def DMA_Suspend_Flag_Definition DMA Suspend Flag Definition + */ +#define GDMA_FIFO_STATUS (BIT(9)) +#define GDMA_SUSPEND_TRANSMISSSION (BIT(8)) +#define GDMA_SUSPEND_CMD_STATUS (BIT(2) | BIT(1)) +#define GDMA_SUSPEND_CHANNEL_STATUS (BIT(0)) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup GDMA_Exported_Functions Peripheral APIs + * \{ + * \ingroup GDMA + */ + +/** + * \brief Deinitializes the GDMA registers to their default reset + * values. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gdma_init(void) + * { + * GDMA_DeInit(); + * } + * \endcode + */ +void GDMA_DeInit(void); + +/** + * \brief Initializes the GDMA Channelx according to the specified + * parameters in the GDMA_InitStruct. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel. + * \param[in] GDMA_InitStruct: Pointer to a GDMA_InitTypeDef structure that + * contains the configuration information for the specified DMA Channel. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gdma_init(void) + * { + * + * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++) + * { + * GDMA_SendData_Buffer[i] = 0x10 + i; + * } + + * GDMA_InitTypeDef GDMA_InitStruct; + * GDMA_StructInit(&GDMA_InitStruct); + * GDMA_InitStruct.GDMA_ChannelNum = 1; + * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral; + * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size + * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc; + * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix; + * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer; + * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR)); + * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX; + * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5 + * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct); + + * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE); + + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE); + * } + * \endcode + */ +void GDMA_Init(GDMA_ChannelTypeDef *GDMA_Channelx, GDMA_InitTypeDef *GDMA_InitStruct); + +/** + * \brief Fills each GDMA_InitStruct member with its default value. + * \param[in] GDMA_InitStruct : pointer to a GDMA_InitTypeDef structure which will + * be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gdma_init(void) + * { + * + * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++) + * { + * GDMA_SendData_Buffer[i] = 0x10 + i; + * } + + * GDMA_InitTypeDef GDMA_InitStruct; + * GDMA_StructInit(&GDMA_InitStruct); + * GDMA_InitStruct.GDMA_ChannelNum = 1; + * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral; + * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size + * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc; + * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix; + * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer; + * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR)); + * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX; + * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5 + * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct); + * + * } + * \endcode + */ +void GDMA_StructInit(GDMA_InitTypeDef *GDMA_InitStruct); + +/** + * \brief Enables or disables the selected GDMA channel. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \param[in] NewState: New state of the selected DMA channel. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gdma_init(void) + * { + * + * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++) + * { + * GDMA_SendData_Buffer[i] = 0x10 + i; + * } + + * GDMA_InitTypeDef GDMA_InitStruct; + * GDMA_StructInit(&GDMA_InitStruct); + * GDMA_InitStruct.GDMA_ChannelNum = 1; + * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral; + * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size + * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc; + * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix; + * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer; + * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR)); + * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX; + * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5 + * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct); + + * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE); + + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE); + * } + * \endcode + */ +void GDMA_Cmd(uint8_t GDMA_Channel_Num, FunctionalState NewState); + +/** + * \brief Enables or disables the specified DMA channelx interrupt source. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \param[in] GDMA_IT: Specifies the GDMA interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg GDMA_INT_Transfer: Transfer complete interrupt source. + * \arg GDMA_INT_Block: Block transfer interrupt source. + * \arg GDMA_INT_SrcTransfer: SourceTransfer interrupt source. + * \arg GDMA_INT_DstTransfer: Destination Transfer interruptsource. + * \arg GDMA_INT_Error: Transfer error interrupt source. + * \param[in] NewState: New state of the specified DMA interrupt source. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gdma_init(void) + * { + * + * for (uint32_t i = 0; i < UART_TX_GDMA_BUFFER_SIZE; i++) + * { + * GDMA_SendData_Buffer[i] = 0x10 + i; + * } + + * GDMA_InitTypeDef GDMA_InitStruct; + * GDMA_StructInit(&GDMA_InitStruct); + * GDMA_InitStruct.GDMA_ChannelNum = 1; + * GDMA_InitStruct.GDMA_DIR = GDMA_DIR_MemoryToPeripheral; + * GDMA_InitStruct.GDMA_BufferSize = UART_TX_GDMA_BUFFER_SIZE;//determine total transfer size + * GDMA_InitStruct.GDMA_SourceInc = DMA_SourceInc_Inc; + * GDMA_InitStruct.GDMA_DestinationInc = DMA_DestinationInc_Fix; + * GDMA_InitStruct.GDMA_SourceDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_DestinationDataSize = GDMA_DataSize_Byte; + * GDMA_InitStruct.GDMA_SourceMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_DestinationMsize = GDMA_Msize_1; + * GDMA_InitStruct.GDMA_SourceAddr = (uint32_t)GDMA_SendData_Buffer; + * GDMA_InitStruct.GDMA_DestinationAddr = (uint32_t)(&(UART0->RB_THR)); + * GDMA_InitStruct.GDMA_DestHandshake = GDMA_Handshake_UART0_TX; + * GDMA_InitStruct.GDMA_ChannelPriority = 2;//channel prority between 0 to 5 + * GDMA_Init(UART_TX_GDMA_CHANNEL, &GDMA_InitStruct); + + * GDMA_INTConfig(UART_TX_GDMA_CHANNEL_NUM, GDMA_INT_Transfer, ENABLE); + + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = UART_TX_GDMA_CHANNEL_IRQN; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * GDMA_Cmd(UART_TX_GDMA_CHANNEL_NUM, ENABLE); + * } + * \endcode + */ +void GDMA_INTConfig(uint8_t GDMA_Channel_Num, uint32_t GDMA_IT, FunctionalState NewState); + +/** + * \brief Clear the specified DMA channelx interrupt pending bit. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \param[in] GDMA_IT: Specifies the GDMA interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg GDMA_INT_Transfer: Transfer complete interrupt source. + * \arg GDMA_INT_Block: Block transfer interrupt source. + * \arg GDMA_INT_SrcTransfer: SourceTransfer interrupt source. + * \arg GDMA_INT_DstTransfer: Destination Transfer interruptsource. + * \arg GDMA_INT_Error: Transfer error interrupt source. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * driver_gdma_init(); + * } + * + * void UART_TX_GDMA_Handler(void) + * { + * GDMA_ClearINTPendingBit(1, GDMA_INT_Transfer); + * //Add user code here. + * } + * \endcode + */ +void GDMA_ClearINTPendingBit(uint8_t GDMA_Channel_Num, uint32_t GDMA_IT); + +/** + * \brief Get selected GDMA channel status. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \return GDMA channel status. + * \retval SET: Channel is be used + * \retval RESET: Channel is free. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * FlagStatus flag_status = GDMA_GetChannelStatus(0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus GDMA_GetChannelStatus(uint8_t GDMA_Channel_Num) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num)); + + if ((GDMA_BASE->ChEnReg & BIT(GDMA_Channel_Num)) != (uint32_t)RESET) + { + + bit_status = SET; + } + + /* Return the selected channel status */ + return bit_status; +} + +/** + * \brief Check whether GDMA Channel transfer interrupt is set. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \return Transfer interrupt status, SET or RESET. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * ITStatus int_status = GDMA_GetTransferINTStatus(0); + * } + * \endcode + */ +__STATIC_INLINE ITStatus GDMA_GetTransferINTStatus(uint8_t GDMA_Channel_Num) +{ + ITStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num)); + + if ((GDMA_BASE->STATUS_TFR & BIT(GDMA_Channel_Num)) != (uint32_t)RESET) + { + + bit_status = SET; + } + + /* Return the transfer interrupt status */ + return bit_status; +} + +/** + * \brief Clear GDMA Channelx all interrupt. + * \param[in] GDMA_Channel_Num: GDMA channel number, can be 0~3. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * GDMA_ClearAllTypeINT(0); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_ClearAllTypeINT(uint8_t GDMA_Channel_Num) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_Channel_Num)); + + GDMA_BASE->CLEAR_TFR = BIT(GDMA_Channel_Num); + GDMA_BASE->CLEAR_BLOCK = BIT(GDMA_Channel_Num); + GDMA_BASE->CLEAR_DST_TRAN = BIT(GDMA_Channel_Num); + GDMA_BASE->CLEAR_SRC_TRAN = BIT(GDMA_Channel_Num); + GDMA_BASE->CLEAR_ERR = BIT(GDMA_Channel_Num); +} + +/** + * \brief Set GDMA transmission source address. + * \param[in] GDMA_Channelx: where x can be 0 to 3 to select the DMA Channel. + * \param[in] Address: Source address. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint32_t data_buf[10] = {0}; + * GDMA_SetSourceAddress(GDMA_Channel0,(uint32_t)data_buf); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_SetSourceAddress(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t Address) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + GDMA_Channelx->SAR = Address; +} + +/** + * \brief Set GDMA transmission destination address. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \param[in] Address: Destination address. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint32_t data_buf[10] = {0}; + * GDMA_SetDestinationAddress(GDMA_Channel0,(uint32_t)data_buf); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_SetDestinationAddress(GDMA_ChannelTypeDef *GDMA_Channelx, + uint32_t Address) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + GDMA_Channelx->DAR = Address; +} + +/** + * \brief Set GDMA buffer size. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \param[in] buffer_size: Set GDMA_BufferSize. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint32_t data_buf_size = 4095;//max + * GDMA_SetBufferSize(GDMA_Channel0,data_buf_size); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_SetBufferSize(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t buffer_size) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + /* configure high 32 bit of CTL register */ + GDMA_Channelx->CTL_HIGH = buffer_size; +} + +/** + * \brief Suspend GDMA transmission from the source. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \param[in] NewState: New state of the DMA Channelx. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * \note To prevent data loss, it is necessary to check whether FIFO data transmission is completed + * after suspend, and judge by checking whether GDMA FIFO is empty. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * GDMA_SuspendCmd(GDMA_Channel0,ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_SuspendCmd(GDMA_ChannelTypeDef *GDMA_Channelx, + FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == DISABLE) + { + /* Not suspend transmission*/ + GDMA_Channelx->CFG_LOW &= ~(GDMA_SUSPEND_TRANSMISSSION); + } + else + { + /* Suspend transmission */ + GDMA_Channelx->CFG_LOW |= GDMA_SUSPEND_TRANSMISSSION; + } +} + +/** + * \brief Get GDMA transfer data length. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \return GDMA transfer data length. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint16_t data_len = GDMA_GetTransferLen(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE uint16_t GDMA_GetTransferLen(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + return (uint16_t)(GDMA_Channelx->CTL_HIGH & 0xffff); +} + +/** + * \brief Set GDMA LLP stucture address. + * \param[in] GDMA_Channelx: Only for GDMA_Channel0~3. + * \param[in] Address: LLP stucture address. + * \return None. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * GDMA_LLIDef GDMA_LLIStruct[4000]; + * GDMA_SetLLPAddress(GDMA_Channel0,(uint32_t)GDMA_LLIStruct); + * } + * \endcode + */ +__STATIC_INLINE void GDMA_SetLLPAddress(GDMA_ChannelTypeDef *GDMA_Channelx, uint32_t Address) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + if ((GDMA_Channelx == GDMA_Channel0) | (GDMA_Channelx == GDMA_Channel1) | \ + (GDMA_Channelx == GDMA_Channel2) | (GDMA_Channelx == GDMA_Channel3)) + { + GDMA_Channelx->LLP = Address; + } +} + +/** + * \brief Check GDMA suspend channel status. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \return GDMA suspend channel status. + * \retval SET: Inactive. + * \retval RESET: Active. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * FlagStatus flag_status = GDMA_GetSuspendChannelStatus(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus GDMA_GetSuspendChannelStatus(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + if ((GDMA_Channelx->CFG_LOW & GDMA_SUSPEND_CHANNEL_STATUS) == GDMA_SUSPEND_CHANNEL_STATUS) + { + bit_status = SET; + } + + /* Return the selected channel suspend status */ + return bit_status; +} + +/** + * \brief Check GDMA suspend command status. + * \param GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \return GDMA suspend command status. + * \retval SET: Suspend. + * \retval RESET: Not suspend. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * FlagStatus flag_status = GDMA_GetSuspendCmdStatus(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus GDMA_GetSuspendCmdStatus(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + if ((GDMA_Channelx->CFG_LOW & GDMA_SUSPEND_CMD_STATUS) == GDMA_SUSPEND_CMD_STATUS) + { + bit_status = SET; + } + + /* Return the selected channel suspend status */ + return bit_status; +} + +/** + * \brief Check GDMA FIFO status. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the GDMA Channel. + * \return GDMA FIFO status. + * \retval SET: FIFO empty. + * \retval RESET: FIFO not empty. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * FlagStatus flag_status = GDMA_GetFIFOStatus(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus GDMA_GetFIFOStatus(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + if ((GDMA_Channelx->CFG_LOW & GDMA_FIFO_STATUS) != (uint32_t)RESET) + { + + bit_status = SET; + } + + /* Return the selected channel status */ + return bit_status; +} + +/** + * \brief Get GDMA source address. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel. + * \return Source address. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint32_t address = GDMA_GetSrcTransferAddress(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t GDMA_GetSrcTransferAddress(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + uint32_t address = 0; + address = GDMA_Channelx->SAR; + return address; +} + +/** + * \brief Get GDMA destination address. + * \param[in] GDMA_Channelx: Where x can be 0 to 3 to select the DMA Channel. + * \return Destination address. + * + * Example usage + * \code{.c} + * + * void gdma_demo(void) + * { + * uint32_t address = GDMA_GetDstTransferAddress(GDMA_Channel0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t GDMA_GetDstTransferAddress(GDMA_ChannelTypeDef *GDMA_Channelx) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + + uint32_t address = 0; + address = GDMA_Channelx->DAR; + return address; +} + +/** \} */ /* End of group GDMA_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /*_RTL8762X_GDMA_H_*/ + + +/******************* (C) COPYRIGHT 2019 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_gpio.h b/inc/peripheral/rtl876x_gpio.h new file mode 100644 index 0000000..aa66709 --- /dev/null +++ b/inc/peripheral/rtl876x_gpio.h @@ -0,0 +1,805 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_gpio.h +* \brief The header file of the peripheral GPIO driver. +* \details This file provides all GPIO firmware functions. +* \author elliot chen +* \date 2015-05-20 +* \version v1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_GPIO_H_ +#define _RTL876X_GPIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup GPIO GPIO + * + * \brief Manage the GPIO peripheral functions. + * + * \ingroup IO + */ +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/** + * \cond private + * \defgroup GPIO_Debounce_Register GPIO Debounce Register + * \{ + */ + +/** + * \brief GPIO Private Defines + */ +#define GPIO_DBCLK_DIV *((volatile uint32_t *)0x40000344UL) + +/** + * \} + * \endcond + */ + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup GPIO_Exported_Constants Macro Definitions + * + * \ingroup GPIO + */ + +/** + * \defgroup GPIO_Number GPIO Number + * \{ + * \ingroup GPIO_Exported_Constants + */ +#define GPIO0 0 +#define GPIO1 1 +#define GPIO2 2 +#define GPIO3 3 +#define GPIO4 4 +#define GPIO5 5 +#define GPIO6 6 +#define GPIO7 7 +#define GPIO8 8 +#define GPIO9 9 +#define GPIO10 10 +#define GPIO11 11 +#define GPIO12 12 +#define GPIO13 13 +#define GPIO14 14 +#define GPIO15 15 +#define GPIO16 16 +#define GPIO17 17 +#define GPIO18 18 +#define GPIO19 19 +#define GPIO20 20 +#define GPIO21 21 +#define GPIO22 22 +#define GPIO23 23 +#define GPIO24 24 +#define GPIO25 25 +#define GPIO26 26 +#define GPIO27 27 +#define GPIO28 28 +#define GPIO29 29 +#define GPIO30 30 +#define GPIO31 31 +/** \} */ + +/** + * \defgroup GPIO_Pins_Define GPIO Pins Define + * \{ + * \ingroup GPIO_Exported_Constants + */ +#define GPIO_Pin_0 ((uint32_t)0x00000001) /*!< Pin 0 selected */ +#define GPIO_Pin_1 ((uint32_t)0x00000002) /*!< Pin 1 selected */ +#define GPIO_Pin_2 ((uint32_t)0x00000004) /*!< Pin 2 selected */ +#define GPIO_Pin_3 ((uint32_t)0x00000008) /*!< Pin 3 selected */ +#define GPIO_Pin_4 ((uint32_t)0x00000010) /*!< Pin 4 selected */ +#define GPIO_Pin_5 ((uint32_t)0x00000020) /*!< Pin 5 selected */ +#define GPIO_Pin_6 ((uint32_t)0x00000040) /*!< Pin 6 selected */ +#define GPIO_Pin_7 ((uint32_t)0x00000080) /*!< Pin 7 selected */ +#define GPIO_Pin_8 ((uint32_t)0x00000100) /*!< Pin 8 selected */ +#define GPIO_Pin_9 ((uint32_t)0x00000200) /*!< Pin 9 selected */ +#define GPIO_Pin_10 ((uint32_t)0x00000400) /*!< Pin 10 selected */ +#define GPIO_Pin_11 ((uint32_t)0x00000800) /*!< Pin 11 selected */ +#define GPIO_Pin_12 ((uint32_t)0x00001000) /*!< Pin 12 selected */ +#define GPIO_Pin_13 ((uint32_t)0x00002000) /*!< Pin 13 selected */ +#define GPIO_Pin_14 ((uint32_t)0x00004000) /*!< Pin 14 selected */ +#define GPIO_Pin_15 ((uint32_t)0x00008000) /*!< Pin 15 selected */ +#define GPIO_Pin_16 ((uint32_t)0x00010000) /*!< Pin 16 selected */ +#define GPIO_Pin_17 ((uint32_t)0x00020000) /*!< Pin 17 selected */ +#define GPIO_Pin_18 ((uint32_t)0x00040000) /*!< Pin 18 selected */ +#define GPIO_Pin_19 ((uint32_t)0x00080000) /*!< Pin 19 selected */ +#define GPIO_Pin_20 ((uint32_t)0x00100000) /*!< Pin 20 selected */ +#define GPIO_Pin_21 ((uint32_t)0x00200000) /*!< Pin 21 selected */ +#define GPIO_Pin_22 ((uint32_t)0x00400000) /*!< Pin 22 selected */ +#define GPIO_Pin_23 ((uint32_t)0x00800000) /*!< Pin 23 selected */ +#define GPIO_Pin_24 ((uint32_t)0x01000000) /*!< Pin 24 selected */ +#define GPIO_Pin_25 ((uint32_t)0x02000000) /*!< Pin 25 selected */ +#define GPIO_Pin_26 ((uint32_t)0x04000000) /*!< Pin 26 selected */ +#define GPIO_Pin_27 ((uint32_t)0x08000000) /*!< Pin 27 selected */ +#define GPIO_Pin_28 ((uint32_t)0x10000000) /*!< Pin 28 selected */ +#define GPIO_Pin_29 ((uint32_t)0x20000000) /*!< Pin 29 selected */ +#define GPIO_Pin_30 ((uint32_t)0x40000000) /*!< Pin 30 selected */ +#define GPIO_Pin_31 ((uint32_t)0x80000000) /*!< Pin 31 selected */ +#define GPIO_Pin_All ((uint32_t)0xFFFFFFFF) /*!< All pins selected */ +/** \} */ + +#define IS_PIN_NUM(NUM) ((NUM) <= (uint8_t)P4_1) + +#define IS_GPIO_PIN(PIN) ((PIN) != (uint32_t)0x00) + +#define IS_GET_GPIO_PIN(PIN) (((PIN) == GPIO_Pin_0) || \ + ((PIN) == GPIO_Pin_1) || \ + ((PIN) == GPIO_Pin_2) || \ + ((PIN) == GPIO_Pin_3) || \ + ((PIN) == GPIO_Pin_4) || \ + ((PIN) == GPIO_Pin_5) || \ + ((PIN) == GPIO_Pin_6) || \ + ((PIN) == GPIO_Pin_7) || \ + ((PIN) == GPIO_Pin_8) || \ + ((PIN) == GPIO_Pin_9) || \ + ((PIN) == GPIO_Pin_10) || \ + ((PIN) == GPIO_Pin_11) || \ + ((PIN) == GPIO_Pin_12) || \ + ((PIN) == GPIO_Pin_13) || \ + ((PIN) == GPIO_Pin_14) || \ + ((PIN) == GPIO_Pin_15) || \ + ((PIN) == GPIO_Pin_16) || \ + ((PIN) == GPIO_Pin_17) || \ + ((PIN) == GPIO_Pin_18) || \ + ((PIN) == GPIO_Pin_19) || \ + ((PIN) == GPIO_Pin_20) || \ + ((PIN) == GPIO_Pin_21) || \ + ((PIN) == GPIO_Pin_22) || \ + ((PIN) == GPIO_Pin_23) || \ + ((PIN) == GPIO_Pin_24) || \ + ((PIN) == GPIO_Pin_25) || \ + ((PIN) == GPIO_Pin_26) || \ + ((PIN) == GPIO_Pin_27) || \ + ((PIN) == GPIO_Pin_28) || \ + ((PIN) == GPIO_Pin_29) || \ + ((PIN) == GPIO_Pin_30) || \ + ((PIN) == GPIO_Pin_31)) +/** + * \brief Bit_SET and Bit_RESET enumeration + */ +typedef enum +{ + Bit_RESET = 0, + Bit_SET +} BitAction; + +#define IS_GPIO_BIT_ACTION(ACTION) (((ACTION) == Bit_RESET) || ((ACTION) == Bit_SET)) + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup GPIO_Exported_Types GPIO Exported Types + * + * \ingroup GPIO + */ + +/** + * \brief GPIO mode enumeration. + * + * \ingroup GPIO_Exported_Types + */ +typedef enum +{ + GPIO_Mode_IN = 0x00, /**< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /**< GPIO Output Mode */ +} GPIOMode_TypeDef; + +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_IN)|| ((MODE) == GPIO_Mode_OUT)) + +/** + * \brief Setting interrupt trigger type. + * + * \ingroup GPIO_Exported_Types + */ +typedef enum +{ + GPIO_INT_Trigger_LEVEL = 0x0, /**< This interrupt is level trigger. */ + GPIO_INT_Trigger_EDGE = 0x1, /**< This interrupt is edge trigger. */ + GPIO_INT_BOTH_EDGE = 0x2, /**< This interrupt is both edge trigger. */ +} GPIOIT_LevelType; + +#define IS_GPIOIT_LEVEL_TYPE(TYPE) (((TYPE) == GPIO_INT_Trigger_LEVEL)\ + || ((TYPE) == GPIO_INT_Trigger_EDGE)\ + || ((TYPE) == GPIO_INT_BOTH_EDGE)) + +/** + * \brief Setting interrupt active mode. + * + * \ingroup GPIO_Exported_Types + */ +typedef enum +{ + GPIO_INT_POLARITY_ACTIVE_LOW = 0x0, /**< Setting interrupt to low active. */ + GPIO_INT_POLARITY_ACTIVE_HIGH = 0x1, /**< Setting interrupt to high active. */ +} GPIOIT_PolarityType; + +#define IS_GPIOIT_POLARITY_TYPE(TYPE) (((TYPE) == GPIO_INT_POLARITY_ACTIVE_LOW)\ + || ((TYPE) == GPIO_INT_POLARITY_ACTIVE_HIGH)) + +/** + * \brief Enable/Disable interrupt debounce. + * + * \ingroup GPIO_Exported_Types + */ +typedef enum +{ + GPIO_INT_DEBOUNCE_DISABLE = 0x0, /**< Disable interrupt debounce. */ + GPIO_INT_DEBOUNCE_ENABLE = 0x1, /**< Enable interrupt debounce. */ +} GPIOIT_DebounceType; + +#define IS_GPIOIT_DEBOUNCE_TYPE(TYPE) (((TYPE) == GPIO_INT_DEBOUNCE_DISABLE)\ + || ((TYPE) == GPIO_INT_DEBOUNCE_ENABLE)) + +/** + * \brief Hardware/Software mode select. + * + * \ingroup GPIO_Exported_Types + */ +typedef enum +{ + GPIO_SOFTWARE_MODE = 0x0, /**< GPIO software mode(default). */ + GPIO_HARDWARE_MODE = 0x1, /**< GPIO hardware control mode. */ +} GPIOControlMode_Typedef; + +#define IS_GPIOIT_MODDE(TYPE) (((TYPE) == GPIO_SOFTWARE_MODE)\ + || ((TYPE) == GPIO_HARDWARE_MODE)) + +/** + * \brief GPIO init structure definition. + * + * \ingroup GPIO_Exported_Types + */ +typedef struct +{ + uint32_t GPIO_Pin; /**< Specifies the GPIO pins to be configured. + This parameter can be any value of \ref GPIO_Pins_Define */ + GPIOMode_TypeDef + GPIO_Mode; /**< Specifies the operating mode for the selected pins. */ + FunctionalState GPIO_ITCmd; /**< Enable or disable GPIO interrupt. + This parameter can be a value of DISABLE or ENABLE. */ + GPIOIT_LevelType GPIO_ITTrigger; /**< Interrupt mode is level or edge trigger. */ + GPIOIT_PolarityType GPIO_ITPolarity; /**< Interrupt mode is high or low active trigger. */ + GPIOIT_DebounceType GPIO_ITDebounce; /**< Enable or disable de-bounce for interrupt. */ + GPIOControlMode_Typedef GPIO_ControlMode; /**< Specifies the gpio control mode. */ + uint32_t GPIO_DebounceTime; /**< Specifies the gpio debounce time(ms). */ +} GPIO_InitTypeDef; + + +/*============================================================================* + * Functions + *============================================================================*/ + + +/** + * \defgroup GPIO_Exported_Functions Peripheral APIs + * \{ + * \ingroup GPIO + */ + +/** + * \brief Deinitializes the GPIO peripheral registers to their default reset values. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gpio_init(void) + * { + * GPIO_DeInit(); + * } + * \endcode + */ +void GPIO_DeInit(void); + +/** + * \brief Initializes the GPIO peripheral according to the specified + * parameters in the GPIO_InitStruct. + * \param[in] GPIO_InitStruct: Pointer to a GPIO_InitTypeDef structure that + * contains the configuration information for the specified GPIO peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gpio_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + * + * GPIO_InitTypeDef GPIO_InitStruct; + * GPIO_StructInit(&GPIO_InitStruct); + * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0); + * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; + * GPIO_InitStruct.GPIO_ITCmd = ENABLE; + * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + * GPIO_InitStruct.GPIO_DebounceTime = 10; + * GPIO_Init(&GPIO_InitStruct); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = GPIO28_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE); + * } + * \endcode + */ +void GPIO_Init(GPIO_InitTypeDef *GPIO_InitStruct); + +/** + * \brief Fills each GPIO_InitStruct member with its default value. + * \param[in] GPIO_InitStruct: Pointer to a GPIO_InitTypeDef structure which will + * be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gpio_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + * + * GPIO_InitTypeDef GPIO_InitStruct; + * GPIO_StructInit(&GPIO_InitStruct); + * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0); + * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; + * GPIO_InitStruct.GPIO_ITCmd = ENABLE; + * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + * GPIO_InitStruct.GPIO_DebounceTime = 10; + * GPIO_Init(&GPIO_InitStruct); + * } + * \endcode + */ +void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct); + +/** + * \brief Enable the specified GPIO pin interrupt. + * \param[in] GPIO_Pin: Where x can be 0 or 31. + * \param[in] NewState: Enable or disable interrupt + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_gpio_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + * + * GPIO_InitTypeDef GPIO_InitStruct; + * GPIO_StructInit(&GPIO_InitStruct); + * GPIO_InitStruct.GPIO_Pin = GPIO_GetPin(P4_0); + * GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; + * GPIO_InitStruct.GPIO_ITCmd = ENABLE; + * GPIO_InitStruct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + * GPIO_InitStruct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + * GPIO_InitStruct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + * GPIO_InitStruct.GPIO_DebounceTime = 10; + * GPIO_Init(&GPIO_InitStruct); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = GPIO28_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE); + * } + * \endcode + */ +void GPIO_INTConfig(uint32_t GPIO_Pin, FunctionalState NewState); + +/** + * \brief Clear the specified GPIO pin interrupt pending bit. + * \param[in] GPIO_Pin: Where x can be 0 or 31. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * driver_gpio_init(); + * } + * + * void GPIO28_Handler(void) + * { + * GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE); + * //Add user code here. + * GPIO_ClearINTPendingBit(GPIO_PIN_INPUT); + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE); +} + * \endcode + */ +void GPIO_ClearINTPendingBit(uint32_t GPIO_Pin); + +/** + * \brief Mask the specified GPIO pin interrupt. + * \param[in] GPIO_Pin: Where x can be 0 or 31. + * \param[in] NewState: Disable or enable interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * + * void gpio_demo(void) + * { + * driver_gpio_init(); + * } + * + * void GPIO28_Handler(void) + * { + * GPIO_INTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, ENABLE); + * + * //Add user code here. + * + * GPIO_ClearINTPendingBit(GPIO_PIN_INPUT); + * GPIO_MaskINTConfig(GPIO_PIN_INPUT, DISABLE); + * GPIO_INTConfig(GPIO_PIN_INPUT, ENABLE); + * } + * \endcode + */ +void GPIO_MaskINTConfig(uint32_t GPIO_Pin, FunctionalState NewState); + +/** + * \brief Get the GPIO_Pin through the given PAD num. + * \param[in] Pin_num: Pad num which can be from P0_0 to H_2, please refer to rtl876x.h "Pin_Number" part. + * \retval GPIO_Pin for GPIO initialization. + * + * Example usage + * \code{.c} + * + * void driver_gpio_init(void) + * { + * uint32_t gpio_pin = GPIO_GetPin(P4_0); + * //result: gpio_pin = GPIO_Pin_28 + * } + * \endcode + */ +uint32_t GPIO_GetPin(uint8_t Pin_num); + +/** + * \brief Get GPIOx(x is 0~31) value through the given pad. + * \param[in] Pin_num: Pad num which can be from P0_0 to H_2, please refer to rtl876x.h "Pin_Number" part. + * \return GPIOx(x is 0~31) value. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * uint8_t gpio_num = GPIO_GetNum(P4_0); + * //result: gpio_num = 28 + * } + * \endcode + */ +uint8_t GPIO_GetNum(uint8_t Pin_num); + +/** + * \brief Enable GPIO debounce clock. + * \param[in] NewState: Disable or enable debounce clock. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_DBClkCmd(ENABLE); + * } + * \endcode + */ +void GPIO_DBClkCmd(FunctionalState NewState); + +/** + * \brief Read the specified input port pin. + * \param[in] GPIO_Pin: Specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be 0~31. + * \return The input port pin value. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * uint8_t input_bit = GPIO_ReadInputDataBit(GPIO_GetPin(P4_0)); + * } + * \endcode + */ +__STATIC_INLINE uint8_t GPIO_ReadInputDataBit(uint32_t GPIO_Pin) +{ + uint8_t bitstatus = RESET; + uint32_t data_in = GPIO->DATAIN; + + /* Check the parameters */ + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if (GPIO->DATAIN & GPIO_Pin) + { + bitstatus = (uint8_t)SET; + } + + return bitstatus; +} + +/** + * \brief Read value of all GPIO input data port. + * \param None. + * \return GPIO input data port value. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * uint32_t input_data = GPIO_ReadInputData(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t GPIO_ReadInputData(void) +{ + return GPIO->DATAIN; +} + +/** + * \brief Read the specified output port pin. + * \param[in] GPIO_Pin: Specifies the port bit to read. + * This parameter can be GPIO_Pin_x where x can be 0~31. + * \retval The output port pin value. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * uint8_t output_bit = GPIO_ReadOutputDataBit(GPIO_GetPin(P4_0)); + * } + * \endcode + */ +__STATIC_INLINE uint8_t GPIO_ReadOutputDataBit(uint32_t GPIO_Pin) +{ + uint8_t bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if (GPIO->DATAOUT & GPIO_Pin) + { + bitstatus = (uint8_t)SET; + } + + return bitstatus; +} + +/** + * \brief Read value of all GPIO output data port. + * \param None. + * \return GPIO output data port value. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * uint32_t output_data = GPIO_ReadOutputData(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t GPIO_ReadOutputData(void) +{ + return ((uint32_t)GPIO->DATAOUT); +} + +/** + * \brief Sets the selected data port bit. + * \param[in] GPIO_Pin: Specifies the port bit to be written. + * This parameter can be GPIO_Pin_x where x can be 0~31 or GPIO_Pin_All. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_SetBits(GPIO_GetPin(P4_0)); + * } + * \endcode + */ +__STATIC_INLINE void GPIO_SetBits(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIO->DATAOUT |= GPIO_Pin; +} + +/** + * \brief Reset the selected data port bit. + * \param[in] GPIO_Pin: Specifies the port bits to be written. + * This parameter can be GPIO_Pin_0 to GPIO_Pin_31 or GPIO_Pin_All. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_ResetBits(GPIO_GetPin(P4_0)); + * } + * \endcode + */ +__STATIC_INLINE void GPIO_ResetBits(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIO->DATAOUT &= ~(GPIO_Pin); +} + +/** + * \brief Set or clear the selected data port bit. + * \param[in] GPIO_Pin: Specifies the port bit to be written. + * This parameter can be one of GPIO_Pin_x where x can be 0~31. + * \param[in] BitVal: specifies the value to be written to the selected bit. + * This parameter can be one of the BitAction enum values: + * \arg Bit_RESET: To clear the port pin. + * \arg Bit_SET: To set the port pin. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_WriteBit(GPIO_GetPin(P4_0), Bit_SET); + * } + * \endcode + */ +__STATIC_INLINE void GPIO_WriteBit(uint32_t GPIO_Pin, BitAction BitVal) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_BIT_ACTION(BitVal)); + + if (BitVal != Bit_RESET) + { + GPIO->DATAOUT |= GPIO_Pin; + } + else + { + GPIO->DATAOUT &= ~(GPIO_Pin); + } +} + +/** + * \brief Set or clear data port. + * \param[in] PortVal: Specifies the value to be written to the selected bit. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_Write(0xFFFFFFFF); + * } + * \endcode + */ +__STATIC_INLINE void GPIO_Write(uint32_t PortVal) +{ + GPIO->DATAOUT = PortVal; +} + +/** + * \brief Get GPIO interrupt status. + * \param[in] GPIO_Pin: Specifies the port bit to be written. + * This parameter can be one of GPIO_Pin_x where x can be 0~31. + * \retturn The new state of GPIO_IT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * ITStatus int_status = GPIO_GetINTStatus(GPIO_GetPin(P4_0)); + * } + * \endcode + */ +__STATIC_INLINE ITStatus GPIO_GetINTStatus(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); + + if ((GPIO->INTSTATUS & GPIO_Pin) == GPIO_Pin) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * \brief Set debounce time. + * \param[in] DebounceTime: Specifies interrupt debounce time. + * This parameter can be 1ms ~ 64ms. + * \return None. + * + * Example usage + * \code{.c} + * + * void gpio_demo(void) + * { + * GPIO_Debounce_Time(10); + * } + * \endcode + */ +__STATIC_INLINE void GPIO_Debounce_Time(uint32_t DebounceTime) +{ + uint8_t count = 0; + + if (DebounceTime < 1) + { + DebounceTime = 1; + } + if (DebounceTime > 64) + { + DebounceTime = 64; + } +#ifdef _IS_ASIC_ + //div = 14;//0xd 0b1101<<8 + GPIO_DBCLK_DIV = ((0xd << 8) | (1 << 12)); +#else + //div = 13;//0xc 0b1100<<8 + GPIO_DBCLK_DIV |= ((1 << 11) | (1 << 10) | (1 << 12)); + GPIO_DBCLK_DIV &= (~((1 << 9) | (1 << 8))); +#endif + count = (244 * DebounceTime) / 100 - 1; + GPIO_DBCLK_DIV &= (~((0xff << 0))); + GPIO_DBCLK_DIV = GPIO_DBCLK_DIV + count; +} + +/** \} */ /* End of group GPIO_Exported_Functions */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_GPIO_H_ */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_hw_aes.h b/inc/peripheral/rtl876x_hw_aes.h new file mode 100644 index 0000000..440c2c0 --- /dev/null +++ b/inc/peripheral/rtl876x_hw_aes.h @@ -0,0 +1,181 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file rtl876x_hw_aes.h +* @brief +* @details +* @author eason li +* @date 2016-01-04 +* @version v0.1 +* ********************************************************************************************************* +*/ + +#ifndef __RTL876X_HW_AES_H +#define __RTL876X_HW_AES_H + +#ifdef __cplusplus +extern "C" { +#endif +/* Includes ------------------------------------------------------------------*/ +#include +#include "rtl876x.h" +#include "hw_aes.h" + +/** + * @brief referenc to hw aes register table + */ +typedef struct +{ + union + { + __IO uint32_t CTL; + struct + { + __IO uint32_t enc_en: 1; /* aes encryption enable */ + __IO uint32_t dec_en: 1; /* aes decryption enable */ + __IO uint32_t ase256_en: 1; /* aes 256-bit mode enable */ + __IO uint32_t aes_mode_sel: 3; /* aes mode select, see HW_AES_MODE below */ + __IO uint32_t access_mode: 1; /* 0: CPU mode, 1: DMA mode */ + __IO uint32_t scram_en: 1; /* scramble function, 0:disable, 1:enable */ + __IO uint32_t use_hidden_key: 1; /* secure related */ + __IO uint32_t copy_hidden_key: 1; /* secure related */ + __IO uint32_t hidden_256: 1; /* secure related */ + __IO uint32_t poly_en: 1; /* XOR polynomial, 0:disable, 1:enable */ + __IO uint32_t rsvd: 19; + __IO uint32_t dout_rdy: 1; /* aes data output ready signal used in CPU mode. + when data output is ready, dout_rdy = 1. + if dout_rdy == 1, "CPU reads enc_dout or dec_dout + for 4 times (128 bits)" will clear dout_rdy to 0. + */ + } CTL_BITS; + }; + __IO uint32_t data_in; + __I uint32_t enc_dout; + __I uint32_t dec_dout; + __IO uint32_t IRK[8]; + __IO uint32_t iv[4]; + union + { + __O uint32_t secure_reg[13]; + struct + { + __O uint32_t RPZ0_CMP_ADDR_TOP_H; /* 0x40 */ + __O uint32_t RPZ0_CMP_ADDR_TOP_L; /* 0x44 */ + __O uint32_t RPZ0_CMP_ADDR_BUTTOM_H; /* 0x48 */ + __O uint32_t RPZ0_CMP_ADDR_BUTTOM_L; /* 0x4C */ + __O uint32_t RPZ1_CMP_ADDR_TOP_H; /* 0x50 */ + __O uint32_t RPZ1_CMP_ADDR_TOP_L; /* 0x54 */ + __O uint32_t RPZ1_CMP_ADDR_BUTTOM_H; /* 0x58 */ + __O uint32_t RPZ1_CMP_ADDR_BUTTOM_L; /* 0x5C */ + __O uint32_t RPZ_SWD_CTRL; /* 0x60 */ + __O uint32_t DSP_MEM_CTRL_H; /* 0x64 */ + __O uint32_t DSP_MEM_CTRL_L; /* 0x68 */ + __O uint32_t rsvd; /* 0x6C */ + __O uint32_t reg_buf_cache_sram_en; /* 0x70 */ + }; + }; + union + { + __IO uint32_t secure_status; + struct + { + __IO uint32_t cnt: 4; + __IO uint32_t S: 1; + __IO uint32_t irk_cnt: 3; + __IO uint32_t rsvd: 8; + __IO uint32_t hash_: 16; + } SEC_STS; + }; + __O uint32_t authentication; +} HW_AES_TypeDef; + +#define HWAES_CTL 0x0 +#define HWAES_DATAIN 0x4 +#define HWAES_ENC_DOUT 0x8 +#define HWAES_DEC_DOUT 0xC +#define HWAES_IRK 0x10 +#define HWAES_IV 0x30 +#define HWAES_SEC_REG 0x40 +#define HWAES_SEC_STS 0x74 +#define HWAES_AUTHEN 0x78 + + +typedef enum +{ + CPU_MODE, + DMA_MODE +} HW_AES_ACCESS_MODE; + +#define DMA_CH_BASE(ChNum) (GDMA_CHANNEL_REG_BASE + ChNum * 0x0058) +#define DMA_CH_IRQ(ChNum) ((GDMA0_Channel0_IRQn + ChNum)) +#define HW_AES_RX_DMA_IO_NUM 14 +#define HW_AES_TX_DMA_IO_NUM 13 + +#define HW_AES_SET_ENC_EN(isEnable) (HWAES->CTL_BITS.enc_en = isEnable) +#define HW_AES_SET_DEC_EN(isEnable) (HWAES->CTL_BITS.dec_en = isEnable) +#define HW_AES_SET_256_EN(isEnable) (HWAES->CTL_BITS.ase256_en = isEnable) +#define HW_AES_GET_256_EN (HWAES->CTL_BITS.ase256_en) +#define HW_AES_SET_AES_MODE(mode) (HWAES->CTL_BITS.aes_mode_sel = (mode & 0x7)) +#define HW_AES_SET_WORK_MODE(mode) (HWAES->CTL_BITS.access_mode = (mode & BIT0)) +#define HW_AES_IS_DATA_OUT_READY (HWAES->CTL_BITS.dout_rdy) +#define HW_AES_SET_INPUT_DATA(data) (HWAES->data_in = (uint32_t)data) +#define HW_AES_READ_ENC_OUTPUT(Out) (Out = HWAES->enc_dout) +#define HW_AES_READ_DEC_OUTPUT(Out) (Out = HWAES->dec_dout) +#define HW_AES_SET_IRK(pIRK, cnt) for (uint8_t i = 0;i < cnt;i ++) {HWAES->IRK[(cnt - 1) - i] = pIRK[i];} +#define HW_AES_GET_IRK(pIRK, cnt) for (uint8_t i = 0;i < cnt;i ++) {pIRK[i] = HWAES->IRK[(cnt - 1) - i];} +#define HW_AES_SET_IV(pIV) for (uint8_t i = 0;i < 4;i ++) {HWAES->iv[3 - i] = pIV[i];} +#define HW_AES_GET_IV(pIV) for (uint8_t i = 0;i < 4;i ++) {pIV[i] = HWAES->iv[3 - i];} +#define HW_AES_SET_SCRAMBLE_EN(isEnable) (HWAES->CTL_BITS.scram_en = isEnable) +#define HW_AES_USE_HIDDEN_KEY(isEnable) (HWAES->CTL_BITS.use_hidden_key = isEnable) +#define HW_AES_COPY_HIDDEN_KEY(isEnable) (HWAES->CTL_BITS.copy_hidden_key = isEnable) +#define HW_AES_SET_HIDDEN_256(isEnable) (HWAES->CTL_BITS.hidden_256 = isEnable) + +#define HWAES_DMA_RX_CH_NUM 2 +#define HWAES_DMA_TX_CH_NUM 1 +#define HWAES_DMA_RX_CH GDMA_Channel2 +#define HWAES_DMA_TX_CH GDMA_Channel1 +#define HWAES_DMA_RX_HANDLER GDMA0_Channel2_Handler +#define HWAES_DMA_TX_HANDLER GDMA0_Channel1_Handler +#define MAX_DMA_BUF_SZ 0xFF0 + +#if 1 +#define AES_INFO(...) DBG_DIRECT(__VA_ARGS__); +#else +#define AES_INFO(...) +#endif +__STATIC_INLINE void hw_aes_clear(void) +{ + HWAES->CTL = 0; +} +__STATIC_INLINE void hw_aes_set_clk(bool is_enable) +{ + /* turn on hw aes clock */ + SYSBLKCTRL->u_238.BITS_238.r_PON_ACTCKE_AES = is_enable; + + /* enable hw aes */ + SYSBLKCTRL->u_218.BITS_218.r_PON_FEN_AES = is_enable; +} + +bool hw_aes_init(const uint32_t *aesKey, uint32_t *iv, T_HW_AES_MODE work_mode, bool isAes256); +bool hw_aes_cpu_operate(uint32_t *in, uint32_t *out, uint32_t word_len, bool isEncrypt); +bool hw_aes_dma_operate(uint32_t *in, uint32_t *out, uint32_t word_len, bool isEncrypt, + uint8_t dma_rx_ch_num, uint8_t dma_tx_ch_num, bool isMac); +void hw_aes_set_dma_rx_done(bool isDone); +bool hw_aes_is_dma_rx_done(void); +void hw_aes_set_dma_tx_done(bool isDone); +bool hw_aes_is_dma_tx_done(void); +bool hw_aes_dma_done(void); +void hw_aes_dma_interrupt_disable(void); +void hw_aes_set_dma_move_src(uint32_t src); +void hw_aes_set_dma_move_dst(uint32_t dst); +void hw_aes_set_dma_carry_size(uint32_t size); +bool aes_cmac_inverse(uint8_t *key, uint8_t *input, uint32_t length, uint8_t *mac, int mode); +uint32_t get_secure_reg_cfg_val(uint32_t in_val); + +void share_dsp_and_cache_ram_rom(void); + +#ifdef __cplusplus +} +#endif +#endif /*__RTL8762X_GDMA_H*/ diff --git a/inc/peripheral/rtl876x_i2c.h b/inc/peripheral/rtl876x_i2c.h new file mode 100644 index 0000000..6452f63 --- /dev/null +++ b/inc/peripheral/rtl876x_i2c.h @@ -0,0 +1,876 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_i2c.h +* \brief The header file of the peripheral I2C driver. +* \details This file provides all I2C firmware functions. +* \author elliot chen +* \date 2015-4-20 +* \version v1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_I2C_H_ +#define _RTL876X_I2C_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup I2C I2C + * + * \brief Manage the I2C peripheral functions. + * + * \ingroup IO + */ + + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup I2C_Exported_Types Init Params Struct + * + * \ingroup I2C + */ + +/** + * \brief I2C init structure definition. + * + * \ingroup I2C_Exported_Types + */ + +typedef struct +{ + uint32_t I2C_Clock; /*!< Specifies the clock frequency,default 40000000. + This parameter must be set with I2C clock div. */ + uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz. */ + uint16_t I2C_DeviveMode; /*!< Specifies the I2C devie mode. + This parameter can be a value of \ref I2C_Device_Mode. */ + uint16_t I2C_AddressMode; /*!< Specifies the I2C address mode. + This parameter can be a value of \ref I2C_Address_Mode. */ + uint16_t I2C_SlaveAddress; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement only in slave mode. + This parameter can be a value of \ref I2C_Acknowledgement. */ + uint32_t I2C_TxThresholdLevel; /* !< Specifies the transmit FIFO Threshold to trigger interrupt I2C_INT_TX_EMPTY. + This parameter can be a value less than 24*/ + uint32_t I2C_RxThresholdLevel; /* != 0x01) && ((SPEED) <= 400000)) + +/** + * \defgroup I2C_Device_Mode I2C Device Mode + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_DeviveMode_Master ((uint16_t)0x0041) +#define I2C_DeviveMode_Slave ((uint16_t)0x0000) +/** \} */ + +/** + * \defgroup I2C_Address_Mode I2C Address Mode + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_AddressMode_7BIT ((uint16_t)0x0000) +#define I2C_AddressMode_10BIT ((uint16_t)0x0001) +/** \} */ + +/** + * \defgroup I2C_Acknowledgement I2C Acknowledgement + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_Ack_Enable ((uint16_t)0x0001) +#define I2C_Ack_Disable ((uint16_t)0x0000) +/** \} */ + +/** + * \defgroup I2C_Flags_Definition I2C Flags Definition + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_FLAG_SLV_ACTIVITY ((uint32_t)0x00000040) +#define I2C_FLAG_MST_ACTIVITY ((uint32_t)0x00000020) +#define I2C_FLAG_RFF ((uint32_t)0x00000010) +#define I2C_FLAG_RFNE ((uint32_t)0x00000008) +#define I2C_FLAG_TFE ((uint32_t)0x00000004) +#define I2C_FLAG_TFNF ((uint32_t)0x00000002) +#define I2C_FLAG_ACTIVITY ((uint32_t)0x00000001) +/** \} */ + +#define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_SLV_ACTIVITY) || ((FLAG) == I2C_FLAG_MST_ACTIVITY) || \ + ((FLAG) == I2C_FLAG_RFF) || ((FLAG) == I2C_FLAG_RFNE) || \ + ((FLAG) == I2C_FLAG_TFE) || ((FLAG) == I2C_FLAG_TFNF) || \ + ((FLAG) == I2C_FLAG_ACTIVITY)) +/** + * \defgroup I2C_Transmit_Abort_Source I2C Transmit Abort Source + * \{ + * \ingroup I2C_Exported_Constants + */ +#define ABRT_SLVRD_INTX ((uint32_t)BIT(15)) +#define ABRT_SLV_ARBLOST ((uint32_t)BIT(14)) +#define ABRT_SLVFLUSH_TXFIFO ((uint32_t)BIT(13)) +#define ARB_LOST ((uint32_t)BIT(12)) +#define ABRT_MASTER_DIS ((uint32_t)BIT(11)) +#define ABRT_10B_RD_NORSTRT ((uint32_t)BIT(10)) +#define ABRT_SBYTE_NORSTRT ((uint32_t)BIT(9)) +#define ABRT_HS_NORSTRT ((uint32_t)BIT(8)) +#define ABRT_SBYTE_ACKDET ((uint32_t)BIT(7)) +#define ABRT_HS_ACKDET ((uint32_t)BIT(6)) +#define ABRT_GCALL_READ ((uint32_t)BIT(5)) +#define ABRT_GCALL_NOACK ((uint32_t)BIT(4)) +#define ABRT_TXDATA_NOACK ((uint32_t)BIT(3)) +#define ABRT_10ADDR2_NOACK ((uint32_t)BIT(2)) +#define ABRT_10ADDR1_NOACK ((uint32_t)BIT(1)) +#define ABRT_7B_ADDR_NOACK ((uint32_t)BIT(0)) +/** \} */ + +#define MS_ALL_ABORT (ARB_LOST | ABRT_MASTER_DIS | ABRT_TXDATA_NOACK |\ + ABRT_10ADDR2_NOACK | ABRT_10ADDR1_NOACK | ABRT_7B_ADDR_NOACK) + +#define IS_I2C_EVENT(EVENT) (((EVENT) == ABRT_SLVRD_INTX) || \ + ((EVENT) == ABRT_SLV_ARBLOST) || \ + ((EVENT) == ABRT_SLVFLUSH_TXFIFO) || \ + ((EVENT) == ARB_LOST) || \ + ((EVENT) == ABRT_MASTER_DIS) || \ + ((EVENT) == ABRT_10B_RD_NORSTRT) || \ + ((EVENT) == ABRT_SBYTE_NORSTRT) || \ + ((EVENT) == ABRT_HS_NORSTRT) || \ + ((EVENT) == ABRT_SBYTE_ACKDET) || \ + ((EVENT) == ABRT_HS_ACKDET) || \ + ((EVENT) == ABRT_GCALL_READ) || \ + ((EVENT) == ABRT_GCALL_NOACK) || \ + ((EVENT) == ABRT_TXDATA_NOACK) || \ + ((EVENT) == ABRT_10ADDR2_NOACK) || \ + ((EVENT) == ABRT_10ADDR1_NOACK) || \ + ((EVENT) == ABRT_7B_ADDR_NOACK)) + +/** + * \defgroup I2C_Interrupts_Definition I2C Interrupts Definition + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_INT_GEN_CALL ((uint32_t)BIT(11)) +#define I2C_INT_START_DET ((uint32_t)BIT(10)) +#define I2C_INT_STOP_DET ((uint32_t)BIT(9)) +#define I2C_INT_ACTIVITY ((uint32_t)BIT(8)) +#define I2C_INT_RX_DONE ((uint32_t)BIT(7)) +#define I2C_INT_TX_ABRT ((uint32_t)BIT(6)) +#define I2C_INT_RD_REQ ((uint32_t)BIT(5)) +#define I2C_INT_TX_EMPTY ((uint32_t)BIT(4)) +#define I2C_INT_TX_OVER ((uint32_t)BIT(3)) +#define I2C_INT_RX_FULL ((uint32_t)BIT(2)) +#define I2C_INT_RX_OVER ((uint32_t)BIT(1)) +#define I2C_INT_RX_UNDER ((uint32_t)BIT(0)) +/** \} */ + +#define I2C_GET_INT(INT) (((INT) == I2C_INT_GEN_CALL) || ((INT) == I2C_INT_START_DET) || \ + ((INT) == I2C_INT_STOP_DET) || ((INT) == I2C_INT_ACTIVITY) || \ + ((INT) == I2C_INT_RX_DONE) || ((INT) == I2C_INT_TX_ABRT) || \ + ((INT) == I2C_INT_RD_REQ) || ((INT) == I2C_INT_TX_EMPTY) || \ + ((INT) == I2C_INT_TX_OVER) || ((INT) == I2C_INT_RX_FULL) || \ + ((INT) == I2C_INT_RX_OVER) || ((INT) == I2C_INT_RX_UNDER)) + +/** + * \defgroup I2C_GDMA_Transfer_Requests I2C GDMA transfer requests + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_GDMAReq_Tx ((uint16_t)0x0002) +#define I2C_GDMAReq_Rx ((uint16_t)0x0001) +/** \} */ +#define IS_I2C_GDMAREQ(GDMAREQ) ((((GDMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((GDMAREQ) != 0x00)) + +/** + * \defgroup I2C_Send_Command I2C Send Command + * \{ + * \ingroup I2C_Exported_Constants + */ +#define I2C_WRITE_CMD 0 +#define I2C_READ_CMD BIT(8) +/** \} */ +#define IS_I2C_CMD(CMD) (((CMD) == I2C_WRITE_CMD) || ((CMD) == I2C_READ_CMD)) + +/** + * \defgroup I2C_Send_Stop I2C Send Stop + * \{ + * \ingroup I2C_Exported_Constants + */ + +#define I2C_STOP_ENABLE BIT(9) +#define I2C_STOP_DISABLE 0 +/** \} */ + +#define IS_I2C_STOP(CMD) (((CMD) == I2C_STOP_ENABLE) || ((CMD) == I2C_STOP_DISABLE)) + +/** + * \brief I2C status. + * + * \ingroup I2C_Exported_Constants + */ +typedef enum +{ + I2C_Success, + I2C_ARB_LOST, + I2C_ABRT_MASTER_DIS, + I2C_ABRT_TXDATA_NOACK, + I2C_ABRT_10ADDR2_NOACK, + I2C_ABRT_10ADDR1_NOACK, + I2C_ABRT_7B_ADDR_NOACK, + I2C_ERR_TIMEOUT +} I2C_Status; + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup I2C_Exported_functions Peripheral APIs + * \{ + * \ingroup I2C + */ + +/** + * \brief Deinitializes the I2Cx peripheral registers to their default reset values. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2c0_init(void) + * { + * I2C_DeInit(I2C0); + * } + * \endcode + */ +void I2C_DeInit(I2C_TypeDef *I2Cx); + +/** + * \brief Initializes the I2Cx peripheral according to the specified + * parameters in the I2C_InitStruct. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] I2C_InitStruct: Pointer to a I2C_InitTypeDef structure that + * contains the configuration information for the specified I2C peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2c0_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE); + * + * I2C_InitTypeDef I2C_InitStruct; + * I2C_StructInit(&I2C_InitStruct); + * + * I2C_InitStruct.I2C_ClockSpeed = 100000; + * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master; + * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT; + * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS; + * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + * + * I2C_Init(I2C0, &I2C_InitStruct); + * I2C_Cmd(I2C0, ENABLE); + * } + * \endcode + */ +void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct); + +/** + * \brief Enable or disable the specified I2C peripheral. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] NewState: New state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2c0_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE); + * + * I2C_InitTypeDef I2C_InitStruct; + * I2C_StructInit(&I2C_InitStruct); + * + * I2C_InitStruct.I2C_ClockSpeed = 100000; + * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master; + * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT; + * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS; + * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + * + * I2C_Init(I2C0, &I2C_InitStruct); + * I2C_Cmd(I2C0, ENABLE); + * } + * \endcode + */ +void I2C_Cmd(I2C_TypeDef *I2Cx, FunctionalState NewState); + +/** + * \brief Fills each I2C_InitStruct member with its default value. + * \param[in] I2C_InitStruct: Pointer to a I2C_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2c0_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE); + * + * I2C_InitTypeDef I2C_InitStruct; + * I2C_StructInit(&I2C_InitStruct); + * + * I2C_InitStruct.I2C_ClockSpeed = 100000; + * I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master; + * I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT; + * I2C_InitStruct.I2C_SlaveAddress = STK8321_ADDRESS; + * I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + * + * I2C_Init(I2C0, &I2C_InitStruct); + * I2C_Cmd(I2C0, ENABLE); + * } + * \endcode + */ +void I2C_StructInit(I2C_InitTypeDef *I2C_InitStruct); + +/** + * \brief Send data in master mode through the I2Cx peripheral. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] pBuf: Byte to be transmitted. + * \param[in] len: Data length to send. + * \return I2C status \ref I2C_Status. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t data[10] = {0x01,x0x02,0x03,0x04}; + * I2C_MasterWrite(I2C0, data, 4); + * } + * \endcode + */ +I2C_Status I2C_MasterWrite(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len); + +/** + * \brief Read data in master mode through the I2Cx peripheral. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] pBuf: Data buffer to receive data. + * \param[in] len: Read data length. + * \return I2C status \ref I2C_Status. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t data[10] = {0}; + * I2C_MasterRead(I2C0, data, 10); + * } + * \endcode + */ +I2C_Status I2C_MasterRead(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len); + +/** + * \brief Sends data and read data in master mode through the I2Cx peripheral. + * Attention:Read data with time out mechanism. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] pWriteBuf: Data buffer to send before read. + * \param[in] Writelen: Send data length. + * \param[in] pReadBuf: Data buffer to receive. + * \param[in] Readlen: Receive data length. + * \return I2C status \ref I2C_Status. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t tx_data[10] = {0x01,x0x02,0x03,0x04}; + * uint8_t rx_data[10] = {0}; + * I2C_RepeatRead(I2C0, tx_data, 4, rx_data, 10); + * } + * \endcode + */ +I2C_Status I2C_RepeatRead(I2C_TypeDef *I2Cx, uint8_t *pWriteBuf, uint16_t Writelen, + uint8_t *pReadBuf, uint16_t Readlen); + +/** + * \brief mask the specified I2C interrupt. + * \param[in] I2Cx: Where x can be 0 or 1. + * \param[in] I2C_IT + * This parameter can be one of the following values: + * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged. + * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C + interface regardless of whether I2C is operating in slave or master mode. + * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless + of whether I2C is operating in slave or master mode + * \arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared. + * \arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the + master does not acknowledge a transmitted byte. This occurs on the last byte of + the transmission, indicating that the transmission is done. + * \arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the + intended actions on the contents of the transmit FIFO. + * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master + is attempting to read data. + * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set + in the IC_TX_TL register. + * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and + the processor attempts to issue another I2C command. + * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the + IC_RX_TL register + * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an + additional byte is received from an external I2C device. + * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading. + * \param[in] NewState: Disable or enable I2C interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET); + * I2C_INTConfig(I2C0, I2C_INT_STOP_DET, ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = I2C0_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + * } + * \endcode + */ +void I2C_INTConfig(I2C_TypeDef *I2Cx, uint16_t I2C_IT, FunctionalState NewState); + +/** + * \brief Clear the specified I2C interrupt pending bit. + * \param[in] I2Cx: Where x can be 0 or 1. + * \param[in] I2C_IT + * This parameter can be one of the following values: + * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged. + * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C + interface regardless of whether I2C is operating in slave or master mode. + * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless + of whether I2C is operating in slave or master mode + * \arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared. + * \arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the + master does not acknowledge a transmitted byte. This occurs on the last byte of + the transmission, indicating that the transmission is done. + * \arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the + intended actions on the contents of the transmit FIFO. + * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master + is attempting to read data. + * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set + in the IC_TX_TL register. + * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and + the processor attempts to issue another I2C command. + * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the + IC_RX_TL register + * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an + additional byte is received from an external I2C device. + * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading. + + * \return None. + * + * Example usage + * \code{.c} + * + * void I2C0_Handler(void) + * { + * if (I2C_GetINTStatus(I2C0, I2C_INT_STOP_DET) == SET) + * { + * //Add user code here. + * I2C_ClearINTPendingBit(I2C0, I2C_INT_STOP_DET); + * } + * } + * \endcode + */ +void I2C_ClearINTPendingBit(I2C_TypeDef *I2Cx, uint16_t I2C_IT); + +/** + * \brief Set slave device address. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] Address: Specifies the slave address which will be transmitte. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * I2C_SetSlaveAddress(I2C0, 0x55); + * } + * \endcode + */ +__STATIC_INLINE void I2C_SetSlaveAddress(I2C_TypeDef *I2Cx, uint16_t Address) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Mask target address */ + I2Cx->IC_TAR &= ~((uint16_t)0x3ff); + /* Configure new target address */ + I2Cx->IC_TAR |= Address & 0x3ff; +} + +/** + * \brief Write command through the I2Cx peripheral. + * \param[in] I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * \param[in] command: command of write or read. + * \arg I2C_READ_CMD: Read command. Data which want to transmit can be 0 in this situation. + * \arg I2C_WRITE_CMD: Write command. + * \param[in] data: Data which to be transmitted. + * \param[in] StopState: Command of write or read. + * \arg I2C_STOP_ENABLE: Send stop signal. + * \arg I2C_STOP_DISABLE: Do not send stop signal. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * I2C_SendCmd(I2C0, 0x01, 0xAA, I2C_STOP_ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2C_SendCmd(I2C_TypeDef *I2Cx, uint16_t command, uint8_t data, + uint16_t StopState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CMD(command)); + assert_param(IS_I2C_STOP(StopState)); + + I2Cx->IC_DATA_CMD = data | command | StopState; +} + +/** + * \brief Received data by the I2Cx peripheral. + * \param[in] I2Cx: Where x can be 1 or 2 to select the I2C peripheral. + * \retval Return the most recent received data. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t data = I2C_ReceiveData(I2C0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2C_ReceiveData(I2C_TypeDef *I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Return the data in the DR register */ + return (uint8_t)I2Cx->IC_DATA_CMD; +} + +/** + * \brief Get data length in Rx FIFO of the I2Cx peripheral. + * \param[in] I2Cx: Where x can be 0 or 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t data_len = I2C_GetRxFIFOLen(I2C0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2C_GetRxFIFOLen(I2C_TypeDef *I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + return (uint8_t)I2Cx->IC_RXFLR; +} + +/** + * \brief Get data length in Tx FIFO of the I2Cx peripheral. + * \param[in] I2Cx: Where x can be 0 or 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * uint8_t data_len = I2C_GetTxFIFOLen(I2C0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2C_GetTxFIFOLen(I2C_TypeDef *I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + return (uint8_t)I2Cx->IC_TXFLR; +} + +/** + * \brief Clear all I2C interrupt. + * \param[in] I2Cx: Where x can be 0 or 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * I2C_ClearAllINT(I2C0); + * } + * \endcode + */ +__STATIC_INLINE void I2C_ClearAllINT(I2C_TypeDef *I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + I2Cx->IC_CLR_INTR; +} + +/** + * \brief Check whether the specified I2C flag is set. + * \param[in] I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param[in] I2C_FLAG: Specifies the flag to check. + * This parameter can be one of the following values: + * \arg I2C_FLAG_SLV_ACTIVITY: Slave FSM activity status. + * \arg I2C_FLAG_MST_ACTIVITY: Master FSM activity status. + * \arg I2C_FLAG_RFF: Receive FIFO completely full. + * \arg I2C_FLAG_RFNE: Receive FIFO not empty. + * \arg I2C_FLAG_TFE: Transmit FIFO completely empty. + * \arg I2C_FLAG_TFNF: Transmit FIFO not full. + * \arg I2C_FLAG_ACTIVITY: I2C activity status. + * \retval The new state of I2C_FLAG (SET or RESET). + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * FlagStatus flag_status = I2C_GetFlagState(I2C0, I2C_FLAG_RFF); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus I2C_GetFlagState(I2C_TypeDef *I2Cx, uint32_t I2C_FLAG) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); + + if ((I2Cx->IC_STATUS & I2C_FLAG) != (uint32_t)RESET) + { + /* I2C_FLAG is set */ + bit_status = SET; + } + + /* Return the I2C_FLAG status */ + return bit_status; +} + +/** + * \brief Check whether the last I2Cx event is equal to the one passed as parameter. + * \param[in] I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * \param[in] I2C_EVENT: specifies the event to be checked about I2C Transmit Abort Status Register. + * This parameter can be one of the following values: + * \arg ABRT_SLVRD_INTX: When the processor side responds to a slave mode request for data to be transmitted to a remote master and user send read command. + * \arg ABRT_SLV_ARBLOST: Slave lost the bus while transmitting data to a remote master. + * \arg ABRT_SLVFLUSH_TXFIFO: Slave has received a read command and some data exists in the TX FIFO so the slave issues a TX_ABRT interrupt to flush old data in TX FIFO. + * \arg ARB_LOST: Master has lost arbitration or the slave transmitter has lost arbitration. + * \arg ABRT_MASTER_DIS: User tries to initiate a Master operation with the Master mode disabled + * \arg ABRT_10B_RD_NORSTRT: The restart is disabled and the master sends a read command in 10-bit addressing mode. + * \arg ABRT_SBYTE_NORSTRT: The restart is disabled and the user is trying to send a START Byte. + * \arg ABRT_HS_NORSTRT: The restart is disabled and the user is trying to use the master to transfer data in High Speed mode. + * \arg ABRT_SBYTE_ACKDET: Master has sent a START Byte and the START Byte was acknowledged (wrong behavior). + * \arg ABRT_HS_ACKDET: Master is in High Speed mode and the High Speed Master code was acknowledged (wrong behavior). + * \arg ABRT_GCALL_READ: Sent a General Call but the user programmed the byte following the General Call to be a read from the bus. + * \arg ABRT_GCALL_NOACK: Sent a General Call and no slave on the bus acknowledged the General Call. + * \arg ABRT_TXDATA_NOACK: Master sent data byte(s) following the address, it did not receive an acknowledge from the remote slave. + * \arg ABRT_10ADDR2_NOACK: Master is in 10-bit address mode and the second address byte of the 10-bit address was not acknowledged by any slave. + * \arg ABRT_10ADDR1_NOACK: Master is in 10-bit address mode and the first 10-bit address byte was not acknowledged by any slave. + * \arg ABRT_7B_ADDR_NOACK: Master is in 7-bit addressing mode and th address sent was not acknowledged by any slave. + * \return An ErrorStatus enumeration value. + * \retval SUCCESS: Last event is equal to the I2C_EVENT. + * \retval ERROR: Last event is different from the I2C_EVENT. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * FlagStatus flag_status = I2C_CheckEvent(I2C0, ABRT_SLVRD_INTX); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus I2C_CheckEvent(I2C_TypeDef *I2Cx, uint32_t I2C_EVENT) +{ + FlagStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_EVENT(I2C_EVENT)); + + if ((I2Cx->IC_TX_ABRT_SOURCE & I2C_EVENT) != (uint32_t)RESET) + { + + bit_status = SET; + } + + /* Return the I2C event status */ + return bit_status; +} + +/** + * \brief Get the specified I2C interrupt status. + * \param[in] I2Cx: where x can be 0 or 1. + * \param[in] I2C_IT + * This parameter can be one of the following values: + * \arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged. + * \arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C + interface regardless of whether DW_apb_i2c is operating in slave or master mode. + * \arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless + of whether DW_apb_i2c is operating in slave or master mode + * \arg I2C_INT_ACTIVITY: This bit captures DW_apb_i2c activity and stays set until it is cleared. + * \arg I2C_INT_RX_DONE: When the DW_apb_i2c is acting as a slave-transmitter, this bit is set to 1 if the + master does not acknowledge a transmitted byte. This occurs on the last byte of + the transmission, indicating that the transmission is done. + * \arg I2C_INT_TX_ABRT: This bit indicates if DW_apb_i2c, as an I2C transmitter, is unable to complete the + intended actions on the contents of the transmit FIFO. + * \arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master + is attempting to read data. + * \arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set + in the IC_TX_TL register. + * \arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and + the processor attempts to issue another I2C command. + * \arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the + IC_RX_TL register + * \arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an + additional byte is received from an external I2C device. + * \arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading. + * \return The new state of I2C_IT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * ITStatus int_status = I2C_GetINTStatus(I2C0, I2C_INT_RD_REQ); + * } + * \endcode + */ +__STATIC_INLINE ITStatus I2C_GetINTStatus(I2C_TypeDef *I2Cx, uint32_t I2C_IT) +{ + ITStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(I2C_GET_INT(I2C_IT)); + + if ((I2Cx->IC_INTR_STAT & I2C_IT) != (uint32_t)RESET) + { + bit_status = SET; + } + + /* Return the I2C_IT status */ + return bit_status; +} + +/** + * \brief Enable or disable the I2Cx GDMA interface. + * \param[in] I2Cx: Where x can be 0 or 1 + * \param[in] I2C_GDMAReq: Specifies the I2C GDMA transfer request to be enabled or disabled. + * This parameter can be one of the following values: + * \arg I2C_GDMAReq_Tx: Tx buffer GDMA transfer request. + * \arg I2C_GDMAReq_Rx: Rx buffer GDMA transfer request. + * \param[in] NewState: New state of the selected I2C GDMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2c0_demo(void) + * { + * I2C_GDMACmd(I2C0, I2C_GDMAReq_Tx, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2C_GDMACmd(I2C_TypeDef *I2Cx, uint16_t I2C_GDMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_I2C_GDMAREQ(I2C_GDMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C GDMA request */ + I2Cx->IC_DMA_CR |= I2C_GDMAReq; + } + else + { + /* Disable the selected I2C GDMA request */ + I2Cx->IC_DMA_CR &= (uint16_t)~(I2C_GDMAReq); + } +} + +/** \} */ /* End of group I2C_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /*_RTL8762X_I2C_H_*/ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_i2s.h b/inc/peripheral/rtl876x_i2s.h new file mode 100644 index 0000000..33b4660 --- /dev/null +++ b/inc/peripheral/rtl876x_i2s.h @@ -0,0 +1,1112 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_i2s.h +* \brief The header file of the peripheral I2S driver. +* \details This file provides all I2S firmware functions. +* \author elliot chen +* \date 2017-12-06 +* \version v1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876x_I2S_H +#define _RTL876x_I2S_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup I2S I2S + * + * \brief Manage the I2S peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup I2S_Exported_Types Inti Params Struct + * + * \ingroup I2S + */ + +/** + * \brief I2S init structure definition. + * + * \ingroup I2S_Exported_Types + */ +typedef struct +{ + uint32_t I2S_ClockSource; /*!< Specifies the I2S clock source. + This parameter can be a value of \ref I2S_Clock_Source*/ + uint32_t I2S_BClockMi; /*!< Specifies the BLCK clock speed. BCLK = 40MHz*(I2S_BClockNi/I2S_BClockMi). + This parameter must range from 1 to 0xffff */ + uint32_t I2S_BClockNi; /*!< Specifies the BLCK clock speed. + This parameter must range from 1 to 0x7FFF */ + uint32_t I2S_DeviceMode; /*!< Specifies the I2S device mode. + This parameter can be a value of \ref I2S_device_mode*/ + uint32_t I2S_ChannelType; /*!< Specifies the channel type used for the I2S communication. + This parameter can be a value of \ref I2S_Channel_Type */ + uint32_t I2S_TxChSequence; /*!< Specifies the transmission channel seqence used for the I2S communication. + This parameter can be a value of \ref I2S_Tx_Ch_Sequence*/ + uint32_t I2S_RxChSequence; /*!< Specifies the receiving channel seqence used for the I2S communication. + This parameter can be a value of \ref I2S_Rx_Ch_Sequence*/ + uint32_t I2S_DataFormat; /*!< Specifies the I2S Data format mode. + This parameter can be a value of \ref I2S_Format_Mode*/ + uint32_t I2S_TxBitSequence; /*!< Specifies the I2S Data bits sequences. + This parameter can be a value of \ref I2S_Tx_Bit_Sequence*/ + uint32_t I2S_RxBitSequence; /*!< Specifies the I2S Data bits sequences. + This parameter can be a value of \ref I2S_Rx_Bit_Sequence*/ + uint32_t I2S_DataWidth; /*!< Specifies the I2S Data width. + This parameter can be a value of \ref I2S_Data_Width */ + uint32_t I2S_MCLKOutput; /*!< Specifies the I2S MCLK output freqency. + This parameter can be a value of \ref I2S_MCLK_Output */ + uint32_t I2S_DMACmd; /*!< Specifies the I2S DMA control. + This parameter can be a value of \ref FunctionalState */ + uint32_t I2S_TxWaterlevel; /*!< Specifies the dma watermark level in transmit mode. + This parameter must range from 1 to 63 */ + uint32_t I2S_RxWaterlevel; /*!< Specifies the dma watermark level in receive mode. + This parameter must range from 1 to 63 */ +} I2S_InitTypeDef; + + +/*============================================================================* + * Register Defines + *============================================================================*/ + +/* Peripheral: I2S */ +/* Description: I2S register defines */ + +/* Register: CTRL0 -------------------------------------------------------*/ +/* Description: Control register 0. Offset: 0x04. */ + +/* CTRL0[30]: I2S_MCLK_SEL. */ +#define I2S_MCLK_SEL_POS (30) +#define I2S_MCLK_SEL_MSK (0x1 << I2S_MCLK_SEL_POS) +#define I2S_MCLK_SEL_CLR (~I2S_MCLK_SEL_MSK) +/* CTRL0[29:28]: I2S_RX_CH_SEQ. */ +#define I2S_RX_CH_SEQ_POS (28) +#define I2S_RX_CH_SEQ_MSK (0x1 << I2S_RX_CH_SEQ_POS) +#define I2S_RX_CH_SEQ_CLR (~I2S_RX_CH_SEQ_MSK) +/* CTRL0[25]: I2S_START_RX. */ +#define I2S_START_RX_POS (25) +#define I2S_START_RX_MSK (0x1 << I2S_START_RX_POS) +#define I2S_START_RX_CLR (~I2S_START_RX_MSK) +/* CTRL0[24]: I2S_RX_DISABLE. */ +#define I2S_RX_DISABLE_POS (24) +#define I2S_RX_DISABLE_MSK (0x1 << I2S_RX_DISABLE_POS) +#define I2S_RX_DISABLE_CLR (~I2S_RX_DISABLE_MSK) +/* CTRL0[23]: I2S_RX_LSB_FIRST. */ +#define I2S_RX_LSB_FIRST_POS (23) +#define I2S_RX_LSB_FIRST_MSK (0x1 << I2S_RX_LSB_FIRST_POS) +#define I2S_RX_LSB_FIRST_CLR (~I2S_RX_LSB_FIRST_MSK) +/* CTRL0[22]: I2S_TX_LSB_FIRST. */ +#define I2S_TX_LSB_FIRST_POS (22) +#define I2S_TX_LSB_FIRST_MSK (0x1 << I2S_TX_LSB_FIRST_POS) +#define I2S_TX_LSB_FIRST_CLR (~I2S_TX_LSB_FIRST_MSK) +/* CTRL0[21:20]: I2S_TX_CH_SEQ. */ +#define I2S_TX_CH_SEQ_POS (20) +#define I2S_TX_CH_SEQ_MSK (0x1 << I2S_TX_CH_SEQ_POS) +#define I2S_TX_CH_SEQ_CLR (~I2S_TX_CH_SEQ_MSK) +/* CTRL0[17]: I2S_START_TX. */ +#define I2S_START_TX_POS (17) +#define I2S_START_TX_MSK (0x1 << I2S_START_TX_POS) +#define I2S_START_TX_CLR (~I2S_START_TX_MSK) +/* CTRL0[16]: I2S_TX_DISABLE. */ +#define I2S_TX_DISABLE_POS (16) +#define I2S_TX_DISABLE_MSK (0x1 << I2S_TX_DISABLE_POS) +#define I2S_TX_DISABLE_CLR (~I2S_TX_DISABLE_MSK) +/* CTRL0[13:12]: I2S_DATA_WIDTH. */ +#define I2S_DATA_WIDTH_POS (12) +#define I2S_DATA_WIDTH_MSK (0x3 << I2S_DATA_WIDTH_POS) +#define I2S_DATA_WIDTH_CLR (~I2S_DATA_WIDTH_MSK) +/* CTRL0[11]: I2S_CHANNEL_TYPE. */ +#define I2S_CHANNEL_TYPE_POS (11) +#define I2S_CHANNEL_TYPE_MSK (0x1 << I2S_CHANNEL_TYPE_POS) +#define I2S_CHANNEL_TYPE_CLR (~I2S_CHANNEL_TYPE_MSK) +/* CTRL0[9:8]: I2S_DATA_FORMAT. */ +#define I2S_DATA_FORMAT_POS (8) +#define I2S_DATA_FORMAT_MSK (0x3 << I2S_DATA_FORMAT_POS) +#define I2S_DATA_FORMAT_CLR (~I2S_DATA_FORMAT_MSK) +/* CTRL0[7]: I2S_CTRL_MODE. */ +#define I2S_CTRL_MODE_POS (7) +#define I2S_CTRL_MODE_MSK (0x1 << I2S_CTRL_MODE_POS) +#define I2S_CTRL_MODE_CLR (~I2S_CTRL_MODE_MSK) +/* CTRL0[4]: I2S_SLAVE_DATA_SEL. */ +#define I2S_SLAVE_DATA_SEL_POS (4) +#define I2S_SLAVE_DATA_SEL_MSK (0x1 << I2S_SLAVE_DATA_SEL_POS) +#define I2S_SLAVE_DATA_SEL_CLR (~I2S_SLAVE_DATA_SEL_MSK) +/* CTRL0[3]: I2S_SLAVE_CLK_SEL. */ +#define I2S_SLAVE_CLK_SEL_POS (3) +#define I2S_SLAVE_CLK_SEL_MSK (0x1 << I2S_SLAVE_CLK_SEL_POS) +#define I2S_SLAVE_CLK_SEL_CLR (~I2S_SLAVE_CLK_SEL_MSK) +/* CTRL0[0]: I2S_RESET. */ +#define I2S_RESET_POS (0) +#define I2S_RESET_MSK (0x1 << I2S_RESET_POS) +#define I2S_RESET_CLR (~I2S_RESET_MSK) + +/* Register: CTRL1 -------------------------------------------------------*/ +/* Description: Control register 1. Offset: 0x08. */ + +/* CTRL1[30]: I2S_TX_IDLE. */ +#define I2S_TX_IDLE_POS (30) +#define I2S_TX_IDLE_MSK (0x1 << I2S_TX_IDLE_POS) +#define I2S_TX_IDLE_CLR (~I2S_TX_IDLE_MSK) +/* CTRL1[29]: I2S_RF_EMPTY. */ +#define I2S_RF_EMPTY_POS (29) +#define I2S_RF_EMPTY_MSK (0x1 << I2S_RF_EMPTY_POS) +#define I2S_RF_EMPTY_CLR (~I2S_RF_EMPTY_MSK) +/* CTRL1[28]: I2S_TF_EMPTY. */ +#define I2S_TF_EMPTY_POS (28) +#define I2S_TF_EMPTY_MSK (0x1 << I2S_TF_EMPTY_POS) +#define I2S_TF_EMPTY_CLR (~I2S_TF_EMPTY_MSK) +/* CTRL1[27]: I2S_RX_FULL. */ +#define I2S_RX_FULL_POS (27) +#define I2S_RX_FULL_MSK (0x1 << I2S_RX_FULL_POS) +#define I2S_RX_FULL_CLR (~I2S_RX_FULL_MSK) +/* CTRL1[26]: I2S_TX_FULL. */ +#define I2S_TX_FULL_POS (26) +#define I2S_TX_FULL_MSK (0x1 << I2S_TX_FULL_POS) +#define I2S_TX_FULL_CLR (~I2S_TX_FULL_MSK) +/* CTRL1[25]: I2S_READY_TO_RX. */ +#define I2S_READY_TO_RX_POS (25) +#define I2S_READY_TO_RX_MSK (0x1 << I2S_READY_TO_RX_POS) +#define I2S_READY_TO_RX_CLR (~I2S_READY_TO_RX_MSK) +/* CTRL1[24]: I2S_READY_TO_TX. */ +#define I2S_READY_TO_TX_POS (24) +#define I2S_READY_TO_TX_MSK (0x1 << I2S_READY_TO_TX_POS) +#define I2S_READY_TO_TX_CLR (~I2S_READY_TO_TX_MSK) + +/* CTRL1[23]: I2S_RX_SNK_LR_SWAP. */ +#define I2S_RX_SNK_LR_SWAP_POS (23) +#define I2S_RX_SNK_LR_SWAP_MSK (0x1 << I2S_RX_SNK_LR_SWAP_POS) +#define I2S_RX_SNK_LR_SWAP_CLR (~I2S_RX_SNK_LR_SWAP_MSK) +/* CTRL1[22]: I2S_RX_SNK_BYTE_SWAP. */ +#define I2S_RX_SNK_BYTE_SWAP_POS (22) +#define I2S_RX_SNK_BYTE_SWAP_MSK (0x1 << I2S_RX_SNK_BYTE_SWAP_POS) +#define I2S_RX_SNK_BYTE_SWAP_CLR (~I2S_RX_SNK_BYTE_SWAP_MSK) +/* CTRL1[21]: I2S_TX_SRC_LR_SWAP. */ +#define I2S_TX_SRC_LR_SWAP_POS (21) +#define I2S_TX_SRC_LR_SWAP_MSK (0x1 << I2S_TX_SRC_LR_SWAP_POS) +#define I2S_TX_SRC_LR_SWAP_CLR (~I2S_TX_SRC_LR_SWAP_MSK) +/* CTRL1[20]: I2S_TX_SRC_BYTE_SWAP. */ +#define I2S_TX_SRC_BYTE_SWAP_POS (20) +#define I2S_TX_SRC_BYTE_SWAP_MSK (0x1 << I2S_TX_SRC_BYTE_SWAP_POS) +#define I2S_TX_SRC_BYTE_SWAP_CLR (~I2S_TX_SRC_BYTE_SWAP_MSK) +/* CTRL1[17]: I2S_CLK_128FS. */ +#define I2S_CLK_128FS_POS (17) +#define I2S_CLK_128FS_MSK (0x1 << I2S_CLK_128FS_POS) +#define I2S_CLK_128FS_CLR (~I2S_CLK_128FS_MSK) +/* CTRL1[16]: I2S_CLK_40M. */ +#define I2S_CLK_128_FS_POS (16) +#define I2S_CLK_128_FS_MSK (0x1 << I2S_CLK_128_FS_POS) +#define I2S_CLK_128_FS_CLR (~I2S_CLK_128_FS_MSK) +/* CTRL1[13]: I2S_CLR_RX_ERR_CNT. */ +#define I2S_CLR_RX_ERR_CNT_POS (13) +#define I2S_CLR_RX_ERR_CNT_MSK (0x1 << I2S_CLR_RX_ERR_CNT_POS) +#define I2S_CLR_RX_ERR_CNT_CLR (~I2S_CLR_RX_ERR_CNT_MSK) +/* CTRL1[12]: I2S_CLR_TX_ERR_CNT. */ +#define I2S_CLR_TX_ERR_CNT_POS (12) +#define I2S_CLR_TX_ERR_CNT_MSK (0x1 << I2S_CLR_TX_ERR_CNT_POS) +#define I2S_CLR_TX_ERR_CNT_CLR (~I2S_CLR_TX_ERR_CNT_MSK) +/* CTRL1[7:0]: I2S_FRAME_SYNC_OFFSET. */ +#define I2S_FRAME_SYNC_OFFSET_POS (0) +#define I2S_FRAME_SYNC_OFFSET_MSK (0xFF << I2S_FRAME_SYNC_OFFSET_POS) +#define I2S_FRAME_SYNC_OFFSET_CLR (~I2S_FRAME_SYNC_OFFSET_MSK) +#define I2S_FRAME_SYNC_OFFSET_DEFAULT (0x81 << I2S_FRAME_SYNC_OFFSET_POS) + +/* Register: DSP_INT_CR -------------------------------------------------------*/ +/* Description:Interrupt clearregister. Offset: 0x0C. */ + +/* DSP_INT_CR[1]: I2S_RX_CLEAR_INT. */ +#define I2S_RX_CLEAR_INT_POS (1) +#define I2S_RX_CLEAR_INT_MSK (0x1 << I2S_RX_CLEAR_INT_POS) +#define I2S_RX_CLEAR_INT_CLR (~I2S_RX_CLEAR_INT_MSK) +/* DSP_INT_CR[0]: I2S_TX_CLEAR_INT. */ +#define I2S_TX_CLEAR_INT_POS (0) +#define I2S_TX_CLEAR_INT_MSK (0x1 << I2S_TX_CLEAR_INT_POS) +#define I2S_TX_CLEAR_INT_CLR (~I2S_TX_CLEAR_INT_MSK) + +/* Register: FIFO_SR -------------------------------------------------------*/ +/* Description: FIFO status register. Offset: 0x14. */ + +/* FIFO_SR[13:8]: I2S_RX_FIFO_DEPTH_CNT. */ +#define I2S_RX_FIFO_DEPTH_CNT_POS (8) +#define I2S_RX_FIFO_DEPTH_CNT_MSK (0x3F << I2S_RX_FIFO_DEPTH_CNT_POS) +#define I2S_RX_FIFO_DEPTH_CNT_CLR (~I2S_RX_FIFO_DEPTH_CNT_MSK) +/* FIFO_SR[5:0]: I2S_TX_FIFO_DEPTH_CNT. */ +#define I2S_TX_FIFO_DEPTH_CNT_POS (0) +#define I2S_TX_FIFO_DEPTH_CNT_MSK (0x3F << I2S_TX_FIFO_DEPTH_CNT_POS) +#define I2S_TX_FIFO_DEPTH_CNT_CLR (~I2S_TX_FIFO_DEPTH_CNT_MSK) + +/* Register: ERROR_CNT_SR -------------------------------------------------------*/ +/* Description: Error counter status register. Offset: 0x18. */ + +/* ERROR_CNT_SR[15:8]: I2S_RX_ERR_CNT. */ +#define I2S_RX_ERR_CNT_POS (8) +#define I2S_RX_ERR_CNT_MSK (0xFF << I2S_RX_ERR_CNT_POS) +#define I2S_RX_ERR_CNT_CLR (~I2S_RX_ERR_CNT_MSK) +/* ERROR_CNT_SR[7:0]: I2S_TX_ERR_CNT. */ +#define I2S_TX_ERR_CNT_POS (0) +#define I2S_TX_ERR_CNT_MSK (0xFF << I2S_TX_ERR_CNT_POS) +#define I2S_TX_ERR_CNT_CLR (~I2S_TX_ERR_CNT_MSK) + +/* Register: BCLK_DIV -------------------------------------------------------*/ +/* Description: BCLK divider register. Offset: 0x1C. */ + +/* BCLK_DIV[31]: I2S_MI_NI_UPDATE. */ +#define I2S_MI_NI_UPDATE_POS (31) +#define I2S_MI_NI_UPDATE_MSK ((uint32_t)0x1 << I2S_MI_NI_UPDATE_POS) +#define I2S_MI_NI_UPDATE_CLR (~I2S_MI_NI_UPDATE_MSK) +/* BCLK_DIV[30:16]: I2S_BCLK_NI. */ +#define I2S_BCLK_NI_POS (16) +#define I2S_BCLK_NI_MSK (0x7FFF << I2S_BCLK_NI_POS) +#define I2S_BCLK_NI_CLR (~I2S_BCLK_NI_MSK) +/* BCLK_DIV[15:0]: I2S_BCLK_MI. */ +#define I2S_BCLK_MI_POS (0) +#define I2S_BCLK_MI_MSK (0xFFFF << I2S_BCLK_MI_POS) +#define I2S_BCLK_MI_CLR (~I2S_BCLK_MI_MSK) + +/* Register: DMA_TRDLR -------------------------------------------------------*/ +/* Description: DMA transmit receive data level register. Offset: 0x20. */ + +/* DMA_TRDLR[5:0]: I2S_TX_DMA_BURST_SIZE. */ +#define I2S_TX_DMA_BURST_SIZE_POS (0) +#define I2S_TX_DMA_BURST_SIZE_MSK (0x3F << I2S_TX_DMA_BURST_SIZE_POS) +#define I2S_TX_DMA_BURST_SIZE_CLR (~I2S_TX_DMA_BURST_SIZE_MSK) +/* DMA_TRDLR[13:8]: I2S_RX_DMA_BURST_SIZE. */ +#define I2S_RX_DMA_BURST_SIZE_POS (8) +#define I2S_RX_DMA_BURST_SIZE_MSK (0x3F << I2S_RX_DMA_BURST_SIZE_POS) +#define I2S_RX_DMA_BURST_SIZE_CLR (~I2S_RX_DMA_BURST_SIZE_MSK) + +/* Register: PERIPH_AUDIO_CLK_224 -------------------------------------------------------*/ +/* Description: peri on register. address: 0x40000224. */ +#define PERIPH_AUDIO_CLK_224 0x40000224 +/* PERIPH_AUDIO_CLK_224[3]: I2S0_EXT_CODEC. */ +#define I2S0_EXT_CODEC_POS (3) +#define I2S0_EXT_CODEC_MSK (0x1 << I2S0_EXT_CODEC_POS) +#define I2S0_EXT_CODEC_CLR (~I2S0_EXT_CODEC_MSK) + +/* Register: PERIPH_AUDIO_CLK_228 -------------------------------------------------------*/ +/* Description: peri on register. address: 0x40000228. */ +#define PERIPH_AUDIO_CLK_228 0x40000228 +/* PERIPH_AUDIO_CLK_228[4]: I2S_MCLK_OUTPUT. */ +#define I2S_MCLK_OUTPUT_POS (4) +#define I2S_MCLK_OUTPUT_MSK (0x1 << I2S_MCLK_OUTPUT_POS) +#define I2S_MCLK_OUTPUT_CLR (~I2S_MCLK_OUTPUT_MSK) + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup I2S_Exported_Constants Macro Defines + * + * \ingroup I2S + */ + +#define IS_I2S_ALL_PERIPH(PERIPH) ((PERIPH) == I2S0) + +/** + * \defgroup I2S_Clock_Source I2S Clock Source + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_CLK_40M (I2S_CLK_128_FS_MSK) +#define I2S_CLK_128fs (I2S_CLK_128FS_MSK) +#define I2S_CLK_256fs ((uint32_t)(0x00)) +/** \} */ + +#define IS_I2S_CLK_SOURCE(CLK) (((CLK) == I2S_CLK_40M) || \ + ((CLK) == I2S_CLK_128fs) || \ + ((CLK) == I2S_CLK_256fs)) + +/** + * \defgroup I2S_Device_Mode I2S Device Mode + * \{ + * \ingroup I2S_Exported_Constants + */ + +#define I2S_DeviceMode_Master ((uint32_t)0x00) +#define I2S_DeviceMode_Slave (I2S_SLAVE_DATA_SEL_MSK )//| I2S_SLAVE_CLK_SEL_MSK) +/** \} */ + +#define IS_I2S_DEVICE_MODE(DEVICE) (((DEVICE) == I2S_DeviceMode_Master) || ((DEVICE) == I2S_DeviceMode_Slave)) + +/** + * \defgroup I2S_Mode I2S Mode + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_MODE_TX (I2S_START_TX_MSK) +#define I2S_MODE_RX (I2S_START_RX_MSK) +/** \} */ + +#define IS_I2S_MODE(MODE) (((MODE) == I2S_MODE_TX) || ((MODE) == I2S_MODE_RX)) + +/** + * \defgroup I2S_Channel_Type I2S Channel Type + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_Channel_Mono (I2S_CHANNEL_TYPE_MSK) +#define I2S_Channel_stereo ((uint32_t)(0x0)) +/** \} */ + +#define IS_I2S_CHANNEL_TYPE(TYPE) (((TYPE) == I2S_Channel_Mono) || ((TYPE) == I2S_Channel_stereo)) + +/** + * \defgroup I2S_Tx_Ch_Sequence I2S Transmission Channel Sequence + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_TX_CH_L_R (0) +#define I2S_TX_CH_R_L ((uint32_t)0x01 << I2S_TX_CH_SEQ_POS) +#define I2S_TX_CH_L_L ((uint32_t)0x02 << I2S_TX_CH_SEQ_POS) +#define I2S_TX_CH_R_R ((uint32_t)0x03 << I2S_TX_CH_SEQ_POS) +/** \} */ + +#define IS_I2S_TX_CH_SEQ(SEQ) (((SEQ) == I2S_TX_CH_L_R) || ((SEQ) == I2S_TX_CH_R_L) || \ + ((SEQ) == I2S_TX_CH_L_L) || ((SEQ) == I2S_TX_CH_R_R)) + +/** + * \defgroup I2S_Rx_Ch_Sequence I2S Receiving Channel Sequence + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_RX_CH_L_R (0) +#define I2S_RX_CH_R_L ((uint32_t)0x01 << I2S_RX_CH_SEQ_POS) +#define I2S_RX_CH_L_L ((uint32_t)0x02 << I2S_RX_CH_SEQ_POS) +#define I2S_RX_CH_R_R ((uint32_t)0x03 << I2S_RX_CH_SEQ_POS) +/** \} */ + +#define IS_I2S_RX_CH_SEQ(SEQ) (((SEQ) == I2S_RX_CH_L_R) || ((SEQ) == I2S_RX_CH_R_L) || \ + ((SEQ) == I2S_RX_CH_L_L) || ((SEQ) == I2S_RX_CH_R_R)) + +/** + * \defgroup I2S_Format_Mode I2S Format Mode + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_Mode ((uint32_t)(0x00 << I2S_DATA_FORMAT_POS)) +#define Left_Justified_Mode ((uint32_t)(0x01 << I2S_DATA_FORMAT_POS)) +#define PCM_Mode_A ((uint32_t)(0x02 << I2S_DATA_FORMAT_POS)) +#define PCM_Mode_B ((uint32_t)(0x03 << I2S_DATA_FORMAT_POS)) +/** \} */ + +#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_Mode) || ((FORMAT) == Left_Justified_Mode) || \ + ((FORMAT) == PCM_Mode_A) || ((FORMAT) == PCM_Mode_B)) + +/** + * \defgroup I2S_Tx_Bit_Sequence I2S Tx Bit Sequence + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_TX_MSB_First ((uint32_t)0x0) +#define I2S_TX_LSB_First (I2S_TX_LSB_FIRST_MSK) +/** \} */ + +#define IS_I2S_TX_BIT_SEQ(SEQ) (((SEQ) == I2S_TX_MSB_First) || ((SEQ) == I2S_TX_LSB_First)) + +/** + * \defgroup I2S_Rx_Bit_Sequence I2S Rx Bit Sequence + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_RX_MSB_First ((uint32_t)0x0) +#define I2S_RX_LSB_First (I2S_RX_LSB_FIRST_MSK) +/** \} */ + +#define IS_I2S_RX_BIT_SEQ(SEQ) (((SEQ) == I2S_RX_MSB_First) || ((SEQ) == I2S_RX_LSB_First)) + +/** + * \defgroup I2S_Data_Width I2S Data Width + * \{ + * \ingroup I2S_Exported_Constants + */ + +#define I2S_Width_16Bits ((uint32_t)(0x00 << I2S_DATA_WIDTH_POS)) +#define I2S_Width_24Bits ((uint32_t)(0x02 << I2S_DATA_WIDTH_POS)) +#define I2S_Width_8Bits ((uint32_t)(0x03 << I2S_DATA_WIDTH_POS)) +/** \} */ + +#define IS_I2S_DATA_WIDTH(WIDTH) (((WIDTH) == I2S_Width_16Bits) || \ + ((WIDTH) == I2S_Width_24Bits) || \ + ((WIDTH) == I2S_Width_8Bits)) + +/** + * \defgroup I2S_MCLK_Output I2S MCLK Output + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_MCLK_128fs ((uint32_t)0x0) +#define I2S_MCLK_256fs (I2S_MCLK_SEL_MSK) +/** \} */ + +#define IS_I2S_MCLK_OUTPUT_TYPE(TYPE) (((TYPE) == I2S_MCLK_128fs) || ((TYPE) == I2S_MCLK_256fs)) + +/** + * \defgroup I2S_DMA_Cmd I2S DMA Cmd + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_DMA_ENABLE ((uint32_t)0x0) +#define I2S_DMA_DISABLE (I2S_CTRL_MODE_MSK) +/** \} */ + +#define IS_I2S_DMA_CMD(CMD) (((CMD) == I2S_DMA_ENABLE) || ((CMD) == I2S_DMA_DISABLE)) + +/** + * \defgroup I2S_Interrupt_Definition I2S Interrupt Definition + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_INT_TX_IDLE (I2S_TX_IDLE_MSK) +#define I2S_INT_RF_EMPTY (I2S_RF_EMPTY_MSK) +#define I2S_INT_TF_EMPTY (I2S_TF_EMPTY_MSK) +#define I2S_INT_RF_FULL (I2S_RX_FULL_MSK) +#define I2S_INT_TF_FULL (I2S_TX_FULL_MSK) +#define I2S_INT_RX_READY (I2S_READY_TO_RX_MSK) +#define I2S_INT_TX_READY (I2S_READY_TO_TX_MSK) +/** \} */ + +#define IS_I2S_INT_CONFIG(INT) (((INT) == I2S_INT_TX_IDLE) || ((INT) == I2S_INT_RF_EMPTY) || \ + ((INT) == I2S_INT_TF_EMPTY) || ((INT) == I2S_INT_RF_FULL) || \ + ((INT) == I2S_INT_TF_FULL) || ((INT) == I2S_INT_RX_READY) || \ + ((INT) == I2S_INT_TX_READY) ) + +/** + * \defgroup I2S_Clear_Interrupt_Definition I2S Clear Interrupt Definition + * \{ + * \ingroup I2S_Exported_Constants + */ +#define I2S_CLEAR_INT_RX_READY (I2S_RX_CLEAR_INT_MSK) +#define I2S_CLEAR_INT_TX_READY (I2S_TX_CLEAR_INT_MSK) +/** \} */ + +#define IS_I2S_CLEAR_INT(CLEAR) (((CLEAR) == I2S_CLEAR_INT_RX_READY) || \ + ((CLEAR) == I2S_CLEAR_INT_TX_READY) ) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup I2S_Exported_Functions Peripheral APIs + * \{ + * \ingroup I2S + */ + +/** + * \brief Deinitializes the I2S peripheral registers to their default values. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2s_init(void) + * { + * I2S_DeInit(I2S0); + * } + * \endcode + */ +void I2S_DeInit(I2S_TypeDef *I2Sx); + +/** + * \brief Initializes the I2S peripheral according to the specified + * parameters in the I2S_InitStruct + * \param[in] I2Sx: Selected I2S peripheral. + * \param[in] I2S_InitStruct: Pointer to a I2S_InitTypeDef structure that + * contains the configuration information for the specified I2S peripheral + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2s_init(void) + * { + * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE); + * + * I2S_InitTypeDef I2S_InitStruct; + * + * I2S_StructInit(&I2S_InitStruct); + * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M; + * I2S_InitStruct.I2S_BClockMi = 0x271; + * I2S_InitStruct.I2S_BClockNi = 0x10; + * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master; + * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo; + * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits; + * I2S_InitStruct.I2S_DataFormat = I2S_Mode; + * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE; + * I2S_Init(I2S0, &I2S_InitStruct); + * I2S_Cmd(I2S0, I2S_MODE_TX, ENABLE); + * } + * \endcode + */ +void I2S_Init(I2S_TypeDef *I2Sx, I2S_InitTypeDef *I2S_InitStruct); + +/** + * \brief Fills each I2S_InitStruct member with its default value. + * \param[in] I2S_InitStruct: Pointer to an I2S_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2s_init(void) + * { + * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE); + * + * I2S_InitTypeDef I2S_InitStruct; + * + * I2S_StructInit(&I2S_InitStruct); + * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M; + * I2S_InitStruct.I2S_BClockMi = 0x271; + * I2S_InitStruct.I2S_BClockNi = 0x10; + * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master; + * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo; + * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits; + * I2S_InitStruct.I2S_DataFormat = I2S_Mode; + * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE; + * I2S_Init(I2S0, &I2S_InitStruct); + * I2S_Cmd(I2S0, I2S_MODE_TX, ENABLE); + * } + * \endcode + */ +void I2S_StructInit(I2S_InitTypeDef *I2S_InitStruct); + +/** + * \brief Enable or disable the selected I2S mode. + * \param[in] I2Sx: Selected I2S peripheral. + * \param[in] mode: Selected I2S operation mode. + * This parameter can be the following values: + * \arg I2S_MODE_TX: Transmission mode. + * \arg I2S_MODE_RX: Receiving mode. + * \param[in] NewState: New state of the operation mode. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_i2s_init(void) + * { + * RCC_PeriphClockCmd(APB_I2S, APB_I2S_CLOCK, ENABLE); + * + * I2S_InitTypeDef I2S_InitStruct; + * + * I2S_StructInit(&I2S_InitStruct); + * I2S_InitStruct.I2S_ClockSource = I2S_CLK_40M; + * I2S_InitStruct.I2S_BClockMi = 0x271; + * I2S_InitStruct.I2S_BClockNi = 0x10; + * I2S_InitStruct.I2S_DeviceMode = I2S_DeviceMode_Master; + * I2S_InitStruct.I2S_ChannelType = I2S_Channel_stereo; + * I2S_InitStruct.I2S_DataWidth = I2S_Width_16Bits; + * I2S_InitStruct.I2S_DataFormat = I2S_Mode; + * I2S_InitStruct.I2S_DMACmd = I2S_DMA_DISABLE; + * I2S_Init(I2S_NUM, &I2S_InitStruct); + * I2S_Cmd(I2S_NUM, I2S_MODE_TX, ENABLE); + * } + * \endcode + */ +void I2S_Cmd(I2S_TypeDef *I2Sx, uint32_t mode, FunctionalState NewState); + +/** + * \brief Enable or disable the specified I2S interrupt source. + * \param[in] I2S_INT: Specifies the I2S interrupt source to be enable or disable. + * This parameter can be the following values: + * \arg I2S_INT_TX_IDLE: Transmit idle interrupt source. + * \arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt source. + * \arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt source. + * \arg I2S_INT_RF_FULL: Receive FIFO full interrupt source. + * \arg I2S_INT_TF_FULL: Transmit FIFO full interrupt source. + * \arg I2S_INT_RX_READY: Ready to receive interrupt source. + * \arg I2S_INT_TX_READY: Ready to transmit interrupt source. + * \param[in] NewState: New state of the specified I2S interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_INTConfig(I2S0, I2S_INT_TF_EMPTY, ENABLE); + * } + * \endcode + */ +void I2S_INTConfig(I2S_TypeDef *I2Sx, uint32_t I2S_INT, FunctionalState newState); + +/** + * \brief Get the specified I2S interrupt status. + * \param[in] I2S_INT: the specified I2S interrupt. + * This parameter can be one of the following values: + * \arg I2S_INT_TX_IDLE: Transmit idle interrupt. + * \arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt. + * \arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt. + * \arg I2S_INT_RF_FULL: Receive FIFO full interrupt. + * \arg I2S_INT_TF_FULL: Transmit FIFO full interrupt. + * \arg I2S_INT_RX_READY: Ready to receive interrupt. + * \arg I2S_INT_TX_READY: Ready to transmit interrupt. + * \return The new state of I2S_INT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * ITStatus int_status = I2S_GetINTStatus(I2S0, I2S_INT_TF_EMPTY); + * } + * \endcode + */ +ITStatus I2S_GetINTStatus(I2S_TypeDef *I2Sx, uint32_t I2S_INT); + +/** + * \brief Clear the I2S interrupt pending bit. + * \param[in] I2S_CLEAR_INT: Specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * \arg I2S_CLEAR_INT_RX_READY: Clear ready to receive interrupt. + * \arg I2S_CLEAR_INT_TX_READY: Clear ready to transmit interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_ClearINTPendingBit(I2S0, I2S_CLEAR_INT_RX_READY); + * } + * \endcode + */ +void I2S_ClearINTPendingBit(I2S_TypeDef *I2Sx, uint32_t I2S_CLEAR_INT); + +/** + * \brief Transmits a data through the SPIx/I2Sx peripheral. + * \param[in] I2Sx: To select the I2Sx peripheral, x can be 0. + * \param[in] Data: Data to be transmitted. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_SendData(I2S0, 0x02); + * } + * \endcode + */ +__STATIC_INLINE void I2S_SendData(I2S_TypeDef *I2Sx, uint32_t Data) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + I2Sx->TX_DR = Data; +} + +/** + * \brief Received data by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \return Return the most recent received data. + * \ + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * uint32_t data = I2S_ReceiveData(I2S0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t I2S_ReceiveData(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + return I2Sx->RX_DR; +} + +/** + * \brief Get transmit FIFO free length by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \return Return the transmit FIFO free length. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * uint8_t data_len = I2S_GetTxFIFOFreeLen(I2S0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2S_GetTxFIFOFreeLen(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + return ((I2Sx->FIFO_SR & I2S_TX_FIFO_DEPTH_CNT_MSK) >> I2S_TX_FIFO_DEPTH_CNT_POS); +} + +/** + * \brief Get receive FIFO data length by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \return The data length of the receive FIFO. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * uint8_t data_len = I2S_GetRxFIFOLen(I2S0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2S_GetRxFIFOLen(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + return ((I2Sx->FIFO_SR & I2S_RX_FIFO_DEPTH_CNT_MSK) >> I2S_RX_FIFO_DEPTH_CNT_POS); +} + +/** + * \brief Get the send error counter value by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \return The send error counter value . + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * uint8_t conter = I2S_GetTxErrCnt(I2S0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2S_GetTxErrCnt(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + return ((I2Sx->ERROR_CNT_SR & I2S_TX_ERR_CNT_MSK) >> I2S_TX_ERR_CNT_POS); +} + +/** + * \brief Get the reception error counter value by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \retval The reception error counter value . + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * uint8_t conter = I2S_GetRxErrCnt(I2S0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t I2S_GetRxErrCnt(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + return ((I2Sx->ERROR_CNT_SR & I2S_RX_ERR_CNT_MSK) >> I2S_RX_ERR_CNT_POS); +} + +/** + * \brief Swap audio data bytes sequence which sent by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] NewState: New state of the bytes sequence. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_SwapBytesForSend(I2S0, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2S_SwapBytesForSend(I2S_TypeDef *I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (NewState == ENABLE) + { + I2Sx->CTRL1 |= I2S_TX_SRC_BYTE_SWAP_MSK; + } + else + { + I2Sx->CTRL1 &= I2S_TX_SRC_BYTE_SWAP_CLR; + } +} + +/** + * \brief Swap audio data bytes sequence which read by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] NewState: New state of the bytes sequence. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_SwapBytesForRead(I2S0, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2S_SwapBytesForRead(I2S_TypeDef *I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (NewState == ENABLE) + { + I2Sx->CTRL1 |= I2S_RX_SNK_BYTE_SWAP_MSK; + } + else + { + I2Sx->CTRL1 &= I2S_RX_SNK_BYTE_SWAP_CLR; + } +} + +/** + * \brief Swap audio channel data which sent by the I2Sx peripheral.. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] NewState: New state of the left and right channel data sequence. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_SwapLRChDataForSend(I2S0, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2S_SwapLRChDataForSend(I2S_TypeDef *I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (NewState == ENABLE) + { + I2Sx->CTRL1 |= I2S_TX_SRC_LR_SWAP_MSK; + } + else + { + I2Sx->CTRL1 &= I2S_TX_SRC_LR_SWAP_CLR; + } +} + +/** + * \brief Swap audio channel data which read by the I2Sx peripheral. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] NewState: New state of the left and right channel data sequence. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_SwapLRChDataForRead(I2S0, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2S_SwapLRChDataForRead(I2S_TypeDef *I2Sx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (NewState == ENABLE) + { + I2Sx->CTRL1 |= I2S_RX_SNK_LR_SWAP_MSK; + } + else + { + I2Sx->CTRL1 &= I2S_RX_SNK_LR_SWAP_CLR; + } +} + +/** + * \brief MCLK output selection which can be from I2S0. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] NewState: New state of MCLK output. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_MCLKOutputSelectCmd(I2S0); + * } + * \endcode + */ +__STATIC_INLINE void I2S_MCLKOutputSelectCmd(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (I2Sx == I2S0) + { + *((volatile uint32_t *)PERIPH_AUDIO_CLK_228) |= I2S_MCLK_OUTPUT_MSK; + } +} + +/** + * \brief I2S0 communication selection which can be from intrnal codec or external codec. + * \param[in] NewState: New state of I2S0 communication selection. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S0_WithExtCodecCmd(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void I2S0_WithExtCodecCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + *((volatile uint32_t *)PERIPH_AUDIO_CLK_224) |= I2S0_EXT_CODEC_MSK; + } + else + { + *((volatile uint32_t *)PERIPH_AUDIO_CLK_224) &= I2S0_EXT_CODEC_CLR; + } +} + +/** + * \brief Config BClk clock. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] I2S_BClockMi: Mi parameter. + * \param[in] I2S_BClockNi: Ni parameter. + * \return Execution status. + * \retval SET: Success. + * \retval RESET: Failure. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * FlagStatus status = I2S_UpdateBClk(I2S0, 0x271, 0x10); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus I2S_UpdateBClk(I2S_TypeDef *I2Sx, uint16_t I2S_BClockMi, + uint16_t I2S_BClockNi) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (!(I2Sx->BCLK_DIV & I2S_MI_NI_UPDATE_MSK)) + { + I2Sx->BCLK_DIV = I2S_BClockMi | (I2S_BCLK_NI_MSK & (I2S_BClockNi << I2S_BCLK_NI_POS)) | + I2S_MI_NI_UPDATE_MSK; + return SET; + } + + return RESET; +} + +/** + * \brief Get BClk clock status. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \return Execution status. + * \retval SET: BLCK is updating. + * \retval RESET: BLCK update is done. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * FlagStatus status = I2S_GetBClkStatus(I2S0); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus I2S_GetBClkStatus(I2S_TypeDef *I2Sx) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + + if (I2Sx->BCLK_DIV & I2S_MI_NI_UPDATE_MSK) + { + return SET; + } + + return RESET; +} + +/** + * \brief Config channel type. + * \param[in] I2Sx: To select I2Sx peripheral, where x can be: 0. + * \param[in] I2S_ChannelType: The channel type used for the I2S communication. + * This parameter can be one of the following values: + * \arg I2S_Channel_Mono: Mono channel. + * \arg I2S_Channel_stereo: Stereo channel. + * \return None. + * + * Example usage + * \code{.c} + * + * void i2s_demo(void) + * { + * I2S_ConfigChannelType(I2S0, I2S_Channel_Mono); + * } + * \endcode + */ +__STATIC_INLINE void I2S_ConfigChannelType(I2S_TypeDef *I2Sx, uint32_t I2S_ChannelType) +{ + I2Sx->CTRL0 &= I2S_CHANNEL_TYPE_CLR; + I2Sx->CTRL0 |= I2S_ChannelType; +} + +/** \} */ /*End of group I2S_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876x_I2S_H_ */ + + + + +/******************* (C) COPYRIGHT 2017 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_io_dlps.h b/inc/peripheral/rtl876x_io_dlps.h new file mode 100644 index 0000000..9a7c25c --- /dev/null +++ b/inc/peripheral/rtl876x_io_dlps.h @@ -0,0 +1,109 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file rtl876x_io_dlps.h +* @brief +* @details +* @author tifnan_ge +* @date 2015-05-18 +* @version v1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_IO_DLPS_H_ +#define _RTL876X_IO_DLPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rtl876x.h" +#include "rtl876x_bitfields.h" +#include "board.h" + +#if (PLATFORM_SUPPORT_POWER_MANAGER == 0) +#include "dlps.h" +#endif + +/** @addtogroup IO Peripheral Drivers + * + * @defgroup IO_DLPS IO DLPS + * @brief IO DLPS dirver module + * \ingroup IO + * @{ + */ + +/** @defgroup IO_DLPS_Exported_Types IO DLPS Exported Types + * @{ + */ + +typedef void (*DLPS_IO_ExitDlpsCB)(void); +typedef void (*DLPS_IO_EnterDlpsCB)(void); + +/** End of group IO_DLPS_Exported_Types + * @} + */ + + + +/*============================================================================* + * Functions + *============================================================================*/ + + +/** @defgroup IO_DLPS_Exported_Functions IO DLPS Exported Functions + * @{ + */ + +/** + * @brief Register io restore function in dlps mode + * @param None + * @retval None + */ +extern void DLPS_IORegister(void); +#if USE_USER_DEFINE_DLPS_EXIT_CB + +extern DLPS_IO_ExitDlpsCB User_IO_ExitDlpsCB; + +/** + * @brief Rrgister user-defined exit dlps callback function + * @param func: user-defined callback functon. + * @retval None + */ +__STATIC_INLINE void DLPS_IORegUserDlpsExitCb(DLPS_IO_ExitDlpsCB func) +{ + User_IO_ExitDlpsCB = func; +} + +#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */ + +#if USE_USER_DEFINE_DLPS_ENTER_CB + +extern DLPS_IO_EnterDlpsCB User_IO_EnterDlpsCB; + +/** + * @brief Rrgister user-defined enter dlps callback function + * @param func: user-defined callback functon. + * @retval None + */ +__STATIC_INLINE void DLPS_IORegUserDlpsEnterCb(DLPS_IO_EnterDlpsCB func) +{ + User_IO_EnterDlpsCB = func; +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_IO_DLPS_H_ */ + +/** @} */ /* End of group IO_DLPS_Exported_Functions */ +/** @} */ /* End of group IO_DLPS */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_ir.h b/inc/peripheral/rtl876x_ir.h new file mode 100644 index 0000000..4a58903 --- /dev/null +++ b/inc/peripheral/rtl876x_ir.h @@ -0,0 +1,1314 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_ir.h +* \brief The header file of the peripheral IR driver. +* \details This file provides all IR firmware functions. +* \author yuan +* \date 2020-10-13 +* \version v2.1.2 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876x_IR_H_ +#define _RTL876x_IR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup IR IR + * + * \brief Manage the IR peripheral functions. + * + * \ingroup IO + */ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** \defgroup IR_Exported_Types Init Params Struct + * + * \ingroup IR + */ + +/** + * \brief IR init structure definition. + * + * \ingroup IR_Exported_Types + */ +typedef struct +{ + uint32_t IR_Clock; + uint32_t IR_Freq; /*!< Specifies the clock frequency. This parameter is IR carrier freqency whose unit is Hz. */ + float IR_DutyCycle; /*!< Specifies the IR duty cycle. */ + uint32_t IR_Mode; /*!< Specifies the IR mode. + This parameter can be a value of \ref IR_Mode */ + uint32_t IR_TxIdleLevel; /*!< Specifies the IR output level in Tx mode + This parameter can be a value of \ref IR_Idle_Status */ + uint32_t IR_TxInverse; /*!< Specifies inverse FIFO data or not in TX mode + This parameter can be a value of \ref IR_TX_Data_Type */ + uint32_t IR_TxFIFOThrLevel; /*!< Specifies TX FIFO interrupt threshold in TX mode. When TX FIFO depth <= threshold value, trigger interrupt. + This parameter can be a value of 1 ~ 32. */ + uint32_t IR_RxStartMode; /*!< Specifies Start mode in RX mode + This parameter can be a value of \ref IR_Rx_Start_Mode. */ + uint32_t IR_RxFIFOThrLevel; /*!< Specifies RX FIFO interrupt threshold in RX mode. when RX FIFO depth > threshold value, trigger interrupt. + This parameter can be a value of \ref IR_Rx_Threshold */ + uint32_t IR_RxFIFOFullCtrl; /*!< Specifies data discard mode in RX mode when RX FIFO is full and receiving new data. + This parameter can be a value of \ref IR_RX_FIFO_DISCARD_SETTING. */ + uint32_t IR_RxTriggerMode; /*!< Specifies trigger in RX mode + This parameter can be a value of \ref IR_RX_Trigger_Mode. */ + uint32_t IR_RxFilterTime; /*!< Specifies filter time in RX mode + This parameter can be a value of \ref IR_RX_Filter_Time. */ + uint32_t IR_RxCntThrType; /*!< Specifies counter level type when trigger IR_INT_RX_CNT_THR interrupt in RX mode. + This parameter can be a value of \ref IR_RX_COUNTER_THRESHOLD_TYPE. */ + uint32_t IR_RxCntThr; /*!< Specifies counter threshold value when trigger IR_INT_RX_CNT_THR interrupt in RX mode. */ + uint8_t IR_TxDmaEn; /*!< Specifies the Tx dma mode. + This parameter must be a value of DISABLE and ENABLE. */ + uint8_t IR_TxWaterLevel; /*!< Specifies the DMA tx water level. + This parameter must range from 0 to 32.*/ + uint8_t IR_RxDmaEn; /*!< Specifies the Rx dma mode. + This parameter must be a value of DISABLE and ENABLE. */ + uint8_t IR_RxWaterLevel; /*!< Specifies the DMA rx water level. + This parameter must range from 0 to 32.*/ +} IR_InitTypeDef; + + +/*============================================================================* + * Register Defines + *============================================================================*/ + +/* Peripheral: IR */ +/* Description: IR register defines */ + +/* Register: TX_CONFIG -------------------------------------------------------*/ +/* Description: IR TX CONFIG register. Offset: 0x04. Address: 0x40003004. */ + +/* TX_CONFIG[31] :IR_MODE_SEL. 0x1: RX mode. 0x0: TX mode. */ +#define IR_MODE_SEL_Pos (31UL) +#define IR_MODE_SEL_Msk (0x1UL << IR_MODE_SEL_Pos) +#define IR_MODE_SEL_CLR (~IR_MODE_SEL_Msk) +/* TX_CONFIG[30] :IR_TX_START. 0x1: Start TX. 0x0: Stop TX. */ +#define IR_TX_START_Pos (30UL) +#define IR_TX_START_Msk (0x1UL << IR_TX_START_Pos) +#define IR_TX_START_CLR (~IR_TX_START_Msk) +/* TX_CONFIG[16] :IR_TX_DUTY_NUM. Duty cycle setting for modulation frequency. */ +/* Example : for 1/3 duty cycle, IR_DUTY_NUM = (IR_DIV_NUM+1)/3 -1. */ +#define IR_TX_DUTY_NUM_Pos (16UL) +#define IR_TX_DUTY_NUM_Msk (0x1FFFUL << IR_TX_DUTY_NUM_Pos) +/* TX_CONFIG[14] :IR_OUTPUT_INVERSE. 0x1: Inverse active output. 0x0: Not inverse active output. */ +#define IR_OUTPUT_INVERSE_Pos (14UL) +#define IR_OUTPUT_INVERSE_Msk (0x1UL << IR_OUTPUT_INVERSE_Pos) +#define IR_OUTPUT_INVERSE_CLR (~IR_OUTPUT_INVERSE_Msk) +/* TX_CONFIG[13] :IR_FIFO_INVERSE. 0x1: Inverse FIFO define. 0x0: Not inverse FIFO define. */ +#define IR_FIFO_INVERSE_Pos (13UL) +#define IR_FIFO_INVERSE_Msk (0x1UL << IR_FIFO_INVERSE_Pos) +#define IR_FIFO_INVERSE_CLR (~IR_FIFO_INVERSE_Msk) +/* TX_CONFIG[8] :IR_TX_FIFO_THRESHOLD. TX FIFO interrupt threshold. when TX FIFO depth <= threshold value, trigger interrupt. */ +#define IR_TX_FIFO_THRESHOLD_Pos (8UL) +#define IR_TX_FIFO_THRESHOLD_Msk (0x1fUL << IR_TX_FIFO_THRESHOLD_Pos) +#define IR_TX_FIFO_THRESHOLD_CLR (~IR_TX_FIFO_THRESHOLD_Msk) +/* TX_CONFIG[6] :IR_TX_IDLE_STATE. TX output State in idle. 0x1: High. 0x0: Low. */ +#define IR_TX_IDLE_STATE_Pos (6UL) +#define IR_TX_IDLE_STATE_Msk (0x1UL << IR_TX_IDLE_STATE_Pos) +#define IR_TX_IDLE_STATE_CLR (~IR_TX_IDLE_STATE_Msk) +/* TX_CONFIG[5] :IR_TX_FIFO_OVER_INT_MASK. TX FIFO empty Interrupt. 0x1: Mask. 0x0: Unmask. */ +#define IR_TX_FIFO_OVER_INT_MASK_Pos (5UL) +#define IR_TX_FIFO_OVER_INT_MASK_Msk (0x1UL << IR_TX_FIFO_OVER_INT_MASK_Pos) +#define IR_TX_FIFO_OVER_INT_MASK_CLR (~IR_TX_FIFO_OVER_INT_MASK_Msk) +/* TX_CONFIG[4] :IR_TX_FIFO_OVER_INT_EN. TX FIFO overflow Interrupt. 0x1: Enable. 0x0: Disable. */ +#define IR_TX_FIFO_OVER_INT_EN_Pos (4UL) +#define IR_TX_FIFO_OVER_INT_EN_Msk (0x1UL << IR_TX_FIFO_OVER_INT_EN_Pos) +#define IR_TX_FIFO_OVER_INT_EN_CLR (~IR_TX_FIFO_OVER_INT_EN_Msk) +#define IR_TX_FIFO_OVER_MSK_TO_EN_Pos (IR_TX_FIFO_OVER_INT_MASK_Pos - IR_TX_FIFO_OVER_INT_EN_Pos) +/* TX_CONFIG[3] :IR_TX_FIFO_LEVEL_INT_MASK. TX FIFO threshold Interrupt. 0x1: Mask. 0x0: Unmask. */ +#define IR_TX_FIFO_LEVEL_INT_MASK_Pos (3UL) +#define IR_TX_FIFO_LEVEL_INT_MASK_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_MASK_Pos) +#define IR_TX_FIFO_LEVEL_INT_MASK_CLR (~IR_TX_FIFO_LEVEL_INT_MASK_Msk) +/* TX_CONFIG[2] :IR_TX_FIFO_EMPTY_INT_MASK. TX FIFO empty Interrupt. 0x1: Mask. 0x0: Unmask. */ +#define IR_TX_FIFO_EMPTY_INT_MASK_Pos (2UL) +#define IR_TX_FIFO_EMPTY_INT_MASK_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_MASK_Pos) +#define IR_TX_FIFO_EMPTY_INT_MASK_CLR (~IR_TX_FIFO_EMPTY_INT_MASK_Msk) +/* TX_CONFIG[1] :IR_TX_FIFO_LEVEL_INT_EN. TX FIFO threshold Interrupt. 0x1: Enable. 0x0: Disable. */ +#define IR_TX_FIFO_LEVEL_INT_EN_Pos (1UL) +#define IR_TX_FIFO_LEVEL_INT_EN_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_EN_Pos) +#define IR_TX_FIFO_LEVEL_INT_EN_CLR (~IR_TX_FIFO_LEVEL_INT_EN_Msk) +/* TX_CONFIG[0] :IR_TX_FIFO_EMPTY_INT_EN. TX FIFO empty Interrupt. 0x1: Enable. 0x0: Disable. */ +#define IR_TX_FIFO_EMPTY_INT_EN_Pos (0UL) +#define IR_TX_FIFO_EMPTY_INT_EN_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_EN_Pos) +#define IR_TX_FIFO_EMPTY_INT_EN_CLR (~IR_TX_FIFO_EMPTY_INT_EN_Msk) +#define IR_TX_MSK_TO_EN_Pos (IR_TX_FIFO_EMPTY_INT_MASK_Pos - IR_TX_FIFO_EMPTY_INT_EN_Pos) +#define IR_TX_STATUS_TO_EN_Pos (IR_TX_FIFO_OVER_INT_EN_Pos - IR_TX_FIFO_EMPTY_INT_MASK_Pos) + +/* Register: TX_SR -----------------------------------------------------------*/ +/* Description: TX_SR register. Offset: 0x08. Address: 0x40003008. */ + +/* TX_SR[15] :IR_TX_FIFO_EMPTY. 0x1: empty. 0x0: not empty. */ +#define IR_TX_FIFO_EMPTY_Pos (15UL) +#define IR_TX_FIFO_EMPTY_Msk (0x1UL << IR_TX_FIFO_EMPTY_Pos) +/* TX_SR[14] :IR_TX_FIFO_FULL. 0x1: full. 0x0: not full. */ +#define IR_TX_FIFO_FULL_Pos (14UL) +#define IR_TX_FIFO_FULL_Msk (0x1UL << IR_TX_FIFO_FULL_Pos) +/* TX_SR[13:7] :IR_TX_FIFO_OFFSET. */ +#define IR_TX_FIFO_OFFSET_Pos (7UL) +#define IR_TX_FIFO_OFFSET_Msk (0x3fUL << IR_TX_FIFO_OFFSET_Pos) +/* TX_SR[4] :IR_TX_STATUS. */ +#define IR_TX_STATUS_Pos (4UL) +#define IR_TX_STATUS_Msk (0x1UL << IR_TX_STATUS_Pos) +/* TX_SR[2] :IR_TX_FIFO_OVER_INT_STATUS. */ +#define IR_TX_FIFO_OVER_INT_STATUS_Pos (2UL) +#define IR_TX_FIFO_OVER_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_OVER_INT_STATUS_Pos) +/* TX_SR[1] :IR_TX_FIFO_LEVEL_INT_STATUS. */ +#define IR_TX_FIFO_LEVEL_INT_STATUS_Pos (1UL) +#define IR_TX_FIFO_LEVEL_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_STATUS_Pos) +/* TX_SR[0] :IR_TX_FIFO_EMPTY_INT_STATUS. */ +#define IR_TX_FIFO_EMPTY_INT_STATUS_Pos (0UL) +#define IR_TX_FIFO_EMPTY_INT_STATUS_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_STATUS_Pos) + +/* Register: TX_INT_CLR -----------------------------------------------------------*/ +/* Description: TX_INT_CLR register. Offset: 0x10. Address: 0x40003010. */ + +/* TX_INT_CLR[3] :IR_TX_FIFO_OVER_INT_CLR. Write 1 clear. */ +#define IR_TX_FIFO_OVER_INT_CLR_Pos (3UL) +#define IR_TX_FIFO_OVER_INT_CLR_Msk (0x1UL << IR_TX_FIFO_OVER_INT_CLR_Pos) +/* TX_INT_CLR[2] :IR_TX_FIFO_LEVEL_INT_CLR. Write 1 clear. */ +#define IR_TX_FIFO_LEVEL_INT_CLR_Pos (2UL) +#define IR_TX_FIFO_LEVEL_INT_CLR_Msk (0x1UL << IR_TX_FIFO_LEVEL_INT_CLR_Pos) +/* TX_INT_CLR[1] :IR_TX_FIFO_EMPTY_INT_CLR. Write 1 clear. */ +#define IR_TX_FIFO_EMPTY_INT_CLR_Pos (1UL) +#define IR_TX_FIFO_EMPTY_INT_CLR_Msk (0x1UL << IR_TX_FIFO_EMPTY_INT_CLR_Pos) +/* TX_INT_CLR[0] :IR_TX_FIFO_CLR. Write 1 clear. */ +#define IR_TX_FIFO_CLR_Pos (0UL) +#define IR_TX_FIFO_CLR_Msk (0x1UL << IR_TX_FIFO_CLR_Pos) + +#define IR_INT_ALL_CLR (IR_TX_FIFO_OVER_INT_CLR_Msk | \ + IR_TX_FIFO_LEVEL_INT_CLR_Msk | \ + IR_TX_FIFO_EMPTY_INT_CLR_Msk) + +/* Register: TX_FIFO ---------------------------------------------------------*/ +/* Description: TX_FIFO register. Offset: 0x14. Address: 0x40003014. */ + +/* TX_FIFO[31] :IR_DATA_TYPE. 0x1: active carrier. 0x0: incative carrier. */ +#define IR_DATA_TYPE_Pos (31UL) +#define IR_DATA_TYPE_Msk (0x1UL << IR_DATA_TYPE_Pos) +#define IR_DATA_TYPE_CLR (~IR_DATA_TYPE_Msk) +/* TX_FIFO[30] :IR_TX_LAST_PACKEET. 0x1: last packet. 0x0: normal packet. */ +#define IR_TX_LAST_PACKEET_Pos (30UL) +#define IR_TX_LAST_PACKEET_Msk (0x1UL << IR_TX_LAST_PACKEET_Pos) +#define IR_TX_LAST_PACKEET_CLR (~IR_TX_LAST_PACKEET_Msk) +/* TX_FIFO[29:28] :IR_LOW_PERIOD_COMPENSATION */ +#define IR_LOW_PERIOD_COMPENSATION_Pos (28UL) +#define IR_LOW_PERIOD_COMPENSATION_Msk (0x3UL << IR_LOW_PERIOD_COMPENSATION_Pos) +#define IR_LOW_PERIOD_COMPENSATION_CLR (~IR_LOW_PERIOD_COMPENSATION_Msk) + +/* Register: RX_CONFIG ------------------------------------------------------*/ +/* Description: IR RX CONFIG register. Offset: 0x18. Address: 0x40003018. */ + +/* RX_CONFIG[28] :IR_RX_START. 0x1: Run. 0x0: Stop. */ +#define IR_RX_START_Pos (28UL) +#define IR_RX_START_Msk (0x1UL << IR_RX_START_Pos) +#define IR_RX_START_CLR (~IR_RX_START_Msk) +/* RX_CONFIG[27] :IR_RX_START_MODE. 0x1: auto mode. 0x0: manual mode. */ +#define IR_RX_START_MODE_Pos (27UL) +#define IR_RX_START_MODE_Msk (0x1UL << IR_RX_START_MODE_Pos) +#define IR_RX_START_MODE_CLR (~IR_RX_START_MODE_Msk) +/* RX_CONFIG[26] :IR_RX_MAN_START. 0x1: Start check waveform. */ +#define IR_RX_MAN_START_Pos (26UL) +#define IR_RX_MAN_START_Msk (0x1UL << IR_RX_MAN_START_Pos) +#define IR_RX_MAN_START_CLR (~IR_RX_MAN_START_Msk) +/* RX_CONFIG[24] :IR_TRIGGER_MODE. 0x1: Run. */ +/* 0x0: high->low trigger. 0x1: low->high trigger. 0x02: high->low or low->high trigger. */ +#define IR_TRIGGER_MODE_Pos (24UL) +#define IR_TRIGGER_MODE_Msk (0x3UL << IR_TRIGGER_MODE_Pos) +#define IR_TRIGGER_MODE_CLR (~IR_TRIGGER_MODE_Msk) +/* RX_CONFIG[21] :IR_FILTER_TIME. */ +#define IR_FILTER_TIME_Pos (21UL) +#define IR_FILTER_TIME_Msk (0x3UL << IR_FILTER_TIME_Pos) +#define IR_FILTER_TIME_CLR (~IR_FILTER_TIME_Msk) +/* RX_CONFIG[19] :IR_RX_FIFO_ERROR_MASK_INT. 0x1: mask. 0x0: unmask.*/ +#define IR_RX_FIFO_ERROR_MASK_INT_Pos (19UL) +#define IR_RX_FIFO_ERROR_MASK_INT_Msk (0x1UL << IR_RX_FIFO_ERROR_MASK_INT_Pos) +#define IR_RX_FIFO_ERROR_MASK_INT_CLR (~IR_RX_FIFO_ERROR_MASK_INT_Msk) +/* RX_CONFIG[18] :IR_RX_CNT_THR_MASK_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_CNT_THR_MASK_INT_Pos (18UL) +#define IR_RX_CNT_THR_MASK_INT_Msk (0x1UL << IR_RX_CNT_THR_MASK_INT_Pos) +#define IR_RX_CNT_THR_MASK_INT_CLR (~IR_RX_CNT_THR_MASK_INT_Msk) +/* RX_CONFIG[17] :IR_RX_FIFO_OF_MASK_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_OF_MASK_INT_Pos (17UL) +#define IR_RX_FIFO_OF_MASK_INT_Msk (0x1UL << IR_RX_FIFO_OF_MASK_INT_Pos) +#define IR_RX_FIFO_OF_MASK_INT_CLR (~IR_RX_FIFO_OF_MASK_INT_Msk) +/* RX_CONFIG[16] :IR_RX_CNT_OF_MASK_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_CNT_OF_MASK_INT_Pos (16UL) +#define IR_RX_CNT_OF_MASK_INT_Msk (0x1UL << IR_RX_CNT_OF_MASK_INT_Pos) +#define IR_RX_CNT_OF_MASK_INT_CLR (~IR_RX_CNT_OF_MASK_INT_Msk) +/* RX_CONFIG[15] :IR_RX_FIFO_LEVEL_MASK_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_LEVEL_MASK_INT_Pos (15UL) +#define IR_RX_FIFO_LEVEL_MASK_INT_Msk (0x1UL << IR_RX_FIFO_LEVEL_MASK_INT_Pos) +#define IR_RX_FIFO_LEVEL_MASK_INT_CLR (~IR_RX_FIFO_LEVEL_MASK_INT_Msk) +/* RX_CONFIG[14] :IR_RX_FIFO_FULL_MASK_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_FULL_MASK_INT_Pos (14UL) +#define IR_RX_FIFO_FULL_MASK_INT_Msk (0x1UL << IR_RX_FIFO_FULL_MASK_INT_Pos) +#define IR_RX_FIFO_FULL_MASK_INT_CLR (~IR_RX_FIFO_FULL_MASK_INT_Msk) +/* RX_CONFIG[13] :IR_RX_FIFO_DISCARD_SET. 0x1: reject new data send to FIFO. 0x0: discard oldest data in FIFO.*/ +#define IR_RX_FIFO_DISCARD_SET_Pos (13UL) +#define IR_RX_FIFO_DISCARD_SET_Msk (0x1UL << IR_RX_FIFO_DISCARD_SET_Pos) +#define IR_RX_FIFO_DISCARD_SET_CLR (~IR_RX_FIFO_DISCARD_SET_Msk) +/* RX_CONFIG[7] :IR_RX_FIFO_LEVE. */ +#define IR_RX_FIFO_LEVEL_Pos (8UL) +#define IR_RX_FIFO_LEVEL_Msk (0x1fUL << IR_RX_FIFO_LEVEL_Pos) +#define IR_RX_FIFO_LEVEL_CLR (~IR_RX_FIFO_LEVEL_Msk) +/* RX_CONFIG[5] :IR_RX_FIFO_ERROR_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_ERROR_INT_Pos (5UL) +#define IR_RX_FIFO_ERROR_INT_Msk (0x1UL << IR_RX_FIFO_ERROR_INT_Pos) +#define IR_RX_FIFO_ERROR_INT_CLR (~IR_RX_FIFO_ERROR_INT_Msk) +/* RX_CONFIG[4] :IR_RX_CNT_THR_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_CNT_THR_INT_Pos (4UL) +#define IR_RX_CNT_THR_INT_Msk (0x1UL << IR_RX_CNT_THR_INT_Pos) +#define IR_RX_CNT_THR_INT_CLR (~IR_RX_CNT_THR_INT_Msk) +/* RX_CONFIG[3] :IR_RX_FIFO_OF_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_OF_INT_Pos (3UL) +#define IR_RX_FIFO_OF_INT_Msk (0x1UL << IR_RX_FIFO_OF_INT_Pos) +#define IR_RX_FIFO_OF_INT_CLR (~IR_RX_FIFO_OF_INT_Msk) +/* RX_CONFIG[2] :IR_RX_CNT_OF_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_CNT_OF_INT_Pos (2UL) +#define IR_RX_CNT_OF_INT_Msk (0x1UL << IR_RX_CNT_OF_INT_Pos) +#define IR_RX_CNT_OF_INT_CLR (~IR_RX_CNT_OF_INT_Msk) +/* RX_CONFIG[1] :IR_RX_FIFO_LEVEL_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_LEVEL_INT_Pos (1UL) +#define IR_RX_FIFO_LEVEL_INT_Msk (0x1UL << IR_RX_FIFO_LEVEL_INT_Pos) +#define IR_RX_FIFO_LEVEL_INT_CLR (~IR_RX_FIFO_LEVEL_INT_Msk) +/* RX_CONFIG[0] :IR_RX_FIFO_FULL_INT. 0x1: enable. 0x0: disable.*/ +#define IR_RX_FIFO_FULL_INT_Pos (0UL) +#define IR_RX_FIFO_FULL_INT_Msk (0x1UL << IR_RX_FIFO_FULL_INT_Pos) +#define IR_RX_FIFO_FULL_INT_CLR (~IR_RX_FIFO_FULL_INT_Msk) +#define IR_RX_MSK_TO_EN_Pos (IR_RX_FIFO_FULL_MASK_INT_Pos - IR_RX_FIFO_FULL_INT_Pos) + +#define IR_RX_MASK_ALL_INT (IR_RX_FIFO_ERROR_MASK_INT_Msk | IR_RX_CNT_THR_MASK_INT_Msk | \ + IR_RX_FIFO_OF_MASK_INT_Msk | IR_RX_CNT_OF_MASK_INT_Msk | \ + IR_RX_FIFO_LEVEL_MASK_INT_Msk | IR_RX_FIFO_FULL_MASK_INT_Msk) + +/* Register: RX_SR -----------------------------------------------------------*/ +/* Description: RX_SR register. Offset: 0x1C. Address: 0x4000301C. */ + +/* RX_SR[17] :IR_TX_FIFO_EMPTY. 0x1: empty. 0x0: not empty. */ +#define IR_RX_FIFO_EMPTY_Pos (17UL) +#define IR_RX_FIFO_EMPTY_Msk (0x1UL << IR_RX_FIFO_EMPTY_Pos) +/* RX_SR[8] :IR_RX_FIFO_OFFSET. */ +#define IR_RX_FIFO_OFFSET_Pos (8UL) +#define IR_RX_FIFO_OFFSET_Msk (0x3fUL << IR_RX_FIFO_OFFSET_Pos) +#define IR_RX_FIFO_OFFSET_CLR (~IR_RX_FIFO_OFFSET_Msk) +/* RX_SR[7] :IR_RX_STATUS. */ +#define IR_RX_STATUS_Pos (7UL) +#define IR_RX_STATUS_Msk (0x1UL << IR_RX_STATUS_Pos) + +/* Register: RX_INT_CLR -----------------------------------------------------------*/ +/* Description: RX_INT_CLR register. Offset: 0x20. Address: 0x40003020. */ + +/* RX_INT_CLR[8] :IR_RX_FIFO_CLR. Write 1 clear. */ +#define IR_RX_FIFO_CLR_Pos (8UL) +#define IR_RX_FIFO_CLR_Msk (0x1UL << IR_RX_FIFO_CLR_Pos) +/* RX_INT_CLR[5] :IR_RX_FIFO_ERROR_INT_CLR. Write 1 clear. */ +#define IR_RX_FIFO_ERROR_INT_CLR_Pos (5UL) +#define IR_RX_FIFO_ERROR_INT_CLR_Msk (0x1UL << IR_RX_FIFO_ERROR_INT_CLR_Pos) +/* RX_INT_CLR[4] :IR_RX_CNT_THR_INT_CLR. Write 1 clear. */ +#define IR_RX_CNT_THR_INT_CLR_Pos (4UL) +#define IR_RX_CNT_THR_INT_CLR_Msk (0x1UL << IR_RX_CNT_THR_INT_CLR_Pos) +/* RX_INT_CLR[3] :IR_RX_FIFO_OF_INT_CLR. Write 1 clear. */ +#define IR_RX_FIFO_OF_INT_CLR_Pos (3UL) +#define IR_RX_FIFO_OF_INT_CLR_Msk (0x1UL << IR_RX_FIFO_OF_INT_CLR_Pos) +/* RX_INT_CLR[2] :IR_RX_CNT_OF_INT_CLR. Write 1 clear. */ +#define IR_RX_CNT_OF_INT_CLR_Pos (2UL) +#define IR_RX_CNT_OF_INT_CLR_Msk (0x1UL << IR_RX_CNT_OF_INT_CLR_Pos) +/* RX_INT_CLR[1] :IR_RX_FIFO_LEVEL_INT_CLR. Write 1 clear. */ +#define IR_RX_FIFO_LEVEL_INT_CLR_Pos (1UL) +#define IR_RX_FIFO_LEVEL_INT_CLR_Msk (0x1UL << IR_RX_FIFO_LEVEL_INT_CLR_Pos) +/* RX_INT_CLR[0] :IR_RX_FIFO_FULL_INT_CLR. Write 1 clear. */ +#define IR_RX_FIFO_FULL_INT_CLR_Pos (0UL) +#define IR_RX_FIFO_FULL_INT_CLR_Msk (0x1UL << IR_RX_FIFO_FULL_INT_CLR_Pos) + +#define IR_RX_INT_ALL_CLR (IR_RX_FIFO_CLR_Msk | IR_RX_FIFO_ERROR_INT_CLR_Msk | \ + IR_RX_CNT_THR_INT_CLR_Msk | IR_RX_FIFO_OF_INT_CLR_Msk | \ + IR_RX_CNT_OF_INT_CLR_Msk | IR_RX_FIFO_LEVEL_INT_CLR_Msk | \ + IR_RX_FIFO_FULL_INT_CLR_Msk) + +/* Register: RX_CNT_INT_SEL -------------------------------------------------*/ +/* Description: IR RX counter interrupt setting register. Offset: 0x24. Address: 0x40003024. */ + +/* RX_CNT_INT_SEL[31] :IR_RX_CNT_THR_TRIGGER_LV. */ +/* 0x1: high level couner >= threshlod trigger interrupt. 0x0: low level couner >= threshlod trigger interrupt. */ +#define IR_RX_CNT_THR_TYPE_Pos (31UL) +#define IR_RX_CNT_THR_TYPE_Msk (0x1UL << IR_RX_CNT_THR_TYPE_Pos) +#define IR_RX_CNT_THR_TYPE_CLR (~IR_RX_CNT_THR_TYPE_Msk) +/* RX_CNT_INT_SEL[30:0] :IR_RX_CNT_THR. */ +#define IR_RX_CNT_THR_Pos (0UL) +#define IR_RX_CNT_THR_Msk (0x7fffffffUL << IR_RX_CNT_THR_Pos) +#define IR_RX_CNT_THR_CLR (~IR_RX_CNT_THR_Msk) + +/* Register: RX_INT_CR -------------------------------------------------*/ +/* Description: IR RX interrupt config register. Offset: 0x34. Address: 0x40003034. */ + +/* RX_INT_CR[7] :IR_RX_RISING_EDGE_INT_CLR. */ +#define IR_RX_RISING_EDGE_INT_CLR_Pos (7UL) +#define IR_RX_RISING_EDGE_INT_CLR_Msk (0x1UL << IR_RX_RISING_EDGE_INT_CLR_Pos) +#define IR_RX_RISING_EDGE_INT_CLR_CLR (~IR_RX_RISING_EDGE_INT_CLR_Msk) +/* RX_INT_CR[6] :IR_RX_FALLING_EDGE_INT_CLR. */ +#define IR_RX_FALLING_EDGE_INT_CLR_Pos (6UL) +#define IR_RX_FALLING_EDGE_INT_CLR_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_CLR_Pos) +#define IR_RX_FALLING_EDGE_INT_CLR_CLR (~IR_RX_FALLING_EDGE_INT_CLR_Msk) +/* RX_INT_CR[5] :IR_RX_RISING_EDGE_INT_STATUS. */ +#define IR_RX_RISING_EDGE_INT_STATUS_Pos (5UL) +#define IR_RX_RISING_EDGE_INT_STATUS_Msk (0x1UL << IR_RX_RISING_EDGE_INT_STATUS_Pos) +#define IR_RX_RISING_EDGE_INT_STATUS_CLR (~IR_RX_RISING_EDGE_INT_STATUS_Msk) +/* RX_INT_CR[4] :IR_RX_FALLING_EDGE_INT_STATUS. */ +#define IR_RX_FALLING_EDGE_INT_STATUS_Pos (4UL) +#define IR_RX_FALLING_EDGE_INT_STATUS_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_STATUS_Pos) +#define IR_RX_FALLING_EDGE_INT_STATUS_CLR (~IR_RX_FALLING_EDGE_INT_STATUS_Msk) +/* RX_INT_CR[3] :IR_RX_RISING_EDGE_INT_MASK. */ +#define IR_RX_RISING_EDGE_INT_MASK_Pos (3UL) +#define IR_RX_RISING_EDGE_INT_MASK_Msk (0x1UL << IR_RX_RISING_EDGE_INT_MASK_Pos) +#define IR_RX_RISING_EDGE_INT_MASK_CLR (~IR_RX_RISING_EDGE_INT_MASK_Msk) +/* RX_INT_CR[2] :IR_RX_FALLING_EDGE_INT_MASK. */ +#define IR_RX_FALLING_EDGE_INT_MASK_Pos (2UL) +#define IR_RX_FALLING_EDGE_INT_MASK_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_MASK_Pos) +#define IR_RX_FALLING_EDGE_INT_MASK_CLR (~IR_RX_FALLING_EDGE_INT_MASK_Msk) +/* RX_INT_CR[1] :IR_RX_RISING_EDGE_INT_EN. */ +#define IR_RX_RISING_EDGE_INT_EN_Pos (1UL) +#define IR_RX_RISING_EDGE_INT_EN_Msk (0x1UL << IR_RX_RISING_EDGE_INT_EN_Pos) +#define IR_RX_RISING_EDGE_INT_EN_CLR (~IR_RX_RISING_EDGE_INT_EN_Msk) +/* RX_INT_CR[0] :IR_RX_FALLING_EDGE_INT_EN. */ +#define IR_RX_FALLING_EDGE_INT_EN_Pos (0UL) +#define IR_RX_FALLING_EDGE_INT_EN_Msk (0x1UL << IR_RX_FALLING_EDGE_INT_EN_Pos) +#define IR_RX_FALLING_EDGE_INT_EN_CLR (~IR_RX_FALLING_EDGE_INT_EN_Msk) + +#define IR_RX_EXTENSION_INT 0x8000 + +/* Register: IR_TX_COMPE -------------------------------------------------*/ +/* Description: IR TX compensation register. Offset: 0x48. Address: 0x40003048. */ + +/* IR_TX_COMPE[29:16] : IR_TX_COMPENSATION. */ +#define IR_TX_COMPENSATION_Pos (16UL) +#define IR_TX_COMPENSATION_Msk (0x3FFFUL << IR_TX_COMPENSATION_Pos) +#define IR_TX_COMPENSATION_CLR (~IR_TX_COMPENSATION_Msk) + +/* Register: DMA_CONFIG -------------------------------------------------*/ +/* Description: IR dma config register. Offset: 0x50. Address: 0x40003050. */ + +/* DMA_CONFIG[0] : IR_TX_DMA_ENABLE. */ +#define IR_TX_DMA_EN_Pos (0UL) +#define IR_TX_DMA_EN_Msk (0x1UL << IR_TX_DMA_EN_Pos) +#define IR_TX_DMA_EN_CLR (~IR_TX_DMA_EN_Msk) +/* DMA_CONFIG[6:1] : IR_TX_WATER_LEVEL. */ +#define IR_TX_WATER_LEVEL_Pos (1UL) +#define IR_TX_WATER_LEVEL_Msk (0x3FUL << IR_TX_WATER_LEVEL_Pos) +#define IR_TX_WATER_LEVEL_CLR (~IR_TX_WATER_LEVEL_Msk) +/* DMA_CONFIG[8] : IR_RX_DMA_ENABLE. */ +#define IR_RX_DMA_EN_Pos (8UL) +#define IR_RX_DMA_EN_Msk (0x1UL << IR_RX_DMA_EN_Pos) +#define IR_RX_DMA_EN_CLR (~IR_RX_DMA_EN_Msk) +/* DMA_CONFIG[14:9] : IR_RX_WATER_LEVEL. */ +#define IR_RX_WATER_LEVEL_Pos (9UL) +#define IR_RX_WATER_LEVEL_Msk (0x3FUL << IR_RX_WATER_LEVEL_Pos) +#define IR_RX_WATER_LEVEL_CLR (~IR_RX_WATER_LEVEL_Msk) + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup IR_Exported_Constants Marco Defines + * + * \ingroup IR + */ + +#define IS_IR_PERIPH(PERIPH) ((PERIPH) == IR) +#define IR_TX_FIFO_SIZE 32 +#define IR_RX_FIFO_SIZE 32 + +/** \defgroup IR_CLOCK IR Clock + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_CLOCK_40M (40000000) +#define IR_CLOCK_90M (90000000) +#define IR_CLOCK_100M (100000000) +/** \} */ + +#define IS_IR_CLOCK(CLK) (((CLK) == IR_CLOCK_40M)\ + || ((CLK) == IR_CLOCK_90M)\ + || ((CLK) == IR_CLOCK_100M)) + +#define IS_IR_FREQUENCY_40M(F) (((F) >= 2442) && ((F) <= 2000000)) +#define IS_IR_FREQUENCY_90M(F) (((F) >= 5494) && ((F) <= 2000000)) +#define IS_IR_FREQUENCY_100M(F) (((F) >= 6104) && ((F) <= 2000000)) + +/** + * \defgroup IR_Mode IR Mode + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_MODE_TX ((uint32_t)((uint32_t)0x0 << IR_MODE_SEL_Pos)) +#define IR_MODE_RX ((uint32_t)((uint32_t)0x1 << IR_MODE_SEL_Pos)) +/** \} */ + +#define IS_IR_MODE(MODE) (((MODE) == IR_MODE_TX) || ((MODE) == IR_MODE_RX)) + +/** + * \defgroup IR_Idle_Status IR Idle Status + * \{ + * \ingroup IR_Exported_Constants + */ + +#define IR_IDLE_OUTPUT_HIGH ((uint32_t)(0x01 << IR_TX_IDLE_STATE_Pos)) +#define IR_IDLE_OUTPUT_LOW ((uint32_t)(0x00 << IR_TX_IDLE_STATE_Pos)) +/** \} */ + +#define IS_IR_IDLE_STATUS(LEVEL) (((LEVEL) == IR_IDLE_OUTPUT_HIGH) || ((LEVEL) == IR_IDLE_OUTPUT_LOW)) + +/** + * \defgroup IR_TX_Data_Type IR TX Data Type + * \{ + * \ingroup IR_Exported_Constants + */ + +#define IR_TX_DATA_NORMAL ((uint32_t)(0 << IR_FIFO_INVERSE_Pos)) +#define IR_TX_DATA_INVERSE ((uint32_t)(1 << IR_FIFO_INVERSE_Pos)) +/** \} */ + +#define IS_IR_TX_DATA_TYPE(TYPE) (((TYPE) == IR_TX_DATA_NORMAL) || ((TYPE) == IR_TX_DATA_INVERSE)) + +/** + * \def IR_Tx_Threshold IR TX Threshold + */ +#define IS_IR_TX_THRESHOLD(THD) ((THD) <= IR_TX_FIFO_SIZE) + +/** + * \def IR_Rx_Threshold IR RX Threshold + */ +#define IS_IR_RX_THRESHOLD(THD) ((THD) <= IR_RX_FIFO_SIZE) + +/** + * \defgroup IR_Rx_Start_Mode RX Start Mode + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_RX_AUTO_MODE ((uint32_t)((0x1) << IR_RX_START_MODE_Pos)) +#define IR_RX_MANUAL_MODE ((uint32_t)((0x0) << IR_RX_START_MODE_Pos)) +/** \} */ + +#define IS_RX_START_MODE(MODE) (((MODE) == IR_RX_AUTO_MODE) || ((MODE) == IR_RX_MANUAL_MODE)) + + +/** + * \defgroup IR_RX_Trigger_Mode RX Trigger Mode + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_RX_FALL_EDGE ((uint32_t)((0x0) << IR_TRIGGER_MODE_Pos)) +#define IR_RX_RISING_EDGE ((uint32_t)((0x1) << IR_TRIGGER_MODE_Pos)) +#define IR_RX_DOUBLE_EDGE ((uint32_t)((0x2) << IR_TRIGGER_MODE_Pos)) +/** \} */ + +#define IS_RX_RX_TRIGGER_EDGE(EDGE) (((EDGE) == IR_RX_FALL_EDGE) || ((EDGE) == IR_RX_RISING_EDGE) || ((EDGE) == IR_RX_DOUBLE_EDGE)) + +/** + * \defgroup IR_RX_FIFO_DISCARD_SETTING IR RX FIFO Discard Setting + * \{ + * \ingroup IR_Exported_Constants + */ + +#define IR_RX_FIFO_FULL_DISCARD_NEWEST ((uint32_t)(0 << IR_RX_FIFO_DISCARD_SET_Pos)) +#define IR_RX_FIFO_FULL_DISCARD_OLDEST ((uint32_t)(1 << IR_RX_FIFO_DISCARD_SET_Pos)) +/** \} */ + +#define IS_IR_RX_FIFO_FULL_CTRL(CTRL) (((CTRL) == IR_RX_FIFO_FULL_DISCARD_NEWEST) || ((CTRL) == IR_RX_FIFO_FULL_DISCARD_OLDEST)) + +/** + * \defgroup IR_RX_Filter_Time RX Filter Time + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_RX_FILTER_TIME_50ns ((uint32_t)((0x0) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_75ns ((uint32_t)((0x2) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_100ns ((uint32_t)((0x3) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_125ns ((uint32_t)((0x4) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_150ns ((uint32_t)((0x5) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_175ns ((uint32_t)((0x6) << IR_FILTER_TIME_Pos)) +#define IR_RX_FILTER_TIME_200ns ((uint32_t)((0x7) << IR_FILTER_TIME_Pos)) +/** \} */ + +#define IS_IR_RX_FILTER_TIME_CTRL(CTRL) (((CTRL) == IR_RX_FILTER_TIME_50ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_75ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_100ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_125ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_150ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_175ns) || \ + ((CTRL) == IR_RX_FILTER_TIME_200ns)) +/** + * \defgroup IR_RX_COUNTER_THRESHOLD_TYPE IR RX Counter Threshold Type + * \{ + * \ingroup IR_Exported_Constants + */ + +#define IR_RX_Count_Low_Level ((uint32_t)0 << IR_RX_CNT_THR_TYPE_Pos) +#define IR_RX_Count_High_Level ((uint32_t)1 << IR_RX_CNT_THR_TYPE_Pos) +/** \} */ + +#define IS_IR_RX_COUNT_LEVEL_CTRL(CTRL) (((CTRL) == IR_RX_Count_Low_Level) || ((CTRL) == IR_RX_Count_High_Level)) + +/** + * \def IR_Rx_Counter_Threshold IR RX Counter Threshold + */ +#define IS_IR_RX_COUNTER_THRESHOLD(THD) ((THD) <= IR_RX_CNT_THR_Msk) + +/** + * \defgroup IR_Interrupt_Definition IR Interrupt Definition + * \{ + * \ingroup IR_Exported_Constants + */ +/* All interrupts in transmission mode */ +#define IR_INT_TF_EMPTY ((uint32_t)IR_TX_FIFO_EMPTY_INT_EN_Msk) +#define IR_INT_TF_LEVEL ((uint32_t)IR_TX_FIFO_LEVEL_INT_EN_Msk) +#define IR_INT_TF_OF ((uint32_t)IR_TX_FIFO_OVER_INT_EN_Msk) +/* All interrupts in receiving mode */ +#define IR_INT_RF_FULL ((uint32_t)IR_RX_FIFO_FULL_INT_Msk) +#define IR_INT_RF_LEVEL ((uint32_t)IR_RX_FIFO_LEVEL_INT_Msk) +#define IR_INT_RX_CNT_OF ((uint32_t)IR_RX_CNT_OF_INT_Msk) +#define IR_INT_RF_OF ((uint32_t)IR_RX_FIFO_OF_INT_Msk) +#define IR_INT_RX_CNT_THR ((uint32_t)IR_RX_CNT_THR_INT_Msk) +#define IR_INT_RF_ERROR ((uint32_t)IR_RX_FIFO_ERROR_INT_Msk) +#define IR_INT_RISING_EDGE ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_RISING_EDGE_INT_EN_Msk)) +#define IR_INT_FALLING_EDGE ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_FALLING_EDGE_INT_EN_Msk)) +/** \} */ + +#define IS_IR_TX_INT_CONFIG(CONFIG) (((CONFIG) == IR_INT_TF_EMPTY) || \ + ((CONFIG) == IR_INT_TF_LEVEL) || \ + ((CONFIG) == IR_INT_TF_OF)) + +#define IS_IR_RX_INT_CONFIG(CONFIG) (((CONFIG) == IR_INT_RF_FULL) || \ + ((CONFIG) == IR_INT_RF_LEVEL) || \ + ((CONFIG) == IR_INT_RX_CNT_OF) || \ + ((CONFIG) == IR_INT_RF_OF) || \ + ((CONFIG) == IR_INT_RX_CNT_THR) || \ + ((CONFIG) == IR_INT_RF_OF) || \ + ((CONFIG) == IR_INT_RISING_EDGE) || \ + ((CONFIG) == IR_INT_FALLING_EDGE)) +#define IS_IR_INT_CONFIG(CONFIG) (IS_IR_TX_INT_CONFIG(CONFIG) || IS_IR_RX_INT_CONFIG(CONFIG)) + +/** + * \defgroup IR_Interrupts_Clear_Flag IR Interrupts Clear Flag + * \{ + * \ingroup IR_Exported_Constants + */ +/* Clear all interrupts in transmission mode */ +#define IR_INT_TF_EMPTY_CLR ((uint32_t)IR_TX_FIFO_EMPTY_INT_CLR_Msk) +#define IR_INT_TF_LEVEL_CLR ((uint32_t)IR_TX_FIFO_LEVEL_INT_CLR_Msk) +#define IR_INT_TF_OF_CLR ((uint32_t)IR_TX_FIFO_OVER_INT_CLR_Msk) +/* Clear all interrupts in receiving mode */ +#define IR_INT_RF_FULL_CLR ((uint32_t)IR_RX_FIFO_FULL_INT_CLR_Msk) +#define IR_INT_RF_LEVEL_CLR ((uint32_t)IR_RX_FIFO_LEVEL_INT_CLR_Msk) +#define IR_INT_RX_CNT_OF_CLR ((uint32_t)IR_RX_CNT_OF_INT_CLR_Msk) +#define IR_INT_RF_OF_CLR ((uint32_t)IR_RX_FIFO_OF_INT_CLR_Msk) +#define IR_INT_RX_CNT_THR_CLR ((uint32_t)IR_RX_CNT_THR_INT_CLR_Msk) +#define IR_INT_RF_ERROR_CLR ((uint32_t)IR_RX_FIFO_ERROR_INT_CLR_Msk) +#define IR_INT_RX_RISING_EDGE_CLR ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_RISING_EDGE_INT_CLR_Msk)) +#define IR_INT_RX_FALLING_EDGE_CLR ((uint32_t)(IR_RX_EXTENSION_INT | IR_RX_FALLING_EDGE_INT_CLR_Msk)) +#define IR_RF_CLR ((uint32_t)IR_RX_FIFO_CLR_Msk) +/** \} */ + +#define IS_IR_INT_CLEAR(INT) (((INT) == IR_INT_TF_EMPTY_CLR) || ((INT) == IR_INT_TF_LEVEL_CLR) || \ + ((INT) == IR_INT_TF_OF_CLR) || ((INT) == IR_INT_RF_FULL_CLR) || \ + ((INT) == IR_INT_RF_LEVEL_CLR) || ((INT) == IR_INT_RX_CNT_OF_CLR) || \ + ((INT) == IR_INT_RF_OF_CLR) || ((INT) == IR_INT_RX_CNT_THR_CLR) || \ + ((INT) == IR_INT_RX_RISING_EDGE_CLR) || ((INT) == IR_INT_RX_FALLING_EDGE_CLR) || \ + ((INT) == IR_INT_RF_ERROR_CLR)) + +/** + * \defgroup IR_Flag IR Flag + * \{ + * \ingroup IR_Exported_Constants + */ +#define IR_FLAG_TF_EMPTY ((uint32_t)IR_TX_FIFO_EMPTY_Msk) +#define IR_FLAG_TF_FULL ((uint32_t)IR_TX_FIFO_FULL_Msk) +#define IR_FLAG_TX_RUN ((uint32_t)IR_TX_STATUS_Msk) +#define IR_FLAG_RF_EMPTY ((uint32_t)IR_RX_FIFO_EMPTY_Msk) +#define IR_FLAG_RX_RUN ((uint32_t)IR_RX_STATUS_Msk) +/** \} */ + +#define IS_IR_FLAG(FLAG) (((FLAG) == IR_FLAG_TF_EMPTY) || ((FLAG) == IR_FLAG_TF_FULL) || \ + ((FLAG) == IR_FLAG_TX_RUN) || ((FLAG) == IR_FLAG_RF_EMPTY) || \ + ((FLAG) == IR_FLAG_RX_RUN)) +/** + * \enum IR_Compensation_Flag IR Compensation Flag + * \ingroup IR_Exported_Constants + */ +typedef enum +{ + IR_COMPEN_FLAG_1_2_CARRIER = ((uint32_t)(1 << IR_LOW_PERIOD_COMPENSATION_Pos)), + IR_COMPEN_FLAG_1_4_CARRIER = ((uint32_t)(2 << IR_LOW_PERIOD_COMPENSATION_Pos)), + IR_COMPEN_FLAG_1_N_SYSTEM_CLK = ((uint32_t)(3 << IR_LOW_PERIOD_COMPENSATION_Pos)), +} IR_TX_COMPEN_TYPE; + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup IR_Exported_Functions Peripheral APIs + * \{ + * \ingroup IR + */ + +/** + * \brief Deinitializes the IR peripheral registers to their default values. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_ir_init(void) + * { + * IR_DeInit(); + * } + * \endcode + */ +void IR_DeInit(void); + +/** + * \brief Initializes the IR peripheral according to the specified + * parameters in IR_InitStruct. + * \param[in] IR_InitStruct: Pointer to a IR_InitTypeDef structure that + * contains the configuration information for the specified IR peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_ir_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE); + + * IR_InitTypeDef IR_InitStruct; + * IR_StructInit(&IR_InitStruct); + + * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz + * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode + * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE; + * IR_InitStruct.IR_RxFIFOThrLevel = + IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt + * IR_InitStruct.IR_RxFIFOFullCtrl = + * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the lastest received dta if RX FIFO is full + * IR_InitStruct.IR_RxFilterTime = + IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it. + * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type + * IR_InitStruct.IR_RxCntThrType = + IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level + * IR_InitStruct.IR_RxCntThr = + 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data + * IR_Init(&IR_InitStruct); + * IR_Cmd(IR_MODE_RX, ENABLE); + * IR_ClearRxFIFO(); + * } + * \endcode + */ +void IR_Init(IR_InitTypeDef *IR_InitStruct); + +/** + * \brief Fills each IR_InitStruct member with its default value. + * \param[in] IR_InitStruct: Pointer to an IR_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_ir_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE); + + * IR_InitTypeDef IR_InitStruct; + * IR_StructInit(&IR_InitStruct); + + * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz + * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode + * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE; + * IR_InitStruct.IR_RxFIFOThrLevel = + IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt + * IR_InitStruct.IR_RxFIFOFullCtrl = + * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the lastest received dta if RX FIFO is full + * IR_InitStruct.IR_RxFilterTime = + IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it. + * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type + * IR_InitStruct.IR_RxCntThrType = + IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level + * IR_InitStruct.IR_RxCntThr = + 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data + * IR_Init(&IR_InitStruct); + * IR_Cmd(IR_MODE_RX, ENABLE); + * IR_ClearRxFIFO(); + * } + * \endcode + */ +void IR_StructInit(IR_InitTypeDef *IR_InitStruct); + +/** + * \brief Enable or disable the selected IR mode. + * \param[in] mode: Selected IR operation mode. + * This parameter can be one of the following values: + * \arg IR_MODE_TX: Transmission mode. + * \arg IR_MODE_RX: Receiving mode. + * \param[in] NewState: New state of the operation mode. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_ir_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, ENABLE); + + * IR_InitTypeDef IR_InitStruct; + * IR_StructInit(&IR_InitStruct); + + * IR_InitStruct.IR_Freq = 38000;// IR carrier freqency is 38KHz + * IR_InitStruct.IR_Mode = IR_MODE_RX;// IR receiveing mode + * IR_InitStruct.IR_RxStartMode = IR_RX_AUTO_MODE; + * IR_InitStruct.IR_RxFIFOThrLevel = + IR_RX_FIFO_THR_LEVEL; // Configure RX FIFO threshold level to trigger IR_INT_RF_LEVEL interrupt + * IR_InitStruct.IR_RxFIFOFullCtrl = + * IR_RX_FIFO_FULL_DISCARD_NEWEST;// Discard the lastest received dta if RX FIFO is full + * IR_InitStruct.IR_RxFilterTime = + IR_RX_FILTER_TIME_50ns;// If high to low or low to high transition time <= 50ns,Filter out it. + * IR_InitStruct.IR_RxTriggerMode = IR_RX_FALL_EDGE;// Configure trigger type + * IR_InitStruct.IR_RxCntThrType = + IR_RX_Count_High_Level;// IR_RX_Count_High_Level is counting high level + * IR_InitStruct.IR_RxCntThr = + 0x1F40;// Configure RX counter threshold.You can use it to decide to stop receiving IR data + * IR_Init(&IR_InitStruct); + * IR_Cmd(IR_MODE_RX, ENABLE); + * IR_ClearRxFIFO(); + * } + * \endcode + */ +void IR_Cmd(uint32_t mode, FunctionalState NewState); + +/** + * \brief Start trigger receive, only in manual receive mode. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_StartManualRxTrigger(); + * } + * \endcode + */ +void IR_StartManualRxTrigger(void); + +/** + * \brief Config counter threshold value in receiving mode.You can use it to stop receiving IR data. + * \param[in] IR_RxCntThrType: Count threshold type. + * This parameter can be the following values: + * \arg IR_RX_Count_Low_Level: Low level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * \arg IR_RX_Count_High_Level: High level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * \param[in] IR_RxCntThr: Configure IR Rx counter threshold value which can be 0 to 0x7fffffffUL. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_SetRxCounterThreshold(IR_RX_Count_Low_Level, 0x100); + * } + * \endcode + */ +void IR_SetRxCounterThreshold(uint32_t IR_RxCntThrType, uint32_t IR_RxCntThr); + +/** + * \brief Send data. + * \param[in] pBuf: Data buffer to send. + * \param[in] len: Send data length. + * \param[in] IsLastPacket: Is it the last package of data. + * This parameter can be one of the following values: + * \arg ENABLE: The last data in IR packet and there is no continous data.In other words, an infrared data transmission is completed. + * \arg DISABLE: There is data to be transmitted continuously. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint32_t data_buf[80] = {0}; + * IR_SendBuf(data_buf, 68, DISABLE); + * } + * \endcode + */ +void IR_SendBuf(uint32_t *pBuf, uint32_t len, FunctionalState IsLastPacket); + +/** + * \brief Send compensation data. + * \param[in] comp_type: Compensation data type. + * This parameter can be one of the following values: + * \arg IR_COMPEN_FLAG_1_2_CARRIER: 1/2 carrier freqency. + * \arg IR_COMPEN_FLAG_1_4_CARRIER: 1/4 carrier freqency. + * \arg IR_COMPEN_FLAG_1_N_SYSTEM_CLK: MOD((0x48[27:16]+0x00[11:0]), 4095)/40MHz. + User can call function of IR_ConfigCompParam to configure 0x48[27:16]. + * \param[in] buf: Data buffer to send. + * \param[in] length: Data length. + * \param[in] IsLastPacket: Is it the last package of data. + * This parameter can be the following values: + * \arg ENABLE: The last data in IR packet and there is no continous data.In other words, an infrared data transmission is completed. + * \arg DISABLE: There is data to be transmitted continuously. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint32_t data_buf[80] = {0}; + * IR_SendCompenBuf(IR_COMPEN_FLAG_1_2_CARRIER, data_buf, 68, DISABLE); + * } + * \endcode + */ +void IR_SendCompenBuf(IR_TX_COMPEN_TYPE comp_type, uint32_t *pBuf, uint32_t len, + FunctionalState IsLastPacket); + +/** + * \brief Read data From RX FIO. + * \param[in] pBuf: Buffer address to receive data. + * \param[in] length: Read data length. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint32_t data_buf[80] = {0}; + * IR_ReceiveBuf(data_buf, 68); + * } + * \endcode + */ +void IR_ReceiveBuf(uint32_t *pBuf, uint32_t length); + +/** + * \brief Enables or disables the specified IR interrupt source. + * \param[in] IR_INT: Specifies the IR interrupt source to be enabled or disabled. + * This parameter can be oen of the following values: + * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt source. + * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt source. + * \arg IR_INT_TF_OF: TX FIFO overflow interrupt source. + * \arg IR_INT_RF_FULL: RX FIFO full interrupt source. + * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt source. + * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt source. + * \arg IR_INT_RF_OF: RX FIFO overflow interrupt source. + * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt source. + * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt source. Trigger when RX FIFO empty and read RX FIFO. + * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * \param[in] newState: New state of the specified IR interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_INTConfig(IR_INT_TF_EMPTY, ENABLE); + * } + * \endcode + */ +void IR_INTConfig(uint32_t IR_INT, FunctionalState newState); + +/** + * \brief Mask or unmask the specified IR interrupt source. + * \param[in] IR_INT: Specifies the IR interrupts sources to be mask or unmask. + * This parameter can be the following values: + * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt. + * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt. + * \arg IR_INT_TF_OF: TX FIFO overflow interrupt. + * \arg IR_INT_RF_FULL: RX FIFO full interrupt. + * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt. + * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt. + * \arg IR_INT_RF_OF: RX FIFO overflow interrupt. + * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt. + * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * \param[in] newState: New state of the specified IR interrupts. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_MaskINTConfig(IR_INT_TF_EMPTY, ENABLE); + * } + * \endcode + */ +void IR_MaskINTConfig(uint32_t IR_INT, FunctionalState newState); + +/** + * \brief Get the specified IR interrupt status. + * \param[in] IR_INT: the specified IR interrupts. + * This parameter can be one of the following values: + * \arg IR_INT_TF_EMPTY: TX FIFO empty interrupt. + * \arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt. + * \arg IR_INT_TF_OF: TX FIFO overflow interrupt. + * \arg IR_INT_RF_FULL: RX FIFO full interrupt. + * \arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt. + * \arg IR_INT_RX_CNT_OF: RX counter overflow interrupt. + * \arg IR_INT_RF_OF: RX FIFO overflow interrupt. + * \arg IR_INT_RX_CNT_THR: RX counter threshold interrupt. + * \arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * \arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * \arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * \return The new state of IR_INT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * ITStatus int_status = IR_GetINTStatus(IR_INT_TF_EMPTY); + * } + * \endcode + */ +ITStatus IR_GetINTStatus(uint32_t IR_INT); + +/** + * \brief Clear the IR interrupt pending bit. + * \param[in] IR_CLEAR_INT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * \arg IR_INT_TF_EMPTY_CLR: Clear TX FIFO empty interrupt. + * \arg IR_INT_TF_LEVEL_CLR: Clear TX FIFO threshold interrupt. + * \arg IR_INT_TF_OF_CLR: Clear TX FIFO overflow interrupt. + * \arg IR_INT_RF_FULL_CLR: Clear RX FIFO full interrupt. + * \arg IR_INT_RF_LEVEL_CLR: Clear RX FIFO threshold interrupt. + * \arg IR_INT_RX_CNT_OF_CLR: Clear RX counter overflow interrupt. + * \arg IR_INT_RF_OF_CLR: Clear RX FIFO overflow interrupt. + * \arg IR_INT_RX_CNT_THR_CLR: Clear RX counter threshold interrupt. + * \arg IR_INT_RF_ERROR_CLR: Clear RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * \arg IR_INT_RX_RISING_EDGE_CLR: Clear RX Rising edge interrupt. + * \arg IR_INT_RX_FALLING_EDGE_CLR: Clear RX Falling edge interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_ClearINTPendingBit(IR_INT_RX_CNT_OF_CLR); + * } + * \endcode + */ +void IR_ClearINTPendingBit(uint32_t IR_CLEAR_INT); + +/** + * \brief Get free size of TX FIFO. + * \param None. + * \return The free size of TX FIFO. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint16_t data_len = IR_GetTxFIFOFreeLen(); + * } + * \endcode + */ +__STATIC_INLINE uint16_t IR_GetTxFIFOFreeLen(void) +{ + return (uint16_t)(IR_TX_FIFO_SIZE - ((IR->TX_SR & (IR_TX_FIFO_OFFSET_Msk)) >> + IR_TX_FIFO_OFFSET_Pos)); +} + +/** + * \brief Get data size in RX FIFO. + * \param None. + * \return Current data size in RX FIFO. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint16_t data_len = IR_GetRxDataLen(); + * } + * \endcode + */ +__STATIC_INLINE uint16_t IR_GetRxDataLen(void) +{ + return ((uint16_t)(((IR->RX_SR) & IR_RX_FIFO_OFFSET_Msk) >> IR_RX_FIFO_OFFSET_Pos)); +} + +/** + * \brief Send one data. + * \param[in] data: Send data. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_SendData(0x80000100); + * } + * \endcode + */ +__STATIC_INLINE void IR_SendData(uint32_t data) +{ + IR->TX_FIFO = data; +} + +/** + * \brief Read one data. + * \param None. + * \return Data which read from RX FIFO. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint32_t data = IR_ReceiveData(30); + * } + * \endcode + */ +__STATIC_INLINE uint32_t IR_ReceiveData(void) +{ + return IR->RX_FIFO; +} + +/** + * \brief Set tx threshold, when TX FIFO depth <= threshold value trigger interrupt. + * \param[in] thd: Tx threshold. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_SetTxThreshold(30); + * } + * \endcode + */ +__STATIC_INLINE void IR_SetTxThreshold(uint8_t thd) +{ + IR->TX_CONFIG &= IR_TX_FIFO_THRESHOLD_CLR; + IR->TX_CONFIG |= (thd << IR_TX_FIFO_THRESHOLD_Pos); +} + +/** + * \brief Set tx threshold, when RX FIFO depth >= threshold value trigger interrupt. + * \param[in] thd: Rx threshold. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_SetRxThreshold(2); + * } + * \endcode + */ +__STATIC_INLINE void IR_SetRxThreshold(uint8_t thd) +{ + IR->RX_CONFIG &= IR_RX_FIFO_LEVEL_CLR; + IR->RX_CONFIG |= (thd << IR_RX_FIFO_LEVEL_Pos); +} + +/** + * \brief Get IR RX current count. + * \param None. + * \return Current counter. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * uint32_t count = IR_GetRxCurrentCount(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t IR_GetRxCurrentCount(void) +{ + return IR->RX_CUR_CNT ; +} + +/** + * \brief Clear IR TX FIFO. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_ClearTxFIFO(); + * } + * \endcode + */ +__STATIC_INLINE void IR_ClearTxFIFO(void) +{ + IR->TX_INT_CLR = IR_TX_FIFO_CLR_Msk; +} + +/** + * \brief Clear IR RX FIFO. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_ClearRxFIFO(); + * } + * \endcode + */ +__STATIC_INLINE void IR_ClearRxFIFO(void) +{ + IR->RX_INT_CLR = IR_RX_FIFO_CLR_Msk; +} + +/** + * \brief Check whether the specified IR flag is set. + * \param[in] IR_FLAG: Specifies the flag to check. + * This parameter can be one of the following values: + * \arg IR_FLAG_TF_EMPTY: TX FIFO empty or not. If SET, TX FIFO is empty. + * \arg IR_FLAG_TF_FULL: TX FIFO full or not. If SET, TX FIFO is full. + * \arg IR_FLAG_TX_RUN: TX run or not. If SET, TX is running. + * \arg IR_FLAG_RF_EMPTY: RX FIFO empty or not. If SET, RX FIFO is empty. + * \arg IR_FLAG_RX_RUN: RX run or not. If SET, RX is running. + * \return The new state of IR_FLAG (SET or RESET). + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * FlagStatus flag_status = IR_GetFlagStatus(IR_FLAG_TF_EMPTY); + * } + * \endcode + */ +__STATIC_INLINE FlagStatus IR_GetFlagStatus(uint32_t IR_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_IR_FLAG(IR_FLAG)); + + if (IR->TX_CONFIG & IR_MODE_SEL_Msk) + { + if (IR->RX_SR & IR_FLAG) + { + bitstatus = SET; + } + return bitstatus; + } + else + { + if (IR->TX_SR & IR_FLAG) + { + bitstatus = SET; + } + return bitstatus; + } +} + +/** + * \brief Set or reset tx data inverse. + * \param[in] NewState: This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_SetTxInverse(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void IR_SetTxInverse(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + IR->TX_CONFIG |= IR_FIFO_INVERSE_Msk; + } + else + { + IR->TX_CONFIG &= IR_FIFO_INVERSE_CLR; + } +} + +/** + * \brief Enbale TX output inverse or not. + * \param[in] NewState: This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void ir_demo(void) + * { + * IR_TxOutputInverse(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void IR_TxOutputInverse(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + IR->TX_CONFIG |= IR_OUTPUT_INVERSE_Msk; + } + else + { + IR->TX_CONFIG &= IR_OUTPUT_INVERSE_CLR; + } +} + +/** \} */ /* End of group IR_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876x_IR_H_ */ + + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_keyscan.h b/inc/peripheral/rtl876x_keyscan.h new file mode 100644 index 0000000..6acfdc5 --- /dev/null +++ b/inc/peripheral/rtl876x_keyscan.h @@ -0,0 +1,627 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_keyscan.h +* \brief The header file of the peripheral KEYSCAN driver. +* \details This file provides all KEYSCAN firmware functions. +* \author tifnan_ge +* \date 2015-04-29 +* \version v1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_KEYSCAN_H_ +#define _RTL876X_KEYSCAN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup KeyScan KeyScan + * + * \brief Manage the KeyScan peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup KeyScan_Exported_Types Init Params Struct + * + * \ingroup KeyScan + */ + +/** + * \brief KeyScan init structure definition. + * + * \ingroup KeyScan_Exported_Types + */ +typedef struct +{ + uint16_t rowSize; /*!< Specifies Keyscan Row Size. + This parameter can be a value <=8. */ + uint16_t colSize; /*!< Specifies Keyscan Column Size. + This parameter can be a value <=20. */ + uint32_t detectPeriod; /*!< Specifies detect period(ms). */ + uint16_t timeout; /*!< Specifies sw interrupt timeout(s). */ + uint16_t scanInterval; /*!< Specifies Keyscan release time. */ + uint32_t debounceEn; /*!< Enable or disable debounce. */ + uint32_t scantimerEn; /*!< Enable or disable scan timer. */ + uint32_t detecttimerEn; /*!< Enable or disable detect timer. */ + uint16_t debounceTime; /*!< Specifies debounce time,debounce time = 31.25us * debounceTime. */ + uint32_t detectMode; /*!< Specifies Key Detect mode. + This parameter can be a value of \ref Keyscan_Press_Detect_Mode */ + uint32_t fifoOvrCtrl; /*!< Specifies Keyscan fifo over flow control. + This parameter can be a value of \ref Keyscan_Fifo_Overflow_Control */ + + uint16_t maxScanData; /*!< Specifies max scan data allowable in each scan. */ + uint32_t scanmode; /*!< Specifies Keyscan mode. + This parameter can be a value of \ref Keyscan_Scan_Mode. */ + uint16_t clockdiv; /*!< Specifies Keyscan clock divider.system clock/(SCAN_DIV+1)=scan clock. */ + uint8_t delayclk; /*!< Specifies Keyscan delay clock divider.delay clock= scan clock/(DELAY_DIV+1)*/ + uint16_t fifotriggerlevel; /*!< Specifies Keyscan fifo threshold to trigger interrupt KEYSCAN_INT_THRESHOLD.*/ + uint8_t debouncecnt; /*!< Specifies Keyscan Debounce time. */ + uint8_t releasecnt; /*!< Specifies Keyscan release time. */ + uint8_t keylimit; /*!< Specifies max scan data allowable in each scan. */ + uint32_t manual_sel; /*!< Specifies trigger mode in manual mode. */ +} KEYSCAN_InitTypeDef; + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup KeyScan_Exported_Constants Marco Definations + * + * \ingroup KeyScan + */ + +#define IS_KeyScan_PERIPH(PERIPH) ((PERIPH) == KEYSCAN) + +/** + * \def Keyscan_Row_Number Keyscan Row Number + */ + +#define IS_KEYSCAN_ROW_NUM(ROW) ((ROW) <= 8) + +/** + * \def Keyscan_Column_Number Keyscan Column Number + */ + +#define IS_KEYSCAN_COL_NUM(COL) ((COL) <= 20) + +/** + * \def Keyscan_Debounce_Time Keyscan Debounce Time + */ +#define IS_KEYSCAN_MAX_SCAN_DATA(DATA_NUM) ((DATA_NUM) <= 26) //0 means no limit + +/** + * \defgroup Keyscan_Scan_Mode Keyscan scan mode + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KeyScan_Manual_Scan_Mode ((uint32_t)(0x0 << 30)) +#define KeyScan_Auto_Scan_Mode ((uint32_t)(0x1 << 30)) +/** \} */ + +#define IS_KEYSCAN_DETECT_MODE(MODE) (((MODE) == KeyScan_Detect_Mode_Edge) || ((MODE) == KeyScan_Detect_Mode_Level)) + +/** + * \defgroup Keyscan_Manual_Mode Keyscan Manual Mode + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KeyScan_Manual_Sel_Bit ((uint32_t)(0x0 << 11)) +#define KeyScan_Manual_Sel_Key ((uint32_t)(0x1 << 11)) +/** \} */ + +/** + * \defgroup Keyscan_Fifo_Overflow_Control Keyscan Fifo Overflow Control + * \{ + * \ingroup KeyScan_Exported_Constants + */ + +#define KeyScan_FIFO_OVR_CTRL_DIS_ALL ((uint32_t)(0x0 << 28)) //discard all the new scan data when FIFO is full +#define KeyScan_FIFO_OVR_CTRL_DIS_LAST ((uint32_t)(0x1 << 28)) //discard the oldest scan data when FIFO is full +/** \} */ + +#define IS_KEYSCAN_FIFO_OVR_CTRL(CTRL) (((CTRL) == KeyScan_FIFO_OVR_CTRL_DIS_ALL) || ((CTRL) == KeyScan_FIFO_OVR_CTRL_DIS_LAST)) + +/** + * \defgroup Keyscan_Debounce_Config Keyscan Debounce Config + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KeyScan_Debounce_Enable ((uint32_t)0x1 << 31) +#define KeyScan_Debounce_Disable ((uint32_t)0x0 << 31) +/** \} */ +#define IS_KEYSCAN_DEBOUNCE_EN(EN) (((EN) == KeyScan_Debounce_Enable) || ((EN) == KeyScan_Debounce_Disable)) //0 means no limit + +/** + * \defgroup Keyscan_Scan_Interval_En Keyscan Scan Interval Enable + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KeyScan_ScanInterval_Enable ((uint32_t)(0x1 << 30)) +#define KeyScan_ScanInterval_Disable ((uint32_t)(0x0 << 30)) +/** \} */ +#define IS_KEYSCAN_SCANINTERVAL_EN(EN) (((EN) == KeyScan_ScanInterval_Enable) || ((EN) == KeyScan_ScanInterval_Disable)) //0 means no limit + +/** + * \defgroup Keyscan_Release_Detect_Timer_En Keyscan Release Detect Timer Enable + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KeyScan_Release_Detect_Enable ((uint32_t)(0x1 << 29)) +#define KeyScan_Release_Detect_Disable ((uint32_t)(0x0 << 29)) +/** \} */ +#define IS_KEYSCAN_RELEASE_DETECT_EN(EN) (((EN) == KeyScan_Release_Detect_Enable) || ((EN) == KeyScan_Release_Detect_Disable)) //0 means no limit + +/** + * \defgroup Keyscan_Press_Detect_Mode Keyscan Press Detect Mode + * \{ + * \ingroup KeyScan_Exported_Constants + */ + +#define KeyScan_Detect_Mode_Edge ((uint32_t)(0x0 << 29)) +#define KeyScan_Detect_Mode_Level ((uint32_t)(0x1 << 29)) +/** \} */ + +#define IS_KEYSCAN_DETECT_MODE(MODE) (((MODE) == KeyScan_Detect_Mode_Edge) || ((MODE) == KeyScan_Detect_Mode_Level)) + +/** + * \defgroup Keyscan_Interrupt_Definition Keyscan Interrupt Definition + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KEYSCAN_INT_THRESHOLD ((uint16_t)(0x1 << 4)) +#define KEYSCAN_INT_OVER_READ ((uint16_t)(0x1 << 3)) +#define KEYSCAN_INT_SCAN_END ((uint16_t)(0x1 << 2)) +#define KEYSCAN_INT_FIFO_NOT_EMPTY ((uint16_t)(0x1 << 1)) +#define KEYSCAN_INT_ALL_RELEASE ((uint16_t)(0x1 << 0)) +/** \} */ + +#define IS_KEYSCAN_CONFIG_IT(IT) ((((IT) & (uint32_t)0xFFF8) == 0x00) && ((IT) != 0x00)) + +/** + * \defgroup Keyscan_Flag_Definition Keyscan Flag Definition + * \{ + * \ingroup KeyScan_Exported_Constants + */ +#define KEYSCAN_FLAG_FIFOLIMIT ((uint32_t)(0x1 << 20)) +#define KEYSCAN_INT_FLAG_THRESHOLD ((uint32_t)(0x1 << 19)) +#define KEYSCAN_INT_FLAG_OVER_READ ((uint32_t)(0x1 << 18)) +#define KEYSCAN_INT_FLAG_SCAN_END ((uint32_t)(0x1 << 17)) +#define KEYSCAN_INT_FLAG_FIFO_NOT_EMPTY ((uint32_t)(0x1 << 16)) +#define KEYSCAN_INT_FLAG_ALL_RELEASE ((uint32_t)(0x1 << 15)) +#define KEYSCAN_FLAG_DATAFILTER ((uint32_t)(0x1 << 3)) +#define KEYSCAN_FLAG_OVR ((uint32_t)(0x1 << 2)) +#define KEYSCAN_FLAG_FULL ((uint32_t)(0x1 << 1)) +#define KEYSCAN_FLAG_EMPTY ((uint32_t)(0x1 << 0)) +/** \} */ + +#define IS_KEYSCAN_FLAG(FLAG) ((((FLAG) & (uint32_t)0x01FF) == 0x00) && ((FLAG) != (uint32_t)0x00)) +#define IS_KEYSCAN_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0x00C0) == 0x00) && ((FLAG) != (uint32_t)0x00)) + +/** + * \def Keyscan_FIFO_AVALIABLE_MASK + */ + +#define STATUS_FIFO_DATA_NUM_MASK ((uint32_t)(0x3F << 4)) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup Keyscan_Exported_functions Peripheral APIs + * \{ + * \ingroup KeyScan + */ + +/** + * \brief Deinitializes the Keyscan peripheral registers to their default reset values(turn off keyscan clock). + * \param[in] KeyScan: selected KeyScan peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_keyscan_init(void) + * { + * KeyScan_DeInit(APBPeriph_KEYSCAN); + * } + * \endcode + */ +void KeyScan_DeInit(KEYSCAN_TypeDef *KeyScan); + +/** + * \brief Initializes the KeyScan peripheral according to the specified + * parameters in the KeyScan_InitStruct + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[in] KeyScan_InitStruct: Pointer to a KEYSCAN_InitTypeDef structure that + * contains the configuration information for the specified KeyScan peripheral + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_keyscan_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE); + + * KEYSCAN_InitTypeDef KEYSCAN_InitStruct; + * KeyScan_StructInit(&KEYSCAN_InitStruct); + + * KEYSCAN_InitStruct.rowSize = KEYBOARD_ROW_SIZE; + * KEYSCAN_InitStruct.colSize = KEYBOARD_COLUMN_SIZE; + * KEYSCAN_InitStruct.scanmode = KeyScan_Manual_Scan_Mode; + * KEYSCAN_InitStruct.debounceEn = vDebounce_En; + + * KeyScan_Init(KEYSCAN, &KEYSCAN_InitStruct); + + * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE); + * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END); + * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); // Unmask keyscan interrupt + * KeyScan_Cmd(KEYSCAN, ENABLE); + * } + * \endcode + */ +void KeyScan_Init(KEYSCAN_TypeDef *KeyScan, KEYSCAN_InitTypeDef *KeyScan_InitStruct); + +/** + * \brief Fills each Keyscan_InitStruct member with its default value. + * \param[in] KeyScan_InitStruct: Pointer to an KEYSCAN_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_keyscan_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, ENABLE); + + * KEYSCAN_InitTypeDef KEYSCAN_InitStruct; + * KeyScan_StructInit(&KEYSCAN_InitStruct); + + * KEYSCAN_InitStruct.rowSize = KEYBOARD_ROW_SIZE; + * KEYSCAN_InitStruct.colSize = KEYBOARD_COLUMN_SIZE; + * KEYSCAN_InitStruct.scanmode = KeyScan_Manual_Scan_Mode; + * KEYSCAN_InitStruct.debounceEn = vDebounce_En; + + * KeyScan_Init(KEYSCAN, &KEYSCAN_InitStruct); + + * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_SCAN_END, ENABLE); + * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_SCAN_END); + * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_SCAN_END, DISABLE); // Unmask keyscan interrupt + * KeyScan_Cmd(KEYSCAN, ENABLE); + * } + * \endcode + */ +void KeyScan_StructInit(KEYSCAN_InitTypeDef *KeyScan_InitStruct); + +/** + * \brief Enables or disables the specified KeyScan interrupt. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[in] KeyScan_IT: Specifies the KeyScan interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt. + * \arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt. + * \arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt. + * \param[in] newState: New state of the specified KeyScan interrupts. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE); + * KeyScan_INTConfig(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE); + * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, DISABLE); + * } + * \endcode + */ +void KeyScan_INTConfig(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, + FunctionalState newState); + +/** + * \brief Mask the specified KeyScan interrupt . + * \param[in] KeyScan: selected KeyScan peripheral. + * \param[in] KeyScan_IT: Specifies the KeyScan interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask. + * \arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt mask. + * \arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt mask. + * \param[in] newState: New state of the specified KeyScan interrupts mask. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_INTMask(KEYSCAN, KEYSCAN_INT_TIMEOUT, ENABLE); + * } + * \endcode + */ +void KeyScan_INTMask(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, + FunctionalState newState); + +/** + * \brief Read data from keyscan FIFO. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[out] outBuf: Buffer to save data read from KeyScan FIFO. + * \param[in] count: Data length to be read. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * uint16_t data[3] = {0}; + * KeyScan_Read(KEYSCAN, data, 3); + * } + * \endcode + */ +void KeyScan_Read(KEYSCAN_TypeDef *KeyScan, uint16_t *outBuf, uint16_t count); + +/** + * \brief Enable or disable the KeyScan peripheral. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[in] NewState: New state of the KeyScan peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_Cmd(KEYSCAN, ENABLE); + * } + * \endcode + */ +void KeyScan_Cmd(KEYSCAN_TypeDef *KeyScan, FunctionalState NewState); + +/** + * \brief Set filter data. + * \param[in] KeyScan: selected KeyScan peripheral. + * \param[in] data: Config the data to be filtered. + * This parameter should not be more than 9 bits. + * \param[in] NewState: New state of the KeyScan peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_FilterDataConfig(KEYSCAN, 0x01, ENABLE); + * + * } + * \endcode + */ +void KeyScan_FilterDataConfig(KEYSCAN_TypeDef *KeyScan, uint16_t data, + FunctionalState NewState); + +/** + * \brief KeyScan debounce time config. + * \param[in] KeyScan: selected KeyScan peripheral. + * \param[in] time: Keyscan hardware debounce time. + * \param[in] NewState: New state of the KeyScan debounce function. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_debounceConfig(KEYSCAN, 10, ENABLE); + * + * } + * \endcode + */ +__STATIC_INLINE void KeyScan_debounceConfig(KEYSCAN_TypeDef *KeyScan, uint8_t time, + FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + KeyScan->TIMERCR &= ~((0xff << 16) | BIT31); + KeyScan->TIMERCR |= ((NewState << 31) | time << 16); + +} + +/** + * \brief Get KeyScan FIFO data num. + * \param[in] KeyScan: selected KeyScan peripheral. + * \return Data length in FIFO. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * uint16_t data_len = KeyScan_GetFifoDataNum(KEYSCAN); + * } + * \endcode + */ +__STATIC_INLINE uint16_t KeyScan_GetFifoDataNum(KEYSCAN_TypeDef *KeyScan) +{ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + + return (uint16_t)((KeyScan->STATUS & STATUS_FIFO_DATA_NUM_MASK) >> 4); +} + +/** + * \brief Clear the KeyScan interrupt pending bit. + * \param[in] KeyScan: selected KeyScan peripheral. + * \param[in] KeyScan_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * \arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask + * \arg KEYSCAN_INT_THRESHOLD + * \arg KEYSCAN_INT_OVER_READ + * \arg KEYSCAN_INT_SCAN_END + * \arg KEYSCAN_INT_FIFO_NOT_EMPTY + * \arg KEYSCAN_INT_ALL_RELEASE + * \return None. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_ClearINTPendingBit(KEYSCAN, KEYSCAN_INT_TIMEOUT); + * } + * \endcode + */ +__STATIC_INLINE void KeyScan_ClearINTPendingBit(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_KEYSCAN_CONFIG_IT(KeyScan_IT)); + + KeyScan->INTCLR |= KeyScan_IT; + + return; +} + +/** + * \brief Clear the specified KeyScan flag. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[in] KeyScan_FLAG: Specifies the flag to clear. + * This parameter can be one of the following values: + * \arg KEYSCAN_FLAG_FIFOLIMIT + * \arg KEYSCAN_FLAG_DATAFILTER + * \arg KEYSCAN_FLAG_OVR + * \return None. + * \note KEYSCAN_FLAG_FULL and KEYSCAN_FLAG_EMPTY can't be cleared manually. + * They are cleared by hardware automatically. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * KeyScan_ClearFlags(KEYSCAN, KEYSCAN_FLAG_FIFOLIMIT); + * } + * \endcode + */ +__STATIC_INLINE void KeyScan_ClearFlags(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_FLAG) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_KEYSCAN_CLEAR_FLAG(KeyScan_FLAG)); + + if (KeyScan_FLAG & KEYSCAN_FLAG_FIFOLIMIT) + { + KeyScan->INTCLR |= BIT8; + } + if (KeyScan_FLAG & KEYSCAN_FLAG_DATAFILTER) + { + KeyScan->INTCLR |= BIT7; + } + if (KeyScan_FLAG & KEYSCAN_FLAG_OVR) + { + KeyScan->INTCLR |= BIT5; + } + + return; +} + +/** + * \brief Check whether the specified KeyScan flag is set. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \param[in] KeyScan_FLAG: Specifies the flag to check. + * This parameter can be one of the following values: + * \arg KEYSCAN_FLAG_FIFOLIMIT: + * \arg KEYSCAN_FLAG_THRESHOLD: + * \arg KEYSCAN_FLAG_OVER_READ: + * \arg KEYSCAN_FLAG_SCAN_END: + * \arg KEYSCAN_FLAG_FIFO_NOT_EMPTY: + * \arg KEYSCAN_FLAG_ALL_RELEASE: + * \arg KEYSCAN_FLAG_DATAFILTER: + * \arg KEYSCAN_FLAG_OVR: + * \arg KEYSCAN_FLAG_FULL: + * \arg KEYSCAN_FLAG_EMPTY: + * \return The new state of KeyScan_FLAG (SET or RESET). + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * FlagStatus flag_status = KeyScan_GetFlagState(KEYSCAN, KEYSCAN_FLAG_OVR); + * + * } + * \endcode + */ +__STATIC_INLINE FlagStatus KeyScan_GetFlagState(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_KEYSCAN_FLAG(KeyScan_FLAG)); + + if ((KeyScan->STATUS & KeyScan_FLAG) != 0) + { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * \brief Read FIFO data. + * \param[in] KeyScan: Selected KeyScan peripheral. + * \return Keyscan FIFO data. + * + * Example usage + * \code{.c} + * + * void keyscan_demo(void) + * { + * uint16_t data = KeyScan_ReadFifoData(KEYSCAN); + * } + * \endcode + */ +__STATIC_INLINE uint16_t KeyScan_ReadFifoData(KEYSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + + return (uint16_t)(KeyScan->FIFODATA); +} + +/** \} */ /* End of group KeyScan_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_KEYSCAN_H_ */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/ diff --git a/inc/peripheral/rtl876x_lpc.h b/inc/peripheral/rtl876x_lpc.h new file mode 100644 index 0000000..64ce335 --- /dev/null +++ b/inc/peripheral/rtl876x_lpc.h @@ -0,0 +1,749 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_lpc.h +* \brief The header file of the peripheral LPC driver. +* \details This file provides all LPC firmware functions. +* \author yuan +* \date 2020-11-16 +* \version v2.1.1 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_LPC_H_ +#define _RTL876X_LPC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup LPC LPC + * + * \brief Manage the LPC peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup LPC_Exported_Types Init Params Struct + * + * \ingroup LPC + */ + +/** + * \brief LPC init structure definition + * + * \ingroup LPC_Exported_Types + */ +typedef struct +{ + uint16_t LPC_Channel; /*!< Specifies the input pin. + This parameter can be a value of ADC_0 to ADC_7. */ + uint32_t LPC_Edge; /*!< Specifies the comparator output edge. */ + uint32_t LPC_Threshold; /*!< Specifies the threshold value of comparator voltage. */ + +} LPC_InitTypeDef; + + +/*============================================================================* + * Register Defines + *============================================================================*/ + +/* Peripheral: LPC */ +/* Description: Low Power Comparator register defines */ + +/* Register: LPC_AON_52 */ +/* Description: LPC AON Register for threshold voltage configuration */ + +/* LPC_AON_52[5:0] :LPC_Threshold. Specified the threshold value of comparator voltage */ +#define LPC_AON_52_THRESHOLD_Pos (0UL) +#define LPC_AON_52_THRESHOLD_Msk (0x3FUL << LPC_AON_52_THRESHOLD_Pos) +#define LPC_AON_52_THRESHOLD_Clr (~LPC_AON_52_THRESHOLD_Msk) + +/* Register: LPC_AON_114 */ +/* Description: LPC AON Register for parameters configuration */ + +/* LPC_AON_114[5] :LPC_Edge. Specified the cmp output edge */ +#define LPC_AON_114_POSEDGE_Pos (5UL) +#define LPC_AON_114_POSEDGE_Msk (0x1UL << LPC_AON_114_POSEDGE_Pos) +/* LPC_AON_114[4:1] :LPC_Channel. Specified the input pin */ +#define LPC_AON_114_CH_NUM_Pos (1UL) +#define LPC_AON_114_CH_NUM_Msk (0xFUL << LPC_AON_114_CH_NUM_Pos) +/* LPC_AON_114[0] : LPC_POWER. 1: Enable power of low power cmp */ +#define LPC_AON_114_POWER_EN_Pos (0UL) +#define LPC_AON_114_POWER_EN_Msk (0x1UL << LPC_AON_114_POWER_EN_Pos) +#define LPC_AON_114_POWER_EN_CLR (~LPC_AON_114_POWER_EN_Msk) + +#define LPC_AON_114_DEFAULT_Msk (0x3F) +#define LPC_AON_114_DEFAULT_Clr (~LPC_AON_114_DEFAULT_Msk) + +/* Register: LPC_CR0 */ +/* Description: Control Register 0 */ +/* LPC_CR0[20] :LPC_LPCOMP_OUTPUT_EN. 1: Enable lpcomp out to NVIC and power sequence. */ +#define LPC_LPCOMP_OUTPUT_EN_Pos (20UL) +#define LPC_LPCOMP_OUTPUT_EN_Msk (0x1UL << LPC_LPCOMP_OUTPUT_EN_Pos) +#define LPC_LPCOMP_OUTPUT_EN_CLR (~(LPC_LPCOMP_OUTPUT_EN_Msk)) + +/* LPC_CR0[19] :LPC_SRC_INT_EN. 1: Enable lpcomp out sync signal to AON interrupt */ +#define LPC_INT_LPCOMP_AON_EN_Pos (19UL) +#define LPC_INT_LPCOMP_AON_EN_Msk (0x1UL << LPC_INT_LPCOMP_AON_EN_Pos) +#define LPC_INT_LPCOMP_AON_EN_CLR (~(LPC_INT_LPCOMP_AON_EN_Msk)) + +/* LPC_CR0[9] :LPC_NV_EN. 1: Enable lpcomp out sync signal to CPU interrupt */ +#define LPC_INT_LPCOMP_NV_EN_Pos (9UL) +#define LPC_INT_LPCOMP_NV_EN_Msk (0x1UL << LPC_INT_LPCOMP_NV_EN_Pos) +#define LPC_INT_LPCOMP_NV_EN_CLR (~(LPC_INT_LPCOMP_NV_EN_Msk)) + +/* LPC_CR0[8] :LPC_EVENT_EN. 1: Enable or disable LPCOMP event */ +#define LPC_INT_LPCOMP_CNT_EN_Pos (8UL) +#define LPC_INT_LPCOMP_CNT_EN_Msk (0x1UL << LPC_INT_LPCOMP_CNT_EN_Pos) +#define LPC_INT_LPCOMP_CNT_EN_CLR (~(LPC_INT_LPCOMP_CNT_EN_Msk)) + +/* LPC_CR0[2] :LPC_FLAG_CLEAR. 1: Clear Event Status of LPCOMP */ +#define LPC_LPCOMP_CNT_CLEAR_Pos (2UL) +#define LPC_LPCOMP_CNT_CLEAR_Msk (0x1UL << LPC_LPCOMP_CNT_CLEAR_Pos) +#define LPC_LPCOMP_CNT_CLEAR_CLR (~(LPC_LPCOMP_CNT_CLEAR_Msk)) + +/* LPC_CR0[1] :LPC_COUNTER_START. 1: Start LPCOMP counter. */ +#define LPC_COUNTER_START_Pos (1UL) +#define LPC_COUNTER_START_Msk (0x1UL << LPC_COUNTER_START_Pos) +#define LPC_COUNTER_START_CLR (~(LPC_COUNTER_START_Msk)) + +/* LPC_CR0[0] :LPC_COUNTER_RESET. 1: Reset LPCOMP Counter */ +#define LPC_COUNTER_RESET_Pos (0UL) +#define LPC_COUNTER_RESET_Msk (0x1UL << LPC_COUNTER_RESET_Pos) +#define LPC_COUNTER_RESET_CLR (~(LPC_COUNTER_RESET_Msk)) + +/* Register: LPC_SR */ +/* Description: Status Register */ + +/* LPC_SR[1] :LPC_COMP_OUTPUT. Event Status of LPCOMP output signal */ +#define LPC_LPCOMP_OUTPUT_AON_Pos (1UL) /*!< Position of */ +#define LPC_LPCOMP_OUTPUT_AON_Msk (0x1UL << LPC_LPCOMP_OUTPUT_AON_Pos) + +/* LPC_SR[0] :LPC_COMP. Event Status of LPCOMP */ +#define LPC_LPCOMP_CNT_Pos (0UL) /*!< Position of */ +#define LPC_LPCOMP_CNT_Msk (0x1UL << LPC_LPCOMP_CNT_Pos) + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup LPC_Exported_constants Marco Definitions + * + * \ingroup LPC + */ + +/** + * \defgroup LPC_Channel LPC Channel + * \{ + * \ingroup LPC_Exported_constants + */ +#define LPC_CHANNEL_P2_2 ((uint32_t)0) +#define LPC_CHANNEL_P2_3 ((uint32_t)1) +#define LPC_CHANNEL_P2_6 ((uint32_t)2) +#define LPC_CHANNEL_VBAT ((uint32_t)3) +/** \} */ + +#define IS_LPC_CHANNEL(CHANNEL) (((CHANNEL) == LPC_CHANNEL_P2_2) || \ + ((CHANNEL) == LPC_CHANNEL_P2_3) || \ + ((CHANNEL) == LPC_CHANNEL_P2_6) || \ + ((CHANNEL) == LPC_CHANNEL_P2_7) || \ + ((CHANNEL) == LPC_CHANNEL_VBAT)) + +/** \defgroup LPC_Edge LPC Edge + * \{ + * \ingroup LPC_Exported_constants + */ +#define LPC_Vin_Below_Vth ((uint32_t)0) +#define LPC_Vin_Over_Vth ((uint32_t)(0x0001UL << LPC_AON_114_POSEDGE_Pos)) +/** \} */ + +#define IS_LPC_EDGE(EDGE) (((EDGE) == LPC_Vin_Below_Vth) || \ + ((EDGE) == LPC_Vin_Over_Vth)) + +/** \defgroup LPC_Threshold LPC Threshold + * \{ + * \ingroup LPC_Exported_constants + */ +#define LPC_80_mV ((uint32_t)(0x0000 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_160_mV ((uint32_t)(0x0001 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_240_mV ((uint32_t)(0x0002 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_320_mV ((uint32_t)(0x0003 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_400_mV ((uint32_t)(0x0004 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_480_mV ((uint32_t)(0x0005 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_560_mV ((uint32_t)(0x0006 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_640_mV ((uint32_t)(0x0007 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_680_mV ((uint32_t)(0x0008 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_720_mV ((uint32_t)(0x0009 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_760_mV ((uint32_t)(0x000a << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_800_mV ((uint32_t)(0x000b << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_840_mV ((uint32_t)(0x000c << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_880_mV ((uint32_t)(0x000d << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_920_mV ((uint32_t)(0x000e << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_960_mV ((uint32_t)(0x000f << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1000_mV ((uint32_t)(0x0010 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1040_mV ((uint32_t)(0x0011 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1080_mV ((uint32_t)(0x0012 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1120_mV ((uint32_t)(0x0013 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1160_mV ((uint32_t)(0x0014 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1200_mV ((uint32_t)(0x0015 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1240_mV ((uint32_t)(0x0016 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1280_mV ((uint32_t)(0x0017 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1320_mV ((uint32_t)(0x0018 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1360_mV ((uint32_t)(0x0019 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1400_mV ((uint32_t)(0x001a << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1440_mV ((uint32_t)(0x001b << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1480_mV ((uint32_t)(0x001c << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1520_mV ((uint32_t)(0x001d << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1560_mV ((uint32_t)(0x001e << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1600_mV ((uint32_t)(0x001f << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1640_mV ((uint32_t)(0x0020 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1680_mV ((uint32_t)(0x0021 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1720_mV ((uint32_t)(0x0022 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1760_mV ((uint32_t)(0x0023 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1800_mV ((uint32_t)(0x0024 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1840_mV ((uint32_t)(0x0025 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1880_mV ((uint32_t)(0x0026 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1920_mV ((uint32_t)(0x0027 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_1960_mV ((uint32_t)(0x0028 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2000_mV ((uint32_t)(0x0029 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2040_mV ((uint32_t)(0x002a << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2080_mV ((uint32_t)(0x002b << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2120_mV ((uint32_t)(0x002c << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2160_mV ((uint32_t)(0x002d << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2200_mV ((uint32_t)(0x002e << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2240_mV ((uint32_t)(0x002f << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2280_mV ((uint32_t)(0x0030 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2320_mV ((uint32_t)(0x0031 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2360_mV ((uint32_t)(0x0032 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2400_mV ((uint32_t)(0x0033 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2440_mV ((uint32_t)(0x0034 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2480_mV ((uint32_t)(0x0035 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2520_mV ((uint32_t)(0x0036 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2560_mV ((uint32_t)(0x0037 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2640_mV ((uint32_t)(0x0038 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2720_mV ((uint32_t)(0x0039 << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2800_mV ((uint32_t)(0x003a << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2880_mV ((uint32_t)(0x003b << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_2960_mV ((uint32_t)(0x003c << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_3040_mV ((uint32_t)(0x003d << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_3120_mV ((uint32_t)(0x003e << LPC_AON_52_THRESHOLD_Pos)) +#define LPC_3200_mV ((uint32_t)(0x003f << LPC_AON_52_THRESHOLD_Pos)) +/** \} */ + +#define IS_LPC_THRESHOLD(THRESHOLD) (((THRESHOLD) == LPC_80_mV) || ((THRESHOLD) == LPC_160_mV) || ((THRESHOLD) == LPC_240_mV) || \ + ((THRESHOLD) == LPC_320_mV) || ((THRESHOLD) == LPC_400_mV) || ((THRESHOLD) == LPC_480_mV) || \ + ((THRESHOLD) == LPC_560_mV) || ((THRESHOLD) == LPC_640_mV) || ((THRESHOLD) == LPC_680_mV) || \ + ((THRESHOLD) == LPC_720_mV) || ((THRESHOLD) == LPC_760_mV) || ((THRESHOLD) == LPC_800_mV) || \ + ((THRESHOLD) == LPC_840_mV) || ((THRESHOLD) == LPC_880_mV) || ((THRESHOLD) == LPC_920_mV) || \ + ((THRESHOLD) == LPC_960_mV) || ((THRESHOLD) == LPC_1000_mV) || ((THRESHOLD) == LPC_1040_mV) || \ + ((THRESHOLD) == LPC_1080_mV) || ((THRESHOLD) == LPC_1120_mV) || ((THRESHOLD) == LPC_1160_mV) || \ + ((THRESHOLD) == LPC_1200_mV) || ((THRESHOLD) == LPC_1240_mV) || ((THRESHOLD) == LPC_1280_mV) || \ + ((THRESHOLD) == LPC_1320_mV) || ((THRESHOLD) == LPC_1360_mV) || ((THRESHOLD) == LPC_1400_mV) || \ + ((THRESHOLD) == LPC_1440_mV) || ((THRESHOLD) == LPC_1480_mV) || ((THRESHOLD) == LPC_1520_mV) || \ + ((THRESHOLD) == LPC_1560_mV) || ((THRESHOLD) == LPC_1600_mV) || ((THRESHOLD) == LPC_1640_mV) || \ + ((THRESHOLD) == LPC_1680_mV) || ((THRESHOLD) == LPC_1720_mV) || ((THRESHOLD) == LPC_1760_mV) || \ + ((THRESHOLD) == LPC_1800_mV) || ((THRESHOLD) == LPC_1840_mV) || ((THRESHOLD) == LPC_1880_mV) || \ + ((THRESHOLD) == LPC_1920_mV) || ((THRESHOLD) == LPC_1960_mV) || ((THRESHOLD) == LPC_2000_mV) || \ + ((THRESHOLD) == LPC_2040_mV) || ((THRESHOLD) == LPC_2080_mV) || ((THRESHOLD) == LPC_2120_mV) || \ + ((THRESHOLD) == LPC_2160_mV) || ((THRESHOLD) == LPC_2200_mV) || ((THRESHOLD) == LPC_2240_mV) || \ + ((THRESHOLD) == LPC_2280_mV) || ((THRESHOLD) == LPC_2320_mV) || ((THRESHOLD) == LPC_2360_mV) || \ + ((THRESHOLD) == LPC_2400_mV) || ((THRESHOLD) == LPC_2440_mV) || ((THRESHOLD) == LPC_2480_mV) || \ + ((THRESHOLD) == LPC_2520_mV) || ((THRESHOLD) == LPC_2560_mV) || ((THRESHOLD) == LPC_2640_mV) || \ + ((THRESHOLD) == LPC_2720_mV) || ((THRESHOLD) == LPC_2800_mV) || ((THRESHOLD) == LPC_2880_mV) || \ + ((THRESHOLD) == LPC_2960_mV) || ((THRESHOLD) == LPC_3040_mV) || ((THRESHOLD) == LPC_3120_mV) || \ + ((THRESHOLD) == LPC_3200_mV)) + +/** \defgroup LPC_Interrupts_Definition LPC Interrupts Definition + * \{ + * \ingroup LPC_Exported_constants + */ +#define LPC_INT_LPCOMP_VOL (LPC_LPCOMP_OUTPUT_EN_Msk) +#define LPC_INT_LPCOMP_CNT (LPC_INT_LPCOMP_CNT_EN_Msk) +/** \} */ + +#define IS_LPC_CONFIG_INT(INT) (((INT) == LPC_INT_LPCOMP_VOL) || \ + ((INT) == LPC_INT_LPCOMP_CNT)) +#define IS_LPC_STATUS_INT(INT) ((INT) == LPC_INT_LPCOMP_CNT) +#define IS_LPC_CLEAR_INT(INT) ((INT) == LPC_INT_LPCOMP_CNT) + +/** \defgroup LPC_Flags_Definition LPC Flags Definition + * \{ + * \ingroup LPC_Exported_constants + */ +#define LPC_FLAG_LPCOMP_AON (LPC_INT_LPCOMP_AON_EN_Msk) +#define LPC_FLAG_LPCOMP_CNT (LPC_INT_LPCOMP_CNT_EN_Msk) +/** \} */ + +#define IS_LPC_FLAG(FLAG) (((FLAG) == LPC_FLAG_LPCOMP_AON) || \ + ((FLAG) == LPC_FLAG_LPCOMP_CNT)) +#define IS_LPC_CLEAR_FLAG(FLAG) ((FLAG) == LPC_FLAG_LPCOMP_CNT) + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup LPC_Exported_Functions Peripheral APIs + * \{ + * \ingroup LPC + */ + +/** + * @brief Reset LPC. + * @param None + * @return None + */ +void LPC_DeInit(void); + +/** + * \brief Initializes LPC peripheral according to + * the specified parameters in LPC_InitStruct. + * \param[in] LPC_InitStruct: Pointer to a LPC_InitTypeDef structure that contains + * the configuration information for the specified LPC peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 2; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * LPC_NvCmd(ENABLE); + * } + * \endcode + */ +void LPC_Init(LPC_InitTypeDef *LPC_InitStruct); + +/** + * \brief Fills each LPC_InitStruct member with its default value. + * \param[in] LPC_InitStruct : Pointer to a LPC_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * } + * \endcode + */ +void LPC_StructInit(LPC_InitTypeDef *LPC_InitStruct); + +/** + * \brief Enables or disables LPC peripheral. + * \param[in] NewState: New state of LPC peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * } + * \endcode + */ +void LPC_Cmd(FunctionalState NewState); + +/** + * \brief Start or stop the LPC counter. + * \param[in] NewState: New state of the LPC counter. + * This parameter can be one of the following values: + * \arg ENABLE: Start LPCOMP counter. + * \arg DISABLE: Stop LPCOMP counter. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * } + * \endcode + */ +void LPC_CounterCmd(FunctionalState NewState); + +/** + * \brief Enables or disables the specified LPC interrupts. + * \param[in] LPC_INT: Specifies the LPC interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * \arg LPC_INT_VOLTAGE_COMP: Voltage detection interrupt source.If VinExample usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 2; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * LPC_NvCmd(ENABLE); + * } + * \endcode + */ +void LPC_INTConfig(uint32_t LPC_INT, FunctionalState NewState); + +/** + * \brief Enable LPC interrupt signal to CPU NVIC. + * \param[in] NewState: Enable or disable RTC interrupt signal to CCU. + * This parameter can be: ENABLE or DISABLE.. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + * LPC_CompOutputConfig(ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 2; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + * } + * \endcode + */ +void LPC_INTCmd(FunctionalState NewState); + + +/** + * \brief Enable wakeup signal to power sequence. + * \param[in] NewState: Enable or disable LPC wakeup signal to power sequence. + * This parameter can be: ENABLE or DISABLE.. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + * LPC_INTCmd(ENABLE); + * LPC_WKCmd(ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 2; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + * } + * \endcode + */ +void LPC_WKCmd(FunctionalState NewState); + +/** + * \brief Configure LPCOMP counter's comparator value. + * \param[in] value: LPCOMP counter's comparator value which can be 0 to 0xfff. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * } + * \endcode + */ +void LPC_SetCompValue(uint32_t value); + +/** + * \brief Reset the LPC counter. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * } + * \endcode + */ +void LPC_ResetCounter(void); + +/** + * @brief Checks whether the specified LPC interrupt is set or not. + * @param LPC_FLAG: specifies the LPC interrupt to check. + * This parameter can be one of the following values: + * @arg LPC_FLAG_LPCOMP_AON: couter comparator AON flag. + * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag. + * @retval The new state of SPI_IT (SET or RESET). + */ +FlagStatus LPC_GetFlagStatus(uint32_t LPC_FLAG); + +/** + * @brief Clear the specified LPC flag. + * @param LPC_FLAG: specifies the LPC flag to clear. + * This parameter can be one of the following values: + * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag. + * @retval None + */ +void LPC_ClearFlag(uint32_t LPC_FLAG); + +/** + * \brief Checks whether the specified LPC interrupt is set or not. + * \param[in] LPC_INT: specifies the LPC interrupt to check. + * This parameter can be one of the following values: + * \arg LPC_INT_COUNT_COMP: couter comparator interrupt. + * \return The new state of SPI_IT (SET or RESET). + * + * Example usage + * \code{.c} + * + * #define LPC_CAPTURE_PIN P2_3 + * #define LPC_CAPTURE_CHANNEL LPC_CAPTURE_PIN - P2_0 + + * #define LPC_VOLTAGE_DETECT_EDGE LPC_Vin_Over_Vth; + * #define LPC_VOLTAGE_DETECT_THRESHOLD LPC_2400_mV; + * #define LPC_COMP_VALUE 0x0A//A LPC comparator interrupt occurs every ten times + * + * void board_lpc_init(void) + * { + * Pad_Config(LPC_CAPTURE_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, + * PAD_OUT_HIGH); + * Pinmux_Config(LPC_CAPTURE_PIN, IDLE_MODE); + * } + * + * void driver_lpc_init(void) + * { + * LPC_InitTypeDef LPC_InitStruct; + * + * LPC_StructInit(&LPC_InitStruct); + * LPC_InitStruct.LPC_Channel = LPC_CAPTURE_CHANNEL; + * LPC_InitStruct.LPC_Edge = LPC_VOLTAGE_DETECT_EDGE; + * LPC_InitStruct.LPC_Threshold = LPC_VOLTAGE_DETECT_THRESHOLD; + * LPC_Init(&LPC_InitStruct); + * LPC_Cmd(ENABLE); + * + * LPC_ResetCounter(); + * LPC_SetCompValue(LPC_COMP_VALUE); + * LPC_CounterCmd(ENABLE); + * LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 2; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + + * LPC_NvCmd(ENABLE); + * } + * + * void lpc_demo(void) + * { + * board_lpc_init(); + * driver_lpc_init(); + * } + * + * void LPCOMP_Handler(void) + * { + * if (LPC_GetINTStatus(LPC_INT_LPCOMP_CNT) == SET) + * { + * LPC_SetCompValue(LPC_GetCounter() + LPC_COMP_VALUE); + * LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT); + * } + * } + * \endcode + */ +ITStatus LPC_GetINTStatus(uint32_t LPC_INT); + +/** + * \brief Clear the specified LPC interrupt pending bit. + * \param[in] LPC_INT: specifies the LPC interrupt to clear. + * This parameter can be one of the following values: + * \arg LPC_INT_COUNT_COMP: Couter comparator interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void lpc_demo(void) + * { + * LPC_ClearINTPendingBit(LPC_INT_COUNT_COMP); + * } + * \endcode + */ +void LPC_ClearINTPendingBit(uint32_t LPC_INT); + +/** + * \brief Read LPCOMP comparator value. + * \param None. + * \return LPCOMP comparator value. + * + * Example usage + * \code{.c} + * + * void lpc_demo(void) + * { + * uint16_t value = LPC_GetCompValue(); + * } + * \endcode + */ +__STATIC_INLINE uint16_t LPC_GetCompValue(void) +{ + return ((LPC->LPC_CMP) & 0xFFF); +} + +/** + * \brief Read LPC counter value. + * \return LPCOMP counter value. + * + * Example usage + * \code{.c} + * + * void lpc_demo(void) + * { + * uint16_t counter = LPC_GetCounter(); + * } + * \endcode + */ +__STATIC_INLINE uint16_t LPC_GetCounter(void) +{ + return ((LPC->LPC_CNT) & 0xFFF); +} + +/** \} */ /* End of group LPC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_LPC_H_ */ + + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_nvic.h b/inc/peripheral/rtl876x_nvic.h new file mode 100644 index 0000000..6e347a2 --- /dev/null +++ b/inc/peripheral/rtl876x_nvic.h @@ -0,0 +1,98 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_nvic.h +* \brief The header file of NVIC driver. +* \details This file provides all NVIC firmware functions. +* \author elliot chen +* \date 2015-05-19 +* \version v1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_NVIC_H_ +#define _RTL876X_NVIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup NVIC NVIC + * \brief Manage the NVIC peripheral functions. + * \ingroup IO + */ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup NVIC_Exported_Types Init Params Struct + * \ingroup NVIC + */ + +/** + * \brief NVIC init structure definition + * \ingroup NVIC_Exported_Types + */ + +typedef struct +{ + IRQn_Type NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. + This parameter can be a value of \ref IRQn_Type in rtl876x.h. */ + uint32_t NVIC_IRQChannelPriority; /*!< Specifies the priority for the IRQ channel. + This parameter can be a value between 0 and x as described in the table.*/ + FunctionalState + NVIC_IRQChannelCmd; /*!< Enabled or disabled the IRQ channel defined in NVIC_IRQChannel.*/ +} NVIC_InitTypeDef; + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup NVIC_Exported_Functions Peripheral APIs + * \ingroup NVIC + * \{ + */ + +/** + * \brief Initializes the NVIC peripheral according to the specified + * parameters in NVIC_InitStruct. + * \param[in] NVIC_InitStruct: Pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void nvic_config(void) + * { + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = RTC_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + * NVIC_Init(&NVIC_InitStruct); + * } + * \endcode + */ +void NVIC_Init(NVIC_InitTypeDef *NVIC_InitStruct); + +/** \} */ /* End of group NVIC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_NVIC_H_ */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_pinmux.h b/inc/peripheral/rtl876x_pinmux.h new file mode 100644 index 0000000..4c225fb --- /dev/null +++ b/inc/peripheral/rtl876x_pinmux.h @@ -0,0 +1,952 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_pinmux.h +* \brief The header file of PAD and PINMUX driver. +* \details This file provides all PAD and PINMUX firmware functions. +* \author Yuan +* \date 2020-11-09 +* \version v1.0.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_PINMUX_H_ +#define _RTL876X_PINMUX_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup PINMUX PINMUX + * + * \brief Manage the PINMUX peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup PINMUX_Exported_Constants PINMUX Exported Constants + * \{ + * \ingroup PINMUX + */ + +/** + * \cond + * \brief Internal Macros + * \{ + */ +/* Pad Functions */ +#define Output_Val (BIT0) +#define Output_En (BIT1) +#define Pull_En (BIT2) +#define Pull_Direction (BIT3) +#define Pull_Resistance (BIT4) +#define WakeUp_En (BIT5) +#define WKPOL (BIT6) +#define SHDN (BIT8) +#define Pin_Mode (BIT9) +#define Pin_Debounce (BIT10) + +/** + * \} + * \endcond + */ + +#define MAX_PIN_NUM 39 + +/** + * \defgroup Pin_Function_Number Pin Function Number + * \ingroup PINMUX_Exported_Constants + * \{ + */ +#if (IC_TYPE == IC_TYPE_BEE3) + +#define TOTAL_PIN_NUM 33 + +#define IDLE_MODE 0 +#define I2C0_CLK 5 +#define I2C0_DAT 6 +#define I2C1_CLK 7 +#define I2C1_DAT 8 +#define PWM2_P 9 +#define PWM2_N 10 +#define ENPWM0_P 11 +#define ENPWM0_N 12 +#define TIM_PWM0 13 +#define TIM_PWM1 14 +#define TIM_PWM2 15 +#define TIM_PWM3 16 +#define TIM_PWM4 17 +#define TIM_PWM5 18 +#define ENPWM0 19 +#define ENPWM1 20 +#define qdec_phase_a_x 21 +#define qdec_phase_b_x 22 +#define qdec_phase_a_y 23 +#define qdec_phase_b_y 24 +#define qdec_phase_a_z 25 +#define qdec_phase_b_z 26 +#define UART1_TX 29 +#define UART1_RX 30 +#define UART1_CTS 31 +#define UART1_RTS 32 +#define IRDA_TX 33 +#define IRDA_RX 34 +#define UART0_TX 35 +#define UART0_RX 36 +#define UART0_CTS 37 +#define UART0_RTS 38 +#define SPI1_SS_N_0_MASTER 39 +#define SPI1_SS_N_1_MASTER 40 +#define SPI1_SS_N_2_MASTER 41 +#define SPI1_CLK_MASTER 42 +#define SPI1_MO_MASTER 43 +#define SPI1_MI_MASTER 44 +#define SPI0_SS_N_0_SLAVE 45 +#define SPI0_CLK_SLAVE 46 +#define SPI0_SO_SLAVE 47 +#define SPI0_SI_SLAVE 48 +#define SPI0_SS_N_0_MASTER 49 +#define SPI0_CLK_MASTER 50 +#define SPI0_MO_MASTER 51 +#define SPI0_MI_MASTER 52 +#define SPI2W_DATA 53 +#define SPI2W_CLK 54 +#define SPI2W_CS 55 +#define SWD_CLK 56 +#define SWD_DIO 57 +#define KEY_COL_0 58 +#define KEY_COL_1 59 +#define KEY_COL_2 60 +#define KEY_COL_3 61 +#define KEY_COL_4 62 +#define KEY_COL_5 63 +#define KEY_COL_6 64 +#define KEY_COL_7 65 +#define KEY_COL_8 66 +#define KEY_COL_9 67 +#define KEY_COL_10 68 +#define KEY_COL_11 69 +#define KEY_COL_12 70 +#define KEY_COL_13 71 +#define KEY_COL_14 72 +#define KEY_COL_15 73 +#define KEY_COL_16 74 +#define KEY_COL_17 75 +#define KEY_COL_18 76 +#define KEY_COL_19 77 +#define KEY_ROW_0 78 +#define KEY_ROW_1 79 +#define KEY_ROW_2 80 +#define KEY_ROW_3 81 +#define KEY_ROW_4 82 +#define KEY_ROW_5 83 +#define KEY_ROW_6 84 +#define KEY_ROW_7 85 +#define KEY_ROW_8 86 +#define KEY_ROW_9 87 +#define KEY_ROW_10 88 +#define KEY_ROW_11 89 +#define DWGPIO 90 +#define DIGI_DEBUG 95 +#define DMIC1_CLK 96 +#define DMIC1_DAT 97 +#define LRC_I_CODEC_SLAVE 98 +#define BCLK_I_CODEC_SLAVE 99 +#define SDI_CODEC_SLAVE 100 +#define SDO_CODEC_SLAVE 101 +#define BT_COEX_I_0 106 +#define BT_COEX_I_1 107 +#define BT_COEX_I_2 108 +#define BT_COEX_I_3 109 +#define BT_COEX_O_0 110 +#define BT_COEX_O_1 111 +#define BT_COEX_O_2 112 +#define BT_COEX_O_3 113 +#define PTA_I2C_CLK_SLAVE 114 +#define PTA_I2C_DAT_SLAVE 115 +#define PTA_I2C_INT_OUT 116 +#define EN_EXPA 117 +#define EN_EXLNA 118 +#define ANT_SW0 119 +#define ANT_SW1 120 +#define ANT_SW2 121 +#define ANT_SW3 122 +#define LRC_SPORT0 123 +#define BCLK_SPORT0 124 +#define ADCDAT_SPORT0 125 +#define DACDAT_SPORT0 126 +#define MCLK 127 +#else +#define IDLE_MODE 0 +#define HCI_UART_TX 1 +#define HCI_UART_RX 2 +#define HCI_UART_CTS 3 +#define HCI_UART_RTS 4 +#define I2C0_CLK 5 +#define I2C0_DAT 6 +#define I2C1_CLK 7 +#define I2C1_DAT 8 +#define PWM2_P 9 +#define PWM2_N 10 +#define PWM3_P 11 +#define PWM3_N 12 +#define timer_pwm0 13 +#define timer_pwm1 14 +#define timer_pwm2 15 +#define timer_pwm3 16 +#define timer_pwm4 17 +#define timer_pwm5 18 +#define timer_pwm6 19 +#define timer_pwm7 20 +#define qdec_phase_a_x 21 +#define qdec_phase_b_x 22 +#define qdec_phase_a_y 23 +#define qdec_phase_b_y 24 +#define qdec_phase_a_z 25 +#define qdec_phase_b_z 26 +#define UART2_TX 27 +#define UART2_RX 28 +#define UART1_TX 29 +#define UART1_RX 30 +#define UART1_CTS 31 +#define UART1_RTS 32 +#define IRDA_TX 33 +#define IRDA_RX 34 +#define UART0_TX 35 +#define UART0_RX 36 +#define UART0_CTS 37 +#define UART0_RTS 38 +#define SPI1_SS_N_0_MASTER 39 +#define SPI1_SS_N_1_MASTER 40 +#define SPI1_SS_N_2_MASTER 41 +#define SPI1_CLK_MASTER 42 +#define SPI1_MO_MASTER 43 +#define SPI1_MI_MASTER 44 +#define SPI0_SS_N_0_SLAVE 45 +#define SPI0_CLK_SLAVE 46 +#define SPI0_SO_SLAVE 47 +#define SPI0_SI_SLAVE 48 +#define SPI0_SS_N_0_MASTER 49 +#define SPI0_CLK_MASTER 50 +#define SPI0_MO_MASTER 51 +#define SPI0_MI_MASTER 52 +#define SPI2W_DATA 53 +#define SPI2W_CLK 54 +#define SPI2W_CS 55 +#define SWD_CLK 56 +#define SWD_DIO 57 +#define KEY_COL_0 58 +#define KEY_COL_1 59 +#define KEY_COL_2 60 +#define KEY_COL_3 61 +#define KEY_COL_4 62 +#define KEY_COL_5 63 +#define KEY_COL_6 64 +#define KEY_COL_7 65 +#define KEY_COL_8 66 +#define KEY_COL_9 67 +#define KEY_COL_10 68 +#define KEY_COL_11 69 +#define KEY_COL_12 70 +#define KEY_COL_13 71 +#define KEY_COL_14 72 +#define KEY_COL_15 73 +#define KEY_COL_16 74 +#define KEY_COL_17 75 +#define KEY_COL_18 76 +#define KEY_COL_19 77 +#define KEY_ROW_0 78 +#define KEY_ROW_1 79 +#define KEY_ROW_2 80 +#define KEY_ROW_3 81 +#define KEY_ROW_4 82 +#define KEY_ROW_5 83 +#define KEY_ROW_6 84 +#define KEY_ROW_7 85 +#define KEY_ROW_8 86 +#define KEY_ROW_9 87 +#define KEY_ROW_10 88 +#define KEY_ROW_11 89 +#define DWGPIO 90 +#define LRC_SPORT1 91 +#define BCLK_SPORT1 92 +#define ADCDAT_SPORT1 93 +#define DACDAT_SPORT1 94 +#define DIGI_DEBUG 95 +#define DMIC1_CLK 96 +#define DMIC1_DAT 97 +#define LRC_I_CODEC_SLAVE 98 +#define BCLK_I_CODEC_SLAVE 99 +#define SDI_CODEC_SLAVE 100 +#define SDO_CODEC_SLAVE 101 +#define LRC_I_PCM 102 +#define BCLK_I_PCM 103 +#define UART2_CTS 104 +#define UART2_RTS 105 +#define BT_COEX_I_0 106 +#define BT_COEX_I_1 107 +#define BT_COEX_I_2 108 +#define BT_COEX_I_3 109 +#define BT_COEX_O_0 110 +#define BT_COEX_O_1 111 +#define BT_COEX_O_2 112 +#define BT_COEX_O_3 113 +#define PTA_I2C_CLK_SLAVE 114 +#define PTA_I2C_DAT_SLAVE 115 +#define PTA_I2C_INT_OUT 116 +#define DSP_GPIO_OUT 117 +#define DSP_JTCK 118 +#define DSP_JTDI 119 +#define DSP_JTDO 120 +#define DSP_JTMS 121 +#define DSP_JTRST 122 +#define LRC_SPORT0 123 +#define BCLK_SPORT0 124 +#define ADCDAT_SPORT0 125 +#define DACDAT_SPORT0 126 +#define MCLK 127 +#endif +/** \} */ + +/** + * \enum PAD_Output_Value PAD Output Value + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_OUTPUT_VAL +{ + PAD_OUT_LOW, + PAD_OUT_HIGH +} PAD_OUTPUT_VAL; + +/** + * \enum PAD_Output_Config PAD Output Config + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_OUTPUT_ENABLE_Mode +{ + PAD_OUT_DISABLE, + PAD_OUT_ENABLE +} PAD_OUTPUT_ENABLE_Mode; + +/** + * \enum PAD_Pull_Mode PAD Pull Mode + * \ingroup PINMUX_Exported_Constants + */ +typedef enum _PAD_Pull_Mode +{ + PAD_PULL_UP, + PAD_PULL_DOWN, + PAD_PULL_NONE, +} PAD_Pull_Mode; + +/** + * \enum PAD_PULL_CONFIG_VAL PAD Pull Config + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_PULL_CONFIG_VAL +{ + PAD_WEAK_PULL, + PAD_STRONG_PULL +} PAD_PULL_VAL; + + +/** + * \enum PAD_WakeUp_Polarity_Value PAD WakeUp Polarity + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_WAKEUP_POL_VAL +{ + PAD_WAKEUP_POL_HIGH, + PAD_WAKEUP_POL_LOW +} PAD_WAKEUP_POL_VAL; + +/** + * \enum PAD_Power_Mode PAD Power Mode + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_PWR_Mode +{ + PAD_NOT_PWRON, + PAD_IS_PWRON = 1 +} PAD_PWR_Mode; + +/** + * \enum PAD_Mode PAD Mode + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_Mode +{ + PAD_SW_MODE, + PAD_PINMUX_MODE +} PAD_Mode; + +/** + * \enum PAD_WakeUp_Debounce_En PAD WakeUp Debounce enable + * + * \ingroup PINMUX_Exported_Constants + */ + +typedef enum _PAD_WAKEUP_DEBOUNCE_EN +{ + PAD_WK_DEBOUNCE_DISABLE, + PAD_WK_DEBOUNCE_ENABLE +} PAD_WAKEUP_DEBOUNCE_EN; + + +/** \} */ /** End of group PINMUX_Exported_Constants */ + +/** + * \brief + */ +//extern const uint8_t digi_debug_pin[32]; + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup PINMUX_Exported_Functions Peripheral APIs + * \ingroup PINMUX + * \{ + */ + +/** + * \brief Configure or reset all pins to idle mode. + * \param None. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void)//XXX represents the name of the peripheral to be configured. + * { + * Pinmux_Reset(); + * } + * \endcode + */ +void Pinmux_Reset(void); + +/** + * \brief Configure the specified pin to idle mode. + * \param Pin_Num: Pin number to be configured. + * This parameter can be one of the following values: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pinmux_Deinit(P2_2); + * } + * \endcode + */ +void Pinmux_Deinit(uint8_t Pin_Num); + +/** + * \brief Config the usage function of the selected pin. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \param[in] Pin_Func: Use function of pin. + * This parameter This parameter refers to \ref Pin_Function_Number + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * Pad_Config(P2_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + * Pad_Config(P2_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + + * Pinmux_Config(P2_0, UART0_TX); + * Pinmux_Config(P2_1, UART0_RX); + * } + * \endcode + */ +void Pinmux_Config(uint8_t Pin_Num, uint8_t Pin_Func); + +/** + * \brief Configure the relevant operation mode, + * peripheral circuit and output level value in software mode of the specified pin + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \param[in] AON_PAD_Mode: Use software mode or pinmux mode. + * This parameter can be one of the following values: + * \arg PAD_SW_MODE: Use software mode. + * \arg PAD_PINMUX_MODE: Use pinmux mode. + * \param[in] AON_PAD_PwrOn: Config power of pad. + * This parameter can be one of the following values: + * \arg PAD_NOT_PWRON: Shutdown power of pad. + * \arg PAD_IS_PWRON: Enable power of pad. + * \param[in] AON_PAD_Pull: config pad pull mode. + * This parameter can be one of the following values: + * \arg PAD_PULL_NONE: No pull. + * \arg PAD_PULL_UP: Pull this pin up. + * \arg PAD_PULL_DOWN: Pull this pin down. + * \param[in] AON_PAD_E: Config pad out put function. + * This parameter can be one of the following values: + * \arg PAD_OUT_DISABLE: Disable pin output. + * \arg PAD_OUT_ENABLE: Enable pad output. + * \param[in] AON_PAD_O: Config pin output level. + * This parameter can be one of the following values: + * \arg PAD_OUT_LOW: Pad output low. + * \arg PAD_OUT_HIGH: Pad output high. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_adc_init(void) + * { + * Pad_Config(P2_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW); + * Pad_Config(P2_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW); + * } + * \endcode + */ +void Pad_Config(uint8_t Pin_Num, + PAD_Mode AON_PAD_Mode, + PAD_PWR_Mode AON_PAD_PwrOn, + PAD_Pull_Mode AON_PAD_Pull, + PAD_OUTPUT_ENABLE_Mode AON_PAD_E, + PAD_OUTPUT_VAL AON_PAD_O); + +/** + * \brief Enable the function of the wake-up system of the specified pin. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \param[in] Polarity: Polarity of wake-up system. + * This parameter can be the following: + * \arg PAD_WAKEUP_POL_HIGH: Use high level wakeup. + * \arg PAD_WAKEUP_POL_LOW: Use low level wakeup. + * \param[in] DebounceEn: Enable delay function. + * \arg PAD_WK_DEBOUNCE_DISABLE: Disable delay function. + * \arg PAD_WK_DEBOUNCE_ENABLE: Enable delay function. + * \param[in] DebounceTime: Set debounce time, range from 0~63ms. + * \return None. + * + * Example usage + * \code{.c} + * //IO enter dlps call back function. + * void io_uart_dlps_enter(void) + * { + * // Switch pad to software mode + * Pad_ControlSelectValue(P2_0, PAD_SW_MODE);//tx pin + * Pad_ControlSelectValue(P2_1, PAD_SW_MODE);//rx pin + * + * System_WakeUpPinEnable(P2_1, PAD_WAKEUP_POL_LOW, PAD_WK_DEBOUNCE_DISABLE); + * } + * \endcode + */ +void System_WakeUpPinEnable(uint8_t Pin_Num, uint8_t Polarity, uint8_t DebounceEn, + uint8_t DebounceTime); + +/** + * \brief Disable the function of the wake-up system of the specified pin. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \return None. + * + * Example usage + * \code{.c} + * #define UART_RX_PIN P4_1 + * + * //System interrupt handler function, for wakeup pin. + * void System_Handler(void) + * { + * if (System_WakeUpInterruptValue(UART_RX_PIN) == SET) + * { + * Pad_ClearWakeupINTPendingBit(UART_RX_PIN); + * System_WakeUpPinDisable(UART_RX_PIN); + * //Add user code here. + * } + * } + * \endcode + */ +void System_WakeUpPinDisable(uint8_t Pin_Num); + +/** + * \brief Get pin interrupt status. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \return Interrupt status. + * \retval 1: Pin wake up system. + * \retval 0: The pin does not wake up the system. + * + * Example usage + * \code{.c} + * #define UART_RX_PIN P4_1 + * + * //System interrupt handler function, for wakeup pin. + * void System_Handler(void) + * { + * if (System_WakeUpInterruptValue(UART_RX_PIN) == SET) + * { + * Pad_ClearWakeupINTPendingBit(UART_RX_PIN); + * System_WakeUpPinDisable(UART_RX_PIN); + * //Add user code here. + * } + * } + * \endcode + */ +uint8_t System_WakeUpInterruptValue(uint8_t Pin_Num); + +/** + * @brief Get debounce wake up status. + * @note: Call this API will clear the debunce wakeup status bit. + * @param None + * @retval Debounce wakeup status + * + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * uint8_t DebounceWakeupStatus = System_DebounceWakeupStatus; + * } + * \endcode + */ +uint8_t System_DebounceWakeupStatus(void); + + +/** + * \brief Configure pad output level. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: Config pin output level. + * This parameter can be one of the following values: + * \arg PAD_OUT_LOW: Pad output low. + * \arg PAD_OUT_HIGH: Pad output high. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_OutputControlValue(P2_0, PAD_OUT_HIGH); + * } + * \endcode + */ +void Pad_OutputControlValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Enable or disable pad output mode. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter sets whether the pin outputs the level in software mode. + * This parameter can be enumerated PAD_OUTPUT_ENABLE_Mod of the values: + * \arg PAD_OUT_DISABLE: Disable output. + * \arg PAD_OUT_ENABLE: Enable output. + * \return None. + * + * Example usage + * \code{.c} + * + * void pad_demo(void) + * { + * Pad_OutputEnableValue(P2_0, PAD_OUT_ENABLE); + * } + * \endcode + */ +void Pad_OutputEnableValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Enable or disable pad pull-up / pull-down resistance function. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to PH_0, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter enable or disable the the pad pin pull-up/pull-down function. + * This parameter can be the following: + * \arg DISABLE: Disable pad pull-up / pull-down function. + * \arg ENABLE: Enable pad pull-up / pull-down function. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_PullEnableValue(P2_0, ENABLE); + * } + * \endcode + */ +void Pad_PullEnableValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Pad pull-up/pull-down resistance function selection. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter sets whether the pin pull-up or pull-down. + * This parameter can be the following: + * \arg 0: Config pad pull-up function. + * \arg 1: Config pad pull-down function. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_PullUpOrDownValue(P2_0, 1); + * } + * \endcode + */ +void Pad_PullUpOrDownValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Configure the strength of pull-up/pull-down resistance. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter sets the strength of pull-up/pull-down resistance. + * This parameter can be the following: + * \arg PAD_WEAK_PULL: Resistance weak pull. + * \arg PAD_STRONG_PULL: Resistance strong pull. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_PullConfigValue(P2_0, PAD_STRONG_PULL); + * } + * \endcode + */ +void Pad_PullConfigValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Set pin power mode. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter sets the power supply mode of the pin, + * and the value is enumeration PAD_PWR_Mode One of the values. + * \arg PAD_NOT_PWRON: Power off. + * \arg PAD_IS_PWRON: Power on. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_PowerOrShutDownValue(P2_0, PAD_NOT_PWRON); + * } + * \endcode + */ +void Pad_PowerOrShutDownValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Set pin mode. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to H_2, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: This parameter sets the pin mode. + * This parameter can be the following: + * \arg PAD_SW_MODE: Software mode. + * \arg PAD_PINMUX_MODE: Pinmux mode. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_ControlSelectValue(P2_0, PAD_SW_MODE); + * } + * \endcode + */ +void Pad_ControlSelectValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Enable the function of the wake-up system of the specified pin. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: Enable wake-up system function. + * \arg 0:Disable wake-up system function. + * \arg 1:Enable wake-up system function. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_WakeupEnableValue(P2_0, 1); + * } + * \endcode + */ +void Pad_WakeupEnableValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Set polarity of wake-up system. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] Polarity: Polarity of wake-up system. + * This parameter can be the following: + * \arg PAD_WAKEUP_POL_LOW:Use low level wakeup. + * \arg PAD_WAKEUP_POL_HIGH: Use high level wakeup. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_WakeupPolarityValue(P2_0, PAD_WAKEUP_POL_HIGH); + * } + * \endcode + */ +void Pad_WakeupPolarityValue(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Config pin delay function. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \param[in] value: Enable delay function. + * \arg 0:Disable delay function. + * \arg 1:Enable delay function. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_WKDebounceConfig(P2_0, 1); + * } + * \endcode + */ +void Pad_WKDebounceConfig(uint8_t Pin_Num, uint8_t value); + +/** + * \brief Get pin interrupt status, function is the same as \see system_WakeUpInterruptValue. + * \param[in] Pin_Num: Pin number to be configured. + * This parameter can be the following: + * \arg P0_0~P0_7, P1_0~P1_7, P2_0~P2_7, P3_0~P3_6, P4_0~P4_3, H0~H2 + * \return Interrupt status. + * \retval 0: The pin does not wake up the system. + * \retval 1: Pin wake up system. + */ +uint8_t Pad_WakeupInterruptValue(uint8_t Pin_Num); + +/** + * @brief Check debounce wake up status. + * @note: Call this API will clear the debunce wakeup status bit. + * @param None + * @retval Debounce wakeup status + */ +uint8_t Pad_DebounceWakeupStatus(void); + +/** + * \brief Clear the interrupt pendign bit of the specified pin + * \param[in] Pin_Num: Pin number to be configured. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "RTL876X_Pin_Number" part. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_ClearWakeupINTPendingBit(P2_0); + * } + * \endcode + */ +void Pad_ClearWakeupINTPendingBit(uint8_t Pin_Num); + +/** + * \brief Clear all wake up pin interrupt pending bit. + * \param[in] Pin_Num: pin number. + * This parameter is from P0_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_xxx_init(void) + * { + * Pad_ClearAllWakeupINT(); + * } + * \endcode + */ +void Pad_ClearAllWakeupINT(void); + +void Pinmux_8080Control(uint32_t value, uint8_t VSYNC, uint8_t RD); + +/** + * \brief Spic0 master enable. + * \param[in] value: 0:Disable 1:Enable. + * \return None. + * + * Example usage + * \code{.c} + * + * void io_demo(void) + * { + * Spic0_control(1); + * } + * \endcode + */ +void Spic0_control(uint8_t value); + +/** + * \brief Spic1 master enable. + * \param[in] value: 0:Disable 1:Enable. + * \return None. + * + * Example usage + * \code{.c} + * + * void io_demo(void) + * { + * Spic1_control(1); + * } + * \endcode + */ +void Spic1_control(uint8_t value); + + +/** \} */ /* End of group PINMUX_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_PINMUX_H_ */ + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_qdec.h b/inc/peripheral/rtl876x_qdec.h new file mode 100644 index 0000000..d716164 --- /dev/null +++ b/inc/peripheral/rtl876x_qdec.h @@ -0,0 +1,597 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_qdec.h +* \brief The header file of the peripheral QDECODER driver. +* \details This file provides all QDECODER firmware functions. +* \author howie wang +* \date 2016-05-10 +* \version v1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_QDECODER_H_ +#define _RTL876X_QDECODER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup QDEC QDEC + * + * \brief Manage the QDEC peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup QDEC_Exported_Types Init Params Struct + * + * \ingroup QDEC + */ + +/** + * \brief Qdecoder init structure definition. + * + * \ingroup QDEC_Exported_Types + */ +typedef struct +{ + uint16_t scanClockDiv; + uint16_t debounceClockDiv; + uint8_t axisConfigX; /*!< Specifies the axis X function. + This parameter can be a value of ENABLE or DISABLE */ + uint8_t axisConfigY; /*!< Specifies the axis Y function. + This parameter can be a value of ENABLE or DISABLE */ + uint8_t axisConfigZ; /*!< Specifies the axis Z function. + This parameter can be a value of ENABLE or DISABLE */ + uint8_t manualLoadInitPhase; /*!< Specifies manual-load Initphase function . + This parameter can be a value of ENABLE or DISABLE */ + uint16_t counterScaleX; /*!< Specifies the axis X conter scale. + This parameter can be a value of \ref QDEC_Axis_counter_Scale */ + uint16_t debounceEnableX; /*!< Specifies the axis X debounce. + This parameter can be a value of \ref Qdec_Debounce */ + uint16_t debounceTimeX; /*!< Specifies the axis X debounce time. */ + uint16_t initPhaseX; /*!< Specifies the axis X function. + This parameter can be a value of \ref Qdec_init_phase */ + uint16_t counterScaleY; /*!< Specifies the axis Y conter scale. + This parameter can be a value of \ref QDEC_Axis_counter_Scale */ + uint16_t debounceEnableY; /*!< Specifies the axis Y debounce. + This parameter can be a value of \ref Qdec_Debounce */ + uint16_t debounceTimeY; /*!< Specifies the axis Y debounce time. */ + uint16_t initPhaseY; /*!< Specifies the axis Y function. + This parameter can be a value of \ref Qdec_init_phase */ + uint16_t counterScaleZ; /*!< Specifies the axis Z conter scale. + This parameter can be a value of \ref QDEC_Axis_counter_Scale */ + uint16_t debounceEnableZ; /*!< Specifies the axis Z debounce. + This parameter can be a value of \ref Qdec_Debounce */ + uint16_t debounceTimeZ; /*!< Specifies the axis Z debounce time. */ + uint16_t initPhaseZ; /*!< Specifies the axis Z function. + This parameter can be a value of \ref Qdec_init_phase */ +} QDEC_InitTypeDef; + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup QDEC_Exported_Constants Macro Definitions + * + * \ingroup QDEC + */ + +#define IS_QDEC_PERIPH(PERIPH) ((PERIPH) == QDEC) + +/** \defgroup QDEC_Interrupts_Definition QDEC Interrupts Definition + * \{ + * \ingroup QDEC_Exported_Constants + */ +#define QDEC_X_INT_NEW_DATA BIT(0)//get New data and state change +#define QDEC_X_INT_ILLEAGE BIT(1)//illeage +#define QDEC_Y_INT_NEW_DATA BIT(2)//get New data and state change +#define QDEC_Y_INT_ILLEAGE BIT(3)//illeage +#define QDEC_Z_INT_NEW_DATA BIT(4)//get New data and state change +#define QDEC_Z_INT_ILLEAGE BIT(5)//illeage +/** \} */ + +#define IS_QDEC_INT_CONFIG(CONFIG) (((CONFIG) == QDEC_X_INT_NEW_DATA) || ((CONFIG) == QDEC_X_INT_ILLEAGE)\ + || ((CONFIG) == QDEC_Y_INT_NEW_DATA) || ((CONFIG) == QDEC_Y_INT_ILLEAGE)\ + || ((CONFIG) == QDEC_Z_INT_NEW_DATA) || ((CONFIG) == QDEC_Z_INT_ILLEAGE)) + +/** \defgroup QDEC_Interrupts_Mask QDEC Interrupts Mask + * \{ + * \ingroup QDEC_Exported_Constants + */ +#define QDEC_X_CT_INT_MASK BIT(0)//get New data and state change +#define QDEC_X_ILLEAGE_INT_MASK BIT(4)//illeage +#define QDEC_Y_CT_INT_MASK BIT(1)//get New data and state change +#define QDEC_Y_ILLEAGE_INT_MASK BIT(5)//illeage +#define QDEC_Z_CT_INT_MASK BIT(2)//get New data and state change +#define QDEC_Z_ILLEAGE_INT_MASK BIT(6)//illeage +/** \} */ + +#define IS_QDEC_INT_MASK_CONFIG(CONFIG) (((CONFIG) == QDEC_X_CT_INT_MASK) || ((CONFIG) == QDEC_X_ILLEAGE_INT_MASK)\ + || ((CONFIG) == QDEC_Y_CT_INT_MASK) || ((CONFIG) == QDEC_Y_ILLEAGE_INT_MASK)\ + || ((CONFIG) == QDEC_Z_CT_INT_MASK) || ((CONFIG) == QDEC_Z_ILLEAGE_INT_MASK)) +/** \defgroup QDEC_Axis_counter_Scale QDEC Axis Counter + * \{ + * \ingroup QDEC_Exported_Constants + */ +#define CounterScale_2_Phase true +#define CounterScale_1_Phase false +/** \} */ + +/** \defgroup QDEC_Debounce QDEC Debounce + * \{ + * \ingroup QDEC_Exported_Constants + */ +#define Debounce_Enable true +#define Debounce_Disable false +/** \} */ + +/** \defgroup QDEC_Manual_Phase QDEC manual phase + * \{ + * \ingroup QDEC_Exported_Constants + */ + +#define manualPhaseEnable true +#define manualPhaseDisable false +/** \} */ + +/** \defgroup Qdec_Init_Phase Qdec Init Phase + * \{ + * \ingroup QDEC_Exported_Constants + */ + +#define phaseMode0 0 //phase 00 +#define phaseMode1 1 //phase 01 +#define phaseMode2 2 //phase 10 +#define phaseMode3 3 //phase 11 +/** \} */ + +/** \defgroup QDEC_Clr_Flag Qdec Clr Flag + * \{ + * \ingroup QDEC_Exported_Constants + */ +#define QDEC_CLR_ILLEGAL_CT_X ((uint32_t)(1 << 20)) +#define QDEC_CLR_ILLEGAL_CT_Y ((uint32_t)(1 << 21)) +#define QDEC_CLR_ILLEGAL_CT_Z ((uint32_t)(1 << 22)) + +#define QDEC_CLR_ACC_CT_X ((uint32_t)(1 << 16)) +#define QDEC_CLR_ACC_CT_Y ((uint32_t)(1 << 17)) +#define QDEC_CLR_ACC_CT_Z ((uint32_t)(1 << 18)) + +#define QDEC_CLR_ILLEGAL_INT_X ((uint32_t)(1 << 12)) +#define QDEC_CLR_ILLEGAL_INT_Y ((uint32_t)(1 << 13)) +#define QDEC_CLR_ILLEGAL_INT_Z ((uint32_t)(1 << 14)) + +#define QDEC_CLR_UNDERFLOW_X ((uint32_t)(1 << 8)) +#define QDEC_CLR_UNDERFLOW_Y ((uint32_t)(1 << 9)) +#define QDEC_CLR_UNDERFLOW_Z ((uint32_t)(1 << 10)) + +#define QDEC_CLR_OVERFLOW_X ((uint32_t)(1 << 4)) +#define QDEC_CLR_OVERFLOW_Y ((uint32_t)(1 << 5)) +#define QDEC_CLR_OVERFLOW_Z ((uint32_t)(1 << 6)) + +#define QDEC_CLR_NEW_CT_X ((uint32_t)(1 << 0)) +#define QDEC_CLR_NEW_CT_Y ((uint32_t)(1 << 1)) +#define QDEC_CLR_NEW_CT_Z ((uint32_t)(1 << 2)) +/** \} */ + +#define IS_QDEC_INT_CLR_CONFIG(CONFIG) (((CONFIG) == QDEC_CLR_ACC_CT_X) || ((CONFIG) == QDEC_CLR_ACC_CT_Y)\ + || ((CONFIG) == QDEC_CLR_ACC_CT_Z) || ((CONFIG) == QDEC_CLR_ILLEGAL_INT_Y)\ + || ((CONFIG) == QDEC_CLR_ILLEGAL_INT_Z) || ((CONFIG) == QDEC_CLR_UNDERFLOW_X)\ + || ((CONFIG) == QDEC_CLR_UNDERFLOW_Y) || ((CONFIG) == QDEC_CLR_UNDERFLOW_Z)\ + || ((CONFIG) == QDEC_CLR_OVERFLOW_X) || ((CONFIG) == QDEC_CLR_OVERFLOW_Y)\ + || ((CONFIG) == QDEC_CLR_OVERFLOW_Z) || ((CONFIG) == QDEC_CLR_NEW_CT_X)\ + || ((CONFIG) == QDEC_CLR_NEW_CT_Y) || ((CONFIG) == QDEC_CLR_NEW_CT_Z)) + +/** \defgroup QDEC_Flag QDEC Flag + * \{ + * \ingroup QDEC_Exported_Constants + */ + +#define QDEC_FLAG_NEW_CT_STATUS_X ((uint32_t)(1 << 0)) +#define QDEC_FLAG_NEW_CT_STATUS_Y ((uint32_t)(1 << 1)) +#define QDEC_FLAG_NEW_CT_STATUS_Z ((uint32_t)(1 << 2)) +#define QDEC_FLAG_OVERFLOW_X ((uint32_t)(1 << 3)) +#define QDEC_FLAG_OVERFLOW_Y ((uint32_t)(1 << 4)) +#define QDEC_FLAG_OVERFLOW_Z ((uint32_t)(1 << 5)) +#define QDEC_FLAG_UNDERFLOW_X ((uint32_t)(1 << 6)) +#define QDEC_FLAG_UNDERFLOW_Y ((uint32_t)(1 << 7)) +#define QDEC_FLAG_UNDERFLOW_Z ((uint32_t)(1 << 8)) +#define QDEC_FLAG_AUTO_STATUS_X ((uint32_t)(1 << 9)) +#define QDEC_FLAG_AUTO_STATUS_Y ((uint32_t)(1 << 10)) +#define QDEC_FLAG_AUTO_STATUS_Z ((uint32_t)(1 << 11)) +#define QDEC_FLAG_ILLEGAL_STATUS_X ((uint32_t)(1 << 12)) +#define QDEC_FLAG_ILLEGAL_STATUS_Y ((uint32_t)(1 << 13)) +#define QDEC_FLAG_ILLEGAL_STATUS_Z ((uint32_t)(1 << 14)) +/** \} */ + +#define IS_QDEC_CLR_INT_STATUS(INT) (((INT) == QDEC_FLAG_ILLEGAL_STATUS_X) || ((INT) == QDEC_FLAG_ILLEGAL_STATUS_Y)\ + || ((INT) == QDEC_FLAG_ILLEGAL_STATUS_Z) || ((INT) == QDEC_FLAG_NEW_CT_STATUS_X)\ + || ((INT) == QDEC_FLAG_NEW_CT_STATUS_Y) || ((INT) == QDEC_FLAG_NEW_CT_STATUS_Z)\ + || ((INT) == QDEC_FLAG_OVERFLOW_X) || ((INT) == QDEC_FLAG_OVERFLOW_Y)\ + || ((INT) == QDEC_FLAG_OVERFLOW_Z) || ((INT) == QDEC_FLAG_UNDERFLOW_X)\ + || ((INT) == QDEC_FLAG_UNDERFLOW_Y) || ((INT) == QDEC_FLAG_UNDERFLOW_Z)\ + || ((INT) == QDEC_FLAG_AUTO_STATUS_X) || ((INT) == QDEC_FLAG_AUTO_STATUS_Y)\ + || ((INT) == QDEC_FLAG_AUTO_STATUS_Z)) + +/** \defgroup QDEC_Axis QDEC Axis + * \{ + * \ingroup QDEC_Exported_Constants + */ + +#define QDEC_AXIS_X ((uint32_t)(1 << 0)) +#define QDEC_AXIS_Y ((uint32_t)(1 << 2)) +#define QDEC_AXIS_Z ((uint32_t)(1 << 3)) +/** \} */ + +/** \defgroup QDEC_Axis_Direction QDEC Axis Direction + * \{ + * \ingroup QDEC_Exported_Constants + */ + +#define QDEC_AXIS_DIR_UP ((uint16_t)0x01) +#define QDEC_AXIS_DIR_DOWN ((uint16_t)0x00) +/** \} */ + +#define IS_QDEC_AXIS_DIR(QDEC_AXIS) ((QDEC_AXIS == QDEC_AXIS_DIR_UP) || (QDEC_AXIS == QDEC_AXIS_DIR_DOWN)) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup QDEC_Exported_Functions Peripheral APIs + * \{ + * \ingroup QDEC + */ + +/** + * \brief Deinitializes the Qdecoder peripheral registers to their default reset values(turn off Qdecoder clock). + * \param[in] QDECx: Selected Qdecoder peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_qdec_init(void) + * { + * QDEC_DeInit(); + * } + * \endcode + */ +void QDEC_DeInit(QDEC_TypeDef *QDECx); + +/** + * \brief Initializes the Qdecoder peripheral according to the specified + * parameters in the QDEC_InitStruct + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_InitStruct: Pointer to a QDEC_InitStruct structure that + * contains the configuration information for the specified Qdecoder peripheral + * \return None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_qdec_init(void) + * { + * QDEC_DeInit(QDEC); + * RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE); + * + * QDEC_InitTypeDef QDEC_InitStruct; + * QDEC_StructInit(&QDEC_InitStruct); + * QDEC_InitStruct.axisConfigY = ENABLE; + * QDEC_InitStruct.debounceEnableY = Debounce_Enable; + * QDEC_Init(QDEC, &QDEC_InitStruct); + * + * QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE); + * } + * \endcode + */ +void QDEC_Init(QDEC_TypeDef *QDECx, QDEC_InitTypeDef *QDEC_InitStruct); + +/** + * \brief Fills each QDEC_InitStruct member with its default value. + * \param[in] QDEC_InitStruct: Pointer to an QDEC_InitStruct structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_qdec_init(void) + * { + * QDEC_DeInit(QDEC); + * RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, ENABLE); + * + * QDEC_InitTypeDef QDEC_InitStruct; + * QDEC_StructInit(&QDEC_InitStruct); + * QDEC_InitStruct.axisConfigY = ENABLE; + * QDEC_InitStruct.debounceEnableY = Debounce_Enable; + * QDEC_Init(QDEC, &QDEC_InitStruct); + * + * QDEC_Cmd(QDEC, QDEC_AXIS_Y, ENABLE); + * } + * \endcode + */ +void QDEC_StructInit(QDEC_InitTypeDef *QDEC_InitStruct); + +/** + * \brief Enables or disables the specified Qdecoder interrupt source. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_IT: Specifies the QDECODER interrupts sources to be enabled or disabled. + * This parameter parameter can be one of the following values: + * \arg QDEC_X_INT_NEW_DATA: The counter interrupt for X axis. + * \arg QDEC_X_INT_ILLEAGE: The illegal interrupt for X axis. + * \arg QDEC_Y_INT_NEW_DATA: The counter interrupt for Y axis. + * \arg QDEC_Y_INT_ILLEAGE: The illegal interrupt for Y axis. + * \arg QDEC_Z_INT_NEW_DATA: The counter interrupt for Z axis. + * \arg QDEC_Z_INT_ILLEAGE: The illegal interrupt for Z axis. + * \param[in] newState: New state of the specified QDECODER interrupt. + * This parameter parameter can be: ENABLE or DISABLE. + * \return None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_qdec_init(void) + * { + * QDEC_INTConfig(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE); + * } + * \endcode + */ +void QDEC_INTConfig(QDEC_TypeDef *QDECx, uint32_t QDEC_IT, FunctionalState newState); + +/** + * \brief Check whether the specified Qdecoder flag is set. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_FLAG: Specifies the flag to check. + * This parameter can be one of the following values: + * \arg QDEC_FLAG_NEW_CT_STATUS_X: Status of the counter interrupt for X axis. + * \arg QDEC_FLAG_NEW_CT_STATUS_Y: Status of the counter interrupt for Y axis. + * \arg QDEC_FLAG_NEW_CT_STATUS_Z: Status of the counter interrupt for Z axis. + * \arg QDEC_FLAG_ILLEGAL_STATUS_X: Status of the illegal interrupt for X axis. + * \arg QDEC_FLAG_ILLEGAL_STATUS_Y: Status of the illegal interrupt for Y axis. + * \arg QDEC_FLAG_ILLEGAL_STATUS_Z: Status of the illegal interrupt for Z axis. + * \arg QDEC_FLAG_OVERFLOW_X: The overflow flag for x-axis accumulation counter. + * \arg QDEC_FLAG_OVERFLOW_Y: The overflow flag for y-axis accumulation counter. + * \arg QDEC_FLAG_OVERFLOW_Z: The overflow flag for z-axis accumulation counter. + * \arg QDEC_FLAG_UNDERFLOW_X: The underflow flag for x-axis accumulation counter. + * \arg QDEC_FLAG_UNDERFLOW_Y: The underflow flag for y-axis accumulation counter. + * \arg QDEC_FLAG_UNDERFLOW_Z: The underflow flag for z-axis accumulation counter. + * \retval The new state of QDEC_FLAG (SET or RESET). + * \return None. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * FlagStatus flag_status = QDEC_GetFlagState(QDEC, QDEC_Y_INT_NEW_DATA, ENABLE); + * } + * \endcode + */ +FlagStatus QDEC_GetFlagState(QDEC_TypeDef *QDECx, uint32_t QDEC_FLAG); + +/** + * \brief Enables or disables mask the specified Qdecoder axis interrupts. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_AXIS: Specifies the Qdecoder axis. + * This parameter can be one or logical OR of the following values: + * \arg QDEC_X_CT_INT_MASK: The x-axis counter interrupt mask. + * \arg QDEC_X_ILLEAGE_INT_MASK: The x-axis illegal interrupt mask. + * \arg QDEC_Y_CT_INT_MASK: The y-axis counter interrupt mask. + * \arg QDEC_Y_ILLEAGE_INT_MASK: The y-axis illegal interrupt mask. + * \arg QDEC_Z_CNT_INT_MASK: The z-axis counter interrupt mask. + * \arg QDEC_Z_ILLEAGE_INT_MASK: The z-axis illegal interrupt mask. + * \param[in] newState: New state of the specified Qdecoder interrupts mask. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * + * QDEC_INTMask(QDEC, QDEC_X_CT_INT_MASK, ENABLE); + * + * } + * \endcode + */ +void QDEC_INTMask(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, FunctionalState newState); + +/** + * \brief Enable or disable the selected Qdecoder axis(x/y/z). + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_AXIS: Specifies the Qdecoder axis. + * This parameter can be one of the following values: + * \arg QDEC_AXIS_X: The qdecoder X axis. + * \arg QDEC_AXIS_Y: The qdecoder Y axis. + * \arg QDEC_AXIS_Z: The qdecoder Z axis. + * \param[in] newState: New state of the selected Qdecoder axis. + * This parameter can be : ENABLE or DISABLE. + * \retturn The count of the axis. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * QDEC_Cmd(QDEC, QDEC_AXIS_X, ENABLE); + * } + * \endcode + */ +void QDEC_Cmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, + FunctionalState newState); + +/** + * \brief Clear Qdecoder interrupt pending bit. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_FLAG: Specifies the flag to clear. + * This parameter parameter can be one of the following values: + * \arg QDEC_CLR_OVERFLOW_X: The overflow flag for x-axis accumulation counter. + * \arg QDEC_CLR_OVERFLOW_Y: The overflow flag for y-axis accumulation counter. + * \arg QDEC_CLR_OVERFLOW_Z: The overflow flag for z-axis accumulation counter. + * \arg QDEC_CLR_ILLEGAL_INT_X: The illegal interrupt for X axis. + * \arg QDEC_CLR_ILLEGAL_INT_Y: The illegal interrupt for Y axis. + * \arg QDEC_CLR_ILLEGAL_INT_Z: The illegal interrupt for Z axis. + * \arg QDEC_CLR_UNDERFLOW_X: The underflow flag for x-axis accumulation counter. + * \arg QDEC_CLR_UNDERFLOW_Y: The underflow flag for y-axis accumulation counter. + * \arg QDEC_CLR_UNDERFLOW_Z: The underflow flag for z-axis accumulation counter. + * \arg QDEC_CLR_NEW_CT_X: The counter interrupt for X axis. + * \arg QDEC_CLR_NEW_CT_Y: The counter interrupt for Y axis. + * \arg QDEC_CLR_NEW_CT_Z: The counter interrupt for Z axis. + * \return None. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * QDEC_ClearINTPendingBit(QDEC, QDEC_CLR_OVERFLOW_X); + * } + * \endcode + */ +__STATIC_INLINE void QDEC_ClearINTPendingBit(QDEC_TypeDef *QDECx, uint32_t QDEC_CLR_INT) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_CLR_INT_STATUS(QDEC_CLR_INT)); + + QDECx->INT_CLR |= QDEC_CLR_INT; + + return; +} + +/** + * \brief Get Qdecoder Axis(x/y/z) direction. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_AXIS: Specifies the Qdecoder axis. + * This parameter parameter can be one of the following values: + * \arg QDEC_AXIS_X: The qdecoder X axis. + * \arg QDEC_AXIS_Y: The qdecoder Y axis. + * \arg QDEC_AXIS_Z: The qdecoder Z axis. + * \return The direction of the axis. + * This parameter parameter can be one of the following values: + * \retval QDEC_AXIS_DIR_UP: The axis is rolling up. + * \retval QDEC_AXIS_DIR_DOWN: The axis is rolling down. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * uint16_t dir = QDEC_GetAxisDirection(QDEC, QDEC_AXIS_X); + * } + * \endcode + */ +__STATIC_INLINE uint16_t QDEC_GetAxisDirection(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS)); + + return ((*((volatile uint32_t *)(&QDECx->REG_SR_X) + QDEC_AXIS / 2) & (1 << 16)) == BIT(16)); +} + +/** + * \brief Get Qdecoder Axis(x/y/z) count. + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_AXIS: Specifies the Qdecoder axis. + * This parameter parameter can be one of the following values: + * \arg QDEC_AXIS_X: The qdecoder X axis. + * \arg QDEC_AXIS_Y: The qdecoder Y axis. + * \arg QDEC_AXIS_Z: The qdecoder Z axis. + * \return The count of the axis. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * uint16_t counter = QDEC_GetAxisCount(QDEC, QDEC_AXIS_X); + * } + * \endcode + */ +__STATIC_INLINE uint16_t QDEC_GetAxisCount(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS)); + + return ((uint16_t)(*((volatile uint32_t *)(&QDECx->REG_SR_X) + QDEC_AXIS / 2))); +} + +/** + * \brief Pause or resume Qdecoder Axis(x/y/z). + * \param[in] QDECx: Selected Qdecoder peripheral. + * \param[in] QDEC_AXIS: Specifies the Qdecoder axis. + * This parameter parameter can be one of the following values: + * \arg QDEC_AXIS_X: The qdecoder X axis. + * \arg QDEC_AXIS_Y: The qdecoder Y axis. + * \arg QDEC_AXIS_Z: The qdecoder Z axis. + * \param[in] newState: New state of the specified Qdecoder Axis. + * This parameter parameter can be one of the following values: + * \arg ENABLE: Pause. + * \arg DISABLE: Resume. + * \return None. + * + * Example usage + * \code{.c} + * + * void qdec_demo(void) + * { + * QDEC_CounterPauseCmd(QDEC, QDEC_AXIS_X, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void QDEC_CounterPauseCmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, + FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS)); + + if (newState == ENABLE) + { + *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) |= BIT3; + } + else + { + *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) &= ~BIT3; + } +} + +/** \} */ /* End of group QDEC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_QDECODER_H_ */ + + +/******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/ + + + diff --git a/inc/peripheral/rtl876x_rcc.h b/inc/peripheral/rtl876x_rcc.h new file mode 100644 index 0000000..43fadff --- /dev/null +++ b/inc/peripheral/rtl876x_rcc.h @@ -0,0 +1,470 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_rcc.h +* \brief The header file of the clock control and reset driver. +* \details This file provides all peripheral clock control firmware functions. +* \author tifnan_ge +* \date 2015-05-16 +* \version v0.1 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_RCC_H_ +#define _RTL876X_RCC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup RCC RCC + * + * \brief Manage the RCC peripheral functions. + * + * \ingroup IO + */ + + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup RCC_Exported_Constants Macro Definitions + * + * \ingroup RCC + */ + +/** + * \defgroup RCC_Peripheral_Clock RCC Peripheral Clock + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define APBPeriph_I2S0_CLOCK ((uint32_t)((1 << 5) | (1 << 8) | (0x00 << 29))) +#define APBPeriph_I2S1_CLOCK ((uint32_t)((1 << 6) | (1 << 8) | (0x00 << 29))) +#define APBPeriph_CODEC_CLOCK ((uint32_t)((1 << 4) | (0x00 << 29))) + +#define APBPeriph_GPIO_CLOCK ((uint32_t)((0x01 << 24) | (0x01 << 29))) +#define APBPeriph_GDMA_CLOCK ((uint32_t)((0x01 << 16) | (0x01 << 29))) +#define APBPeriph_TIMER_CLOCK ((uint32_t)((0x01 << 14) | (0x01 << 29))) +#define APBPeriph_ENHTIMER_CLOCK ((uint32_t)((0x01 << 14) | (0x01 << 29))) +#define APBPeriph_UART2_CLOCK ((uint32_t)((0x01 << 10) | (0x01 << 29))) +#define APBPeriph_UART1_CLOCK ((uint32_t)((0x01 << 12) | (0x01 << 29))) +#define APBPeriph_FLASH_CLOCK ((uint32_t)((0x01 << 8) | (0x01 << 29))) + +#define APBPeriph_FLASH2_CLOCK ((uint32_t)((0x01 << 26) | (0x02 << 29))) +#define APBPeriph_FLASH1_CLOCK ((uint32_t)((0x01 << 24) | (0x02 << 29))) +#define APBPeriph_IR_CLOCK ((uint32_t)((0x01 << 20) | (0x02 << 29))) +#define APBPeriph_SPI1_CLOCK ((uint32_t)((0x01 << 18) | (0x02 << 29))) +#define APBPeriph_SPI0_CLOCK ((uint32_t)((0x01 << 16) | (0x02 << 29))) +#define APBPeriph_CTC_CLOCK ((uint32_t)((0x01 << 12) | (0x02 << 29))) +#define APBPeriph_UART0_CLOCK ((uint32_t)((0x01 << 0) | (0x02 << 29))) + +#define APBPeriph_IF8080_CLOCK ((uint32_t)((0x01 << 28) | (0x03 << 29))) +#define APBPeriph_ADC_CLOCK ((uint32_t)((0x01 << 24) | (0x03 << 29))) +#define APBPeriph_SPI2W_CLOCK ((uint32_t)((0x01 << 16) | (0x03 << 29))) +#define APBPeriph_KEYSCAN_CLOCK ((uint32_t)((0x01 << 6) | (0x03 << 29))) +#define APBPeriph_QDEC_CLOCK ((uint32_t)((0x01 << 4) | (0x03 << 29))) +#define APBPeriph_I2C1_CLOCK ((uint32_t)((0x01 << 2) | (0x03 << 29))) +#define APBPeriph_I2C0_CLOCK ((uint32_t)((0x01 << 0) | (0x03 << 29))) +/** \} */ + +#define IS_APB_PERIPH_CLOCK(CLOCK) (((CLOCK) == APBPeriph_GPIO_CLOCK) || ((CLOCK) == APBPeriph_GDMA_CLOCK)\ + || ((CLOCK) == APBPeriph_TIMER_CLOCK) || ((CLOCK) == APBPeriph_IR_CLOCK)\ + || ((CLOCK) == APBPeriph_SPI1_CLOCK) || ((CLOCK) == APBPeriph_SPI0_CLOCK)\ + || ((CLOCK) == APBPeriph_UART0_CLOCK) || ((CLOCK) == APBPeriph_ADC_CLOCK)\ + || ((CLOCK) == APBPeriph_SPI2W_CLOCK) || ((CLOCK) == APBPeriph_KEYSCAN_CLOCK)\ + || ((CLOCK) == APBPeriph_QDEC_CLOCK) || ((CLOCK) == APBPeriph_I2C1_CLOCK)\ + || ((CLOCK) == APBPeriph_I2C0_CLOCK) || ((CLOCK) == APBPeriph_CODEC_CLOCK)\ + || ((CLOCK) == APBPeriph_UART1_CLOCK) || ((CLOCK) == APBPeriph_UART2_CLOCK)\ + || ((CLOCK) == APBPeriph_I2S0_CLOCK) || ((CLOCK) == APBPeriph_I2S1_CLOCK)\ + || ((CLOCK) == APBPeriph_IF8080_CLOCK) || ((CLOCK) == APBPeriph_ENHTIMER_CLOCK)) + +/** + * \defgroup APB_Peripheral_Define APB Peripheral Define + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define APBPeriph_CTC ((uint32_t)((1 << 21) | (0x00 << 26))) +#define APBPeriph_TIMER ((uint32_t)((1 << 16) | (0x00 << 26))) +#define APBPeriph_ENHTIMER ((uint32_t)((1 << 16) | (0x00 << 26))) +#define APBPeriph_GDMA ((uint32_t)((1 << 13) | (0x00 << 26))) +#define APBPeriph_UART1 ((uint32_t)((1 << 12) | (0x00 << 26))) +#define APBPeriph_FLASH2 ((uint32_t)((1 << 5) | (0x00 << 26))) +#define APBPeriph_FLASH ((uint32_t)((1 << 4) | (0x00 << 26))) +#define APBPeriph_FLASH1 ((uint32_t)((1 << 3) | (0x00 << 26))) + +#define APBPeriph_IF8080 ((uint32_t)((1 << 25) | (0x02 << 26))) +#define APBPeriph_SPI2W ((uint32_t)((1 << 24) | (0x02 << 26))) +#define APBPeriph_KEYSCAN ((uint32_t)((1 << 19) | (0x02 << 26))) +#define APBPeriph_QDEC ((uint32_t)((1 << 18) | (0x02 << 26))) +#define APBPeriph_I2C1 ((uint32_t)((1 << 17) | (0x02 << 26))) +#define APBPeriph_I2C0 ((uint32_t)((1 << 16) | (0x02 << 26))) +#define APBPeriph_IR ((uint32_t)((1 << 10) | (0x02 << 26))) +#define APBPeriph_SPI1 ((uint32_t)((1 << 9) | (0x02 << 26))) +#define APBPeriph_SPI0 ((uint32_t)((1 << 8) | (0x02 << 26))) +#define APBPeriph_UART0 ((uint32_t)((1 << 0) | (0x02 << 26))) +#define APBPeriph_UART2 ((uint32_t)((1 << 1) | (0x02 << 26))) + +#define APBPeriph_GPIO ((uint32_t)((1 << 8) | (0x03 << 26))) +#define APBPeriph_ADC ((uint32_t)((1 << 0) | (0x03 << 26))) + +#define APBPeriph_I2S1 ((uint32_t)((1 << 2) | (0x00 << 26))) +#define APBPeriph_I2S0 ((uint32_t)((1 << 1) | (0x00 << 26))) +#define APBPeriph_CODEC ((uint32_t)((1 << 0) | (0x00 << 26))) +/** \} */ + +#define IS_APB_PERIPH(PERIPH) (((PERIPH) == APBPeriph_TIMER) || ((PERIPH) == APBPeriph_GDMA)\ + || ((PERIPH) == APBPeriph_SPI2W) || ((PERIPH) == APBPeriph_KEYSCAN)\ + || ((PERIPH) == APBPeriph_QDEC) || ((PERIPH) == APBPeriph_I2C1)\ + || ((PERIPH) == APBPeriph_I2C0) || ((PERIPH) == APBPeriph_IR)\ + || ((PERIPH) == APBPeriph_SPI1) || ((PERIPH) == APBPeriph_SPI0)\ + || ((PERIPH) == APBPeriph_UART0) || ((PERIPH) == APBPeriph_GPIO)\ + || ((PERIPH) == APBPeriph_ADC) || ((PERIPH) == APBPeriph_CODEC)\ + || (PERIPH == APBPeriph_UART1) || (PERIPH == APBPeriph_UART2)\ + || ((PERIPH) == APBPeriph_I2S0) || ((PERIPH) == APBPeriph_I2S1)\ + || ((PERIPH) == APBPeriph_IF8080) || ((PERIPH) == APBPeriph_ENHTIMER)) + +/** + * \defgroup RCC_Peripheral_Clock RCC Peripheral Clock + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define CLOCK_GATE_5M ((uint32_t)(0x01 << 29))/* 5M clock source for adc and keyscan */ +#define CLOCK_GATE_20M ((uint32_t)(0x01 << 27))/* 20M clock source for 2wssi and qdec */ +#define CLOCK_GATE_10M ((uint32_t)(0x01 << 28))/* 10M clock source for bluewiz */ +/** \} */ +#define IS_CLOCK_GATE(CLOCK) (((CLOCK) == CLOCK_GATE_5M) || ((CLOCK) == CLOCK_GATE_20M)\ + || ((CLOCK) == CLOCK_GATE_10M)) + +/** + * \defgroup I2C_Clock_Divider I2C Clock Divider + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define I2C_CLOCK_DIV_1 ((uint16_t)0x0) +#define I2C_CLOCK_DIV_2 ((uint16_t)0x1) +#define I2C_CLOCK_DIV_4 ((uint16_t)0x2) +#define I2C_CLOCK_DIV_8 ((uint16_t)0x3) +/** \} */ +#define IS_I2C_DIV(DIV) (((DIV) == I2C_CLOCK_DIV_1) || \ + ((DIV) == I2C_CLOCK_DIV_2) || \ + ((DIV) == I2C_CLOCK_DIV_4) || \ + ((DIV) == I2C_CLOCK_DIV_8)) +/** + * \defgroup SPI_Clock_Divider SPI Clock Divider + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define SPI_CLOCK_DIV_1 ((uint16_t)0x0) +#define SPI_CLOCK_DIV_2 ((uint16_t)0x1) +#define SPI_CLOCK_DIV_4 ((uint16_t)0x2) +#define SPI_CLOCK_DIV_8 ((uint16_t)0x3) +/** \} */ +#define IS_SPI_DIV(DIV) (((DIV) == SPI_CLOCK_DIV_1) || \ + ((DIV) == SPI_CLOCK_DIV_2) || \ + ((DIV) == SPI_CLOCK_DIV_4) || \ + ((DIV) == SPI_CLOCK_DIV_8)) + +/** + * \defgroup UART_Clock_Divider UART Clock Divider + * \{ + * \ingroup RCC_Exported_Constants + */ + +#define UART_CLOCK_DIV_1 ((uint16_t)0x0) +#define UART_CLOCK_DIV_2 ((uint16_t)0x1) +#define UART_CLOCK_DIV_4 ((uint16_t)0x2) +#define UART_CLOCK_DIV_16 ((uint16_t)0x3) +/** \} */ +#define IS_UART_DIV(DIV) (((DIV) == UART_CLOCK_DIV_1) || \ + ((DIV) == UART_CLOCK_DIV_2) || \ + ((DIV) == UART_CLOCK_DIV_4) || \ + ((DIV) == UART_CLOCK_DIV_16)) +/** + * \defgroup TIM_Clock_Divider TIM Clock Divider + * \{ + * \ingroup RCC_Exported_Constants + */ + + +#define TIM_CLOCK_DIV_1 0x00 +#define TIM_CLOCK_DIV_125 0x03 +#define TIM_CLOCK_DIV_2 0x04 +#define TIM_CLOCK_DIV_4 0x05 +#define TIM_CLOCK_DIV_8 0x06 +#define TIM_CLOCK_DIV_40 0x07 +/** \} */ +#define IS_TIM_DIV(DIV) (((DIV) == TIM_CLOCK_DIV_1) || \ + ((DIV) == TIM_CLOCK_DIV_125) || \ + ((DIV) == TIM_CLOCK_DIV_2) || \ + ((DIV) == TIM_CLOCK_DIV_4) || \ + ((DIV) == TIM_CLOCK_DIV_8) || \ + ((DIV) == TIM_CLOCK_DIV_40)) + +/** + * \defgroup TIM_Clock_Divider TIM Clock Divider + * \{ + * \ingroup RCC_Exported_Constants + */ + +typedef enum +{ + TIM_CLK_2 = 2, + TIM_CLK_3, + TIM_CLK_4, + TIM_CLK_5, + TIMENH_CLK_0, + TIMENH_CLK_1, +} E_TIM_NUM; + +#define TIM0_CLK 0x00 +#define TIM_CLOCK_DIV_125 0x03 +#define TIM_CLOCK_DIV_2 0x04 +#define TIM_CLOCK_DIV_4 0x05 +#define TIM_CLOCK_DIV_8 0x06 +#define TIM_CLOCK_DIV_40 0x07 +/** \} */ +#define IS_TIM_DIV(DIV) (((DIV) == TIM_CLOCK_DIV_1) || \ + ((DIV) == TIM_CLOCK_DIV_125) || \ + ((DIV) == TIM_CLOCK_DIV_2) || \ + ((DIV) == TIM_CLOCK_DIV_4) || \ + ((DIV) == TIM_CLOCK_DIV_8) || \ + ((DIV) == TIM_CLOCK_DIV_40)) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup RCC_Exported_Functions Peripheral APIs + * \ingroup RCC + * \{ + */ + +/** + * \brief Enables or disables the APB peripheral clock. + * \param APBPeriph: Specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * \arg APBPeriph_ADC + * \arg APBPeriph_CODEC + * \arg APBPeriph_GDMA + * \arg APBPeriph_GPIO + * \arg APBPeriph_I2C1 + * \arg APBPeriph_I2C0 + * \arg APBPeriph_I2S0 + * \arg APBPeriph_I2S1 + * \arg APBPeriph_IF8080 + * \arg APBPeriph_IR + * \arg APBPeriph_KEYSCAN + * \arg APBPeriph_QDEC + * \arg APBPeriph_SPI2W + * \arg APBPeriph_SPI1 + * \arg APBPeriph_SPI0 + * \arg APBPeriph_TIMER + * \arg APBPeriph_UART0 + * \arg APBPeriph_UART1 + * \arg APBPeriph_UART2 + * \param APBPeriph_Clock: Specifies the APB peripheral clock config. + * This parameter can be one of the following values(must be the same with APBPeriph): + * \arg APBPeriph_ADC_CLOCK + * \arg APBPeriph_CODEC_CLOCK + * \arg APBPeriph_GDMA_CLOCK + * \arg APBPeriph_GPIO_CLOCK + * \arg APBPeriph_I2C1_CLOCK + * \arg APBPeriph_I2C0_CLOCK + * \arg APBPeriph_I2S0_CLOCK + * \arg APBPeriph_I2S1_CLOCK + * \arg APBPeriph_IR_CLOCK + * \arg APBPeriph_KEYSCAN_CLOCK + * \arg APBPeriph_QDEC_CLOCK + * \arg APBPeriph_SPI1_CLOCK + * \arg APBPeriph_SPI0_CLOCK + * \arg APBPeriph_SPI2W_CLOCK + * \arg APBPeriph_TIMER_CLOCK + * \arg APBPeriph_UART0_CLOCK + * \arg APBPeriph_UART1_CLOCK + * \arg APBPeriph_UART2_CLOCK + * \param NewState: New state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * \retval None. + */ +void RCC_PeriphClockCmd(uint32_t APBPeriph, uint32_t APBPeriph_Clock, + FunctionalState NewState); +/** + * \brief I2C clock divider config. + * \param I2Cx: Where x can be 0 or 1 to select the I2C peripheral. + * \param ClockDiv: Specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * \arg I2C_CLOCK_DIV_1 + * \arg I2C_CLOCK_DIV_2 + * \arg I2C_CLOCK_DIV_4 + * \arg I2C_CLOCK_DIV_8 + * \retval None. + */ +void RCC_I2CClkDivConfig(I2C_TypeDef *I2Cx, uint16_t ClockDiv); + +/** + * \brief SPI clock divider config. + * \param SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param ClockDiv: Specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * \arg SPI_CLOCK_DIV_1 + * \arg SPI_CLOCK_DIV_2 + * \arg SPI_CLOCK_DIV_4 + * \arg SPI_CLOCK_DIV_8 + * \retval None. + */ +void RCC_SPIClkDivConfig(SPI_TypeDef *SPIx, uint16_t ClockDiv); + +/** + * @brief TIMER & ENH-TIMER clock divider config. + * @param TIMx: selected TIM number. + * @param ClockDiv: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg TIM_CLOCK_DIV_1 + * @arg TIM_CLOCK_DIV_125 + * @arg TIM_CLOCK_DIV_2 + * @arg TIM_CLOCK_DIV_4 + * @arg TIM_CLOCK_DIV_8 + * @arg TIM_CLOCK_DIV_40 + * @retval None + */ +void RCC_TIMClkDivConfig(E_TIM_NUM TIMx, uint16_t ClockDiv); + +/** + * \brief UART clock divider config. + * \param UARTx: Selected UART peripheral. + * \param ClockDiv: Specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * \arg UART_CLOCK_DIV_1 + * \arg UART_CLOCK_DIV_2 + * \arg UART_CLOCK_DIV_4 + * \arg UART_CLOCK_DIV_16 + * \retval None. + */ +void RCC_UARTClkDivConfig(UART_TypeDef *UARTx, uint16_t ClockDiv); + +/** + * \brief Enables or disables the APB peripheral function. + * \param APBPeriph: Specifies the APB peripheral . + * This parameter can be one of the following values: + * \arg APBPeriph_ADC + * \arg APBPeriph_CODEC + * \arg APBPeriph_GDMA + * \arg APBPeriph_GPIO + * \arg APBPeriph_I2C1 + * \arg APBPeriph_I2C0 + * \arg APBPeriph_I2S0 + * \arg APBPeriph_I2S1 + * \arg APBPeriph_IF8080 + * \arg APBPeriph_IR + * \arg APBPeriph_KEYSCAN + * \arg APBPeriph_QDEC + * \arg APBPeriph_SPI2W + * \arg APBPeriph_SPI1 + * \arg APBPeriph_SPI0 + * \arg APBPeriph_TIMER + * \arg APBPeriph_UART0 + * \arg APBPeriph_UART1 + * \arg APBPeriph_UART2 + * \param NewState: New state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * \retval None. + */ +void RCC_PeriFunctionConfig(uint32_t APBPeriph, FunctionalState NewState); + +/** + * \brief Enables or disables the APB peripheral clock. + * \param APBPeriph_Clock: Specifies the APB peripheral clock config. + * This parameter can be one of the following values(must be the same with APBPeriph): + * \arg APBPeriph_ADC_CLOCK + * \arg APBPeriph_CODEC_CLOCK + * \arg APBPeriph_GDMA_CLOCK + * \arg APBPeriph_GPIO_CLOCK + * \arg APBPeriph_I2C1_CLOCK + * \arg APBPeriph_I2C0_CLOCK + * \arg APBPeriph_I2S0_CLOCK + * \arg APBPeriph_I2S1_CLOCK + * \arg APBPeriph_IR_CLOCK + * \arg APBPeriph_KEYSCAN_CLOCK + * \arg APBPeriph_QDEC_CLOCK + * \arg APBPeriph_SPI1_CLOCK + * \arg APBPeriph_SPI0_CLOCK + * \arg APBPeriph_SPI2W_CLOCK + * \arg APBPeriph_TIMER_CLOCK + * \arg APBPeriph_UART0_CLOCK + * \arg APBPeriph_UART1_CLOCK + * \arg APBPeriph_UART2_CLOCK + * \param NewState: New state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * \retval None. + */ +void RCC_PeriClockConfig(uint32_t APBPeriph_Clock, FunctionalState NewState); + +/** + * \brief Enable clock 5M source. + * \param None. + * \return None. + */ +__STATIC_INLINE void RCC_ClockSrc5MCmd(void) +{ + /*Open 5M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29; +} + +/** + * \brief Enable clock 10M source. + * \param None. + * \return None. + */ +__STATIC_INLINE void RCC_ClockSrc10MCmd(void) +{ + /*Open 10M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28; +} + +/** + * \brief Enable clock 20M source. + * \param None. + * \return None. + */ +__STATIC_INLINE void RCC_ClockSrc20MCmd(void) +{ + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; +} + +/** \} */ /* End of group RCC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_RCC_H_ */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor *****END OF FILE****/ + + + diff --git a/inc/peripheral/rtl876x_rtc.h b/inc/peripheral/rtl876x_rtc.h new file mode 100644 index 0000000..7334d3c --- /dev/null +++ b/inc/peripheral/rtl876x_rtc.h @@ -0,0 +1,1061 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_rtc.h +* \brief The header file of the peripheral RTC driver. +* \details This file provides all RTC firmware functions. +* \author yuan +* \date 2020-06-01 +* \version v2.1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_RTC_H_ +#define _RTL876X_RTC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup RTC RTC + * + * \brief Manage the RTC peripheral functions. + * + * \ingroup IO + */ + + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" +#include "rtl876x_alias.h" + + +/*============================================================================* + * Registers Definitions + *============================================================================*/ + +/* Peripheral: RTC */ +/* Description: Real time counter register defines */ + +/* Register: CR0 */ +/* Description: RTC Control Register 0. Offset: 0x00. Address: 0x40000100. */ + +/* CR0[31] :RTC_RST. Enable interrupt signal to MCU. 0x1: Enable. 0x0: Disable. */ +#define RTC_RST_Pos (31UL) +#define RTC_RST_Msk (0x1UL << RTC_RST_Pos) +#define RTC_RST_CLR (~(RTC_RST_Msk)) + +/* CR0[30] :RTC_NV_EN. Enable interrupt signal to MCU. 0x1: Enable. 0x0: Disable. */ +#define RTC_NV_EN_Pos (30UL) +#define RTC_NV_EN_Msk (0x1UL << RTC_NV_EN_Pos) +#define RTC_NV_EN_CLR (~(RTC_NV_EN_Msk)) + +/* CR0[29] :RTC_WAKEUP_EN. Enable wakeup signal to AON register. 0x1: Enable. 0x0: Disable. */ +#define RTC_WAKEUP_EN_Pos (29UL) +#define RTC_WAKEUP_EN_Msk (0x1UL << RTC_WAKEUP_EN_Pos) +#define RTC_WAKEUP_EN_CLR (~(RTC_WAKEUP_EN_Msk)) + +/* CR0[23] :RTC_COMP3_WAKEUP_EN. Enable or disable compare3 wakeup function. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP3_WAKEUP_EN_Pos (23UL) +#define RTC_COMP3_WAKEUP_EN_Msk (0x1UL << RTC_COMP3_WAKEUP_EN_Pos) +#define RTC_COMP3_WAKEUP_EN_Clr (~(RTC_COMP3_WAKEUP_EN_Msk)) + +/* CR0[22] :RTC_INT_EN. Enable or disable compare2 wakeup function. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP2_WAKEUP_EN_Pos (22UL) +#define RTC_COMP2_WAKEUP_EN_Msk (0x1UL << RTC_COMP2_WAKEUP_EN_Pos) +#define RTC_COMP2_WAKEUP_EN_Clr (~(RTC_COMP2_WAKEUP_EN_Msk)) + +/* CR0[21] :RTC_INT_EN. Enable or disable compare1 wakeup function. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP1_WAKEUP_EN_Pos (21UL) +#define RTC_COMP1_WAKEUP_EN_Msk (0x1UL << RTC_COMP1_WAKEUP_EN_Pos) +#define RTC_COMP1_WAKEUP_EN_Clr (~(RTC_COMP1_WAKEUP_EN_Msk)) + +/* CR0[20] :RTC_INT_EN. Enable or disable compare0 wakeup function. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP0_WAKEUP_EN_Pos (20UL) +#define RTC_COMP0_WAKEUP_EN_Msk (0x1UL << RTC_COMP0_WAKEUP_EN_Pos) +#define RTC_COMP0_WAKEUP_EN_Clr (~(RTC_COMP0_WAKEUP_EN_Msk)) + +/* CR0[19] :RTC_INT_EN. Enable or disable compare3 interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_COMP3_EN_Pos (19UL) +#define RTC_INT_COMP3_EN_Msk (0x1UL << RTC_INT_COMP3_EN_Pos) +#define RTC_INT_COMP3_EN_Clr (~(RTC_INT_COMP3_EN_Msk)) + +/* CR0[18] :RTC_INT_EN. Enable or disable compare2 interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_COMP2_EN_Pos (18UL) +#define RTC_INT_COMP2_EN_Msk (0x1UL << RTC_INT_COMP2_EN_Pos) +#define RTC_INT_COMP2_EN_Clr (~(RTC_INT_COMP2_EN_Msk)) + +/* CR0[17] :RTC_INT_EN. Enable or disable compare1 interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_COMP1_EN_Pos (17UL) +#define RTC_INT_COMP1_EN_Msk (0x1UL << RTC_INT_COMP1_EN_Pos) +#define RTC_INT_COMP1_EN_Clr (~(RTC_INT_COMP1_EN_Msk)) + +/* CR0[16] :RTC_INT_EN. Enable or disable compare0 interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_COMP0_EN_Pos (16UL) +#define RTC_INT_COMP0_EN_Msk (0x1UL << RTC_INT_COMP0_EN_Pos) +#define RTC_INT_COMP0_EN_Clr (~(RTC_INT_COMP0_EN_Msk)) + +/* CR0[15] :RTC_INT_EN. Enable or disable compare3gt interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP3GT_WAKEUP_EN_Pos (15UL) +#define RTC_COMP3GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP3GT_WAKEUP_EN_Pos) +#define RTC_COMP3GT_WAKEUP_EN_Clr (~(RTC_COMP3GT_WAKEUP_EN_Msk)) + +/* CR0[14] :RTC_INT_EN. Enable or disable compare2gt interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP2GT_WAKEUP_EN_Pos (14UL) +#define RTC_COMP2GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP2GT_WAKEUP_EN_Pos) +#define RTC_COMP2GT_WAKEUP_EN_Clr (~(RTC_COMP2GT_WAKEUP_EN_Msk)) + +/* CR0[13] :RTC_INT_EN. Enable or disable compare1gt interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP1GT_WAKEUP_EN_Pos (13UL) +#define RTC_COMP1GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP1GT_WAKEUP_EN_Pos) +#define RTC_COMP1GT_WAKEUP_EN_Clr (~(RTC_COMP1GT_WAKEUP_EN_Msk)) + +/* CR0[12] :RTC_INT_EN. Enable or disable compare0gt interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_COMP0GT_WAKEUP_EN_Pos (12UL) +#define RTC_COMP0GT_WAKEUP_EN_Msk (0x1UL << RTC_COMP0GT_WAKEUP_EN_Pos) +#define RTC_COMP0GT_WAKEUP_EN_Clr (~(RTC_COMP0GT_WAKEUP_EN_Msk)) + +/* CR0[11] :RTC_INT_EN. Enable or disable prescale & comp3 interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_PRE_COMP3_EN_Pos (11UL) +#define RTC_INT_PRE_COMP3_EN_Msk (0x1UL << RTC_INT_PRE_COMP3_EN_Pos) +#define RTC_INT_PRE_COMP3_EN_Clr (~(RTC_INT_PRE_COMP3_EN_Msk)) + +/* CR0[10] :RTC_INT_EN. Enable or disable prescale comp interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_PRE_COMP_EN_Pos (10UL) +#define RTC_INT_PRE_COMP_EN_Msk (0x1UL << RTC_INT_PRE_COMP_EN_Pos) +#define RTC_INT_PRE_COMP_EN_Clr (~(RTC_INT_PRE_COMP_EN_Msk)) + +/* CR0[9] :RTC_MASK_TICK_INT. Mask RTC tick interrupt. 0x1: Unmask. 0x0: Mask. */ +#define RTC_INT_OVERFLOW_EN_Pos (9UL) +#define RTC_INT_OVERFLOW_EN_Msk (0x1UL << RTC_INT_OVERFLOW_EN_Pos) +#define RTC_INT_OVERFLOW_EN_Clr (~(RTC_INT_OVERFLOW_EN_Msk)) + +/* CR0[8] :RTC_INT_EN. Enable or disable tick interrupt. 0x1: Enable. 0x0: Disable. */ +#define RTC_INT_TICK_EN_Pos (8UL) +#define RTC_INT_TICK_EN_Msk (0x1UL << RTC_INT_TICK_EN_Pos) +#define RTC_INT_TICK_EN_Clr (~(RTC_INT_TICK_EN_Msk)) + +/* CR0[2] :RTC_PRE_COUNTER_RST. Reset Prescale Counter. 0x1: Reset Counter to 0. */ +#define RTC_PRE_COUNTER_RST_Pos (2UL) +#define RTC_PRE_COUNTER_RST_Msk (0x1UL << RTC_PRE_COUNTER_RST_Pos) +#define RTC_PRE_COUNTER_RST_CLR (~(RTC_PRE_COUNTER_RST_Msk)) + +/* CR0[1] :RTC_COUNTER_RST. Reset 24bit-RTC Counter. 0x1: Reset Counter to 0. */ +#define RTC_COUNTER_RST_Pos (1UL) +#define RTC_COUNTER_RST_Msk (0x1UL << RTC_COUNTER_RST_Pos) +#define RTC_COUNTER_RST_CLR (~(RTC_COUNTER_RST_Msk)) + +/* CR0[0] :RTC_START. Start or stop RTC 24bit-RTC Counter. 0x1: Start 24bit-RTC Counter.0x0: Stop 24bit-RTC Counter. */ +#define RTC_START_Pos (0UL) +#define RTC_START_Msk (0x1UL << RTC_START_Pos) +#define RTC_START_CLR (~(RTC_START_Msk)) + +/* Register: INT_CLR */ +/* Description: Interrupt clear register. Offset: 0x04. Address: 0x40000104. */ + +/* INT_CLR[15] :RTC_COMP3_WK_CLR. Clear Interrupt Status of Comparator1. */ +/* This status is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP3_WK_CLR_Pos (15UL) +#define RTC_COMP3_WK_CLR_SET (0x1UL << RTC_COMP3_WK_CLR_Pos) +#define RTC_COMP3_WK_CLR_RESET (~(RTC_COMP3_WK_CLR_SET)) + +/* INT_CLR[14] :RTC_COMP2_WK_CLR. Clear Interrupt Status of Comparator1. */ +/* This status is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP2_WK_CLR_Pos (14UL) +#define RTC_COMP2_WK_CLR_SET (0x1UL << RTC_COMP2_WK_CLR_Pos) +#define RTC_COMP2_WK_CLR_RESET (~(RTC_COMP2_WK_CLR_SET)) + +/* INT_CLR[13] :RTC_COMP1_WK_CLR. Clear Interrupt Status of Comparator1. */ +/* This status is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP1_WK_CLR_Pos (13UL) +#define RTC_COMP1_WK_CLR_SET (0x1UL << RTC_COMP1_WK_CLR_Pos) +#define RTC_COMP1_WK_CLR_RESET (~(RTC_COMP1_WK_CLR_SET)) + +/* INT_CLR[12] :RTC_COMP0_WK_CLR. Clear Interrupt Status of Comparator0. */ +/* This status is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP0_WK_CLR_Pos (12UL) +#define RTC_COMP0_WK_CLR_SET (0x1UL << RTC_COMP0_WK_CLR_Pos) +#define RTC_COMP0_WK_CLR_RESET (~(RTC_COMP0_WK_CLR_SET)) + +/* INT_CLR[11] :RTC_COMP3_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP3_CLR_Pos (11UL) +#define RTC_COMP3_CLR_SET (0x1UL << RTC_COMP3_CLR_Pos) +#define RTC_COMP3_CLR_RESET (~(RTC_COMP3_CLR_SET)) + +/* INT_CLR[10] :RTC_COMP2_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP2_CLR_Pos (10UL) +#define RTC_COMP2_CLR_SET (0x1UL << RTC_COMP2_CLR_Pos) +#define RTC_COMP2_CLR_RESET (~(RTC_COMP2_CLR_SET)) + +/* INT_CLR[9] :RTC_COMP1_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP1_CLR_Pos (9UL) +#define RTC_COMP1_CLR_SET (0x1UL << RTC_COMP1_CLR_Pos) +#define RTC_COMP1_CLR_RESET (~(RTC_COMP1_CLR_SET)) + +/* INT_CLR[8] :RTC_COMP0_CLR. Clear Interrupt Status of Comparator0. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP0_CLR_Pos (8UL) +#define RTC_COMP0_CLR_SET (0x1UL << RTC_COMP0_CLR_Pos) +#define RTC_COMP0_CLR_RESET (~(RTC_COMP0_CLR_SET)) + +/* INT_CLR[7] :RTC_COMP3_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP3GT_CLR_Pos (7UL) +#define RTC_COMP3GT_CLR_SET (0x1UL << RTC_COMP3GT_CLR_Pos) +#define RTC_COMP3GT_CLR_RESET (~(RTC_COMP3GT_CLR_SET)) + +/* INT_CLR[6] :RTC_COMP2GT_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP2GT_CLR_Pos (6UL) +#define RTC_COMP2GT_CLR_SET (0x1UL << RTC_COMP2GT_CLR_Pos) +#define RTC_COMP2GT_CLR_RESET (~(RTC_COMP2GT_CLR_SET)) + +/* INT_CLR[5] :RTC_COMP1GT_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP1GT_CLR_Pos (5UL) +#define RTC_COMP1GT_CLR_SET (0x1UL << RTC_COMP1GT_CLR_Pos) +#define RTC_COMP1GT_CLR_RESET (~(RTC_COMP1GT_CLR_SET)) + +/* INT_CLR[4] :RTC_COMP0GT_CLR. Clear Interrupt Status of Comparator0. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_COMP0GT_CLR_Pos (4UL) +#define RTC_COMP0GT_CLR_SET (0x1UL << RTC_COMP0GT_CLR_Pos) +#define RTC_COMP0GT_CLR_RESET (~(RTC_COMP0GT_CLR_SET)) + +/* INT_CLR[3] :RTC_PRE_COMP3_CLR. Clear Interrupt Status of prescale and prescale_comp3. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_PRE_COMP3_CLR_Pos (3UL) +#define RTC_PRE_COMP3_CLR_SET (0x1UL << RTC_PRE_COMP3_CLR_Pos) +#define RTC_PRE_COMP3_CLR_RESET (~(RTC_PRE_COMP3_CLR_SET)) + +/* INT_CLR[6] :RTC_PRE_COMP_CLR. Clear Interrupt Status of Comparator1. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_PRE_COMP_CLR_Pos (2UL) +#define RTC_PRE_COMP_CLR_SET (0x1UL << RTC_PRE_COMP_CLR_Pos) +#define RTC_PRE_COMP_CLR_RESET (~(RTC_PRE_COMP_CLR_SET)) + +/* INT_CLR[1] :RTC_OVERFLOW_CLR. Clear Interrupt Status of Overflow. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_OVERFLOW_CLR_Pos (1UL) +#define RTC_OVERFLOW_CLR_SET (0x1UL << RTC_OVERFLOW_CLR_Pos) +#define RTC_OVERFLOW_CLR_RESET (~(RTC_OVERFLOW_CLR_SET)) + +/* INT_CLR[0] :RTC_TICK_CLR. Clear Interrupt Status of Tick. */ +/* This interrupt is cleared by software.write 1 then write 0 after 2T to clear. */ +#define RTC_TICK_CLR_Pos (0UL) +#define RTC_TICK_CLR_SET (0x1UL << RTC_TICK_CLR_Pos) +#define RTC_TICK_CLR_RESET (~(RTC_TICK_CLR_SET)) + +#define RTC_COMP_INT_EN_OFFSET (RTC_INT_COMP0_EN_Pos - RTC_COMP0_CLR_Pos) +#define RTC_PRE_COMP_INT_EN_OFFSET (RTC_INT_PRE_COMP_EN_Pos - RTC_PRE_COMP_CLR_Pos) + + +/* Clear all interrupt */ +#define RTC_ALL_INT_CLR_SET (RTC_PRE_COMP3_CLR_SET | RTC_PRE_COMP_CLR_SET | \ + RTC_COMP3_CLR_SET | RTC_COMP2_CLR_SET | \ + RTC_COMP1_CLR_SET | RTC_COMP0_CLR_SET | \ + RTC_OVERFLOW_CLR_SET | RTC_TICK_CLR_SET) + +/* Clear all wakeup */ +#define RTC_ALL_WAKEUP_CLR_SET (RTC_COMP3_WK_CLR_SET | RTC_COMP2_WK_CLR_SET | \ + RTC_COMP1_WK_CLR_SET | RTC_COMP0_WK_CLR_SET | \ + RTC_COMP3GT_CLR_SET | RTC_COMP2GT_CLR_SET | \ + RTC_COMP1GT_CLR_SET | RTC_COMP0GT_CLR_SET) + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup RTC_Exported_Constants Macro Definitions + * + * \ingroup RTC + */ + +/** + * \defgroup RTC_Interrupts_Definition RTC Interrupts Definition + * \{ + * \ingroup RTC_Exported_Constants + */ +typedef enum +{ + RTC_INT_TICK = RTC_INT_TICK_EN_Msk, + RTC_INT_OVF = RTC_INT_OVERFLOW_EN_Msk, + RTC_INT_PRE_COMP = RTC_INT_PRE_COMP_EN_Msk, + RTC_INT_PRE_COMP3 = RTC_INT_PRE_COMP3_EN_Msk, + RTC_INT_COMP0 = RTC_INT_COMP0_EN_Msk, + RTC_INT_COMP1 = RTC_INT_COMP1_EN_Msk, + RTC_INT_COMP2 = RTC_INT_COMP2_EN_Msk, + RTC_INT_COMP3 = RTC_INT_COMP3_EN_Msk, +} E_RTC_INT; + +/** \} */ + +#define IS_RTC_INT(INT) (((INT) == RTC_INT_TICK) || \ + ((INT) == RTC_INT_OVF) || \ + ((INT) == RTC_INT_COMP0) || \ + ((INT) == RTC_INT_COMP1) || \ + ((INT) == RTC_INT_COMP2) || \ + ((INT) == RTC_INT_COMP3) || \ + ((INT) == RTC_INT_PRE_COMP) || \ + ((INT) == RTC_INT_PRE_COMP3)) + +/** + * \defgroup RTC_Wakeup_Definition RTC Wakeup Definition + * \{ + * \ingroup RTC_Exported_Constants + */ +typedef enum +{ + RTC_WK_TICK = RTC_INT_TICK_EN_Msk, + RTC_WK_OVF = RTC_INT_OVERFLOW_EN_Msk, + RTC_WK_PRE_COMP = RTC_INT_PRE_COMP_EN_Msk, + RTC_WK_PRE_COMP3 = RTC_INT_PRE_COMP3_EN_Msk, + RTC_WK_COMP0GT = RTC_COMP0GT_WAKEUP_EN_Msk, + RTC_WK_COMP1GT = RTC_COMP1GT_WAKEUP_EN_Msk, + RTC_WK_COMP2GT = RTC_COMP2GT_WAKEUP_EN_Msk, + RTC_WK_COMP3GT = RTC_COMP3GT_WAKEUP_EN_Msk, + RTC_WK_COMP0 = RTC_COMP0_WAKEUP_EN_Msk, + RTC_WK_COMP1 = RTC_COMP1_WAKEUP_EN_Msk, + RTC_WK_COMP2 = RTC_COMP2_WAKEUP_EN_Msk, + RTC_WK_COMP3 = RTC_COMP3_WAKEUP_EN_Msk, +} E_RTC_WK; + +/** \} */ + +#define IS_RTC_WK(WK) (((WK) == RTC_WK_TICK) || \ + ((WK) == RTC_WK_OVF) || \ + ((WK) == RTC_WK_PRE_COMP) || \ + ((WK) == RTC_WK_PRE_COMP3) || \ + ((WK) == RTC_WK_COMP0GT) || \ + ((WK) == RTC_WK_COMP1GT) || \ + ((WK) == RTC_WK_COMP2GT) || \ + ((WK) == RTC_WK_COMP3GT) || \ + ((WK) == RTC_WK_COMP0) || \ + ((WK) == RTC_WK_COMP1) || \ + ((WK) == RTC_WK_COMP2) || \ + ((WK) == RTC_WK_COMP3)) + +/** + * \defgroup RTC_Comp_Definition RTC Comparator Definition + * \{ + * \ingroup RTC_Exported_Constants + */ +typedef enum +{ + RTC_COMP0 = 0, + RTC_COMP1, + RTC_COMP2, + RTC_COMP3, +} E_RTC_COMP_INDEX; + +/** \} */ + +#define IS_RTC_COMP(COMP) (((COMP) == RTC_COMP0) || \ + ((COMP) == RTC_COMP1) || \ + ((COMP) == RTC_COMP2) || \ + ((COMP) == RTC_COMP3)) + +/** + * \defgroup RTC_CompGT_Definition RTC ComparatorGT Definition + * \{ + * \ingroup RTC_Exported_Constants + */ +typedef enum +{ + RTC_COMP0GT = 0, + RTC_COMP1GT, + RTC_COMP2GT, + RTC_COMP3GT, +} E_RTC_COMPGT_INDEX; + +/** \} */ + +/** + * \defgroup RTC_32K_Selction RTC Selction + * \{ + * \ingroup RTC_Exported_Constants + */ +typedef enum +{ + RTC_32K_XI, + RTC_32k_P2_4, + RTC_32K_GPIO_MAX, +} +RTC_32K_GPIO_IN; + +#define IS_RTC_32K(GPIO) (((GPIO) == RTC_32K_XI) || \ + ((GPIO) == RTC_32k_P2_4) || \ + ((GPIO) == RTC_32K_GPIO_MAX)) +/** \} */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup RTC_Exported_Functions Peripheral APIs + * \{ + * \ingroup RTC + */ + +/** + * \brief Fast write RTC register,internal function. + * \param[in] regAddress: The register address. + * \param[in] data: Data which write to register. + * \return None. + */ +void RTC_WriteReg(uint32_t regAddress, uint32_t data); + +/** + * \brief Deinitializes the RTC peripheral registers to their default reset values(turn off clock). + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * } + * \endcode + */ +void RTC_DeInit(void); + +/** + * \brief Set RTC prescaler value. + * \param[in] value: The prescaler value to be set.Should be no more than 12 bits! + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_SetPrescaler(uint16_t value); + +/** + * \brief Start or stop RTC peripheral. + * \param[in] NewState: New state of RTC peripheral. + * This parameter can be one of the following values: + * \arg ENABLE: Start RTC. + * \arg DISABLE: Stop RTC. + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_Cmd(FunctionalState NewState); + +/** + * \brief Enable or disable the specified RTC interrupt source. + * \param[in] RTC_INT: Specifies the RTC interrupt source which to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg RTC_INT_TICK: Tick interrupt source. + * \arg RTC_INT_OVF: counter overflow interrupt + * \arg RTC_INT_COMP0: Compare 0 interrupt source. + * \arg RTC_INT_COMP1: Compare 1 interrupt source. + * \arg RTC_INT_COMP2: Compare 2 interrupt source. + * \arg RTC_INT_COMP3: Compare 3 interrupt source. + * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source. + * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source. + * \param[in] NewState: New state of the specified RTC interrupt. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_INTConfig(E_RTC_INT RTC_INT, FunctionalState NewState); + +/** + * \brief Enable or disable the specified RTC wakeup function. + * \param RTC_WK: specifies the RTC wakeup function to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg RTC_WK_TICK: tick wakeup function + * \arg RTC_WK_OVF: tick wakeup function + * \arg RTC_WK_PRE_CMP: prescale compare wakeup function + * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * \arg RTC_WK_CMP0: compare 0 wakeup function + * \arg RTC_WK_CMP1: compare 1 wakeup function + * \arg RTC_WK_CMP2: compare 2 wakeup function + * \arg RTC_WK_CMP3: compare 3 wakeup function + * \param NewState: new state of the specified RTC wakeup function. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_WKConfig(E_RTC_WK RTC_WK, FunctionalState NewState); + +/** + * \brief Enable RTC interrupt signal to CPU NVIC. + * \param[in] NewState: Enable or disable RTC interrupt signal to MCU. + * This parameter can be: ENABLE or DISABLE.. + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_NvCmd(FunctionalState NewState); + +/** + * \brief Enable or disable system wake up function of RTC. + * \param[in] NewState: new state of the wake up function. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_SystemWakeupConfig(ENABLE); + * } + * \endcode + */ +void RTC_SystemWakeupConfig(FunctionalState NewState); + +/** + * \brief Reset counter value of RTC. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ResetCounter(); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_ResetCounter(void); + +/** + * \brief Reset prescaler counter value of RTC. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ResetPrescalerCounter(); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +void RTC_ResetPrescalerCounter(void); + +/** + * \brief Check whether the specified RTC interrupt is set. + * \param[in] RTC_INT: Specifies the RTC interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg RTC_INT_TICK: RTC tick interrupt source. + * \arg RTC_INT_COMP0: Compare 0 interrupt source. + * \arg RTC_INT_COMP1: Compare 1 interrupt source. + * \arg RTC_INT_COMP2: Compare 2 interrupt source. + * \arg RTC_INT_COMP3: Compare 3 interrupt source. + * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source. + * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source. + * \return The new state of RTC_INT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * ITStatus int_status = RTC_GetINTStatus(RTC_INT_COMP0); + * } + * \endcode + */ +ITStatus RTC_GetINTStatus(E_RTC_INT RTC_INT); + +/** + * \brief Clear the interrupt pending bits of RTC. + * \param[in] RTC_INT: specifies the RTC interrupt flag to clear. + * This parameter can be any combination of the following values: + * \arg RTC_INT_TICK: RTC tick interrupt source. + * \arg RTC_INT_OVF: RTC counter overflow interrupt source. + * \arg RTC_INT_COMP0: Compare 0 interrupt source. + * \arg RTC_INT_COMP1: Compare 1 interrupt source. + * \arg RTC_INT_COMP2: Compare 2 interrupt source. + * \arg RTC_INT_COMP3: Compare 3 interrupt source. + * \arg RTC_INT_PRE_COMP: Prescale compare interrupt source. + * \arg RTC_INT_PRE_COMP3: Prescale & compare 3 interrupt source. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ClearINTPendingBit(RTC_INT_COMP0); + * } + * \endcode + */ +void RTC_ClearINTPendingBit(E_RTC_INT RTC_INT); + +/** + * \brief Checks whether the specified RTC wakeup state is set or not. + * \param RTC_WK: specifies the RTC interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg RTC_WK_TICK: tick wakeup function + * \arg RTC_WK_OVF: tick wakeup function + * \arg RTC_WK_PRE_CMP: prescale compare wakeup function + * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * \arg RTC_WK_CMP0: compare 0 wakeup function + * \arg RTC_WK_CMP1: compare 1 wakeup function + * \arg RTC_WK_CMP2: compare 2 wakeup function + * \arg RTC_WK_CMP3: compare 3 wakeup function + * \return The new state of RTC_INT (SET or RESET). + */ +ITStatus RTC_GetWakeupStatus(E_RTC_WK RTC_WK); + +/** + * \brief Clear the wakeup status bits of RTC. + * \param RTC_WK: specifies the RTC wakeup flag to clear. + * This parameter can be any combination of the following values: + * \arg RTC_WK_TICK: tick wakeup function + * \arg RTC_WK_OVF: tick wakeup function + * \arg RTC_WK_PRE_CMP: prescale compare wakeup function + * \arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * \arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * \arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * \arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * \arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * \arg RTC_WK_CMP0: compare 0 wakeup function + * \arg RTC_WK_CMP1: compare 1 wakeup function + * \arg RTC_WK_CMP2: compare 2 wakeup function + * \arg RTC_WK_CMP3: compare 3 wakeup function + * \return None. + */ +void RTC_ClearWakeupStatusBit(E_RTC_WK RTC_WK); + +/** + * \brief Clear the interrupt pending bit of the select comparator of RTC. + * \param[in] index: the comparator number. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ClearCompINT(0); + * } + * \endcode + */ +void RTC_ClearCompINT(E_RTC_COMP_INDEX index); + +/** + * \brief Clear the overflow interrupt pending bit of RTC. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ClearOverFlowINT(); + * } + * \endcode + */ +void RTC_ClearOverFlowINT(void); + +/** + * \brief Clear the tick interrupt pending bit of RTC. + * \param[in] None. + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_ClearTickINT(); + * } + * \endcode + */ +void RTC_ClearTickINT(void); + +/** + * @brief Select source clock to gpio input of RTC. + * @param gpio: the selected gpio. + * @retval None + */ +void RTC_SelectSrcToGpioInput(RTC_32K_GPIO_IN rtc_in); + +/** + * \brief Set RTC comparator value. + * \param[in] index: The comparator number,can be 0 ~ 3. + * \param[in] value: The comparator value to be set.Should be no more than 24 bits! + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void RTC_SetCompValue(E_RTC_COMP_INDEX index, uint32_t value) +{ + /* Check the parameters */ + assert_param(IS_RTC_COMP(index)); + + RTC_WriteReg((uint32_t)(&(RTC->COMP0) + index), (value & 0xFFFFFFFF)); +} + +/** + * \brief Set RTC comparator GT value. + * \param[in] index: The comparator gt number, can be 0 ~ 3. + * \param[in] value: The comparator value to be set. + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE 49 + * #define RTC_COMP_INDEX RTC_COMP3 + * #define RTC_COMP_INDEX_INT RTC_INT_COMP3 + * #define RTC_COMP_VALUE (1000) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetCompValue(RTC_COMP_INDEX, RTC_COMP_VALUE); + * + * RTC_MaskINTConfig(RTC_COMP_INDEX_INT, DISABLE); + * RTC_INTConfig(RTC_COMP_INDEX_INT, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void RTC_SetCompGTValue(E_RTC_COMPGT_INDEX index, uint32_t value) +{ + /* Check the parameters */ + assert_param(IS_RTC_COMPGT(index)); + + RTC_WriteReg((uint32_t)(&(RTC->COMP0GT) + index), (value & 0xFFFFFFFF)); +} + +/** + * \brief Set RTC prescaler comparator value. + * \param[in] value: The comparator value to be set.Should be no more than 12 bits! + * \return None. + * + * Example usage + * \code{.c} + * + * #define RTC_PRESCALER_VALUE (3200 - 1)//max 4095 + * #define RTC_PRECOMP_VALUE (320)//max 4095 + * #define RTC_COMP3_VALUE (10) + * + * void driver_rtc_init(void) + * { + * RTC_DeInit(); + * + * RTC_SetPrescaler(RTC_PRESCALER_VALUE); + * RTC_SetPreCompValue(RTC_PRECOMP_VALUE); + * RTC_SetCompValue(RTC_COMP3, RTC_COMP3_VALUE); + * + * RTC_MaskINTConfig(RTC_INT_PRE_COMP3, DISABLE); + * RTC_INTConfig(RTC_INT_PRE_COMP3, ENABLE); + * + * RTC_NvCmd(ENABLE); + * RTC_Cmd(ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void RTC_SetPreCompValue(uint32_t value) +{ + RTC_WriteReg((uint32_t)(&(RTC->PRE_COMP)), (value & 0xFFF)); +} + +/** + * \brief Get counter value of RTC. + * \param[in] None. + * \return The counter value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uitn32_t counter = RTC_GetCounter(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t RTC_GetCounter(void) +{ + return RTC->CNT; +} + +/** + * \brief Get prescaler counter value of RTC. + * \param[in] None. + * \return The prescaler counter value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uitn32_t pre_counter = RTC_GetPreCounter(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t RTC_GetPreCounter(void) +{ + return RTC->PRE_CNT; +} + +/** + * \brief Get RTC comparator value. + * \param[in] index: The comparator number. + * \return The comparator value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uint32_t data = RTC_GetCompValue(RTC_COMP0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t RTC_GetCompValue(E_RTC_COMP_INDEX index) +{ + return *((volatile uint32_t *)(&(RTC->COMP0) + index)); +} + +/** + * \brief Get RTC comparator gt value. + * \param[in] index: The comparator number 0~3. + * \return The comparator value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uitn32_t data = RTC_GetCompGTValue(0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t RTC_GetCompGTValue(E_RTC_COMPGT_INDEX index) +{ + return *((volatile uint32_t *)(&(RTC->COMP0GT) + index)); +} + +/** + * \brief Get RTC prescaler comparator value. + * \param[in] None. + * \return The prescaler comparator value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uitn32_t data = RTC_GetPreCompValue(); + * } + * \endcode + */ +__STATIC_INLINE uint32_t RTC_GetPreCompValue(void) +{ + return RTC->PRE_COMP; +} + +/** + * \brief Write backup register for store time information. + * \param[in] value: valuer=write to back up reister + * \return None. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * RTC_WriteBackupReg(0x01020304); + * } + * \endcode + */ +//void RTC_WriteBackupReg(uint32_t value); +__STATIC_INLINE void RTC_WriteBackupReg(uint32_t value) +{ + RTC_WriteReg((uint32_t)(&(RTC->BACKUP)), value); +} + +/** + * \brief Read backup register. + * \param[in] None. + * \return Register value. + * + * Example usage + * \code{.c} + * + * void rtc_demo(void) + * { + * uint32_t reg_data = RTC_ReadBackupReg(); + * } + * \endcode + */ +//uint32_t RTC_ReadBackupReg(void); +__STATIC_INLINE uint32_t RTC_ReadBackupReg(void) +{ + return (RTC->BACKUP); +} + +/** \} */ /* End of group RTC_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_RTC_H_ */ + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_spi.h b/inc/peripheral/rtl876x_spi.h new file mode 100644 index 0000000..6ad0e13 --- /dev/null +++ b/inc/peripheral/rtl876x_spi.h @@ -0,0 +1,931 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_spi.h +* \brief The header file of the peripheral SPI driver. +* \details This file provides all SPI firmware functions. +* \author elliot chen +* \date 2015-5-6 +* \version v1.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_SPI_H_ +#define _RTL876X_SPI_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup SPI SPI + * + * \brief Manage the SPI peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup SPI_Exported_Types Init Params Struct + * + * \ingroup SPI + */ + +/** + * \brief SPI init structure definition. + * + * \ingroup SPI_Exported_Types + */ + +typedef struct +{ + uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of \ref SPI_Data_Direction. */ + uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of \ref SPI_Mode. */ + uint16_t SPI_DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of \ref SPI_Data_Size. */ + uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state. + This parameter can be a value of \ref SPI_Clock_Polarity */ + uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of \ref SPI_Clock_Phase */ + uint32_t SPI_SwapTxBitEn; /*!< Specifies whether to swap spi tx data bit. + This parameter can be a value of \ref SPI_Swap_Enable. + \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/ + uint32_t SPI_SwapRxBitEn; /*!< Specifies whether to swap spi rx data bit + This parameter can be a value of \ref SPI_Swap_Enable. + \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/ + uint32_t SPI_SwapTxByteEn; /*!< Specifies whether to swap spi tx data bit + This parameter can be a value of \ref SPI_Swap_Enable. + \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/ + uint32_t SPI_SwapRxByteEn; /*!< Specifies whether to swap spi rx data bit + This parameter can be a value of \ref SPI_Swap_Enable. + \note This parameter can only be configed if the SPI0 peripheral is set to Slave Mode.*/ + uint32_t SPI_ToggleEn; /*!< Specifies whether to toggle when transfer done. */ + uint32_t SPI_BaudRatePrescaler; /*!< Specifies the speed of SCK clock. SPI Clock Speed = clk source/SPI_ClkDIV + \note The communication clock is derived from the master clock. The slave clock does not need to be set. */ + uint16_t SPI_FrameFormat; /*!< Specifies which serial protocol transfers the data. + This parameter can be a value of \ref SPI_Frame_Format. */ + uint32_t SPI_TxThresholdLevel; /*!< Specifies the transmit FIFO Threshold. */ + uint32_t SPI_RxThresholdLevel; /*!< Specifies the receive FIFO Threshold. */ + uint32_t SPI_NDF; /*!< Specifies the trigger condition in EEPROM mode. + This parameter should be the value of the length of read data. */ + uint16_t SPI_TxDmaEn; /*!< Specifies the Tx dma mode. */ + uint16_t SPI_RxDmaEn; /*!< Specifies the Rx dma mode. */ + uint8_t SPI_TxWaterlevel; /*!< Specifies the DMA tx water level. */ + uint8_t SPI_RxWaterlevel; /*!< Specifies the DMA rx water level. */ + +} SPI_InitTypeDef; + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup SPI_Exported_Constants Macro Definitions + * + * \ingroup SPI + */ + +#define IS_SPI_ALL_PERIPH(PERIPH) (((PERIPH) == SPI0) || \ + ((PERIPH) == SPI1)) + +#define IS_SPI_CLOCK_SPEED(SPEED) (((SPEED) >= 0x01) && ((SPEED) <= 40000000)) + +/** + * \defgroup SPI_Data_Direction SPI Data Direction + * \{ + * \ingroup SPI_Exported_Constants + */ +#define SPI_Direction_FullDuplex ((uint16_t)0x0000) +#define SPI_Direction_TxOnly ((uint16_t)0x0001) +#define SPI_Direction_RxOnly ((uint16_t)0x0002) +#define SPI_Direction_EEPROM ((uint16_t)0x0003) +/** \} */ + +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_FullDuplex) || \ + ((MODE) == SPI_Direction_RxOnly) || \ + ((MODE) == SPI_Direction_TxOnly) || \ + ((MODE) == SPI_Direction_EEPROM)) + +/** + * \defgroup SPI_Mode SPI Mode + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_Mode_Master ((uint16_t)0x0104) +#define SPI_Mode_Slave ((uint16_t)0x0000) +/** \} */ +#define IS_SPI_MODE(MODE) (((MODE) == SPI_Mode_Master) || \ + ((MODE) == SPI_Mode_Slave)) + +/** + * \defgroup SPI_Data_Size SPI Data Size + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_DataSize_4b ((uint16_t)0x0003) +#define SPI_DataSize_5b ((uint16_t)0x0004) +#define SPI_DataSize_6b ((uint16_t)0x0005) +#define SPI_DataSize_7b ((uint16_t)0x0006) +#define SPI_DataSize_8b ((uint16_t)0x0007) +#define SPI_DataSize_9b ((uint16_t)0x0008) +#define SPI_DataSize_10b ((uint16_t)0x0009) +#define SPI_DataSize_11b ((uint16_t)0x000a) +#define SPI_DataSize_12b ((uint16_t)0x000b) +#define SPI_DataSize_13b ((uint16_t)0x000c) +#define SPI_DataSize_14b ((uint16_t)0x000d) +#define SPI_DataSize_15b ((uint16_t)0x000e) +#define SPI_DataSize_16b ((uint16_t)0x000f) +#define SPI_DataSize_17b ((uint16_t)0x0010) +#define SPI_DataSize_18b ((uint16_t)0x0011) +#define SPI_DataSize_19b ((uint16_t)0x0012) +#define SPI_DataSize_20b ((uint16_t)0x0013) +#define SPI_DataSize_21b ((uint16_t)0x0014) +#define SPI_DataSize_22b ((uint16_t)0x0015) +#define SPI_DataSize_23b ((uint16_t)0x0016) +#define SPI_DataSize_24b ((uint16_t)0x0017) +#define SPI_DataSize_25b ((uint16_t)0x0018) +#define SPI_DataSize_26b ((uint16_t)0x0019) +#define SPI_DataSize_27b ((uint16_t)0x001A) +#define SPI_DataSize_28b ((uint16_t)0x001B) +#define SPI_DataSize_29b ((uint16_t)0x001C) +#define SPI_DataSize_30b ((uint16_t)0x001D) +#define SPI_DataSize_31b ((uint16_t)0x001E) +#define SPI_DataSize_32b ((uint16_t)0x001F) +/** \} */ +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DataSize_4b) || \ + ((DATASIZE) == SPI_DataSize_5b) || \ + ((DATASIZE) == SPI_DataSize_6b) || \ + ((DATASIZE) == SPI_DataSize_7b) || \ + ((DATASIZE) == SPI_DataSize_8b) || \ + ((DATASIZE) == SPI_DataSize_9b) || \ + ((DATASIZE) == SPI_DataSize_10b) || \ + ((DATASIZE) == SPI_DataSize_11b) || \ + ((DATASIZE) == SPI_DataSize_12b) || \ + ((DATASIZE) == SPI_DataSize_13b) || \ + ((DATASIZE) == SPI_DataSize_14b) || \ + ((DATASIZE) == SPI_DataSize_15b) || \ + ((DATASIZE) == SPI_DataSize_16b) || \ + ((DATASIZE) == SPI_DataSize_17b) || \ + ((DATASIZE) == SPI_DataSize_18b) || \ + ((DATASIZE) == SPI_DataSize_19b) || \ + ((DATASIZE) == SPI_DataSize_20b) || \ + ((DATASIZE) == SPI_DataSize_21b) || \ + ((DATASIZE) == SPI_DataSize_22b) || \ + ((DATASIZE) == SPI_DataSize_23b) || \ + ((DATASIZE) == SPI_DataSize_24b) || \ + ((DATASIZE) == SPI_DataSize_25b) || \ + ((DATASIZE) == SPI_DataSize_26b) || \ + ((DATASIZE) == SPI_DataSize_27b) || \ + ((DATASIZE) == SPI_DataSize_28b) || \ + ((DATASIZE) == SPI_DataSize_29b) || \ + ((DATASIZE) == SPI_DataSize_30b) || \ + ((DATASIZE) == SPI_DataSize_31b) || \ + ((DATASIZE) == SPI_DataSize_32b)) + +/** + * \defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler Value + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_BaudRatePrescaler_2 ((uint32_t)0x0002) +#define SPI_BaudRatePrescaler_4 ((uint32_t)0x0004) +#define SPI_BaudRatePrescaler_6 ((uint32_t)0x0006) +#define SPI_BaudRatePrescaler_8 ((uint32_t)0x0008) +#define SPI_BaudRatePrescaler_10 ((uint32_t)0x000A) +#define SPI_BaudRatePrescaler_12 ((uint32_t)0x000C) +#define SPI_BaudRatePrescaler_14 ((uint32_t)0x000E) +#define SPI_BaudRatePrescaler_16 ((uint32_t)0x0010) +#define SPI_BaudRatePrescaler_32 ((uint32_t)0x0020) +#define SPI_BaudRatePrescaler_64 ((uint32_t)0x0040) +#define SPI_BaudRatePrescaler_128 ((uint32_t)0x0080) +#define SPI_BaudRatePrescaler_256 ((uint32_t)0x0100) +/** \} */ +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BaudRatePrescaler_2) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_4) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_8) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_10) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_12) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_14) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_16) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_32) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_64) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_128) || \ + ((PRESCALER) == SPI_BaudRatePrescaler_256)) + +/** + * \defgroup SPI_Clock_Polarity SPI Clock Polarity + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_CPOL_Low ((uint16_t)0x0000) +#define SPI_CPOL_High ((uint16_t)0x0001) +/** \} */ +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_CPOL_Low) || \ + ((CPOL) == SPI_CPOL_High)) + +/** + * \defgroup SPI_Clock_Phase SPI Clock Phase + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_CPHA_1Edge ((uint16_t)0x0000) +#define SPI_CPHA_2Edge ((uint16_t)0x0001) +/** \} */ +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_CPHA_1Edge) || \ + ((CPHA) == SPI_CPHA_2Edge)) + +/** + * \defgroup SPI_Frame_Format SPI Frame Format + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_Frame_Motorola ((uint16_t)0x0000) +#define SPI_Frame_TI_SSP ((uint16_t)0x0001) +#define SPI_Frame_NS_MICROWIRE ((uint16_t)0x0002) +#define SPI_Frame_Reserve ((uint16_t)0x0003) +/** \} */ +#define IS_SPI_FRAME_FORMAT(FRAME) (((FRAME) == SPI_Frame_Motorola) || \ + ((FRAME) == SPI_Frame_TI_SSP) || \ + ((FRAME) == SPI_Frame_NS_MICROWIRE) || \ + ((FRAME) == SPI_Frame_Reserve)) + +/** + * \defgroup SPI_Flags_Definition SPI Flags Definition + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_FLAG_BUSY ((uint16_t)0x0001) +#define SPI_FLAG_TFNF ((uint16_t)0x0002) +#define SPI_FLAG_TFE ((uint16_t)0x0004) +#define SPI_FLAG_RFNE ((uint16_t)0x0008) +#define SPI_FLAG_RFF ((uint16_t)0x0010) +#define SPI_FLAG_TXE ((uint16_t)0x0020) +#define SPI_FLAG_DCOL ((uint16_t)0x0040) +/** \} */ +#define IS_SPI_GET_FLAG(FLAG) (((FLAG) == SPI_FLAG_DCOL) || ((FLAG) == SPI_FLAG_TXE) || \ + ((FLAG) == SPI_FLAG_RFF) || ((FLAG) == SPI_FLAG_RFNE) || \ + ((FLAG) == SPI_FLAG_TFE) || ((FLAG) == SPI_FLAG_TFNF) || \ + ((FLAG) == SPI_FLAG_BUSY)) + +/** + * \defgroup SPI_Interrupt_Definition SPI Interrupt Definition + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_INT_TXE ((uint8_t)BIT(0)) +#define SPI_INT_TXO ((uint8_t)BIT(1)) +#define SPI_INT_RXU ((uint8_t)BIT(2)) +#define SPI_INT_RXO ((uint8_t)BIT(3)) +#define SPI_INT_RXF ((uint8_t)BIT(4)) +#define SPI_INT_MST ((uint8_t)BIT(5)) +#define SPI_INT_TUF ((uint8_t)BIT(6)) +#define SPI_INT_RIG ((uint8_t)BIT(7)) +/** \} */ + +#define IS_SPI_CONFIG_IT(IT) (((IT) == SPI_INT_TXE) || \ + ((IT) == SPI_INT_TXO) || \ + ((IT) == SPI_INT_RXU) || \ + ((IT) == SPI_INT_RXO) || \ + ((IT) == SPI_INT_RXF) || \ + ((IT) == SPI_INT_MST) || \ + ((IT) == SPI_INT_TUF) || \ + ((IT) == SPI_INT_RIG) ) +/** + * \defgroup SPI_GDMA_Transfer_Request SPI GDMA Transfer Request + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_GDMAReq_Tx ((uint16_t)0x0002) +#define SPI_GDMAReq_Rx ((uint16_t)0x0001) +/** \} */ +#define IS_SPI_GDMAREQ(GDMAREQ) ((((GDMAREQ) & (uint16_t)0xFFFC) == 0x00) && ((GDMAREQ) != 0x00)) + +/** + * \defgroup SPI_Swap_Enable SPI Swap Enable + * \{ + * \ingroup SPI_Exported_Constants + */ + +#define SPI_SWAP_ENABLE ((uint32_t)0x0001) +#define SPI_SWAP_DISABLE ((uint32_t)0x0000) +/** \} */ +#define IS_SPI_SWAPMODE(mode) (((mode) == SPI_SWAP_ENABLE) || \ + ((mode) == SPI_SWAP_DISABLE)) + + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup SPI_Exported_functions Peripheral APIs + * \{ + * \ingroup SPI + */ + +/** + * \brief Deinitializes the SPIx peripheral registers to their default reset values. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi_init(void) + * { + * SPI_DeInit(SPI0); + * } + * \endcode + */ +void SPI_DeInit(SPI_TypeDef *SPIx); + +/** + * \brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] SPI_InitStruct: Pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE); + + * SPI_InitTypeDef SPI_InitStruct; + * SPI_StructInit(&SPI_InitStruct); + * + * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM; + * SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; + * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; + * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; + * SPI_InitStruct.SPI_BaudRatePrescaler = 100; + * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1; + * SPI_InitStruct.SPI_NDF = 1 - 1; + * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola; + * + * SPI_Init(SPI0, &SPI_InitStruct); + * } + * \endcode + */ +void SPI_Init(SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct); + +/** + * \brief Fills each SPI_InitStruct member with its default value. + * \param[in] SPI_InitStruct: Pointer to a SPI_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi_init(void) + * { + * + * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE); + + * SPI_InitTypeDef SPI_InitStruct; + * SPI_StructInit(&SPI_InitStruct); + * + * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM; + * SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; + * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; + * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; + * SPI_InitStruct.SPI_BaudRatePrescaler = 100; + * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1; + * SPI_InitStruct.SPI_NDF = 1 - 1; + * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola; + * + * SPI_Init(SPI0, &SPI_InitStruct); + * } + * \endcode + */ +void SPI_StructInit(SPI_InitTypeDef *SPI_InitStruct); + +/** + * \brief Enables or disables the selected SPI peripheral. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] NewState: New state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_spi_init(void) + * { + * + * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE); + * + * SPI_InitTypeDef SPI_InitStruct; + * SPI_StructInit(&SPI_InitStruct); + * + * SPI_InitStruct.SPI_Direction = SPI_Direction_EEPROM; + * SPI_InitStruct.SPI_Mode = SPI_Mode_Master; + * SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; + * SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; + * SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; + * SPI_InitStruct.SPI_BaudRatePrescaler = 100; + * SPI_InitStruct.SPI_RxThresholdLevel = 1 - 1; + * SPI_InitStruct.SPI_NDF = 1 - 1; + * SPI_InitStruct.SPI_FrameFormat = SPI_Frame_Motorola; + * + * SPI_Init(SPI0, &SPI_InitStruct); + * SPI_Cmd(SPI0, ENABLE); + * } + * \endcode + */ +void SPI_Cmd(SPI_TypeDef *SPIx, FunctionalState NewState); + +/** + * \brief Transmits a number of bytes through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] pBuf: Bytes to be transmitted. + * \param[in] len: Byte length to be transmitted. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint8_t data_buf[] = {0x01,0x02,0x03}; + * SPI_SendBuffer(SPI0, data_buf, sizeof(data_buf)); + * } + * \endcode + */ +void SPI_SendBuffer(SPI_TypeDef *SPIx, uint8_t *pBuf, uint16_t len); + +/** + * \brief Transmits a number of halfWords through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] pBuf: Halfwords to be transmitted. + * \param[in] len: Halfwords length to be transmitted. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint16_t data_buf[] = {0x0102,0x0203,0x0304}; + * SPI_SendHalfWord(SPI0, data_buf, sizeof(data_buf)); + * } + * \endcode + */ +void SPI_SendHalfWord(SPI_TypeDef *SPIx, uint16_t *pBuf, uint16_t len); + +/** + * \brief Transmits a number of words through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] pBuf: Words to be transmitted. + * \param[in] len: Word length to be transmitted. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint32_t data_buf[] = {0x01020304,0x02030405,0x03040506}; + * SPI_SendWord(SPI0, data_buf, sizeof(data_buf)); + * } + * \endcode + */ +void SPI_SendWord(SPI_TypeDef *SPIx, uint32_t *pBuf, uint16_t len); + +/** + * \brief Enable or disable the specified SPI interrupt source. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] SPI_IT: Specifies the SPI interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * \arg SPI_INT_TXE: Transmit FIFO empty interrupt source. + * \arg SPI_INT_TXO: Transmit FIFO overflow interrupt source. + * \arg SPI_INT_RXU: Receive FIFO underflow interrupt source. + * \arg SPI_INT_RXO: Receive FIFO overflow interrupt source. + * \arg SPI_INT_RXF: Receive FIFO full interrupt source. + * \arg SPI_INT_MST: Multi-Master contention interrupt source. + * \param[in] NewState: New state of the specified SPI interrupt source. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_INTConfig(SPI0, SPI_INT_RXF, ENABLE); + * } + * \endcode + */ +void SPI_INTConfig(SPI_TypeDef *SPIx, uint8_t SPI_IT, FunctionalState NewState); + +/** + * \brief Clear the specified SPI interrupt pending bit. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] SPI_IT: Specifies the SPI interrupt to clear. + * This parameter can be one of the following values: + * \arg SPI_INT_MST: Multi-Master Contention Interrupt. + * \arg SPI_INT_RXO: Receive FIFO Overflow Interrupt. + * \arg SPI_INT_RXU: Receive FIFO Underflow Interrupt. + * \arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_ClearINTPendingBit(SPI0, SPI_INT_RXF); + * } + * \endcode + */ +void SPI_ClearINTPendingBit(SPI_TypeDef *SPIx, uint16_t SPI_IT); + +/** + * \brief Transmits a data through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1 to select the SPI peripheral. + * \param[in] Data: Data to be transmitted. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint32_t data = 0x01020304; + * SPI_SendData(SPI0, data); + * } + * \endcode + */ +__STATIC_INLINE void SPI_SendData(SPI_TypeDef *SPIx, uint32_t Data) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + SPIx->DR[0] = Data; + while (!(SPIx->SR & BIT(1))); +} + +/** + * \brief Received data by the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1. + * \retval The most recent received data. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint32_t data = SPI_ReceiveData(SPI0); + * } + * \endcode + */ +__STATIC_INLINE uint32_t SPI_ReceiveData(SPI_TypeDef *SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + return (uint32_t)SPIx->DR[0]; +} + +/** + * \brief Get data length in Tx FIFO through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1. + * \return Data length in Tx FIFO. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint8_t data_len = SPI_GetTxFIFOLen(SPI0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t SPI_GetTxFIFOLen(SPI_TypeDef *SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + return (uint8_t)SPIx->TXFLR; +} + +/** + * \brief Get data length in Rx FIFO through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1. + * \return Data length in Rx FIFO. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * uint8_t data_len = SPI_GetRxFIFOLen(SPI0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t SPI_GetRxFIFOLen(SPI_TypeDef *SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + return (uint8_t)SPIx->RXFLR; +} + +/** + * \brief Change SPI direction mode. + * \param[in] SPIx: Where x can be 0 or 1. + * \param[in] dir: Value of direction mode. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_ChangeDirection(SPI0, SPI_Direction_EEPROM); + * } + * \endcode + */ +__STATIC_INLINE void SPI_ChangeDirection(SPI_TypeDef *SPIx, uint16_t dir) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_DIRECTION_MODE(dir)); + + /* Disable the selected SPI peripheral */ + SPIx->SSIENR &= ~0x01; + + /* Change SPI direction mode */ + SPIx->CTRLR0 &= ~(0x03 << 8); + SPIx->CTRLR0 |= dir << 8; + + /* Enable the selected SPI peripheral */ + SPIx->SSIENR |= 0x01; +} + +/** + * \brief Set read Data length only in EEPROM mode through the SPIx peripheral,which + enables you to receive up to 64 KB of data in a continuous transfer. + * \param[in] SPIx: Where x can be 0 or 1 + * \param[in] len: Length of read data which can be 1 to 65536. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_SetReadLen(SPI0, 100); + * } + * \endcode + */ +__STATIC_INLINE void SPI_SetReadLen(SPI_TypeDef *SPIx, uint16_t len) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Disable the selected SPI peripheral */ + SPIx->SSIENR &= ~0x01; + /* set read length in SPI EEPROM mode */ + SPIx->CTRLR1 = len - 1; + /* Enable the selected SPI peripheral */ + SPIx->SSIENR |= 0x01; +} + +/** + * \brief Set cs number through the SPIx peripheral. + * \param[in] SPIx: Where x can be 0 or 1 + * \param[in] number: If SPIx is SPI0, number must be 0. If SPIx is SPI1, number can be 0 to 2. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_SetCSNumber(SPI1, 1); + * } + * \endcode + */ +__STATIC_INLINE void SPI_SetCSNumber(SPI_TypeDef *SPIx, uint8_t number) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* set cs number */ + SPIx->SER = BIT(number); +} + +/** + * \brief Check whether the specified SPI interrupt is set. + * \param[in] SPIx: Where x can be 0 or 1 + * \param[in] SPI_IT: Specifies the SPI interrupt to check. + * This parameter can be one of the following values: + * \arg SPI_INT_MST: Multi-Master Contention Interrupt. + * \arg SPI_INT_RXF: Receive FIFO Full Interrupt. + * \arg SPI_INT_RXO: Receive FIFO Overflow Interrupt. + * \arg SPI_INT_RXU: Receive FIFO Underflow Interrupt. + * \arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt . + * \arg SPI_INT_TXE: Transmit FIFO Empty Interrupt. + * \return The new state of SPI_IT (SET or RESET). + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * ITStatus int_status = SPI_GetINTStatus(SPI0, SPI_INT_RXF); + * } + * \endcode + */ +__STATIC_INLINE ITStatus SPI_GetINTStatus(SPI_TypeDef *SPIx, uint32_t SPI_IT) +{ + ITStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CONFIG_IT(SPI_IT)); + + if ((SPIx->ISR & SPI_IT) != (uint32_t)RESET) + { + bit_status = SET; + } + + /* Return the SPI_IT status */ + return bit_status; +} + +/** + * \brief Check whether the specified SPI flag is set. + * \param[in] SPIx: Where x can be 0 or 1 + * \param[in] SPI_FLAG: Specifies the SPI flag to check. + * This parameter can be one of the following values: + * \arg SPI_FLAG_DCOL: Data Collision Error flag.Set if it is actively transmitting in master mode when another master selects this device as a slave. + * \arg SPI_FLAG_TXE: Transmission error flag.Set if the transmit FIFO is empty when a transfer is started in slave mode. + * \arg SPI_FLAG_RFF: Receive FIFO full flag. Set if the receive FIFO is completely full. + * \arg SPI_FLAG_RFNE: Receive FIFO Not Empty flag.Set if receive FIFO is not empty. + * \arg SPI_FLAG_TFE: Transmit FIFO Empty flag.Set if transmit FIFO is empty. + * \arg SPI_FLAG_TFNF: Transmit FIFO Not Full flag.Set if transmit FIFO is not full. + * \arg SPI_FLAG_BUSY: SPI Busy flag.Set if it is actively transferring data.reset if it is idle or disabled. + * \return The new state of SPI_FLAG (SET or RESET). + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * FlagStatus flag_status = SPI_GetFlagState(SPI0, SPI_FLAG_TXE); + * + * } + * \endcode + */ +__STATIC_INLINE FlagStatus SPI_GetFlagState(SPI_TypeDef *SPIx, uint8_t SPI_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_GET_FLAG(SPI_FLAG)); + + /* Check the status of the specified SPI flag */ + if ((SPIx->SR & SPI_FLAG) != (uint8_t)RESET) + { + /* SPI_FLAG is set */ + bitstatus = SET; + } + + /* Return the SPI_FLAG status */ + return bitstatus; +} + +/** + * \brief Enables or disables the SPIx GDMA interface. + * \param[in] SPIx: Where x can be 0 or 1 + * \param[in] SPI_GDMAReq: Specifies the SPI GDMA transfer request to be enabled or disabled. + * This parameter can be one of the following values: + * \arg SPI_GDMAReq_Tx: Tx buffer DMA transfer request. + * \arg SPI_GDMAReq_Rx: Rx buffer DMA transfer request. + * \param[in] NewState: New state of the selected SPI GDMA transfer request. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_GDMACmd(SPI0, SPI_GDMAReq_Tx, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE void SPI_GDMACmd(SPI_TypeDef *SPIx, uint16_t SPI_GDMAReq, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_GDMAREQ(SPI_GDMAReq)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI GDMA request */ + SPIx->DMACR |= SPI_GDMAReq; + } + else + { + /* Disable the selected SPI GDMA request */ + SPIx->DMACR &= (uint16_t)~(SPI_GDMAReq); + } +} +/** + * \brief Change SPI speed daynamically. + * \param[in] SPIx: Where x can be 0 or 1. + * \param[in] precalser: Value of prescaler. + * This parameter can be one of the following values: + * \arg SPI_BaudRatePrescaler_2 + * \arg SPI_BaudRatePrescaler_4 + * \arg SPI_BaudRatePrescaler_6 + * \arg SPI_BaudRatePrescaler_8 + * \arg SPI_BaudRatePrescaler_10 + * \arg SPI_BaudRatePrescaler_12 + * \arg SPI_BaudRatePrescaler_14 + * \arg SPI_BaudRatePrescaler_16 + * \arg SPI_BaudRatePrescaler_32 + * \arg SPI_BaudRatePrescaler_64 + * \arg SPI_BaudRatePrescaler_128 + * \arg SPI_BaudRatePrescaler_256 + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_Change_CLK(SPI0, SPI_BaudRatePrescaler_2); + * } + * \endcode + */ +__STATIC_INLINE void SPI_Change_CLK(SPI_TypeDef *SPIx, uint32_t prescaler) +{ + SPIx->BAUDR = prescaler % 0xFFFF; +} + +/** + * \brief Set SPI Rx sample delay. + * \param[in] SPIx: Where x can be 0 or 1. + * \param[in] delay: This parameter can be 0 to 255. + * \return None. + * + * Example usage + * \code{.c} + * + * void spi_demo(void) + * { + * SPI_SetRxSampleDly(SPI0, 1); + * } + * \endcode + */ +__STATIC_INLINE void SPI_SetRxSampleDly(SPI_TypeDef *SPIx, uint32_t delay) +{ + SPIx->RX_SAMPLE_DLY = delay & 0xFF; +} + +/** \} */ /* End of group SPI_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_SPI_H_ */ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_tim.h b/inc/peripheral/rtl876x_tim.h new file mode 100644 index 0000000..be0e4df --- /dev/null +++ b/inc/peripheral/rtl876x_tim.h @@ -0,0 +1,661 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_tim.h +* \brief The header file of the peripheral TIMER driver. +* \details This file provides all TIMER firmware functions. +* \author Yuan +* \date 2020-09-29 +* \version v1.0.0 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_TIM_H_ +#define _RTL876X_TIM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup TIM TIM + * \brief Manage the TIM peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup TIM_Exported_Types Init Params Struct + * + * \ingroup TIM + */ + +/** + * \brief TIM init structure definition. + * + * \ingroup TIM_Exported_Types + */ +typedef struct +{ + uint16_t TIM_ClockSrc; /*!< Deprecated use RCC instead.*/ + uint16_t TIM_SOURCE_DIV; /*!< Specifies the clock source div. + This parameter can be a value of \ref TIM_Clock_Divider*/ + uint16_t TIM_SOURCE_DIV_En; /*!< Timer source clock div enable. */ + uint16_t TIM_Mode; /*!< Specifies the counter mode. + This parameter can be a value of \ref TIM_Mode. */ + uint16_t TIM_PWM_En; /*!< Specifies the PWM mode. + This parameter can be a value of DISABLE or ENABLE */ + uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must range from 0x0000 to 0xFFFFFFFF. */ + uint32_t TIM_PWM_High_Count; /*!< Specifies the PWM High Count. + This parameter must range from 0x0000 to 0xFFFFFFFF. */ + uint32_t TIM_PWM_Low_Count; /*!< Specifies the PWM Low Count. + This parameter must range from 0x0000 to 0xFFFFFFFF. */ + uint32_t TIM_EventMode; /*!< Specifies the TIM event mode. */ + uint32_t TIM_EventIndex; /*!< Specifies the TIM event index. */ + uint32_t TIM_EventDuration; /*!< Specifies the TIM event duration.*/ + uint8_t ClockDepend; /*!< Specifies TIM Source depend.timer3 depend timer2 ,timer5 depend timer4. + This parameter can be a value of ENABLE or DISABLE */ + uint32_t PWM_Deazone_Size; /*!Example usage + * \code{.c} + * + * void driver_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * + * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE; + * TIM_InitStruct.TIM_Period = 1000000 - 1 ; + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct); + * } + * \endcode + */ +void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct); + +/** + * \brief Fills each TIM_InitStruct member with its default value. + * \param[in] TIM_TimeBaseInitStruct: Pointer to a TIM_TimeBaseInitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * + * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE; + * TIM_InitStruct.TIM_Period = 1000000 - 1; + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_TimeBaseInit(TIM4, &TIM_InitStruct); + * } + * \endcode + */ +void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct); + +/** + * \brief Enable or disable the specified TIM peripheral. + * Attention: If interrupt status can't be cleared normally after disable TIM by this API, + * you can choose API of TIM_CmdSafe to disable TIM. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \param[in] NewState: New state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * + * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE; + * TIM_InitStruct.TIM_Period = 1000000 - 1; + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_TimeBaseInit(TIM4, &TIM_InitStruct); + * TIM_Cmd(TIM4, ENABLE); + * } + * \endcode + */ +void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState); + +/** + * \brief Protective measures for turning off the TIM. + * This function should be used after TIM_ClearINT function otherwise it will occur an error. + * \param[in] TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * \retval None + * + * Example usage + * \code{.c} + * + * void WDT_handler(void) + * { + * TIM_ClearINT(TIM6); + * TIM_SafeStop(TIM6); + * } + * \endcode + */ +void TIM_CmdSafe(TIM_TypeDef *TIMx); + +/** + * \brief Enables or disables the specified TIMx interrupt. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \param[in] NewState: New state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_timer_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * + * TIM_InitStruct.TIM_PWM_En = PWM_DISABLE; + * TIM_InitStruct.TIM_Period = 1000000 - 1; + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_TimeBaseInit(TIM4, &TIM_InitStruct); + * TIM_ClearINT(TIM4); + * TIM_INTConfig(TIM4, ENABLE); + */ +void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState); + +/** + * \brief Change TIM period value. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \param[in] period: Period value to be changed. + * \return None. + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * uint32_t new_period = 1000000 - 1; + * TIM_Cmd(TIM4, DISABLE); + * TIM_ChangePeriod(TIM4, new_period); + * + * } + * \endcode + */ +void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period); + +/** + * \brief Change PWM freq and duty according high_cnt and low_cnt + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \param[in] high_count: This parameter can be 0x00~0xFFFFFFFF. + * \param[in] low_count: This parameter can be 0x00~0xFFFFFFFF. + * \return None. + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * uint32_t high_count = 1000000 - 1; + * uint32_t low_count = 1000000 - 1; + * TIM_Cmd(TIM4, DISABLE); + * TIM_ChangePeriod(TIM4, high_count, low_count); + * } + * \endcode + */ +void TIM_PWMChangeFreqAndDuty(TIM_TypeDef *TIMx, uint32_t high_count, uint32_t low_count); + +/** + * \brief Get TIMx current value when timer is running. + * \param[in] TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * \return The counter value. + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * uint32_t cur_value = TIM_GetCurrentValue(TIM4); + * } + * \endcode + */ +__STATIC_INLINE uint32_t TIM_GetCurrentValue(TIM_TypeDef *TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + return TIMx->CurrentValue; +} + +/** + * \brief Check whether the TIM interrupt has occurred or not. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \return The new state of the TIM_IT(SET or RESET). + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * ITStatus int_status = TIM_GetINTStatus(TIM4); + * } + * \endcode + */ +__STATIC_INLINE ITStatus TIM_GetINTStatus(TIM_TypeDef *TIMx) +{ + ITStatus bitstatus = RESET; + uint16_t itstatus = (uint16_t)TIMx->IntStatus; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (itstatus != (uint16_t)RESET) + { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * \brief Clear TIM interrupt. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * TIM_ClearINT(TIM4); + * } + * \endcode + */ +__STATIC_INLINE void TIM_ClearINT(TIM_TypeDef *TIMx) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + /* Clear the IT */ + TIMx->EOI; +} + +/** + * \brief Check whether the TIM is in operation or not. + * \param[in] TIMx: Where x can be 2 to 5 to select the TIMx peripheral. + * \return The new state of the timer operation status (SET or RESET). + * + * Example usage + * \code{.c} + * + * void timer_demo(void) + * { + * ITStatus intstatus = TIM_GetOperationStatus(TIM4); + * } + * \endcode + */ +__STATIC_INLINE ITStatus TIM_GetOperationStatus(TIM_TypeDef *TIMx) +{ + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (TIMx->ControlReg & BIT(0)) + { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * \brief PWM complementary output emergency stop and resume. + * PWM_P emergency stop level state is configured by PWM_Stop_State_P, + * PWM_N emergency stop level state is configured by PWM_Stop_State_N. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of complementary output. + * \ref DISABLE: Resume PWM complementary output. + * \ref ENABLE: PWM complementary output emergency stop. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + * \return None. + * + * Example usage + * \code{.c} + * + * void board_pwm_init(void) + * { + * Pad_Config(P0_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH); + * Pad_Config(P0_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, + * PAD_OUT_HIGH); + * Pad_Config(P2_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, + * PAD_OUT_HIGH); + * + * Pinmux_Config(P0_1, PWM_OUT_PIN_PINMUX); + * Pinmux_Config(P0_2, PWM_OUT_P_PIN_PINMUX); + * Pinmux_Config(P2_2, PWM_OUT_N_PIN_PINMUX); + * } + * + * void driver_pwm_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE; + * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT; + * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT; + * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH; + * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW; + * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output + * TIM_InitStruct.PWM_Deazone_Size = 255; + * TIM_TimeBaseInit(TIM2, &TIM_InitStruct); + * + * TIM_Cmd(TIM2, ENABLE); + * } + * + * void pwm_demo(void) + * { + * board_pwm_init(); + * driver_pwm_init(); + * //Add delay. + * TIM_PWMComplOutputEMCmd(PWM2,ENABLE); + * } + * \endcode + */ +void TIM_PWMComplOutputEMCmd(PWM_TypeDef *PWMx, FunctionalState NewState); + +/** + * \brief Enable or disable bypass dead zone function of PWM complementary output. + * After enabling, PWM_P = ~PWM_N. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of the PWMx peripheral. + * \ref DISABLE: Disable bypass dead zone function. + * \ref ENABLE: Enable bypass dead zone function. + * \return None. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + * + * Example usage + * \code{.c} + * + * void driver_pwm_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * TIM_StructInit(&TIM_InitStruct); + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE; + * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT; + * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT; + * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH; + * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW; + * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output + * TIM_InitStruct.PWM_Deazone_Size = 255; + * TIM_TimeBaseInit(TIM2, &TIM_InitStruct); + * + * TIM_Cmd(TIM2, ENABLE); + * TIM_PWMDZBypassCmd(PWM2, ENABLE); + * } + * \endcode + */ +void TIM_PWMDZBypassCmd(PWM_TypeDef *PWMx, FunctionalState NewState); + +/** + * \brief Change the PWM dead time clock source. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of the PWMx peripheral. + * \ref DISABLE: Use 32k clock source. + * \ref ENABLE: Use 5M clock source. + * \return None. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + * + * Example usage + * \code{.c} + * + * Example usage + * \code{.c} + * + * void driver_pwm_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + * //Open 5M clock source. + * RCC_ClockSrc5MCmd(); + * + * TIM_TimeBaseInitTypeDef TIM_InitStruct; + * + * TIM_StructInit(&TIM_InitStruct); + * TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + * TIM_InitStruct.TIM_PWM_En = PWM_ENABLE; + * TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT; + * TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT; + * TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH; + * TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW; + * TIM_InitStruct.PWMDeadZone_En = DEADZONE_ENABLE; //enable to use pwn p/n output + * TIM_InitStruct.PWM_Deazone_Size = PWM_DEAD_ZONE_SIZE; + * TIM_TimeBaseInit(TIM2, &TIM_InitStruct); + * + * //Use 5M clock source. + * TIM_PWMChangeDZClockSrc(PWM2,ENABLE); + * + * TIM_Cmd(TIM2, ENABLE); + * } + * \endcode + */ +void TIM_PWMChangeDZClockSrc(PWM_TypeDef *PWMx, FunctionalState NewState); + +/** + * \brief PWM complementary output emergency stop. + * \param[in] PWMx: PWM2. + * \return None. + */ +__STATIC_INLINE void PWM_Deadzone_EMStop(PWM_TypeDef *PWMx) +{ + /* Check the parameters. */ + assert_param(IS_PWM_ALL_PERIPH(PWMx)); + + PWMx->CR |= BIT(8); +} + +/** + * @brief Get PWM current output status. + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @retval The output state of the timer(SET: High or RESET: Low). + */ +__STATIC_INLINE FlagStatus TIM_GetPWMOutputStatus(TIM_TypeDef *TIMx) +{ + uint32_t timer_index = 0; + uint32_t reg_value = 0; + ITStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + timer_index = ((uint32_t)TIMx - TIM0_REG_BASE) / (TIM1_REG_BASE - TIM0_REG_BASE); + reg_value = *((volatile uint32_t *)0x40006024UL); + + if ((reg_value >> timer_index) & BIT(0)) + { + bitstatus = SET; + } + + return bitstatus; +} +/** \} */ /* End of group TIM_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /*_RTL876X_TIM_H_*/ + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/inc/peripheral/rtl876x_trng.h b/inc/peripheral/rtl876x_trng.h new file mode 100644 index 0000000..bac5167 --- /dev/null +++ b/inc/peripheral/rtl876x_trng.h @@ -0,0 +1,162 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file rtl876x_trng.h +* @brief +* @details +* @author eason li +* @date 2019-05-06 +* @version v0.1 +* ********************************************************************************************************* +*/ + +#ifndef __RTL876X_TRNG_H +#define __RTL876X_TRNG_H +// *INDENT-OFF* +#ifdef __cplusplus +extern "C" { +#endif +/* Includes ------------------------------------------------------------------*/ +#include +#include "rtl876x.h" + +/** + * @brief referenc to IO_MODULE (sheet: SoC-VENDOR_REG) + */ +typedef struct +{ + union /* 0x00 */ + { + __IO uint32_t CTRL; + struct + { + __IO uint32_t rng_srst: 1; /* RNG Software Reset, High Active. It will reset all digital except programmable registers, except Calibration Degital. */ + __IO uint32_t clk_hf_sel: 1; /* Selection of High Speed Clock: 0: clk_hfosc_rng, 1: clk_hfosc_rng/2 */ + __IO uint32_t corrector_bypass: 1; /* Random Bias Corrector will be bypassed if corrector_bypass = 1 */ + __IO uint32_t rsvd0: 2; + __IO uint32_t corrector_imode: 1; /* Random Bias Corrector sample rate, 0: 4 valid TRNG, 1: 2 valid TRNG (But corrector_bypass is the highest priority) */ + __IO uint32_t dbg0_sel: 5; /* The Debug Signal Group 0 Selection. */ + __IO uint32_t dbg1_sel: 5; /* The Debug Signal Group 1 Selection. */ + __IO uint32_t lfsr_bypass_1: 1; /* LFSR_1 will be bypassed if lfsr_bypass_1 = 1. */ + __IO uint32_t lfsr_mode: 1; + __IO uint32_t st_en: 1; /* Self test enable */ + __IO uint32_t mode: 1; /* 0: TRNG -> BIAS -> LFSR -> self-test -> buf; 1: TRNG -> BIAS -> self-test -> LFSR -> buf */ + __IO uint32_t rsvd1: 12; + } CTRL_field; + }; + + __IO uint32_t rsvd0[6]; // 0x04 - 0x18 + + union /* 0x1C */ + { + __IO uint32_t RNG_return0; + struct + { + __I uint32_t out_ready: 1; /* The Random Number for Realtek is Ready to Read. */ + __IO uint32_t rsvd0: 31; + } return0_field; + }; + + __I uint32_t valid_bit_num; /* 0x20, The Bit Number of Realtek Random Number is Generated after reset. It will be wrapped around if reach the top. */ + __I uint32_t drop_num; /* 0x24, The Bit Number of Realtek Random Number is Dropped after reset. It will be wrapped around if reach the top. */ + __I uint32_t random_out; /* 0x28, Random Number for Realtek. It will return all zeros if random number is not ready. */ + __IO uint32_t lfsr_poly_lsb; /* 0x2C, RNG LFSR_1 Polynomial LSB 32-bit from register (for Realtek) */ + __IO uint32_t lfsr_poly_msb; /* 0x30, RNG LFSR_1 Polynomial MSB 32-bit from register (for Realtek) */ + __IO uint32_t rsvd1; /* 0x34 */ + + union /* 0x38 */ + { + __IO uint32_t RNG_POWER; + struct + { + __IO uint32_t gating_en: 1; /* Enable power gating function. */ + __IO uint32_t rsvd: 31; + } power_field; + }; + + union /* 0x3C */ + { + __IO uint32_t RNG_st; + struct + { + __IO uint32_t thr_done_rep: 8; /* Done threshold for repetition count test */ + __IO uint32_t thr_err_rep: 8; /* Error threshold for repetition count test */ + __IO uint32_t window_size_adap2: 2; + __IO uint32_t window_size_adap1: 2; + __IO uint32_t compare_unit_adap2: 1; /* Compare unit for adaptive test 2, 0 : bit mode, 1 : byte mode */ + __IO uint32_t compare_unit_adap1: 1; /* Compare unit for adaptive test 1, 0 : bit mode, 1 : byte mode */ + __IO uint32_t compare_unit_rep: 1; /* Compare unit for repetition test, 0 : bit mode, 1 : byte mode */ + __IO uint32_t rsvd: 1; + __IO uint32_t thr_done_adap2: 4; /* Done threshold for adaptive proportion test (pass times), Default : pass four times, done_adap2 will be asserted */ + __IO uint32_t thr_done_adap1: 4; /* Done threshold for adaptive proportion test (pass times), Default : pass four times, done_adap1 will be asserted */ + } st_field; + }; + + union /* 0x40 */ + { + __IO uint32_t RNG_st_return; + struct + { + __IO uint32_t err_adap2: 1; /* Error will be asserted when adaptive proportion test detects error */ + __IO uint32_t err_adap1: 1; /* Error will be asserted when adaptive proportion test detects error */ + __IO uint32_t err_rep: 1; /* Error will be asserted when repetition count test detects error */ + __IO uint32_t err: 1; /* Error will be asserted when self test detects error */ + __I uint32_t done_adap2: 1; /* Adaptive proportion test 2 is ready */ + __I uint32_t done_adap1: 1; /* Adaptive proportion test 1 is ready */ + __I uint32_t done_rep: 1; /* Repetition count test is ready */ + __I uint32_t done: 1; /* Repetition count test is ready */ + __IO uint32_t rsvd: 24; + } st_return_field; + }; + + __IO uint32_t rsvd2[4]; /* 0x44 - 0x50 */ + + union /* 0x54 */ + { + __IO uint32_t RNG_interrupt_st; + struct + { + __O uint32_t write_data: 1; /* 1 to set, 0 to clear bit with 1. */ + __IO uint32_t rsvd0: 1; + __IO uint32_t parity: 1; /* interrupt for buffer parity check */ + __IO uint32_t rsvd1: 29; + } interrupt_st_field; + }; + + __IO uint32_t rsvd3[2]; /* 0x58 - 0x5C */ + + union /* 0x60 */ + { + __IO uint32_t RNG_st_thr_err; + struct + { + __IO uint32_t adap2: 16; /* Error threshold for adaptive proportion test, Bit-mode: Max = 3/4 * window size, Byte-mode: Max = 1/4 * window size */ + __IO uint32_t adap1: 16; /* Error threshold for adaptive proportion test, Bit-mode: Max = 3/4 * window size, Byte-mode: Max = 1/4 * window size */ + } st_thr_err_field; + }; + + union /* 0x64 */ + { + __IO uint32_t RNG_interrupt_enable; + struct + { + __O uint32_t write_data: 1; /* 1 to set, 0 to clear bit with 1. */ + __IO uint32_t rsvd0: 1; + __IO uint32_t parity: 1; /* set 1 to enable interrupt */ + __IO uint32_t rsvd1: 29; + } interrupt_enable_field; + }; +} TRNG_TypeDef; + +#define TRNG_BASE 0x40006200UL +#define TRNG ((TRNG_TypeDef *) TRNG_BASE) + +extern void (*init_true_random_generator)(void); +extern uint32_t (*get_true_random_number)(void); + +#ifdef __cplusplus +} +#endif +#endif /*__RTL876X_TRNG_H*/ + diff --git a/inc/peripheral/rtl876x_uart.h b/inc/peripheral/rtl876x_uart.h new file mode 100644 index 0000000..23a4011 --- /dev/null +++ b/inc/peripheral/rtl876x_uart.h @@ -0,0 +1,878 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* \file rtl876x_uart.h +* \brief The header file of the peripheral UART driver. +* \details This file provides all UART firmware functions. +* \author yuan +* \date 2019-11-14 +* \version v2.1.0 +* ********************************************************************************************************* +*/ + + +#ifndef _RTL876X_UART_H_ +#define _RTL876X_UART_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup IO Peripheral Drivers + * \defgroup UART UART + * + * \brief Manage the UART peripheral functions. + * + * \ingroup IO + */ + +/*============================================================================* + * Includes + *============================================================================*/ +#include "rtl876x.h" +#include "rtl876x_alias.h" + + +/*============================================================================* + * Types + *============================================================================*/ + +/** + * \defgroup UART_Exported_Types Init Params Struct + * \brief + * \ingroup UART + */ + +/** + * \brief UART init structure definition. + * + * \ingroup UART_Exported_Types + */ +typedef struct +{ + //baudrate calibration + uint16_t UART_OvsrAdj; /*!< Specifies the baud rate setting, ovsr_adj, please refer to baudrate setting table.*/ + uint16_t UART_Div; /*!< Specifies the baud rate setting, div, please refer to baudrate setting table.*/ + uint16_t UART_Ovsr; /*!< Specifies the baud rate setting, ovsr, please refer to baudrate setting table.*/ + uint16_t UART_WordLen; /*!< Specifies the UART Wordlength + This parameter can be a value of \ref UART_Word_Length. */ + uint16_t UART_StopBits; /*!< Specifies the stop bit. + This parameter can be a value of \ref UART_Stop_Bits. */ + uint16_t UART_Parity; /*!< Specifies the parity. + This parameter can be a value of \ref UART_Parity. */ + uint16_t UART_TxThdLevel; /*!< Specifies the Tx threshold level. + This parameter must range from 1 to 29.*/ + uint16_t UART_RxThdLevel; /*!< Specifies the Rx threshold level. + This parameter must range from 1 to 29.*/ + uint16_t UART_IdleTime; /*!< Specifies the idle time. + This parameter can be a value of \ref UART_Rx_Idle_Time. */ + uint16_t UART_HardwareFlowControl; /*!< Specifies the hardware flow control. + This parameter can be a value of \ref UART_Hardware_Flow_Control. */ + uint16_t UART_DmaEn; /*!< Specifies the dma mode. + This parameter must be a value of DISABLE and ENABLE */ + uint16_t UART_TxDmaEn; /*!< Specifies the Tx dma mode. + This parameter must be a value of DISABLE and ENABLE */ + uint16_t UART_RxDmaEn; /*!< Specifies the Rx dma mode. + This parameter must be a value of DISABLE and ENABLE */ + uint8_t UART_TxWaterLevel; /*!< Specifies the DMA tx water level. + This parameter must range from 1 to 16.*/ + uint8_t UART_RxWaterLevel; /*!< Specifies the DMA rx water level. + This parameter must range from 1 to 31.*/ +} UART_InitTypeDef; + + +/*============================================================================* + * Constants + *============================================================================*/ + +/** + * \defgroup UART_Exported_Constants Macro Definitions + * + * \ingroup UART + */ + +#define IS_UART_PERIPH(PERIPH) (((PERIPH) == UART0) || ((PERIPH) == UART1)) + +#define UART_TX_FIFO_SIZE 16 +#define UART_RX_FIFO_SIZE 32 + +/** \defgroup UART_Interrupts_Definition UART Interrupts Definition + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_INT_RD_AVA ((uint16_t)(1 << 0))//receive data avaliable +#define UART_INT_TX_FIFO_EMPTY ((uint16_t)(1 << 1)) +#define UART_INT_RX_LINE_STS ((uint16_t)(1 << 2)) +#define UART_INT_TX_DONE ((uint16_t)(1 << 4)) +#define UART_INT_TX_THD ((uint16_t)(1 << 5)) +#define UART_INT_RX_BREAK ((uint16_t)(1 << 6)) +#define UART_INT_RX_IDLE ((uint16_t)(1 << 7)) +/** \} */ + +#define IS_UART_INT(INT) ((((INT) & 0xFFFFFF80) == 0x00) && ((INT) != 0x00)) + +#define IS_UART_GET_INT(INT) ((INT) & (UART_INT_RD_AVA | UART_INT_TX_FIFO_EMPTY | UART_INT_RX_LINE_STS |\ + UART_INT_TX_DONE | UART_INT_TX_THD |\ + UART_INT_RX_IDLE)) + +/** \defgroup UART_Interrupt_Identifier UART Interrupt Identifier + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_INT_PENDING ((uint16_t)(1 << 0)) +#define UART_INT_ID_LINE_STATUS ((uint16_t)(0x03 << 1)) +#define UART_INT_ID_RX_LEVEL_REACH ((uint16_t)(0x02 << 1)) +#define UART_INT_ID_RX_DATA_TIMEOUT ((uint16_t)(0x06 << 1)) +#define UART_INT_ID_TX_EMPTY ((uint16_t)(0x01 << 1)) +/** \} */ + +#define IS_UART_INT_ID(ID) (((ID) == UART_INT_ID_LINE_STATUS) || ((ID) == UART_INT_ID_RX_LEVEL_REACH)\ + || ((ID) == UART_INT_ID_RX_TMEOUT) || ((ID) == UART_INT_ID_TX_EMPTY)) + +/** \defgroup UART_Parity UART Parity + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_PARITY_NO_PARTY ((uint16_t)(0x00 << 3)) +#define UART_PARITY_ODD ((uint16_t)(0x01 << 3)) +#define UART_PARITY_EVEN ((uint16_t)(0x03 << 3)) +/** \} */ + +#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NO_PARTY) || ((PARITY) == UART_PARITY_ODD)\ + || ((PARITY) == UART_PARITY_EVEN)) + +/** \defgroup UART_Stop_Bits UART Stop Bits + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_STOP_BITS_1 ((uint16_t)(0 << 2)) +#define UART_STOP_BITS_2 ((uint16_t)(1 << 2)) +/** \} */ + +#define IS_UART_STOPBITS(STOP) (((STOP) == UART_STOP_BITS_1) || ((STOP) == UART_STOP_BITS_2)) + +/** + * \defgroup UART_Word_Length UART Word Length + * \{ + * \ingroup UART_Exported_Constants + */ +#define UART_WORD_LENGTH_7BIT ((uint16_t)(0 << 0)) +#define UART_WORD_LENGTH_8BIT ((uint16_t)(1 << 0)) +/** \} */ + +#define IS_UART_WORD_LENGTH(LEN) ((((LEN)) == UART_WORD_LENGTH_7BIT) || (((LEN)) == UART_WORD_LENGTH_8BIT)) + +/** \defgroup UART_Hardware_Flow_Control UART Hardware Flow Control + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_HW_FLOW_CTRL_DISABLE ((uint16_t)0x00) +#define UART_HW_FLOW_CTRL_ENABLE ((uint16_t)((1 << 5) | (1 << 1))) +/** \} */ + +#define IS_UART_AUTO_FLOW_CTRL(CTRL) (((CTRL) == UART_AUTO_FLOW_CTRL_EN) || ((CTRL) == UART_AUTO_FLOW_CTRL_DIS)) + +/** \defgroup UART_Flag UART Flag + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_FLAG_RX_DATA_AVA ((uint16_t)(1 << 0)) +#define UART_FLAG_RX_OVERRUN ((uint16_t)(1 << 1)) +#define UART_FLAG_RX_PARITY_ERR ((uint16_t)(1 << 2)) +#define UART_FLAG_RX_FRAME_ERR ((uint16_t)(1 << 3)) +#define UART_FLAG_RX_BREAK_ERR ((uint16_t)(1 << 4)) +#define UART_FLAG_TX_FIFO_EMPTY ((uint16_t)(1 << 5)) //Transmitter Holding Register or Transmitter FIFO empty +#define UART_FLAG_TX_EMPTY ((uint16_t)(1 << 6)) //Transmitter Holding Register(or tx FIFO) and Transmitter shift Register both empty +#define UART_FLAG_RX_FIFO_ERR ((uint16_t)(1 << 7)) +#define UART_FLAG_RX_BREAK ((uint16_t)(1 << 8)) +#define UART_FLAG_RX_IDLE ((uint16_t)(1 << 9)) //Only to show difference cause the address of UART RX Ilde flag is isolate +#define UART_FLAG_TX_DONE ((uint16_t)(1 << 10)) //Interrupt status of tx waveform done & TX_FIFO_EMPTY = 1 +#define UART_FLAG_TX_THD ((uint16_t)(1 << 11)) //Interrupt status of TX_FIFO_LEVEL<=txfifo_trigger_level +/** \} */ + +#define IS_UART_GET_FLAG(FLAG) (((FLAG) == UART_FLAG_RX_DATA_RDY) || ((FLAG) == UART_FLAG_RX_OVERRUN)\ + || ((FLAG) == UART_FLAG_PARTY_ERR) || ((FLAG) == UART_FLAG_FRAME_ERR)\ + || ((FLAG) == UART_FLAG_BREAK_ERR) || ((FLAG) == UART_FLAG_THR_EMPTY)\ + || ((FLAG) == UART_FLAG_THR_TSR_EMPTY) || ((FLAG) == UART_FLAG_RX_FIFO_ERR)\ + || ((FLAG) == UART_FLAG_RX_IDLE)) + +/** \defgroup UART_DMA UART DMA + * \{ + * \ingroup UART_Exported_Constants + */ + +#define UART_DMA_DISABLE ((uint16_t)(0 << 3)) +#define UART_DMA_ENABLE ((uint16_t)(1 << 3)) +/** \} */ + +#define IS_UART_DMA_CFG(CFG) (((CFG) == UART_DMA_ENABLE) || ((CFG) == UART_DMA_DISABLE)) + +/** \defgroup UART_Rx_Idle_Time UART Rx Idle Time + * \{ + * \ingroup UART_Exported_Constants + */ +#define UART_RX_IDLE_1BYTE ((uint16_t)(0x00)) +#define UART_RX_IDLE_2BYTE ((uint16_t)(0x01)) +#define UART_RX_IDLE_4BYTE ((uint16_t)(0x02)) +#define UART_RX_IDLE_8BYTE ((uint16_t)(0x03)) +#define UART_RX_IDLE_16BYTE ((uint16_t)(0x04)) +#define UART_RX_IDLE_32BYTE ((uint16_t)(0x05)) +#define UART_RX_IDLE_64BYTE ((uint16_t)(0x06)) +#define UART_RX_IDLE_128BYTE ((uint16_t)(0x07)) +#define UART_RX_IDLE_256BYTE ((uint16_t)(0x08)) +#define UART_RX_IDLE_512BYTE ((uint16_t)(0x09)) +#define UART_RX_IDLE_1024BYTE ((uint16_t)(0x0A)) +#define UART_RX_IDLE_2048BYTE ((uint16_t)(0x0B)) +#define UART_RX_IDLE_4096BYTE ((uint16_t)(0x0C)) +#define UART_RX_IDLE_8192BYTE ((uint16_t)(0x0D)) +#define UART_RX_IDLE_16384BYTE ((uint16_t)(0x0E)) +#define UART_RX_IDLE_32768BYTE ((uint16_t)(0x0F)) +/** \} */ + +#define IS_UART_IDLE_TIME(TIME) ((TIME) <= 0x0F) + +/** \defgroup UART_Interrupts_Mask_Definition UART Interrupts Mask Definition + * \{ + * \ingroup UART_Exported_Constants + */ +#define UART_INT_MASK_RD_AVA ((uint16_t)(1 << 0)) +#define UART_INT_MASK_TX_FIFO_EMPTY ((uint16_t)(1 << 1)) +#define UART_INT_MASK_RX_LINE_STS ((uint16_t)(1 << 2)) +#define UART_INT_MASK_RX_BREAK ((uint16_t)(1 << 4)) +#define UART_INT_MASK_RX_IDLE ((uint16_t)(1 << 5)) +#define UART_INT_MASK_TX_DONE ((uint16_t)(1 << 6))//Transmitter Holding Register(or tx FIFO) and Transmitter shift Register both empty +#define UART_INT_MASK_TX_THD ((uint16_t)(1 << 7)) +/** \} */ + +#define IS_UART_INT_MASK(INT) ((INT) & (UART_INT_MASK_RD_AVA | UART_INT_MASK_TX_FIFO_EMPTY | UART_INT_MASK_RX_LINE_STS |\ + UART_INT_MASK_RX_BREAK | UART_INT_MASK_RX_IDLE |\ + UART_INT_MASK_TX_DONE | UART_INT_MASK_TX_THD)) + +/** \cond Private + * \defgroup UART_Tx_Rx_FIFO_CLEAR_BIT UART TRx Fifo Clear Bits + * \{ + */ +#define FCR_CLEAR_RX_FIFO_Set ((uint32_t)(1 << 1)) +#define FCR_CLEAR_RX_FIFO_Reset ((uint32_t)~(1 << 1)) +#define FCR_CLEAR_TX_FIFO_Set ((uint32_t)(1 << 2)) +#define FCR_CLEAR_TX_FIFO_Reset ((uint32_t)~(1 << 2)) + +/** + * \} + * \endcond + */ + +/** \} */ /* End of group UART_Exported_Constants */ + +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * \defgroup UART_Exported_Functions Peripheral APIs + * \{ + * \ingroup UART + */ + +/** + * \brief Deinitialize the selected UART peripheral registers to their default reset values(turn off UART clock). + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * UART_DeInit(UART0); + * } + * \endcode + */ +void UART_DeInit(UART_TypeDef *UARTx); + +/** + * \brief Initialize the selected UART peripheral according to the specified + * parameters in UART_InitStruct. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] UART_InitStruct: Pointer to a UART_InitTypeDef structure that + * contains the configuration information for the selected UART peripheral. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * UART_DeInit(UART0); + * + * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + * + * UART_InitTypeDef UART_InitStruct; + * UART_StructInit(&UART_InitStruct); + * UART_InitStruct.UART_Div = 20; + * UART_InitStruct.UART_Ovsr = 12; + * UART_InitStruct.UART_OvsrAdj = 0x252; + * UART_InitStruct.UART_RxThdLevel = 16; + * //Add other initialization parameters that need to be configured here. + * UART_Init(UART0, &UART_InitStruct); + * } + * \endcode + */ +void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct); + +/** + * \brief Fills each UART_InitStruct member with its default value. + * \param[in] UART_InitStruct: pointer to an UART_InitTypeDef structure which will be initialized. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * UART_DeInit(UART0); + * + * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + * + * UART_InitTypeDef UART_InitStruct; + * UART_StructInit(&UART_InitStruct); + * UART_InitStruct.UART_Div = 20; + * UART_InitStruct.UART_Ovsr = 12; + * UART_InitStruct.UART_OvsrAdj = 0x252; + * UART_InitStruct.UART_RxThdLevel = 16; + * //Add other initialization parameters that need to be configured here. + * UART_Init(UART0, &UART_InitStruct); + * } + * \endcode + */ +void UART_StructInit(UART_InitTypeDef *UART_InitStruct); + +/** + * \brief Mask or unmask the specified UART interrupt source. + * \param[in] UART_INT: Specified the UART interrupt source that to be mask or unmask. + * This parameter can be one of the following values: + * \arg UART_INT_MASK_RD_AVA: Mask INTCR(erbi). + * \arg UART_INT_MASK_FIFO_EMPTY: Mask INTCR(etbei). + * \arg UART_INT_MASK_LINE_STS: Mask INTCR(elsi). + * \arg UART_INT_MASK_RX_BREAK: Mask rx break interrupt. + * \arg UART_INT_MASK_RX_IDLE: Mask rx break interrupt. + * \arg UART_INT_MASK_TX_DONE: Mask the interrupt tx done interrupt. + * \arg UART_INT_MASK_TX_THD: Mask tx fifo threshold interrupt. + * \param[in] NewState: New state of the specified UART interrupt source. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * UART_DeInit(UART0); + * + * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + * + * UART_InitTypeDef UART_InitStruct; + * UART_StructInit(&UART_InitStruct); + * UART_InitStruct.UART_Div = 20; + * UART_InitStruct.UART_Ovsr = 12; + * UART_InitStruct.UART_OvsrAdj = 0x252; + * UART_InitStruct.UART_RxThdLevel = 16; + * //Add other initialization parameters that need to be configured here. + * UART_Init(UART0, &UART_InitStruct); + * + * UART_MaskINTConfig(UART0, UART_INT_MASK_RD_AVA, ENABLE); + * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + * UART_MaskINTConfig(UART0, UART_INT_MASK_RD_AVA, DISABLE); + * } + * \endcode + */ +void UART_MaskINTConfig(UART_TypeDef *UARTx, uint32_t UART_INT_MASK, + FunctionalState newState); +/** + * rtl876x_uart.h + * \brief Enables or disables the specified UART interrupts. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] UART_IT: Specified the UART interrupt source that to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg UART_INT_RD_AVA: Rx data avaliable interrupt source. + * \arg UART_INT_TX_FIFO_EMPTY: Tx FIFO empty interrupt source. + * \arg UART_INT_RX_LINE_STS: Rx line status interrupt source. + * \arg UART_INT_TX_DONE: Tx done interrupt source. + * \arg UART_INT_TX_THD: Tx threshold(FIFO data length <= thredhold) interrupt source. + * \arg UART_INT_RX_BREAK: Rx break signal interrupt source. + * \arg UART_INT_RX_IDLE: Rx idle interrupt source. + * \param[in] newState: New state of the specified UART interrupt source. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void driver_uart_init(void) + * { + * UART_DeInit(UART0); + * + * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + * + * UART_InitTypeDef UART_InitStruct; + * UART_StructInit(&UART_InitStruct); + * UART_InitStruct.UART_Div = 20; + * UART_InitStruct.UART_Ovsr = 12; + * UART_InitStruct.UART_OvsrAdj = 0x252; + * UART_InitStruct.UART_RxThdLevel = 16; + * //Add other initialization parameters that need to be configured here. + * UART_Init(UART0, &UART_InitStruct); + * + * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + * } + * \endcode + */ +void UART_INTConfig(UART_TypeDef *UARTx, uint32_t UART_IT, FunctionalState newState); + +/** + * \brief Send data. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] inBuf: Buffer of data to be sent. + * \param[in] count: Length of data to be sent. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data[] = "UART demo"; + * UART_SendData(UART0, data, sizeof(data)); + * } + * \endcode + */ +void UART_SendData(UART_TypeDef *UARTx, const uint8_t *inBuf, uint16_t count); + +/** + * \brief Receive data from RX FIFO. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[out] outBuf: Buffer to store data which read from RX FIFO. + * \param[in] count: Length of data to read. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data[32] = {10}; + * UART_ReceiveData(UART0, data, 10); + * } + * \endcode + */ +void UART_ReceiveData(UART_TypeDef *UARTx, uint8_t *outBuf, uint16_t count); + +/** + * \brief Set UART communication baudrate. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] div: Parameter of the selected UART baudrate. + * \param[in] ovsr: Parameter of the selected UART baudrate. + * \param[in] ovsr_adj: Parameter of the selected UART baudrate. + * \return None. + * + * Example usage + * \code{.c} + * UART_BaudRate_Table + * These three parameters set the baud rate calibration parameters of UART. + * Note that these parameters are for data length 8 bits (clock source 40MHz only). + baudrate | div | ovsr | ovsr_adj +-------------------------------------------------------- + 1200Hz | 0xC35 | 0x5 | 0x16D + 4800Hz | 0x682 | 0x0 | 0x0 + 7200Hz | 0x457 | 0x0 | 0x0 + 9600Hz | 0x341 | 0x0 | 0x0 + 14400Hz | 0xFA | 0x6 | 0x10 + 19200Hz | 0x120 | 0x2 | 0x3 + 28800Hz | 0xC0 | 0x2 | 0x3 + 38400Hz | 0x90 | 0x2 | 0x3 + 57600Hz | 0x60 | 0x2 | 0x3 + 76800Hz | 0x48 | 0x2 | 0x3 + 115200Hz | 0x30 | 0x2 | 0x3 + 230400Hz | 0x18 | 0x2 | 0x3 + 460800Hz | 0xC | 0x2 | 0x3 + 500000Hz | 0x8 | 0x5 | 0x0 + 921600Hz | 0x6 | 0x2 | 0x3 + 1000000Hz | 0x8 | 0x0 | 0x0 + 1382400Hz | 0x2 | 0x9 | 0xAA + 1444400Hz | 0x2 | 0x8 | 0x1F7 + 1500000Hz | 0x2 | 0x8 | 0x292 + 1843200Hz | 0x2 | 0x5 | 0x1F7 + 2000000Hz | 0x4 | 0x0 | 0x0 + 3000000Hz | 0x1 | 0x8 | 0x292 + 4000000Hz | 0x1 | 0x5 | 0x0 + ------------------------------------------------ + * void uart_demo(void) + * { + * uint16_t div = 20; + * uint16_t ovsr = 12; + * uint16_t ovsr_adj = 0x252; + * UART_SetBaudRate(UART0, div, ovsr, ovsr_adj); + * } + * \endcode + */ +void UART_SetBaudRate(UART_TypeDef *UARTx, uint16_t div, uint16_t ovsr, uint16_t ovsr_adj); + +/** + * \brief Set UART communication parameters. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] wordLen: Data width of the selected UART peripheral. + * This parameter can be one of the following values: + * \arg UART_WORD_LENGTH_7BIT: 7-bit data length. + * \arg UART_WORD_LENGTH_8BIT: 8-bit data length. + * \param[in] parity: parity of the selected UART peripheral. + * This parameter can be one of the following values: + * \arg UART_STOP_BITS_1: 1-bit stop bit. + * \arg UART_STOP_BITS_2: 2-bit stop bit. + * \param[in] stopBits: Stop bit of the selected UART peripheral. + * This parameter can be one of the following values: + * \arg UART_PARITY_NO_PARTY: No parity. + * \arg UART_PARITY_ODD: Odd parity. + * \arg UART_PARITY_EVEN: Even parity. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint16_t word_len = UART_WORD_LENGTH_8BIT; + * uint16_t parity = UART_PARITY_NO_PARTY; + * uint16_t stop_bits = UART_STOP_BITS_1; + * UART_SetParams(UART0, wordLen, parity, stopBits); + * } + * \endcode + */ +void UART_SetParams(UART_TypeDef *UARTx, uint16_t wordLen, uint16_t parity, uint16_t stopBits); + +/** + * \brief Config UART loopback function. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] NewState: Enable or disable UART loopback function. + * This parameter can be: ENABLE or DISABLE. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * UART_LoopBackCmd(UART0, ENABLE); + * } + * \endcode + */ +void UART_LoopBackCmd(UART_TypeDef *UARTx, FunctionalState NewState); + +/** + * \brief Check whether the specified UART flag is set. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] UART_FLAG: Specified UART flag to check. + * This parameter can be one of the following values: + * \arg UART_FLAG_RX_DATA_AVA: Rx data is avaliable. + * \arg UART_FLAG_RX_OVERRUN: Rx FIFO overrun. + * \arg UART_FLAG_RX_PARITY_ERR: Rx parity error. + * \arg UART_FLAG_RX_FRAME_ERR: Rx frame error. + * \arg UART_FLAG_RX_BREAK_ERR: Rx break error. + * \arg UART_FLAG_TX_FIFO_EMPTY: Tx Holding Register or Tx FIFO empty + * \arg UART_FLAG_TX_EMPTY: Tx FIFO and Tx shift register are both empty. + * \arg UART_FLAG_RX_FIFO_ERR: Rx FIFO error. + * \arg UART_FLAG_RX_BREAK: Rx break. + * \arg UART_FLAG_RX_IDLE: Rx idle. + * \arg UART_FLAG_TX_DONE: Tx waveform done & TX_FIFO_EMPTY = 1. + * \arg UART_FLAG_TX_THD: TX_FIFO_LEVEL<=txfifo_trigger_level. + * \return New status of UART flag. + * \retval SET: The specified UART flag bit is set. + * \retval RESET: The specified flag is not set. + * + * Example usage + * \code{.c} + * + * void uart_senddata_continuous(UART_TypeDef *UARTx, const uint8_t *pSend_Buf, uint16_t vCount) + * { + * uint8_t count; + * + * while (vCount / UART_TX_FIFO_SIZE > 0) + * { + * while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0); + * for (count = UART_TX_FIFO_SIZE; count > 0; count--) + * { + * UARTx->RB_THR = *pSend_Buf++; + * } + * vCount -= UART_TX_FIFO_SIZE; + * } + * + * while (UART_GetFlagStatus(UARTx, UART_FLAG_TX_FIFO_EMPTY) == 0); + * while (vCount--) + * { + * UARTx->RB_THR = *pSend_Buf++; + * } + * } + * \endcode + */ +FlagStatus UART_GetFlagStatus(UART_TypeDef *UARTx, uint32_t UART_FLAG); + +/** + * \brief Send one byte of data. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \param[in] data: Byte data to send. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data = 0x55; + * UART_SendByte(UART0, data); + * } + * \endcode + */ +__STATIC_INLINE void UART_SendByte(UART_TypeDef *UARTx, uint8_t data) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + UARTx->RB_THR = data; + + return; +} + +/** + * \brief Read a byte of data from UART RX FIFO. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return Which byte data has been read. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data = UART_ReceiveByte(UART0); + * + * } + * \endcode + */ +__STATIC_INLINE uint8_t UART_ReceiveByte(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + return (uint8_t)(UARTx->RB_THR); +} + +/** + * \brief Get interrupt identifier of the selected UART peripheral. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return The interrupt identifier value. + * This return value can be one or a combination of the following: + * \retval UART_INT_ID_LINE_STATUS: Rx line status interrupt ID. + * \retval UART_INT_ID_RX_LEVEL_REACH: Rx data available or trigger level reached interrupt ID. + * \retval UART_INT_ID_RX_TMEOUT: Rx FIFO data timeout interrupt ID. + * \retval UART_INT_ID_TX_EMPTY: Tx FIFO empty interrupt ID. + * + * Example usage + * \code{.c} + * + * void board_uart_init(void) + * { + * Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); + * Pad_Config(UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); + * + * Pinmux_Config(UART_TX_PIN, UART0_TX); + * Pinmux_Config(UART_RX_PIN, UART0_RX); + * } + * + * void driver_uart_init(void) + * { + * RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + * + * UART_InitTypeDef UART_InitStruct; + * UART_StructInit(&UART_InitStruct); + * + * UART_Init(UART0, &UART_InitStruct); + * + * //enable rx interrupt and line status interrupt + * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + * UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE); + * + * NVIC_InitTypeDef NVIC_InitStruct; + * NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn; + * NVIC_InitStruct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE; + * NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + * NVIC_Init(&NVIC_InitStruct); + * } + * + * void UART0_Handler() + * { + * uint16_t rx_len = 0; + * uint8_t uart_rev_data[32]; + * + * //Get interrupt ID. + * uint32_t int_status = UART_GetIID(UART0); + * + * //Disable interrupt. + * UART_INTConfig(UART0, UART_INT_RD_AVA, DISABLE); + * + * if (UART_GetFlagStatus(UART0, UART_FLAG_RX_IDLE) == SET) + * { + * UART_INTConfig(UART0, UART_INT_RX_IDLE, DISABLE); + * //Add user code here. + * UART_ClearRxFIFO(UART0); + * UART_INTConfig(UART0, UART_INT_RX_IDLE, ENABLE); + * } + * + * switch (int_status & 0x0E) + * { + * case UART_INT_ID_RX_DATA_TIMEOUT: + * rx_len = UART_GetRxFIFODataLen(UART0); + * UART_ReceiveData(UART0, uart_rev_data, rx_len); + * //Add user code here. + * break; + * + * case UART_INT_ID_LINE_STATUS: + * //Add user code here. + * break; + * + * case UART_INT_ID_RX_LEVEL_REACH: + * rx_len = UART_GetRxFIFODataLen(UART0); + * UART_ReceiveData(UART0, uart_rev_data, rx_len); + * //Add user code here. + * break; + * + * case UART_INT_ID_TX_EMPTY: + * //Add user code here. + * break; + * + * default: + * break; + * } + * + * UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + * } + * \endcode + */ +__STATIC_INLINE uint16_t UART_GetIID(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + return (uint16_t)(UARTx->INTID_FCR & (0x0000000E)); +} + +/** + * \brief Clear Tx FIFO of the selected UART peripheral. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * UART_ClearTxFIFO(UART0); + * } + * \endcode + */ +__STATIC_INLINE void UART_ClearTxFIFO(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + UARTx->INTID_FCR = (((UARTx->STSR & BIT24) >> 21) | ((UARTx->STSR & 0x7C000000) >> 18) | (( + UARTx->STSR & BIT25) >> 25) | FCR_CLEAR_TX_FIFO_Set); + + return; +} + +/** + * \brief Clear Rx FIFO of the selected UART peripheral. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return None. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * UART_ClearRxFIFO(UART0); + * } + * \endcode + */ +__STATIC_INLINE void UART_ClearRxFIFO(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + UARTx->INTID_FCR = (((UARTx->STSR & BIT24) >> 21) | ((UARTx->STSR & 0x7C000000) >> 18) | (( + UARTx->STSR & BIT25) >> 25) | FCR_CLEAR_RX_FIFO_Set); + + return; +} + +/** + * \brief Get the data length in Tx FIFO of the selected UART peripheral. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return Data length in UART TX FIFO. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data_len = UART_GetTxFIFODataLen(UART0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t UART_GetTxFIFODataLen(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + return (uint8_t)(UARTx->FIFO_LEVEL & 0x1F); +} + +/** + * \brief Get the data length in Rx FIFO of the selected UART peripheral. + * \param[in] UARTx: UART peripheral selected, x can be 0 ~ 1. + * \return Data length in UART RX FIFO. + * + * Example usage + * \code{.c} + * + * void uart_demo(void) + * { + * uint8_t data_len = UART_GetRxFIFODataLen(UART0); + * } + * \endcode + */ +__STATIC_INLINE uint8_t UART_GetRxFIFODataLen(UART_TypeDef *UARTx) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + return (uint8_t)((UARTx->FIFO_LEVEL >> 8) & 0x3F); +} + +/** \} */ /* End of group UART_Exported_Functions */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_UART_H_ */ + + +/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/ + diff --git a/inc/peripheral/rtl876x_wdg.h b/inc/peripheral/rtl876x_wdg.h new file mode 100644 index 0000000..aa2bdfc --- /dev/null +++ b/inc/peripheral/rtl876x_wdg.h @@ -0,0 +1,156 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file rtl876x_wdg.h +* @brief header file of watch dog driver. +* @details +* @author Lory_xu +* @date 2016-06-12 +* @version v0.1 +* ********************************************************************************************************* +*/ + +#ifndef _RTL876X_WDG_H_ +#define _RTL876X_WDG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x.h" +#include "rtl876x_bitfields.h" + +/** @addtogroup IO Peripheral Drivers + * + * @defgroup WATCH_DOG WATCH_DOG + * @brief Watch Dog driver module + * \ingroup IO + * @{ + */ + +/** @defgroup WATCH_DOG_Exported_Types Watch Dog Exported Types + * @{ + */ +typedef enum +{ + INTERRUPT_CPU = 0, + RESET_ALL_EXCEPT_AON = 1, + RESET_CORE_DOMAIN = 2, + RESET_ALL = 3 +} T_WDG_MODE; + +/** + * wdg reset reason introduction: + * 1.If you want to get reset reason from aon 0x16, deviding three types: + * a) HW reset: aon reg 0x16 is cleared to 0, magic pattern on ram will change + * b) SW RESET_ALL: aon reg 0x16 is cleared to 0,but magic pattern on ram not change + * c) SW RESET_ALL_EXCEPT_AON: obtain reset reason by reading aon reg 0x16 . + * 2. Attention: don't use 0x1 as your reset reason when using RESET_ALL_EXCEPT_AON type! Because 0x1 is default value. + */ +typedef enum +{ + RESET_REASON_HW = 0x0, /* HW reset */ + RESET_REASON_WDG_TIMEOUT = 0x1, + RESET_REASON_POWERDOWN = 0xC0, + SW_RESET_APP_START = 0xD0, + SWITCH_HCI_MODE = 0xD1, + SWITCH_TEST_MODE = 0xD2, + DFU_SWITCH_TO_OTA_MODE = 0xD3, + DFU_ACTIVE_RESET = 0xD4, + DFU_FAIL_RESET = 0xD5, + UPPER_CMD_RESET, + SINGLE_TONE_TIMEOUT_RESET, + UART_CMD_RESET, + RESET_REASON_FACTORY_RESET, + RESET_REASON_LPC_TRIGGER, + KEYBOARD_LOW_POWER_RESET, + MOUSE_LOW_POWER_RESET, + MOUSE_SWITCH_TO_USB_MODE, + MOUSE_SWITCH_TO_UART_DFU_MODE, + EXIT_RF_TEST_MODE, + SW_RESET_APP_END = 0xFF, +} T_SW_RESET_REASON; + +typedef void (*APP_CB_WDG_RESET_TYPE)(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason); +typedef bool (*BOOL_WDG_CB)(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason); + +/** + * @} + */ + +/** @defgroup WATCH_DOG_Exported_Variables Watch Dog Exported Variables + * @{ + */ + +extern APP_CB_WDG_RESET_TYPE app_cb_wdg_reset; +extern BOOL_WDG_CB user_wdg_cb; + +/** + * @} + */ + +/** @defgroup WATCH_DOG_Exported_Functions Watch Dog Exported Functions + * @{ + */ + +/** + * @brief Watch Dog Clock Enable. + */ +extern void WDG_ClockEnable(void); + +/** + * @brief Watch Dog Timer Config. + * @param div_factor: 16Bit: 32.768k/(1+divfactor). + * @param cnt_limit: 2^(cnt_limit+1) - 1 ; max 11~15 = 0xFFF. + * @param wdg_mode: 0: interrupt CPU + * 1: reset all except aon + * 2: reset core domain + * 3: reset all + * @retval none. + */ +extern void WDG_Config(uint16_t div_factor, uint8_t cnt_limit, T_WDG_MODE wdg_mode); + +/** + * @brief Watch Dog Timer Enable. + NOTE: When call WDG_Disable() before entering dlps, must call WDG_Config() before WDG_Enable() when exiting dlps! + */ +extern void WDG_Enable(void); + +/** + * @brief Watch Dog Timer Disable. + */ +extern void WDG_Disable(void); + +/** + * @brief Watch Dog Timer Restart. + */ +extern void WDG_Restart(void); + +/** + * @brief Watch Dog System Reset. + * @param wdg_mode: 0: interrupt CPU + * 1: reset all except aon + * 2: reset core domain + * 3: reset all + */ +extern void WDG_SystemReset(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason); + + +extern T_SW_RESET_REASON reset_reason_get(void); + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif //_RTL876X_WDG_H_ diff --git a/inc/platform/adc_lib.h b/inc/platform/adc_lib.h new file mode 100644 index 0000000..d70948e --- /dev/null +++ b/inc/platform/adc_lib.h @@ -0,0 +1,47 @@ +#ifndef __ADC_K_LIB_H +#define __ADC_K_LIB_H + +#include +#include + +#define SOC_VERSION_CHECK 1 + +#define ADC_K_VERSION_N2 1 +#define ADC_K_VERSION_N1 1 +#define ADC_K_VERSION_0 1 +#define ADC_K_VERSION_P1 1 + +#define USE_ADC_DIVIDE_SINGLE_MODE 1 +#define USE_ADC_BYPASS_SINGLE_MODE 1 +#define USE_ADC_DIVIDE_DIFF_MODE 1 +#define USE_ADC_BYPASS_DIFF_MODE 1 + +typedef enum +{ + DIVIDE_SINGLE_MODE = 1, + BYPASS_SINGLE_MODE = 2, + DIVIDE_DIFFERENTIAL_MODE = 3, + BYPASS_DIFFERENTIAL_MODE = 4, +} ADC_SampleMode; + +typedef enum +{ + NO_ERROR = 0, + PARAMETER_ERROR = -1, + RAM_DATA_ERROR = -2, + NO_CALIBRATION = -3, + VERSION_ERROR = -4, +} ADC_ErrorStatus; + +extern int8_t ADC_K_Version; +extern uint16_t ADC_Resistance_Value; + +bool ADC_CalibrationInit(void); +float ADC_GetVoltage(const ADC_SampleMode vSampleMode, int32_t vSampleData, + ADC_ErrorStatus *pErrorStatus); +uint16_t ADC_GetResistance(void); + + + + +#endif diff --git a/inc/platform/aes_api.h b/inc/platform/aes_api.h new file mode 100644 index 0000000..c206e61 --- /dev/null +++ b/inc/platform/aes_api.h @@ -0,0 +1,409 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file aes_api.h + * @brief aes apis abstracted for encryption related. + * @details AES encryption APIs which delivers HW/SW implemented reliable and safe AES solution. + * @author Abel + * @date 2017.5.17 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef _AES_API_H_ +#define _AES_API_H_ + +/*============================================================================* + * Header Files +*============================================================================*/ +#include +#include + + +/** @defgroup AES_API AES API Sets + * @brief API sets for aes encryption implementation + * @{ + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup AES_API_Exported_Functions AES API Sets Exported Functions + * @{ + */ + +/** + * @brief 128 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ecb_encrypt(uint8_t plaintext[16], const uint8_t key[16], uint8_t *encrypted); + +/** + * @brief 128 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ecb_encrypt_buffer(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted, + uint32_t data_word_len); + +/** + * @brief 128 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @return decryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes128_ecb_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output); + +/** + * @brief 128 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return decryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes128_ecb_decrypt_buffer(uint8_t *input, const uint8_t key[16], uint8_t *output, + uint32_t data_word_len); + +/** + * @brief 128 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ecb_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[16], + uint8_t *encrypted); + +/** + * @brief 128 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ecb_encrypt_msb2lsb_buffer(uint8_t *plaintext, const uint8_t key[16], + uint8_t *encrypted, uint32_t data_word_len); + +/** + * @brief 128 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @return decryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes128_ecb_decrypt_msb2lsb(uint8_t *input, const uint8_t *key, uint8_t *output); + +/** + * @brief 128 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return decryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes128_ecb_decrypt_msb2lsb_buffer(uint8_t *input, const uint8_t key[16], uint8_t *output, + uint32_t data_word_len); + +/** + * @brief 256 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_encrypt(uint8_t plaintext[16], const uint8_t key[32], uint8_t *encrypted); + +/** + * @brief 256 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_encrypt_buffer(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted, + uint32_t data_word_len); + +/** + * @brief 256 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @return decryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes256_ecb_decrypt(uint8_t *input, const uint8_t *key, uint8_t *output); + +/** + * @brief 256 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return decryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] +*/ +bool aes256_ecb_decrypt_buffer(uint8_t *input, const uint8_t key[32], uint8_t *output, + uint32_t data_word_len); + +/** + * @brief 256 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[32], + uint8_t *encrypted); + +/** + * @brief 256 bit AES ECB encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_encrypt_msb2lsb_buffer(uint8_t *plaintext, const uint8_t key[32], + uint8_t *encrypted, uint32_t data_word_len); + +/** + * @brief 256 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @return decryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_decrypt_msb2lsb(uint8_t *input, const uint8_t *key, uint8_t *output); + +/** + * @brief 256 bit AES ECB decryption on speicified encrypted data and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return decryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ecb_decrypt_msb2lsb_buffer(uint8_t *input, const uint8_t key[32], uint8_t *output, + uint32_t data_word_len); + + +/** + * @brief 128 bit AES CBC encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_cbc_encrypt(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 128 bit AES CBC descryption on speicified plaintext and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_cbc_decrypt(uint8_t *input, const uint8_t key[16], uint8_t *output, uint32_t *p_iv, + uint32_t data_word_len); + +/** + * @brief 128 bit AES CBC encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_cbc_encrypt_msb2lsb(uint8_t plaintext[16], const uint8_t key[16], uint8_t *encrypted, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 128 bit AES CBC descryption on speicified plaintext and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note most significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_cbc_decrypt_msb2lsb(uint8_t *input, const uint8_t key[16], uint8_t *output, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 256 bit AES CBC encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_cbc_encrypt(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 256 bit AES CBC descryption on speicified plaintext and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_cbc_decrypt(uint8_t *input, const uint8_t key[32], uint8_t *output, uint32_t *p_iv, + uint32_t data_word_len); + +/** + * @brief 128 bit AES CTR encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ctr_encrypt(uint8_t *plaintext, const uint8_t key[16], uint8_t *encrypted, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 128 bit AES CTR descryption on speicified plaintext and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes128_ctr_decrypt(uint8_t *input, const uint8_t key[16], uint8_t *output, uint32_t *p_iv, + uint32_t data_word_len); + +/** + * @brief 256 bit AES CTR encryption on speicified plaintext and keys + * @param plaintext specifed plain text to be encypted + * @param key keys to encrypt the plaintext + * @param encrypted output buffer to store encrypted data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ctr_encrypt(uint8_t *plaintext, const uint8_t key[32], uint8_t *encrypted, + uint32_t *p_iv, uint32_t data_word_len); + +/** + * @brief 256 bit AES CTR descryption on speicified plaintext and keys + * @param input specifed encypted data to be decypted + * @param key keys to decrypt the data + * @param output output buffer to store plain data + * @param p_iv initialization vector (IV) for CBC mode + * @param data_word_len word length of the data to be descrypted, must be multiples of 4 + * @return encryption results + * @retval true successful + * @retval false fail + * @note least significant octet of encrypted data corresponds to encypted[0] + */ +bool aes256_ctr_decrypt(uint8_t *input, const uint8_t key[32], uint8_t *output, uint32_t *p_iv, + uint32_t data_word_len); + +/** @} */ /* End of group AES_API_Exported_Functions */ + +/** @} */ /* End of group AES_API */ + + +#endif diff --git a/inc/platform/app_define.h b/inc/platform/app_define.h new file mode 100644 index 0000000..6ad379a --- /dev/null +++ b/inc/platform/app_define.h @@ -0,0 +1,84 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file app_define.h + * @brief + * @author + * @date + * @version + *************************************************************************************** + * @attention + *

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    + *************************************************************************************** + */ + +#ifndef APP_DEFINE_H +#define APP_DEFINE_H + +/** @defgroup APP_DEFINE APP Define + * @{ + */ + + + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup APP_DEFINE_Exported_Macros App Define Exported Macros + * @brief + * @{ + */ +#ifndef UNUSED +#define UNUSED(expr) do { (void)(expr); } while (0) +#endif + +//#pragma diag_suppress 174 // expression has no effect +//#pragma diag_suppress 223 // function declared implicitly + +/////////////////////////////////////////////////////////////////// + +#define SPIFLASH0IntrHandler SPI_Flash0_Handler +#define SPIFLASH1IntrHandler SPI_Flash1_Handler +#define Gpio2IntrHandler GPIO2_Handler +#define Gpio3IntrHandler GPIO3_Handler +#define Gpio4IntrHandler GPIO4_Handler +#define Gpio5IntrHandler GPIO5_Handler +#define Timer3IntrHandler Timer3_Handler +#define Timer4IntrHandler Timer4_Handler +#define Timer5IntrHandler Timer5_Handler +#define Timer6IntrHandler Timer6_Handler +#define Timer7IntrHandler Timer7_Handler +#define Gpio6IntrHandler GPIO6_Handler +#define Gpio7IntrHandler GPIO7_Handler +#define Gpio8IntrHandler GPIO8_Handler +#define Gpio9IntrHandler GPIO9_Handler +#define Gpio10IntrHandler GPIO10_Handler +#define Gpio11IntrHandler GPIO11_Handler +#define Gpio12IntrHandler GPIO12_Handler +#define Gpio13IntrHandler GPIO13_Handler +#define Gpio14IntrHandler GPIO14_Handler +#define Gpio15IntrHandler GPIO15_Handler +#define Gpio16IntrHandler GPIO16_Handler +#define Gpio17IntrHandler GPIO17_Handler +#define Gpio18IntrHandler GPIO18_Handler +#define Gpio19IntrHandler GPIO19_Handler +#define Gpio20IntrHandler GPIO20_Handler +#define Gpio21IntrHandler GPIO21_Handler +#define Gpio22IntrHandler GPIO22_Handler +#define Gpio23IntrHandler GPIO23_Handler +#define Gpio24IntrHandler GPIO24_Handler +#define Gpio25IntrHandler GPIO25_Handler +#define Gpio26IntrHandler GPIO26_Handler +#define Gpio27IntrHandler GPIO27_Handler +#define Gpio28IntrHandler GPIO28_Handler +#define Gpio29IntrHandler GPIO29_Handler +#define Gpio30IntrHandler GPIO30_Handler +#define Gpio31IntrHandler GPIO31_Handler +/** End of APP_DEFINE_Exported_Macros + * @} + */ + +/** @} */ /* End of group APP_DEFINE */ + +#endif // APP_DEFINE_H diff --git a/inc/platform/app_section.h b/inc/platform/app_section.h new file mode 100644 index 0000000..5a70c57 --- /dev/null +++ b/inc/platform/app_section.h @@ -0,0 +1,64 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file app_section.h + * @brief + * @author + * @date 2017.6.7 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef _APP_SECTION_H_ +#define _APP_SECTION_H_ + +/** @defgroup APP_SECTION APP Section + * @brief memory section definition for user application. + * @{ + */ +/* app encryption */ +#define APP_ENCRYPTION_SIGNATURE __attribute__((section(".encryption.signature"))) +#define APP_ENCRYPION_DUMMY_ALIGN __attribute__((section(".encryption.dummy.align"))) __attribute__((aligned(16))) +/* app encryption code*/ +#define APP_ENCRYPTION_TEXT_SECTION __attribute__((section(".app.encryption.text"))) + +/*flash const data or flash function */ +#define APP_FLASH_HEADER __attribute__((section(".app.flash.header"))) __attribute__((used)) +#define APP_FLASH_HEADER_AUTH __attribute__((section(".app.flash.header.auth"))) __attribute__((used)) +#define APP_FLASH_HEADER_EXT __attribute__((section(".app.flash.header_ext"))) __attribute__((used)) +/* flash code */ +#define APP_FLASH_TEXT_SECTION __attribute__((section(".app.flash.text"))) +/* flash ro data */ +#define APP_FLASH_RODATA_SECTION __attribute__((section(".app.flash.rodata"))) +/* ram code */ +#define DATA_RAM_FUNCTION __attribute__((section(".app.data_ram.text"))) /*!< data ram code */ +#define SHARE_CACHE_RAM_SECTION __attribute__((section(".ram.sharecacheram.text"))) /*!< share cache ram code or data*/ + +/* global variable or ram function, data on (default) */ +#define RAM_DATAON_DATA_SECTION __attribute__((section(".ram.dataon.data"))) /*!< DATA ON */ +#define RAM_DATAON_BSS_SECTION __attribute__((section(".ram.dataon.bss"))) /*!< DATA ON */ +#define RAM_DATAON_UNINIT_SECTION __attribute__((section(".uninit.ram"))) /*!< DATA ON */ + +/* buffer on */ +#define RAM_BUFFERON_DATA_SECTION __attribute__((section(".ram.bufferon.data"))) /*!< BUFFER ON */ +#define RAM_BUFFERON_BSS_SECTION __attribute__((section(".ram.bufferon.bss"))) /*!< BUFFER ON */ + + +/* overlay section, only support three overlay sections now. */ +#define OVERLAY_SECTION_BOOT_ONCE __attribute__((section(".app.overlay_a"))) /*!< overlay a section */ +#define OVERLAY_B_SECTION __attribute__((section(".app.overlay_b"))) /*!< overlay b section */ +#define OVERLAY_C_SECTION __attribute__((section(".app.overlay_c"))) /*!< overlay c section */ + + + + +/** @} */ /* End of group APP_SECTION */ + +#endif /* _APP_SECTION_H_ */ diff --git a/inc/platform/auto_k_rf.h b/inc/platform/auto_k_rf.h new file mode 100644 index 0000000..ebf98ff --- /dev/null +++ b/inc/platform/auto_k_rf.h @@ -0,0 +1,107 @@ +#ifndef _AUTO_K_RF_H_ +#define _AUTO_K_RF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define FLT_MAX 40000 + +#define K_RF_SUCCESS 0 +#define K_RF_READ_DRIFT_FAIL 1 +#define K_RF_K_FAIL 2 +#define K_RF_WRITE_CONFIG_FAIL 3 + +#define BASE_MAGNIFIED 1000000 +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +typedef unsigned char BOOLEAN; +typedef void VOID; +typedef unsigned char UCHAR; +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef unsigned long long UINT64; +typedef signed char CHAR; +typedef signed char INT8; +typedef signed short INT16; +typedef signed int INT32; +typedef signed long long INT64; + +#define MODEM_PI_PAGE_0 0 +#define MODEM_PI_PAGE_1 1 +#define MODEM_PI_PAGE_2 2 +#define MODEM_PI_PAGE_3 3 +#define MODEM_PI_PAGE_4 4 +#define MODEM_PI_PAGE_5 5 +#define MODEM_PI_PAGE_6 6 +#define MODEM_PI_PAGE_7 7 + +#define TRANS_MODEM_REG(x) (((x) >> 1) | 0x40) /* this is used to translate byte address to word address*/ + +extern UINT32(*rtk_read_modem_radio_reg_pi)(UCHAR modem_page, UCHAR addr, UCHAR type); +extern void (*rtk_write_modem_radio_reg_pi)(UCHAR modem_page, UCHAR addr, UCHAR type, UINT16 val); +extern UINT16(*rtk_ioq_read_rfc_reg)(UINT8); +extern void (*rtk_write_rfc_reg_pi)(UINT8, UINT16); +extern void (*rtk_update_rfc_reg_pi)(UINT8, UINT16, UINT16); + +#define RTK_WRITE_RF_REG_PI(waddr, value) rtk_write_rfc_reg_pi(waddr, value) +#define RTK_READ_RF_REG_PI(waddr) rtk_ioq_read_rfc_reg(waddr) +#define RTK_UPDATE_RF_REG_PI(waddr, bm_mask, value) rtk_update_rfc_reg_pi(waddr, bm_mask, value) +#define RTK_WRITE_MODEM_REG_PI(modem_page, waddr, value) \ + rtk_write_modem_radio_reg_pi(modem_page, waddr, TYPE_MODEM, value) +#define RTK_READ_MODEM_REG_PI(modem_page, waddr) rtk_read_modem_radio_reg_pi(modem_page, waddr, TYPE_MODEM) +#define RTK_UPDATE_MODEM_REG_PI(modem_page, waddr, bm_mask, value) \ + { \ + UINT16 temp = RTK_READ_MODEM_REG_PI(modem_page, waddr); \ + RTK_WRITE_MODEM_REG_PI(modem_page, waddr, (temp & ~(bm_mask)) | ((bm_mask) & (value))); \ + } + +void init_dft(UINT8 rx_channel, UINT16 rx_gain, UINT16 dft_size, UINT16 pwr_avg_times, + UINT8 reg_dft_sum_scale, UINT32 *reg08, UINT32 *reg0A); +void deinit_dft(UINT32 reg08, UINT32 reg0A); + +double modem_dft(double IF_val, UINT32 *raw_data); + +uint8_t Auto_K_RF(uint8_t rx_channel, uint32_t freq_drift_threshold, uint8_t *cal_xtal_result); + +uint8_t Auto_K_RF_MP(uint8_t rx_channel, uint32_t freq_drift_threshold, uint8_t *cal_xtal_result, + uint8_t cl_type, uint8_t calMethod); +#ifdef __cplusplus +} +#endif + +#endif /* _AUTO_K_RF_H_ */ diff --git a/inc/platform/auto_k_rf_bonding_dut.h b/inc/platform/auto_k_rf_bonding_dut.h new file mode 100644 index 0000000..9c22923 --- /dev/null +++ b/inc/platform/auto_k_rf_bonding_dut.h @@ -0,0 +1,38 @@ +#ifndef _AUTO_K_RF_BONDING_DUT_H +#define _AUTO_K_RF_BONDING_DUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/** + * @brief get information from the DUT. + * @param golden_info golden information + * @param dut_info DUT information + * @return Status of Operation. + * @retval true success + * @retval false fail + * @note the function will firstly check the golden_info, if check success return the dut_info. +*/ +bool dut_info_get(uint8_t golden_info[32], uint8_t dut_info[32]); + +/** + * @brief check the verify result. + * @param result_info result information + * @return Status of Operation. + * @retval true success + * @retval false fail +*/ +bool check_verify_result(uint8_t result_info[16]); + + + +#ifdef __cplusplus +} +#endif + +#endif /*_AUTO_K_RF_BONDING_DUT_H*/ diff --git a/inc/platform/auto_k_rf_bonding_golden.h b/inc/platform/auto_k_rf_bonding_golden.h new file mode 100644 index 0000000..29e3ffc --- /dev/null +++ b/inc/platform/auto_k_rf_bonding_golden.h @@ -0,0 +1,57 @@ +#ifndef _AUTO_K_RF_BONDING_GOLDEN_H +#define _AUTO_K_RF_BONDING_GOLDEN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define BEE1_DUT_DEV_TYPE 0x11 +#define BEE1_GOLDEN_DEV_TYPE 0x12 +#define BEE2_DUT_DEV_TYPE 0x21 +#define BEE2_GOLDEN_DEV_TYPE 0x22 +#define SBEE2_DUT_DEV_TYPE 0x31 +#define SBEE2_GOLDEN_DEV_TYPE 0x32 + +/** + * @brief get information from golden sample. + * @param golden_info golden sample information + * @param dut_ic_type DUT IC type + * @return Status of Operation. + * @retval true success + * @retval false fail +*/ +bool golden_info_get(uint8_t golden_info[32], uint8_t dut_ic_type); + +/** + * @brief verify the information from the DUT. + * @param dut_info DUT information + * @param dut_ic_type DUT IC type + * @return Status of Operation. + * @retval true verify success + * @retval false verify fail +*/ +bool dut_info_verify(uint8_t dut_info[32], uint8_t dut_ic_type); + +/** + * @brief get verify result information. + * @param result_info result information + * @param verify_result verify result from dut_info_verify + * @param dut_ic_type DUT IC type + * @return Status of Operation. + * @retval true success + * @retval false fail +*/ +bool verify_result_info_get(uint8_t result_info[16], bool verify_result, uint8_t dut_ic_type); + +uint32_t platform_random(uint32_t max); + + +#ifdef __cplusplus +} +#endif + +#endif /*_AUTO_K_RF_BONDING_GOLDEN_H*/ + diff --git a/inc/platform/bee2_adc_lib.h b/inc/platform/bee2_adc_lib.h new file mode 100644 index 0000000..d44bb1c --- /dev/null +++ b/inc/platform/bee2_adc_lib.h @@ -0,0 +1,33 @@ +#ifndef __ADC_K_LIB_H +#define __ADC_K_LIB_H + +#include +#include + +typedef enum +{ + DIVIDE_SINGLE_MODE = 1, + BYPASS_SINGLE_MODE = 2, + DIVIDE_DIFFERENTIAL_MODE = 3, + BYPASS_DIFFERENTIAL_MODE = 4, +} ADC_SampleMode; + +typedef enum +{ + NO_ERROR = 0, + PARAMETER_ERROR = -1, + RAM_DATA_ERROR = -2, + NO_CALIBRATION = -3, + VERSION_ERROR = -4, +} ADC_ErrorStatus; + +extern int16_t ADC_K_Version; + +bool ADC_CalibrationInit(void); +float ADC_GetVoltage(const ADC_SampleMode vSampleMode, int32_t vSampleData, + ADC_ErrorStatus *pErrorStatus); +uint16_t ADC_GetResistance(void); + + + +#endif diff --git a/inc/platform/cmsis_armcc.h b/inc/platform/cmsis_armcc.h new file mode 100644 index 0000000..a604afc --- /dev/null +++ b/inc/platform/cmsis_armcc.h @@ -0,0 +1,867 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + +/* *INDENT-OFF* */ + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + +/* *INDENT-ON* */ + +#endif /* __CMSIS_ARMCC_H */ diff --git a/inc/platform/cmsis_gcc.h b/inc/platform/cmsis_gcc.h new file mode 100644 index 0000000..0256188 --- /dev/null +++ b/inc/platform/cmsis_gcc.h @@ -0,0 +1,2097 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin +#define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM +#define __ASM __asm +#endif +#ifndef __INLINE +#define __INLINE inline +#endif +#ifndef __STATIC_INLINE +#define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE +#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN +#define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED +#define __USED __attribute__((used)) +#endif +#ifndef __WEAK +#define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED +#define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT +#define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION +#define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +struct __attribute__((packed)) T_UINT32 { uint32_t v; }; +#pragma GCC diagnostic pop +#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; +#pragma GCC diagnostic pop +#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +__PACKED_STRUCT T_UINT16_READ { uint16_t v; }; +#pragma GCC diagnostic pop +#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; +#pragma GCC diagnostic pop +#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpacked" +#pragma GCC diagnostic ignored "-Wattributes" +__PACKED_STRUCT T_UINT32_READ { uint32_t v; }; +#pragma GCC diagnostic pop +#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED +#define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT +#define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, control" : "=r"(result)); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, control_ns" : "=r"(result)); + return (result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile("MSR control, %0" : : "r"(control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile("MSR control_ns, %0" : : "r"(control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, ipsr" : "=r"(result)); + return (result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, apsr" : "=r"(result)); + return (result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, xpsr" : "=r"(result)); + return (result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, psp" : "=r"(result)); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, psp_ns" : "=r"(result)); + return (result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile("MSR psp, %0" : : "r"(topOfProcStack) :); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile("MSR psp_ns, %0" : : "r"(topOfProcStack) :); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, msp" : "=r"(result)); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, msp_ns" : "=r"(result)); + return (result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile("MSR msp, %0" : : "r"(topOfMainStack) :); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile("MSR msp_ns, %0" : : "r"(topOfMainStack) :); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, sp_ns" : "=r"(result)); + return (result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile("MSR sp_ns, %0" : : "r"(topOfStack) :); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, primask" : "=r"(result) :: "memory"); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, primask_ns" : "=r"(result) :: "memory"); + return (result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile("MSR primask, %0" : : "r"(priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile("MSR primask_ns, %0" : : "r"(priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, basepri" : "=r"(result)); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, basepri_ns" : "=r"(result)); + return (result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile("MSR basepri, %0" : : "r"(basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile("MSR basepri_ns, %0" : : "r"(basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile("MSR basepri_max, %0" : : "r"(basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, faultmask" : "=r"(result)); + return (result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile("MRS %0, faultmask_ns" : "=r"(result)); + return (result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile("MSR faultmask, %0" : : "r"(faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile("MSR faultmask_ns, %0" : : "r"(faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile("MRS %0, psplim" : "=r"(result)); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile("MRS %0, psplim_ns" : "=r"(result)); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile("MSR psplim, %0" : : "r"(ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile("MSR psplim_ns, %0\n" : : "r"(ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile("MRS %0, msplim" : "=r"(result)); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile("MRS %0, msplim_ns" : "=r"(result)); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile("MSR msplim, %0" : : "r"(MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile("MSR msplim_ns, %0" : : "r"(MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile("VMRS %0, fpscr" : "=r"(result)); + return (result); +#endif +#else + return (0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile("VMSR fpscr, %0" : : "r"(fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile("isb 0xF"::: "memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile("dsb 0xF"::: "memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile("dmb 0xF"::: "memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile("rev %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value)); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile("rev16 %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value)); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile("revsh %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value)); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile("rbit %0, %1" : "=r"(result) : "r"(value)); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile("ldrexb %0, %1" : "=r"(result) : "Q"(*addr)); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile("ldrexb %0, [%1]" : "=r"(result) : "r"(addr) : "memory"); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile("ldrexh %0, %1" : "=r"(result) : "Q"(*addr)); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile("ldrexh %0, [%1]" : "=r"(result) : "r"(addr) : "memory"); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile("ldrex %0, %1" : "=r"(result) : "Q"(*addr)); + return (result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile("strexb %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"((uint32_t)value)); + return (result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile("strexh %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"((uint32_t)value)); + return (result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile("strex %0, %2, %1" : "=&r"(result), "=Q"(*addr) : "r"(value)); + return (result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ + __extension__ \ + ({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ + ({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile("rrx %0, %1" : __CMSIS_GCC_OUT_REG(result) : __CMSIS_GCC_USE_REG(value)); + return (result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile("ldrbt %0, %1" : "=r"(result) : "Q"(*ptr)); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile("ldrbt %0, [%1]" : "=r"(result) : "r"(ptr) : "memory"); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile("ldrht %0, %1" : "=r"(result) : "Q"(*ptr)); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile("ldrht %0, [%1]" : "=r"(result) : "r"(ptr) : "memory"); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldrt %0, %1" : "=r"(result) : "Q"(*ptr)); + return (result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile("strbt %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value)); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile("strht %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value)); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile("strt %1, %0" : "=Q"(*ptr) : "r"(value)); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldab %0, %1" : "=r"(result) : "Q"(*ptr)); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldah %0, %1" : "=r"(result) : "Q"(*ptr)); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile("lda %0, %1" : "=r"(result) : "Q"(*ptr)); + return (result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile("stlb %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value)); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile("stlh %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value)); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile("stl %1, %0" : "=Q"(*ptr) : "r"((uint32_t)value)); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldaexb %0, %1" : "=r"(result) : "Q"(*ptr)); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldaexh %0, %1" : "=r"(result) : "Q"(*ptr)); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile("ldaex %0, %1" : "=r"(result) : "Q"(*ptr)); + return (result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile("stlexb %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value)); + return (result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile("stlexh %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value)); + return (result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile("stlex %0, %2, %1" : "=&r"(result), "=Q"(*ptr) : "r"((uint32_t)value)); + return (result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("sadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhadd8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("ssub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("usub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhsub8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("sadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhadd16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("ssub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("usub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhsub16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("sasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhasx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("ssax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("qsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("shsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("usax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uqsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uhsax %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("usad8 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile("usada8 %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +#define __SSAT16(ARG1,ARG2) \ + ({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ + ({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile("uxtb16 %0, %1" : "=r"(result) : "r"(op1)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("uxtab16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile("sxtb16 %0, %1" : "=r"(result) : "r"(op1)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("sxtab16 %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("smuad %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("smuadx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile("smlad %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile("smladx %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD(uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u + { + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile("smlald %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2), + "0"(llr.w32[0]), "1"(llr.w32[1])); +#else /* Big endian */ + __ASM volatile("smlald %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2), + "0"(llr.w32[1]), "1"(llr.w32[0])); +#endif + + return (llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX(uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u + { + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile("smlaldx %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2), + "0"(llr.w32[0]), "1"(llr.w32[1])); +#else /* Big endian */ + __ASM volatile("smlaldx %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2), + "0"(llr.w32[1]), "1"(llr.w32[0])); +#endif + + return (llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("smusd %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("smusdx %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile("smlsd %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile("smlsdx %0, %1, %2, %3" : "=r"(result) : "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD(uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u + { + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile("smlsld %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2), + "0"(llr.w32[0]), "1"(llr.w32[1])); +#else /* Big endian */ + __ASM volatile("smlsld %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2), + "0"(llr.w32[1]), "1"(llr.w32[0])); +#endif + + return (llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX(uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u + { + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile("smlsldx %0, %1, %2, %3" : "=r"(llr.w32[0]), "=r"(llr.w32[1]): "r"(op1), "r"(op2), + "0"(llr.w32[0]), "1"(llr.w32[1])); +#else /* Big endian */ + __ASM volatile("smlsldx %0, %1, %2, %3" : "=r"(llr.w32[1]), "=r"(llr.w32[0]): "r"(op1), "r"(op2), + "0"(llr.w32[1]), "1"(llr.w32[0])); +#endif + + return (llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile("sel %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE int32_t __QADD(int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile("qadd %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +__STATIC_FORCEINLINE int32_t __QSUB(int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile("qsub %0, %1, %2" : "=r"(result) : "r"(op1), "r"(op2)); + return (result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ + ({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ + ({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA(int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile("smmla %0, %1, %2, %3" : "=r"(result): "r"(op1), "r"(op2), "r"(op3)); + return (result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/inc/platform/core_cm0plus.h b/inc/platform/core_cm0plus.h new file mode 100644 index 0000000..fbd73b0 --- /dev/null +++ b/inc/platform/core_cm0plus.h @@ -0,0 +1,969 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) +#pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
    + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
    + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
    + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) +#define __ASM __asm /*!< asm keyword for ARM Compiler */ +#define __INLINE __inline /*!< inline keyword for ARM Compiler */ +#define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __ASM __asm /*!< asm keyword for ARM Compiler */ +#define __INLINE __inline /*!< inline keyword for ARM Compiler */ +#define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) +#define __ASM __asm /*!< asm keyword for GNU Compiler */ +#define __INLINE inline /*!< inline keyword for GNU Compiler */ +#define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) +#define __ASM __asm /*!< asm keyword for IAR Compiler */ +#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ +#define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) +#define __ASM __asm /*!< asm keyword for TI CCS Compiler */ +#define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) +#define __ASM __asm /*!< asm keyword for TASKING Compiler */ +#define __INLINE inline /*!< inline keyword for TASKING Compiler */ +#define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) +#define __packed +#define __ASM _asm /*!< asm keyword for COSMIC Compiler */ +#define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ +#define __STATIC_INLINE static inline + +#else +#error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) +#if defined __TARGET_FPU_VFP +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#if defined __ARM_PCS_VFP +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined ( __GNUC__ ) +#if defined (__VFP_FP__) && !defined(__SOFTFP__) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined ( __ICCARM__ ) +#if defined __ARMVFP__ +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined ( __TMS470__ ) +#if defined __TI_VFP_SUPPORT__ +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined ( __TASKING__ ) +#if defined __FPU_VFP__ +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined ( __CSMC__ ) +#if ( __CSMC__ & 0x400U) +#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus +extern "C" { +#endif + +#define __VTOR_PRESENT 1U +#define __MPU_PRESENT 1U + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES +#ifndef __CM0PLUS_REV +#define __CM0PLUS_REV 0x0000U +#warning "__CM0PLUS_REV not defined in device header file; using default!" +#endif + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT 0U +#warning "__MPU_PRESENT not defined in device header file; using default!" +#endif + +#ifndef __VTOR_PRESENT +#define __VTOR_PRESENT 0U +#warning "__VTOR_PRESENT not defined in device header file; using default!" +#endif + +#ifndef __NVIC_PRIO_BITS +#define __NVIC_PRIO_BITS 2U +#warning "__NVIC_PRIO_BITS not defined in device header file; using default!" +#endif + +#ifndef __Vendor_SysTickConfig +#define __Vendor_SysTickConfig 0U +#warning "__Vendor_SysTickConfig not defined in device header file; using default!" +#endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus +#define __I volatile /*!< Defines 'read only' permissions */ +#else +#define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0: 28; /*!< bit: 0..27 Reserved */ + uint32_t V: 1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C: 1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z: 1; /*!< bit: 30 Zero condition code flag */ + uint32_t N: 1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR: 9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0: 23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR: 9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0: 15; /*!< bit: 9..23 Reserved */ + uint32_t T: 1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1: 3; /*!< bit: 25..27 Reserved */ + uint32_t V: 1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C: 1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z: 1; /*!< bit: 30 Zero condition code flag */ + uint32_t N: 1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV: 1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL: 1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1: 30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t + ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t + AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t + SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t + SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t + CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t + RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +#define MPU_DEFS_RASR_SIZE_32B (0x04 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_64B (0x05 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_128B (0x06 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_256B (0x07 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_512B (0x08 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_1KB (0x09 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_2KB (0x0A << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_4KB (0x0B << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_8KB (0x0C << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_16KB (0x0D << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_32KB (0x0E << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_64KB (0x0F << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_1MB (0x13 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_2MB (0x14 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_4MB (0x15 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_8MB (0x16 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_16MB (0x17 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_32MB (0x18 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_64MB (0x19 << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_1GB (0x1D << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_2GB (0x1E << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASR_SIZE_4GB (0x1F << MPU_RASR_SIZE_Pos) +#define MPU_DEFS_RASE_AP_NO_ACCESS (0x0 << MPU_RASR_AP_Pos) +#define MPU_DEFS_RASE_AP_PRIV_RW (0x1 << MPU_RASR_AP_Pos) +#define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos) +#define MPU_DEFS_RASE_AP_FULL_ACCESS (0x3 << MPU_RASR_AP_Pos) +#define MPU_DEFS_RASE_AP_PRIV_RO (0x5 << MPU_RASR_AP_Pos) +#define MPU_DEFS_RASE_AP_RO (0x6 << MPU_RASR_AP_Pos) +#define MPU_DEFS_NORMAL_MEMORY_WT (MPU_RASR_C_Msk) +#define MPU_DEFS_NORMAL_MEMORY_WB (MPU_RASR_C_Msk | MPU_RASR_B_Msk) +#define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk |MPU_RASR_S_Msk) +#define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB |MPU_RASR_S_Msk) +#define MPU_DEFS_SHARED_DEVICE (MPU_RASR_B_Msk) +#define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0) + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1U) +#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ +#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return ((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : + 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return ((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> + (8U - __NVIC_PRIO_BITS))); + } + else + { + return ((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & (uint32_t)0xFFUL) >> + (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for (;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority(SysTick_IRQn, + (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = + 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/inc/platform/core_cmFunc.h b/inc/platform/core_cmFunc.h new file mode 100644 index 0000000..95b27b8 --- /dev/null +++ b/inc/platform/core_cmFunc.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) +#pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) +#include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) +#include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) +#include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) +#include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) +#include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/inc/platform/core_cmInstr.h b/inc/platform/core_cmInstr.h new file mode 100644 index 0000000..c1ab637 --- /dev/null +++ b/inc/platform/core_cmInstr.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) +#pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) +#include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) +#include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) +#include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) +#include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) +#include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/inc/platform/core_cmSimd.h b/inc/platform/core_cmSimd.h new file mode 100644 index 0000000..af5337d --- /dev/null +++ b/inc/platform/core_cmSimd.h @@ -0,0 +1,96 @@ +/**************************************************************************//** + * @file core_cmSimd.h + * @brief CMSIS Cortex-M SIMD Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) +#pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMSIMD_H +#define __CORE_CMSIMD_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) +#include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) +#include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) +#include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) +#include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) +#include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CMSIMD_H */ diff --git a/inc/platform/cp.h b/inc/platform/cp.h new file mode 100644 index 0000000..dcc9a0b --- /dev/null +++ b/inc/platform/cp.h @@ -0,0 +1,259 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file cp.h +* @brief apple's authentication coprocessor driver header file. +* @details none. +* @author tifnan +* @date 2015-09-09 +* @version v1.0 +********************************************************************************************************* +*/ + +#ifndef _CP_H_ +#define _CP_H_ + +/*============================================================================* + * Header Files +*============================================================================*/ +#include +#include + +//cp device address, if reset pin pull low, 0x10; if reset pin pull high, 0x11 +#define CP_DEVICE_ADDRESS_RESET_POLL_LOW 0x10 +#define CP_DEVICE_ADDRESS_RESET_POLL_HIGH 0x11 + + +//cp register address (block 1) +#define CP_REG_DEV_VER 0x00 //RO, device verision +#define CP_REG_FW_VER 0x01 //RO, firmware verision +#define CP_REG_MAJ_VER 0x02 //RO, authentication protocol major verision +#define CP_REG_MIN_VER 0x03 //RO, authentication protocol minor verision +#define CP_dev_id 0x04 //RO, device id, 4bytes(0x00000200) +#define CP_ERR_CODE 0x05 //RO, error code -- read clear + +//cp register address (block 2) +#define CP_REG_CS 0x10 //RW, authentication control & status +#define CP_SIG_LEN 0x11 //RW, signature data length, 2bytes(128) +#define CP_SIG_DATA 0x12 //RW, signature data, 128 bytes +#define CP_REG_CHA_LEN 0x20 //RW, challenge data length, 2bytes(20) +#define CP_REG_CHA_DATA 0x21 //RW, challenge data, 128bytes + +//cp register address (block 3) +#define CP_REG_ACD_LEN 0x30 //RO, accessory certificate data length, 2bytes(<=1280) +#define CP_REG_ACD1 0x31 //RO, accessory certificate data page1, 128bytes +#define CP_REG_ACD2 0x32 //RO, accessory certificate data page2, 128bytes +#define CP_REG_ACD3 0x33 //RO, accessory certificate data page3, 128bytes +#define CP_REG_ACD4 0x34 //RO, accessory certificate data page4, 128bytes +#define CP_REG_ACD5 0x35 //RO, accessory certificate data page5, 128bytes +#define CP_REG_ACD6 0x36 //RO, accessory certificate data page6, 128bytes +#define CP_REG_ACD7 0x37 //RO, accessory certificate data page7, 128bytes +#define CP_REG_ACD8 0x38 //RO, accessory certificate data page8, 128bytes +#define CP_REG_ACD9 0x39 //RO, accessory certificate data page9, 128bytes +#define CP_REG_ACD10 0x3A //RO, accessory certificate data page10, 128bytes + +//cp register address (block 4) +#define CP_REG_ST_CS 0x40 //RW, self-test control & status +#define CP_REG_SEC 0x4D //RO, system event counter + +//cp register address (block 5) +#define CP_REG_ADCD_LEN 0x50 //RW, apple device certificate data length, 2bytes(0x0000) +#define CP_REG_ADCD1 0x51 //RW, apple device certificate data page1, 128bytes +#define CP_REG_ADCD2 0x52 //RW, apple device certificate data page2, 128bytes +#define CP_REG_ADCD3 0x53 //RW, apple device certificate data page3, 128bytes +#define CP_REG_ADCD4 0x54 //RW, apple device certificate data page4, 128bytes +#define CP_REG_ADCD5 0x55 //RW, apple device certificate data page5, 128bytes +#define CP_REG_ADCD6 0x56 //RW, apple device certificate data page6, 128bytes +#define CP_REG_ADCD7 0x57 //RW, apple device certificate data page7, 128bytes +#define CP_REG_ADCD8 0x58 //RW, apple device certificate data page8, 128bytes + + + +/** @defgroup ACP Authentication Coprocessor + * @brief apple's authentication coprocessor module driver + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup ACP_Exported_Types Authentication Coprocessor Exported Types + * @{ + */ + +//cp process result +/** @brief ACP process repsonse value */ +typedef enum +{ + CP_PRO_RES_NO_VALID = 0x80, //!
    © COPYRIGHT 2015 Realtek Semiconductor Corporation
    + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#if ! defined (__CRC16BTX_H) +#define __CRC16BTX_H + +/*============================================================================* + * Header Files +*============================================================================*/ +#include + + +/** @defgroup CRC_FCS CRC Implementation + * @brief CRC implementation for specified polynomial + * @{ + */ + +/*============================================================================* + * Macro +*============================================================================*/ +/** @defgroup CRC_FCS_Exported_Macros CRC Implementation Exported Macros + * @{ + */ +/** defines and macros */ +#define BTXFCS_INIT 0x0000 /**< Initial FCS value */ +#define BTXFCS_GOOD 0x0000 /**< Good final FCS value */ +/** @} */ /* End of group CRC_FCS_Exported_Macros */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup CRC_FCS_Exported_Functions CRC Implementation Exported Functions + * @brief + * @{ + */ +/** +* @brief Calculate a new fcs given the current fcs and the new data. +* Polynomial: X**0 + X**2 + X**15 + X16 +* +* @param fcs: init or good final +* @param cp: data point +* @param len: length +* +* @return +* +*/ +uint16_t btxfcs(uint16_t fcs, + uint8_t *cp, + uint32_t len); + +/** @} */ /* End of group CRC_FCS_Exported_Functions */ + +/** @} */ /* End of group CRC_FCS */ + +#endif /**< #if ! defined (__CRC16BTX_H) */ + +/** End of CRC16BTX.H */ + diff --git a/inc/platform/crc8ets.h b/inc/platform/crc8ets.h new file mode 100644 index 0000000..b498c19 --- /dev/null +++ b/inc/platform/crc8ets.h @@ -0,0 +1,48 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file crc8ets.h + * @brief CRC/FCS routines based on ETSI TS 101 369 V6.3.0 (1999-03) / + * GSM 07.10 version 6.3.0 Release 1997, B.3.5 Reversed CRC table. + * Generator polynomial: x**8 + x**2 + x + 1 + * @author gordon + * @date 2015-07-13 + * @version v1.0 + *************************************************************************************** + * @attention + *

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    + *************************************************************************************** + */ + +#if ! defined (__CRC8ETS_H) +#define __CRC8ETS_H + +/* +#if ! defined (__BASETYPE_H) +#include +#endif +*/ +#include + +/** @defgroup CRC_FCS CRC Implementation + * @brief CRC implementation for specified polynomial + * @{ + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup CRC_FCS_Exported_Functions CRC Implementation Exported Functions + * @brief + * @{ + */ + +uint8_t crc8EtsGen(uint8_t *p, uint16_t len); +uint8_t crc8EtsCheck(uint8_t *p, uint16_t len, uint8_t rfcs); +/** @} */ /* End of group CRC_FCS_Exported_Functions */ + +/** @} */ /* End of group CRC_FCS */ + +#endif /**< ! defined (__CRC8ETS_H) */ + diff --git a/inc/platform/dfu_flash.h b/inc/platform/dfu_flash.h new file mode 100644 index 0000000..e5c4f4b --- /dev/null +++ b/inc/platform/dfu_flash.h @@ -0,0 +1,199 @@ +#ifndef DFU_FLASH_H +#define DFU_FLASH_H + +#include +#include +#include "patch_header_check.h" +#include "dfu_api.h" + +/** @defgroup DFU_API DFU API Sets + * @brief API sets for device firmware update implementation + * @{ + */ + + +/*******************************OTA ERROR CODE********************/ +#define DFU_UPDATE_SUCCESS 0x0 +#define DFU_UPDATE_ERROR_LEN_NOT_ALIGN 0x1 +#define DFU_UPDATE_ERROR_EMPTY_BUFFER 0x2 +#define DFU_UPDATE_ERROR_BASE_ADDR_INVALID 0x3 +#define DFU_UPDATE_ERROR_IMAGE_SIZE_TOO_LARGE 0x4 +#define DFU_UPDATE_ERROR_PACKET_SIZE_TOO_LARGE 0x5 +#define DFU_UPDATE_ERROR_FLASH_ERASE_LEN_NOT_ALIGN 0x6 +#define DFU_UPDATE_ERROR_FLASH_ERASE_FAIL 0x7 +#define DFU_UPDATE_ERROR_FLASH_WRITE_FAIL 0x8 +#define DFU_UPDATE_ERROR_FLASH_READBACK_FAIL 0x9 +#define DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH 0xa + +#define DFU_CHECKSUM_SUCCESS 0x0 +#define DFU_CHECKSUM_ERROR_BASE_ADDR_INVALID 0x1 +#define DFU_CHECKSUM_ERROR_IMAGE_TYPE_INVALID 0x2 +#define DFU_CHECKSUM_ERROR_CHECK_FAIL 0x3 + + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup DFU_API_Exported_Types DFU API Sets Exported Types + * @brief + * @{ + */ + +typedef enum +{ + DFU_START = 0, + DFU_DOING, + DFU_END, +} T_DFU_STATUS; + +typedef union +{ + T_IMG_CTRL_HEADER_FORMAT *p_header; //for DFU_START + uint32_t dfu_length; //for DFU_DOING + bool image_check_result; //for DFU_END +} T_DFU_DATA; + +typedef void (*P_FUNC_DFU_STATUS_CB)(T_DFU_STATUS status, T_DFU_DATA data); + +/** + * @} + */ + +/*============================================================================* + * Variables + *============================================================================*/ +/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Variables + * @brief + * @{ + */ + + + +/** + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DFU_API_Exported_Functions DFU API Sets Exported Functions + * @{ + */ +/** + * @brief check whether in OTA mode. +*/ +bool dfu_check_ota_mode_flag(void); + +/** + * @brief set aon reg value means whether in OTA mode or not. +*/ +void dfu_set_ota_mode_flag(bool enable); + +/** + * @brief switch to the OTA mode, if support normal ota app need call it. +*/ +void dfu_switch_to_ota_mode(void); + +/** + * @brief OTA procedure do wdg system reset. + * @param is_active_fw true means dfu success! otherwise fail. +*/ +void dfu_fw_reboot(bool is_active_fw); + + +/** + * @brief OTA image default ecb mode aes decrypt, last less then 16bytes no encrypted. +*/ +void dfu_hw_aes_decrypt_image(uint8_t *input, uint8_t *output, uint32_t length); + +/** + * @brief report specified target ic type. + * @param image_id image_id to identify FW. + * @param p_ic_type To store ic type. + * @return 0 if report ic type info successfully, error line number otherwise +*/ +uint32_t dfu_report_target_ic_type(uint16_t image_id, uint8_t *p_ic_type); + +/** + * @brief report specified FW info and current OTA offset. + * @param image_id image_id to identify FW. + * @param p_origin_fw_version To store current FW version. + * @param p_offset To store current file offset. + * @return 0 if report FW info successfully, error line number otherwise +*/ +uint32_t dfu_report_target_fw_info(uint16_t image_id, uint32_t *p_origin_fw_version, + uint32_t *p_offset); + +/** +* @brief calculate checksum of lenth of buffer in flash. +* @param image_id image_id to identify FW. +* @param offset offset of the image. +* @param length length of data. +* @param crc_val ret crc value point. +* @return 0 if buffer checksum calcs successfully, error line number otherwise +*/ +uint32_t dfu_check_buf_crc(uint8_t *buf, uint32_t length, uint16_t crc_val); + + +/** + * @brief unlock flash is need when erase or write flash. +*/ +bool unlock_flash_bp_all(void); + +/** + * @brief lock flash after erase or write flash. +*/ +void lock_flash_bp(void); +/** + * @brief erase a sector of the flash, will retry three times at most + * @param image_id image_id to identify FW. + * @param offset offset of the image. + * @return 0 if erase successfully, error line number otherwise, +*/ +uint32_t dfu_flash_erase_sector_with_retry(uint16_t image_id, uint32_t offset); + + +/** + * @brief write specified image data with specified length to flash + * @param image_id image_id to identify FW. + * @param offset offset of the image. + * @param length length of data. + * @param p_void pointer to data. + * @return 0 if write FW image successfully, error line number otherwise +*/ +uint32_t dfu_update(uint16_t image_id, uint32_t offset, uint32_t length, + uint32_t *p_void, bool is_new_image); + + +/** + * @brief calculate checksum of the image and compare with given checksum value. + * @param image_id image_id to identify image. + * @return true if the image integrity check passes, false otherwise +*/ +bool dfu_check_checksum(uint16_t image_id, uint32_t offset); + + +void dfu_set_image_ready(T_IMG_CTRL_HEADER_FORMAT *p_header); + + +/** + * @brief copy appdata from active bank to updating bank. + * @param image_id image_id to identify image. + * @param dlAddress address the img copy to. + * @param dlSize copy size. + * @return true if the image copied success, false otherwise +*/ +bool dfu_copy_img(uint16_t image_id, uint32_t dlAddress, uint32_t dlSize); +/** + * @} + */ + +/** + * @} + */ + + + + +#endif //DFU_FLASH_H diff --git a/inc/platform/dlps.h b/inc/platform/dlps.h new file mode 100644 index 0000000..94f2a62 --- /dev/null +++ b/inc/platform/dlps.h @@ -0,0 +1,346 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dlps.h + * @brief DLPS implementation head file. + * @author lory_xu + * @date 2014-08-05 + * @version v1.0 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef __DLPS_H +#define __DLPS_H + + +/*============================================================================* + * Header Files +*============================================================================*/ +#include +#include +#include "os_queue.h" +#include "otp.h" +#include "system_rtl876x.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/** @defgroup DLPS_PLATFORM DLPS Platform + * @brief Deep low power state support + * @{ + */ + +/*============================================================================* + * Types +*============================================================================*/ +/** @defgroup DLPS_PLATFORM_Exported_Types DLPS Platform Exported Types + * @{ + */ + +/** @brief This CB is used for any module which needs to be checked before entering DLPS */ +typedef bool (*DLPSEnterCheckFunc)(); + +/** @brief This CB is used for any module which needs to control the hw before entering or after exiting from DLPS */ +typedef void (*DLPSHWControlFunc)(); + +/*============================================================================* + * Platform Unit +*============================================================================*/ + +/** @brief PlatformPMStage struct */ +typedef enum +{ + PLATFORM_PM_CHECK = 0, + PLATFORM_PM_STORE = 1, + PLATFORM_PM_ENTER = 2, + PLATFORM_PM_EXIT = 3, + PLATFORM_PM_RESTORE = 4, + PLATFORM_PM_PEND = 5, +} PlatformPMStage; + + +/** @brief PlatformPowerMode struct */ +typedef enum +{ + PLATFORM_POWERDOWN = 1, /**< Power down */ + PLATFORM_DLPS_PFM = 2, /**< DLPS (PFM) */ + PLATFORM_DLPS_RET = 3, /**< DLPS (RET) */ + PLATFORM_ACTIVE = 5, /**< Active */ +} PlatformPowerMode; + +typedef enum +{ + PLATFORM_PM_WAKEUP_UNKNOWN = 0x0000, + PLATFORM_PM_WAKEUP_USER = 0x0001, + PLATFORM_PM_WAKEUP_OS = 0x0002, + PLATFORM_PM_WAKEUP_PRE_SYSTEM_LEVEL = 0x0003, + PLATFORM_PM_WAKEUP_PF_RTC = 0x0100, + PLATFORM_PM_WAKEUP_RTC = 0x0200, + PLATFORM_PM_WAKEUP_MAC = 0x0400, + PLATFORM_PM_WAKEUP_GPIO = 0x0800, + PLATFORM_PM_WAKEUP_CTC = 0x1000, +} PlatformWakeupReason; + +typedef enum +{ + PLATFORM_PM_ERROR_UNKNOWN = 0x0, + PLATFORM_PM_ERROR_POWER_MODE = 0x1, + PLATFORM_PM_ERROR_DISABLE_DLPS_TIME = 0x2, + PLATFORM_PM_ERROR_32K_CHECK_LOCK = 0x3, + PLATFORM_PM_ERROR_LOG_DMA_NOT_IDLE = 0x4, + PLATFORM_PM_ERROR_CALLBACK_CHECK = 0x5, + PLATFORM_PM_ERROR_INTERRUPT_OCCURRED = 0x6, + PLATFORM_PM_ERROR_WAKEUP_TIME = 0x7, + PLATFORM_PM_ERROR_DATA_UART = 0x8, +} PlatformPowerModeErrorCode; + +typedef enum +{ + BTMAC_PM_WAKEUP_UNKNOWN = 0x0, + BTMAC_PM_WAKEUP_LEGACY = 0x1, + BTMAC_PM_WAKEUP_LE = 0x2, + BTMAC_PM_WAKEUP_PRE_SYSTEM_LEVEL = 0x3, +} BtmacWakeupReason; + +typedef enum +{ + BTMAC_PM_ERROR_UNKNOWN = 0x0, + BTMAC_PM_ERROR_POWER_MODE = 0x1, + BTMAC_PM_ERROR_ROLE_SWITCH = 0x3, + BTMAC_PM_ERROE_BQB = 0x4, + BTMAC_PM_ERROR_PSD = 0x5, + BTMAC_PM_ERROR_CSB_ENABLE = 0x6, + BTMAC_PM_ERROR_NOT_EMPTY_QUEUE_OF_LOWER = 0x7, + BTMAC_PM_ERROR_CONTROLLER_TO_HOST_BUSY = 0x8, + BTMAC_PM_ERROR_TX_BUSY = 0x9, + BTMAC_PM_ERROR_LE_REG_S_INST = 0xB, + BTMAC_PM_ERROR_ADV_STATE_NOT_IDLE = 0xC, + BTMAC_PM_ERROR_SCAN_STATE_NOT_IDLE = 0xD, + BTMAC_PM_ERROR_INITIATOR_UNIT_ENABLE = 0xE, + BTMAC_PM_ERROR_CHANNEL_MAP_UPDATE = 0xF, + BTMAC_PM_ERROR_CONNECTION_UPDATE = 0x10, + BTMAC_PM_ERROR_PHY_UPDATE = 0x11, + BTMAC_PM_ERROR_CONN_STATE_NOT_IDLE = 0x12, + BTMAC_PM_ERROR_LE_SCHE_NOT_READY = 0x13, + BTMAC_PM_ERROR_INTERRUPT_PENDING = 0x14, + BTMAC_PM_ERROR_WAKEUP_TIME = 0x15, + BTMAC_PM_ERROR_32K_CHECK_LOCK = 0x16, +} BtmacPowerModeErrorCode; + +typedef enum +{ + NO_DATARAM_SHUTDOWN, + LAST_4K_DATARAM_SHUTDOWN, /**< 4k */ + LAST_8K_DATARAM_SHUTDOWN, /**< 4k + 4k */ + LAST_24K_DATARAM_SHUTDOWN, /**< 16k + 4k + 4k */ + LAST_56K_DATARAM_SHUTDOWN /**< 32k + 16k + 4k + 4k */ +} DATARAM_SHUTDOWN_LEVEL; + +/*============================================================================* + * BTMAC Unit +*============================================================================*/ + +typedef enum +{ + BTMAC_DEEP_SLEEP = 0, /**< Deep sleep */ + BTMAC_ACTIVE = 1, /**< Active */ +} BtmacPowerMode; + +/** @brief DLPS error code*/ + + +/** @} */ /* End of group DLPS_PLATFORM_Exported_Types */ + +/*============================================================================* + * Variables +*============================================================================*/ +/** @defgroup DLPS_PLATFORM_Exported_Variables DLPS Platform Exported Variables + * @{ + */ + + +/** @} */ /* End of group DLPS_PLATFORM_Exported_Variables */ + +/*============================================================================* + * Functions +*============================================================================*/ + +extern void platform_pm_set_power_mode(PlatformPowerMode pf_power_mode_user); +extern PlatformPowerMode platform_pm_get_power_mode(void); +extern void btmac_pm_set_power_mode(BtmacPowerMode bz_power_mode_user); +extern void power_manager_suspend_all(void); +extern void power_manager_resume_all(void); +extern void platform_pm_register_callback_func(void *cb_func, PlatformPMStage pf_pm_stage); +extern void platform_pm_get_statistics(uint32_t *wakeup_count, uint32_t *last_wakeup_clk, + uint32_t *last_sleep_clk); +extern void btmac_pm_get_statistics(uint32_t *wakeup_count, uint32_t *last_wakeup_clk, + uint32_t *last_sleep_clk); +extern void platform_pm_stop_all_non_excluded_timer(void); + +extern PlatformPowerModeErrorCode platform_pm_get_error_code(void); +extern uint32_t *platform_pm_get_refuse_reason(void); +extern PlatformWakeupReason platform_pm_get_wakeup_reason(void); + +extern BtmacPowerModeErrorCode btmac_pm_get_error_code(void); +extern BtmacWakeupReason btmac_pm_get_wakeup_reason(void); +/** @defgroup DLPS_PLATFORM_Exported_Functions DLPS Platform Exported Functions + * @{ + */ + +/** + * @brief Register Check CB to DlpsPlatform which will call it before entering Dlps. + * @param func DLPSEnterCheckFunc + * @return Status of Operation. + * @retval true success + * @retval false fail +*/ +static inline bool dlps_check_cb_reg(DLPSEnterCheckFunc func) +{ + platform_pm_register_callback_func(func, PLATFORM_PM_CHECK); + return true; +} + +/** + * @brief Register HW Control CB to DlpsPlatform which will call it before entering Dlps or after exiting from Dlps (according to dlpsState) . + * @param func DLPSHWControlFunc + * @param dlpsState tell the DlpsPlatform the CB should be called when DLPS_ENTER or DLPS_EXITx_XXX. + * @return Status of Operation. + * @retval true success + * @retval false fail +*/ +static inline bool dlps_hw_control_cb_reg(DLPSHWControlFunc func, PlatformPMStage dlpsState) +{ + platform_pm_register_callback_func(func, dlpsState); + return true; +} + +/** + * @brief Keep platform in @ref LPM_ACTIVE_MODE which means will stop platform enter any lower power mode. + * @param none + * @return none +*/ +static inline void lps_mode_pause(void) +{ + power_manager_suspend_all(); +} + +/** + * @brief Restore to original LPSMode. + * @param none + * @return none +*/ +static inline void lps_mode_resume(void) +{ + power_manager_resume_all(); +} + +/** + * @brief Set active time after boot before entering into dlps + * @param active_time_ms time to keep active, unit ms + * @return none +*/ +void set_boot_active_time(uint32_t active_time_ms); + +/** + * @brief LPSMode Set . + * @param mode LPSMode + * @return none +*/ +static inline void lps_mode_set(PlatformPowerMode mode) +{ + btmac_pm_set_power_mode(BTMAC_DEEP_SLEEP); + platform_pm_set_power_mode(mode); +} + +/** + * @brief LPSMode Get . + * @param none + * @return @ref LPSMode +*/ +static inline PlatformPowerMode lps_mode_get(void) +{ + return platform_pm_get_power_mode(); +} + +/** + * @brief Return dlps wakeup counts . + * @param none + * @return count value +*/ +static inline uint32_t lps_wakeup_count_get(void) +{ + uint32_t wakeup_count, last_wakeup_clk, last_sleep_clk; + platform_pm_get_statistics(&wakeup_count, &last_wakeup_clk, &last_sleep_clk); + return wakeup_count; +} + +/** + * @brief Set data ram to shut down instead of deep sleep when enter dlps to reduce power consumption. + Data ram(totol 88k) divides into 5 blocks: 32k + 32k + 16k + 4k + 4k. + * @param level + * @return none + */ +static inline void set_dataram_to_shutdown(DATARAM_SHUTDOWN_LEVEL level) +{ + switch (level) + { + case LAST_4K_DATARAM_SHUTDOWN: + { + OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0xf; + OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x10; + } + break; + case LAST_8K_DATARAM_SHUTDOWN: + { + OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x7; + OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x18; + } + break; + case LAST_24K_DATARAM_SHUTDOWN: + { + OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x3; + OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x1c; + } + break; + case LAST_56K_DATARAM_SHUTDOWN: + { + OTP->ram_cfg[MEMCFG_DEEPSLEEP].mcu_data_sram = 0x1; + OTP->ram_cfg[MEMCFG_SHUTDOWN].mcu_data_sram = 0x1e; + } + break; + default: + break; + } +} + +/** + * @brief LPSMode enter powerdown mode directly . + * @param none + * @return none +*/ +static inline void lps_mode_enter_powerdown_directly(void) +{ + SystemCall(SYSTEM_CALL_ENTER_POWERDOWN_DIRECTLY, 0); +} + +/** @} */ /* End of group DLPS_PLATFORM_Exported_Functions */ + +/** @} */ /* End of group DLPS_PLATFORM */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __DLPS_PLATFORM_H */ diff --git a/inc/platform/flash_adv_cfg.h b/inc/platform/flash_adv_cfg.h new file mode 100644 index 0000000..032c935 --- /dev/null +++ b/inc/platform/flash_adv_cfg.h @@ -0,0 +1,161 @@ +/** +**************************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +**************************************************************************************************** +* @file flash_adv_cfg.h +* @brief +* @note flash advanced functions +* @author Grace +* @date 2018-04-19 +* @version v0.1 +* ************************************************************************************************** +*/ + +#ifndef _FLASH_ADV_CFG_H_ +#define _FLASH_ADV_CFG_H_ + +#include +#include +#include "flash_device.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** @defgroup FLASH_DEVICE Flash Device + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types + * @brief + * @{ + */ + +/** End of FLASH_DEVICE_Exported_Types + * @} + */ +/************************************************************************************************* + * Functions +*************************************************************************************************/ +/** @defgroup FLASH_DEVICE_Exported_Functions Flash Device Exported Functions + * @brief + * @{ + */ + +/** +* @brief get block protect level +* @param *bp_lv a set of BPx ~ BP0 +* @return success or not +*/ +bool flash_get_block_protect_locked(uint8_t *bp_lv); + +/** +* @brief set block protect by map +* @param bp_lv a set of BPx ~ BP0 +* @return success or not +*/ +bool flash_set_block_protect_locked(uint8_t bp_lv); + +/** +* @brief only unlock prefer section by addres +* @param unlock_addr address section to be unlocked +* @param *old_bp_lv before unlock +* @return success or not +*/ +bool flash_sw_protect_unlock_by_addr_locked(uint32_t unlock_addr, uint8_t *old_bp_lv); + +/** +* @brief read vendor_id to switch callback +* @return true if success +* false if not support +*/ +bool flash_otp_init(void); + +/** +* @brief safe version of flash_otp_erase +* @param type erase type +* @param addr address to erase when erase block or sector +* @return true if success +*/ +bool flash_otp_erase_locked(T_ERASE_TYPE type, uint32_t addr); + +/** +* @brief safe version of flash_otp_write +* @param start_addr start_addr address where is going to be flash in flash +* @param data_len data length to be program +* @param data data buffer to be program into +* @return true if success +*/ +bool flash_otp_write_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data); + +/** +* @brief safe version of flash_otp_read +* @param start_addr start_addr address where is going to be read in flash +* @param data_len data length to be read +* @param data data buffer to be read into +* @return true if success +*/ +bool flash_otp_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data); + +/** +* @brief safe version of flash_otp_enter +* @return true if success +*/ +bool flash_otp_enter_locked(void); + +/** +* @brief safe version of flash_otp_exit +* @return true if success +*/ +bool flash_otp_exit_locked(void); + +/** +* @brief safe version of flash_otp_set_lb +* @return true if success +*/ +bool flash_otp_set_lb_locked(void); + +/** +* @brief safe version of flash_otp_get_lb +* @return true if success +*/ +bool flash_otp_get_lb_locked(void); + +/** + * @brief read SFDP data + * @param start_addr start_addr address in SFDP table + * @param data_len data length to be read + * @param data data buffer to be read into + * @return true if success +*/ +bool flash_sfdp_read_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data); + +/** + * @brief The quick user mode read (use split read to improve read speed) + * @param start_addr start_addr address where is going to be read in flash (4 byte aligned) + * @param data_len data length to be read + * @param data data buffer to be read into + * @return true if success +*/ +bool flash_read_quick_locked(uint32_t start_addr, uint32_t data_len, uint8_t *data); + +/** + * @brief read flash ID + * @param void + * @return flash id +*/ +uint32_t flash_get_id(void); + +/** @} */ /* End of group FLASH_DEVICE_Exported_Functions */ + + +/** @} */ /* End of group FLASH_DEVICE */ + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _FLASH_ADV_CFG_H_ diff --git a/inc/platform/flash_device.h b/inc/platform/flash_device.h new file mode 100644 index 0000000..5a0887c --- /dev/null +++ b/inc/platform/flash_device.h @@ -0,0 +1,430 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file flash_device.h +* @brief This file contains structures the functions regarding flash device. +* @author Brenda_li +* @date 2016-11-9 +* @version v1.0 + + ****************************************************************************** + * @attention + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + * + * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. + ****************************************************************************** + */ + +/***************************************************************************************** +* Introduction +***************************************************************************************** +* - Flash function would be splitted into two modules: flash_driver and flash_device +* - flash_driver will handle flash_spic register to provide flash basic read/write function +* - flash_device would provide flash layout or other functions. +******************************************************************************************/ +#ifndef _FLASH_DEVICE_H +#define _FLASH_DEVICE_H +/*============================================================================* + * Header Files +*============================================================================*/ +#include +#include + +/** @defgroup FLASH_DEVICE Flash Device + * @brief Flash image layout and APIs + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup FLASH_DEVICE_Exported_Macros Flash Device Exported Macros + * @brief + * @{ + */ +#define FMC_PAGE_SIZE 0x1000 +#define FMC_SEC_SECTION_LEN (4 * 1024) +#define FMC_BLK_SECTION_LEN (64 * 1024) +#define FMC_ERASE_PATTERN (0xffffffff) + +#if (IC_TYPE == IC_TYPE_BEE3) +#define FLASH_OFFSET_TO_NO_CACHE 0x01000000 /*!< memory offset between no cache and cache flash address */ +#elif (IC_TYPE == IC_TYPE_SBEE2) +#define FLASH_OFFSET_TO_NO_CACHE 0x04000000 +#endif + +//leverage config signature from bee1 +#define SIGNATURE_CONFIG 0x8721bee2 + +/******** bit definitions of hardfault configuration ********/ +#define BIT_ENABLE_SAVE_HARDFAULT 0x00000001 /* BIT0 */ +#define BIT_ENABLE_DUMP_HARDFAULT 0x00000004 /* BIT2 */ +#define BIT_CLEAR_HISTROY_AFTER_DUMP 0x00000008 /* BIT3 */ +#define BIT_CLEAR_HISTROY_BEFORE_SAVING 0x00000010 /* BIT4 */ + +/** End of FLASH_DEVICE_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types + * @brief + * @{ + */ + +/******************** flash erase type ******************* +FLASH_ERASE_CHIP: erase whole chip +FLASH_ERASE_SECTOR: erase specified sector(page, 4K always) +FLASH_ERASE_BLOCK: erase specified block(16 sector always) +****************************************************************/ +typedef enum +{ + FLASH_ERASE_CHIP = 1, /*! + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** @defgroup FTL Flash Transport Layer + * @brief simple implementation of file system for flash + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup FTL_Exported_Macros Flash Transport Layer Exported Macros + * @brief + * @{ + */ + +/** @defgroup FTL_WRITE_ERROR_CODE FTL Write Error Code + * @{ + */ +#define FTL_WRITE_SUCCESS (0x00) +#define FTL_WRITE_ERROR_IN_INTR (0x01) /**< can't write ftl in a interrupt */ +#define FTL_WRITE_ERROR_INVALID_ADDR (0x02) /**< logical addr is not 4byte align or exceed the max logical address */ +#define FTL_WRITE_ERROR_OUT_OF_SPACE (0x03) /**< ftl have no space for store new data */ +#define FTL_WRITE_ERROR_READ_BACK (0x04) /**< ftl write to flash error */ +#define FTL_WRITE_ERROR_VERIFY (0x05) +#define FTL_WRITE_ERROR_INVALID_SIZE (0x06) /**< write length is not 4byte align */ +#define FTL_WRITE_ERROR_ERASE_FAIL (0x07) /**< flash erase fail result in ftl write fail */ +#define FTL_WRITE_ERROR_NOT_INIT (0x08) /**< write ftl too early before ftl init */ +#define FTL_WRITE_ERROR_NEED_GC (0x09) /**< ftl_only_gc_in_idle is opened */ +/** + * @} + */ + +/** @defgroup FTL_READ_ERROR_CODE FTL Read Error Code +* @{ +*/ +#define FTL_READ_SUCCESS (0x00) +#define FTL_READ_ERROR_INVALID_LOGICAL_ADDR (0x01) /**< logical addr is not 4byte align or exceed the max logical address */ +#define FTL_READ_ERROR_READ_NOT_FOUND (0x02) /**< logical addr never be writed so that can't found */ +#define FTL_READ_ERROR_PARSE_ERROR (0x03) /**< recorded logical addr is changed even though crc check pass*/ +#define FTL_READ_ERROR_INVALID_SIZE (0x04) /**< read length is not 4byte align */ +#define FTL_READ_ERROR_NOT_INIT (0x05) /**< read ftl too early before ftl init */ +#define FTL_READ_ERROR_CRC_CHECK_FAIL (0x06) /**< crc check fail */ +/** + * @} + */ + +#define FTL_INIT_ERROR_ERASE_FAIL (0x01) /**< flash erase fail result in ftl init fail */ +#define FTL_INIT_ERROR_NOT_INIT (0x02) /**< ftl init fail because of empty function*/ + +#define FTL_IOCTL_ERROR_NOT_INIT (0x01) /**< ftl ioctl fail because of empty function*/ +/** End of FTL_Exported_Macros + * @} + */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FTL_Exported_Types Flash Transport Layer Exported Types + * @brief + * @{ + */ +typedef enum +{ + FTL_IOCTL_DEBUG = 0, /**< IO code for ftl debug */ + FTL_IOCTL_CLEAR_ALL = 2, /**< IO code for clear ftl section*/ + FTL_IOCTL_ERASE_INVALID_PAGE = 3, /**< IO code to erase invalid page*/ + FTL_IOCTL_ENABLE_GC_IN_IDLE = 4, /**< IO code to enable garbage collection in idle task*/ + FTL_IOCTL_DISABLE_GC_IN_IDLE = 5, /**< IO code to disable garbage collection in idle task*/ + FTL_IOCTL_DO_GC_IN_APP = 6, /**< IO code to do garbage collection in app*/ +} T_FTL_IOCTL_CODE; + +/** End of FTL_Exported_Types + * @} + */ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup FTL_Exported_Functions Flash Transport Layer Exported Functions + * @brief + * @{ + */ +/** + * @brief Save specified value to specified ftl offset + * @param pdata specify data buffer + * @param offset specify FTL offset to store + * @arg Min: 0 + * @arg Max: depend on configuried ftl size + * @param size size to store + * @arg Min: 4 + * @arg Max: depend on configuried ftl size + * @return status + * @retval 0 status successful + * @retval otherwise fail + * @note FTL offset is pre-defined and no conflict + */ +uint32_t ftl_save(void *pdata, uint16_t offset, uint16_t size); + +/** + * @brief Load specified ftl offset parameter to specified buffer + * @param pdata specify data buffer + * @param offset specify FTL offset to load + * @arg Min: 0 + * @arg Max: depend on configuried ftl size + * @param size size to load + * @arg Min: 4 + * @arg Max: depend on configuried ftl size + * @return status + * @retval 0 status successful + * @retval otherwise fail + * @note FTL offset is pre-defined and no conflict + */ +uint32_t ftl_load(void *pdata, uint16_t offset, uint16_t size); + + +/** + * @brief Control function entry for ftl + * @param cmd command code for different operation + * @param p1 command parameter @ref T_FTL_IOCTL_CODE + * @param p2 extended command parameters + * @return results of control + * @retval 0 status successful + * @retval otherwise fail + */ +uint32_t ftl_ioctl(uint32_t cmd, uint32_t p1, uint32_t p2); + +/** @} */ /* End of group FTL_Exported_Functions */ + + +/** @} */ /* End of group FTL */ + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _FTL_H_ diff --git a/inc/platform/hw_aes.h b/inc/platform/hw_aes.h new file mode 100644 index 0000000..df25f80 --- /dev/null +++ b/inc/platform/hw_aes.h @@ -0,0 +1,139 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hw_aes.h + * @brief HW aes apis abstracted for encryption related. + * @details AES encryption APIs which delivers HW implemented reliable and safe AES solution. + * @author Lory Xu + * @date 2017.5.17 + * @version v1.0 + * ************************************************************************************* + */ + +#ifndef HW_AES_H +#define HW_AES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** @defgroup HW_AES Hardware AES + * @brief API Sets for hardware AES engine + * @{ + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup HW_AES_Exported_Types HW AES Exported Types + * @{ + */ + +/** @brief encrytion zone for image encryption feature. */ +typedef enum +{ + ZONE0, + ZONE1, + ZONE_NOT_USED +} T_PROTECT_ZONE; + +/** @brief AES mode definition for HW AES. */ +typedef enum +{ + AES_MODE_NONE, + AES_MODE_CBC, + AES_MODE_ECB, + AES_MODE_CFB, + AES_MODE_OFB, + AES_MODE_CTR +} T_HW_AES_MODE; + +/** End of HW_AES_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup HW_AES_Exported_Functions HW AES Exported Functions + * @brief + * @{ + */ + +extern bool hw_aes_decrypt_16byte(uint8_t *input, uint8_t *output); + +/** + * @brief 128 bit AES encryption via DMA on speicified plain data and keys + * @param p_in specifed plain data to be encypted + * @param p_out output buffer to store encrypted data + * @param data_word_len input buffer length + * @param key key buffer + * @param iv initialization vector for AES CBC mode + * @param mode aes mode specified by @ref T_HW_AES_MODE + * @return encryption results + * @retval true successful + * @retval false fail + * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function + */ +bool hw_aes_encrypt128_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len, + uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode); +/** + * @brief 128 bit AES decryption via DMA on speicified data and keys + * @param p_in specifed encrypted data to be decypted + * @param p_out output buffer to store plain data + * @param data_word_len input buffer length + * @param key key buffer + * @param iv initialization vector for AES CBC mode + * @param mode aes mode specified by @ref T_HW_AES_MODE + * @return encryption results + * @retval true successful + * @retval false fail + * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function + */ +bool hw_aes_decrypt128_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len, + uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode); +/** + * @brief 256 bit AES encryption via DMA on speicified plain data and keys + * @param p_in specifed plain data to be encypted + * @param p_out output buffer to store encrypted data + * @param data_word_len input buffer length + * @param key key buffer + * @param iv initialization vector for AES CBC mode + * @param mode aes mode specified by @ref T_HW_AES_MODE + * @return encryption results + * @retval true successful + * @retval false fail + * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function + */ +bool hw_aes_encrypt256_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len, + uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode); +/** + * @brief 256 bit AES decryption via DMA on speicified data and keys + * @param p_in specifed encrypted data to be decypted + * @param p_out output buffer to store plain data + * @param data_word_len input buffer length + * @param key key buffer + * @param iv initialization vector for AES CBC mode + * @param mode aes mode specified by @ref T_HW_AES_MODE + * @return encryption results + * @retval true successful + * @retval false fail + * @note HWAES_DMA_RX_CH_NUM and HWAES_DMA_TX_CH_NUM DMA channels are occupied by this function + */ +bool hw_aes_decrypt256_use_dma(uint32_t *p_in, uint32_t *p_out, uint16_t data_word_len, + uint32_t *key, uint32_t *iv, T_HW_AES_MODE mode); + +/** @} */ /* End of group HW_AES_Exported_Functions */ + + +/** @} */ /* End of group HW_AES */ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/platform/log_uart_dma.h b/inc/platform/log_uart_dma.h new file mode 100644 index 0000000..d8c506c --- /dev/null +++ b/inc/platform/log_uart_dma.h @@ -0,0 +1,86 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file log_uart_dma.h +* @brief This file provides APIs of log uart with DMA channel. +* @details +* @author Lory Xu +* @date 2016-01-11 +* @version v0.1 +********************************************************************************************************* +*/ + +#ifndef LOG_UART_DMA_H +#define LOG_UART_DMA_H + +#include "pingpong_buffer.h" +#include "rtl876x.h" +#include "trace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + LOG_DMA_STATE_IDLE = 0, + LOG_DMA_STATE_PROCESS_MCU, + LOG_DMA_STATE_PENDING_MCU, + LOG_DMA_STATE_MAX +} T_LOG_DMA_STATE; + +typedef enum +{ + LOG_DMA_SIGNAL_MCU_REQUEST = 0, + LOG_DMA_SIGNAL_MCU_DONE, + LOG_DMA_SIGNAL_MAX +} T_LOG_DMA_SIGNAL; + +typedef struct +{ + uint16_t MCU_LogMissed; + uint16_t PendedMCU_BufferSize; + uint8_t *PendedMCU_Buffer; /* MCU uses ping pong buffer */ + volatile T_LOG_DMA_STATE State; + T_LOG_DMA_STATE LastState; +} T_LOG_DMA_SM; + +typedef struct +{ + uint32_t ReadIndex; /* DSP uses ring buffer */ + uint32_t WriteIndex; + uint8_t *Buffer; + uint16_t BufferSize; /* MCU uses ping pong buffer */ + T_LOG_DMA_SIGNAL Signal; +} T_LOG_DMA_EVT; + +#define LogDMA_StateTran(State_) (me->LastState = me->State, me->State = (State_)) + +/* Config Log DMA Channel */ +#define LogDMAChannelNum 3 +#define LogDMAChannel GDMA_Channel3 +#define LogDMAIRQn GDMA0_Channel3_IRQn +#define LogUartDMAIntrHandler GDMA0_Channel3_Handler + +extern PingpongBuffer *pMCU_PPB; +extern T_LOG_DMA_SM *pLogDMA_SM; + +void LogUartDMAInit(void); +void LogUartDMAStart(uint8_t *p_outputbuf, uint16_t output_size); +void LogUartDMAIntrHandler(void); +void LogUartDMAIdleHook(void); +bool log_pm_check(void); + +void LogDMA_SM_Dispatch(T_LOG_DMA_SM *me, T_LOG_DMA_EVT const *e); + +__STATIC_INLINE void NEVER_HAPPEN(uint32_t line_no, T_LOG_DMA_SM *me, T_LOG_DMA_EVT const *e) +{ + OS_PRINT_WARN3("Line %d: Log SM Error: state: %d, signal: %d", line_no, me->State, e->Signal); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/platform/mem_types.h b/inc/platform/mem_types.h new file mode 100644 index 0000000..508e3f1 --- /dev/null +++ b/inc/platform/mem_types.h @@ -0,0 +1,49 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file Mem_types.h + * @brief define memory types for RAM + * @date 2017.6.6 + * @version v1.0 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +#ifndef _MEM_TYPES_H_ +#define _MEM_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup MEM_CONFIG Memory Configure + * @{ + */ + +/*============================================================================* + * Types +*============================================================================*/ +/** @defgroup MEM_CONFIG_Exported_Types Memory Configure Exported Types + * @{ + */ + +typedef enum +{ + RAM_TYPE_DATA_ON = 0, + RAM_TYPE_BUFFER_ON = 1, + RAM_TYPE_NUM = 2 +} RAM_TYPE; + +/** @} */ /* End of group MEM_TYPES_Exported_Types */ + +/** @} */ /* End of group MEM_CONFIG */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _MEM_TYPES_H_ */ diff --git a/inc/platform/otp.h b/inc/platform/otp.h new file mode 100644 index 0000000..98992d5 --- /dev/null +++ b/inc/platform/otp.h @@ -0,0 +1,282 @@ +/** +**************************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +**************************************************************************************************** +* @file otp.h +* @brief +* @date 2018-04-04 +* @version v1.0 +* ************************************************************************************************** +*/ + +#ifndef _OTP_H_ +#define _OTP_H_ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + OS_TICK_10MS = 0, + OS_TICK_5MS = 1, + OS_TICK_2MS = 2, + OS_TICK_1MS = 3, +} OS_TICK; + +/** + * @struct EFUSE_RAM_CONFIG + * @brief RAM EFuse settings. + * + * Refer to EFUSE[0x]. + */ +typedef struct EFUSE_RAM_CONFIG_ +{ + uint32_t phy_retram: 1; + uint32_t cam: 2; + uint32_t cache: 9; + uint32_t mcu_data_sram: 5; + uint32_t mcu_buffer_sram: 2; + uint32_t reserved: 13; +} __attribute__((packed)) EFUSE_RAM_CONFIG; + +enum +{ + MEMCFG_LOWPOWER, // active mode: set deep sleep + MEMCFG_UNUSED, // active mode: set shut down + MEMCFG_DEEPSLEEP, // lps/dlps mode: set deep sleep + MEMCFG_SHUTDOWN, // lps/dlps mode: set shut down + MEMCFG_MAX +}; + +/* OTP start addr: 0x00200164, size: 0x394 */ +typedef struct otp_struct +{ + uint8_t rsvd0[130]; //start addr:0x00200164 + uint8_t timer_diff_threshold; //start addr:0x002001e6 + uint8_t rsvd01[5]; //start addr:0x002001e7 + uint8_t bw_rf_low_clk_frac; //0x002001ec, 0: 32768 Hz, 1: 32000 Hz + uint8_t rsvd02[207]; + + /*****************upper *********************/ + /* start addr:0x002002bc,size:0x78*/ + uint64_t trace_mask[4]; + uint16_t stack_en: 1; //start addr:0x002002dc + uint16_t upper_rsvd1: 15; + uint8_t upper_rsvd2[86]; + /****************end upper *******************/ + + /*****************boot_cfg *******************/ + /* start addr:0x00200334, size:0x8*/ + uint32_t SWD_ENABLE: 1; + uint32_t boot_cfg_rsvd1: 15; + uint8_t boot_cfg_rsvd2; + uint8_t bt_tx_power; // start addr:0x00200337 + uint32_t boot_cfg_rsvd3; + /*************end boot_cfg *******************/ + + /*****************flash_cfg *******************/ + /* start addr:0x0020033c,size:0x10*/ + uint32_t flash_cfg_rsvd0: 27; + uint32_t is_support_deep_power_down: 1; + uint32_t rsvd: 1; + uint32_t data_byte_for_toggle_cs: 2; + uint32_t basic_cfg_from_otp: 1; /*!< basic configuration source ( 0: QVL; 1: OTP) */ + uint32_t flash_wait_max; //0x00200340 + uint32_t spic_wait_max; //0x00200344 + uint8_t flash_cfg_rsvd1[4]; + + /*************end flash_cfg *******************/ + + /*****************flash_setting ***************/ + /* start addr:0x0020034c,size:0x8 */ + uint8_t bit_mode: 2; + uint8_t flash_setting_rsvd0: 6; + uint8_t flash_setting_rsvd1: 3; + uint8_t bp_enable : 1; + uint8_t bp_lv : 4; + uint8_t delay_10us_before_toggle_cs; //start addr:0x0020034e + uint8_t delay_10us_after_toggle_cs; + uint8_t disable_irq_lv: 3; + uint8_t read_turn_on_off_rf: 1; + uint8_t flash_setting_rsvd2: 4; + uint8_t flash_setting_rsvd3[2]; //start addr:0x00200351 + uint8_t flash_dma_ch: 4; + uint8_t flash_setting_rsvd4: 4; + /*************end flash_setting *******************/ + + uint8_t pmu_cfg[15]; //start addr:0x00200354, size:0x24 + uint8_t pmu_cfg_rsvd: 5; + uint8_t ldo_311_aux_power_domain: 3; + uint8_t pmu_cfg_rsvd2[20]; + + /*****************os_cfg *********************/ + /* start addr: 0x00200378, size:0x1e,padding 2 bytes to ensure 4 bytes align */ + uint8_t getStackHighWaterMark : 1; /* 0 for release version, 1 for debug version */ + uint8_t checkForStackOverflow : 1; /* 0 for release version, 1 for debug version */ + uint8_t printAllLogBeforeEnterDLPS : 1; /* 0 for release version, 1 for debug version */ + uint8_t dumpMemoryWhenHardFaultOrWDG : 1; /* 0 for release version, 1 for debug version */ + uint8_t dumpMemoryUsage : 1; /* 0 for release version, 1 for debug version */ + uint8_t enableASSERT: 1; /* 0 for release version, 1 for debug version */ + uint8_t cpu_sleep_en: 1; /* default = 1 */ + uint8_t printDLPSCheckLog: 1; /* default = 0 */ + + uint8_t wdgConfigDivfactor; //addr=0x00200379, default = 31 + uint8_t wdgConfigCntLimit : 4; /* refer to WDG_Config(), default = 15 */ + uint8_t wdgEnableInRom : 1; /* 1 for release version, 0 for debug version */ + uint8_t wdgResetInRom : 1; /* 1 for release version, 0 for debug version */ + uint8_t wdgMode : 2; /* 0: interrupt CPU, 1: reset all but aon + 2: reset core domain, 3: reset all */ + + uint8_t timerMaxNumber; /* default = 0x20 */ + uint8_t timerQueueLength; /* default = 0x20 */ + uint8_t UseAliOS : 1; + uint8_t reserved : 7; + uint16_t dyn_malloc_task_stack_size; + + uint32_t appDataAddr; //0x00200380 + uint32_t appDataSize; //0x00200384 + uint32_t heapDataONSize; //0x00200388 + uint32_t heapBufferONSize; //0x0020038c + + uint16_t idle_task_stack_size; /* measured in bytes, default 256 * 4 bytes */ + uint16_t timer_task_stack_size; /* measured in bytes, default 256 * 4 bytes */ + uint16_t lower_task_stack_size; /* measured in bytes, default 768 * 4 bytes */ + uint8_t os_cfg_padding[2]; + /****************end os_cfg *******************/ + + /****************platform config****************/ + /* start addr: 0x00200398, size: 0xfe, padding size: 0x2 */ + uint32_t logPin : 6; /* default = P0_3 */ + uint32_t logChannel : 2; /* LogChannel_TypeDef: default is LOG_CHANNEL_LOG1_UART */ + uint32_t logBaudRate : 4; /* UartBaudRate_TypeDef: default is BAUD_RATE_2000000 */ + uint32_t platform_cfg_rsvd0 : 4; + uint32_t logDisable : 1; /* Disable all DBG_DIRECT and DBG_BUFFER log */ + uint32_t dump_info_before_reset : 1; + uint32_t write_info_to_flash_before_reset : 1; + uint32_t platform_cfg_rsvd1 : 1; + uint32_t log_ram_type : 1; + uint32_t image_split_read : 1; /* using split read in image integrity check */ + uint32_t ftl_mapping_table_ram_type : 1; + uint32_t ftl_enable_write_skip : 1; /*if enable, if read value equal write value will skip*/ + uint32_t ftl_logic_addr_map_bit_num : 3; /*4bit by step, default value is 3 means 12bit*/ + uint32_t platform_cfg_rsvd2 : 4; + uint32_t run_in_app : 1; + uint32_t aes_key[8]; /* for OTA encryption/decryption */ + uint32_t reboot_record_address; // 0x002003bc + + uint32_t reboot_record_item_limit_power_2 : 4; /* max number of reboot record (2^n), 0x002003c0*/ + uint32_t platform_cfg_rsvd3: 12; + uint32_t wdgIP : 1; /* default = 0 */ + uint32_t resetWhenHardFault : 1; + uint32_t log_ram_size : 3; + uint32_t hardfault_print_buf_log : 1; + uint32_t platform_cfg_rsvd4: 8; + uint32_t log_timestamp_src : 2; + + uint32_t platform_cfg_rsvd5: 13; //adc_channel, 0x002003c4 + uint32_t systick_clk_src: 1; + uint32_t platform_cfg_rsvd51: 12; + uint32_t ftl_use_mapping_table: 1; + uint32_t ftl_app_logical_addr_base: 3; + uint32_t ftl_only_gc_in_idle: 1; + uint32_t write_info_to_flash_when_hardfault: 1; + + uint32_t systick_ext_clk_freq; //0x002003c8 + uint32_t share_cache_ram_reg; //0x002003cc + uint32_t ftl_real_logic_addr_size; /* FTL real logic address size */ + + uint32_t Version; //start addr: 0x002003d4, size = 0x50 + uint32_t Info; // flash info + uint32_t PageSize; + uint32_t Main_Addr; + /*** flash layout table, 12 words***/ + uint32_t ota_bank0_addr; //0x002003e4 + uint32_t ota_bank0_size; + uint32_t ota_bank1_addr; + uint32_t ota_bank1_size; + uint32_t ftl_addr; //0x002003f4 + uint32_t ftl_size; + uint32_t ota_tmp_addr; + uint32_t ota_tmp_size; + uint32_t bkp_data1_addr; //0x00200404 + uint32_t bkp_data1_size; + uint32_t bkp_data2_addr; + uint32_t bkp_data2_size; //0x00200410 + /***** end flash layout table*******/ + uint32_t HardFault_Record_CFG; + uint32_t HardFault_Record_BegAddr; + uint32_t HardFault_Record_EndAddr; + uint8_t flash_info_tbl_rsvd1[3]; + uint8_t flash_info_tbl_padding; //padding 1 byte + + uint8_t flash_basic_cfg_rsvd[18]; // start addr: 0x00200424, size:0x12 + uint8_t flash_adv_cfg_rsvd[12]; //start addr: 0x00200436 , size:0xc + uint8_t flash_query_info_rsvd[12]; // start addr: 0x00200442, size:0xc + uint8_t flash_spec_cfg_rsvd1[54]; //start addr: 0x0020044e ,size:0x36 + uint32_t os_tick_rate_HZ; + uint8_t flash_spec_cfg_rsvd2[14]; + uint8_t flash_padding[2]; + /****************end platform config****************/ + + EFUSE_RAM_CONFIG ram_cfg[MEMCFG_MAX] __attribute__((aligned( + 4))); //start addr = 0x00200498, size=0x10 + uint8_t phy_init_cfg_rsvd0[3]; //start addr = 0x002004a8, size=0x28 + uint8_t tpm_max_txgain_LE1M; //start addr = 0x002004ab + uint8_t tpm_max_txgain_LE2M; + uint8_t tpm_max_txgain_LE2M_2402; //start addr = 0x002004ad + uint8_t tpm_max_txgain_LE2M_2480; //start addr = 0x002004ae + uint8_t phy_init_cfg_rsvd1[33]; + uint8_t cap_touch_cfg_rsvd[48]; //start addr = 0x002004d0, size=0x30, padding 1byte + + /*****************OTA Config *******************/ + /* start addr:0x00200500, size:0x16*/ + uint32_t ota_use_randon_address: 1; + uint32_t ota_adv_with_image_version: 1; + uint32_t ota_with_encryption_data: 1; + uint32_t ota_with_encryption_use_aes256: 1; + uint32_t ota_with_encryption_aes_type: 2; + uint32_t ota_resvd: 1; + uint32_t ota_link_loss_reset: 1; + uint32_t ota_use_buffer_check: 1; + uint32_t ota_rsrvd: 15; + uint32_t ota_timeout_wait_packet: 8; + uint8_t ota_rst_tgt_name[8]; + uint8_t ota_timeout_total; //0x0020050c + uint8_t ota_timeout_wait4_conn; + uint8_t ota_timeout_wait4_image_transfer; + uint8_t ota_timeout_ctittv; + uint8_t ota_adv_random_address[6]; //end addr = 0x002004f6 + + /* start addr:0x00200516, size: 0x8*/ + uint8_t clk_cfg_rsvd[12]; +} __attribute__((packed))T_OTP_CFG; +/*end otp, addr = 0x00200522*/ + +typedef enum +{ + EXTERNAL_CLOCK = 0, + CORE_CLOCK = 1 +} SYSTICK_CLK_SRC_TYPE; + +typedef enum +{ + ALWAYS_ACTIVE = 0, + AON_DOMAIN = 1, + PON_DOMAIN = 2, + CORE_DOMAIN = 4, + ALWAYS_INACTIVE = 6, +} LDO_POWER_DOMAIN_TYPE; + +#define OTP_STRUCT_BASE 0x00200164UL +#define OTP ((T_OTP_CFG *) OTP_STRUCT_BASE) + +#ifdef __cplusplus +} +#endif + +#endif /* _OTP_H_ */ + diff --git a/inc/platform/overlay_mgr.h b/inc/platform/overlay_mgr.h new file mode 100644 index 0000000..bb3febc --- /dev/null +++ b/inc/platform/overlay_mgr.h @@ -0,0 +1,95 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file overlay_mgr.h + * @brief + * @author + * @date + * @version + *************************************************************************************** + * @attention + *

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    + *************************************************************************************** + */ + +#ifndef _OVERLAY_MGR_H_ +#define _OVERLAY_MGR_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup OVERLAY_MANAGER Overlay Manager + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup OVERLAY_MANAGER_Exported_Types Overlay Manager Exported Types + * @{ + */ +typedef enum +{ + OVERLAY_SCENARIO_BOOT_ONCE = 0, + OVERLAY_SCENARIO_B, + OVERLAY_SCENARIO_C, + OVERLAY_SCENARIO_NUM, +} T_OVERLAY_SCENARIO_IDX; + +typedef struct +{ + char *signature; + + void *load_ro_base; + void *load_rw_base; + + void *image_ro_base; + void *image_rw_base; + void *image_zi_base; + + uint32_t ro_length; + uint32_t rw_length; + uint32_t zi_length; +} T_OVERLAY_SECTION; +/** End of OVERLAY_MANAGER_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup OVERLAY_MANAGER_Exported_Functions Overlay Manager Exported Functions + * @brief + * @{ + */ +/** + * @brief Load Code(RO), RW Data and ZI Data of a given overlay section. + * @param scenario_idx Overlay section index, support only three sections now. + * @return None + */ +bool load_overlay(T_OVERLAY_SCENARIO_IDX scenario_idx); + +/** + * @brief return the current scenario index + * @param none. + * @return @ref T_OVERLAY_SCENARIO_IDX + * @retval OVERLAY_SCENARIO_NUM, invalid scenario index + * @retval other T_OVERLAY_SCENARIO_IDX value, valid secnario index + */ +T_OVERLAY_SCENARIO_IDX get_current_scenario_index(void); + +/** @} */ /* End of group OVERLAY_MANAGER_Exported_Functions */ + + +/** @} */ /* End of group OVERLAY_MANAGER */ + +#ifdef __cplusplus +} +#endif + +#endif /* _OVERLAY_MGR_H_ */ diff --git a/inc/platform/patch_header_check.h b/inc/platform/patch_header_check.h new file mode 100644 index 0000000..b68b289 --- /dev/null +++ b/inc/platform/patch_header_check.h @@ -0,0 +1,334 @@ +/** + ****************************************************************************** + * @file patch_header_check.h + * @author + * @version V0.0.1 + * @date 2017-09-01 + * @brief This file contains all the functions regarding patch header check. + ****************************************************************************** + * @attention + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + * + * Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. + ****************************************************************************** + */ + +#ifndef _PATCH_HEADER_CHECK_H_ +#define _PATCH_HEADER_CHECK_H_ +#include +#include +#include "rtl876x.h" +#include "flash_device.h" +#include "rtl876x_ic_type.h" + +/** @addtogroup FLASH_DEVICE Flash Device + * @{ + */ + +/*============================================================================* + * Constants + *============================================================================*/ +/** @defgroup FLASH_DEVICE_Exported_Constants Flash Device Exported Constants + * @brief + * @{ + */ + +#define SIGNATURE_APP_CB 0x0e85d101 /**< patch callback app signature definition*/ +#define UUID_SIZE 16 + +#define DEFINED_IC_TYPE IC_TYPE + +#define DFU_HEADER_SIZE 12 /*currently, first 12 byte only will be treated as image header*/ +#define IMG_HEADER_SIZE 1024 + +#define FSBL_EXT_PATTERN 0x736c + +#define UP_ALIGN(size, align) (((size) + (align) - 1) & ~(align - 1)) + + +/** End of FLASH_DEVICE_Exported_Constants + * @} + */ + + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup FLASH_DEVICE_Exported_Types Flash Device Exported Types + * @brief + * @{ + */ + +typedef enum +{ + IMAGE_FIRST = 0x278D, + SCCD = 0x278D, + OCCD = 0x278E, + FactoryCode = 0x278F, + OTA = 0x2790, /**< OTA header */ + SecureBoot = 0x2791, + RomPatch = 0x2792, + AppPatch = 0x2793, + AppData1 = 0x2794, + AppData2 = 0x2795, + AppData3 = 0x2796, + AppData4 = 0x2797, + AppData5 = 0x2798, + AppData6 = 0x2799, + UpperStack = 0x279a, + IMAGE_MAX = 0x279b, + IMAGE_USER_DATA = 0xFFFE, /** +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief LogMissedCounter records the number of log missed. + If the value is greater then 0, please reduce logs or speed up log uart/DMA. + */ +typedef struct +{ + uint8_t *pInputBuffer; + uint8_t *pOutputBuffer; + uint16_t InputBufferSize; + uint16_t OutputBufferSize; + uint32_t LogMissedCounter; + uint32_t MaxBufferSize; +} PingpongBuffer; + +static inline uint32_t PPB_GetLogMissedCounter(PingpongBuffer *pPPB) +{ + return pPPB->LogMissedCounter; +} + +static inline void PPB_ClearLogMissedCounter(PingpongBuffer *pPPB) +{ + pPPB->LogMissedCounter = 0; +} + +static inline bool PPB_IsInit(PingpongBuffer *pPPB) +{ + return ((pPPB->pInputBuffer != NULL) && (pPPB->pOutputBuffer != NULL)); +} + +static inline bool PPB_IsOutputBufEmpty(PingpongBuffer *pPPB) +{ + return (pPPB->OutputBufferSize == 0); +} + +static inline bool PPB_IsInputBufEmpty(PingpongBuffer *pPPB) +{ + return (pPPB->InputBufferSize == 0); +} + +static inline uint16_t PPB_GetOutputBufSize(PingpongBuffer *pPPB) +{ + return pPPB->OutputBufferSize; +} + +static inline uint16_t PPB_GetInputBufSize(PingpongBuffer *pPPB) +{ + return pPPB->InputBufferSize; +} + +void PPB_Init(PingpongBuffer *pPPB); +void PPB_Uninit(PingpongBuffer *pPPB); +void PPB_Init_DLPS_Restore(PingpongBuffer *pPPB); +void PPB_Write(PingpongBuffer *pPPB, const uint8_t *source, uint16_t size); +void PPB_ClearOutputBuffer(PingpongBuffer *pPPB); +void PPB_BufSwitch(PingpongBuffer *pPPB); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/platform/platform_autoconf.h b/inc/platform/platform_autoconf.h new file mode 100644 index 0000000..c3d386c --- /dev/null +++ b/inc/platform/platform_autoconf.h @@ -0,0 +1,63 @@ +/** +************************************************************************************************************ +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file platform_autoconf.h +* @brief Platform configuration +* @author +* @date 2018-04-16 +* @version v0.1 +************************************************************************************************************* +*/ +#ifndef _PLATFORM_AUTOCONF_H_ +#define _PLATFORM_AUTOCONF_H_ + + +/** @defgroup BUILD_CONFIGURATION Build Configuration + * @brief Platform build configuration + * @{ + */ + +//#define RELEASE_VERSION + +#ifdef RELEASE_VERSION +#define CHECK_STACK_OVERFLOW_ENABLE 0 +#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 0 +#define PLATFORM_ASSERT_ENABLE 0 +#define CONFIG_LOG_FUNCTION_ENABLE 0 +#define RUN_APP_IN_HCIMODE_ENABLE 0 +#define SUPPORT_FTL_IN_APP 0 +/*disable it if need reduce code size*/ +#define ENABLE_FULL_FEATURED_DIRECT_LOG 1 +/** + * RETARGET_PRINTF_METHOD different value + * 0: redefine printf empty function + * 1: redefine printf and using except log uart to print log + * others: redefine printf just using log uart to print log +*/ +#define RETARGET_PRINTF_METHOD 0 +#else +#define CHECK_STACK_OVERFLOW_ENABLE 1 +#define CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE 1 +#define PLATFORM_ASSERT_ENABLE 1 +#define CONFIG_LOG_FUNCTION_ENABLE 1 +#define RUN_APP_IN_HCIMODE_ENABLE 0 +#define SUPPORT_FTL_IN_APP 0 +/*disable it if need reduce code size*/ +#define ENABLE_FULL_FEATURED_DIRECT_LOG 1 + +/** + * RETARGET_PRINTF_METHOD different value + * 0: redefine printf empty function + * 1: redefine printf and using except log uart to print log + * others: redefine printf just using log uart to print log +*/ +#define RETARGET_PRINTF_METHOD 0 +#endif + + +/** End of BUILD_CONFIGURATION + * @} + */ + +#endif /* End of _PLATFORM_AUTOCONF_H_ */ diff --git a/inc/platform/platform_utils.h b/inc/platform/platform_utils.h new file mode 100644 index 0000000..60d5e77 --- /dev/null +++ b/inc/platform/platform_utils.h @@ -0,0 +1,124 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ + * @file platform_utils.h + * @brief utility helper function for user application + * @author lory_xu + * @date 2017-02 + * @version v1.0 + *************************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + *************************************************************************************** + */ + +#ifndef _PLATFORM_UTILS_H_ +#define _PLATFORM_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Header Files +*============================================================================*/ +#include +#include +#include +#include "rtl876x.h" +/** @defgroup PLATFORM_UTILS Platform Utilities + * @brief Utility helper functions + * @{ + */ + +#if (PLATFORM_SUPPORT_CLOCK_MANAGER == 1) +#include "clock_manager.h" +#else +#define CLOCK_100MHZ 100000000 +#define CLOCK_90MHZ 90000000 +#define CLOCK_40MHZ 40000000 +#define CLOCK_53MHZ 53333333 +#define CLOCK_80MHZ 80000000 +#define CLOCK_20MHZ 20000000 +#define CLOCK_10MHZ 10000000 +#define CLOCK_5MHZ 5000000 +#define CLOCK_2P5MHZ 2500000 +#define CLOCK_1P25MHZ 1250000 +#define CLOCK_625KHZ 625000 +#endif + + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup PLATFORM_UTILS_Exported_Functions Platform Utilities Exported Functions + * @brief + * @{ + */ + +/** + * @brief Generate random number given max number allowed + * @param max to specify max number that allowed + * @return random number + */ + +extern uint32_t platform_random(uint32_t max); + + +#if defined ( __CC_ARM ) +/** + * @brief Busy delay for a specified number of milliseconds. + * @param[in] t The number of milliseconds to delay. + * @return none + */ +extern volatile void (*platform_delay_ms)(uint32_t t); +/** + * @brief Busy delay for a specified number of microseconds. + * @param[in] t The number of microseconds to delay. + * @return none + */ +extern volatile void (*platform_delay_us)(uint32_t t); +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) || defined (__GNUC__) +/** + * @brief Busy delay for a specified number of milliseconds. + * @param[in] t The number of milliseconds to delay. + * @return none + */ +extern void (*platform_delay_ms)(uint32_t t); +/** + * @brief Busy delay for a specified number of microseconds. + * @param[in] t The number of microseconds to delay. + * @return none + */ +extern void (*platform_delay_us)(uint32_t t); +#endif + +/** + * @brief Get the vendor timer tick + + * @param none + * @return none + * @note Features of the vendor timer: + * (1) clock rate is 40M + * (2) width is 26 bits (max 0x3FFFFFF) + * (3) tick counter is incremental + * + */ +static inline uint32_t platform_vendor_tick(void) +{ + return HAL_READ32(VENDOR_REG_BASE, 0x30); +} + +/** @} */ /* End of group PLATFORM_UTILS_Exported_Functions */ + +/** @} */ /* End of group PLATFORM_UTILS */ + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/platform/psram_platform.h b/inc/platform/psram_platform.h new file mode 100644 index 0000000..7b7b6de --- /dev/null +++ b/inc/platform/psram_platform.h @@ -0,0 +1,27 @@ +#ifndef _PSRAM_PLATFORM_H_ +#define _PSRAM_PLATFORM_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void psram_init(void); + +void psram_config(uint8_t bit_mode); + +void psram_try_high_speed(void); + +bool psram_read(uint32_t addr, uint32_t len, uint8_t *data); + +bool psram_write(uint32_t addr, uint32_t len, uint8_t *data); + +void psram_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _PSRAM_PLATFORM_H_ */ diff --git a/inc/platform/qspi_lcd_platform.h b/inc/platform/qspi_lcd_platform.h new file mode 100644 index 0000000..e4d9f48 --- /dev/null +++ b/inc/platform/qspi_lcd_platform.h @@ -0,0 +1,17 @@ +#ifndef _QSPI_LCD_PLATFORM_H_ +#define _QSPI_LCD_PLATFORM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void qspi_lcd_platform_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _QSPI_LCD_PLATFORM_H_ */ diff --git a/inc/platform/readme b/inc/platform/readme new file mode 100644 index 0000000..e69de29 diff --git a/inc/platform/rom_uuid.h b/inc/platform/rom_uuid.h new file mode 100644 index 0000000..f46e6ad --- /dev/null +++ b/inc/platform/rom_uuid.h @@ -0,0 +1,4 @@ +#ifndef _rom_uuid_h +#define _rom_uuid_h +#define DEFINE_rom_uuid { 0xf9,0x4c,0x6b,0x7e,0x11,0xc5,0xeb,0x11,0x82,0x82,0xf7,0x4a,0x0c,0x0c,0xef,0x5b } +#endif diff --git a/inc/platform/rtl876x.h b/inc/platform/rtl876x.h new file mode 100644 index 0000000..4ef1678 --- /dev/null +++ b/inc/platform/rtl876x.h @@ -0,0 +1,3593 @@ + +/** +***************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file rtl876x.h + * @brief CMSIS Cortex-M0+ Peripheral Access Layer Header File for + * RTL876X from Realtek Semiconductor. + * @date 2020.10.10 + * @version v1.0 + + * @date 3. March 2015 + * + * @note Generated with SVDConv Vx.xxp + * from CMSIS SVD File 'RTL876X.xml' Version x.xC, + * + * @par Copyright (c) 2020 Realtek Semiconductor. All Rights Reserved. + * + * The information contained herein is property of Realtek Semiconductor. + * Terms and conditions of usage are described in detail in Realtek + * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * + * Licensees are granted free, non-transferable use of the information. NO + * WARRANTY of ANY KIND is provided. This heading must NOT be removed from + * the file. + * + * + + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2020 Realtek Semiconductor Corporation

    + * ************************************************************************************* +*/ + +#ifndef RTL876X_H +#define RTL876X_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @defgroup RTL876X Rtl876x + * @brief CMSIS Cortex-M0+ peripheral access layer header file for + * RTL876X from Realtek Semiconductor + * @{ + */ + +/*============================================================================* + * Types +*============================================================================*/ +/** @defgroup RTL876x_Exported_types RTL876X Exported types + * @{ + */ + +/** brief Interrupt Number Definition */ +typedef enum IRQn +{ + /* ------------------- Cortex-M0+ Processor Exceptions Numbers ------------------- */ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 HardFault Interrupt */ + SVCall_IRQn = -5, /**< 11 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 System Tick Interrupt */ + + System_IRQn = 0, /**< [0] System Interrupt */ + WDG_IRQn, /**< [1] Watch Dog Interrupt */ + BTMAC_IRQn, /**< [2] BTMAC Interrupt ( an Extension of interrupt ) */ + Timer3_IRQn, /**< [3] Timer3 global interrupt */ + Timer2_IRQn, /**< [4] Timer2 global interrupt */ + Platform_IRQn, /**< [5] Platform error interrupt */ + I2S0_RX_IRQn, /**< [6] I2S0 RX interrupt */ + I2S0_TX_IRQn, /**< [7] I2S0 TX interrupt */ + Timer4_5_IRQn, /**< [8] Timer 4 to 5 interrupt ( an Extension of interrupt ) */ + GPIO4_IRQn, /**< [9] GPIO 4 interrupt */ + GPIO5_IRQn, /**< [10] GPIO 5 interrupt */ + UART1_IRQn, /**< [11] UART1 interrupt */ + UART0_IRQn, /**< [12] UART0 interrupt */ + RTC_IRQn, /**< [13] Realtime counter interrupt */ + SPI0_IRQn, /**< [14] SPI0 interrupt */ + SPI1_IRQn, /**< [15] SPI1 interrupt */ + I2C0_IRQn, /**< [16] I2C0 interrupt */ + I2C1_IRQn, /**< [17] I2C1 interrupt */ + ADC_IRQn, /**< [18] ADC global interrupt */ + Peripheral_IRQn, /**< [19] Peripheral Interrupt ( an Extension of interrupt ) */ + GDMA0_Channel0_IRQn, /**< [20] RTK-DMA0 channel 0 global interrupt */ + GDMA0_Channel1_IRQn, /**< [21] RTK-DMA0 channel 1 global interrupt */ + GDMA0_Channel2_IRQn, /**< [22] RTK-DMA0 channel 2 global interrupt */ + GDMA0_Channel3_IRQn, /**< [23] RTK-DMA0 channel 3 global interrupt */ + ENHANCED_TIMER0_IRQn, /**< [24] Enhanced timer0 interrupt */ + ENHANCED_TIMER1_IRQn, /**< [25] Enhanced timer1 interrupt */ + GPIO_Group3_IRQn, /**< [26] GPIO Group3 Interrupt ( an Extension of interrupt ) */ + GPIO_Group2_IRQn, /**< [27] GPIO Group2 Interrupt ( an Extension of interrupt ) */ + IR_IRQn, /**< [28] IR Interrupt */ + GPIO_Group1_IRQn, /**< [29] GPIO Group1 Interrupt ( an Extension of interrupt ) */ + GPIO_Group0_IRQn, /**< [30] GPIO Group0 Interrupt ( an Extension of interrupt ) */ + Reserved_IRQn, /**< [31] Reserved */ + /****** Bee3 Extension Interrupt Numbers ************/ + TIMER4_IRQ = 8, + TIMER5_IRQ = 8, + GPIO3_IRQn = 26, + GPIO7_IRQn = 26, + GPIO11_IRQn = 26, + GPIO15_IRQn = 26, + GPIO19_IRQn = 26, + GPIO23_IRQn = 26, + GPIO27_IRQn = 26, + GPIO31_IRQn = 26, + GPIO2_IRQn = 27, + GPIO6_IRQn = 27, + GPIO10_IRQn = 27, + GPIO14_IRQn = 27, + GPIO18_IRQn = 27, + GPIO22_IRQn = 27, + GPIO26_IRQn = 27, + GPIO30_IRQn = 27, + GPIO1_IRQn = 29, + GPIO9_IRQn = 29, + GPIO13_IRQn = 29, + GPIO17_IRQn = 29, + GPIO21_IRQn = 29, + GPIO25_IRQn = 29, + GPIO29_IRQn = 29, + GPIO0_IRQn = 30, + GPIO8_IRQn = 30, + GPIO12_IRQn = 30, + GPIO16_IRQn = 30, + GPIO20_IRQn = 30, + GPIO24_IRQn = 30, + GPIO28_IRQn = 30, + Peripheral_First_IRQn = 50, + SPIC0_IRQn = 50, + qdecode_IRQn = 51, + KeyScan_IRQn = 52, + SPI2W_IRQn = 53, + LPCOMP_IRQn = 54, + PTA_Mailbox_IRQn = 55, + CAP_TOUCH_IRQn = 56, + TRNG_IRQn = 57, +} IRQn_Type, *PIRQn_Type; +/** @} */ /* End of group RTL876x_Exported_types */ + +/** @defgroup Configuration_of_CMSIS Configuration of CMSIS + * @brief Configuration of the cm4 Processor and Core Peripherals + * @{ + */ +/* ----------------Configuration of the cm0+ Processor and Core Peripherals---------------- */ +#define __FPU_PRESENT 0 /* FPU present */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +/** @} */ /* End of group Configuration_of_CMSIS */ + +/*============================================================================* + * Header Files +*============================================================================*/ +/* Processor and core peripherals */ +#include "core_cm0plus.h" +#include "system_rtl876x.h" +#include "rtl876x_ic_type.h" + +/*============================================================================* + * Types +*============================================================================*/ +/** @addtogroup RTL876x_Exported_types RTL876X Exported types + * @{ + */ + +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} FunctionalState; + +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) +//typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; + +/** @} */ /* End of group RTL876x_Exported_types */ + + +/*============================================================================* + * RTL876X Pin Number +*============================================================================*/ +/** @defgroup RTL876X_Pin_Number RTL876X Pin Number + * @{ + */ +#if (IC_TYPE == IC_TYPE_BEE3) + +#define P0_0 0 /**> 8) |\ + (((uint32_t)(x) & (uint32_t)0xff000000) >> 24))) + +#define WAP16(x) ((uint16_t)(\ + (((uint16_t)(x) & (uint16_t)0x00ff) << 8) |\ + (((uint16_t)(x) & (uint16_t)0xff00) >> 8))) + +#if SYSTEM_ENDIAN == LITTLE_ENDIAN +#ifndef rtk_le16_to_cpu +#define rtk_cpu_to_le32(x) ((uint32_t)(x)) +#define rtk_le32_to_cpu(x) ((uint32_t)(x)) +#define rtk_cpu_to_le16(x) ((uint16_t)(x)) +#define rtk_le16_to_cpu(x) ((uint16_t)(x)) +#define rtk_cpu_to_be32(x) SWAP32((x)) +#define rtk_be32_to_cpu(x) SWAP32((x)) +#define rtk_cpu_to_be16(x) WAP16((x)) +#define rtk_be16_to_cpu(x) WAP16((x)) +#endif + +#elif SYSTEM_ENDIAN == BIG_ENDIAN +#ifndef rtk_le16_to_cpu +#define rtk_cpu_to_le32(x) SWAP32((x)) +#define rtk_le32_to_cpu(x) SWAP32((x)) +#define rtk_cpu_to_le16(x) WAP16((x)) +#define rtk_le16_to_cpu(x) WAP16((x)) +#define rtk_cpu_to_be32(x) ((uint32_t)(x)) +#define rtk_be32_to_cpu(x) ((uint32_t)(x)) +#define rtk_cpu_to_be16(x) ((uint16_t)(x)) +#define rtk_be16_to_cpu(x) ((uint16_t)(x)) +#endif +#endif + +#define HAL_READ32(base, addr) \ + rtk_le32_to_cpu(*((volatile uint32_t *)(base + addr))) + +#define HAL_WRITE32(base, addr, value32) \ + ((*((volatile uint32_t *)(base + addr))) = rtk_cpu_to_le32(value32)) + +#define HAL_UPDATE32(addr, mask, value32) \ + HAL_WRITE32(0, addr, (HAL_READ32(0, addr) & ~mask) | (value32 & mask)) + +#define HAL_READ16(base, addr) \ + rtk_le16_to_cpu(*((volatile uint16_t *)(base + addr))) + +#define HAL_WRITE16(base, addr, value) \ + ((*((volatile uint16_t *)(base + addr))) = rtk_cpu_to_le16(value)) + +#define HAL_UPDATE16(addr, mask, value16) \ + HAL_WRITE16(0, addr, (HAL_READ16(0, addr) & ~mask) | (value16 & mask)) + +#define HAL_READ8(base, addr) \ + (*((volatile uint8_t *)(base + addr))) + +#define HAL_WRITE8(base, addr, value) \ + ((*((volatile uint8_t *)(base + addr))) = value) + +#define HAL_UPDATE8(addr, mask, value8) \ + HAL_WRITE8(0, addr, (HAL_READ8(0, addr) & ~mask) | (value8 & mask)) + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#ifdef BIT +#undef BIT +#endif +#define BIT(_n) (uint32_t)(1U << (_n)) + +#ifdef BIT64 +#undef BIT64 +#endif +#define BIT64(n) (1ULL << (n)) + +#define BIT_BAND(reg, bit_pos) (*((volatile uint32_t*)(0x42000000 + ((uint32_t)® - 0x40000000) * 32 + bit_pos * 4))) + + +/* Uncomment the line below to expanse the "assert_param" macro in the + Standard Peripheral Library drivers code */ + +//#define USE_FULL_ASSERT + +/** @} */ /* End of group RTL876X_Exported_Macros */ + + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup RTL876X_Exported_Functions RTL876X Sets Exported Functions + * @brief + * @{ + */ +#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)0 : io_assert_failed((uint8_t *)__FILE__, __LINE__)) +void io_assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + +/** + * @brief Read data from aon register + * @param offset: register address + * @return data read from register + */ +extern uint16_t btaon_fast_read(uint16_t offset); +extern uint8_t btaon_fast_read_8b(uint16_t offset); + +/** + * @brief Read data from aon register safely + * @param offset: register address + * @return data read from register + */ +extern uint16_t btaon_fast_read_safe(uint16_t offset); +extern uint8_t btaon_fast_read_safe_8b(uint16_t offset); + +/** + * @brief Write data to aon register + * @param offset: register address + * @param data: data to be writen to register + * @return + */ +extern void btaon_fast_write(uint16_t offset, uint16_t data); +extern void btaon_fast_write_8b(uint16_t offset, uint8_t data); + +/** + * @brief Write data to aon egister safely + * @param offset: register address + * @param data: data to be writen to register + * @return + */ +extern void btaon_fast_write_safe(uint16_t offset, uint16_t data); +extern void btaon_fast_write_safe_8b(uint16_t offset, uint8_t data); + +/** + * @brief Write data to aon egister + * @param offset: register address + * @param mask: indicate which bit in data will be updated + * @param data: data to be writen to register + * @return + */ +extern void btaon_fast_update(uint16_t offset, uint16_t mask, uint16_t data); +extern void btaon_fast_update_8b(uint16_t offset, uint8_t mask, uint8_t data); + +/** + * @brief Write data to aon egister safely + * @param offset: register address + * @param mask: indicate which bit in data will be updated + * @param data: data to be writen to register + * @return + */ +extern void btaon_fast_update_safe(uint16_t offset, uint16_t mask, uint16_t data); +extern void btaon_fast_update_safe_8b(uint16_t offset, uint8_t mask, uint8_t data); + +/** @} */ /* End of RTL876X_Exported_Functions */ + +/** @} */ /* End of group RTL876X */ + +#ifdef __cplusplus +} +#endif +#endif /* RTL876X_H */ + diff --git a/inc/platform/rtl876x_ic_type.h b/inc/platform/rtl876x_ic_type.h new file mode 100644 index 0000000..9c006b2 --- /dev/null +++ b/inc/platform/rtl876x_ic_type.h @@ -0,0 +1,33 @@ +/** +***************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ + * @file rtl876x_ic_type.h + * @brief IC type selection + * @author + * @date + * @version v1.0 + *************************************************************************************** + * @attention + *

    © COPYRIGHT 2020 Realtek Semiconductor Corporation

    + *************************************************************************************** + */ + +#ifndef _RTL876X_IC_TYPE_H_ +#define _RTL876X_IC_TYPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define IC_TYPE_SBEE2 9 +#define IC_TYPE_BEE3 12 + +#define IC_TYPE IC_TYPE_BEE3 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/inc/platform/rtl876x_lib_platform.h b/inc/platform/rtl876x_lib_platform.h new file mode 100644 index 0000000..b5de50f --- /dev/null +++ b/inc/platform/rtl876x_lib_platform.h @@ -0,0 +1,247 @@ +/** +************************************************************************************************************ +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file rtl876x_lib_platform.h +* @brief +* @details +* @author +* @date +* @version +************************************************************************************************************* +*/ + +#ifndef _RTL876X_LIB_PLATFORM_H_ +#define _RTL876X_LIB_PLATFORM_H_ + +#include +#include +#include +#include "mem_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + READ_SUCCESS = 0, + READ_NOT_FIND_CONFIG = 1, + READ_NOT_FIND_BDADDR = 2, + READ_NOT_FIND_XTAL_OFFSET = 3, + READ_FAIL = 4, +} T_READ_BDADDR_RESULT; + +typedef enum +{ + EFUSE_UPDATE_SUCCESS = 0, + EFUSE_UPDATE_READ_PROTECTED, + EFUSE_UPDATE_WRITE_MAC_FAIL, + EFUSE_UPDATE_SPACE_EXHAUSTED, + EFUSE_UPDATE_READ_FAIL, +} T_EFUSE_UPDATE_RESULT; + +typedef enum +{ + DSN = 0, + HWREV, + PSN, + SKUID, + IRID, + PRO_PID +} T_FLASH_READ_PROVISION; + +typedef enum +{ + BT_MAC = 0, //BD address + BT_MAX_LE_LINK_NUM, + BT_LE_MASTER_LINK_NUM, + BT_LE_SLAVE_LINK_NUM, +} T_READ_PARAMETER; + +/** + * @brief another log buffer API, the fmt string will occupy flash space + */ +void log_buffer_retarget(uint32_t info, const char *fmt, ...); + +#define DBG_BUFFER_RETARGET(...) do {\ + log_buffer_retarget(COMBINE_TRACE_INFO(TYPE_BEE2, SUBTYPE_DIRECT, 0, 0), __VA_ARGS__);\ + } while (0) + +/*============================================================================* + * Log Retarget Sample Usage + *============================================================================*/ +/** + * @brief retarget other library code log to bee2 buffer log print. + * @note If enable, increase code size because more log will occupy flash space + * +* Example usage + * \code{.c} + +//enable retarget other library code log to bee2 buffer log print or not +#define ENABLE_RETARGET_LOG 1 + +#if ENABLE_RETARGET_LOG +#define LogDebug(...) DBG_BUFFER_RETARGET(__VA_ARGS__) +#else +#define LogDebug(...) +#endif + +void test_log_retarget(void) +{ + char str[] = {'a','b','c', '\0'}; + float data1 = 3.14125; + uint32_t data2 = 1024; + LogDebug("test"); + LogDebug("string:%s", str); + LogDebug("float:%f", data1); + LogDebug("uint:%d", data2); +} + * \endcode + */ +/*============================================================================*/ + +/** + * @brief peek max free block size of specified ram type heap + */ +size_t os_mem_max_free_block_peek(RAM_TYPE ram_type); + + +void show_sdk_lib_version(void); + +/** + * @brief read bd addr set in config file + * @param p_bdaddr: buffer to save bd addr + * @retval read result + * @arg 0: read success + * @arg 1: no config file in flash + * @arg 2: no bd setting found + */ +T_READ_BDADDR_RESULT read_config_bdaddr(uint8_t *p_bdaddr); + +/** + * @brief read mp config parameter + * @param type: the item of config file + * @param p_data: the return data + * @arg true: read success + * @arg false: read fail + */ +T_READ_BDADDR_RESULT read_config_item(T_READ_PARAMETER type, uint8_t *p_data); + +/** + * @brief read xtal offset set in config file + * @param p_xtal_offset: buffer to save xtal offset + * @retval read result + * @arg 0: read success + * @arg 1: no config file in flash + * @arg 3: no xtal offset found + */ +T_READ_BDADDR_RESULT read_config_xtal_offset(uint8_t *p_xtal_offset); + +/** + * @brief update bd address set in config file + * @param p_cfg_read_addr: the address of read config file + * @param p_cfg_write_addr: the address of write config file + * @param p_bdaddr: buffer to the updated bd address + * @retval update result + * @arg true: update success + * @arg false: update fail + */ +bool update_bdaddr(uint8_t *p_cfg_read_addr, uint8_t *p_cfg_write_addr, uint8_t *p_bdaddr); + +/** + * @brief update xtal offset set in config file + * @param p_cfg_read_addr: the address of read config file + * @param p_cfg_write_addr: the address of write config file + * @param xtal: the updated xtal offset + * @retval update result + * @arg true: update success + * @arg false: update fail + */ +bool update_xtal_offset(uint8_t *p_cfg_read_addr, uint8_t *p_cfg_write_addr, uint8_t xtal); + +/** + * @brief Write MAC address to config, this is mainly used on production line. + * @param[in] p_mac_addr The buffer hold MAC address (48 bits). + * @return Write MAC to config fail or success. + * @retval true Write MAC to config success. + * @retval false Write MAC to config fails or not write existed MAC. + */ +bool UpdateMAC(uint8_t *p_mac_addr); + +/** + * @brief update tx power in config file + * @param[in] tx_power index for power. tx_power = power*2 + tx_power Power + 0x10 8 dBm + 0x8 4 dBm + 0x6 3 dBm + 0x0 0 dBm + 0xD8 -20 dBm + * @return update tx power to config fail or success. + * @retval true update tx power to config success. + * @retval false update tx power to config fails or not write existed tx power. + */ +bool UpdateTxPower(uint8_t tx_power); + +/** + * @brief Write MAC address to eFuse, this is mainly used on production line. + * Because eFuse space limitation, only write MAC to eFuse once supported. + * @param[in] p_mac_addr The buffer hold MAC address (48 bits). + * @return Write MAC to config fail or success. + * @retval EFUSE_UPDATE_SUCCESS Write MAC to eFuse success. + * @retval EFUSE_UPDATE_READ_PROTECTED Can not update eFuse while it is read protected. + * @retval EFUSE_UPDATE_WRITE_MAC_FAIL Write MAC to eFuse fails. + * @retval EFUSE_UPDATE_SPACE_EXHAUSTED eFuse space is exhausted. + */ +T_EFUSE_UPDATE_RESULT update_mac_to_efuse(uint8_t *p_mac_addr); + +/** + * @brief Write 40M XTAL calibration data to config, this is mainly used on production line. + * @param[in] xtal The value of 40M XTAL calibration data + * @return Write calibration data to config fail or success. + * @retval true Success. + * @retval false Fail. + */ +bool WriteXtalToConfig(uint8_t xtal); + +/** + * @brief Write 40M XTAL calibration data to Efuse, this is mainly used on production line. + * @param[in] xtal The value of 40M XTAL calibration data + * @return Write calibration data to Efuse fail or success. + * @retval true Success. + * @retval false Fail. + * @note The Efuse space is limited, please don't call this function more than 5 five times. + */ +bool WriteXtalToEfuse(uint8_t xtal); + + +/** + * @brief allow customers to write provision data to specific flash region + * @param data input data + * @param region input region + * @ret true if success + */ +bool flash_provision_write(uint8_t *data, T_FLASH_READ_PROVISION region); + +/** + * @brief allow customers to read provision data from specific flash region + * @param data output data + * @param region output region + * @ret true if success + */ +bool flash_provision_read(uint8_t *data, T_FLASH_READ_PROVISION region); + +/** + * @brief get 14 bytes EUID + * @param none + * @return uint8_t *, the pointer to a copy of EUID. + */ +uint8_t *get_ic_euid(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* _RTL876X_LIB_PLATFORM_H_ */ diff --git a/inc/platform/sha256.h b/inc/platform/sha256.h new file mode 100644 index 0000000..c5dfd0f --- /dev/null +++ b/inc/platform/sha256.h @@ -0,0 +1,92 @@ +/********************************************************************* +* Filename: sha256.h +* Author: Brad Conte (brad AT bradconte.com) +* Copyright: +* Disclaimer: This code is presented "as is" without any guarantees. +* Details: Defines the API for the corresponding SHA1 implementation. +*********************************************************************/ + +/* + This code is released into the public domain free of any restrictions. + The author requests acknowledgement if the code is used, but does not require it. + This code is provided free of any liability and without any quality claims by the author. + https://github.com/B-Con/crypto-algorithms + */ + +#ifndef SHA256_H +#define SHA256_H + +/*************************** HEADER FILES ***************************/ +#include +#include +#include + +/** @defgroup SHA256_API Sha256 + * @brief APIs for using SHA256 + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SHA256_API_Exported_Macros SHA256 APIs Exported Macros + * @{ + */ + +#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest + +#define SHA256_USE_DYNAMIC_ALLOC 0 + +/** End of SHA256_API_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SHA256_API_Exported_Types SHA256 APIs Exported Types + * @{ + */ + +typedef unsigned char BYTE; // 8-bit byte +typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines + +/** @brief Context structure to store SHA256 algorithm intermediate information */ +typedef struct +{ + BYTE data[64]; + WORD datalen; + unsigned long long bitlen; + WORD state[8]; +} SHA256_CTX; + +/** End of SHA256_API_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup SHA256_API_Exported_Functions SHA256 APIs Exported Functions + * @brief + * @{ + */ + +void SHA256_Init(SHA256_CTX *ctx); +void SHA256_Update(SHA256_CTX *ctx, const BYTE data[], size_t len); +void SHA256_Final(SHA256_CTX *ctx, BYTE hash[]); +void SHA256(const void *in, size_t len, uint8_t *result); +bool SHA256_Alloc(SHA256_CTX **ctx); +void SHA256_Free(SHA256_CTX *ctx); + +/** End of SHA256_API_Exported_Functions + * @} + */ + + +/** End of SHA256_API + * @} + */ + +#endif // SHA256_H + diff --git a/inc/platform/system_rtl876x.h b/inc/platform/system_rtl876x.h new file mode 100644 index 0000000..b8d2f3b --- /dev/null +++ b/inc/platform/system_rtl876x.h @@ -0,0 +1,246 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file System_rtl876x.h + * @brief CMSIS Device System Header file + * @details CMSIS Device System Header File for RTL876x Device Series + * @author + * @date 3. March 2016 + * @version v1.0 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2016 Realtek Semiconductor Corporation

    + * ************************************************************************************ + */ + +/*============================================================================* + * Define to prevent recursive inclusion + *============================================================================*/ +#ifndef SYSTEM_RTL876X_H +#define SYSTEM_RTL876X_H + + +/*============================================================================* + * Headers + *============================================================================*/ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup SYSTEM_RTL876X System RTL876X + * @brief CMSIS API sets for RTL876x Device Series + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SYSTEM_RTL876X_Exported_Types System RTL876X Exported Types + * @{ + */ +typedef void (*IRQ_Fun)(); /**< ISR Handler Prototype */ + +typedef enum +{ + LOG_TIMESTAMP_OS = 0, + LOG_TIMESTAMP_HW_TIMER = 1, + LOG_TIMESTAMP_RSVD = 2, + LOG_TIMESTAMP_MAX = 3 +} T_LOG_TIMESTAMP_TYPE; + +typedef enum +{ + LOG_BAUD_RATE_9600, + LOG_BAUD_RATE_19200, + LOG_BAUD_RATE_115200, + LOG_BAUD_RATE_230400, + LOG_BAUD_RATE_460800, + LOG_BAUD_RATE_921600, + LOG_BAUD_RATE_2000000, + LOG_BAUD_RATE_3000000, + LOG_BAUD_RATE_4000000, + LOG_BAUD_RATE_6000000 +} LOG_BAUD_RATE_TypeDef; + +typedef enum +{ + InitialSP_VECTORn = 0, + Reset_VECTORn, + NMI_VECTORn, + HardFault_VECTORn, + RSVD_MemMang_VECTORn, + RSVD_BusFault_VECTORn, + RSVD_UsageFault_VECTORn, + RSVD0_VECTORn, + RSVD1_VECTORn, + RSVD2_VECTORn, + RSVD3_VECTORn, + SVC_VECTORn, + DebugMonitor_VECTORn, + RSVD4_VECTORn, + PendSV_VECTORn, + SysTick_VECTORn, + System_VECTORn = 16, + WDG_VECTORn, + BTMAC_VECTORn, + Timer3_VECTORn, + Timer2_VECTORn, + Platform_VECTORn, + I2S0_TX_VECTORn, + I2S0_RX_VECTORn, + Timer4_5_VECTORn, + GPIO4_VECTORn, + GPIO5_VECTORn, + Uart1_VECTORn, + Uart0_VECTORn, + RTC_VECTORn, + SPI0_VECTORn, + SPI1_VECTORn, + I2C0_VECTORn, + I2C1_VECTORn, + ADC_VECTORn, + Peripheral_VECTORn, + GDMA0_Channel0_VECTORn, + GDMA0_Channel1_VECTORn, + GDMA0_Channel2_VECTORn, + GDMA0_Channel3_VECTORn, + Enhanced_Timer0_VECTORn, + Enhanced_Timer1_VECTORn, + GPIO_Group3_VECTORn, + GPIO_Group2_VECTORn, + IR_VECTORn, + GPIO_Group1_VECTORn, + GPIO_Group0_VECTORn, + RSVD5_VECTORn, + Timer4_VECTORn = 48, + Timer5_VECTORn, + SPIC0_VECTORn = 50, + Qdecode_VECTORn, + Keyscan_VECTORn, + SPI2W_VECTORn, + LPCOMP_VECTORn, + PTA_Mailbox_VECTORn, + CAP_Touch_VECTORn, + TRNG_VECTORn = 57, +} VECTORn_Type; + +typedef enum _SYSTEM_CALL_OPCODE +{ + SYSTEM_CALL_BASE = 0x0, + SYSTEM_CALL_WDG_RESET, + SYSTEM_CALL_AUTO_K_RF, + SYSTEM_CALL_PMU_FORCE_PWM_MODE, + SYSTEM_CALL_ENTER_POWERDOWN_DIRECTLY, +} T_SYSTEM_CALL_OPCODE; + +typedef bool (*APP_MAIN_FUNC)(); +typedef void (*USER_CALL_BACK)(); + +/** @} */ /* End of group SYSTEM_RTL876X_Exported_types */ + +/*============================================================================* + * Variables + *============================================================================*/ +/** @defgroup SYSTEM_RTL876X_Exported_Variables System RTL876X Exported Variables + * @brief + * @{ + */ +extern APP_MAIN_FUNC upperstack_entry; +extern APP_MAIN_FUNC app_pre_main; +extern APP_MAIN_FUNC app_main; +extern USER_CALL_BACK app_pre_main_cb; +/** @} */ /* End of group SYSTEM_RTL876X_Exported_Variables */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup SYSTEM_RTL876X_Exported_Functions System RTL876X Exported Functions + * @brief + * @{ + */ + +/** + * @brief Initialize RAM vector table to a given RAM address. + * @param ram_vector_addr: RAM Vector Address. + * @retval TRUE Success + * @retval FALSE Fail + * @note When using vector table relocation, the base address of the new vector + * table must be aligned to the size of the vector table extended to the + * next larger power of 2. In RTL8762C, the base address is aligned at 0x100. + */ +extern bool RamVectorTableInit(uint32_t ram_vector_addr); + +/** + * @brief Update ISR Handler in RAM Vector Table. + * @param v_num: Vector number(index) + * @param isr_handler: User defined ISR Handler. + * @retval TRUE Success + * @retval FALSE Fail + */ +extern bool RamVectorTableUpdate(VECTORn_Type v_num, IRQ_Fun isr_handler); + +/* + * @brief Call the system service. + * @param opcode: operation code. + * @param parm: parameter. + * @return none + */ +extern void SystemCall(uint32_t opcode, uint32_t parm); + +/* + * @brief update ram layout for app. + * @param app_global_size: app global ram size. + * @param data_heap_size: data on heap total size. + * @param share_cache_ram_size: the size of share cache to ram. + * @return none + */ +extern void update_ram_layout(uint32_t app_global_size, uint32_t data_heap_size, + uint32_t share_cache_ram_size); + + +/** + * @brief get cpu clock + * @param none + * @return uint32, for example 40000000 is 40M, 20000000 is 20M. + */ +extern uint32_t get_cpu_clock(void); + + +/** + * @brief get ic type + * @param none + * @return uint8_t, ic type: + * #define RTL8762ESF 0x1D + * #define RTL8762EGF 0x18 + * #define RTL8762ERF 0x28 + * #define RTL8762EJF 0x29 + * #define RTL8762EMF 0x39 + * #define RS625MF 0x49 + * #define RTL8762EKF 0x5A + * #define RTL8762EKO 0x6C + */ +extern uint8_t get_ic_type(void); + +/** + * @brief Deinit the IO function of one pin. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @retval None + */ +extern void Pinmux_Deinit_rom(uint8_t Pin_Num); + + +/** @} */ /* End of group SYSTEM_RTL876X_Exported_Functions */ + +/** @} */ /* End of group SYSTEM_RTL876X */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_RTL876X_H */ + diff --git a/inc/platform/test_mode.h b/inc/platform/test_mode.h new file mode 100644 index 0000000..6c7d571 --- /dev/null +++ b/inc/platform/test_mode.h @@ -0,0 +1,189 @@ +/** +**************************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +**************************************************************************************************** +* @file test_mode.h +* @brief test mode definition. +* @author Serval Li +* @date 2017-08-29 +* @version v1.0 +**************************************************************************************************** +*/ + +#ifndef _TEST_MODE_H_ +#define _TEST_MODE_H_ + +#include +#include +#include "rtl876x.h" +#include "rtl876x_wdg.h" +#include "patch_header_check.h" +#include "flash_device.h" +#include "trace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup TEST_MODE Test Mode + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup TEST_MODE_Exported_Macros Test Mode Exported Macros + * @brief + * @{ + */ +/* ascii value of "test" */ +#define TEST_MODE_FLAG_DEFAULT 0x74657374 +#define TEST_MODE_FLAG_DISABLE 0x50245150 + +/* General Purpose FW register */ +#define BTAON_FAST_TEST_MODE 0x16 +/** End of TEST_MODE_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup TEST_MODE_Exported_Types Test Mode Exported Types + * @brief + * @{ + */ + +/* 0x16 (BTAON_FAST_TEST_MODE) */ +typedef union +{ + uint16_t d16; + struct + { + uint8_t is_nanwang_dfu_mode : 1; /* bit[0]: customized for nanwang dfu mode */ + uint8_t rsvd : 4; /* bit[4:1]: reserved for ROM code */ + uint8_t test_mode : 3; /* bit[7:5]: test mode */ + uint8_t reset_reason : 8; /* bit[15:8]: reset reason */ + } s; +} T_BTAON_FAST_TEST_MODE_TYPE; + +typedef enum +{ + NOT_TEST_MODE = 0, + DIRECT_TEST_MODE = 1, + SINGLE_TONE_MODE = 2, + AUTO_PAIR_WITH_FIX_ADDR_MODE = 3, + DATA_UART_TEST_MODE = 4, + WRISTBAND_TEST_MODE = 5, + MOUSE_TEST_MODE = 6, + //add more +} T_TEST_MODE; +/** End of TEST_MODE_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup TEST_MODE_Exported_Functions Test Mode Exported Functions + * @brief + * @{ + */ +static inline bool dfu_check_nw_dfu_mode_flag(void) +{ + T_BTAON_FAST_TEST_MODE_TYPE nFastBoot; + nFastBoot.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + DFU_PRINT_INFO1("dfu_check_nw_dfu_mode_flag: ota(%d)", nFastBoot.s.is_nanwang_dfu_mode); + + return nFastBoot.s.is_nanwang_dfu_mode ? true : false; +} + +static inline void dfu_set_nw_dfu_mode_flag(bool enable) +{ + T_BTAON_FAST_TEST_MODE_TYPE nFastBoot; + nFastBoot.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + if (enable) + { + nFastBoot.s.is_nanwang_dfu_mode = 1; + } + else + { + nFastBoot.s.is_nanwang_dfu_mode = 0; + } + btaon_fast_write_safe(BTAON_FAST_TEST_MODE, nFastBoot.d16); + DFU_PRINT_INFO1("dfu_set_nw_dfu_mode_flag ota(%d)", nFastBoot.s.is_nanwang_dfu_mode); +} + +static inline T_TEST_MODE get_test_mode(void) +{ + T_BTAON_FAST_TEST_MODE_TYPE aon; + aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + return (T_TEST_MODE)(aon.s.test_mode); +} + +static inline void switch_to_test_mode(T_TEST_MODE test_mode) +{ + T_BTAON_FAST_TEST_MODE_TYPE aon; + aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + aon.s.test_mode = test_mode; + btaon_fast_write_safe(BTAON_FAST_TEST_MODE, aon.d16); + + WDG_SystemReset(RESET_ALL_EXCEPT_AON, SWITCH_TEST_MODE); +} + +static inline void reset_test_mode(void) +{ + T_BTAON_FAST_TEST_MODE_TYPE aon; + aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + aon.s.test_mode = NOT_TEST_MODE; + btaon_fast_write_safe(BTAON_FAST_TEST_MODE, aon.d16); +} + +static inline bool is_test_mode_enable(void) +{ + uint32_t start_addr = flash_get_bank_addr(FLASH_BKP_DATA1); + if (start_addr) + { + uint32_t r_data = 0; + flash_auto_read_locked(start_addr, &r_data); + return r_data == TEST_MODE_FLAG_DEFAULT; + } + return false; +} + +static inline bool test_mode_disable(void) +{ + bool retval = false; + uint32_t start_addr = flash_get_bank_addr(FLASH_BKP_DATA1); + if (start_addr) + { + retval = flash_auto_write_locked(start_addr, TEST_MODE_FLAG_DISABLE); + } + return retval; +} + +void set_hci_mode_flag(bool enable); + +bool check_hci_mode_flag(void); + +static inline void switch_to_hci_mode(void) +{ + set_hci_mode_flag(true); + WDG_SystemReset(RESET_ALL_EXCEPT_AON, SWITCH_HCI_MODE); +} + +#if (BUILD_DATATRANS == 1) +void set_datatrans_patch_flag(bool enable); + +bool check_datatrans_patch_flag(void); +#endif + +/** @} */ /* End of group TEST_MODE_Exported_Functions*/ + +/** @} */ /* End of group TEST_MODE*/ +#ifdef __cplusplus +} +#endif + +#endif /* _TEST_MODE_H_ */ + diff --git a/inc/platform/trace.h b/inc/platform/trace.h new file mode 100644 index 0000000..d764ca8 --- /dev/null +++ b/inc/platform/trace.h @@ -0,0 +1,2015 @@ +/** + * Copyright (c) 2017, Realtek Semiconductor Corporation. All rights reserved. + */ + +#ifndef _TRACE_H_ +#define _TRACE_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \defgroup TRACE Trace + * + * \brief Defines debug trace macros for each module. + * + */ + + +/* Log Section Definition */ +#define TRACE_DATA __attribute__((section(".TRACE"))) __attribute__((aligned(4))) __attribute__((used)) + +/** + * trace.h + * + * \name TRACE_LEVEL + * \brief Log Level Definition. + * \anchor TRACE_LEVEL + */ +/** + * \ingroup TRACE + */ +/**@{*/ +#define LEVEL_ERROR 0 +#define LEVEL_WARN 1 +#define LEVEL_INFO 2 +#define LEVEL_TRACE 3 +#define LEVEL_NUM 4 +/**@}*/ + +/* + * DBG_LEVEL is used to control the log printed by DBG_BUFFER(). + * -1 : Print None + * LEVEL_ERROR : Print ERROR + * LEVEL_WARN : Print ERROR, WARN + * LEVEL_INFO : Print ERROR, WARN, INFO + * LEVEL_TRACE : Print ERROR, WARN, INFO, TRACE + */ +#define DBG_LEVEL LEVEL_TRACE + +/* Log type definition */ +typedef enum +{ + TYPE_UPPERSTACK_RESET = 0, /* Bee1(deprecated) */ + TYPE_UPPERSTACK_FORMAT = 1, /* Bee1 */ + TYPE_UPPERSTACK_MESSAGE = 2, /* Bee1 */ + TYPE_UPPERSTACK_BINARY = 3, /* Bee1 */ + TYPE_UPPERSTACK_STRING = 4, /* Bee1 */ + TYPE_UPPERSTACK_BDADDR1 = 5, /* Bee1 */ + TYPE_UPPERSTACK_BDADDR2 = 6, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA1 = 7, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA2 = 8, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA3 = 9, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA4 = 10, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA5 = 11, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA6 = 12, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA7 = 13, /* Bee1 */ + TYPE_UPPERSTACK_RAMDATA8 = 14, /* Bee1 */ + + TYPE_PLATFORM_DBG_DIRECT = 16, /* Bee1 */ + + /* type 32~127 reserved for project id, e.g. bumblebee3, bee2 */ + TYPE_BUMBLEBEE3 = 32, + TYPE_BEE2 = 33, + TYPE_BEE3 = 35, + + /* type 128~207 reserved for 3rd party definition */ + + /* type 220~251 reserved for Bee1 platform debug buffer */ +} T_LOG_TYPE; + + +/* Log subtype definition */ +typedef enum +{ + SUBTYPE_DIRECT = 0x00, + + SUBTYPE_FORMAT = 0x10, + SUBTYPE_DOWN_MESSAGE = 0x11, + SUBTYPE_UP_MESSAGE = 0x12, + + SUBTYPE_DOWN_SNOOP = 0x20, + SUBTYPE_UP_SNOOP = 0x28, + + SUBTYPE_BDADDR = 0x30, + + SUBTYPE_STRING = 0x40, + + SUBTYPE_BINARY = 0x50, + + SUBTYPE_INDEX = 0x60, +} T_LOG_SUBTYPE; + +/** + * trace.h + * + * \name MODULE_ID + * \brief Module ID definition. + * \anchor MODULE_ID + */ +/** + * \ingroup TRACE + */ +/**@{*/ +typedef enum +{ + /* platform modules */ + MODULE_PATCH = 0, + MODULE_OS = 1, + MODULE_OSIF = 2, + MODULE_BOOT = 3, + MODULE_PM = 4, + MODULE_AES = 5, + MODULE_FS = 6, + + /* device modules */ + MODULE_KEYSCAN = 12, + MODULE_QDECODE = 13, + MODULE_IR = 14, + MODULE_3DG = 15, + MODULE_ADC = 16, + MODULE_GDMA = 17, + MODULE_I2C = 18, + MODULE_RTC = 19, + MODULE_SPI = 20, + MODULE_TIMER = 21, + MODULE_UART = 22, + MODULE_FLASH = 23, + MODULE_GPIO = 24, + MODULE_PINMUX = 25, + MODULE_PWM = 26, + MODULE_USB = 27, + MODULE_SDIO = 28, + MODULE_CHARGER = 29, + MODULE_DSP = 30, + MODULE_EFUSE = 31, + MODULE_CTC = 32, + + /* stack modules */ + MODULE_APP = 48, + MODULE_DFU = 49, + MODULE_RFCOMM = 50, + MODULE_PROFILE = 51, + MODULE_PROTOCOL = 52, + MODULE_GAP = 53, + MODULE_BTE = 54, + MODULE_BTIF = 55, + MODULE_GATT = 56, + MODULE_SMP = 57, + MODULE_SDP = 58, + MODULE_L2CAP = 59, + MODULE_HCI = 60, + MODULE_SNOOP = 61, + MODULE_UPPERSTACK = 62, + MODULE_LOWERSTACK = 63, + + MODULE_NUM = 64 +} T_MODULE_ID; +/**@}*/ + +/** + * trace.h + * + * \name MODULE_BITMAP + * \brief Module bitmap definition. + * \anchor MODULE_BITMAP + */ +/** + * \ingroup TRACE + */ +/**@{*/ +#define MODULE_BIT_PATCH ((uint64_t)1 << MODULE_PATCH ) +#define MODULE_BIT_OS ((uint64_t)1 << MODULE_OS ) +#define MODULE_BIT_OSIF ((uint64_t)1 << MODULE_OSIF ) +#define MODULE_BIT_BOOT ((uint64_t)1 << MODULE_BOOT ) +#define MODULE_BIT_PM ((uint64_t)1 << MODULE_PM ) +#define MODULE_BIT_AES ((uint64_t)1 << MODULE_AES ) +#define MODULE_BIT_FS ((uint64_t)1 << MODULE_FS ) + +#define MODULE_BIT_KEYSCAN ((uint64_t)1 << MODULE_KEYSCAN ) +#define MODULE_BIT_QDECODE ((uint64_t)1 << MODULE_QDECODE ) +#define MODULE_BIT_IR ((uint64_t)1 << MODULE_IR ) +#define MODULE_BIT_3DG ((uint64_t)1 << MODULE_3DG ) +#define MODULE_BIT_ADC ((uint64_t)1 << MODULE_ADC ) +#define MODULE_BIT_GDMA ((uint64_t)1 << MODULE_GDMA ) +#define MODULE_BIT_I2C ((uint64_t)1 << MODULE_I2C ) +#define MODULE_BIT_RTC ((uint64_t)1 << MODULE_RTC ) +#define MODULE_BIT_SPI ((uint64_t)1 << MODULE_SPI ) +#define MODULE_BIT_TIMER ((uint64_t)1 << MODULE_TIMER ) +#define MODULE_BIT_UART ((uint64_t)1 << MODULE_UART ) +#define MODULE_BIT_FLASH ((uint64_t)1 << MODULE_FLASH ) +#define MODULE_BIT_GPIO ((uint64_t)1 << MODULE_GPIO ) +#define MODULE_BIT_PINMUX ((uint64_t)1 << MODULE_PINMUX ) +#define MODULE_BIT_PWM ((uint64_t)1 << MODULE_PWM ) +#define MODULE_BIT_USB ((uint64_t)1 << MODULE_USB ) +#define MODULE_BIT_SDIO ((uint64_t)1 << MODULE_SDIO ) +#define MODULE_BIT_CHARGER ((uint64_t)1 << MODULE_CHARGER ) +#define MODULE_BIT_DSP ((uint64_t)1 << MODULE_DSP ) +#define MODULE_BIT_EFUSE ((uint64_t)1 << MODULE_EFUSE ) +#define MODULE_BIT_CTC ((uint64_t)1 << MODULE_CTC ) + +#define MODULE_BIT_APP ((uint64_t)1 << MODULE_APP ) +#define MODULE_BIT_DFU ((uint64_t)1 << MODULE_DFU ) +#define MODULE_BIT_RFCOMM ((uint64_t)1 << MODULE_RFCOMM ) +#define MODULE_BIT_PROFILE ((uint64_t)1 << MODULE_PROFILE ) +#define MODULE_BIT_PROTOCOL ((uint64_t)1 << MODULE_PROTOCOL ) +#define MODULE_BIT_GAP ((uint64_t)1 << MODULE_GAP ) +#define MODULE_BIT_BTIF ((uint64_t)1 << MODULE_BTIF ) +#define MODULE_BIT_GATT ((uint64_t)1 << MODULE_GATT ) +#define MODULE_BIT_SMP ((uint64_t)1 << MODULE_SMP ) +#define MODULE_BIT_SDP ((uint64_t)1 << MODULE_SDP ) +#define MODULE_BIT_L2CAP ((uint64_t)1 << MODULE_L2CAP ) +#define MODULE_BIT_HCI ((uint64_t)1 << MODULE_HCI ) +#define MODULE_BIT_SNOOP ((uint64_t)1 << MODULE_SNOOP ) +#define MODULE_BIT_LOWERSTACK ((uint64_t)1 << MODULE_LOWERSTACK) +#define MODULE_BIT_UPPERSTACK ((uint64_t)1 << MODULE_UPPERSTACK) +/**@}*/ + +/* Internal function that is used by internal macro DBG_DIRECT. */ +extern void log_direct(uint32_t info, const char *fmt, ...); +extern void log_direct_app(uint32_t info, const char *fmt, ...); + +#if (ENABLE_FULL_FEATURED_DIRECT_LOG == 1) +#define log_direct_retarget log_direct_app +#else +#define log_direct_retarget log_direct +#endif + +/* Internal function that is used by internal macro DBG_LOWERSTACK. */ +void LogBufferLowerStack(uint32_t control, uint16_t log_str_index, uint8_t param_num, ...); + +/* Internal function that is used by internal macro DBG_LOWERSTACKDATA. */ +void LogBufferLowerStackData(uint32_t control, uint16_t log_str_index, uint16_t length, + uint8_t *p_str); + +/* Internal function that is used by internal macro DBG_BUFFER. */ +void log_buffer(uint32_t info, uint32_t log_str_index, uint8_t param_num, ...); + +/* Internal function that is used by internal macro DBG_INDEX. */ +void log_index(uint32_t info, uint32_t log_str_index, uint8_t param_num, ...); + +/* Internal function that is used by internal macro DBG_SNOOP. */ +void log_snoop(uint32_t info, uint16_t length, uint8_t *p_snoop); + +/* Internal function that is used by public macro TRACE_BDADDR. */ +const char *trace_bdaddr(uint32_t info, char *bd_addr); + +/* Internal function that is used by public macro TRACE_STRING. */ +const char *trace_string(uint32_t info, char *p_data); + +/* Internal function that is used by public macro TRACE_BINARY. */ +const char *trace_binary(uint32_t info, uint16_t length, uint8_t *p_data); + +#define COMBINE_TRACE_INFO(type, subtype, module, level) (uint32_t)(((type)<<24) | ((subtype)<<16) | ((module)<<8) | (level)) + +/* Internal macro that is wrapped by internal macro DBG_BUFFER. */ +#define DBG_BUFFER_INTERNAL(type, sub_type, module, level, fmt, param_num, ...) do {\ + static const char format[] TRACE_DATA = fmt;\ + log_buffer(COMBINE_TRACE_INFO(type, sub_type, module, level), (uint32_t)format, param_num, ##__VA_ARGS__);\ + } while (0) + +#if (DBG_LEVEL >= LEVEL_ERROR) +#define DBG_BUFFER_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) do {\ + DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_ERROR, fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#define DBG_INDEX_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) do {\ + log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_ERROR), fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#else +#define DBG_BUFFER_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) +#define DBG_INDEX_LEVEL_ERROR(type, sub_type, module, fmt, param_num, ...) +#endif + +#if (DBG_LEVEL >= LEVEL_WARN) +#define DBG_BUFFER_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) do {\ + DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_WARN, fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#define DBG_INDEX_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) do {\ + log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_WARN), fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#else +#define DBG_BUFFER_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) +#define DBG_INDEX_LEVEL_WARN(type, sub_type, module, fmt, param_num, ...) +#endif + +#if (DBG_LEVEL >= LEVEL_INFO) +#define DBG_BUFFER_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) do {\ + DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_INFO, fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#define DBG_INDEX_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) do {\ + log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_INFO), fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#else +#define DBG_BUFFER_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) +#define DBG_INDEX_LEVEL_INFO(type, sub_type, module, fmt, param_num, ...) +#endif + +#if (DBG_LEVEL >= LEVEL_TRACE) +#define DBG_BUFFER_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) do {\ + DBG_BUFFER_INTERNAL(type, sub_type, module, LEVEL_TRACE, fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#define DBG_INDEX_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) do {\ + log_index(COMBINE_TRACE_INFO(type, sub_type, module, LEVEL_TRACE), fmt, param_num, ##__VA_ARGS__);\ + } while (0) +#else +#define DBG_BUFFER_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) +#define DBG_INDEX_LEVEL_TRACE(type, sub_type, module, fmt, param_num, ...) +#endif + +#define DBG_BUFFER(type, sub_type, module, level, fmt, param_num,...) \ + DBG_BUFFER_##level(type, sub_type, module, fmt, param_num, ##__VA_ARGS__) + +#define DBG_INDEX(type, sub_type, module, level, fmt, param_num,...) \ + DBG_INDEX_##level(type, sub_type, module, fmt, param_num, ##__VA_ARGS__) + +#define DBG_DIRECT(...) do {\ + log_direct_retarget(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_DIRECT, 0, 0), __VA_ARGS__);\ + } while (0) + +#define DBG_LOWERSTACK(color, file_num, line_num, log_str_index, param_num, ...) do {\ + LogBufferLowerStack(((file_num)<<16)|(line_num), (uint16_t)(log_str_index), param_num, ##__VA_ARGS__);\ + } while (0) + +#define DBG_LOWERSTACKDATA(color, file_num, line_num, log_str_index, length, str) do {\ + LogBufferLowerStackData(((color)<<24)|((file_num)<<16)|(line_num), (uint16_t)(log_str_index), length, str);\ + } while (0) + +#define DBG_SNOOP(type, sub_type, module, level, length, snoop) do {\ + log_snoop(COMBINE_TRACE_INFO(type, sub_type, module, level), length, snoop);\ + } while (0) + + +extern bool is_log_init; + +/** + * trace.h + * + * \brief Initialize module trace mask. + * + * \param[in] mask Module trace mask array. Set NULL to load default mask array. + * + * \return None. + * + * \ingroup TRACE + */ +void log_module_trace_init(uint64_t mask[LEVEL_NUM]); + +/** + * trace.h + * + * \brief Enable/Disable the module ID's trace. + * + * \param[in] module_id The specific module ID defined in \ref MODULE_ID. + * + * \param[in] trace_level The trace level of the module ID defined in \ref TRACE_LEVEL. + * + * \param[in] set Enable or disable the module ID's trace. + * \arg \c true Enable the module ID's trace. + * \arg \c false Disable the module ID's trace. + * + * \return The status of setting module ID's trace. + * \retval true Module ID's trace was set successfully. + * \retval false Module ID's trace was failed to set. + * + * \ingroup TRACE + */ +bool log_module_trace_set(T_MODULE_ID module_id, uint8_t trace_level, bool set); + +/** + * trace.h + * + * \brief Enable/Disable module bitmap's trace. + * + * \param[in] module_bitmap The module bitmap defined in \ref MODULE_BITMAP. + * + * \param[in] trace_level The trace level of the module bitmap defined in \ref TRACE_LEVEL. + * + * \param[in] set Enable or disable the module bitmap's trace. + * \arg \c true Enable the module bitmap's trace. + * \arg \c false Disable the module bitmap's trace. + * + * \return The status of setting module bitmap's trace. + * \retval true Module bitmap's trace was set successfully. + * \retval false Module bitmap's trace was failed to set. + * + * \ingroup TRACE + */ +bool log_module_bitmap_trace_set(uint64_t module_bitmap, uint8_t trace_level, bool set); + +/** + * trace.h + * + * \name AUXILIARY_PRINT_BDADDR + * \brief Auxiliary Interface that is used to print BD address. + * \anchor AUXILIARY_PRINT_BDADDR + */ +/** + * \ingroup TRACE + */ +#define TRACE_BDADDR(bd_addr) \ + trace_bdaddr(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_BDADDR, 0, 0), (char *)(bd_addr)) + +/** + * trace.h + * + * \name AUXILIARY_PRINT_STRING + * \brief Auxiliary Interface that is used to print string. + * \anchor AUXILIARY_PRINT_STRING + */ +/** + * \ingroup TRACE + */ +#define TRACE_STRING(data) \ + trace_string(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_STRING, 0, 0), (char *)(data)) + +/** + * trace.h + * + * \name AUXILIARY_PRINT_BINARY + * \brief Auxiliary Interface that is used to print binary string. + * \anchor AUXILIARY_PRINT_BINARY + */ +/** + * \ingroup TRACE + */ +/**@{*/ +#define TRACE_BINARY(length, data) \ + trace_binary(COMBINE_TRACE_INFO(TYPE_BEE3, SUBTYPE_BINARY, 0, 0), length, (uint8_t *)(data)) +/**@}*/ + + +/* Bluetooth HCI Snoop Trace Interfaces */ +#define BT_SNOOP_DOWN_TRACE(length, snoop) \ + DBG_SNOOP(TYPE_BEE3, SUBTYPE_DOWN_SNOOP, MODULE_SNOOP, LEVEL_ERROR, length, snoop); +#define BT_SNOOP_UP_TRACE(length, snoop) \ + DBG_SNOOP(TYPE_BEE3, SUBTYPE_UP_SNOOP, MODULE_SNOOP, LEVEL_ERROR, length, snoop); + + +/* Bluetooth Message Trace Interfaces */ +#define BT_MESSAGE_DOWN_PRINT_ERROR(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_ERROR, "", 2, length, message) +#define BT_MESSAGE_DOWN_PRINT_WARN(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_WARN, "", 2, length, message) +#define BT_MESSAGE_DOWN_PRINT_INFO(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_INFO, "", 2, length, message) +#define BT_MESSAGE_DOWN_PRINT_TRACE(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_DOWN_MESSAGE, MODULE_UPPERSTACK, LEVEL_TRACE, "", 2, length, message) +#define BT_MESSAGE_UP_PRINT_ERROR(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_ERROR, "", 2, length, message) +#define BT_MESSAGE_UP_PRINT_WARN(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_WARN, "", 2, length, message) +#define BT_MESSAGE_UP_PRINT_INFO(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_INFO, "", 2, length, message) +#define BT_MESSAGE_UP_PRINT_TRACE(length, message) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_UP_MESSAGE, MODULE_UPPERSTACK, LEVEL_TRACE, "", 2, length, message) + + +/* Patch Trace Interfaces */ +#define PATCH_PRINT_ERROR0(fmt) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 0) +#define PATCH_PRINT_ERROR1(fmt, arg0) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 1, arg0) +#define PATCH_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 2, arg0, arg1) +#define PATCH_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 3, arg0, arg1, arg2) +#define PATCH_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 4, arg0, arg1, arg2, arg3) +#define PATCH_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PATCH_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PATCH_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PATCH_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_ERROR, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PATCH_PRINT_WARN0(fmt) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 0) +#define PATCH_PRINT_WARN1(fmt, arg0) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 1, arg0) +#define PATCH_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 2, arg0, arg1) +#define PATCH_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 3, arg0, arg1, arg2) +#define PATCH_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 4, arg0, arg1, arg2, arg3) +#define PATCH_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PATCH_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PATCH_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PATCH_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_WARN, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PATCH_PRINT_INFO0(fmt) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 0) +#define PATCH_PRINT_INFO1(fmt, arg0) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 1, arg0) +#define PATCH_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 2, arg0, arg1) +#define PATCH_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 3, arg0, arg1, arg2) +#define PATCH_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 4, arg0, arg1, arg2, arg3) +#define PATCH_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PATCH_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PATCH_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PATCH_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_INFO, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PATCH_PRINT_TRACE0(fmt) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 0) +#define PATCH_PRINT_TRACE1(fmt, arg0) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 1, arg0) +#define PATCH_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define PATCH_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define PATCH_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define PATCH_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PATCH_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PATCH_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PATCH_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_INDEX(TYPE_BEE3, SUBTYPE_INDEX, MODULE_PATCH, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth Lower Stack Trace Interfaces */ +#define LOWERSTACK_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 0) +#define LOWERSTACK_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define LOWERSTACK_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define LOWERSTACK_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define LOWERSTACK_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define LOWERSTACK_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define LOWERSTACK_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define LOWERSTACK_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define LOWERSTACK_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define LOWERSTACK_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 0) +#define LOWERSTACK_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define LOWERSTACK_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define LOWERSTACK_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define LOWERSTACK_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define LOWERSTACK_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define LOWERSTACK_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define LOWERSTACK_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define LOWERSTACK_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define LOWERSTACK_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 0) +#define LOWERSTACK_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 1, arg0) +#define LOWERSTACK_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define LOWERSTACK_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define LOWERSTACK_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define LOWERSTACK_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define LOWERSTACK_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define LOWERSTACK_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define LOWERSTACK_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define LOWERSTACK_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 0) +#define LOWERSTACK_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 1, arg0) +#define LOWERSTACK_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define LOWERSTACK_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define LOWERSTACK_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define LOWERSTACK_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define LOWERSTACK_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define LOWERSTACK_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define LOWERSTACK_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_LOWERSTACK, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* OS Trace Interfaces */ +#define OS_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 0) +#define OS_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define OS_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define OS_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define OS_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define OS_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OS_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OS_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OS_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OS_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 0) +#define OS_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define OS_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define OS_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define OS_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define OS_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OS_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OS_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OS_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OS_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 0) +#define OS_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 1, arg0) +#define OS_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define OS_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define OS_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define OS_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OS_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OS_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OS_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OS_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 0) +#define OS_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 1, arg0) +#define OS_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define OS_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define OS_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define OS_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OS_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OS_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OS_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OS, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* OSIF Trace Interfaces */ +#define OSIF_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 0) +#define OSIF_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define OSIF_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define OSIF_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define OSIF_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define OSIF_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OSIF_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OSIF_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OSIF_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OSIF_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 0) +#define OSIF_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define OSIF_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define OSIF_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define OSIF_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define OSIF_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OSIF_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OSIF_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OSIF_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OSIF_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 0) +#define OSIF_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 1, arg0) +#define OSIF_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define OSIF_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define OSIF_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define OSIF_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OSIF_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OSIF_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OSIF_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define OSIF_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 0) +#define OSIF_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 1, arg0) +#define OSIF_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define OSIF_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define OSIF_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define OSIF_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define OSIF_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define OSIF_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define OSIF_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_OSIF, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + +/* CTC Trace Interfaces */ +#define CTC_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 0) +#define CTC_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define CTC_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define CTC_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define CTC_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define CTC_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define CTC_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define CTC_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define CTC_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define CTC_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 0) +#define CTC_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define CTC_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define CTC_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define CTC_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define CTC_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define CTC_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define CTC_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define CTC_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define CTC_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 0) +#define CTC_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 1, arg0) +#define CTC_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define CTC_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define CTC_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define CTC_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define CTC_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define CTC_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define CTC_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define CTC_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 0) +#define CTC_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 1, arg0) +#define CTC_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define CTC_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define CTC_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define CTC_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define CTC_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define CTC_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define CTC_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_CTC, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + +/* Bluetooth HCI Trace Interfaces */ +#define HCI_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 0) +#define HCI_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define HCI_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define HCI_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define HCI_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define HCI_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define HCI_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define HCI_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define HCI_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define HCI_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 0) +#define HCI_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define HCI_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define HCI_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define HCI_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define HCI_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define HCI_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define HCI_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define HCI_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define HCI_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 0) +#define HCI_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 1, arg0) +#define HCI_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define HCI_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define HCI_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define HCI_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define HCI_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define HCI_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define HCI_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define HCI_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 0) +#define HCI_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 1, arg0) +#define HCI_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define HCI_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define HCI_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define HCI_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define HCI_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define HCI_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define HCI_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_HCI, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth L2CAP Trace Interfaces */ +#define L2CAP_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 0) +#define L2CAP_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define L2CAP_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define L2CAP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define L2CAP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define L2CAP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define L2CAP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define L2CAP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define L2CAP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define L2CAP_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 0) +#define L2CAP_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define L2CAP_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define L2CAP_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define L2CAP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define L2CAP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define L2CAP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define L2CAP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define L2CAP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define L2CAP_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 0) +#define L2CAP_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 1, arg0) +#define L2CAP_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define L2CAP_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define L2CAP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define L2CAP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define L2CAP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define L2CAP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define L2CAP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define L2CAP_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 0) +#define L2CAP_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 1, arg0) +#define L2CAP_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define L2CAP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define L2CAP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define L2CAP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define L2CAP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define L2CAP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define L2CAP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_L2CAP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth SDP Trace Interfaces */ +#define SDP_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 0) +#define SDP_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define SDP_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define SDP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define SDP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define SDP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SDP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SDP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SDP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SDP_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 0) +#define SDP_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define SDP_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define SDP_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define SDP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define SDP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SDP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SDP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SDP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SDP_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 0) +#define SDP_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 1, arg0) +#define SDP_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define SDP_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define SDP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define SDP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SDP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SDP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SDP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SDP_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 0) +#define SDP_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 1, arg0) +#define SDP_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define SDP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define SDP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define SDP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SDP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SDP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SDP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SDP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth SMP Trace Interfaces */ +#define SMP_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 0) +#define SMP_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define SMP_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define SMP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define SMP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define SMP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SMP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SMP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SMP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SMP_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 0) +#define SMP_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define SMP_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define SMP_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define SMP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define SMP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SMP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SMP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SMP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SMP_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 0) +#define SMP_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 1, arg0) +#define SMP_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define SMP_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define SMP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define SMP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SMP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SMP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SMP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define SMP_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 0) +#define SMP_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 1, arg0) +#define SMP_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define SMP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define SMP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define SMP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define SMP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define SMP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define SMP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_SMP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth GATT Trace Interfaces */ +#define GATT_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 0) +#define GATT_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define GATT_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define GATT_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define GATT_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define GATT_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GATT_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GATT_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GATT_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GATT_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 0) +#define GATT_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define GATT_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define GATT_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define GATT_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define GATT_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GATT_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GATT_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GATT_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GATT_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 0) +#define GATT_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 1, arg0) +#define GATT_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define GATT_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define GATT_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define GATT_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GATT_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GATT_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GATT_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GATT_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 0) +#define GATT_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 1, arg0) +#define GATT_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define GATT_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define GATT_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define GATT_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GATT_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GATT_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GATT_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GATT, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth BTIF Trace Interfaces */ +#define BTIF_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 0) +#define BTIF_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define BTIF_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define BTIF_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define BTIF_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define BTIF_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTIF_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTIF_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTIF_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTIF_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 0) +#define BTIF_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define BTIF_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define BTIF_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define BTIF_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define BTIF_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTIF_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTIF_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTIF_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTIF_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 0) +#define BTIF_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 1, arg0) +#define BTIF_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define BTIF_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define BTIF_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define BTIF_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTIF_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTIF_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTIF_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTIF_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 0) +#define BTIF_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 1, arg0) +#define BTIF_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define BTIF_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define BTIF_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define BTIF_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTIF_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTIF_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTIF_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTIF, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth BTE Trace Interfaces */ +#define BTE_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 0) +#define BTE_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define BTE_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define BTE_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define BTE_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define BTE_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTE_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTE_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTE_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTE_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 0) +#define BTE_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define BTE_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define BTE_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define BTE_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define BTE_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTE_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTE_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTE_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTE_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 0) +#define BTE_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 1, arg0) +#define BTE_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define BTE_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define BTE_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define BTE_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTE_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTE_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTE_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define BTE_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 0) +#define BTE_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 1, arg0) +#define BTE_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define BTE_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define BTE_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define BTE_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define BTE_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define BTE_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define BTE_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BTE, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth GAP Trace Interfaces */ +#define GAP_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 0) +#define GAP_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define GAP_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define GAP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define GAP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define GAP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GAP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GAP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GAP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GAP_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 0) +#define GAP_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define GAP_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define GAP_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define GAP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define GAP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GAP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GAP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GAP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GAP_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 0) +#define GAP_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 1, arg0) +#define GAP_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define GAP_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define GAP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define GAP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GAP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GAP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GAP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define GAP_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 0) +#define GAP_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 1, arg0) +#define GAP_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define GAP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define GAP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define GAP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define GAP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define GAP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define GAP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_GAP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth RFCOMM Trace Interfaces */ +#define RFCOMM_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 0) +#define RFCOMM_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define RFCOMM_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define RFCOMM_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define RFCOMM_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define RFCOMM_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define RFCOMM_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define RFCOMM_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define RFCOMM_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define RFCOMM_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 0) +#define RFCOMM_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define RFCOMM_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define RFCOMM_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define RFCOMM_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define RFCOMM_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define RFCOMM_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define RFCOMM_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define RFCOMM_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define RFCOMM_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 0) +#define RFCOMM_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 1, arg0) +#define RFCOMM_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define RFCOMM_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define RFCOMM_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define RFCOMM_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define RFCOMM_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define RFCOMM_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define RFCOMM_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define RFCOMM_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 0) +#define RFCOMM_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 1, arg0) +#define RFCOMM_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define RFCOMM_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define RFCOMM_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define RFCOMM_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define RFCOMM_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define RFCOMM_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define RFCOMM_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_RFCOMM, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth Protocol Trace Interfaces */ +#define PROTOCOL_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 0) +#define PROTOCOL_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define PROTOCOL_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define PROTOCOL_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define PROTOCOL_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define PROTOCOL_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROTOCOL_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROTOCOL_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROTOCOL_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROTOCOL_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 0) +#define PROTOCOL_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define PROTOCOL_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define PROTOCOL_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define PROTOCOL_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define PROTOCOL_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROTOCOL_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROTOCOL_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROTOCOL_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROTOCOL_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 0) +#define PROTOCOL_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 1, arg0) +#define PROTOCOL_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define PROTOCOL_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define PROTOCOL_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define PROTOCOL_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROTOCOL_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROTOCOL_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROTOCOL_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROTOCOL_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 0) +#define PROTOCOL_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 1, arg0) +#define PROTOCOL_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define PROTOCOL_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define PROTOCOL_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define PROTOCOL_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROTOCOL_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROTOCOL_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROTOCOL_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROTOCOL, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth Profile Trace Interfaces */ +#define PROFILE_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 0) +#define PROFILE_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define PROFILE_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define PROFILE_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define PROFILE_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define PROFILE_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROFILE_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROFILE_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROFILE_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROFILE_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 0) +#define PROFILE_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define PROFILE_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define PROFILE_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define PROFILE_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define PROFILE_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROFILE_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROFILE_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROFILE_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROFILE_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 0) +#define PROFILE_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 1, arg0) +#define PROFILE_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define PROFILE_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define PROFILE_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define PROFILE_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROFILE_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROFILE_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROFILE_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define PROFILE_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 0) +#define PROFILE_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 1, arg0) +#define PROFILE_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define PROFILE_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define PROFILE_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define PROFILE_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PROFILE_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define PROFILE_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define PROFILE_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PROFILE, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/** + * trace.h + * + * \name APP_PRINT_TRACE + * \brief Bluetooth APP Trace Interfaces. + * \anchor APP_PRINT_TRACE + */ +/** + * \ingroup TRACE + */ +/**@{*/ +#define APP_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 0) +#define APP_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define APP_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define APP_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define APP_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define APP_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define APP_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define APP_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define APP_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define APP_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 0) +#define APP_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define APP_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define APP_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define APP_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define APP_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define APP_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define APP_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define APP_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define APP_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 0) +#define APP_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 1, arg0) +#define APP_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define APP_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define APP_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define APP_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define APP_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define APP_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define APP_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define APP_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 0) +#define APP_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 1, arg0) +#define APP_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define APP_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define APP_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define APP_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define APP_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define APP_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define APP_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +/**@}*/ + + +/* AES Trace Interfaces */ +#define AES_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 0) +#define AES_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define AES_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define AES_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define AES_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define AES_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 0) +#define AES_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define AES_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define AES_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define AES_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define AES_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 0) +#define AES_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 1, arg0) +#define AES_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define AES_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define AES_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_AES, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) + +/* Power Manager Trace Interfaces */ +#define PM_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 0) +#define PM_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define PM_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define PM_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define PM_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define PM_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 0) +#define PM_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define PM_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define PM_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define PM_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define PM_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 0) +#define PM_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 1, arg0) +#define PM_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define PM_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define PM_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define PM_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define PM_PRINT_INFO9(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 9, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) +#define PM_PRINT_INFO10(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 10, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) +#define PM_PRINT_INFO13(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_PM, LEVEL_INFO, "!**"fmt, 13, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) + +/* Boot Trace Interfaces */ +#define BOOT_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 0) +#define BOOT_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define BOOT_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define BOOT_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define BOOT_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define BOOT_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 0) +#define BOOT_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define BOOT_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define BOOT_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define BOOT_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define BOOT_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 0) +#define BOOT_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 1, arg0) +#define BOOT_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define BOOT_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define BOOT_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_BOOT, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) + + +/* Bluetooth OTA/DFU Trace Interfaces */ +#define DFU_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 0) +#define DFU_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define DFU_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define DFU_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define DFU_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define DFU_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define DFU_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define DFU_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define DFU_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define DFU_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 0) +#define DFU_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define DFU_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define DFU_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define DFU_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define DFU_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define DFU_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define DFU_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define DFU_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define DFU_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 0) +#define DFU_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 1, arg0) +#define DFU_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define DFU_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define DFU_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define DFU_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define DFU_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define DFU_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define DFU_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define DFU_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 0) +#define DFU_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 1, arg0) +#define DFU_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define DFU_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define DFU_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define DFU_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define DFU_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define DFU_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define DFU_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_DFU, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + +/* Bluetooth FLASH/CACHE Trace Interfaces */ +#define FLASH_PRINT_ERROR0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 0) +#define FLASH_PRINT_ERROR1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 1, arg0) +#define FLASH_PRINT_ERROR2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 2, arg0, arg1) +#define FLASH_PRINT_ERROR3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 3, arg0, arg1, arg2) +#define FLASH_PRINT_ERROR4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 4, arg0, arg1, arg2, arg3) +#define FLASH_PRINT_ERROR5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define FLASH_PRINT_ERROR6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define FLASH_PRINT_ERROR7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define FLASH_PRINT_ERROR8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_ERROR, "!!!"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define FLASH_PRINT_WARN0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 0) +#define FLASH_PRINT_WARN1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 1, arg0) +#define FLASH_PRINT_WARN2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 2, arg0, arg1) +#define FLASH_PRINT_WARN3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 3, arg0, arg1, arg2) +#define FLASH_PRINT_WARN4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 4, arg0, arg1, arg2, arg3) +#define FLASH_PRINT_WARN5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define FLASH_PRINT_WARN6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define FLASH_PRINT_WARN7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define FLASH_PRINT_WARN8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_WARN, "!!*"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define FLASH_PRINT_INFO0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 0) +#define FLASH_PRINT_INFO1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 1, arg0) +#define FLASH_PRINT_INFO2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 2, arg0, arg1) +#define FLASH_PRINT_INFO3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 3, arg0, arg1, arg2) +#define FLASH_PRINT_INFO4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 4, arg0, arg1, arg2, arg3) +#define FLASH_PRINT_INFO5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define FLASH_PRINT_INFO6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define FLASH_PRINT_INFO7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define FLASH_PRINT_INFO8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_INFO, "!**"fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) +#define FLASH_PRINT_TRACE0(fmt) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 0) +#define FLASH_PRINT_TRACE1(fmt, arg0) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 1, arg0) +#define FLASH_PRINT_TRACE2(fmt, arg0, arg1) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 2, arg0, arg1) +#define FLASH_PRINT_TRACE3(fmt, arg0, arg1, arg2) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 3, arg0, arg1, arg2) +#define FLASH_PRINT_TRACE4(fmt, arg0, arg1, arg2, arg3) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 4, arg0, arg1, arg2, arg3) +#define FLASH_PRINT_TRACE5(fmt, arg0, arg1, arg2, arg3, arg4) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 5, arg0, arg1, arg2, arg3, arg4) +#define FLASH_PRINT_TRACE6(fmt, arg0, arg1, arg2, arg3, arg4, arg5) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 6, arg0, arg1, arg2, arg3, arg4, arg5) +#define FLASH_PRINT_TRACE7(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 7, arg0, arg1, arg2, arg3, arg4, arg5, arg6) +#define FLASH_PRINT_TRACE8(fmt, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_FLASH, LEVEL_TRACE, fmt, 8, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + +#ifdef __cplusplus +} +#endif + +#endif /* _TRACE_H_ */ diff --git a/inc/platform/version.h b/inc/platform/version.h new file mode 100644 index 0000000..4c6ded0 --- /dev/null +++ b/inc/platform/version.h @@ -0,0 +1,21 @@ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 3 +#define VERSION_REVISION 1 +#define VERSION_BUILDNUM 1 +#define VERSION_GCID 0x483dbbfa +#define VERSION_GCID2 0x185b11a2 +#define CUSTOMER_NAME sdk +#define CN_1 's' +#define CN_2 'd' +#define CN_3 'k' +#define CN_4 '#' +#define CN_5 '#' +#define CN_6 '#' +#define CN_7 '#' +#define CN_8 '#' +#define BUILDING_TIME "Mon Sep 29 17:57:18 2025" +#define NAME2STR(a) #a +#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME) +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILDNUM) diff --git a/inc/rcu/ima_adpcm_enc.h b/inc/rcu/ima_adpcm_enc.h new file mode 100644 index 0000000..c8fb820 --- /dev/null +++ b/inc/rcu/ima_adpcm_enc.h @@ -0,0 +1,29 @@ +/** +************************************************************************************************************ +* Copyright(c) 2014-2015, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file ima_adpcm_enc.h +* @brief +* @author Chenjie Jin +* @date 2018-05-14 +* @version v0.2 +************************************************************************************************************* +*/ + +#ifndef __IMA_ADPCM_ENCODE_H__ +#define __IMA_ADPCM_ENCODE_H__ + +#include "stdint.h" + +typedef struct +{ + short valprev; /* Previous output value */ + char index; /* Index into stepsize table */ + uint16_t seq_id; /* sequnce index */ +} T_IMA_ADPCM_STATE; + +int ima_adpcm_encode(short *indata, unsigned char *outdata, int len, T_IMA_ADPCM_STATE *state); + +extern T_IMA_ADPCM_STATE ima_adpcm_global_state; + +#endif /* __CVSD_ENCODE_H__ */ diff --git a/inc/rcu/sbc.h b/inc/rcu/sbc.h new file mode 100644 index 0000000..098fd81 --- /dev/null +++ b/inc/rcu/sbc.h @@ -0,0 +1,67 @@ +#ifndef _SBC_H_ +#define _SBC_H_ + +/* defines */ +#define SBC_SUPPORT_OTHER_MODE 0 //0:just support mono mode + +#define SBC_SUCCESS 0 +#define SBC_NOT_ENOUGH_DATA -1 +#define SBC_BUFFER_TOO_SMALL -2 +#define SBC_NO_SYNCBYTE -3 +#define SBC_CHECKSUM_ERROR -4 + +#define SBC_SYNCBYTE 0x9c +#define SBC_MAX_SUBBANDS 8 +#if SBC_SUPPORT_OTHER_MODE +#define SBC_MAX_CHANNELS 2 +#else +#define SBC_MAX_CHANNELS 1 +#endif +#define SBC_TERMINATOR -1 + +/* structs, typedefs */ +#define SBC_FREQU16000 0x0 +#define SBC_FREQU32000 0x1 +#define SBC_FREQU44100 0x2 +#define SBC_FREQU48000 0x3 +typedef unsigned short TSBCSamplingFrequency; + +#define SBC_BLOCKS4 0x0 +#define SBC_BLOCKS8 0x1 +#define SBC_BLOCKS12 0x2 +#define SBC_BLOCKS16 0x3 +typedef unsigned short TSBCBlockNumber; + +#define SBC_MODE_MONO 0x0 +#if SBC_SUPPORT_OTHER_MODE +#define SBC_MODE_DUAL 0x1 +#define SBC_MODE_STEREO 0x2 +#define SBC_MODE_JOINT 0x3 +#endif +typedef unsigned short TSBCChannelMode; + +#define SBC_ALLOCLOUDNESS 0x0 +#define SBC_ALLOCSNR 0x1 +typedef unsigned short TSBCAllocMethod; + +#define SBC_SUBBANDS4 0x0 +#define SBC_SUBBANDS8 0x1 +typedef unsigned short TSBCSubbandNumber; + +typedef struct +{ + TSBCSamplingFrequency samplingFrequency; + TSBCBlockNumber blockNumber; + TSBCChannelMode channelMode; + TSBCAllocMethod allocMethod; + TSBCSubbandNumber subbandNumber; + unsigned char bitpool; +} T_SBC_PARAMS; + +extern T_SBC_PARAMS sbc_enc_params; + +void sbc_init_encoder(void); +int sbc_encode(unsigned char *p_input_buff, int input_size, T_SBC_PARAMS *p_params, + unsigned char *p_output_buff, int *p_output_size); + +#endif diff --git a/src/app/findmy/UARPDK/CoreUARPAccessory.c b/src/app/findmy/UARPDK/CoreUARPAccessory.c new file mode 100644 index 0000000..8a489b0 --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPAccessory.c @@ -0,0 +1,1336 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#include "CoreUARPPlatform.h" +#include "fmna_dfu_platform.h" + +#include "CoreUARPAccessory.h" +#include "CoreUARPUtils.h" + + +/* MARK: INTERNAL PROTOTYPES */ + + +static uint32_t uarpAccessoryProcessVersionDiscoveryRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgVersionDiscoveryRequest *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessAssetAvailableNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetAvailableNotification *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessAssetRescindedNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetRescindedNotification *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessAssetDataResponse( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetDataResponse *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessAssetTransferNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetDataTransferNotification *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessApplyStagedAssetsRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgApplyStagedAssetsRequest *pRxMsg, + uint32_t lengthRxMsg ); + +static uint32_t uarpAccessoryProcessInformationRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAccessoryInformationRequest *pRxMsg, + uint32_t lengthRxMsg ); + +#if !(UARP_DISABLE_VENDOR_SPECIFIC) + +static uint32_t uarpAccessoryProcessVendorSpecific( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgVendorSpecific *pRxMsg, + uint32_t lengthRxMsg ); + +#endif + +static struct uarpRemoteControllerObj * + uarpAccessoryRemoteControllerFind( struct uarpAccessoryObj *pAccessory, + void *pDelegate ); + +static uint32_t uarpAccessoryTxAssetDataRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint16_t assetID, uint32_t dataOffset, uint32_t dataLength ); + +static uint32_t uarpAccessoryTxAssetProcessingNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint16_t assetID, uint16_t assetProcessingFlags ); + +static uint32_t uarpAccessoryTxSync( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController ); + +static uint32_t uarpAccessoryCallbackUpdateInformationTLV( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPTLVHeader *pTlv ); + +static uint32_t uarpAccessoryAllocAndPrepareTransmitBuffer( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint8_t **ppBuffer, uint32_t *pBufferLength, + uint16_t msgType, uint16_t txMsgLength ); + +static uint32_t uarpAccessoryTransmitBuffer( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint8_t *pBuffer, uint32_t bufferLength ); + +static uint32_t uarpAccessoryAssetProcessingComplete( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint16_t assetID, uint16_t assetProcessingFlags ); + +/* MARK: CORE */ + +static uint16_t error_line; +static const char* const error_file = __FILE__; + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryInit( struct uarpAccessoryObj *pAccessory, + struct uarpAccessoryCallbacksObj *pCallbacks, + void *pAccessoryDelegate ) +{ + uint32_t status; + + /* qualifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusUnknownAccessory ); + __UARP_Verify_Action( pCallbacks, exit, status = kUARPStatusInvalidObject ); + __UARP_Verify_Action( pAccessoryDelegate, exit, status = kUARPStatusInvalidObject ); + + memset( pAccessory, 0, sizeof( struct uarpAccessoryObj ) ); + + pAccessory->callbacks = *pCallbacks; + + __UARP_Verify_Action( pAccessory->callbacks.fRequestTransmitMsgBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fReturnTransmitMsgBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fSendMessage, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fAccessoryQueryAccessoryInfo, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fAccessoryAssetOffered, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fAssetRescinded, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fAccessoryAssetDataResponse, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fUpdateDataTransferPause, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fUpdateDataTransferResume, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pAccessory->callbacks.fApplyStagedAssets, exit, status = kUARPStatusInvalidFunctionPointer ); + + pAccessory->pDelegate = pAccessoryDelegate; + + pAccessory->nextRemoteControllerID = 1; + + pAccessory->pControllerList = NULL; + + uarpLogDebug( kUARPLoggingCategoryAccessory, "Initialized New Accessory" ); + + /* TODO: add capabilities field.... + - support re-connect / resume of superbinaries */ + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit /* This resolves "exit:" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryRemoteControllerAdd( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + void *pControllerDelegate ) +{ + uint32_t status; + struct uarpRemoteControllerObj *pTmp; + + /* qualifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pRemoteController, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pControllerDelegate, exit, status = kUARPStatusInvalidArgument ); + + /* ensure that we don't already have this controller on the list */ + pTmp = uarpAccessoryRemoteControllerFind( pAccessory, pControllerDelegate ); + __UARP_Require_Action( ( pTmp == NULL ), exit, status = kUARPStatusDuplicateController ); + + /* init the new remote controller */ + memset( (void *)pRemoteController, 0, sizeof( struct uarpRemoteControllerObj ) ); + + pRemoteController->remoteControllerID = pAccessory->nextRemoteControllerID++; + + pRemoteController->dataTransferAllowed = kUARPYes; + + pRemoteController->txMsgID = kUARPInitialTxMsgID; + pRemoteController->lastRxMsgID = kUARPInitialTxMsgID - 1; + + pRemoteController->selectedProtocolVersion = kUARPProtocolVersionMinimum; + + pRemoteController->pDelegate = pControllerDelegate; + + /* update list */ + pRemoteController->pNext = pAccessory->pControllerList; + + pAccessory->pControllerList = pRemoteController; + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Remote Controller Added" ); + + status = kUARPStatusSuccess; + /* CHANGE: After controller send Sync msg, accessory respond own Sync msg */ +// status = uarpAccessoryTxSync( pAccessory, pRemoteController ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryRemoteControllerRemove( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController ) +{ + uint32_t status; + struct uarpRemoteControllerObj *pTmp; + struct uarpRemoteControllerObj *pRemoteControllerList; + + /* Verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusUnknownAccessory ); + __UARP_Verify_Action( pRemoteController, exit, status = kUARPStatusInvalidArgument ); + + /* remove and cleanup the matching remote controller */ + pRemoteControllerList = pAccessory->pControllerList; + pAccessory->pControllerList = NULL; + + while ( pRemoteControllerList ) + { + pTmp = pRemoteControllerList; + + pRemoteControllerList = pRemoteControllerList->pNext; + + if ( pTmp != pRemoteController ) + { + pTmp->pNext = pAccessory->pControllerList; + pAccessory->pControllerList = pTmp; + continue; + } + } + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Remote Controller Removed" ); + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit /* This resolves "exit:" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +struct uarpRemoteControllerObj * uarpAccessoryRemoteControllerFind( struct uarpAccessoryObj *pAccessory, void *pDelegate ) +{ + struct uarpRemoteControllerObj *pTmp; + struct uarpRemoteControllerObj *pRemoteController; + + pRemoteController = NULL; + + if ( pAccessory && pDelegate ) + { + for ( pTmp = pAccessory->pControllerList; pTmp; pTmp = pTmp->pNext ) + { + if ( pTmp->pDelegate == pDelegate ) + { + pRemoteController = pTmp; + break; + } + } + } + + return pRemoteController; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryRecvMessage( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint8_t *pRxMsg, uint32_t lengthRxMsg ) +{ + uint32_t status; + uint32_t lengthValidation; + struct UARPMsgHeader *uarpMsg; + struct uarpRemoteControllerObj *pRemoteController; + + /* look for the remote accessory in the list */ + pRemoteController = uarpAccessoryRemoteControllerFind( pAccessory, pControllerDelegate ); + + if ( pRemoteController == NULL ) + { + status = kUARPStatusUnknownController; + } + else if ( pRxMsg == NULL ) + { + status = kUARPStatusInvalidMessage; + } + else if ( sizeof( struct UARPMsgHeader ) > lengthRxMsg ) + { + status = kUARPStatusInvalidMessageLength; + } + else + { + status = kUARPStatusSuccess; + } + __UARP_Require_Quiet( status == kUARPStatusSuccess, exit ); + + /* determine the type of message and get it to the proper dispatcher */ + uarpMsg = (struct UARPMsgHeader *)pRxMsg; + + /* ensure proper endianess */ + uarpMsg->msgType = uarpNtohs( uarpMsg->msgType ); + uarpMsg->msgPayloadLength = uarpNtohs( uarpMsg->msgPayloadLength ); + uarpMsg->msgID = uarpNtohs( uarpMsg->msgID ); + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Type <0x%04x> ID <%u>", uarpMsg->msgType, uarpMsg->msgID ); + + /* if this is the sync message, we will resync msg id */ + if ( uarpMsg->msgType == kUARPMsgSync ) + { + status = kUARPStatusSuccess; + } + /* look for missing, duplicate, out of order packets */ + else if ( (uint16_t)( uarpMsg->msgID - 1 ) == pRemoteController->lastRxMsgID ) + { + status = kUARPStatusSuccess; + } + else if ( uarpMsg->msgID == pRemoteController->lastRxMsgID ) + { + uarpLogDebug( kUARPLoggingCategoryAccessory, "RX BAD MSG ID - duplicate <%u> last id <%u>", + uarpMsg->msgID, pRemoteController->lastRxMsgID ); + + /* don't process a duplicate packet */ + status = kUARPStatusDuplicateMessageID; + + pRemoteController->uarpStats.packetsDuplicate++; + } + else if ( uarpMsg->msgID < pRemoteController->lastRxMsgID ) + { + uarpLogDebug( kUARPLoggingCategoryAccessory, "RX BAD MSG ID - out of order <%u> last id <%u>", + uarpMsg->msgID, pRemoteController->lastRxMsgID ); + + /* don't process an out of order packet */ + status = kUARPStatusOutOfOrderMessageID; + + pRemoteController->uarpStats.packetsOutOfOrder++; + } + else if ( uarpMsg->msgID > ( pRemoteController->lastRxMsgID + 1 ) ) + { + uarpLogDebug( kUARPLoggingCategoryAccessory, "RX BAD MSG ID - missed <%u> last id <%u>", + uarpMsg->msgID, pRemoteController->lastRxMsgID ); + + /* we should proceed if we missed a packet. */ + /* TODO: should we be tracking outstanding requests so we can resend ? */ + status = kUARPStatusSuccess; + + pRemoteController->uarpStats.packetsMissed++; + } + else + { + status = kUARPStatusSuccess; + } + pRemoteController->lastRxMsgID = uarpMsg->msgID; + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* validate the length of the message */ + lengthValidation = uarpMsg->msgPayloadLength; + lengthValidation += (uint32_t)sizeof( struct UARPMsgHeader ); + __UARP_Require_Action( ( lengthRxMsg == lengthValidation ), exit, status = kUARPStatusInvalidMessage ); + + /* process the message */ + switch ( uarpMsg->msgType ) + { + case kUARPMsgSync: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Sync" ); + + status = uarpAccessoryTxSync( pAccessory, pRemoteController ); + + break; + + case kUARPMsgVersionDiscoveryRequest: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Version Discovery Request" ); + + status = uarpAccessoryProcessVersionDiscoveryRequest( pAccessory, pRemoteController, + (struct UARPMsgVersionDiscoveryRequest *)pRxMsg, + lengthRxMsg ); + break; + + case kUARPMsgAssetAvailableNotification: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Asset Available Notification" ); + + status = uarpAccessoryProcessAssetAvailableNotification( pAccessory, pRemoteController, + (struct UARPMsgAssetAvailableNotification *)pRxMsg, + lengthRxMsg ); + break; + + case kUARPMsgAssetRescindedNotification: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Asset Rescinded Notification" ); + + status = uarpAccessoryProcessAssetRescindedNotification( pAccessory, pRemoteController, + (struct UARPMsgAssetRescindedNotification *)pRxMsg, + lengthRxMsg ); + break; + + case kUARPMsgAssetDataResponse: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Asset Data Response" ); + + status = uarpAccessoryProcessAssetDataResponse( pAccessory, pRemoteController, + (struct UARPMsgAssetDataResponse *)pRxMsg, + lengthRxMsg ); + break; + + case kUARPMsgAssetDataTransferNotification: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Data Transfer Notification Request" ); + + status = uarpAccessoryProcessAssetTransferNotification( pAccessory, pRemoteController, + (struct UARPMsgAssetDataTransferNotification *)pRxMsg, + lengthRxMsg ); + break; + + case kUARPMsgApplyStagedAssetsRequest: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Apply Staged Asset Request" ); + + status = uarpAccessoryProcessApplyStagedAssetsRequest( pAccessory, pRemoteController, + (struct UARPMsgApplyStagedAssetsRequest *)pRxMsg, + lengthRxMsg ); + + dfu_service_handle_active_image(); + + break; + + case kUARPMsgAccessoryInformationRequest: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Accessory Information Request" ); + + status = uarpAccessoryProcessInformationRequest( pAccessory, pRemoteController, + (struct UARPMsgAccessoryInformationRequest *)pRxMsg, + lengthRxMsg ); + break; + + + case kUARPMsgAssetProcessingNotificationAck: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Asset Processing Notification Ack" ); + + status = kUARPStatusSuccess; + + break; + +#if !(UARP_DISABLE_CONTROLLER) + /* + kUARPMsgVersionDiscoveryResponse + kUARPMsgAccessoryInformationResponse + kUARPMsgAssetDataRequest + kUARPMsgAssetProcessingNotification + kUARPMsgApplyStagedAssetsResponse + kUARPMsgAssetAvailableNotificationAck + kUARPMsgAssetDataTransferNotificationAck + kUARPMsgAssetRescindedNotificationAck + */ +#endif + +#if !(UARP_DISABLE_VENDOR_SPECIFIC) + + case kUARPMsgVendorSpecific: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Vendor Specific" ); + + status = uarpAccessoryProcessVendorSpecific( pAccessory, pRemoteController, + (struct UARPMsgVendorSpecific *)pRxMsg, + lengthRxMsg ); + break; +#endif + + default: + + uarpLogDebug( kUARPLoggingCategoryAccessory, "MSG RCV Unknown 0x%8x", uarpMsg->msgType ); + + status = kUARPStatusUnknownMessageType; + + break; + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessVersionDiscoveryRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgVersionDiscoveryRequest *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint32_t status; + uint32_t txMsgLength; + uint16_t protocolVersionController; + struct UARPMsgVersionDiscoveryResponse *pTxMsg; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgVersionDiscoveryRequest ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* Endian convert message, beyond header. The calling function has converted the header already */ + protocolVersionController = uarpNtohs( pRxMsg->protocolVersionController ); + + /* make sure we can work with what the controller is offering */ + uarpLogDebug( kUARPLoggingCategoryAccessory, "MsgRx Version Discovery Request" ); + uarpLogDebug( kUARPLoggingCategoryAccessory, " - Accessory Max Protocol Version %u", pRemoteController->selectedProtocolVersion ); + uarpLogDebug( kUARPLoggingCategoryAccessory, " - Controller Max Protocol Version %u", protocolVersionController ); + + if ( pRemoteController->selectedProtocolVersion > protocolVersionController ) + { + pRemoteController->selectedProtocolVersion = protocolVersionController; + } + + uarpLogDebug( kUARPLoggingCategoryAccessory, " - Selected Protocol Version %u", pRemoteController->selectedProtocolVersion ); + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgVersionDiscoveryResponse ); + uarpLogDebug( kUARPLoggingCategoryAccessory, "Msg Tx lebgth %u", txMsgLength ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgVersionDiscoveryResponse, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Prepare our response */ + pTxMsg->status = uarpHtons( kUARPStatusSuccess ); + pTxMsg->protocolVersionAccessory = uarpHtons( pRemoteController->selectedProtocolVersion ); + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessAssetAvailableNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetAvailableNotification *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint32_t status; + uint32_t txMsgLength; + struct uarpAssetCoreObj assetCore; + struct UARPMsgAssetAvailableNotification *pTxMsg; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgAssetAvailableNotification ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* prepare the asset to begin the transfer */ + assetCore.assetTag = pRxMsg->assetTag; /* already in the right endian */ + assetCore.assetFlags = uarpNtohs( pRxMsg->assetFlags ); + assetCore.assetID = uarpNtohs( pRxMsg->assetID ); + + uarpVersionEndianSwap( &(pRxMsg->assetVersion), &(assetCore.assetVersion) ); + + assetCore.assetTotalLength = uarpNtohl( pRxMsg->assetLength ); + assetCore.assetNumPayloads = uarpNtohs( pRxMsg->assetNumPayloads ); + + /* ACK this; note we did not swap RX Msg in place */ + txMsgLength = sizeof( struct UARPMsgAssetAvailableNotification ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgAssetAvailableNotificationAck, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + pTxMsg->assetTag = pRxMsg->assetTag; + pTxMsg->assetFlags = pRxMsg->assetFlags; + pTxMsg->assetID = pRxMsg->assetID; + pTxMsg->assetVersion = pRxMsg->assetVersion; + pTxMsg->assetLength = pRxMsg->assetLength; + pTxMsg->assetNumPayloads = pRxMsg->assetNumPayloads; + + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* inform the FWUPAPP this is happening */ + status = pAccessory->callbacks.fAccessoryAssetOffered( pAccessory->pDelegate, pRemoteController->pDelegate, + &assetCore ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessAssetRescindedNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetRescindedNotification *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint16_t assetID; + uint32_t status; + uint32_t txMsgLength; + struct UARPMsgAssetRescindedNotification *pTxMsg; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgAssetRescindedNotification ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* translate the asset ID */ + assetID = uarpNtohs( pRxMsg->assetID ); + + uarpLogDebug( kUARPLoggingCategoryAccessory, "Asset Rescinded ID <%u> from Controller <%d>", + assetID, pRemoteController->remoteControllerID ); + + /* ACK this; note we did not swap RX Msg in place */ + txMsgLength = sizeof( struct UARPMsgAssetRescindedNotification ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgAssetRescindedNotificationAck, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + pTxMsg->assetID = pRxMsg->assetID; + + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* inform the FWUPAPP this is happening */ + pAccessory->callbacks.fAssetRescinded( pAccessory->pDelegate, pRemoteController->pDelegate, assetID ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessAssetDataResponse( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetDataResponse *pRxMsg, + uint32_t lengthRxMsg ) +{ + void *pBuffer; + uint32_t status; + uint16_t assetID; + uint32_t lengthBuffer; + uint16_t currentRequestStatus; + uint32_t currentRequestedLength; + uint32_t currentRespondedOffset; + uint32_t currentRespondedLength; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgAssetDataResponse ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* look for the asset in our list and do some endian translation */ + assetID = uarpNtohs( pRxMsg->assetID ); + + currentRequestStatus = uarpNtohs( pRxMsg->status ); + currentRespondedOffset = uarpNtohl( pRxMsg->dataOffset ); + currentRequestedLength = (uint32_t)uarpNtohs( pRxMsg->numBytesRequested ); + currentRespondedLength = (uint32_t)uarpNtohs( pRxMsg->numBytesResponded ); + + uarpLogInfo( kUARPLoggingCategoryAccessory, "RCV %u bytes from offset %u of asset id %u", + currentRespondedLength, currentRespondedOffset, assetID ); + + /* look for any obvious errors */ + if ( currentRequestStatus != kUARPStatusSuccess ) + { + status = currentRequestStatus; + } + else if ( currentRespondedLength > ( lengthRxMsg - sizeof( struct UARPMsgAssetDataResponse ) ) ) + { + status = kUARPStatusInvalidDataResponseLength; + } + else if ( currentRespondedLength > currentRequestedLength ) + { + status = kUARPStatusInvalidDataResponseLength; + } + else + { + status = kUARPStatusSuccess; + } + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* alias the buffer */ + pBuffer = (void *)( (uint8_t *)pRxMsg + sizeof( struct UARPMsgAssetDataResponse ) ); + lengthBuffer = currentRespondedLength; + + /* inform the upper layer */ + status = pAccessory->callbacks.fAccessoryAssetDataResponse( pAccessory->pDelegate, pRemoteController->pDelegate, + assetID, pBuffer, lengthBuffer, currentRespondedOffset ); + +__UARP_Verify_exit + /* TODO: if failure for any reason, tell FWUPAPP we need to purge this asset */ + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessAssetTransferNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAssetDataTransferNotification *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint32_t status; + uint16_t assetTransferFlags; + uint32_t txMsgLength; + struct UARPMsgAssetDataTransferNotification *pTxMsg; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgAssetDataTransferNotification ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* setup the assetID in proper endianess */ + assetTransferFlags = uarpNtohs( pRxMsg->assetTransferFlags ); + + /* ACK this; note we did not swap RX Msg in place */ + txMsgLength = sizeof( struct UARPMsgAssetDataTransferNotification ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgAssetDataTransferNotificationAck, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + pTxMsg->assetTransferFlags = pRxMsg->assetTransferFlags; + + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* adhere to kUARPAssetDataTransferPause / kUARPAssetDataTransferResume */ + if ( ( assetTransferFlags & kUARPAssetDataTransferPause ) && ( pRemoteController->dataTransferAllowed == kUARPYes ) ) + { + uarpLogInfo( kUARPLoggingCategoryAccessory, "Data Transfer Paused by Controller" ); + + pRemoteController->dataTransferAllowed = kUARPNo; + + status = pAccessory->callbacks.fUpdateDataTransferPause( pAccessory->pDelegate, pRemoteController->pDelegate ); + } + else if ( ( assetTransferFlags & kUARPAssetDataTransferResume ) && ( pRemoteController->dataTransferAllowed == kUARPNo ) ) + { + uarpLogInfo( kUARPLoggingCategoryAccessory, "Data Transfer Resumed by Controller" ); + + pRemoteController->dataTransferAllowed = kUARPYes; + + status = pAccessory->callbacks.fUpdateDataTransferResume( pAccessory->pDelegate, pRemoteController->pDelegate ); + } + else + { + status = kUARPStatusInvalidDataTransferNotification; + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessApplyStagedAssetsRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgApplyStagedAssetsRequest *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint32_t status; + uint16_t flags; + uint32_t txMsgLength; + struct UARPMsgApplyStagedAssetsResponse *pTxMsg; + + /* tell the FWUPAPP */ + status = pAccessory->callbacks.fApplyStagedAssets( pAccessory->pDelegate, pRemoteController->pDelegate, &flags ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgApplyStagedAssetsResponse ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgApplyStagedAssetsResponse, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Prepare our response */ + pTxMsg->status = uarpHtons( kUARPStatusSuccess ); + pTxMsg->flags = uarpHtons( flags ); + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryTxAssetProcessingNotification( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint16_t assetID, uint16_t assetProcessingFlags ) +{ + uint32_t status; + uint32_t txMsgLength; + struct UARPMsgAssetProcessingNotification *pTxMsg; + + /* We could actually get here with a NULL pRemoteController, for abandoning an asset + which was left behind by a, now unreachable, remote controller */ + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgAssetProcessingNotification ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgAssetProcessingNotification, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Prepare our response */ + pTxMsg->assetID = uarpHtons( assetID ); + pTxMsg->assetProcessingFlags = uarpHtons( assetProcessingFlags ); + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryTxAssetDataRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint16_t assetID, uint32_t dataOffset, uint32_t dataLength ) +{ + uint32_t status; + uint32_t txMsgLength; + uint32_t numBytesRequested; + struct UARPMsgAssetDataRequest *pTxMsg; + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgAssetDataRequest ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgAssetDataRequest, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Prepare our response */ + pTxMsg->assetID = uarpHtons( assetID ); + pTxMsg->dataOffset = uarpHtonl( dataOffset ); + + /* determine how big of a chunk we can download */ + numBytesRequested = dataLength; + + if ( numBytesRequested > kUARPMaxBytesRequested ) + { + numBytesRequested = kUARPMaxBytesRequested; + } + + pTxMsg->numBytesRequested = uarpHtons( (uint16_t)numBytesRequested ); + + uarpLogInfo( kUARPLoggingCategoryAccessory, "REQ %u bytes (instead of %u) from offset %u of asset id %u", + numBytesRequested, dataLength, dataOffset, assetID ); + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryTxSync( struct uarpAccessoryObj *pAccessory, struct uarpRemoteControllerObj *pRemoteController ) +{ + uint32_t status; + uint32_t txMsgLength; + struct UARPMsgHeader *pTxMsg; + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgHeader ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgSync, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryProcessInformationRequest( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgAccessoryInformationRequest *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint32_t status; + uint32_t txMsgLength; + uint32_t bufferLength; + uint32_t lengthTlv; + struct UARPTLVHeader *pTlv; + struct UARPMsgAccessoryInformationResponse *pTxMsg; + + /* Verifiers */ + __UARP_Require_Action( ( lengthRxMsg >= sizeof( struct UARPMsgAccessoryInformationRequest ) ), exit, + status = kUARPStatusInvalidMessage ); + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgAccessoryInformationResponse ) + sizeof( struct UARPTLVHeader ); + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, &bufferLength, + kUARPMsgAccessoryInformationResponse, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Query the TLV from the product, and have it copy the response inline if there is room */ + pTlv = (struct UARPTLVHeader *)((uint8_t *)pTxMsg + sizeof( struct UARPMsgAccessoryInformationResponse )); + lengthTlv = bufferLength - txMsgLength; + + pTlv->tlvType = uarpNtohl( pRxMsg->informationOption ); + pTlv->tlvLength = lengthTlv; + + /* Prepare our response, need to update the header's msgPayloadLength */ + status = uarpAccessoryCallbackUpdateInformationTLV( pAccessory, pRemoteController, pTlv ); + + if ( status == kUARPStatusSuccess ) + { + txMsgLength += pTlv->tlvLength; + bufferLength = (uint16_t)txMsgLength - (uint16_t)sizeof( struct UARPMsgHeader ); + + pTxMsg->msgHdr.msgPayloadLength = uarpHtons( bufferLength ); + + pTlv->tlvType = uarpHtonl( pTlv->tlvType ); + pTlv->tlvLength = uarpHtonl( pTlv->tlvLength ); + } + + pTxMsg->status = uarpHtons( status ); + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryCallbackUpdateInformationTLV( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPTLVHeader *pTlv ) +{ + void *pBuffer; + uint32_t lengthBuffer; + uint32_t status; + + pBuffer = (void *)( (uint8_t *)pTlv + sizeof( struct UARPTLVHeader ) ); + lengthBuffer = pTlv->tlvLength; + + /* call the callback, unless this is something we track internally */ + if ( pTlv->tlvType == kUARPTLVAccessoryInformationStatistics ) + { + struct UARPStatistics *pStats; + + pStats = (struct UARPStatistics *)pBuffer; + + if ( lengthBuffer >= sizeof( struct UARPStatistics ) ) + { + pStats->packetsNoVersionAgreement = uarpHtonl( pRemoteController->uarpStats.packetsNoVersionAgreement ); + pStats->packetsMissed = uarpHtonl( pRemoteController->uarpStats.packetsMissed ); + pStats->packetsDuplicate = uarpHtonl( pRemoteController->uarpStats.packetsDuplicate ); + pStats->packetsOutOfOrder = uarpHtonl( pRemoteController->uarpStats.packetsOutOfOrder ); + + lengthBuffer = sizeof( struct UARPStatistics ); + + status = kUARPStatusSuccess; + } + else + { + status = kUARPStatusNoResources; + } + } + else + { + status = pAccessory->callbacks.fAccessoryQueryAccessoryInfo( pAccessory->pDelegate, pTlv->tlvType, + pBuffer, lengthBuffer, &lengthBuffer ); + } + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* copy back the length */ + pTlv->tlvLength = lengthBuffer; + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetDeny( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Asset <%d> Deny", assetID ); + + status = uarpAccessoryAssetProcessingComplete( pAccessory, pControllerDelegate, + assetID, kUARPAssetProcessingFlagsUploadDenied ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetAbandon( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Asset <%d> Abandon", assetID ); + + status = uarpAccessoryAssetProcessingComplete( pAccessory, pControllerDelegate, + assetID, kUARPAssetProcessingFlagsUploadAbandoned ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetCorrupt( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Asset <%d> Corrupt", assetID ); + + status = uarpAccessoryAssetProcessingComplete( pAccessory, pControllerDelegate, + assetID, kUARPAssetProcessingFlagsAssetCorrupt ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetStaged( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryAccessory, "Asset <%d> Staged", assetID ); + + status = uarpAccessoryAssetProcessingComplete( pAccessory, pControllerDelegate, + assetID, kUARPAssetProcessingFlagsUploadComplete ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetProcessingComplete( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint16_t assetID, uint16_t assetProcessingFlags ) +{ + uint32_t status; + struct uarpRemoteControllerObj *pRemoteController; + + /* alias the remote controller */ + pRemoteController = uarpAccessoryRemoteControllerFind( pAccessory, pControllerDelegate ); + + if ( pRemoteController ) + { + status = uarpAccessoryTxAssetProcessingNotification( pAccessory, pRemoteController, + assetID, assetProcessingFlags ); + } + else if ( assetProcessingFlags == kUARPAssetProcessingFlagsUploadAbandoned ) + { + /* remote controller can be NULL when abandoning an asset */ + status = kUARPStatusSuccess; + } + else + { + status = kUARPStatusUnknownController; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAssetRequestData( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint16_t assetID, uint32_t requestOffset, uint32_t requestLength ) +{ + uint32_t status; + struct uarpRemoteControllerObj *pRemoteController; + + /* alias the remote controller */ + pRemoteController = uarpAccessoryRemoteControllerFind( pAccessory, pControllerDelegate ); + + if ( pRemoteController == NULL ) + { + status = kUARPStatusUnknownController; + } + else if ( pRemoteController->dataTransferAllowed == kUARPNo ) + { + status = kUARPStatusDataTransferPaused; + } + else + { + status = uarpAccessoryTxAssetDataRequest( pAccessory, pRemoteController, assetID, requestOffset, requestLength ); + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryAllocAndPrepareTransmitBuffer( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint8_t **ppBuffer, uint32_t *pBufferLength, + uint16_t msgType, uint16_t txMsgLength ) +{ + uint32_t status; + uint32_t bufferLength; + struct UARPMsgHeader *pTxMsg; + + /* just in case fRequestTransmitMsgBuffer doesn't do proper initialization */ + *ppBuffer = NULL; + + if ( pBufferLength ) + { + *pBufferLength = 0; + } + + status = pAccessory->callbacks.fRequestTransmitMsgBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)ppBuffer, &bufferLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + __UARP_Require( ( bufferLength >= txMsgLength ), exit ); + + /* Prepare our response */ + pTxMsg = (struct UARPMsgHeader *)(*ppBuffer); + + pTxMsg->msgType = uarpHtons( msgType ); + + pTxMsg->msgPayloadLength = uarpHtons( txMsgLength - (uint16_t)sizeof( struct UARPMsgHeader ) ); + + if ( pBufferLength ) + { + *pBufferLength = bufferLength; + } + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpAccessoryTransmitBuffer( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + uint8_t *pBuffer, uint32_t bufferLength ) +{ + uint32_t status; + struct UARPMsgHeader *pMsgHdr; + + /* update the msgID field here, not at alloc time */ + pMsgHdr = (struct UARPMsgHeader *)pBuffer; + + pMsgHdr->msgID = uarpHtons( pRemoteController->txMsgID ); + + status = pAccessory->callbacks.fSendMessage( pAccessory->pDelegate, + pRemoteController->pDelegate, + pBuffer, bufferLength ); + + if ( status == kUARPStatusSuccess ) + { + pRemoteController->txMsgID++; + } + else + { + pAccessory->callbacks.fReturnTransmitMsgBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + pBuffer ); + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +#if !(UARP_DISABLE_VENDOR_SPECIFIC) + +uint32_t uarpAccessoryProcessVendorSpecific( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + struct UARPMsgVendorSpecific *pRxMsg, + uint32_t lengthRxMsg ) +{ + uint8_t *pBuffer; + uint32_t length; + uint32_t status; + uint32_t lengthNeeded; + + /* Verifiers */ + lengthNeeded = sizeof( struct UARPMsgVendorSpecific ); + __UARP_Require_Action( ( lengthRxMsg >= lengthNeeded ), exit, status = kUARPStatusInvalidMessage ); + + /* Tell FWUPAPP about this option */ + pBuffer = (uint8_t *)( (uint8_t *)pRxMsg + sizeof( struct UARPMsgVendorSpecific ) ); + + uarpLogDebug( kUARPLoggingCategoryAccessory, "Vendor Specific Message from Remote UARP Controller %d " + "OUI <%02x-%02x-%02x> MsgType <0x%04x>", + pRemoteController->remoteControllerID, pRxMsg->oui[0], pRxMsg->oui[1], pRxMsg->oui[2], + uarpNtohs( pRxMsg->msgType ) ); + + /* TODO: we should be looking at msg payload length too */ + if ( pAccessory->callbacks.fVendorSpecific ) + { + length = lengthRxMsg - sizeof( struct UARPMsgVendorSpecific ); + + status = pAccessory->callbacks.fVendorSpecific( pAccessory->pDelegate, pRemoteController->pDelegate, + pRxMsg->oui, uarpNtohs( pRxMsg->msgType ), + pBuffer, length ); + } + else + { + status = kUARPStatusUnknownMessageType; + } + +__UARP_Verify_exit + return status; +} + +#endif + +/* -------------------------------------------------------------------------------- */ + +#if !(UARP_DISABLE_VENDOR_SPECIFIC) + +uint32_t uarpAccessoryTxMsgVendorSpecific( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint8_t oui[kUARPOUILength], uint16_t msgType, + uint8_t *pBuffer, uint32_t lengthBuffer ) +{ + uint8_t *pTmp; + uint32_t status; + uint32_t txMsgLength; + struct UARPMsgVendorSpecific *pTxMsg; + struct uarpRemoteControllerObj *pRemoteController; + + /* alias objects */ + pRemoteController = uarpAccessoryRemoteControllerFind( pAccessory, pControllerDelegate ); + __UARP_Require_Action( pRemoteController, exit, status = kUARPStatusUnknownController ); + + /* get a buffer */ + txMsgLength = sizeof( struct UARPMsgVendorSpecific ) + lengthBuffer; + + status = uarpAccessoryAllocAndPrepareTransmitBuffer( pAccessory->pDelegate, + pRemoteController->pDelegate, + (uint8_t **)&pTxMsg, NULL, + kUARPMsgVendorSpecific, + txMsgLength ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + /* Prepare our response */ + pTxMsg->oui[0] = oui[0]; + pTxMsg->oui[1] = oui[1]; + pTxMsg->oui[2] = oui[2]; + pTxMsg->msgType = uarpHtons( msgType ); + + if ( pBuffer && ( lengthBuffer > 0 ) ) + { + pTmp = (uint8_t *)pTxMsg + (uint32_t)sizeof( struct UARPMsgVendorSpecific ); + memcpy( pTmp, pBuffer, lengthBuffer ); + } + + /* send the message */ + status = uarpAccessoryTransmitBuffer( pAccessory->pDelegate, pRemoteController->pDelegate, + (uint8_t *)pTxMsg, txMsgLength ); + +__UARP_Verify_exit + return status; +} + +#endif + diff --git a/src/app/findmy/UARPDK/CoreUARPAccessory.h b/src/app/findmy/UARPDK/CoreUARPAccessory.h new file mode 100644 index 0000000..4434702 --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPAccessory.h @@ -0,0 +1,302 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + + +#ifndef uarpAccessory_h +#define uarpAccessory_h + +#include "CoreUARPPlatform.h" +#include "CoreUARPProtocolDefines.h" +#include "CoreUARPUtils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* MARK: Forward Declarations */ + +struct uarpAccessoryObj; +struct uarpRemoteControllerObj; + +/* MARK: Callbacks */ + + +/* -------------------------------------------------------------------------------- */ +/*! @brief request buffer for tx'ing a uarp message + @discussion this routine is called when the lower layer would like a buffer for the purpose of sending a uarp message + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param ppBuffer double pointer where the buffer pointer will be returned. Callback managed. Caller MUST NOT free this memory + @param pLength value to return the length of the buffer needed + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryRequestTransmitMsgBuffer)( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t **ppBuffer, uint32_t *pLength ); + + +/* -------------------------------------------------------------------------------- */ +/*! @brief return previously allocated buffer + @discussion this routine is called when the lower layer is done with a dynamically allocated buffer for a uarp message + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param pBuffer pointer to the buffer being returned + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpAccessoryReturnTransmitMsgBuffer)( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer ); + + +/* -------------------------------------------------------------------------------- */ +/*! @brief send uarp message to controller + @discussion this routine is called when the lower layer needs to send a uarp message to the controller + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pControllerDelegate pointer to the firmware updater delegate's controller context pointer + @param pBuffer pointer to the buffer being sent + @param length length of the buffer pointed to above + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessorySendMessage)( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer, uint32_t length ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief apply staged assets + @discussion this routine is called when the lower layer has been instructed to apply staged assets by the controller + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param pFlags pointer to return apply staged assets flags + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryApplyStagedAssets)( void *pAccessoryDelegate, void *pControllerDelegate, + uint16_t *pFlags ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief query accessory info + @discussion this routine is called when the controller has requested one of the info TLVs + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param infoType accessory information type + @param pBuffer buffer for responding to the accessory information + @param lengthBuffer length of buffer pointed to above + @param pLengthNeeded length needed to respond to this query + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryQueryAccessoryInfo)( void *pAccessoryDelegate, uint32_t infoType, void *pBuffer, + uint32_t lengthBuffer, uint32_t *pLengthNeeded ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief asset offered + @discussion this routine is called when the controller has offered an asset + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param pAssetCore pointer to the core asset object + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryAssetOffered)( void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpAssetCoreObj *pAssetCore ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief asset rescinded + @discussion this routine is called when the controller has rescinded a previously offered an asset + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param assetID pointer to the core asset object + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpAccessoryAssetRescinded)( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t assetID ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief data response + @discussion this routine is called when the controller has responded to a data request + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param assetID asset ID + @param pBuffer pointer to the buffer containing response bytes + @param length length of the buffer pointed to above + @param offset offset into the asset, based on zero + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryAssetDataResponse)( void *pAccessoryDelegate, void *pControllerDelegate, + uint16_t assetID, + uint8_t *pBuffer, uint32_t length, uint32_t offset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief pause transfers + @discussion this routine is called when the lower layer has been instructed to pause data requests by the controller + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryUpdateDataTransferPause)( void *pAccessoryDelegate, void *pControllerDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief resume transfers + @discussion this routine is called when the lower layer has been instructed to resume previously paused data requesrs by the controller + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpAccessoryUpdateDataTransferResume)( void *pAccessoryDelegate, void *pControllerDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief vendor specific callback + @discussion this routine is called when a vendor specific message has been received + @param pAccessoryDelegate pointer to the accessory delegate, passed into this layer's accessory init + @param pControllerDelegate pointer to the controller delegate, passed into this layer's controller add + @param oui vendor specific OUI + @param msgType vendor specific message type + @param pBuffer pointer to the buffer for the vendor specific message + @param lengthBuffer size of the buffer representing the payload of the vendor specific message + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpVendorSpecific)( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t oui[kUARPOUILength], uint16_t msgType, + uint8_t *pBuffer, uint32_t lengthBuffer ); + + +/* MARK: Objects */ + + +/* UARP Remote Controller Object - callbacks */ + +struct uarpAccessoryCallbacksObj +{ + fcnUarpAccessoryRequestTransmitMsgBuffer fRequestTransmitMsgBuffer; /* required */ + fcnUarpAccessoryReturnTransmitMsgBuffer fReturnTransmitMsgBuffer; /* required */ + fcnUarpAccessorySendMessage fSendMessage; /* required */ + fcnUarpAccessoryQueryAccessoryInfo fAccessoryQueryAccessoryInfo; /* required */ + fcnUarpAccessoryAssetOffered fAccessoryAssetOffered; /* required */ + fcnUarpAccessoryAssetRescinded fAssetRescinded; /* required */ + fcnUarpAccessoryAssetDataResponse fAccessoryAssetDataResponse; /* required */ + fcnUarpAccessoryUpdateDataTransferPause fUpdateDataTransferPause; /* required */ + fcnUarpAccessoryUpdateDataTransferResume fUpdateDataTransferResume; /* required */ + fcnUarpAccessoryApplyStagedAssets fApplyStagedAssets; /* required */ + fcnUarpVendorSpecific fVendorSpecific; /* optional */ +}; + + +/* UARP Accessory Object */ + +struct uarpAccessoryObj +{ + void *pDelegate; /* it is up to the implementer to define this context */ + + int nextRemoteControllerID; + + struct uarpAccessoryCallbacksObj callbacks; + + struct uarpRemoteControllerObj *pControllerList; +}; + + +/* UARP Remote Controller Object - internal usage */ + +struct uarpRemoteControllerObj +{ + void *pDelegate; /* it is up to the implementer to define this context */ + + int remoteControllerID; + UARPBool dataTransferAllowed; + + uint16_t txMsgID; + uint16_t lastRxMsgID; + + uint32_t selectedProtocolVersion; + + struct UARPStatistics uarpStats; + + struct uarpRemoteControllerObj *pNext; +}; + +uint32_t uarpAccessoryInit( struct uarpAccessoryObj *pAccessory, + struct uarpAccessoryCallbacksObj *pCallbacks, + void *pAccessoryDelegate ); + +uint32_t uarpAccessoryRemoteControllerAdd( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController, + void *pControllerDelegate ); + +uint32_t uarpAccessoryRemoteControllerRemove( struct uarpAccessoryObj *pAccessory, + struct uarpRemoteControllerObj *pRemoteController ); + +uint32_t uarpAccessoryRecvMessage( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint8_t *pRxMsg, uint32_t lengthRxMsg ); + +uint32_t uarpAccessoryAssetRequestData( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint16_t assetID, uint32_t requestOffset, uint32_t requestLength ); + +uint32_t uarpAccessoryAssetDeny( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ); + +uint32_t uarpAccessoryAssetAbandon( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ); + +uint32_t uarpAccessoryAssetStaged( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ); + +uint32_t uarpAccessoryAssetCorrupt( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, uint16_t assetID ); + +#if !(UARP_DISABLE_VENDOR_SPECIFIC) + +uint32_t uarpAccessoryTxMsgVendorSpecific( struct uarpAccessoryObj *pAccessory, void *pControllerDelegate, + uint8_t oui[kUARPOUILength], uint16_t msgType, + uint8_t *pBuffer, uint32_t lengthBuffer ); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* uarpAccessory_h */ diff --git a/src/app/findmy/UARPDK/CoreUARPPlatform.h b/src/app/findmy/UARPDK/CoreUARPPlatform.h new file mode 100644 index 0000000..b1b655c --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPPlatform.h @@ -0,0 +1,56 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#ifndef CoreUARPPlatform_h +#define CoreUARPPlatform_h + +#include "CoreUARPPlatformRTK.h" + +#endif /* CoreUARPPlatform_h */ diff --git a/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.c b/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.c new file mode 100644 index 0000000..c956a01 --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.c @@ -0,0 +1,2166 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#include "CoreUARPPlatformAccessory.h" +#include "fmna_dfu_platform.h" +#include "FMNASampleUARP.h" + +/* MARK: INTERNAL DEFINES */ + +#define kUARPDataRequestTypeInvalid 0x00 +#define kUARPDataRequestTypeSuperBinaryHeader 0x01 +#define kUARPDataRequestTypeSuperBinaryPayloadHeader 0x02 +#define kUARPDataRequestTypeSuperBinaryMetadata 0x04 +#define kUARPDataRequestTypePayloadMetadata 0x10 +#define kUARPDataRequestTypePayloadPayload 0x20 +#define kUARPDataRequestTypeOutstanding 0x80 + +#define kUARPPayloadIndexInvalid -1 + +#define kUARPAssetHasHeader 0x01 +#define kUARPAssetHasPayloadHeader 0x02 +#define kUARPAssetNeedsMetadata 0x04 +#define kUARPAssetHasMetadata 0x08 +#define kUARPAssetHasPayload 0x10 +#define kUARPAssetMarkForCleanup 0x80 + +static uint16_t error_line; +static const char* const error_file = __FILE__; + +typedef uint32_t (* fcnUarpPlatformAssetDataRequestComplete)( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ); + +/* MARK: INTERNAL PROTOTYPES */ + +static struct uarpPlatformAsset * + uarpPlatformAssetFindByAssetID( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint16_t assetID ); + +static uint32_t uarpPlatformUpdateSuperBinaryMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ); + +static uint32_t uarpPlatformUpdatePayloadMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ); + +static uint32_t uarpPlatformUpdatePayloadPayload( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ); + +static uint32_t uarpPlatformUpdateMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer, + fcnUarpPlatformAccessoryMetaDataTLV fMetaDataTLV, + fcnUarpPlatformAccessoryMetaDataComplete fMetaDataComplete ); + +static void uarpPlatformCleanupAssetsForController( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController ); + +static uint32_t uarpPlatformAccessoryAssetSuperBinaryPullHeader( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +static UARPBool uarpPlatformAccessoryShouldRequestMetadata( uint8_t flags ); + +static uint32_t uarpPlatformAccessoryAssetAbandonInternal( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset, + UARPBool notifyController ); + +static uint32_t uarpPlatformDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ); + +static uint32_t uarpPlatformSuperBinaryHeaderDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ); + +static uint32_t uarpPlatformAssetPayloadHeaderDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ); + +static uint32_t uarpPlatformAssetRequestDataContinue( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +static uint32_t uarpPlatformAssetRequestData( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset, + uint8_t requestType, uint32_t relativeOffset, uint32_t lengthNeeded ); + +static void uarpPlatformAssetCleanup( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ); + +static void uarpPlatformAssetRelease( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ); + +static void uarpPlatformAssetOrphan( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ); + +static void uarpPlatformAssetRescind( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +static UARPBool uarpPlatformAssetIsCookieValid( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie ); + +/* MARK: CALLBACK PROTOTYPES */ + +static uint32_t uarpPlatformRequestTransmitMsgBuffer( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t **ppBuffer, uint32_t *pLength ); + +static void uarpPlatformReturnTransmitMsgBuffer( void *pAccessoryDelegate, void *pControllerDelegate, uint8_t *pBuffer ); + +static uint32_t uarpPlatformSendMessage( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer, uint32_t length ); + +static uint32_t uarpPlatformDataTransferPause( void *pAccessoryDelegate, void *pControllerDelegate ); + +static uint32_t uarpPlatformDataTransferResume( void *pAccessoryDelegate, void *pControllerDelegate ); + +static uint32_t uarpPlatformQueryAccessoryInfo( void *pAccessoryDelegate, uint32_t infoType, void *pBuffer, + uint32_t lengthBuffer, uint32_t *pLengthNeeded ); + +static uint32_t uarpPlatformApplyStagedAssets( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t *pFlags ); + +static void uarpPlatformAssetRescinded( void *pAccessoryDelegate, void *pControllerDelegate, + uint16_t assetID ); + +static uint32_t uarpPlatformAssetDataResponse( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t assetID, + uint8_t *pBuffer, uint32_t length, uint32_t offset ); + +static uint32_t uarpPlatformAssetOffered( void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpAssetCoreObj *pAssetCore ); + +/* MARK: CONTROL ROUTINES */ + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryInit( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformOptionsObj *pOptions, + struct uarpPlatformAccessoryCallbacks *pCallbacks, + void *pVendorExtension, + fcnUarpVendorSpecific fVendorSpecific, + void *pDelegate ) +{ + uint32_t status; + struct uarpAccessoryCallbacksObj callbacks; + + /* verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pOptions, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pCallbacks, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pDelegate, exit, status = kUARPStatusInvalidArgument ); + + __UARP_Verify_Action( pCallbacks->fRequestBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fReturnBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fRequestTransmitMsgBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fReturnTransmitMsgBuffer, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fSendMessage, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fDataTransferPause, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fDataTransferResume, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fSuperBinaryOffered, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fDynamicAssetOffered, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetRescinded, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetCorrupt, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetOrphaned, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetReady, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetMetaDataTLV, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fAssetMetaDataComplete, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fPayloadReady, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fPayloadMetaDataTLV, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fPayloadMetaDataComplete, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fPayloadData, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fPayloadDataComplete, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fApplyStagedAssets, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fManufacturerName, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fModelName, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fSerialNumber, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fHardwareVersion, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fActiveFirmwareVersion, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fStagedFirmwareVersion, exit, status = kUARPStatusInvalidFunctionPointer ); + __UARP_Verify_Action( pCallbacks->fLastError, exit, status = kUARPStatusInvalidFunctionPointer ); + + /* clear everything up */ + memset( pAccessory, 0, sizeof( struct uarpPlatformAccessory ) ); + + /* store the delegate */ + pAccessory->callbacks = *pCallbacks; + pAccessory->pDelegate = pDelegate; + pAccessory->pVendorExtension = pVendorExtension; + + /* setup callbacks */ + callbacks.fRequestTransmitMsgBuffer = uarpPlatformRequestTransmitMsgBuffer; + callbacks.fReturnTransmitMsgBuffer = uarpPlatformReturnTransmitMsgBuffer; + callbacks.fSendMessage = uarpPlatformSendMessage; + callbacks.fAccessoryQueryAccessoryInfo = uarpPlatformQueryAccessoryInfo; + callbacks.fAccessoryAssetOffered = uarpPlatformAssetOffered; + callbacks.fAssetRescinded = uarpPlatformAssetRescinded; + callbacks.fAccessoryAssetDataResponse = uarpPlatformAssetDataResponse; + callbacks.fUpdateDataTransferPause = uarpPlatformDataTransferPause; + callbacks.fUpdateDataTransferResume = uarpPlatformDataTransferResume; + callbacks.fApplyStagedAssets = uarpPlatformApplyStagedAssets; + callbacks.fVendorSpecific = fVendorSpecific; + + /* tell the lower edge we are here */ + pAccessory->_options = *pOptions; + + status = uarpAccessoryInit( &(pAccessory->_accessory), &callbacks, (void *)pAccessory ); + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformControllerAdd( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + void *pControllerDelegate ) +{ + uint32_t status; + + /* uarpAccessoryRemoteControllerAdd() needs this set before it is called */ + pController->pDelegate = pControllerDelegate; + + /* tell the lower layer about the controller */ + status = uarpAccessoryRemoteControllerAdd( &(pAccessory->_accessory), + &(pController->_controller), + (void *)pController ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Add Remote UARP Controller %d", + pController->_controller.remoteControllerID ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformControllerRemove( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Remove Remote UARP Controller %d", + pController->_controller.remoteControllerID ); + + /* tell the lower layer we are removing the contoller */ + status = uarpAccessoryRemoteControllerRemove( &(pAccessory->_accessory), + &(pController->_controller) ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + uarpPlatformCleanupAssetsForController( pAccessory, pController ); + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryRecvMessage( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint8_t *pBuffer, uint32_t length ) +{ + uint32_t status; + + /* Verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "RECV %u bytes from Remote UARP Controller %d", + length, pController->_controller.remoteControllerID ); + + /* let the lower layer know we got a message */ + status = uarpAccessoryRecvMessage( &(pAccessory->_accessory), (void *)pController, pBuffer, length ); + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + + uint32_t uarpPlatformAccessoryAssetIsAcceptable( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + UARPBool *pIsAcceptable ) +{ + uint32_t status; + struct UARPVersion activeFwVersion; + struct UARPVersion stagedFwVersion; + UARPVersionComparisonResult compareResult; + + /* assume the asset is acceptable until proven otherwise */ + *pIsAcceptable = kUARPYes; + + /* make sure the offer is a newer version than we are running */ + status = pAccessory->callbacks.fActiveFirmwareVersion( pAccessory->pDelegate, + pAsset->core.assetTag, + &activeFwVersion ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + compareResult = uarpVersionCompare( &activeFwVersion, &(pAsset->core.assetVersion) ); + + if ( compareResult != kUARPVersionComparisonResultIsNewer ) + { + uarpLogInfo( kUARPLoggingCategoryPlatform, "Active Firmware version is newer than the offered asset" ); + + *pIsAcceptable = kUARPNo; + } + __UARP_Require_Action_Quiet( ( *pIsAcceptable == kUARPYes ), exit, status = kUARPStatusSuccess ); + + /* make sure we don't have this version or newer staged */ + status = pAccessory->callbacks.fStagedFirmwareVersion( pAccessory->pDelegate, + pAsset->core.assetTag, + &stagedFwVersion ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + + compareResult = uarpVersionCompare( &stagedFwVersion, &(pAsset->core.assetVersion) ); + + if ( compareResult != kUARPVersionComparisonResultIsNewer ) + { + uarpLogInfo( kUARPLoggingCategoryPlatform, "Staged Firmware version is newer than the offered asset" ); + + *pIsAcceptable = kUARPNo; + } + __UARP_Require_Action_Quiet( ( *pIsAcceptable == kUARPYes ), exit, status = kUARPStatusSuccess ); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + if ( status != kUARPStatusSuccess ) + { + *pIsAcceptable = kUARPNo; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetCookieIsAcceptable( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie, + UARPBool *pIsAcceptable ) +{ + UARPVersionComparisonResult versionResult; + + versionResult = uarpVersionCompare( &(pAsset->core.assetVersion), &(pCookie->assetVersion) ); + + if ( pAsset->core.assetTag != pCookie->assetTag ) + { + *pIsAcceptable = kUARPNo; + } + else if ( versionResult != kUARPVersionComparisonResultIsEqual ) + { + *pIsAcceptable = kUARPNo; + } + else if ( pAsset->core.assetTotalLength != pCookie->assetTotalLength ) + { + *pIsAcceptable = kUARPNo; + } + else if ( pAsset->core.assetNumPayloads != pCookie->assetNumPayloads ) + { + *pIsAcceptable = kUARPNo; + } + else + { + *pIsAcceptable = kUARPYes; + } + + return kUARPStatusSuccess; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetAccept( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + UARPBool isPresent; + uint8_t flags; + uint32_t status; + struct uarpPlatformAsset *pAssetTmp; + + /* verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + /* add to our list, after making sure we aren't already on it. + We could be on it because we are merging / resuming */ + isPresent = kUARPNo; + + for ( pAssetTmp = pAccessory->pAssetList; pAssetTmp; pAssetTmp = pAssetTmp->pNext ) + { + if ( pAssetTmp == pAsset ) + { + isPresent = kUARPYes; + break; + } + } + if ( isPresent == kUARPNo ) + { + pAsset->pNext = pAccessory->pAssetList; + pAccessory->pAssetList = pAsset; + } + + pAsset->pausedByAccessory = kUARPNo; + + /* setup the scratch buffers for this asset, we may be merging an asset that already has a payload window */ + if ( pAsset->lengthScratchBuffer != pAccessory->_options.payloadWindowLength ) + { + pAsset->lengthScratchBuffer = pAccessory->_options.payloadWindowLength; + + if ( pAsset->pScratchBuffer ) + { + pAccessory->callbacks.fReturnBuffer( pAccessory->pDelegate, pAsset->pScratchBuffer ); + pAsset->pScratchBuffer = NULL; + } + } + + if ( pAsset->pScratchBuffer == NULL ) + { + status = pAccessory->callbacks.fRequestBuffer( pAccessory->pDelegate, &(pAsset->pScratchBuffer), + pAsset->lengthScratchBuffer ); + __UARP_Require( ( status == kUARPStatusSuccess ), exit ); + } + + /* read the SuperBinary Header */ + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Flags <%02x>", pAsset->internalFlags ); + uarpLogInfo( kUARPLoggingCategoryPlatform, "Selected Payload %d, Flags <%02x>", + pAsset->selectedPayloadIndex, pAsset->payload.internalFlags ); + + /* determine what we need to do for pulling the asset, this is because of resuming an orphaned asset */ + flags = kUARPAssetHasHeader | kUARPAssetHasPayloadHeader; + + if ( ( pAsset->internalFlags & flags ) == 0 ) + { + status = uarpPlatformAccessoryAssetSuperBinaryPullHeader( pAccessory, pAsset ); + } + else if ( uarpPlatformAccessoryShouldRequestMetadata( pAsset->internalFlags ) == kUARPYes ) + { + status = uarpPlatformAccessoryAssetRequestMetaData( pAccessory, pAsset ); + } + else if ( pAsset->selectedPayloadIndex == kUARPPayloadIndexInvalid ) + { + pAccessory->callbacks.fAssetMetaDataComplete( pAccessory->pDelegate, pAsset->pDelegate ); + + status = kUARPStatusSuccess; + } + else if ( uarpPlatformAccessoryShouldRequestMetadata( pAsset->payload.internalFlags ) == kUARPYes ) + { + pAccessory->callbacks.fPayloadReady( pAccessory->pDelegate, pAsset->pDelegate ); + + status = kUARPStatusSuccess; + } + else + { + status = uarpPlatformAccessoryPayloadRequestData( pAccessory, pAsset ); + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetDeny( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + /* verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pController, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "Deny Asset ID <%u> for Controller <%d>", + pAsset->core.assetID, pController->_controller.remoteControllerID ); + + status = uarpAccessoryAssetDeny( &(pAccessory->_accessory), + (void *)pController, + pAsset->core.assetID ); + if ( status == kUARPStatusSuccess ) + { + pAsset->internalFlags |= kUARPAssetMarkForCleanup; + + pAsset->pDelegate = NULL; + } + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetAbandon( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + status = uarpPlatformAccessoryAssetAbandonInternal( pAccessory, pController, pAsset, kUARPYes ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetRelease( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + status = uarpPlatformAccessoryAssetAbandonInternal( pAccessory, pController, pAsset, kUARPNo ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetRequestMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + if ( pAsset && ( pAsset->sbHdr.superBinaryMetadataLength > 0 ) ) + { + status = uarpPlatformAssetRequestData( pAccessory, pAsset, + kUARPDataRequestTypeSuperBinaryMetadata, + 0, + pAsset->sbHdr.superBinaryMetadataLength ); + } + else + { + status = kUARPStatusNoMetaData; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetSetPayloadIndex( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, int payloadIdx ) +{ + return uarpPlatformAssetSetPayloadIndexWithCookie( pAccessory, pAsset, payloadIdx, NULL ); +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetSetPayloadIndexWithCookie( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, int payloadIdx, + struct uarpPlatformAssetCookie *pCookie ) +{ + uint32_t offset; + uint32_t status; + UARPBool isValidCookie; + + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + __UARP_Require_Action( ( payloadIdx < pAsset->core.assetNumPayloads ), exit, + status = kUARPStatusInvalidArgument ); + + isValidCookie = uarpPlatformAssetIsCookieValid( pAccessory, pAsset, pCookie ); + + if ( isValidCookie ) + { + payloadIdx = pCookie->selectedPayloadIndex; + } + + pAsset->lengthPayloadRecvd = 0; + + /* save off the index and clear the fact that we have the paylaod header */ + pAsset->selectedPayloadIndex = payloadIdx; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Set Active Payload Index <%d>", pAsset->selectedPayloadIndex ); + + pAsset->internalFlags = pAsset->internalFlags & ~kUARPAssetHasPayloadHeader; + pAsset->payload.internalFlags = 0; + + /* determine offset based on selected index payloadIdx */ + offset = pAsset->selectedPayloadIndex * sizeof( struct UARPPayloadHeader ); + + /* call the lower edge */ + status = uarpPlatformAssetRequestData( pAccessory, pAsset, + kUARPDataRequestTypeSuperBinaryPayloadHeader, + offset, + sizeof( struct UARPPayloadHeader ) ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryPayloadRequestMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + if ( pAsset && ( pAsset->payload.plHdr.payloadMetadataLength > 0 ) ) + { + status = uarpPlatformAssetRequestData( pAccessory, pAsset, + kUARPDataRequestTypePayloadMetadata, + 0, + pAsset->payload.plHdr.payloadMetadataLength ); + } + else + { + status = kUARPStatusNoMetaData; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetSetPayloadOffset( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint32_t payloadOffset ) +{ + uint32_t status; + + /* ensure that... + - we have selected a payload + - the offset is within bounds + - there is not an outstanding data request + */ + if ( pAsset == NULL ) + { + status = kUARPStatusInvalidArgument; + } + else if ( pAsset->selectedPayloadIndex == kUARPPayloadIndexInvalid ) + { + status = kUARPStatusInvalidPayload; + } + else if ( payloadOffset >= pAsset->payload.plHdr.payloadLength ) + { + status = kUARPStatusInvalidOffset; + } + else if ( pAsset->dataReq.requestType & kUARPDataRequestTypeOutstanding ) + { + status = kUARPStatusAssetInFlight; + } + else + { + pAsset->lengthPayloadRecvd = payloadOffset; + + status = kUARPStatusSuccess; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryPayloadRequestData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + return uarpPlatformAccessoryPayloadRequestDataWithCookie( pAccessory, pAsset, NULL ); +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryPayloadRequestDataWithCookie( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie ) +{ + UARPBool isValidCookie; + uint32_t length; + uint32_t status; + + /* verifiers */ + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + /* if we have a valid cookie and try to update the payload offset */ + isValidCookie = uarpPlatformAssetIsCookieValid( pAccessory, pAsset, pCookie ); + + if ( isValidCookie == kUARPYes ) + { + status = uarpPlatformAssetSetPayloadOffset( pAccessory, pAsset, pCookie->lengthPayloadRecvd ); + __UARP_Check( status == kUARPStatusSuccess ); + } + + /* payload window unless less is left */ + length = pAsset->payload.plHdr.payloadLength - pAsset->lengthPayloadRecvd; + + if ( length > pAsset->lengthScratchBuffer ) + { + length = pAsset->lengthScratchBuffer; + } + + /* call the lower edge */ + status = uarpPlatformAssetRequestData( pAccessory, pAsset, + kUARPDataRequestTypePayloadPayload, + pAsset->lengthPayloadRecvd, + length ); + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryPayloadRequestDataPause( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + __UARP_Require_Action( ( pAsset->pausedByAccessory == kUARPNo ), exit, status = kUARPStatusSuccess ); + + pAsset->pausedByAccessory = kUARPYes; + + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Transfer paused on Asset ID %u, by accessory request", + pAsset->core.assetID ); + + /* NOTE: Intentionally do not try to pause an outstanding data request. Let it complete. */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryPayloadRequestDataResume( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + __UARP_Require_Action( ( pAsset->pausedByAccessory == kUARPYes ), exit, status = kUARPStatusSuccess ); + + pAsset->pausedByAccessory = kUARPNo; + + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Transfer resumed on Asset ID %u, by accessory request", + pAsset->core.assetID ); + + __UARP_Require_Action( ( pAsset->pController != NULL ), exit, status = kUARPStatusSuccess ); + + if ( ( pAsset->dataReq.requestType & kUARPDataRequestTypeOutstanding ) == 0 ) + { + status = uarpPlatformAccessoryPayloadRequestData( pAccessory, pAsset ); + } + else + { + status = kUARPStatusSuccess; + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetFullyStaged( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + /* verifiers */ + __UARP_Verify_Action( pAccessory, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + __UARP_Require_Action( pAsset->pController, exit, status = kUARPStatusInvalidArgument ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "Staged Asset ID <%u> for Controller <%d>", + pAsset->core.assetID, + pAsset->pController->_controller.remoteControllerID ); + + status = uarpAccessoryAssetStaged( &(pAccessory->_accessory), + pAsset->pController->_controller.pDelegate, + pAsset->core.assetID ); + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessorySuperBinaryMerge( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAssetOrphaned, + struct uarpPlatformAsset *pAssetOffered ) +{ + uint32_t status; + + /* verifiers */ + __UARP_Verify_Action( pAssetOrphaned, exit, status = kUARPStatusInvalidArgument ); + __UARP_Verify_Action( pAssetOffered, exit, status = kUARPStatusInvalidArgument ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Merging Assets <%u> -> <%u>", + pAssetOffered->core.assetID, pAssetOrphaned->core.assetID ); + + pAssetOrphaned->core.assetID = pAssetOffered->core.assetID; + + pAssetOrphaned->dataReq.requestType &= ~kUARPDataRequestTypeOutstanding; + + pAssetOffered->internalFlags |= kUARPAssetMarkForCleanup; + + pAssetOrphaned->pController = pAssetOffered->pController; + pAssetOffered->pController = NULL; + + /* set the delegate for the platform */ + pAssetOrphaned->pDelegate = pAssetOrphaned; + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformAccessorySendMessageComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint8_t *pBuffer ) +{ + if ( pAccessory ) + { + uarpPlatformReturnTransmitMsgBuffer( pAccessory, pController, pBuffer ); + } + + return; +} + +/* MARK: HELPERS */ + +/* -------------------------------------------------------------------------------- */ + +struct uarpPlatformAsset * + uarpPlatformAssetFindByAssetID( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint16_t assetID ) +{ + struct uarpPlatformAsset *pTmp; + struct uarpPlatformAsset *pAsset; + + pAsset = NULL; + + /* look for the remote accessory in the superbinary list */ + for ( pTmp = pAccessory->pAssetList; pTmp; pTmp = pTmp->pNext ) + { + if ( ( pTmp->pController == pController ) && ( pTmp->core.assetID == assetID ) ) + { + pAsset = pTmp; + break; + } + } + + return pAsset; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformUpdateSuperBinaryMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ) +{ + uint32_t status; + + /* mark as having the metadata */ + pAsset->internalFlags |= kUARPAssetHasMetadata; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "SuperBinary MetaData Rx COMPLETE" ); + + status = uarpPlatformUpdateMetaData( pAccessory, pAsset, pBuffer, lengthBuffer, + pAccessory->callbacks.fAssetMetaDataTLV, + pAccessory->callbacks.fAssetMetaDataComplete ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformUpdatePayloadMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ) +{ + uint32_t status; + struct uarpPayloadObj *pPayload; + + /* mark as having the metadata */ + pPayload = &(pAsset->payload); + pPayload->internalFlags |= kUARPAssetHasMetadata; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset <%d> Payload <%c%c%c%c> MetaData Rx COMPLETE", + pAsset->core.assetID, + pPayload->payload4cc[0], pPayload->payload4cc[1], + pPayload->payload4cc[2], pPayload->payload4cc[3] ); + + status = uarpPlatformUpdateMetaData( pAccessory, pAsset, pBuffer, lengthBuffer, + pAccessory->callbacks.fPayloadMetaDataTLV, + pAccessory->callbacks.fPayloadMetaDataComplete ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformUpdatePayloadPayload( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer ) +{ + uint32_t status; + uint32_t dfu_status; + struct uarpPayloadObj *pPayload; + struct uarpPlatformAssetCookie cookie; + + /* need to update what was coming from controller */ + pPayload = &(pAsset->payload); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Payload <%c%c%c%c> Payload Rx Window Complete %u bytes from offset %u", + pPayload->payload4cc[0], pPayload->payload4cc[1], + pPayload->payload4cc[2], pPayload->payload4cc[3], + lengthBuffer, pAsset->lengthPayloadRecvd ); + + cookie.assetTag = pAsset->core.assetTag; + cookie.assetVersion = pAsset->core.assetVersion; + cookie.assetTotalLength = pAsset->core.assetTotalLength; + cookie.assetNumPayloads = pAsset->core.assetNumPayloads; + cookie.selectedPayloadIndex = pAsset->selectedPayloadIndex; + cookie.lengthPayloadRecvd = pAsset->lengthPayloadRecvd; + + pAccessory->callbacks.fPayloadData( pAccessory->pDelegate, pAsset->pDelegate, pBuffer, lengthBuffer, + pAsset->lengthPayloadRecvd, (void *)&cookie, sizeof( cookie ) ); + + dfu_status = dfu_handle_uarp_payload(pBuffer, lengthBuffer, pAsset->lengthPayloadRecvd); + + if(dfu_status == kUARPStatusSuccess) + { + pAsset->lengthPayloadRecvd += lengthBuffer; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Payload <%c%c%c%c> Payload RX %u bytes of %u", + pPayload->payload4cc[0], pPayload->payload4cc[1], + pPayload->payload4cc[2], pPayload->payload4cc[3], + pAsset->lengthPayloadRecvd, pPayload->plHdr.payloadLength ); + } + else if(dfu_status == kUARPStatusInvalidPayload) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Asset corrupt"); + + status = uarpAccessoryAssetCorrupt( &(pAccessory->_accessory), pAsset->pController->_controller.pDelegate, + pAsset->core.assetID ); + + pAccessory->callbacks.fAssetCorrupt( pAccessory->pDelegate, pAsset->pDelegate ); + + return status; + } + else if(dfu_status == kUARPStatusRequestResendPayload) + { + //Todo: limit of resend times + pAsset->lengthPayloadRecvd = get_resend_offset(); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Payload <%c%c%c%c> resend Payload RX %u bytes of %u", + pPayload->payload4cc[0], pPayload->payload4cc[1], + pPayload->payload4cc[2], pPayload->payload4cc[3], + pAsset->lengthPayloadRecvd, pPayload->plHdr.payloadLength ); + } + + + /* either pull the next window or indicate this is completed */ + if ( pAsset->lengthPayloadRecvd == pPayload->plHdr.payloadLength ) + { + pPayload->internalFlags |= kUARPAssetHasPayload; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Payload <%c%c%c%c> Payload Rx COMPLETE", + pPayload->payload4cc[0], pPayload->payload4cc[1], + pPayload->payload4cc[2], pPayload->payload4cc[3] ); + + pAccessory->callbacks.fPayloadDataComplete( pAccessory->pDelegate, pAsset->pDelegate ); + + status = kUARPStatusSuccess; + } + else if ( pAsset->pausedByAccessory == kUARPNo ) + { + status = uarpPlatformAccessoryPayloadRequestData( pAccessory, pAsset ); + } + else + { + status = kUARPStatusSuccess; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformCleanupAssetsForController( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController ) +{ + struct uarpPlatformAsset *pAssets; + struct uarpPlatformAsset *pTmpAsset; + + /* run through the assets, orphaning superbinaries from this controller. */ + pAssets = pAccessory->pAssetList; + pAccessory->pAssetList = NULL; + + while ( pAssets ) + { + pTmpAsset = pAssets; + pAssets = pAssets->pNext; + + /* different controller and we can just continue */ + if ( pTmpAsset->pController != pController ) + { + pTmpAsset->pNext = pAccessory->pAssetList; + pAccessory->pAssetList = pTmpAsset; + continue; + } + + /* If we're a dynamic asset, we need to be released */ + if ( uarpAssetIsDynamicAsset( &pTmpAsset->core ) ) + { + pTmpAsset->internalFlags |= kUARPAssetMarkForCleanup; + } + + if ( pTmpAsset->internalFlags & kUARPAssetMarkForCleanup ) + { + uarpPlatformAssetRelease( pAccessory, pTmpAsset ); + + uarpPlatformAssetCleanup( pAccessory, pTmpAsset ); + + continue; + } + + /* if we're a superbinary, let the upper layer know we were orphaned and keep it around */ + uarpPlatformAssetOrphan( pAccessory, pTmpAsset ); + + pTmpAsset->pNext = pAccessory->pAssetList; + pAccessory->pAssetList = pTmpAsset; + } + + return; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformCleanupAssets( struct uarpPlatformAccessory *pAccessory ) +{ + uarpPlatformCleanupAssetsForController( pAccessory, NULL ); + + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformUpdateMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + void *pBuffer, uint32_t lengthBuffer, + fcnUarpPlatformAccessoryMetaDataTLV fMetaDataTLV, + fcnUarpPlatformAccessoryMetaDataComplete fMetaDataComplete ) +{ + uint8_t *pTmp; + uint32_t tlvType; + uint32_t tlvLength; + uint32_t status; + uint32_t remainingLength; + struct UARPTLVHeader *pTlv; + + /* mark as having the metadata */ + pAsset->internalFlags |= kUARPAssetHasMetadata; + + /* iterate */ + pTmp = pBuffer; + remainingLength = lengthBuffer; + + while ( remainingLength >= sizeof( struct UARPTLVHeader ) ) + { + pTlv = (struct UARPTLVHeader *)pTmp; + + tlvType = uarpNtohl( pTlv->tlvType ); + tlvLength = uarpNtohl( pTlv->tlvLength ); + + pTmp += sizeof( struct UARPTLVHeader ); + remainingLength -= sizeof( struct UARPTLVHeader ); + + __UARP_Require_Action( ( remainingLength >= tlvLength ), exit, status = kUARPStatusMetaDataCorrupt ); + + fMetaDataTLV( pAccessory->pDelegate, pAsset->pDelegate, tlvType, tlvLength, pTmp ); + + pTmp += tlvLength; + remainingLength -= tlvLength; + } + + fMetaDataComplete( pAccessory->pDelegate, pAsset->pDelegate ); + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetSuperBinaryPullHeader( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + + /* verifiers */ + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + + /* call the lower edge */ + status = uarpPlatformAssetRequestData( pAccessory, pAsset, + kUARPDataRequestTypeSuperBinaryHeader, + 0, + sizeof( struct UARPSuperBinaryHeader ) ); + +__UARP_Verify_exit /* This resolves "__UARP_Verify_exit" if you have chosen to compile in __UARP_Verify_Action */ + return status; +} + +/* -------------------------------------------------------------------------------- */ + +UARPBool uarpPlatformAccessoryShouldRequestMetadata( uint8_t flags ) +{ + UARPBool status; + + if ( ( flags & kUARPAssetNeedsMetadata ) && ( ( flags & kUARPAssetHasMetadata ) == 0 ) ) + { + status = kUARPYes; + } + else + { + status = kUARPNo; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAccessoryAssetAbandonInternal( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset, + UARPBool notifyController ) +{ + uint32_t status; + + if ( pAsset ) + { + uarpLogDebug( kUARPLoggingCategoryPlatform, "Abandon Asset ID <%u> for Controller <%d>", + pAsset->core.assetID, + pController ? pController->_controller.remoteControllerID : -1 ); + + if ( notifyController == kUARPYes ) + { + status = uarpAccessoryAssetAbandon( &(pAccessory->_accessory), + pController, + pAsset->core.assetID ); + } + else + { + status = kUARPStatusSuccess; + } + + pAsset->dataReq.requestType &= ~kUARPDataRequestTypeOutstanding; + + pAsset->internalFlags |= kUARPAssetMarkForCleanup; + + pAsset->pController = NULL; + } + else + { + status = kUARPStatusSuccess; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformSuperBinaryHeaderDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ) +{ + uint32_t status; + struct UARPSuperBinaryHeader *pSbHdr; + + /* alias the request buffer and superbinary header */ + pSbHdr = (struct UARPSuperBinaryHeader *)pBuffer; + + pAsset->sbHdr.superBinaryFormatVersion = uarpNtohl( pSbHdr->superBinaryFormatVersion ); + pAsset->sbHdr.superBinaryHeaderLength = uarpNtohl( pSbHdr->superBinaryHeaderLength ); + pAsset->sbHdr.superBinaryLength = uarpNtohl( pSbHdr->superBinaryLength ); + + uarpVersionEndianSwap( &(pSbHdr->superBinaryVersion), &(pAsset->sbHdr.superBinaryVersion) ); + + pAsset->sbHdr.superBinaryMetadataOffset = uarpNtohl( pSbHdr->superBinaryMetadataOffset ); + pAsset->sbHdr.superBinaryMetadataLength = uarpNtohl( pSbHdr->superBinaryMetadataLength ); + pAsset->sbHdr.payloadHeadersOffset = uarpNtohl( pSbHdr->payloadHeadersOffset ); + pAsset->sbHdr.payloadHeadersLength = uarpNtohl( pSbHdr->payloadHeadersLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Offered (asset id %u)", + pAsset->core.assetID ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Format Version %08x", + pAsset->sbHdr.superBinaryFormatVersion ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Header Length %u", + pAsset->sbHdr.superBinaryHeaderLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Length %u", + pAsset->sbHdr.superBinaryLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Version (%u.%u.%u.%u)", + pAsset->sbHdr.superBinaryVersion.major, + pAsset->sbHdr.superBinaryVersion.minor, + pAsset->sbHdr.superBinaryVersion.release, + pAsset->sbHdr.superBinaryVersion.build ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Metadata Offset %u", + pAsset->sbHdr.superBinaryMetadataOffset ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Metadata Length %u", + pAsset->sbHdr.superBinaryMetadataLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Headers Offset %u", + pAsset->sbHdr.payloadHeadersOffset ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Headers Length %u", + pAsset->sbHdr.payloadHeadersLength ); + + total_payload_index = pAsset->sbHdr.payloadHeadersLength / 40 - 1; + + /* Verify lengths and offset */ + if ( pAsset->sbHdr.superBinaryFormatVersion != kUARPSuperBinaryFormatVersion ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else if ( pAsset->sbHdr.superBinaryHeaderLength != sizeof( struct UARPSuperBinaryHeader ) ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else if ( ( pAsset->sbHdr.superBinaryMetadataOffset + pAsset->sbHdr.superBinaryMetadataLength ) > + pAsset->core.assetTotalLength ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else if ( ( pAsset->sbHdr.payloadHeadersOffset + pAsset->sbHdr.payloadHeadersLength ) > + pAsset->core.assetTotalLength ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else + { + status = kUARPStatusSuccess; + } + + if ( status != kUARPStatusSuccess ) + { + status = uarpAccessoryAssetCorrupt( &(pAccessory->_accessory), pAsset->pController->_controller.pDelegate, + pAsset->core.assetID ); + + pAccessory->callbacks.fAssetCorrupt( pAccessory->pDelegate, pAsset->pDelegate ); + } + else + { + if ( pAsset->sbHdr.superBinaryMetadataLength > 0 ) + { + pAsset->internalFlags |= kUARPAssetNeedsMetadata; + } + + pAsset->internalFlags |= kUARPAssetHasHeader; + + status = uarpPlatformDataRequestComplete( pAccessory, pAsset, reqType, payloadTag, 0, NULL, 0 ); + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetPayloadHeaderDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t * pBuffer, uint32_t length ) +{ + uint32_t status; + struct UARPPayloadHeader *pPlHdr; + + /* TODO: double check reqType */ + + /* alias the request buffer and superbinary header */ + pPlHdr = (struct UARPPayloadHeader *)pBuffer; + + pAsset->payload.plHdr.payloadHeaderLength = uarpNtohl( pPlHdr->payloadHeaderLength ); + pAsset->payload.plHdr.payloadTag = pPlHdr->payloadTag; /* no endian intentionally */ + + uarpVersionEndianSwap( &(pPlHdr->payloadVersion), &(pAsset->payload.plHdr.payloadVersion) ); + + pAsset->payload.plHdr.payloadMetadataOffset = uarpNtohl( pPlHdr->payloadMetadataOffset ); + pAsset->payload.plHdr.payloadMetadataLength = uarpNtohl( pPlHdr->payloadMetadataLength ); + pAsset->payload.plHdr.payloadOffset = uarpNtohl( pPlHdr->payloadOffset ); + pAsset->payload.plHdr.payloadLength = uarpNtohl( pPlHdr->payloadLength ); + + pAsset->payload.internalFlags |= kUARPAssetHasPayloadHeader; + + if ( pAsset->payload.plHdr.payloadMetadataLength > 0 ) + { + pAsset->payload.internalFlags |= kUARPAssetNeedsMetadata; + } + + uarpPayloadTagUnpack( pAsset->payload.plHdr.payloadTag, pAsset->payload.payload4cc ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Offered (asset id %u), Payload %d", + pAsset->core.assetID, pAsset->selectedPayloadIndex ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Header Length %u", + pAsset->payload.plHdr.payloadHeaderLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Tag 0x%08x <%c%c%c%c>", + pAsset->payload.plHdr.payloadTag, + pAsset->payload.payload4cc[0], + pAsset->payload.payload4cc[1], + pAsset->payload.payload4cc[2], + pAsset->payload.payload4cc[3]); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Version (%u.%u.%u.%u)", + pAsset->payload.plHdr.payloadVersion.major, + pAsset->payload.plHdr.payloadVersion.minor, + pAsset->payload.plHdr.payloadVersion.release, + pAsset->payload.plHdr.payloadVersion.build ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Metadata Offset %u", + pAsset->payload.plHdr.payloadMetadataOffset ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Metadata Length %u", + pAsset->payload.plHdr.payloadMetadataLength ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Offset %u", + pAsset->payload.plHdr.payloadOffset ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, "- Payload Length %u", + pAsset->payload.plHdr.payloadLength ); + + /* Verify lengths and offset */ + if ( ( pAsset->payload.plHdr.payloadMetadataOffset + pAsset->payload.plHdr.payloadMetadataLength ) > + pAsset->core.assetTotalLength ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else if ( ( pAsset->payload.plHdr.payloadOffset + pAsset->payload.plHdr.payloadLength ) > + pAsset->core.assetTotalLength ) + { + status = kUARPStatusInvalidSuperBinaryHeader; + } + else + { + status = kUARPStatusSuccess; + } + + if ( status != kUARPStatusSuccess ) + { + status = uarpAccessoryAssetCorrupt( &(pAccessory->_accessory), pAsset->pController->_controller.pDelegate, + pAsset->core.assetID ); + + pAccessory->callbacks.fAssetCorrupt( pAccessory->pDelegate, pAsset->pDelegate ); + } + else + { + pAsset->internalFlags |= kUARPAssetHasPayloadHeader; + + status = uarpPlatformDataRequestComplete( pAccessory, pAsset, reqType, payloadTag, 0, NULL, 0 ); + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetRequestDataContinue( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + uint32_t status; + uint32_t bytesToRequest; + + /* TODO: make quiet */ + __UARP_Require_Action( ( pAsset->pausedByAccessory == kUARPNo ), exit, status = kUARPStatusDataTransferPaused ); + __UARP_Require_Action( ( pAsset->dataReq.bytesRemaining > 0 ), exit, status = kUARPStatusAssetNoBytesRemaining ); + + /* adjust bytes to request */ + bytesToRequest = pAsset->dataReq.bytesRemaining; + + if ( bytesToRequest > pAccessory->_options.maxRxPayloadLength ) + { + bytesToRequest = pAccessory->_options.maxRxPayloadLength; + } + + uarpLogInfo( kUARPLoggingCategoryPlatform, "REQ BYTES - Asset <%u> <%c%c%c%c> Request Type <0x%x> ", + pAsset->core.assetID, + pAsset->payload.payload4cc[0] ? pAsset->payload.payload4cc[0] : '0', + pAsset->payload.payload4cc[1] ? pAsset->payload.payload4cc[1] : '0', + pAsset->payload.payload4cc[2] ? pAsset->payload.payload4cc[2] : '0', + pAsset->payload.payload4cc[3] ? pAsset->payload.payload4cc[3] : '0', + pAsset->dataReq.requestType); + uarpLogInfo( kUARPLoggingCategoryPlatform, + "Relative Offset <%u> Absolute Offset <%u> Current Offset <%u> ", + pAsset->dataReq.relativeOffset, + pAsset->dataReq.absoluteOffset, + pAsset->dataReq.currentOffset); + uarpLogInfo( kUARPLoggingCategoryPlatform, + "Bytes Requested <%u> Bytes Responded <%u> Bytes Remaining <%u> Bytes to Request <%u>", + pAsset->dataReq.bytesRequested, + pAsset->dataReq.bytesResponded, + pAsset->dataReq.bytesRemaining, + bytesToRequest ); + + status = uarpAccessoryAssetRequestData( (void *)&(pAccessory->_accessory), + (void *)pController, + pAsset->core.assetID, + pAsset->dataReq.currentOffset, + bytesToRequest ); + +__UARP_Verify_exit + /* TODO: is this appropriate here, given the require macros?? */ + if ( status == kUARPStatusSuccess ) + { + pAsset->dataReq.requestType |= kUARPDataRequestTypeOutstanding; + } + else if ( status == kUARPStatusDataTransferPaused ) + { + status = kUARPStatusSuccess; + } + else if ( status == kUARPStatusAssetNoBytesRemaining ) + { + status = kUARPStatusSuccess; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ +/* pAsset will be released when returning from this routine */ +void uarpPlatformAssetCleanup( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ) +{ + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset cleaned up (asset id %u)", + pAsset->core.assetID ); + + if ( pAsset->pScratchBuffer ) + { + pAccessory->callbacks.fReturnBuffer( pAccessory->pDelegate, (uint8_t *)pAsset->pScratchBuffer ); + } + + pAccessory->callbacks.fReturnBuffer( pAccessory->pDelegate, (uint8_t *)pAsset ); + + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetOffered( void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpAssetCoreObj *pAssetCore ) +{ + uint32_t status; + struct uarpPlatformAsset *pAsset; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + /* initializers */ + pAsset = NULL; + + /* alias our context pointer */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + status = pAccessory->callbacks.fRequestBuffer( pAccessory->pDelegate, (uint8_t **)&pAsset, + sizeof( struct uarpPlatformAsset ) ); + __UARP_Require( status == kUARPStatusSuccess, exit ); + + pAsset->pController = pController; + + pAsset->core = *pAssetCore; + + pAsset->selectedPayloadIndex = kUARPPayloadIndexInvalid; + + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Offered from UARP Controller %d ", + pController->_controller.remoteControllerID, + pAsset->core.assetID ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "- Version <%u.%u.%u.%u>", + pAsset->core.assetVersion.major, + pAsset->core.assetVersion.minor, + pAsset->core.assetVersion.release, + pAsset->core.assetVersion.build ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "- Flags <0x%08x>", pAsset->core.assetFlags ); + + uarpLogDebug( kUARPLoggingCategoryPlatform, "- Tag <0x%08x>", pAsset->core.assetTag ); + + /* put this on the right asset list and indicate to the upper layer */ + pAsset->pNext = pAccessory->pAssetList; + pAccessory->pAssetList = pAsset; + + /* Tell the upper layer about this asset being offered */ + if ( uarpAssetIsSuperBinary( &(pAsset->core) ) ) + { + pAccessory->callbacks.fSuperBinaryOffered( pAccessory->pDelegate, pController->pDelegate, pAsset ); + + status = kUARPStatusSuccess; + } + else if ( uarpAssetIsDynamicAsset( &(pAsset->core) ) ) + { + pAccessory->callbacks.fDynamicAssetOffered( pAccessory->pDelegate, pController->pDelegate, pAsset ); + + status = kUARPStatusSuccess; + } + else + { + status = kUARPStatusInvalidAssetType; + } + +__UARP_Verify_exit + if ( status == kUARPStatusSuccess ) + { + uarpPlatformCleanupAssetsForController( pAccessory, NULL ); + } + /* TODO: if failed, free asset and payloads */ + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetDataResponse( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t assetID, + uint8_t *pBuffer, uint32_t length, uint32_t offset ) +{ + uint8_t *pResponseBuffer; + uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength]; + uint32_t status; + struct uarpPlatformAsset *pAsset; + struct uarpDataRequestObj *pRequest; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + fcnUarpPlatformAssetDataRequestComplete fRequestComplete; + + /* alias our context pointers */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + pAsset = uarpPlatformAssetFindByAssetID( pAccessory, pController, assetID ); + __UARP_Require_Action( pAsset, exit, status = kUARPStatusNoResources ); + + /* if the asset has been abandoned or rescinded, we should ignore this response */ + if ( pAsset->internalFlags & kUARPAssetMarkForCleanup ) + { + pAsset = NULL; + } + __UARP_Require_Action( pAsset, exit, status = kUARPStatusUnknownAsset ); + + /* copy into the data response buffer, if everything checks out */ + pRequest = &(pAsset->dataReq); + __UARP_Require_Action( ( pRequest->currentOffset == offset ), exit, status = kUARPStatusMismatchDataOffset ); + __UARP_Require_Action( ( pRequest->bytesRequested >= length ), exit, + status = kUARPStatusInvalidDataResponseLength ); + + /* pRequest->requestType | 0x80 is always true*/ +// __UARP_Require_Action( ( pRequest->requestType | kUARPDataRequestTypeOutstanding ), exit, +// status = kUARPStatusInvalidDataResponse ); + + uarpPayloadTagUnpack( pRequest->payloadTag, payload4cc ); + + pResponseBuffer = pRequest->bytes; + pResponseBuffer += pRequest->bytesResponded; + + /* copy buffers */ + memcpy( pResponseBuffer, pBuffer, length ); + + pRequest->bytesResponded += length; + + pRequest->requestType = pRequest->requestType & ~kUARPDataRequestTypeOutstanding; + + /* some requests are internal to the Firmware Updater, so we will hijack the completion routine */ + if ( pRequest->requestType == kUARPDataRequestTypeSuperBinaryHeader ) + { + fRequestComplete = uarpPlatformSuperBinaryHeaderDataRequestComplete; + } + else if ( pRequest->requestType == kUARPDataRequestTypeSuperBinaryPayloadHeader ) + { + fRequestComplete = uarpPlatformAssetPayloadHeaderDataRequestComplete; + } + else + { + fRequestComplete = uarpPlatformDataRequestComplete; + } + + /* inform the delegate when the request is full */ + /* TODO: Handle when we simply won't fill the requested buffer; or does bytesRequested handle that? */ + pRequest->bytesRemaining = pRequest->bytesRequested - pRequest->bytesResponded; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "RSP BYTES - Asset <%u> <%c%c%c%c> Request Type <0x%x> ", + pAsset->core.assetID, + payload4cc[0], payload4cc[1], payload4cc[2], payload4cc[3], pRequest->requestType); + + uarpLogInfo( kUARPLoggingCategoryPlatform, + "Relative Offset <%u> Absolute Offset <%u> Current Offset <%u> ", + pRequest->relativeOffset, pRequest->absoluteOffset, pRequest->currentOffset ); + + uarpLogInfo( kUARPLoggingCategoryPlatform, + "Bytes Requested <%u> Bytes Responded <%u> Total Bytes Responded <%u> Bytes Remaining <%u> ", + pRequest->bytesRequested, length, pRequest->bytesResponded, pRequest->bytesRemaining ); + + + pRequest->currentOffset = pRequest->absoluteOffset + pRequest->bytesResponded; + + /* TODO: do we want to hold onto a full payload if paused, until resume? */ + if ( pRequest->bytesResponded == pRequest->bytesRequested ) + { + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Data Response from Controller ID <%d> - All Bytes Requested", + pController->_controller.remoteControllerID ); + + status = fRequestComplete( pAccessory, pAsset, pRequest->requestType, + pRequest->payloadTag, pRequest->relativeOffset, + pRequest->bytes, pRequest->bytesResponded ); + } + else if ( pController->_controller.dataTransferAllowed == kUARPNo ) + { + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Data Response from Controller ID <%d>" + "Transfer Paused by controller, wait for resume", + pController->_controller.remoteControllerID ); + + status = kUARPStatusSuccess; + } + else if ( pAsset->pausedByAccessory == kUARPYes ) + { + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Data Response from Controller ID <%d>" + "Transfer Paused by accessory, wait for resume", + pController->_controller.remoteControllerID ); + + status = kUARPStatusSuccess; + } + else + { + status = uarpPlatformAssetRequestDataContinue( pAccessory, pAsset->pController, pAsset ); + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformAssetRequestData( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset, + uint8_t requestType, uint32_t relativeOffset, uint32_t lengthNeeded ) + +{ + uint32_t status; + uint32_t tmp32; + uint32_t startOffset; + uint32_t maxLength; + struct uarpPayloadObj *pPayload; + struct uarpDataRequestObj *pRequest; + + __UARP_Verify_Action( pAsset, exit, status = kUARPStatusInvalidArgument ); + __UARP_Require_Action( pAsset->pScratchBuffer, exit, status = kUARPStatusNoResources ); + __UARP_Require_Action( ( pAsset->lengthScratchBuffer >= lengthNeeded ), exit, + status = kUARPStatusNoResources ); + + pRequest = &(pAsset->dataReq); + __UARP_Require_Action( ( ( pRequest->requestType & kUARPDataRequestTypeOutstanding ) == 0 ), exit, + status = kUARPStatusAssetInFlight ); + + pRequest->requestType = requestType; + pRequest->relativeOffset = relativeOffset; + pRequest->bytesRequested = lengthNeeded; + pRequest->bytes = pAsset->pScratchBuffer; + + pRequest->bytesResponded = 0; + + /* Only one outstanding request per asset */ + if ( pRequest->requestType == kUARPDataRequestTypeSuperBinaryHeader ) + { + startOffset = 0; + maxLength = sizeof( struct UARPSuperBinaryHeader ); + } + else if ( pRequest->requestType == kUARPDataRequestTypeSuperBinaryPayloadHeader ) + { + startOffset = pAsset->sbHdr.payloadHeadersOffset; + maxLength = pAsset->sbHdr.payloadHeadersLength; + } + else if ( pRequest->requestType == kUARPDataRequestTypeSuperBinaryMetadata ) + { + startOffset = pAsset->sbHdr.superBinaryMetadataOffset; + maxLength = pAsset->sbHdr.superBinaryMetadataLength; + } + else if ( pRequest->requestType == kUARPDataRequestTypePayloadMetadata ) + { + pPayload = &(pAsset->payload); + + pRequest->payloadTag = pAsset->payload.plHdr.payloadTag; + + startOffset = pPayload->plHdr.payloadMetadataOffset; + maxLength = pPayload->plHdr.payloadMetadataLength; + } + else if ( pRequest->requestType == kUARPDataRequestTypePayloadPayload ) + { + pPayload = &(pAsset->payload); + + pRequest->payloadTag = pAsset->payload.plHdr.payloadTag; + + startOffset = pPayload->plHdr.payloadOffset; + maxLength = pPayload->plHdr.payloadLength; + } + else + { + startOffset = 0; + maxLength = 0; + } + + /* validate the request */ + __UARP_Require_Action( ( maxLength > 0 ), exit, status = kUARPStatusInvalidDataRequestLength ); + __UARP_Require_Action( ( pRequest->bytesRequested <= maxLength ), exit, + status = kUARPStatusInvalidDataRequestLength ); + + tmp32 = pRequest->relativeOffset + pRequest->bytesRequested; + __UARP_Require_Action( ( tmp32 <= maxLength ), exit, status = kUARPStatusInvalidDataRequestOffset ); + + /* make the call */ + pRequest->absoluteOffset = startOffset + pRequest->relativeOffset; + pRequest->currentOffset = pRequest->absoluteOffset + pRequest->bytesResponded; + pRequest->bytesRemaining = pRequest->bytesRequested - pRequest->bytesResponded; + + status = uarpPlatformAssetRequestDataContinue( pAccessory, pAsset->pController, pAsset ); + +__UARP_Verify_exit + return status; +} + +/* MARK: CALLBACKS */ + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformRequestTransmitMsgBuffer( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t **ppBuffer, uint32_t *pLength ) +{ + uint32_t status; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + status = pAccessory->callbacks.fRequestTransmitMsgBuffer( pAccessory->pDelegate, pController->pDelegate, + ppBuffer, pLength ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformReturnTransmitMsgBuffer( void *pAccessoryDelegate, void *pControllerDelegate, uint8_t *pBuffer ) +{ + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + pAccessory->callbacks.fReturnTransmitMsgBuffer( pAccessory->pDelegate, pController->pDelegate, pBuffer ); + + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformSendMessage( void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer, uint32_t length ) +{ + uint32_t status; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + /* alias delegates */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + uarpLogDebug( kUARPLoggingCategoryPlatform, "SEND %u bytes to Remote UARP Controller %d", + length, pController->_controller.remoteControllerID ); + + status = pAccessory->callbacks.fSendMessage( pAccessory->pDelegate, pController->pDelegate, pBuffer, length ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformDataTransferPause( void *pAccessoryDelegate, void *pControllerDelegate ) +{ + uint32_t status; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + /* alias delegates */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Transfers PAUSED from Remote Controller %u", + pController->_controller.remoteControllerID ); + + status = pAccessory->callbacks.fDataTransferPause( pAccessory->pDelegate, pController->pDelegate ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformDataTransferResume( void *pAccessoryDelegate, void *pControllerDelegate ) +{ + uint32_t status; + struct uarpPlatformAsset *pAsset; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + /* alias delegates */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Transfers RESUMED from Remote Controller %u", + pController->_controller.remoteControllerID ); + + /* look through the assets related to this controller and see if there are any outstanding data requests + if there are, it was likely dropped by the controller so we need to re-request */ + for ( pAsset = pAccessory->pAssetList; pAsset != NULL; pAsset = pAsset->pNext ) + { + if ( pAsset->pController != pController ) + { + continue; + } + + status = uarpPlatformAssetRequestDataContinue( pAccessory, pController, pAsset ); + __UARP_Check( status == kUARPStatusSuccess ); + } + + status = pAccessory->callbacks.fDataTransferResume( pAccessory->pDelegate, pController->pDelegate ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformDataRequestComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint8_t reqType, uint32_t payloadTag, + uint32_t offset, uint8_t *pBuffer, uint32_t length ) +{ + uint32_t status; + + uarpLogInfo( kUARPLoggingCategoryPlatform, "Data Request Complete; %u bytes at offset %u", length, offset ); + + if ( reqType == kUARPDataRequestTypeSuperBinaryHeader ) + { + pAccessory->callbacks.fAssetReady( pAccessory->pDelegate, pAsset->pDelegate ); + + status = kUARPStatusSuccess; + } + else if ( reqType == kUARPDataRequestTypeSuperBinaryMetadata ) + { + status = uarpPlatformUpdateSuperBinaryMetaData( pAccessory, pAsset, pBuffer, length ); + } + else if ( reqType == kUARPDataRequestTypeSuperBinaryPayloadHeader ) + { + pAccessory->callbacks.fPayloadReady( pAccessory->pDelegate, pAsset->pDelegate ); + + status = kUARPStatusSuccess; + } + else if ( reqType == kUARPDataRequestTypePayloadMetadata ) + { + status = uarpPlatformUpdatePayloadMetaData( pAccessory, pAsset, pBuffer, length ); + } + else if ( reqType == kUARPDataRequestTypePayloadPayload ) + { + status = uarpPlatformUpdatePayloadPayload( pAccessory, pAsset, pBuffer, length ); + } + else + { + status = kUARPStatusInvalidDataRequestType; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformQueryAccessoryInfo( void *pAccessoryDelegate, uint32_t infoType, void *pBuffer, + uint32_t lengthBuffer, uint32_t *pLengthNeeded ) +{ + uint32_t status; + struct UARPVersion *pVersion; + struct UARPLastErrorAction *pLastAction; + struct uarpPlatformAccessory *pAccessory; + + /* alias delegates */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + + *pLengthNeeded = lengthBuffer; + + switch ( infoType ) + { + case kUARPTLVAccessoryInformationManufacturerName: + + status = pAccessory->callbacks.fManufacturerName( pAccessory->pDelegate, pBuffer, pLengthNeeded ); + + break; + + case kUARPTLVAccessoryInformationModelName: + + status = pAccessory->callbacks.fModelName( pAccessory->pDelegate, pBuffer, pLengthNeeded ); + + break; + + case kUARPTLVAccessoryInformationHardwareVersion: + + status = pAccessory->callbacks.fHardwareVersion( pAccessory->pDelegate, pBuffer, pLengthNeeded ); + + break; + + case kUARPTLVAccessoryInformationSerialNumber: + + status = pAccessory->callbacks.fSerialNumber( pAccessory->pDelegate, pBuffer, pLengthNeeded ); + + break; + + case kUARPTLVAccessoryInformationFirmwareVersion: + case kUARPTLVAccessoryInformationStagedFirmwareVersion: + + *pLengthNeeded = sizeof( struct UARPVersion ); + if ( *pLengthNeeded > lengthBuffer ) + { + status = kUARPStatusNoResources; + break; + } + + pVersion = (struct UARPVersion *)pBuffer; + + if ( infoType == kUARPTLVAccessoryInformationFirmwareVersion ) + { + status = pAccessory->callbacks.fActiveFirmwareVersion( pAccessory->pDelegate, 0, pVersion ); + } + else + { + status = pAccessory->callbacks.fStagedFirmwareVersion( pAccessory->pDelegate, 0, pVersion ); + } + + pVersion->major = uarpHtonl( pVersion->major ); + pVersion->minor = uarpHtonl( pVersion->minor ); + pVersion->release = uarpHtonl( pVersion->release ); + pVersion->build = uarpHtonl( pVersion->build ); + + break; + + case kUARPTLVAccessoryInformationLastError: + + *pLengthNeeded = (uint32_t)sizeof( struct UARPLastErrorAction ); + if ( *pLengthNeeded > lengthBuffer ) + { + status = kUARPStatusNoResources; + break; + } + + pLastAction = (struct UARPLastErrorAction *)pBuffer; + + status = pAccessory->callbacks.fLastError( pAccessory->pDelegate, pLastAction ); + + pLastAction->lastAction = uarpHtonl( pLastAction->lastAction ); + pLastAction->lastError = uarpHtonl( pLastAction->lastError ); + + status = kUARPStatusSuccess; + break; + + default: + *pLengthNeeded = 0; + status = kUARPStatusUnknownInformationOption; + break; + } + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPlatformApplyStagedAssets( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t *pFlags ) +{ + uint32_t status; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + /* alias delegates */ + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + status = pAccessory->callbacks.fApplyStagedAssets( pAccessory->pDelegate, pController->pDelegate, pFlags ); + + return status; +} + +/* -------------------------------------------------------------------------------- */ +/* This routine is here in case we add a callback to the upper layer */ +void uarpPlatformAssetRelease( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ) +{ + uarpLogInfo( kUARPLoggingCategoryPlatform, "Asset Released" ); + + return; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformAssetOrphan( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset ) +{ + uarpLogInfo( kUARPLoggingCategoryPlatform, "Orphan %s Asset <%u>", + uarpAssetIsSuperBinary( &pAsset->core ) ? "SuperBinary" : "Dynamic ", + pAsset->core.assetID ); + + pAsset->pController = NULL; + + pAccessory->callbacks.fAssetOrphaned( pAccessory->pDelegate, pAsset->pDelegate ); + + return; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformAssetRescinded( void *pAccessoryDelegate, void *pControllerDelegate, uint16_t assetID ) +{ + struct uarpPlatformAsset *pAsset; + struct uarpPlatformAccessory *pAccessory; + struct uarpPlatformController *pController; + + pAccessory = (struct uarpPlatformAccessory *)pAccessoryDelegate; + pController = (struct uarpPlatformController *)pControllerDelegate; + + if ( assetID == kUARPAssetIDAllAssets ) + { + for ( pAsset = pAccessory->pAssetList; pAsset; pAsset = pAsset->pNext ) + { + if ( pAsset->pController == pController ) + { + uarpPlatformAssetRescind( pAccessory, pController, pAsset ); + } + } + } + else + { + pAsset = uarpPlatformAssetFindByAssetID( pAccessory, pController, assetID ); + __UARP_Require( pAsset, exit ); + + uarpPlatformAssetRescind( pAccessory, pController, pAsset ); + } + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPlatformAssetRescind( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ) +{ + uarpLogDebug( kUARPLoggingCategoryPlatform, "Asset Rescinded from UARP Controller %d ", + pController->_controller.remoteControllerID, pAsset->core.assetID ); + + pAsset->dataReq.requestType &= ~kUARPDataRequestTypeOutstanding; + + pAsset->internalFlags |= kUARPAssetMarkForCleanup; + + pAccessory->callbacks.fAssetRescinded( pAccessory->pDelegate, pController->pDelegate, pAsset->pDelegate ); +} + +/* -------------------------------------------------------------------------------- */ + +UARPBool uarpPlatformAssetIsCookieValid( struct uarpPlatformAccessory *pAccessory, struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie ) +{ + UARPBool isValid; + UARPVersionComparisonResult versionResult; + + if ( pCookie == NULL ) + { + isValid = kUARPNo; + } + else if ( pCookie->assetTag != pAsset->core.assetTag ) + { + isValid = kUARPNo; + } + else if ( pCookie->assetTotalLength != pAsset->core.assetTotalLength ) + { + isValid = kUARPNo; + } + else if ( pCookie->assetNumPayloads != pAsset->core.assetNumPayloads ) + { + isValid = kUARPNo; + } + else if ( pCookie->selectedPayloadIndex >= pAsset->core.assetNumPayloads ) + { + isValid = kUARPNo; + } + else + { + versionResult = uarpVersionCompare( &(pCookie->assetVersion), &(pAsset->core.assetVersion) ); + + if ( versionResult != kUARPVersionComparisonResultIsEqual ) + { + isValid = kUARPNo; + } + else + { + isValid = kUARPYes; + } + } + + return isValid; +} diff --git a/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.h b/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.h new file mode 100644 index 0000000..263303f --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPPlatformAccessory.h @@ -0,0 +1,668 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#ifndef CoreUARPPlatformAccessory_h +#define CoreUARPPlatformAccessory_h + +#include "CoreUARPPlatform.h" +#include "CoreUARPUtils.h" +#include "CoreUARPAccessory.h" +#include "CoreUARPProtocolDefines.h" + +struct uarpPlatformAsset; + +/* Unfortunately, we had some typos and we don't want to break any backwards compatibility */ +#define fcnUarpPlatformAAccessoryRequestBuffer fcnUarpPlatformAccessoryRequestBuffer +#define fcnUarpPlatformAAccessoryReturnBuffer fcnUarpPlatformAccessoryReturnBuffer + + +/* -------------------------------------------------------------------------------- */ +/*! @brief request buffer for general usage + @discussion this routine is called when the lower layer would like a dyamically allocated buffer + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param ppBuffer double pointer where the buffer pointer will be returned. Callback managed. Caller MUST NOT free this memory + @param length the length of the buffer needed + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpPlatformAccessoryRequestBuffer)( void *pAccessoryDelegate, uint8_t **ppBuffer, + uint32_t length ); + + +/* -------------------------------------------------------------------------------- */ +/*! @brief return previously allocated buffer + @discussion this routine is called when the lower layer is done with a dynamically allocated buffer + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pBuffer pointer to the buffer being returned + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpPlatformAccessoryReturnBuffer)( void *pAccessoryDelegate, uint8_t *pBuffer ); + + +/* -------------------------------------------------------------------------------- */ +/*! @brief pause data transfers + @discussion this routine is called when the controller has requested to pause data transfers + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pControllerDelegate pointer to the firmware updater delegate's controller context pointer + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpPlatformAccessoryDataTransferPause)( void *pAccessoryDelegate, void *pControllerDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief resume data transfers + @discussion this routine is called when the controller has requested to resume data transfers + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pControllerDelegate pointer to the firmware updater delegate's controller context pointer + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpPlatformAccessoryDataTransferResume)( void *pAccessoryDelegate, void *pControllerDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accessory specific implementation to handle an asset being offered + @discussion This routine is called when the platform accessory layer has been offered a UARP asset from a remote controller + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pControllerDelegate pointer to the accessory specific layer's representation of a UARP controller + @param pAsset pointer to the asset being offered + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryAssetOffered)( void *pAccessoryDelegate, + void *pControllerDelegate, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accessory specific implementation to handle an asset is ready for transfer processing + @discussion This routine is called asynchronously in response to the accessory specific layer accepting an offerred asset. + After this has been called, the accessory specific implementation can begin to process the payload(s) [and any metadata]. + If this asset is a superbinary, the superbinary header will have been read. + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of the asset which has been accepted + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryAssetReady)( void *pAccessoryDelegate, + void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief MetaData TLV has been received + @discussion This routine is called to inform the accsessory specific layer of a TLV in the Asset's MetaData + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of an asset + @param tlvType type field of the MetaData TLV + @param tlvLength length field of the MetaData TLV + @param pTlvValue pointer to the value of the MetaData TLV + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryMetaDataTLV)( void *pAccessoryDelegate, + void *pAssetDelegate, + uint32_t tlvType, + uint32_t tlvLength, + uint8_t *pTlvValue ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief MetaData has been completely processed + @discussion This routine is called to inform the accsessory specific layer that the SuperBinary Asset's MetaData has been completely processed + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of an asset + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryMetaDataComplete)( void *pAccessoryDelegate, + void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accessory specific implementation to handle a selected payload is ready for transfer processing + @discussion This routine is called asynchronously in response to the accessory specific layer accepting an offerred asset. + After this has been called, the accessory specific implementation can begin to process the selected payload data [and any metadata]. + If this asset is a superbinary, the superbinary header will have been read. + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of the asset which has been accepted + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryPayloadReady)( void *pAccessoryDelegate, + void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Payload Data has been received + @discussion This routine is called when the platform accessory layer has been offered a UARP asset from a remote controller + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of an asset + @param pBuffer pointer to the payload window buffer + @param lengthBuffer length of valid data in the payload window buffer + @param offset offset into the payload being transferred, relative to the payload's beginning offset + @param pAssetState opaque pointer to the firmware updater's representation of an asset; may be used to restore transfer state at power on; + actually points to + @param lengthAssetState length of the pointer represented by the asset state opaque pointers + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryPayloadData)( void *pAccessoryDelegate, + void *pAssetDelegate, + uint8_t *pBuffer, + uint32_t lengthBuffer, + uint32_t offset, + uint8_t *pAssetState, + uint32_t lengthAssetState ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Payload Data has been completely processed + @discussion This routine is called to inform the accsessory specific layer that the selected payload's data has been completely processed + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pAssetDelegate pointer to the accessory specific layer's representation of an asset + */ +/* -------------------------------------------------------------------------------- */ +typedef void (*fcnUarpPlatformAccessoryPayloadDataComplete)( void *pAccessoryDelegate, + void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief asset release callback + @discussion this routine is called when the lower layer is ready to release and free all objects associated with an asset + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pAssetDelegate pointer to the firmware updater delegate's asset context pointer + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (* fcnUarpPlatformAccessoryAssetRelease)( void *pAccessoryDelegate, void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief asset orphan callback + @discussion this routine is called when the lower layer has orphaned the asset; because the controller has become unreachable + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pAssetDelegate pointer to the firmware updater delegate's asset context pointer + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpPlatformAccessoryAssetOrphan)( void *pAccessoryDelegate, void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief controller has rescinded an asset + @discussion this routine is called when the controller has rescinded a previously offered an asset to the accessory + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pControllerDelegate pointer to the firmware updater delegate's controller context pointer + @param pAssetDelegate pointer to a firmware update delegate's asset context pointer + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpPlatformAccessoryAssetRescinded)( void *pAccessoryDelegate, void *pControllerDelegate, + void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief asset corrupt + @discussion this routine is called when the stack has found that an asset is corrupt + @param pAccessoryDelegate pointer to the firmware updater delegate's accessory context pointer + @param pAssetDelegate pointer to a firmware update delegate's asset context pointer + */ +/* -------------------------------------------------------------------------------- */ +typedef void (* fcnUarpPlatformAccessoryAssetCorrupt)( void *pAccessoryDelegate, void *pAssetDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Query Info String + @discussion This routine is called to query the accsessory specific layer for the accessory's info option + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pOptionString pointer to the memory location to copy the info option + @param pLength pointer to return the length of the info option + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (*fcnUarpPlatformAccessoryQueryInfoString)( void *pAccessoryDelegate, + uint8_t *pOptionString, + uint32_t *pLength ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Query Info Version + @discussion This routine is called to query the accsessory specific layer for the accessory's info option + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param assetTag the 4cc of the asset in question + @param pVersion double pointer to return the info version + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (*fcnUarpPlatformAccessoryQueryInfoVersion)( void *pAccessoryDelegate, + uint32_t assetTag, + struct UARPVersion *pVersion ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Query Last Error + @discussion This routine is called to query the accsessory specific layer for the accessory's info option + @param pAccessoryDelegate pointer to the accessory specific layer's representation of a UARP accessory + @param pLast pointer to return the last action with an error / status + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +typedef uint32_t (*fcnUarpPlatformAccessoryQueryLastError)( void *pAccessoryDelegate, + struct UARPLastErrorAction *pLast ); + +struct uarpPlatformAccessoryCallbacks +{ + fcnUarpPlatformAccessoryRequestBuffer fRequestBuffer; + fcnUarpPlatformAccessoryReturnBuffer fReturnBuffer; + fcnUarpAccessoryRequestTransmitMsgBuffer fRequestTransmitMsgBuffer; + fcnUarpAccessoryReturnTransmitMsgBuffer fReturnTransmitMsgBuffer; + fcnUarpAccessorySendMessage fSendMessage; + fcnUarpPlatformAccessoryDataTransferPause fDataTransferPause; + fcnUarpPlatformAccessoryDataTransferResume fDataTransferResume; + fcnUarpPlatformAccessoryAssetOffered fSuperBinaryOffered; + fcnUarpPlatformAccessoryAssetOffered fDynamicAssetOffered; + fcnUarpPlatformAccessoryAssetRescinded fAssetRescinded; + fcnUarpPlatformAccessoryAssetCorrupt fAssetCorrupt; + fcnUarpPlatformAccessoryAssetOrphan fAssetOrphaned; + fcnUarpPlatformAccessoryAssetReady fAssetReady; + fcnUarpPlatformAccessoryMetaDataTLV fAssetMetaDataTLV; + fcnUarpPlatformAccessoryMetaDataComplete fAssetMetaDataComplete; + fcnUarpPlatformAccessoryPayloadReady fPayloadReady; + fcnUarpPlatformAccessoryMetaDataTLV fPayloadMetaDataTLV; + fcnUarpPlatformAccessoryMetaDataComplete fPayloadMetaDataComplete; + fcnUarpPlatformAccessoryPayloadData fPayloadData; + fcnUarpPlatformAccessoryPayloadDataComplete fPayloadDataComplete; + fcnUarpAccessoryApplyStagedAssets fApplyStagedAssets; + fcnUarpPlatformAccessoryQueryInfoString fManufacturerName; + fcnUarpPlatformAccessoryQueryInfoString fModelName; + fcnUarpPlatformAccessoryQueryInfoString fSerialNumber; + fcnUarpPlatformAccessoryQueryInfoString fHardwareVersion; + fcnUarpPlatformAccessoryQueryInfoVersion fActiveFirmwareVersion; + fcnUarpPlatformAccessoryQueryInfoVersion fStagedFirmwareVersion; + fcnUarpPlatformAccessoryQueryLastError fLastError; +}; + +struct uarpPlatformController +{ + struct uarpRemoteControllerObj _controller; + + void *pDelegate; + + struct uarpPlatformController *pNext; +}; + +struct uarpPlatformAccessory +{ + struct uarpAccessoryObj _accessory; + + struct uarpPlatformOptionsObj _options; + + void *pVendorExtension; + + struct uarpPlatformAccessoryCallbacks callbacks; + + void *pDelegate; /* passed into uarpPlatformAccessoryInit() */ + + struct uarpPlatformAsset *pAssetList; +}; + +struct uarpPlatformAssetCookie +{ + uint32_t assetTag; + struct UARPVersion assetVersion; + uint32_t assetTotalLength; + uint16_t assetNumPayloads; + int selectedPayloadIndex; + uint32_t lengthPayloadRecvd; +}; + +struct uarpPlatformAsset +{ + struct UARPSuperBinaryHeader sbHdr; + + struct uarpAssetCoreObj core; + + uint8_t internalFlags; + + /* only one outstanding data request can happen per asset */ + struct uarpDataRequestObj dataReq; + + UARPBool pausedByAccessory; + + /* only one payload is "active" at a time; even in a multiple payload superbinary */ + int selectedPayloadIndex; + struct uarpPayloadObj payload; + uint32_t lengthPayloadRecvd; + + /* the scratch buffer is used for pulling superbinary metadata, payload metadata and payload window chunks */ + uint8_t *pScratchBuffer; + uint32_t lengthScratchBuffer; + + struct uarpPlatformController *pController; + + void *pDelegate; + + struct uarpPlatformAsset *pNext; +}; + +/* -------------------------------------------------------------------------------- */ +/*! @brief Initialize a platform accessory + @discussion This routine is called to initialize a platform accessory + @param pAccessory pointer to the platform accessory, allocated by the caller + @param pOptions pointer to accessory specific options, allocated by the caller + @param pCallbacks pointer to a structure containing the + @param pVendorExtension function pointer to vendor extension + @param fVendorSpecific function pointer to handle vendor specific messages, allows for vendor specific implementations to be in a different file + @param pDelegate pointer to the accessory specific layer's delegate for the + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryInit( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformOptionsObj *pOptions, + struct uarpPlatformAccessoryCallbacks *pCallbacks, + void *pVendorExtension, + fcnUarpVendorSpecific fVendorSpecific, + void *pDelegate ); + + +/* -------------------------------------------------------------------------------- */ +/*! @brief Add a controller to the accessory + @discussion This routine is called to inform a platform accessory of reachable controller + @param pAccessory pointer to the platform accessory, allocated by the caller + @param pController pointer to the controller, allocated by the caller + @param pControllerDelegate pointer to the accessory's representation of a remote controller + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformControllerAdd( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + void *pControllerDelegate ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Remove a controller to the accessory + @discussion This routine is called to inform a platform accessory of a controller which is no longer reachable + @param pAccessory pointer to the platform accessory, allocated by the caller + @param pController pointer to the controller, allocated by the caller + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformControllerRemove( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief An acessory has received a UARP message from the controller + @discussion This routine is called to inform a platform accessory of a uarp message from controller + @param pAccessory pointer to the platform accessory, allocated by the caller + @param pController pointer to the platform controller's representation of the remote controller + @param pBuffer pointer to the uarp message + @param length length of the data pointed to the uarp message + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryRecvMessage( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint8_t *pBuffer, uint32_t length ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Is Asset Acceptable? + @discussion This routine should be called by the accessory specifc layer in order to determine if we should deny this asset offer + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @param pIsAcceptable pointer to be returned + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetIsAcceptable( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + UARPBool *pIsAcceptable ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Is Asset Cookie Acceptable? + @discussion This routine should be called by the accessory specifc layer in order to determine if we should deny this asset offer + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @param pIsAcceptable pointer to be returned + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetCookieIsAcceptable( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie, + UARPBool *pIsAcceptable ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accept Asset + @discussion This routine should be called by the accessory specifc layer when it wants to accept an offerred asset and start it's transfer. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pController pointer to the platform controller's representation of the remote controller + @param pAsset pointer to the asset being accepted + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetAccept( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accept Deny + @discussion This routine should be called by the accessory specifc layer when it wants to deny an offerred asset + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pController pointer to the platform controller's representation of the remote controller + @param pAsset pointer to the asset having it's active payload set + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetDeny( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accept Abandon + @discussion This routine should be called by the accessory specifc layer when it wants to abandon a previously accepted asset + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pController pointer to the platform controller's representation of the remote controller + @param pAsset pointer to the asset having it's active payload set + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetAbandon( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Accept Release + @discussion This routine should be called by the accessory specifc layer when it is completely done processing the asset. + This marks an asset as "ready for cleanup". uarpPlatformCleanupAssets() should be called to free any buffers / allocated memory + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pController pointer to the platform controller's representation of the remote controller + @param pAsset pointer to the asset having it's active payload set + @return kUARPStatusXXX +*/ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetRelease( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Request MetaData for the Asset + @discussion This routine should be called by the accessory specifc layer when it wants to request the asset's metadata + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetRequestMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Set Asset Payload Index + @discussion This routine should be called by the accessory specifc layer to when it wants to change the active payload. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @param payloadIdx zero-based index to the payload to be operated on + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAssetSetPayloadIndex( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + int payloadIdx ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Set Asset Payload Index + @discussion This routine should be called by the accessory specifc layer to when it wants to change the active payload. + This variant is for an accessory who maintains asset transfer state across power loss. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @param payloadIdx zero-based index to the payload to be operated on + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAssetSetPayloadIndexWithCookie( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + int payloadIdx, + struct uarpPlatformAssetCookie *pCookie ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Request MetaData for the payload + @discussion This routine should be called by the accessory specifc layer when it wants to request the selected payload's metadata + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having metadata requested + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryPayloadRequestMetaData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Set Asset Payload Offset + @discussion This routine should be called by the accessory specifc layer to when it wants to change the offset into the active payload. + A good use of this when a power interruption occurred during an asset transfer. The UARP Stack's merge routine would be oblivious. + This should be called between "metadata complete" and "request payload data" + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having it's active payload set + @param payloadOffset relative offset into the payload + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAssetSetPayloadOffset( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + uint32_t payloadOffset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Request Data for the payload + @discussion This routine should be called by the accessory specifc layer when it wants to request the selected payload's data. + This will continue until the payload is completely transferred. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having payload data requested + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryPayloadRequestData( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Request Data for the payload + @discussion This routine should be called by the accessory specifc layer when it wants to request the selected payload's data. + This will continue until the payload is completely transferred. + This variant is for an accessory who maintains asset transfer state across power loss. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset having payload data requested + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryPayloadRequestDataWithCookie( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset, + struct uarpPlatformAssetCookie *pCookie ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Pause requesting data for the payload + @discussion This routine should be called by the accessory specifc layer when it wants to pause trasnfer of the selected payload's data. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset whose data requests are being paused + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryPayloadRequestDataPause( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Resume requesting data for the payload + @discussion This routine should be called by the accessory specifc layer when it wants to resume trasnfer of the selected payload's data. + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset whose data requests can resume + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryPayloadRequestDataResume( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Asset has been fully staged + @discussion This routine should be called by the accessory specifc layer when it has fully staged an asset + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAsset pointer to the asset whose data requests can resume + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessoryAssetFullyStaged( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAsset ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Merge two superbinary assets + @discussion Merge an equal offered superbinary into an abandoned superbinary; offered asset will be free'd + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pAssetOrphaned pointer to the orphaned asset + @param pAssetOffered pointer to the offerred asset + @return kUARPStatusXXX + */ +/* -------------------------------------------------------------------------------- */ +uint32_t uarpPlatformAccessorySuperBinaryMerge( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformAsset *pAssetOrphaned, + struct uarpPlatformAsset *pAssetOffered ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Send Message Complete + @discussion Called by the accessory specific layer to inform this layer that the uarp message has been sent + @param pAccessory pointer to the platfform accessory's representation of an accesory + @param pController pointer to the platform controller's representation of the remote controller + @param pBuffer pointer to the buffer representing the UARP message + */ +/* -------------------------------------------------------------------------------- */ +void uarpPlatformAccessorySendMessageComplete( struct uarpPlatformAccessory *pAccessory, + struct uarpPlatformController *pController, + uint8_t *pBuffer ); + +/* -------------------------------------------------------------------------------- */ +/*! @brief Cleanup assets + @discussion Called by the accessory specific layer to do garabgae collection on assets marked for cleanup + @param pAccessory pointer to the platfform accessory's representation of an accesory + */ +/* -------------------------------------------------------------------------------- */ +void uarpPlatformCleanupAssets( struct uarpPlatformAccessory *pAccessory ); + +#endif /* CoreUARPPlatformAccessory_h */ diff --git a/src/app/findmy/UARPDK/CoreUARPPlatformRTK.c b/src/app/findmy/UARPDK/CoreUARPPlatformRTK.c new file mode 100644 index 0000000..6ffb7aa --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPPlatformRTK.c @@ -0,0 +1,125 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + + +#include "CoreUARPPlatformRTK.h" +#include +#include "fmna_constants_platform.h" +#include "os_mem.h" + +#define HTONS(val) ((uint16_t)((((val) & 0xff00) >> 8) | ((((val) & 0x00ff) << 8)))) + +#define HTONL(val) ((((uint32_t) (val) & 0xff000000) >> 24) | \ + (((uint32_t) (val) & 0x00ff0000) >> 8) | \ + (((uint32_t) (val) & 0x0000ff00) << 8) | \ + (((uint32_t) (val) & 0x000000ff) << 24)) + +#define kUarpEmbeddedLoggingSubsystem "com.apple.uarp.embedded" +#define kUarpLoggingCategoryAccessory "protocolaccessory" +#define kUarpLoggingCategoryController "protocolcontroller" +#define kUarpLoggingCategoryPlatform "platform" +#define kUarpLoggingCategoryProduct "product" +#define kUarpLoggingCategoryMemory "memory" +#define kUarpLoggingCategoryAssert "assert" +#define kUarpLoggingCategoryUnknown "unknown" + +/* -------------------------------------------------------------------------------- */ + +void * uarpZalloc( size_t length ) +{ + void *pBuffer; + + pBuffer = os_mem_zalloc( RAM_TYPE_DATA_ON, length ); + + uarpLogInfo( kUARPLoggingCategoryMemory, "0x%p - alloc %d bytes", pBuffer, (int)length ); + + return pBuffer; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpFree( void * pBuffer ) +{ + if ( pBuffer ) + { + uarpLogInfo( kUARPLoggingCategoryMemory, "0x%p - freed", pBuffer ); + + os_mem_free( pBuffer ); + } +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpHtonl( uint32_t val32 ) +{ + return HTONL( val32 ); +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpNtohl( uint32_t val32 ) +{ + return HTONL( val32 ); +} + +/* -------------------------------------------------------------------------------- */ + +uint16_t uarpHtons( uint16_t val16 ) +{ + return HTONS( val16 ); +} + +/* -------------------------------------------------------------------------------- */ + +uint16_t uarpNtohs( uint16_t val16 ) +{ + return HTONS( val16 ); +} + diff --git a/src/app/findmy/UARPDK/CoreUARPPlatformRTK.h b/src/app/findmy/UARPDK/CoreUARPPlatformRTK.h new file mode 100644 index 0000000..42144df --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPPlatformRTK.h @@ -0,0 +1,188 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#ifndef CoreUARPPlatformRTK_H +#define CoreUARPPlatformRTK_H + +#include +#include +#include +#include +#include "fmna_constants_platform.h" +#include "trace.h" +#include "board.h" +#include "os_sync.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UARP_DISABLE_VENDOR_SPECIFIC 1 + +typedef enum +{ + kUARPLoggingCategoryAccessory, + kUARPLoggingCategoryController, + kUARPLoggingCategoryPlatform, + kUARPLoggingCategoryProduct, + kUARPLoggingCategoryMemory, + kUARPLoggingCategoryAssert, + kUARPLoggingCategoryMax +} +UARPLoggingCategory; + +#define uarpLogError(category,...) FMNA_LOG_ERROR(__VA_ARGS__) +#define uarpLogDebug(category,...) FMNA_LOG_DEBUG(__VA_ARGS__) +#define uarpLogInfo(category,...) FMNA_LOG_INFO(__VA_ARGS__) + +void *uarpZalloc(size_t length); +void uarpFree(void *pBuffer); + +uint32_t uarpHtonl(uint32_t val32); +uint32_t uarpNtohl(uint32_t val32); + +uint16_t uarpHtons(uint16_t val16); +uint16_t uarpNtohs(uint16_t val16); + +#define CRITICAL_REGION_ENTER() flags = os_lock(); \ + +#define CRITICAL_REGION_EXIT() os_unlock(flags) + +#define __UARP_Require(assertion, exceptionLabel) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + error_line = __LINE__; \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define __UARP_Require_Action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + error_line = __LINE__; \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define __UARP_Require_Quiet(assertion, exceptionLabel) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define __UARP_Require_Action_Quiet(assertion, exceptionLabel, action) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define __UARP_Check(assertion) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + APP_PRINT_ERROR2("UARP Check Failed, file: %s:%d", TRACE_STRING(error_file), __LINE__); \ + } \ + } while ( 0 ) + +#if !(UARP_DISABLE_VERIFY) + +#define __UARP_Verify_Action(assertion, exceptionLabel, action) \ + do \ + { \ + if ( !(assertion) ) \ + { \ + error_line = __LINE__; \ + { \ + action; \ + } \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +#define __UARP_Verify_exit exit: \ + do \ + { \ + if (error_line) \ + { \ + APP_PRINT_ERROR2("UARP Verify Failed, file: %s:%d", TRACE_STRING(error_file), error_line); \ + error_line = 0; \ + } \ + } while ( 0 ); + +#else + +#define __UARP_Verify_Action(assertion, exceptionLabel, action) + +#define __UARP_Verify_exit exit: \ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CoreUARPPlatformRTK_H */ diff --git a/src/app/findmy/UARPDK/CoreUARPProtocolDefines.h b/src/app/findmy/UARPDK/CoreUARPProtocolDefines.h new file mode 100644 index 0000000..0668a62 --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPProtocolDefines.h @@ -0,0 +1,447 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + + +#ifndef uarpProtocolDefines_h +#define uarpProtocolDefines_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* NOTE: If your compile supports packing structures differently, + you will need to modify UARP_ATTRIBUTE_[POST][PRE]PACKED */ +#define UARP_ATTRIBUTE_POST_PACKED __attribute__((packed)) + +#define UARP_ATTRIBUTE_PRE_PACKED + +#define kUARPProtocolVersionMinimum 1 +#define kUARPProtocolVersion 1 + +#define kUARPMaxBytesRequested 0xFFFF + +/* UARP Message Set Definition */ + +#define kUARPMsgSync 0x0000 /* A -> C, C -> A */ +#define kUARPMsgVersionDiscoveryRequest 0x0001 /* C -> A */ +#define kUARPMsgVersionDiscoveryResponse 0x0002 /* A -> C */ +#define kUARPMsgAccessoryInformationRequest 0x0003 /* C -> A */ +#define kUARPMsgAccessoryInformationResponse 0x0004 /* A -> C */ +#define kUARPMsgAssetAvailableNotification 0x0005 /* C -> A --- */ +#define kUARPMsgAssetDataRequest 0x0006 /* A -> C --- */ +#define kUARPMsgAssetDataResponse 0x0007 /* C -> A --- */ +#define kUARPMsgAssetDataTransferNotification 0x0008 /* C -> A */ +#define kUARPMsgAssetProcessingNotification 0x0009 /* A -> C */ +#define kUARPMsgApplyStagedAssetsRequest 0x000A /* C -> A */ +#define kUARPMsgApplyStagedAssetsResponse 0x000B /* A -> C */ +#define kUARPMsgAssetRescindedNotification 0x000C /* C -> A --- */ +#define kUARPMsgAssetAvailableNotificationAck 0x000D /* A -> C --- */ +#define kUARPMsgAssetDataTransferNotificationAck 0x000E /* A -> C --- */ +#define kUARPMsgAssetProcessingNotificationAck 0x000F /* C -> A --- */ +#define kUARPMsgAssetRescindedNotificationAck 0x0010 + +#if 0 // TODO: implement +#define kUARPMsgDebugModeRequest +#define kUARPMsgDebugModeResponse +#define kUARPMsgDebugNotification +#endif + +#define kUARPMsgVendorSpecific 0xFFFF + +/* UARP Message Status Defintions */ + +#define kUARPStatusSuccess 0x0000 +#define kUARPStatusUnknownMessageType 0x0001 +#define kUARPStatusIncompatibleProtocolVersion 0x0002 +#define kUARPStatusInvalidAssetTag 0x0003 +#define kUARPStatusInvalidDataRequestOffset 0x0004 +#define kUARPStatusInvalidDataRequestLength 0x0005 +#define kUARPStatusMismatchUUID 0x0006 +#define kUARPStatusAssetDataPaused 0x0007 +#define kUARPStatusInvalidMessageLength 0x0008 +#define kUARPStatusInvalidMessage 0x0009 +#define kUARPStatusInvalidTLV 0x000A +#define kUARPStatusNoResources 0x000B +#define kUARPStatusUnknownAccessory 0x000C +#define kUARPStatusUnknownController 0x000D +#define kUARPStatusInvalidFunctionPointer 0x000E +#define kUARPStatusCorruptSuperBinary 0x000F +#define kUARPStatusAssetInFlight 0x0010 +#define kUARPStatusAssetIdUnknown 0x0011 +#define kUARPStatusInvalidDataResponseLength 0x0012 +#define kUARPStatusAssetTransferComplete 0x0013 +#define kUARPStatusUnknownPersonalizationOption 0x0014 +#define kUARPStatusMismatchPersonalizationOption 0x0015 +#define kUARPStatusInvalidAssetType 0x0016 +#define kUARPStatusUnknownAsset 0x0017 +#define kUARPStatusNoVersionAgreement 0x0018 +#define kUARPStatusUnknownDataTransferState 0x0019 +#define kUARPStatusUnsupported 0x001A +#define kUARPStatusInvalidObject 0x001B +#define kUARPStatusUnknownInformationOption 0x001C +#define kUARPStatusInvalidDataResponse 0x001D +#define kUARPStatusInvalidArgument 0x001E +#define kUARPStatusDataTransferPaused 0x001F +#define kUARPStatusUnknownPayload 0x0020 +#define kUARPStatusInvalidDataTransferNotification 0x0021 +#define kUARPStatusMetaDataTypeNotFound 0x0022 +#define kUARPStatusMetaDataCorrupt 0x0023 +#define kUARPStatusOutOfOrderMessageID 0x0024 +#define kUARPStatusDuplicateMessageID 0x0025 +#define kUARPStatusMismatchDataOffset 0x0026 +#define kUARPStatusInvalidLength 0x0027 +#define kUARPStatusNoMetaData 0x0028 +#define kUARPStatusDuplicateController 0x0029 +#define kUARPStatusDuplicateAccessory 0x002A +#define kUARPStatusInvalidOffset 0x002B +#define kUARPStatusInvalidPayload 0x002C +#define kUARPStatusProcessingIncomplete 0x002D +#define kUARPStatusInvalidDataRequestType 0x002E +#define kUARPStatusInvalidSuperBinaryHeader 0x002F +#define kUARPStatusInvalidPayloadHeader 0x0030 +#define kUARPStatusAssetNoBytesRemaining 0x0031 +#define kUARPStatusRequestResendPayload 0x0032 + +/* we had some typos and do not want to break anyone's implementation */ +#define kUARPStatusUnkownPersonalizationOption kUARPStatusUnknownPersonalizationOption + + +/* BOOL */ + +typedef uint8_t UARPBool; + +#define kUARPNo 0 +#define kUARPYes 1 + + +/* Message Defintions */ + +#define kUARPInitialTxMsgID 1 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgHeader +{ + uint16_t msgType; + uint16_t msgPayloadLength; + uint16_t msgID; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPTLVHeader +{ + uint32_t tlvType; + uint32_t tlvLength; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPVersion +{ + uint32_t major; + uint32_t minor; + uint32_t release; + uint32_t build; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgVersionDiscoveryRequest +{ + struct UARPMsgHeader msgHdr; + uint16_t protocolVersionController; +} UARP_ATTRIBUTE_POST_PACKED; + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgVersionDiscoveryResponse +{ + struct UARPMsgHeader msgHdr; + uint16_t status; + uint16_t protocolVersionAccessory; +} UARP_ATTRIBUTE_POST_PACKED; + +#define kUARPTLVAccessoryInformationManufacturerName 0x00000001 +#define kUARPTLVAccessoryInformationModelName 0x00000002 +#define kUARPTLVAccessoryInformationSerialNumber 0x00000003 +#define kUARPTLVAccessoryInformationHardwareVersion 0x00000004 +#define kUARPTLVAccessoryInformationFirmwareVersion 0x00000005 +#define kUARPTLVAccessoryInformationStagedFirmwareVersion 0x00000006 +#define kUARPTLVAccessoryInformationStatistics 0x00000007 +#define kUARPTLVAccessoryInformationLastError 0x00000008 + +/* TODO: Add support later */ +#if 0 +#define kUARPTLVAccessoryInformationAssetInfo +#define kUARPTLVAccessoryInformationCategory +#define kUARPTLVAccessoryInformationDebugParam +#endif + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAccessoryInformationRequest +{ + struct UARPMsgHeader msgHdr; + uint32_t informationOption; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAccessoryInformationResponse +{ + struct UARPMsgHeader msgHdr; + uint16_t status; +} UARP_ATTRIBUTE_POST_PACKED; + +UARP_ATTRIBUTE_PRE_PACKED struct UARPStatistics +{ + uint32_t packetsNoVersionAgreement; + uint32_t packetsMissed; + uint32_t packetsDuplicate; + uint32_t packetsOutOfOrder; +} UARP_ATTRIBUTE_POST_PACKED; + +#define kUARPLastActionApplyFirmwareUpdate 0x00000001 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPLastErrorAction +{ + uint32_t lastAction; + uint32_t lastError; /* Vendor Specific */ +} UARP_ATTRIBUTE_POST_PACKED; + + +#define kUARPAssetFlagsAssetTypeSuperBinary 0x0001 +#define kUARPAssetFlagsAssetTypeDynamic 0x0002 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetAvailableNotification +{ + struct UARPMsgHeader msgHdr; + uint32_t assetTag; + uint16_t assetFlags; + uint16_t assetID; + struct UARPVersion assetVersion; + uint32_t assetLength; + uint16_t assetNumPayloads; +} UARP_ATTRIBUTE_POST_PACKED; + +#define kUARPAssetIDInvalid 0x0000 +#define kUARPAssetIDAllAssets 0xFFFF + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetRescindedNotification +{ + struct UARPMsgHeader msgHdr; + uint16_t assetID; +} UARP_ATTRIBUTE_POST_PACKED; + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetDataRequest +{ + struct UARPMsgHeader msgHdr; + uint16_t assetID; + uint32_t dataOffset; + uint16_t numBytesRequested; +} UARP_ATTRIBUTE_POST_PACKED; + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetDataResponse +{ + struct UARPMsgHeader msgHdr; + uint16_t status; + uint16_t assetID; + uint32_t dataOffset; + uint16_t numBytesRequested; + uint16_t numBytesResponded; +} UARP_ATTRIBUTE_POST_PACKED; + + +#define kUARPAssetDataTransferPause 0x0001 +#define kUARPAssetDataTransferResume 0x0002 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetDataTransferNotification +{ + struct UARPMsgHeader msgHdr; + uint16_t assetTransferFlags; +} UARP_ATTRIBUTE_POST_PACKED; + + +#define kUARPAssetProcessingFlagsUploadComplete 0x0001 +#define kUARPAssetProcessingFlagsUploadDenied 0x0002 +#define kUARPAssetProcessingFlagsUploadAbandoned 0x0003 +#define kUARPAssetProcessingFlagsAssetCorrupt 0x0004 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgAssetProcessingNotification +{ + struct UARPMsgHeader msgHdr; + uint16_t assetID; + uint16_t assetProcessingFlags; +} UARP_ATTRIBUTE_POST_PACKED; + + +#define kUARPApplyStagedAssetsFlagsSuccess 0x0001 +#define kUARPApplyStagedAssetsFlagsFailure 0x0002 +#define kUARPApplyStagedAssetsFlagsNeedsRestart 0x0003 +#define kUARPApplyStagedAssetsFlagsNothingStaged 0x0004 +#define kUARPApplyStagedAssetsFlagsMidUpload 0x0005 +#define kUARPApplyStagedAssetsFlagsInUse 0x0006 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgApplyStagedAssetsRequest +{ + struct UARPMsgHeader msgHdr; +} UARP_ATTRIBUTE_POST_PACKED; + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgApplyStagedAssetsResponse +{ + struct UARPMsgHeader msgHdr; + uint16_t status; + uint16_t flags; +} UARP_ATTRIBUTE_POST_PACKED; + + +#if 0 // MARK: needs implementation for kUARPMsgDebugModeRequest / kUARPMsgDebugModeResponse / kUARPMsgDebugNotification + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgDebugModeRequest +{ + struct UARPMsgHeader msgHdr; + uint32_t mode; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgDebugModeResponse +{ + struct UARPMsgHeader msgHdr; + uint16_t status; + uint32_t mode; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgDebugNotification +{ + struct UARPMsgHeader msgHdr; + uint32_t index; +} UARP_ATTRIBUTE_POST_PACKED; + +#endif + + +/* OUI maintained here http://standards-oui.ieee.org/oui.txt */ +#define kUARPOUILength 3 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPMsgVendorSpecific +{ + struct UARPMsgHeader msgHdr; + uint8_t oui[kUARPOUILength]; + uint16_t msgType; +} UARP_ATTRIBUTE_POST_PACKED; + + +#if 0 // MARK: for use with kUARPTLVAccessoryInformationAssetInfo + +UARP_ATTRIBUTE_PRE_PACKED struct UARPTLVAssetInformation +{ + uint32_t type; + uint32_t length; + uint32_t assetTag; + uint32_t runningVersion; + uint32_t stagedVersion; + uint32_t flags; + /* description immediately follows, if length allows */ +} UARP_ATTRIBUTE_POST_PACKED; +#endif + +/* MARK: SUPERBINARY */ + +#define kUARPSuperBinaryFormatVersion 2 + +#define kUARPSuperBinaryPayloadTagLength 4 + +UARP_ATTRIBUTE_PRE_PACKED struct UARPSuperBinaryHeader +{ + uint32_t superBinaryFormatVersion; + uint32_t superBinaryHeaderLength; + uint32_t superBinaryLength; + struct UARPVersion superBinaryVersion; + uint32_t superBinaryMetadataOffset; + uint32_t superBinaryMetadataLength; + uint32_t payloadHeadersOffset; + uint32_t payloadHeadersLength; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPPayloadHeader +{ + uint32_t payloadHeaderLength; + uint32_t payloadTag; + struct UARPVersion payloadVersion; + uint32_t payloadMetadataOffset; + uint32_t payloadMetadataLength; + uint32_t payloadOffset; + uint32_t payloadLength; +} UARP_ATTRIBUTE_POST_PACKED; + + +UARP_ATTRIBUTE_PRE_PACKED struct UARPSuperBinaryTLVHeader +{ + uint32_t tlvType; + uint32_t tlvLength; +} UARP_ATTRIBUTE_POST_PACKED; + +/* this is done to make "largest message header" calculation easy */ + +union UARPMessages +{ + struct UARPMsgVersionDiscoveryRequest discoveryRequest; + struct UARPMsgVersionDiscoveryResponse discoveryResponse; + struct UARPMsgAccessoryInformationRequest infoRequest; + struct UARPMsgAccessoryInformationResponse infoResponse; + struct UARPMsgAssetAvailableNotification assetAvailable; + struct UARPMsgAssetRescindedNotification assetRescinded; + struct UARPMsgAssetDataRequest dataRequest; + struct UARPMsgAssetDataResponse dataResponse; + struct UARPMsgAssetDataTransferNotification transferNotification; + struct UARPMsgAssetProcessingNotification processingNotification; + struct UARPMsgApplyStagedAssetsRequest applyAssetRequest; + struct UARPMsgApplyStagedAssetsResponse applyAssetResponse; + struct UARPMsgVendorSpecific vendorSpecific; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* uarpProtocolDefines_h */ diff --git a/src/app/findmy/UARPDK/CoreUARPUtils.c b/src/app/findmy/UARPDK/CoreUARPUtils.c new file mode 100644 index 0000000..20e972b --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPUtils.c @@ -0,0 +1,231 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#include "CoreUARPUtils.h" + +/* -------------------------------------------------------------------------------- */ + +uint32_t uarpPayloadTagPack( uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength] ) +{ + uint32_t payloadTag; + + payloadTag = 0; + + payloadTag |= payload4cc[3]; + + payloadTag <<= 8; + + payloadTag |= payload4cc[2]; + + payloadTag <<= 8; + + payloadTag |= payload4cc[1]; + + payloadTag <<= 8; + + payloadTag |= payload4cc[0]; + + return payloadTag; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpPayloadTagUnpack( uint32_t payloadTag, uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength] ) +{ + uint8_t *pTmp; + + pTmp = (uint8_t *)&payloadTag; + + if ( payloadTag == 0 ) + { + payload4cc[0] = '0'; + payload4cc[1] = '0'; + payload4cc[2] = '0'; + payload4cc[3] = '0'; + } + else + { + payload4cc[0] = pTmp[0]; + payload4cc[1] = pTmp[1]; + payload4cc[2] = pTmp[2]; + payload4cc[3] = pTmp[3]; + } +} + +/* -------------------------------------------------------------------------------- */ + +UARPVersionComparisonResult uarpVersionCompare( struct UARPVersion *pExistingVersion, + struct UARPVersion *pProposedVersion ) +{ + UARPVersionComparisonResult result; + + /* compare major versions */ + if ( pExistingVersion->major > pProposedVersion->major ) + { + result = kUARPVersionComparisonResultIsOlder; + } + else if ( pExistingVersion->major < pProposedVersion->major ) + { + result = kUARPVersionComparisonResultIsNewer; + } + /* compare minor versions if major versions are equal */ + else if ( pExistingVersion->minor > pProposedVersion->minor ) + { + result = kUARPVersionComparisonResultIsOlder; + } + else if ( pExistingVersion->minor < pProposedVersion->minor ) + { + result = kUARPVersionComparisonResultIsNewer; + } + /* compare release versions if minor versions are equal */ + else if ( pExistingVersion->release > pProposedVersion->release ) + { + result = kUARPVersionComparisonResultIsOlder; + } + else if ( pExistingVersion->release < pProposedVersion->release ) + { + result = kUARPVersionComparisonResultIsNewer; + } + /* compare build versions if minor versions are equal */ + else if ( pExistingVersion->build > pProposedVersion->build ) + { + result = kUARPVersionComparisonResultIsOlder; + } + else if ( pExistingVersion->build < pProposedVersion->build ) + { + result = kUARPVersionComparisonResultIsNewer; + } + /* if we got here, version is equivalent */ + else + { + result = kUARPVersionComparisonResultIsEqual; + } + + return result; +} + +/* -------------------------------------------------------------------------------- */ + +UARPVersionComparisonResult uarpAssetCoreCompare( struct uarpAssetCoreObj *pExistingCore, + struct uarpAssetCoreObj *pProposedCore ) +{ + UARPVersionComparisonResult result; + + if ( pExistingCore->assetFlags != pProposedCore->assetFlags ) + { + result = kUARPVersionComparisonResultNotEqual; + } + else if ( pExistingCore->assetTag != pProposedCore->assetTag ) + { + result = kUARPVersionComparisonResultNotEqual; + } + else if ( pExistingCore->assetTotalLength != pProposedCore->assetTotalLength ) + { + result = kUARPVersionComparisonResultNotEqual; + } + else if ( pExistingCore->assetNumPayloads != pProposedCore->assetNumPayloads ) + { + result = kUARPVersionComparisonResultNotEqual; + } + else + { + result = uarpVersionCompare( &(pExistingCore->assetVersion), &(pProposedCore->assetVersion) ); + } + + return result; +} + +/* -------------------------------------------------------------------------------- */ + +void uarpVersionEndianSwap( struct UARPVersion *pVersion, struct UARPVersion *pVersionSwapped ) +{ + /* network to host, host to network, technically irrelevant */ + pVersionSwapped->major = uarpNtohl( pVersion->major ); + pVersionSwapped->minor = uarpNtohl( pVersion->minor ); + pVersionSwapped->release = uarpNtohl( pVersion->release ); + pVersionSwapped->build = uarpNtohl( pVersion->build ); +} + +/* -------------------------------------------------------------------------------- */ + +UARPBool uarpAssetIsSuperBinary( struct uarpAssetCoreObj *pCore ) +{ + UARPBool isSuperBinary; + + if ( pCore->assetFlags & kUARPAssetFlagsAssetTypeSuperBinary ) + { + isSuperBinary = kUARPYes; + } + else + { + isSuperBinary = kUARPNo; + } + + return isSuperBinary; +} + +/* -------------------------------------------------------------------------------- */ + +UARPBool uarpAssetIsDynamicAsset( struct uarpAssetCoreObj *pCore ) +{ + UARPBool isDynamicAsset; + + if ( pCore->assetFlags & kUARPAssetFlagsAssetTypeDynamic ) + { + isDynamicAsset = kUARPYes; + } + else + { + isDynamicAsset = kUARPNo; + } + + return isDynamicAsset; +} + diff --git a/src/app/findmy/UARPDK/CoreUARPUtils.h b/src/app/findmy/UARPDK/CoreUARPUtils.h new file mode 100644 index 0000000..ece15d0 --- /dev/null +++ b/src/app/findmy/UARPDK/CoreUARPUtils.h @@ -0,0 +1,148 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#ifndef CoreUARPUtils_h +#define CoreUARPUtils_h + +#include "CoreUARPPlatform.h" +#include "CoreUARPProtocolDefines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + kUARPVersionComparisonResultIsEqual, + kUARPVersionComparisonResultIsNewer, + kUARPVersionComparisonResultIsOlder, + kUARPVersionComparisonResultNotEqual, + kUARPVersionComparisonResultMax +} +UARPVersionComparisonResult; + +struct uarpAssetCoreObj +{ + uint16_t assetID; + uint16_t assetFlags; // should be kUARPAssetFlagsAssetTypeSuperBinary 0x0001 + uint32_t assetTag; // A SuperBinary Firmware asset will be have all four characters set to 0. + struct UARPVersion assetVersion; + uint32_t assetTotalLength; + uint16_t assetNumPayloads; +}; + +struct uarpDataRequestObj +{ + uint8_t requestType; + + uint32_t payloadTag; + uint32_t relativeOffset; // offset to be added to the current offset when filling buffer with chunks + uint32_t bytesRequested; + + uint8_t *bytes; // allocated by platform app + uint32_t bytesResponded; + + // until bytesResponded is equal to bytesRequested + // or bytesResponded + absoluteOffset == full length + uint32_t absoluteOffset; // offset into the superbinary + uint32_t currentOffset; // offset into the payload tag's metadata/payload + uint32_t bytesRemaining; +}; + +struct uarpPayloadObj +{ + struct UARPPayloadHeader plHdr; + + uint8_t internalFlags; + uint8_t vendorFlags; + + uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength]; +}; + +struct uarpPlatformOptionsObj +{ + uint32_t maxTxPayloadLength; + uint32_t maxRxPayloadLength; + uint32_t payloadWindowLength; +}; + +uint32_t uarpPayloadTagPack( uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength] ); + +void uarpPayloadTagUnpack( uint32_t payloadTag, uint8_t payload4cc[kUARPSuperBinaryPayloadTagLength] ); + +/* response is relative to "is the proposed version ... than the existing version?" + + TODO: Description for what to do with an offered Superbinary is coming from a different controller + + If offered superbinary is newer than the transferring one... + - abandon the transferring one + - accept the new one + + If offered superbinary is older than the transferring one... + - deny the new one + */ +UARPVersionComparisonResult uarpVersionCompare( struct UARPVersion *pExistingVersion, + struct UARPVersion *pProposedVersion ); + +UARPVersionComparisonResult uarpAssetCoreCompare( struct uarpAssetCoreObj *pExistingCore, + struct uarpAssetCoreObj *pProposedCore ); + +void uarpVersionEndianSwap( struct UARPVersion *pVersion, struct UARPVersion *pVersionSwapped ); + + +UARPBool uarpAssetIsSuperBinary( struct uarpAssetCoreObj *pCore ); + +UARPBool uarpAssetIsDynamicAsset( struct uarpAssetCoreObj *pCore ); + +#ifdef __cplusplus +} +#endif + +#endif /* CoreUARPUtils_h */ diff --git a/src/app/findmy/app_task.c b/src/app/findmy/app_task.c new file mode 100644 index 0000000..b6453e9 --- /dev/null +++ b/src/app/findmy/app_task.c @@ -0,0 +1,183 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file app_task.c + * @brief Routines to create App task and handle events & messages + * @author jane + * @date 2017-06-02 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "otp_config.h" +#include "os_mem.h" +#if (AON_WDG_ENABLE == 1) +#include "rtl876x_aon_wdg.h" +#endif + +/** @defgroup PERIPH_APP_TASK Peripheral App Task + * @brief This file handles the implementation of application task related functions. + * + * Create App task and handle events & messages + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +#define APP_TASK_PRIORITY 2 //!< Task priorities +#define APP_TASK_STACK_SIZE 256 * 14 //!< Task stack size +#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size +#define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size +#define MAX_NUMBER_OF_BT_IND_MESSAGE 0x10 //!< BT indication message queue size +#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size + +/*============================================================================* + * Variables + *============================================================================*/ +void *app_task_handle; //!< APP Task handle +void *evt_queue_handle; //!< Event queue handle +void *io_queue_handle; //!< IO queue handle +void *bt_indication_queue; //!< BT indication queue handle + +/*============================================================================* + * Functions + *============================================================================*/ +void app_main_task(void *p_param); + +/** + * @brief Initialize App task + * @return void + */ +void app_task_init() +{ + os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE, + APP_TASK_PRIORITY); +} + +/** + * @brief Send msg to app task. + * @param[in] p_handle: The handle to the message queue being peeked. + * @return The status of the message queue peek. + * @retval true:Message queue was peeked successfully. + * @retval false:Message queue was failed to peek. + */ +bool app_send_msg_to_apptask(T_IO_MSG *p_msg) +{ + uint8_t event = EVENT_IO_TO_APP; + + if (os_msg_send(io_queue_handle, p_msg, 0) == false) + { + APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_io_msg_to_app fail"); + return false; + } + if (os_msg_send(evt_queue_handle, &event, 0) == false) + { + APP_PRINT_ERROR0("[app_task] app_send_msg_to_apptask: send_evt_msg_to_app fail"); + return false; + } + return true; +} + +uint32_t app_sched_event_put(void const *p_event_data, + uint16_t event_size, + app_sched_event_handler_t handler) +{ + uint8_t event = EVENT_IO_TO_APP; + T_IO_MSG msg; + msg.type = IO_MSG_TYPE_OTHERS; + T_APP_SCHED_EVT_STUCT *evt_context = os_mem_alloc(RAM_TYPE_DATA_ON, sizeof(T_APP_SCHED_EVT_STUCT)); + evt_context->event_size = event_size; + evt_context->p_event_data = os_mem_alloc(RAM_TYPE_DATA_ON, event_size); + memcpy(evt_context->p_event_data, p_event_data, event_size); + + if (handler != NULL) + { + evt_context->handler = handler; + } + else + { + evt_context->handler = NULL; + } + msg.u.buf = (void *)evt_context; + + if (os_msg_send(io_queue_handle, &msg, 0) == false) + { + APP_PRINT_ERROR0("send_io_msg_to_app fail"); + return false; + } + if (os_msg_send(evt_queue_handle, &event, 0) == false) + { + APP_PRINT_ERROR0("send_evt_msg_to_app fail"); + return false; + } + return true; +} + +/** + * @brief App task to handle events & messages + * @param[in] p_param Parameters sending to the task + * @return void + */ +void app_main_task(void *p_param) +{ + uint8_t event; + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t)); + /* create a queue to store packets when credits is not enough */ + os_msg_queue_create(&bt_indication_queue, MAX_NUMBER_OF_BT_IND_MESSAGE, sizeof(T_BT_INDICATION)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + driver_init(); + +#if (ROM_WATCH_DOG_ENABLE == 1) + extern void reset_watch_dog_timer_enable(void); + reset_watch_dog_timer_enable(); +#endif + +#if (AON_WDG_ENABLE == 1) + aon_wdg_init(AON_WDT_RESET_ALL, AON_WDG_TIME_OUT_PERIOD_SECOND); + aon_wdg_enable(); + AON_WDG_Restart(); +#endif + + while (true) + { + if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true) + { + if (event == EVENT_IO_TO_APP) + { + T_IO_MSG io_msg; + if (os_msg_recv(io_queue_handle, &io_msg, 0) == true) + { + app_handle_io_msg(io_msg); + } + } + else + { + gap_handle_msg(event); + } + } + } +} + +/** @} */ /* End of group PERIPH_APP_TASK */ + + diff --git a/src/app/findmy/app_task.h b/src/app/findmy/app_task.h new file mode 100644 index 0000000..ed535f3 --- /dev/null +++ b/src/app/findmy/app_task.h @@ -0,0 +1,87 @@ +/** +***************************************************************************************** +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file app_task.h + * @brief Routines to create App task and handle events & messages + * @author scarlett_liang + * @date 2022-12-02 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2022 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ +#ifndef _APP_TASK_H_ +#define _APP_TASK_H_ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdint.h" +#include "fmna_gatt.h" +#include "app_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Global Variables + *============================================================================*/ +extern void *bt_indication_queue; + +/*============================================================================* + * Types + *============================================================================*/ +typedef void (*app_sched_event_handler_t)(void *p_event_data, uint16_t event_size); + +typedef struct +{ + void *p_event_data; + uint16_t event_size; + app_sched_event_handler_t handler; +} T_APP_SCHED_EVT_STUCT; + +typedef struct +{ + uint16_t length; + uint16_t conn_handle; + FMNA_Service_Opcode_t opcode; + void *buf; +} T_BT_INDICATION; + +/*============================================================================* +* Global functions +*============================================================================*/ +extern void driver_init(void); + +/** + * @brief Initialize App task + * @return void + */ +void app_task_init(void); + +/**@brief Function for scheduling an event. + * + * @details Puts an event into the event queue. + * + * @param[in] p_event_data Pointer to event data to be scheduled. + * @param[in] event_size Size of event data to be scheduled. + * @param[in] handler Event handler to receive the event. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t app_sched_event_put(void const *p_event_data, + uint16_t event_size, + app_sched_event_handler_t handler); + + +bool app_send_msg_to_apptask(T_IO_MSG *p_msg); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/crypto/fm-crypto.c b/src/app/findmy/crypto/fm-crypto.c new file mode 100644 index 0000000..20ce2a7 --- /dev/null +++ b/src/app/findmy/crypto/fm-crypto.c @@ -0,0 +1,752 @@ +/* + * need a license header here + */ + +/* + * WolfSSL shim, providing the core cryptographic functionality + * required to implement the FindMy protocol. + */ + +#include +#include +#include +#include "fm-crypto.h" + +const byte KDF_LABEL_UPDATE[] = "update"; +const byte KDF_LABEL_DIVERSIFY[] = "diversify"; +const byte KDF_LABEL_INTERMEDIATE[] = "intermediate"; +const byte KDF_LABEL_CONNECT[] = "connect"; +const byte KDF_LABEL_SERVERSS[] = "ServerSharedSecret"; +const byte KDF_LABEL_PAIRINGSESS[] = "PairingSession"; +const byte KDF_LABEL_SNPROTECTION[] = "SerialNumberProtection"; + +#define CHECK_RV_RET(_rv_, _val_) if (_rv_) return _val_; +#define CHECK_RV(_rv_) CHECK_RV_RET(_rv_, _rv_); +#define CHECK_RV_GOTO(_rv_, _label_) if (_rv_) goto _label_; + +/* + * OpenSSL: SHA256() + */ +int fm_crypto_sha256(word32 msg_nbytes, const byte *msg, byte out[32]) +{ + int rv = mbedtls_sha256(msg, msg_nbytes, out, 0); + return rv; +} + +int fm_crypto_ckg_init(fm_crypto_ckg_context_t ctx) +{ + int rv = 0; + XMEMSET(ctx, 0, sizeof(struct fm_crypto_ckg_context)); + ctx->p = (mbedtls_ecp_point *)os_mem_zalloc(RAM_TYPE_DATA_ON, sizeof(mbedtls_ecp_point)); + if (ctx->p == NULL) + { + rv = -1; + goto cleanup; + } + mbedtls_ecp_point_init(ctx->p); + + /* + * OpenSSL: RAND_bytes() + */ + rv = mbedtls_platform_frng(NULL, ctx->r1, sizeof(ctx->r1)); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: EC_KEY_new_by_curve_name(NID_secp224r1) + */ + + mbedtls_ecp_keypair_init(&ctx->key); + mbedtls_ecp_group_load(&(ctx->key.grp), MBEDTLS_ECP_DP_SECP224R1); + rv = mbedtls_ecp_gen_keypair(&(ctx->key.grp), &(ctx->key.d), &(ctx->key.Q), mbedtls_platform_frng, + NULL); + CHECK_RV_GOTO(rv, cleanup); + +cleanup: + if (rv) + { + XMEMSET(ctx, 0, sizeof(struct fm_crypto_ckg_context)); + } + + return rv; +} + +void fm_crypto_ckg_free(fm_crypto_ckg_context_t ctx) +{ + mbedtls_ecp_keypair_free(&ctx->key); + if (ctx->p) + { + mbedtls_ecp_point_free(ctx->p); + os_mem_free(ctx->p); + } + + XMEMSET(ctx, 0, sizeof(struct fm_crypto_ckg_context)); +} + +int fm_crypto_ckg_gen_c1(fm_crypto_ckg_context_t ctx, byte out[32]) +{ + // Construct s || r. + byte msg[28 + sizeof(ctx->r1)]; + XMEMCPY(msg + 28, ctx->r1, sizeof(ctx->r1)); + + /* + * OpenSSL: BN_bn2bin() + EC_KEY_get0_private_key() + */ + int rv = mbedtls_mpi_write_binary(&ctx->key.d, msg, 28); + CHECK_RV(rv); + + /* + * OpenSSL: SHA256() + */ + return fm_crypto_sha256(sizeof(msg), msg, out); +} + +/*! @function _fm_crypto_points_add + @abstract Adds two given points on an elliptic curve. + + @param r Resulting EC point r = s + t. + @param s EC point s. + @param t EC point t. + @param dp Curve parameters. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_points_add(mbedtls_ecp_point *r, + mbedtls_ecp_point *s, + mbedtls_ecp_point *t, + const mbedtls_ecp_group *dp) +{ + mbedtls_mpi m; + mbedtls_mpi_init(&m); + mbedtls_mpi_lset(&m, 1); + + int rv = mbedtls_ecp_muladd((mbedtls_ecp_group *)dp, r, &m, s, &m, t); + CHECK_RV_GOTO(rv, cleanup); + +cleanup: + mbedtls_mpi_free(&m); + return rv; +} + +int fm_crypto_ckg_gen_c3(fm_crypto_ckg_context_t ctx, + const byte c2[89], + byte out[60]) +{ + /* + * OpenSSL: EC_KEY_new_by_curve_name(NID_secp224r1) + */ + mbedtls_ecp_point S; + mbedtls_ecp_point_init(&S); + + /* + * Import and check S'. + * + * OpenSSL: EC_POINT_set_affine_coordinates_GFp() + */ + mbedtls_ecp_group grp; + mbedtls_ecp_group_init(&grp); + int rv = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP224R1); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_ecp_point_read_binary(&grp, &S, c2, 1 + 28 * 2); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: EC_POINT_is_on_curve() + */ + rv = mbedtls_ecp_check_pubkey(&grp, &S); + CHECK_RV_GOTO(rv, cleanup); + + /* + * Compute S + S'. + * + * OpenSSL: EC_POINT_add() + */ + rv = _fm_crypto_points_add(ctx->p, &ctx->key.Q, &S, &grp); + CHECK_RV_GOTO(rv, cleanup); + + /* + * C3 := s || r + * + * OpenSSL: BN_bn2bin() + EC_KEY_get0_private_key() + */ + rv = mbedtls_mpi_write_binary(&ctx->key.d, out, 28); + CHECK_RV_GOTO(rv, cleanup); + + XMEMCPY(out + 28, ctx->r1, sizeof(ctx->r1)); + + // Store r'. + XMEMCPY(ctx->r2, c2 + 1 + 28 * 2, sizeof(ctx->r2)); + +cleanup: + mbedtls_ecp_point_free(&S); + mbedtls_ecp_group_free(&grp); + return rv; +} + +int fm_crypto_ckg_finish(fm_crypto_ckg_context_t ctx, + byte p[57], + byte skn[32], + byte sks[32]) +{ + byte x[28]; + + /* + * OpenSSL: BN_bn2bin() + EC_POINT_get_affine_coordinates_GFp() + */ + mbedtls_mpi_write_binary(&ctx->p->X, x, 28); + + byte r1r2[32 * 2]; + XMEMCPY(r1r2, ctx->r1, 32); + XMEMCPY(r1r2 + 32, ctx->r2, 32); + + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte sk[32 * 2]; + int rv = mbed_KDF963(MBED_KDF963_SHA256, + x, sizeof(x), /* Z */ + r1r2, sizeof(r1r2), /* sharedinfo */ + sk, sizeof(sk)); /* derived key */ + CHECK_RV(rv); + + XMEMCPY(skn, sk, 32); + XMEMCPY(sks, sk + 32, 32); + + /* + * Write uncompressed point in X9.63 format. + * + * OpenSSL: BN_bn2bin() + EC_POINT_get_affine_coordinates_GFp() + */ + p[0] = 0x04; + rv = mbedtls_mpi_write_binary(&ctx->p->X, p + 1, 28); + CHECK_RV(rv); + + return mbedtls_mpi_write_binary(&ctx->p->Y, p + 1 + 28, 28); +} + +int fm_crypto_roll_sk(const byte sk[32], byte out[32]) +{ + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + return mbed_KDF963(MBED_KDF963_SHA256, + (uint8_t *)sk, 32, /* Z */ + (uint8_t *)KDF_LABEL_UPDATE, sizeof(KDF_LABEL_UPDATE) - 1, /* sharedinfo */ + out, 32); /* derived key */ +} + +int fm_crypto_derive_ltk(const byte skn[32], byte out[16]) +{ + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte ik[32]; + int rv = mbed_KDF963(MBED_KDF963_SHA256, + (uint8_t *)skn, 32, /* Z */ + (uint8_t *)KDF_LABEL_INTERMEDIATE, sizeof(KDF_LABEL_INTERMEDIATE) - 1, /* sharedinfo */ + ik, sizeof(ik)); /* derived key */ + CHECK_RV(rv); + + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + return mbed_KDF963(MBED_KDF963_SHA256, + ik, sizeof(ik), /* Z */ + (uint8_t *)KDF_LABEL_CONNECT, sizeof(KDF_LABEL_CONNECT) - 1, /* sharedinfo */ + out, 16); /* derived key */ +} + +/*! @function _fm_crypto_scmult + @abstract Scalar multiplication on an elliptic curve. + + @param r Resulting EC point r = s * B. + @param s Scalar s. + @param B Base point B. + @param dp Curve parameters. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_scmult(mbedtls_ecp_point *r, + mbedtls_mpi *s, + mbedtls_ecp_point *B, + const mbedtls_ecp_group *dp) +{ + int rv = mbedtls_ecp_mul((mbedtls_ecp_group *)dp, r, s, B, mbedtls_platform_frng, NULL); + + return rv; +} + +/*! @function _fm_crypto_scmult_reduce + @abstract Takes a 36-byte value uv, reduces it to a valid scalar s, + and computes r = s * B. + + @param r Resulting EC point r = (uv (mod q-1) + 1) * B. + @param uv 36-byte pre-scalar value. + @param B Base point B. + @param dp Curve parameters. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_scmult_reduce(mbedtls_ecp_point *r, + const byte uv[36], + mbedtls_ecp_point *B, + const mbedtls_ecp_group *dp) +{ + mbedtls_mpi s; + mbedtls_mpi_init(&s); + + mbedtls_mpi qm1; + mbedtls_mpi_init(&qm1); + + int rv = mbedtls_mpi_read_binary(&s, uv, 28 + 8); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_copy(&qm1, &dp->N); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_sub_int(&qm1, &qm1, 1); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_mod_mpi(&s, &s, &qm1); + CHECK_RV_GOTO(rv, cleanup); + + /* + * s := u (mod q-1) + 1 + * + * OpenSSL: BN_add_word() + */ + rv = mbedtls_mpi_add_int(&s, &s, 1); + CHECK_RV_GOTO(rv, cleanup); + + rv = _fm_crypto_scmult(r, &s, B, dp); + +cleanup: + mbedtls_mpi_free(&s); + mbedtls_mpi_free(&qm1); + + return rv; +} + +/*! @function _fm_crypto_scmult_twin_reduce + @abstract Takes two 36-byte values u and v, reduces them to valid scalars s + and t, a and computes r = s * P + t * G. + + @param r Resulting EC point r = (u (mod q-1) + 1) * P + (v (mod q-1) + 1) * G. + @param u 36-byte pre-scalar value. + @param v 36-byte pre-scalar value. + @param P EC point P. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_scmult_twin_reduce(mbedtls_ecp_point *r, + const byte u[36], + const byte v[36], + mbedtls_ecp_keypair *P) +{ + int rv; + /* + * OpenSSL: EC_GROUP_new_by_curve_name(NID_secp224r1) + EC_POINT_new() + */ + mbedtls_ecp_point r1; + mbedtls_ecp_point_init(&r1); + + /* + * OpenSSL: EC_GROUP_new_by_curve_name(NID_secp224r1) + EC_POINT_new() + */ + mbedtls_ecp_point r2; + mbedtls_ecp_point_init(&r2); + + /* + * OpenSSL: EC_GROUP_new_by_curve_name(NID_secp224r1) + EC_POINT_new() + */ + mbedtls_ecp_point g; + mbedtls_ecp_point_init(&g); + + rv = mbedtls_mpi_copy(&g.X, &P->grp.G.X); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_copy(&g.Y, &P->grp.G.Y); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_lset(&g.Z, 1); + CHECK_RV_GOTO(rv, cleanup); + + rv = _fm_crypto_scmult_reduce(&r1, u, &P->Q, &P->grp); + CHECK_RV_GOTO(rv, cleanup); + /* + * OpenSSL: EC_POINT_mul() + */ + rv = _fm_crypto_scmult_reduce(&r2, v, &g, &P->grp); + CHECK_RV_GOTO(rv, cleanup); + + rv = _fm_crypto_points_add(r, &r1, &r2, &P->grp); + +cleanup: + mbedtls_ecp_point_free(&r1); + mbedtls_ecp_point_free(&r2); + mbedtls_ecp_point_free(&g); + + return rv; +} + +int fm_crypto_derive_primary_or_secondary_x(const byte sk[32], + const byte p[57], + byte out[28]) +{ + int rv = 0; + /* + * OpenSSL: EC_KEY_new_by_curve_name(NID_secp224r1) + */ + mbedtls_ecp_keypair P; + mbedtls_ecp_keypair_init(&P); + + /* + * OpenSSL: EC_GROUP_new_by_curve_name(NID_secp224r1) + EC_POINT_new() + */ + mbedtls_ecp_point r; + mbedtls_ecp_point_init(&r); + + /* + * OpenSSL: EC_POINT_set_affine_coordinates_GFp() + */ + rv = mbedtls_ecp_group_load(&P.grp, MBEDTLS_ECP_DP_SECP224R1); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_ecp_point_read_binary(&P.grp, &P.Q, p, 1 + 28 * 2); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: EC_POINT_is_on_curve() + */ + rv = mbedtls_ecp_check_pubkey(&P.grp, &P.Q); + + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte at[2 * (28 + 8)]; + rv = mbed_KDF963(MBED_KDF963_SHA256, (uint8_t *)sk, 32, + (uint8_t *)KDF_LABEL_DIVERSIFY, sizeof(KDF_LABEL_DIVERSIFY) - 1, /* sharedinfo */ + at, sizeof(at)); + CHECK_RV_GOTO(rv, cleanup); + + rv = _fm_crypto_scmult_twin_reduce(&r, at, &at[28 + 8], &P); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: BN_bn2bin() + EC_POINT_get_affine_coordinates_GFp() + */ + rv = mbedtls_mpi_write_binary(&r.X, out, 28); + +cleanup: + mbedtls_ecp_keypair_free(&P); + mbedtls_ecp_point_free(&r); + return rv; +} + +int fm_crypto_derive_server_shared_secret(const byte seeds[32], + const byte seedk1[32], + byte out[32]) +{ + byte ikm[2 * 32]; + XMEMCPY(ikm, seeds, 32); + XMEMCPY(ikm + 32, seedk1, 32); + + /* + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + return mbed_KDF963(MBED_KDF963_SHA256, + ikm, sizeof(ikm), /* Z */ + (uint8_t *)KDF_LABEL_SERVERSS, sizeof(KDF_LABEL_SERVERSS) - 1, /* sharedinfo */ + out, 32); /* derived key */ +} + +/*! @function _fm_crypto_aes128gcm_encrypt + @abstract Encrypts a message using AES-128-GCM. + + @param key 128-bit AES key. + @param iv 128-bit IV. + @param msg_nbytes Byte length of message. + @param msg Message. + @param out Output buffer for the ciphertext. + @param tag Output buffer for the 128-bit authentication tag. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_aes128gcm_encrypt(const byte key[16], + const byte iv[16], + word32 msg_nbytes, + const byte *msg, + byte *out, + byte *tag) +{ + mbedtls_gcm_context gcm_ctx; + mbedtls_gcm_init(&gcm_ctx); + int rv = mbedtls_gcm_setkey(&gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, 128); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: EVP_Encrypt*() + EVP_aes_128_gcm() + */ + rv = mbedtls_gcm_crypt_and_tag(&gcm_ctx, MBEDTLS_GCM_ENCRYPT, msg_nbytes, iv, 16, NULL, 0, msg, out, + 16, tag); + +cleanup: + mbedtls_gcm_free(&gcm_ctx); + return rv; +} + + +/*! @function _fm_crypto_aes128gcm_decrypt + @abstract Decrypts a ciphertext using AES-128-GCM. + + @param key 128-bit AES key. + @param iv 128-bit IV. + @param ct_nbytes Byte length of ciphertext. + @param ct Ciphertext. + @param tag 128-bit authentication tag. + @param out Output buffer for the plaintext. + + @return 0 on success, a negative value on error. + */ +static int _fm_crypto_aes128gcm_decrypt(const byte key[16], + const byte iv[16], + word32 ct_nbytes, + const byte *ct, + const byte *tag, + byte *out) +{ + mbedtls_gcm_context gcm_ctx; + mbedtls_gcm_init(&gcm_ctx); + int rv = mbedtls_gcm_setkey(&gcm_ctx, MBEDTLS_CIPHER_ID_AES, key, 128); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_gcm_auth_decrypt(&gcm_ctx, ct_nbytes, iv, 16, NULL, 0, tag, 16, ct, out); + +cleanup: + mbedtls_gcm_free(&gcm_ctx); + return rv; +} + +int fm_crypto_decrypt_e3(const byte serverss[32], + word32 e3_nbytes, + const byte *e3, + word32 *out_nbytes, + byte *out) +{ + // E3 has the 16 byte tag appended. + if (e3_nbytes <= 16) + { + return -1; + } + + if (*out_nbytes < e3_nbytes - 16) + { + return -1; + } + + /* + * Derive K1 and IV1. + * + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte key_iv[32]; + int rv = mbed_KDF963(MBED_KDF963_SHA256, + (uint8_t *)serverss, 32, /* Z */ + (uint8_t *)KDF_LABEL_PAIRINGSESS, sizeof(KDF_LABEL_PAIRINGSESS) - 1, /* sharedinfo */ + key_iv, sizeof(key_iv)); /* derived key */ + CHECK_RV(rv); + + /* + * OpenSSL: EVP_Decrypt*() + EVP_aes_128_gcm() + */ + rv = _fm_crypto_aes128gcm_decrypt(key_iv, key_iv + 16, e3_nbytes - 16, e3, + e3 + e3_nbytes - 16, out); + CHECK_RV(rv); + + *out_nbytes = e3_nbytes - 16; + return rv; +} + +int fm_crypto_verify_s2(const byte pub[65], + word32 sig_nbytes, + const byte *sig, + word32 msg_nbytes, + const byte *msg) +{ + + mbedtls_ecdsa_context ctx; + mbedtls_ecdsa_init(&ctx); + + int rv = mbedtls_ecp_group_load(&ctx.grp, MBEDTLS_ECP_DP_SECP256R1); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_ecp_point_read_binary(&ctx.grp, &ctx.Q, pub, 1 + 32 * 2); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_ecp_check_pubkey(&ctx.grp, &ctx.Q); + CHECK_RV_GOTO(rv, cleanup); + + byte hash[32]; + rv = fm_crypto_sha256(msg_nbytes, msg, hash); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash), sig, sig_nbytes); + CHECK_RV_GOTO(rv, cleanup); + +cleanup: + mbedtls_ecdsa_free(&ctx); + + return rv; +} + +int fm_crypto_authenticate_with_ksn(const byte serverss[32], + word32 msg_nbytes, + const byte *msg, + byte out[32]) +{ + mbedtls_md_context_t md_ctx; + mbedtls_md_init(&md_ctx); + const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + /* + * Derive KSN. + * + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte ksn[32]; + int rv = mbed_KDF963(MBED_KDF963_SHA256, + (uint8_t *)serverss, 32, /* Z */ + (uint8_t *)KDF_LABEL_SNPROTECTION, sizeof(KDF_LABEL_SNPROTECTION) - 1, /* sharedinfo */ + ksn, sizeof(ksn)); /* derived key */ + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_md_setup(&md_ctx, info, 1); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_md_hmac_starts(&md_ctx, ksn, sizeof(ksn)); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_md_hmac_update(&md_ctx, msg, msg_nbytes); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_md_hmac_finish(&md_ctx, out); + CHECK_RV_GOTO(rv, cleanup); + +cleanup: + mbedtls_md_free(&md_ctx); + return rv; +} + +int fm_crypto_generate_seedk1(byte out[32]) +{ + int rv = mbedtls_platform_frng(NULL, out, 32); + return rv; +} + +int fm_crypto_encrypt_to_server(const byte pub[65], + word32 msg_nbytes, + const byte *msg, + word32 *out_nbytes, + byte *out) +{ + int rv = 0; + mbedtls_ecp_keypair key; + mbedtls_ecp_keypair_init(&key); + + mbedtls_ecp_keypair Q; + mbedtls_ecp_keypair_init(&Q); + + mbedtls_ecp_group_load(&(key.grp), MBEDTLS_ECP_DP_SECP256R1); + mbedtls_ecp_group_load(&(Q.grp), MBEDTLS_ECP_DP_SECP256R1); + + // Need space for Q || C || T. + if (*out_nbytes < 65 + msg_nbytes + 16) + { + return -1; + } + + word32 x_len = 0; + /* + * Import and check Q_E. + * + * OpenSSL: EC_POINT_set_affine_coordinates_GFp() + */ + rv = mbedtls_ecp_point_read_binary(&Q.grp, &Q.Q, pub, 1 + 32 * 2); + CHECK_RV_GOTO(rv, cleanup); + + /* + * OpenSSL: EC_POINT_is_on_curve() + */ + rv = mbedtls_ecp_check_pubkey(&Q.grp, &Q.Q); + CHECK_RV_GOTO(rv, cleanup); + + /* + * Generate ephemeral key. + * + * OpenSSL: EC_KEY_generate_key() + */ + rv = mbedtls_ecp_gen_keypair(&key.grp, &key.d, &key.Q, mbedtls_platform_frng, NULL); + CHECK_RV_GOTO(rv, cleanup); + + /* + * Generate shared secret. + * + * OpenSSL: ECDH_compute_key() + */ + byte x[32]; + x_len = (word32)sizeof(x); + mbedtls_mpi z; + mbedtls_mpi_init(&z); + + rv = mbedtls_ecdh_compute_shared(&key.grp, &z, &Q.Q, &key.d, mbedtls_platform_frng, NULL); + mbedtls_mpi_write_binary(&z, x, x_len); + CHECK_RV_GOTO(rv, cleanup); + assert(x_len == 32); + + // Compute sharedinfo. + byte info[2 * 65]; + XMEMCPY(info + 65, pub, 65); + + /* + * OpenSSL: BN_bn2bin() + EC_POINT_get_affine_coordinates_GFp() + */ + info[0] = 0x04; + rv = mbedtls_mpi_write_binary(&key.Q.X, info + 1, 32); + CHECK_RV_GOTO(rv, cleanup); + + rv = mbedtls_mpi_write_binary(&key.Q.Y, info + 1 + 32, 32); + CHECK_RV_GOTO(rv, cleanup); + + // Copy Q into out. + XMEMCPY(out, info, 65); + + /* + * Derive key and IV. + * + * OpenSSL: Custom X9.63 KDF implementation using SHA256() + */ + byte key_iv[32]; + rv = mbed_KDF963(MBED_KDF963_SHA256, + x, sizeof(x), /* Z */ + info, sizeof(info), /* sharedinfo */ + key_iv, sizeof(key_iv)); /* derived key */ + CHECK_RV_GOTO(rv, cleanup); + + /* + * Encrypt. + * + * OpenSSL: EVP_Encrypt*() + EVP_aes_128_gcm() + */ + rv = _fm_crypto_aes128gcm_encrypt(key_iv, key_iv + 16, msg_nbytes, msg, + out + 65, out + 65 + msg_nbytes); + CHECK_RV_GOTO(rv, cleanup); + + *out_nbytes = 65 + msg_nbytes + 16; + +cleanup: + mbedtls_ecp_keypair_free(&Q); + mbedtls_ecp_keypair_free(&key); + mbedtls_mpi_free(&z); + return rv; +} diff --git a/src/app/findmy/crypto/fm-crypto.h b/src/app/findmy/crypto/fm-crypto.h new file mode 100644 index 0000000..cb569a3 --- /dev/null +++ b/src/app/findmy/crypto/fm-crypto.h @@ -0,0 +1,220 @@ +/* + * need a license header here + */ + +/* + * WolfSSL shim, providing the core cryptographic functionality + * required to implement the FindMy protocol. + */ + +#ifndef FM_CRYPTO_H +#define FM_CRYPTO_H + +#include +#include +#include "mbedtls/sha256.h" +#include "mbedtls/kdf963.h" +#include "mbedtls/aes.h" +#include "mbedtls/gcm.h" +#include "mbedtls/ecdsa.h" +#include "mbedtls/md.h" +#include "mbedtls/ecdh.h" +#include + +typedef struct fm_crypto_ckg_context +{ + mbedtls_ecp_keypair key; + byte r1[32]; + byte r2[32]; + mbedtls_ecp_point *p; +} *fm_crypto_ckg_context_t; + +/*! @function fm_crypto_sha256 + @abstract Hashes a given message using SHA-256. + + @param msg_nbytes Byte length of message. + @param msg Message to hash. + @param out 32-byte output buffer for SHA-256 digest. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_sha256(word32 msg_nbytes, const byte *msg, byte out[32]); + +/*! @function fm_crypto_ckg_init + @abstract Initializes a given collaborative key generation context. + + @param ctx Collaborative key generation context. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_ckg_init(fm_crypto_ckg_context_t ctx); + +/*! @function fm_crypto_ckg_gen_c1 + @abstract Generates message C1. + + @param ctx Collaborative key generation context. + @param out 32-byte output buffer for C1. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_ckg_gen_c1(fm_crypto_ckg_context_t ctx, byte out[32]); + +/*! @function fm_crypto_ckg_gen_c3 + @abstract Generates message C3. + + @param ctx Collaborative key generation context. + @param c2 89-byte message C2 from the Apple device. + @param out 60-byte output buffer for C3. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_ckg_gen_c3(fm_crypto_ckg_context_t ctx, + const byte c2[89], + byte out[60]); + +/*! @function fm_crypto_ckg_finish + @abstract Finalizes collaborative key generation. + + @param ctx Collaborative key generation context. + @param p 57-byte output buffer for final public key P. + @param skn 32-byte output buffer for symmetric key SKN. + @param sks 32-byte output buffer for symmetric key SKS. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_ckg_finish(fm_crypto_ckg_context_t ctx, + byte p[57], + byte skn[32], + byte sks[32]); + +/*! @function fm_crypto_ckg_free + @abstract Frees a given collaborative key generation context. + + @param ctx Collaborative key generation context. + */ +void fm_crypto_ckg_free(fm_crypto_ckg_context_t ctx); + +/*! @function fm_crypto_generate_seedk1 + @abstract Generates SeedK1. + + @param out 32-byte output buffer for SeedK1. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_generate_seedk1(byte out[32]); + +/*! @function fm_crypto_derive_server_shared_secret + @abstract Derives the ServerSharedSecret. + + @param seeds 32-byte unique server seed for pairing. + @param seedk1 32-byte encryption key seed for pairing. + @param out 32-byte output buffer for ServerSharedSecret. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_derive_server_shared_secret(const byte seeds[32], + const byte seedk1[32], + byte out[32]); + +/*! @function fm_crypto_authenticate_with_ksn + @abstract Authenticates a given message using the KSN. + + @param serverss 32-byte ServerSharedSecret + @param msg_nbytes Byte length of message. + @param msg Message. + @param out 32-byte output buffer for MAC. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_authenticate_with_ksn(const byte serverss[32], + word32 msg_nbytes, + const byte *msg, + byte out[32]); + +/*! @function fm_crypto_encrypt_to_server + @abstract Encrypt a message to the Apple server. + + @param pub Apple server encryption key in X9.63 format. + @param msg_nbytes Byte length of message. + @param msg Message to encrypt. + @param out_nbytes Pointer to length of output buffer. + (MUST be at least 65 + msg_nbytes + 16.) + @param out Output buffer for ciphertext. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_encrypt_to_server(const byte pub[65], + word32 msg_nbytes, + const byte *msg, + word32 *out_nbytes, + byte *out); + +/*! @function fm_crypto_verify_s2 + @abstract Verifies signature S2 received from the server. + + @param pub Apple server signature verification key in X9.63 format. + @param sig_nbytes Byte length of the signature. + @param sig Signature over message. + @param msg_nbytes Byte length of message to verify. + @param msg Message to verify. + + @return 0 if the signature is valid, a negative value otherwise. + */ +int fm_crypto_verify_s2(const byte pub[65], + word32 sig_nbytes, + const byte *sig, + word32 msg_nbytes, + const byte *msg); + +/*! @function fm_crypto_decrypt_e3 + @abstract Decrypts server message E3. + + @param serverss 32-byte ServerSharedSecret + @param e3_nbytes Byte length of message E3. + @param e3 Message E3. + @param out_nbytes Pointer to length of output buffer. + (MUST be at least e3_nbytes - 16.) + @param out Output buffer for plaintext. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_decrypt_e3(const byte serverss[32], + word32 e3_nbytes, + const byte *e3, + word32 *out_nbytes, + byte *out); + +/*! @function fm_crypto_roll_sk + @abstract Computes SK_i+1 from a given SK_i. SK can be SKN or SKS. + + @param sk 32-byte symmetric key SKN_i or SKS_j. + @param out 32-byte output buffer for SKN_i+1 or SKS_j+1. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_roll_sk(const byte sk[32], byte out[32]); + +/*! @function fm_crypto_derive_ltk + @abstract Derives LTK_i from a given SKN_i. + + @param skn 32-byte symmetric key SKN_i. + @param out 16-byte output buffer for LTK_i. + + @return 0 on success, a negative value on error. + */ +int fm_crypto_derive_ltk(const byte skn[32], byte out[16]); + +/*! @function fm_crypto_derive_primary_or_secondary_x + @abstract Derives a primary key P_i or a secondary key PW_j. + + @param sk 32-byte symmetric key SKN_i or SKS_j. + @param p 57-byte public key P as generated at pairing. + @param out 28-byte output buffer for x(P_i) or x(PW_j). + + @return 0 on success, a negative value on error. + */ +int fm_crypto_derive_primary_or_secondary_x(const byte sk[32], + const byte p[57], + byte out[28]); + +#endif // FM_CRYPTO_H diff --git a/src/app/findmy/crypto/third-party/mbedtls/aes.h b/src/app/findmy/crypto/third-party/mbedtls/aes.h new file mode 100644 index 0000000..77ecffd --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/aes.h @@ -0,0 +1,627 @@ +/** + * \file aes.h + * + * \brief This file contains AES definitions and functions. + * + * The Advanced Encryption Standard (AES) specifies a FIPS-approved + * cryptographic algorithm that can be used to protect electronic + * data. + * + * The AES algorithm is a symmetric block cipher that can + * encrypt and decrypt information. For more information, see + * FIPS Publication 197: Advanced Encryption Standard and + * ISO/IEC 18033-2:2006: Information technology -- Security + * techniques -- Encryption algorithms -- Part 2: Asymmetric + * ciphers. + * + * The AES-XTS block mode is standardized by NIST SP 800-38E + * + * and described in detail by IEEE P1619 + * . + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_AES_H +#define MBEDTLS_AES_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" +#include "mbedtls/platform_util.h" + +#include +#include + +/* padlock.c and aesni.c rely on these values! */ +#define MBEDTLS_AES_ENCRYPT 1 /**< AES encryption. */ +#define MBEDTLS_AES_DECRYPT 0 /**< AES decryption. */ + +/* Error codes in range 0x0020-0x0022 */ +/** Invalid key length. */ +#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 +/** Invalid data input length. */ +#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 + +/* Error codes in range 0x0021-0x0025 */ +/** Invalid input data. */ +#define MBEDTLS_ERR_AES_BAD_INPUT_DATA -0x0021 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_AES_ALT) +// Regular implementation +// + +/** + * \brief The AES context-type definition. + */ +typedef struct mbedtls_aes_context { + int MBEDTLS_PRIVATE(nr); /*!< The number of rounds. */ + size_t MBEDTLS_PRIVATE(rk_offset); /*!< The offset in array elements to AES + round keys in the buffer. */ +#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C) + uint32_t MBEDTLS_PRIVATE(buf)[44]; /*!< Aligned data buffer to hold + 10 round keys for 128-bit case. */ +#else + uint32_t MBEDTLS_PRIVATE(buf)[68]; /*!< Unaligned data buffer. This buffer can + hold 32 extra Bytes, which can be used for + one of the following purposes: +
    • Alignment if VIA padlock is + used.
    • +
    • Simplifying key expansion in the 256-bit + case by generating an extra round key. +
    */ +#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH && !MBEDTLS_PADLOCK_C */ +} +mbedtls_aes_context; + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief The AES XTS context-type definition. + */ +typedef struct mbedtls_aes_xts_context { + mbedtls_aes_context MBEDTLS_PRIVATE(crypt); /*!< The AES context to use for AES block + encryption or decryption. */ + mbedtls_aes_context MBEDTLS_PRIVATE(tweak); /*!< The AES context used for tweak + computation. */ +} mbedtls_aes_xts_context; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#else /* MBEDTLS_AES_ALT */ +#include "aes_alt.h" +#endif /* MBEDTLS_AES_ALT */ + +/** + * \brief This function initializes the specified AES context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_init(mbedtls_aes_context *ctx); + +/** + * \brief This function releases and clears the specified AES context. + * + * \param ctx The AES context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_free(mbedtls_aes_context *ctx); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. This must not be \c NULL. + */ +void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + * If this is \c NULL, this function does nothing. + * Otherwise, the context must have been at least initialized. + */ +void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function sets the encryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed in bits. Valid options are: + *
    • 128 bits
    • + *
    • 192 bits
    • + *
    • 256 bits
    + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits); + +/** + * \brief This function sets the decryption key. + * + * \param ctx The AES context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of data passed. Valid options are: + *
    • 128 bits
    • + *
    • 192 bits
    • + *
    • 256 bits
    + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits); + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • + *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits); + +/** + * \brief This function prepares an XTS context for decryption and + * sets the decryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * It must be initialized. + * \param key The decryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * This must be a readable buffer of size \p keybits bits. + * \param keybits The size of \p key passed in bits. Valid options are: + *
    • 256 bits (each of key1 and key2 is a 128-bit key)
    • + *
    • 512 bits (each of key1 and key2 is a 256-bit key)
    + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * \brief This function performs an AES single-block encryption or + * decryption operation. + * + * It performs the operation defined in the \p mode parameter + * (encrypt or decrypt), on the input data buffer defined in + * the \p input parameter. + * + * mbedtls_aes_init(), and either mbedtls_aes_setkey_enc() or + * mbedtls_aes_setkey_dec() must be called before the first + * call to this API with the same context. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param input The buffer holding the input data. + * It must be readable and at least \c 16 Bytes long. + * \param output The buffer where the output data will be written. + * It must be writeable and at least \c 16 Bytes long. + + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16]); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief This function performs an AES-CBC encryption or decryption operation + * on full blocks. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined in + * the \p input parameter. + * + * It can be called as many times as needed, until all the input + * data is processed. mbedtls_aes_init(), and either + * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called + * before the first call to this API with the same context. + * + * \note This function operates on full blocks, that is, the input size + * must be a multiple of the AES block size of \c 16 Bytes. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the IV, you should + * either save it manually or use the cipher module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. This must be a + * multiple of the block size (\c 16 Bytes). + * \param iv Initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH + * on failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function performs an AES-XTS encryption or decryption + * operation for an entire XTS data unit. + * + * AES-XTS encrypts or decrypts blocks based on their location as + * defined by a data unit number. The data unit number must be + * provided by \p data_unit. + * + * NIST SP 800-38E limits the maximum size of a data unit to 2^20 + * AES blocks. If the data unit is larger than this, this function + * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. + * + * \param ctx The AES XTS context to use for AES XTS operations. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of a data unit in Bytes. This can be any + * length between 16 bytes and 2^24 bytes inclusive + * (between 1 and 2^20 block cipher blocks). + * \param data_unit The address of the data unit encoded as an array of 16 + * bytes in little-endian format. For disk encryption, this + * is typically the index of the block device sector that + * contains the data. + * \param input The buffer holding the input data (which is an entire + * data unit). This function reads \p length Bytes from \p + * input. + * \param output The buffer holding the output data (which is an entire + * data unit). This function writes \p length Bytes to \p + * output. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is + * smaller than an AES block in size (16 Bytes) or if \p + * length is larger than 2^20 blocks (16 MiB). + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/** + * \brief This function performs an AES-CFB128 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt or decrypt), on the input data buffer + * defined in the \p input parameter. + * + * For CFB, you must set up the context with mbedtls_aes_setkey_enc(), + * regardless of whether you are performing an encryption or decryption + * operation, that is, regardless of the \p mode parameter. This is + * because CFB mode uses the same key schedule for encryption and + * decryption. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you must either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of the input data in Bytes. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function performs an AES-CFB8 encryption or decryption + * operation. + * + * It performs the operation defined in the \p mode + * parameter (encrypt/decrypt), on the input data buffer defined + * in the \p input parameter. + * + * Due to the nature of CFB, you must use the same key schedule for + * both encryption and decryption operations. Therefore, you must + * use the context initialized with mbedtls_aes_setkey_enc() for + * both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \note Upon exit, the content of the IV is updated so that you can + * call the same function again on the next + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT + * \param length The length of the input data. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output); +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) + * encryption or decryption operation. + * + * For OFB, you must set up the context with + * mbedtls_aes_setkey_enc(), regardless of whether you are + * performing an encryption or decryption operation. This is + * because OFB mode uses the same key schedule for encryption and + * decryption. + * + * The OFB operation is identical for encryption or decryption, + * therefore no operation mode needs to be specified. + * + * \note Upon exit, the content of iv, the Initialisation Vector, is + * updated so that you can call the same function again on the next + * block(s) of data and get the same result as if it was encrypted + * in one call. This allows a "streaming" usage, by initialising + * iv_off to 0 before the first call, and preserving its value + * between calls. + * + * For non-streaming use, the iv should be initialised on each call + * to a unique value, and iv_off set to 0 on each call. + * + * If you need to retain the contents of the initialisation vector, + * you must either save it manually or use the cipher module + * instead. + * + * \warning For the OFB mode, the initialisation vector must be unique + * every encryption operation. Reuse of an initialisation vector + * will compromise security. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * It must point to a valid \c size_t. + * \param iv The initialization vector (updated after use). + * It must be a readable and writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output); + +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/** + * \brief This function performs an AES-CTR encryption or decryption + * operation. + * + * Due to the nature of CTR, you must use the same key schedule + * for both encryption and decryption operations. Therefore, you + * must use the context initialized with mbedtls_aes_setkey_enc() + * for both #MBEDTLS_AES_ENCRYPT and #MBEDTLS_AES_DECRYPT. + * + * \warning You must never reuse a nonce value with the same key. Doing so + * would void the encryption for the two messages encrypted with + * the same nonce and key. + * + * There are two common strategies for managing nonces with CTR: + * + * 1. You can handle everything as a single message processed over + * successive calls to this function. In that case, you want to + * set \p nonce_counter and \p nc_off to 0 for the first call, and + * then preserve the values of \p nonce_counter, \p nc_off and \p + * stream_block across calls to this function as they will be + * updated by this function. + * + * With this strategy, you must not encrypt more than 2**128 + * blocks of data with the same key. + * + * 2. You can encrypt separate messages by dividing the \p + * nonce_counter buffer in two areas: the first one used for a + * per-message nonce, handled by yourself, and the second one + * updated by this function internally. + * + * For example, you might reserve the first 12 bytes for the + * per-message nonce, and the last 4 bytes for internal use. In that + * case, before calling this function on a new message you need to + * set the first 12 bytes of \p nonce_counter to your chosen nonce + * value, the last 4 to 0, and \p nc_off to 0 (which will cause \p + * stream_block to be ignored). That way, you can encrypt at most + * 2**96 messages of up to 2**32 blocks each with the same key. + * + * The per-message nonce (or information sufficient to reconstruct + * it) needs to be communicated with the ciphertext and must be unique. + * The recommended way to ensure uniqueness is to use a message + * counter. An alternative is to generate random nonces, but this + * limits the number of messages that can be securely encrypted: + * for example, with 96-bit random nonces, you should not encrypt + * more than 2**32 messages with the same key. + * + * Note that for both strategies, sizes are measured in blocks and + * that an AES block is 16 bytes. + * + * \warning Upon return, \p stream_block contains sensitive data. Its + * content must not be written to insecure storage and should be + * securely discarded as soon as it's no longer needed. + * + * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. + * \param length The length of the input data. + * \param nc_off The offset in the current \p stream_block, for + * resuming within the current cipher stream. The + * offset pointer should be 0 at the start of a stream. + * It must point to a valid \c size_t. + * \param nonce_counter The 128-bit nonce and counter. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param stream_block The saved stream block for resuming. This is + * overwritten by the function. + * It must be a readable-writeable buffer of \c 16 Bytes. + * \param input The buffer holding the input data. + * It must be readable and of size \p length Bytes. + * \param output The buffer holding the output data. + * It must be writeable and of size \p length Bytes. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/** + * \brief Internal AES block encryption function. This is only + * exposed to allow overriding it using + * \c MBEDTLS_AES_ENCRYPT_ALT. + * + * \param ctx The AES context to use for encryption. + * \param input The plaintext block. + * \param output The output (ciphertext) block. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16]); + +/** + * \brief Internal AES block decryption function. This is only + * exposed to allow overriding it using see + * \c MBEDTLS_AES_DECRYPT_ALT. + * + * \param ctx The AES context to use for decryption. + * \param input The ciphertext block. + * \param output The output (plaintext) block. + * + * \return \c 0 on success. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16]); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_aes_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/asn1.h b/src/app/findmy/crypto/third-party/mbedtls/asn1.h new file mode 100644 index 0000000..830458b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/asn1.h @@ -0,0 +1,641 @@ +/** + * \file asn1.h + * + * \brief Generic ASN.1 parsing + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_ASN1_H +#define MBEDTLS_ASN1_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" +#include "mbedtls/platform_util.h" + +#include + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +/** + * \addtogroup asn1_module + * \{ + */ + +/** + * \name ASN1 Error codes + * These error codes are combined with other error codes for + * higher error granularity. + * e.g. X.509 and PKCS #7 error codes + * ASN1 is a standard to specify data structures. + * \{ + */ +/** Out of data when parsing an ASN1 data structure. */ +#define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 +/** ASN1 tag was of an unexpected value. */ +#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 +/** Error when trying to determine the length or invalid length. */ +#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 +/** Actual length differs from expected length. */ +#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 +/** Data is invalid. */ +#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 +/** Memory allocation failed */ +#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A +/** Buffer too small when writing ASN.1 data structure. */ +#define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C + +/** \} name ASN1 Error codes */ + +/** + * \name DER constants + * These constants comply with the DER encoded ASN.1 type tags. + * DER encoding uses hexadecimal representation. + * An example DER sequence is:\n + * - 0x02 -- tag indicating INTEGER + * - 0x01 -- length in octets + * - 0x05 -- value + * Such sequences are typically read into \c ::mbedtls_x509_buf. + * \{ + */ +#define MBEDTLS_ASN1_BOOLEAN 0x01 +#define MBEDTLS_ASN1_INTEGER 0x02 +#define MBEDTLS_ASN1_BIT_STRING 0x03 +#define MBEDTLS_ASN1_OCTET_STRING 0x04 +#define MBEDTLS_ASN1_NULL 0x05 +#define MBEDTLS_ASN1_OID 0x06 +#define MBEDTLS_ASN1_ENUMERATED 0x0A +#define MBEDTLS_ASN1_UTF8_STRING 0x0C +#define MBEDTLS_ASN1_SEQUENCE 0x10 +#define MBEDTLS_ASN1_SET 0x11 +#define MBEDTLS_ASN1_PRINTABLE_STRING 0x13 +#define MBEDTLS_ASN1_T61_STRING 0x14 +#define MBEDTLS_ASN1_IA5_STRING 0x16 +#define MBEDTLS_ASN1_UTC_TIME 0x17 +#define MBEDTLS_ASN1_GENERALIZED_TIME 0x18 +#define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C +#define MBEDTLS_ASN1_BMP_STRING 0x1E +#define MBEDTLS_ASN1_PRIMITIVE 0x00 +#define MBEDTLS_ASN1_CONSTRUCTED 0x20 +#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 + +/* Slightly smaller way to check if tag is a string tag + * compared to canonical implementation. */ +#define MBEDTLS_ASN1_IS_STRING_TAG(tag) \ + ((unsigned int) (tag) < 32u && ( \ + ((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING) | \ + (1u << MBEDTLS_ASN1_UTF8_STRING) | \ + (1u << MBEDTLS_ASN1_T61_STRING) | \ + (1u << MBEDTLS_ASN1_IA5_STRING) | \ + (1u << MBEDTLS_ASN1_UNIVERSAL_STRING) | \ + (1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0)) + +/* + * Bit masks for each of the components of an ASN.1 tag as specified in + * ITU X.690 (08/2015), section 8.1 "General rules for encoding", + * paragraph 8.1.2.2: + * + * Bit 8 7 6 5 1 + * +-------+-----+------------+ + * | Class | P/C | Tag number | + * +-------+-----+------------+ + */ +#define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0 +#define MBEDTLS_ASN1_TAG_PC_MASK 0x20 +#define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F + +/** \} name DER constants */ + +/** Returns the size of the binary string, without the trailing \\0 */ +#define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1) + +/** + * Compares an mbedtls_asn1_buf structure to a reference OID. + * + * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a + * 'unsigned char *oid' here! + */ +#define MBEDTLS_OID_CMP(oid_str, oid_buf) \ + ((MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len) || \ + memcmp((oid_str), (oid_buf)->p, (oid_buf)->len) != 0) + +#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \ + ((MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len)) || \ + memcmp((oid_str), (oid_buf), (oid_buf_len)) != 0) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Functions to parse ASN.1 data structures + * \{ + */ + +/** + * Type-length-value structure that allows for ASN1 using DER. + */ +typedef struct mbedtls_asn1_buf { + int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */ + size_t len; /**< ASN1 length, in octets. */ + unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ +} +mbedtls_asn1_buf; + +/** + * Container for ASN1 bit strings. + */ +typedef struct mbedtls_asn1_bitstring { + size_t len; /**< ASN1 length, in octets. */ + unsigned char unused_bits; /**< Number of unused bits at the end of the string */ + unsigned char *p; /**< Raw ASN1 data for the bit string */ +} +mbedtls_asn1_bitstring; + +/** + * Container for a sequence of ASN.1 items + */ +typedef struct mbedtls_asn1_sequence { + mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ + + /** The next entry in the sequence. + * + * The details of memory management for sequences are not documented and + * may change in future versions. Set this field to \p NULL when + * initializing a structure, and do not modify it except via Mbed TLS + * library functions. + */ + struct mbedtls_asn1_sequence *next; +} +mbedtls_asn1_sequence; + +/** + * Container for a sequence or list of 'named' ASN.1 data items + */ +typedef struct mbedtls_asn1_named_data { + mbedtls_asn1_buf oid; /**< The object identifier. */ + mbedtls_asn1_buf val; /**< The named value. */ + + /** The next entry in the sequence. + * + * The details of memory management for named data sequences are not + * documented and may change in future versions. Set this field to \p NULL + * when initializing a structure, and do not modify it except via Mbed TLS + * library functions. + */ + struct mbedtls_asn1_named_data *next; + + /** Merge next item into the current one? + * + * This field exists for the sake of Mbed TLS's X.509 certificate parsing + * code and may change in future versions of the library. + */ + unsigned char MBEDTLS_PRIVATE(next_merged); +} +mbedtls_asn1_named_data; + +#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) +/** + * \brief Get the length of an ASN.1 element. + * Updates the pointer to immediately behind the length. + * + * \param p On entry, \c *p points to the first byte of the length, + * i.e. immediately after the tag. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. + */ +int mbedtls_asn1_get_len(unsigned char **p, + const unsigned char *end, + size_t *len); + +/** + * \brief Get the tag and length of the element. + * Check for the requested tag. + * Updates the pointer to immediately behind the tag and length. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * after the length, i.e. the first byte of the content. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On successful completion, \c *len contains the length + * read from the ASN.1 input. + * \param tag The expected tag. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start + * with the requested tag. + * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element + * would end beyond \p end. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable. + */ +int mbedtls_asn1_get_tag(unsigned char **p, + const unsigned char *end, + size_t *len, int tag); +#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */ + +#if defined(MBEDTLS_ASN1_PARSE_C) +/** + * \brief Retrieve a boolean ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value (\c 0 or \c 1). + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BOOLEAN. + */ +int mbedtls_asn1_get_bool(unsigned char **p, + const unsigned char *end, + int *val); + +/** + * \brief Retrieve an integer ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + */ +int mbedtls_asn1_get_int(unsigned char **p, + const unsigned char *end, + int *val); + +/** + * \brief Retrieve an enumerated ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param val On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 ENUMERATED. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + */ +int mbedtls_asn1_get_enum(unsigned char **p, + const unsigned char *end, + int *val); + +/** + * \brief Retrieve a bitstring ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param bs On success, ::mbedtls_asn1_bitstring information about + * the parsed value. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid BIT STRING. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. + */ +int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, + mbedtls_asn1_bitstring *bs); + +/** + * \brief Retrieve a bitstring ASN.1 tag without unused bits and its + * value. + * Updates the pointer to the beginning of the bit/octet string. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * of the content of the BIT STRING. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param len On success, \c *len is the length of the content in bytes. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with + * a valid BIT STRING with a nonzero number of unused bits. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 BIT STRING. + */ +int mbedtls_asn1_get_bitstring_null(unsigned char **p, + const unsigned char *end, + size_t *len); + +/** + * \brief Parses and splits an ASN.1 "SEQUENCE OF ". + * Updates the pointer to immediately behind the full sequence tag. + * + * This function allocates memory for the sequence elements. You can free + * the allocated memory with mbedtls_asn1_sequence_free(). + * + * \note On error, this function may return a partial list in \p cur. + * You must set `cur->next = NULL` before calling this function! + * Otherwise it is impossible to distinguish a previously non-null + * pointer from a pointer to an object allocated by this function. + * + * \note If the sequence is empty, this function does not modify + * \c *cur. If the sequence is valid and non-empty, this + * function sets `cur->buf.tag` to \p tag. This allows + * callers to distinguish between an empty sequence and + * a one-element sequence. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p is equal to \p end. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param cur A ::mbedtls_asn1_sequence which this function fills. + * When this function returns, \c *cur is the head of a linked + * list. Each node in this list is allocated with + * mbedtls_calloc() apart from \p cur itself, and should + * therefore be freed with mbedtls_free(). + * The list describes the content of the sequence. + * The head of the list (i.e. \c *cur itself) describes the + * first element, `*cur->next` describes the second element, etc. + * For each element, `buf.tag == tag`, `buf.len` is the length + * of the content of the content of the element, and `buf.p` + * points to the first byte of the content (i.e. immediately + * past the length of the element). + * Note that list elements may be allocated even on error. + * \param tag Each element of the sequence must have this tag. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains + * extra data after a valid SEQUENCE OF \p tag. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with + * an ASN.1 SEQUENCE in which an element has a tag that + * is different from \p tag. + * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 SEQUENCE. + */ +int mbedtls_asn1_get_sequence_of(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_sequence *cur, + int tag); +/** + * \brief Free a heap-allocated linked list presentation of + * an ASN.1 sequence, including the first element. + * + * There are two common ways to manage the memory used for the representation + * of a parsed ASN.1 sequence: + * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc(). + * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of(). + * When you have finished processing the sequence, + * call mbedtls_asn1_sequence_free() on `head`. + * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner, + * for example on the stack. Make sure that `head->next == NULL`. + * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of(). + * When you have finished processing the sequence, + * call mbedtls_asn1_sequence_free() on `head->cur`, + * then free `head` itself in the appropriate manner. + * + * \param seq The address of the first sequence component. This may + * be \c NULL, in which case this functions returns + * immediately. + */ +void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq); + +/** + * \brief Traverse an ASN.1 SEQUENCE container and + * call a callback for each entry. + * + * This function checks that the input is a SEQUENCE of elements that + * each have a "must" tag, and calls a callback function on the elements + * that have a "may" tag. + * + * For example, to validate that the input is a SEQUENCE of `tag1` and call + * `cb` on each element, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx); + * ``` + * + * To validate that the input is a SEQUENCE of ANY and call `cb` on + * each element, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx); + * ``` + * + * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING} + * and call `cb` on each element that is an OCTET STRING, use + * ``` + * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx); + * ``` + * + * The callback is called on the elements with a "may" tag from left to + * right. If the input is not a valid SEQUENCE of elements with a "must" tag, + * the callback is called on the elements up to the leftmost point where + * the input is invalid. + * + * \warning This function is still experimental and may change + * at any time. + * + * \param p The address of the pointer to the beginning of + * the ASN.1 SEQUENCE header. This is updated to + * point to the end of the ASN.1 SEQUENCE container + * on a successful invocation. + * \param end The end of the ASN.1 SEQUENCE container. + * \param tag_must_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_must_val. + * \param tag_must_val The required value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_must_mask. + * Mismatching tags lead to an error. + * For example, a value of \c 0 for both \p tag_must_mask + * and \p tag_must_val means that every tag is allowed, + * while a value of \c 0xFF for \p tag_must_mask means + * that \p tag_must_val is the only allowed tag. + * \param tag_may_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_may_val. + * \param tag_may_val The desired value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_may_mask. + * Mismatching tags will be silently ignored. + * For example, a value of \c 0 for \p tag_may_mask and + * \p tag_may_val means that any tag will be considered, + * while a value of \c 0xFF for \p tag_may_mask means + * that all tags with value different from \p tag_may_val + * will be ignored. + * \param cb The callback to trigger for each component + * in the ASN.1 SEQUENCE that matches \p tag_may_val. + * The callback function is called with the following + * parameters: + * - \p ctx. + * - The tag of the current element. + * - A pointer to the start of the current element's + * content inside the input. + * - The length of the content of the current element. + * If the callback returns a non-zero value, + * the function stops immediately, + * forwarding the callback's return value. + * \param ctx The context to be passed to the callback \p cb. + * + * \return \c 0 if successful the entire ASN.1 SEQUENCE + * was traversed without parsing or callback errors. + * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input + * contains extra data after a valid SEQUENCE + * of elements with an accepted tag. + * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts + * with an ASN.1 SEQUENCE in which an element has a tag + * that is not accepted. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 SEQUENCE. + * \return A non-zero error code forwarded from the callback + * \p cb in case the latter returns a non-zero value. + */ +int mbedtls_asn1_traverse_sequence_of( + unsigned char **p, + const unsigned char *end, + unsigned char tag_must_mask, unsigned char tag_must_val, + unsigned char tag_may_mask, unsigned char tag_may_val, + int (*cb)(void *ctx, int tag, + unsigned char *start, size_t len), + void *ctx); + +#if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Retrieve an integer ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the ASN.1 element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param X On success, the parsed value. + * + * \return 0 if successful. + * \return An ASN.1 error code if the input does not start with + * a valid ASN.1 INTEGER. + * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does + * not fit in an \c int. + * \return An MPI error code if the parsed value is too large. + */ +int mbedtls_asn1_get_mpi(unsigned char **p, + const unsigned char *end, + mbedtls_mpi *X); +#endif /* MBEDTLS_BIGNUM_C */ + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. + * \param params The buffer to receive the parameters. + * This is zeroized if there are no parameters. + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int mbedtls_asn1_get_alg(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params); + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no + * params. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p On entry, \c *p points to the start of the ASN.1 element. + * On successful completion, \c *p points to the first byte + * beyond the AlgorithmIdentifier element. + * On error, the value of \c *p is undefined. + * \param end End of data. + * \param alg The buffer to receive the OID. + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int mbedtls_asn1_get_alg_null(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg); + +/** + * \brief Find a specific named_data entry in a sequence or list based on + * the OID. + * + * \param list The list to seek through + * \param oid The OID to look for + * \param len Size of the OID + * + * \return NULL if not found, or a pointer to the existing entry. + */ +const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, + const char *oid, size_t len); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +/** + * \brief Free a mbedtls_asn1_named_data entry + * + * \deprecated This function is deprecated and will be removed in a + * future version of the library. + * Please use mbedtls_asn1_free_named_data_list() + * or mbedtls_asn1_free_named_data_list_shallow(). + * + * \param entry The named data entry to free. + * This function calls mbedtls_free() on + * `entry->oid.p` and `entry->val.p`. + */ +void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *entry); +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** + * \brief Free all entries in a mbedtls_asn1_named_data list. + * + * \param head Pointer to the head of the list of named data entries to free. + * This function calls mbedtls_free() on + * `entry->oid.p` and `entry->val.p` and then on `entry` + * for each list entry, and sets \c *head to \c NULL. + */ +void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head); + +/** + * \brief Free all shallow entries in a mbedtls_asn1_named_data list, + * but do not free internal pointer targets. + * + * \param name Head of the list of named data entries to free. + * This function calls mbedtls_free() on each list element. + */ +void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name); + +/** \} name Functions to parse ASN.1 data structures */ +/** \} addtogroup asn1_module */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#endif /* asn1.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/asn1write.h b/src/app/findmy/crypto/third-party/mbedtls/asn1write.h new file mode 100644 index 0000000..7af4aba --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/asn1write.h @@ -0,0 +1,389 @@ +/** + * \file asn1write.h + * + * \brief ASN.1 buffer writing functionality + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_ASN1_WRITE_H +#define MBEDTLS_ASN1_WRITE_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/asn1.h" + +#define MBEDTLS_ASN1_CHK_ADD(g, f) \ + do \ + { \ + if ((ret = (f)) < 0) \ + return ret; \ + else \ + (g) += ret; \ + } while (0) + +#define MBEDTLS_ASN1_CHK_CLEANUP_ADD(g, f) \ + do \ + { \ + if ((ret = (f)) < 0) \ + goto cleanup; \ + else \ + (g) += ret; \ + } while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) +/** + * \brief Write a length field in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param len The length value to write. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, + size_t len); +/** + * \brief Write an ASN.1 tag in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param tag The tag to write. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, + unsigned char tag); +#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */ + +#if defined(MBEDTLS_ASN1_WRITE_C) +/** + * \brief Write raw buffer data. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param buf The data buffer to write. + * \param size The length of the data buffer. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t size); + +#if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Write an arbitrary-precision number (#MBEDTLS_ASN1_INTEGER) + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param X The MPI to write. + * It must be non-negative. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, + const mbedtls_mpi *X); +#endif /* MBEDTLS_BIGNUM_C */ + +/** + * \brief Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start); + +/** + * \brief Write an OID tag (#MBEDTLS_ASN1_OID) and data + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param oid The OID to write. + * \param oid_len The length of the OID. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start, + const char *oid, size_t oid_len); + +/** + * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param oid The OID of the algorithm to write. + * \param oid_len The length of the algorithm's OID. + * \param par_len The length of the parameters, which must be already written. + * If 0, NULL parameters are added + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, + const unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len); + +/** + * \brief Write an AlgorithmIdentifier sequence in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param oid The OID of the algorithm to write. + * \param oid_len The length of the algorithm's OID. + * \param par_len The length of the parameters, which must be already written. + * \param has_par If there are any parameters. If 0, par_len must be 0. If 1 + * and \p par_len is 0, NULL parameters are added. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, + const unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len, int has_par); + +/** + * \brief Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param boolean The boolean value to write, either \c 0 or \c 1. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, + int boolean); + +/** + * \brief Write an int tag (#MBEDTLS_ASN1_INTEGER) and value + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param val The integer value to write. + * It must be non-negative. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val); + +/** + * \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value + * in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param val The integer value to write. + * + * \return The number of bytes written to \p p on success. + * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val); + +/** + * \brief Write a string in ASN.1 format using a specific + * string encoding tag. + + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param tag The string encoding tag to write, e.g. + * #MBEDTLS_ASN1_UTF8_STRING. + * \param text The string to write. + * \param text_len The length of \p text in bytes (which might + * be strictly larger than the number of characters). + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, + int tag, const char *text, + size_t text_len); + +/** + * \brief Write a string in ASN.1 format using the PrintableString + * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING). + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param text The string to write. + * \param text_len The length of \p text in bytes (which might + * be strictly larger than the number of characters). + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_printable_string(unsigned char **p, + const unsigned char *start, + const char *text, size_t text_len); + +/** + * \brief Write a UTF8 string in ASN.1 format using the UTF8String + * string encoding tag (#MBEDTLS_ASN1_UTF8_STRING). + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param text The string to write. + * \param text_len The length of \p text in bytes (which might + * be strictly larger than the number of characters). + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start, + const char *text, size_t text_len); + +/** + * \brief Write a string in ASN.1 format using the IA5String + * string encoding tag (#MBEDTLS_ASN1_IA5_STRING). + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param text The string to write. + * \param text_len The length of \p text in bytes (which might + * be strictly larger than the number of characters). + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start, + const char *text, size_t text_len); + +/** + * \brief Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and + * value in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param buf The bitstring to write. + * \param bits The total number of bits in the bitstring. + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t bits); + +/** + * \brief This function writes a named bitstring tag + * (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format. + * + * As stated in RFC 5280 Appendix B, trailing zeroes are + * omitted when encoding named bitstrings in DER. + * + * \note This function works backwards within the data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer which is used for bounds-checking. + * \param buf The bitstring to write. + * \param bits The total number of bits in the bitstring. + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_named_bitstring(unsigned char **p, + const unsigned char *start, + const unsigned char *buf, + size_t bits); + +/** + * \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING) + * and value in ASN.1 format. + * + * \note This function works backwards in data buffer. + * + * \param p The reference to the current position pointer. + * \param start The start of the buffer, for bounds-checking. + * \param buf The buffer holding the data to write. + * \param size The length of the data buffer \p buf. + * + * \return The number of bytes written to \p p on success. + * \return A negative error code on failure. + */ +int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t size); + +/** + * \brief Create or find a specific named_data entry for writing in a + * sequence or list based on the OID. If not already in there, + * a new entry is added to the head of the list. + * Warning: Destructive behaviour for the val data! + * + * \param list The pointer to the location of the head of the list to seek + * through (will be updated in case of a new entry). + * \param oid The OID to look for. + * \param oid_len The size of the OID. + * \param val The associated data to store. If this is \c NULL, + * no data is copied to the new or existing buffer. + * \param val_len The minimum length of the data buffer needed. + * If this is 0, do not allocate a buffer for the associated + * data. + * If the OID was already present, enlarge, shrink or free + * the existing buffer to fit \p val_len. + * + * \return A pointer to the new / existing entry on success. + * \return \c NULL if there was a memory allocation error. + */ +mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **list, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_ASN1_WRITE_C */ + +#endif /* MBEDTLS_ASN1_WRITE_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/base64.h b/src/app/findmy/crypto/third-party/mbedtls/base64.h new file mode 100644 index 0000000..8f459b7 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/base64.h @@ -0,0 +1,82 @@ +/** + * \file base64.h + * + * \brief RFC 1521 base64 encoding/decoding + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_BASE64_H +#define MBEDTLS_BASE64_H + +#include "mbedtls/build_info.h" + +#include + +/** Output buffer too small. */ +#define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A +/** Invalid character in input. */ +#define MBEDTLS_ERR_BASE64_INVALID_CHARACTER -0x002C + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encode a buffer into base64 format + * + * \param dst destination buffer + * \param dlen size of the destination buffer + * \param olen number of bytes written + * \param src source buffer + * \param slen amount of data to be encoded + * + * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. + * *olen is always updated to reflect the amount + * of data that has (or would have) been written. + * If that length cannot be represented, then no data is + * written to the buffer and *olen is set to the maximum + * length representable as a size_t. + * + * \note Call this function with dlen = 0 to obtain the + * required buffer size in *olen + */ +int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen); + +/** + * \brief Decode a base64-formatted buffer + * + * \param dst destination buffer (can be NULL for checking size) + * \param dlen size of the destination buffer + * \param olen number of bytes written + * \param src source buffer + * \param slen amount of data to be decoded + * + * \return 0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or + * MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is + * not correct. *olen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dst = NULL or dlen = 0 to obtain + * the required buffer size in *olen + */ +int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_base64_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* base64.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/bignum.h b/src/app/findmy/crypto/third-party/mbedtls/bignum.h new file mode 100644 index 0000000..abf991e --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/bignum.h @@ -0,0 +1,1094 @@ +/** + * \file bignum.h + * + * \brief Multi-precision integer library + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_BIGNUM_H +#define MBEDTLS_BIGNUM_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include + +#include "app_section.h" +#if defined(MBEDTLS_FS_IO) +#include +#endif + +/** An error occurred while reading from or writing to a file. */ +#define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 +/** There is an invalid character in the digit string. */ +#define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 +/** The buffer is too small to write to. */ +#define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 +/** The input arguments are negative or result in illegal output. */ +#define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A +/** The input argument for division is zero, which is not allowed. */ +#define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C +/** The input arguments are not acceptable. */ +#define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E +/** Memory allocation failed. */ +#define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 + +#define MBEDTLS_MPI_CHK(f) \ + do \ + { \ + if ((ret = (f)) != 0) \ + goto cleanup; \ + } while (0) + +/* + * Maximum size MPIs are allowed to grow to in number of limbs. + */ +#define MBEDTLS_MPI_MAX_LIMBS 10000 + +#if !defined(MBEDTLS_MPI_WINDOW_SIZE) +/* + * Maximum window size used for modular exponentiation. Default: 2 + * Minimum value: 1. Maximum value: 6. + * + * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used + * for the sliding window calculation. (So 64 by default) + * + * Reduction in size, reduces speed. + */ +#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ +#endif /* !MBEDTLS_MPI_WINDOW_SIZE */ + +#if !defined(MBEDTLS_MPI_MAX_SIZE) +/* + * Maximum size of MPIs allowed in bits and bytes for user-MPIs. + * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) + * + * Note: Calculations can temporarily result in larger MPIs. So the number + * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. + */ +#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ +#endif /* !MBEDTLS_MPI_MAX_SIZE */ + +#define MBEDTLS_MPI_MAX_BITS (8 * MBEDTLS_MPI_MAX_SIZE) /**< Maximum number of bits for usable MPIs. */ + +/* + * When reading from files with mbedtls_mpi_read_file() and writing to files with + * mbedtls_mpi_write_file() the buffer should have space + * for a (short) label, the MPI (in the provided radix), the newline + * characters and the '\0'. + * + * By default we assume at least a 10 char label, a minimum radix of 10 + * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). + * Autosized at compile time for at least a 10 char label, a minimum radix + * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. + * + * This used to be statically sized to 1250 for a maximum of 4096 bit + * numbers (1234 decimal chars). + * + * Calculate using the formula: + * MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + + * LabelSize + 6 + */ +#define MBEDTLS_MPI_MAX_BITS_SCALE100 (100 * MBEDTLS_MPI_MAX_BITS) +#define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 +#define MBEDTLS_MPI_RW_BUFFER_SIZE (((MBEDTLS_MPI_MAX_BITS_SCALE100 + \ + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / \ + MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6) + +/* + * Define the base integer type, architecture-wise. + * + * 32 or 64-bit integer types can be forced regardless of the underlying + * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 + * respectively and undefining MBEDTLS_HAVE_ASM. + * + * Double-width integers (e.g. 128-bit in 64-bit architectures) can be + * disabled by defining MBEDTLS_NO_UDBL_DIVISION. + */ +#if !defined(MBEDTLS_HAVE_INT32) + #if defined(_MSC_VER) && defined(_M_AMD64) +/* Always choose 64-bit when using MSC */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ +typedef int64_t mbedtls_mpi_sint; +typedef uint64_t mbedtls_mpi_uint; +#define MBEDTLS_MPI_UINT_MAX UINT64_MAX + #elif defined(__GNUC__) && ( \ + defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) || \ + (defined(__sparc__) && defined(__arch64__)) || \ + defined(__s390x__) || defined(__mips64) || \ + defined(__aarch64__)) + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* MBEDTLS_HAVE_INT64 */ +typedef int64_t mbedtls_mpi_sint; +typedef uint64_t mbedtls_mpi_uint; +#define MBEDTLS_MPI_UINT_MAX UINT64_MAX + #if !defined(MBEDTLS_NO_UDBL_DIVISION) +/* mbedtls_t_udbl defined as 128-bit unsigned int */ +typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(__ARMCC_VERSION) && defined(__aarch64__) +/* + * __ARMCC_VERSION is defined for both armcc and armclang and + * __aarch64__ is only defined by armclang when compiling 64-bit code + */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ +typedef int64_t mbedtls_mpi_sint; +typedef uint64_t mbedtls_mpi_uint; +#define MBEDTLS_MPI_UINT_MAX UINT64_MAX + #if !defined(MBEDTLS_NO_UDBL_DIVISION) +/* mbedtls_t_udbl defined as 128-bit unsigned int */ +typedef __uint128_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(MBEDTLS_HAVE_INT64) +/* Force 64-bit integers with unknown compiler */ +typedef int64_t mbedtls_mpi_sint; +typedef uint64_t mbedtls_mpi_uint; +#define MBEDTLS_MPI_UINT_MAX UINT64_MAX + #endif +#endif /* !MBEDTLS_HAVE_INT32 */ + +#if !defined(MBEDTLS_HAVE_INT64) +/* Default to 32-bit compilation */ + #if !defined(MBEDTLS_HAVE_INT32) + #define MBEDTLS_HAVE_INT32 + #endif /* !MBEDTLS_HAVE_INT32 */ +typedef int32_t mbedtls_mpi_sint; +typedef uint32_t mbedtls_mpi_uint; +#define MBEDTLS_MPI_UINT_MAX UINT32_MAX + #if !defined(MBEDTLS_NO_UDBL_DIVISION) +typedef uint64_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ +#endif /* !MBEDTLS_HAVE_INT64 */ + +/* + * Sanity check that exactly one of MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 is defined, + * so that code elsewhere doesn't have to check. + */ +#if (!(defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64))) || \ + (defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64)) +#error "Only 32-bit or 64-bit limbs are supported in bignum" +#endif + +/** \typedef mbedtls_mpi_uint + * \brief The type of machine digits in a bignum, called _limbs_. + * + * This is always an unsigned integer type with no padding bits. The size + * is platform-dependent. + */ + +/** \typedef mbedtls_mpi_sint + * \brief The signed type corresponding to #mbedtls_mpi_uint. + * + * This is always an signed integer type with no padding bits. The size + * is platform-dependent. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MPI structure + */ +typedef struct mbedtls_mpi { + /** Pointer to limbs. + * + * This may be \c NULL if \c n is 0. + */ + mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); + + /** Sign: -1 if the mpi is negative, 1 otherwise. + * + * The number 0 must be represented with `s = +1`. Although many library + * functions treat all-limbs-zero as equivalent to a valid representation + * of 0 regardless of the sign bit, there are exceptions, so bignum + * functions and external callers must always set \c s to +1 for the + * number zero. + * + * Note that this implies that calloc() or `... = {0}` does not create + * a valid MPI representation. You must call mbedtls_mpi_init(). + */ + signed short MBEDTLS_PRIVATE(s); + + /** Total number of limbs in \c p. */ + unsigned short MBEDTLS_PRIVATE(n); + /* Make sure that MBEDTLS_MPI_MAX_LIMBS fits in n. + * Use the same limit value on all platforms so that we don't have to + * think about different behavior on the rare platforms where + * unsigned short can store values larger than the minimum required by + * the C language, which is 65535. + */ +#if MBEDTLS_MPI_MAX_LIMBS > 65535 +#error "MBEDTLS_MPI_MAX_LIMBS > 65535 is not supported" +#endif +} +mbedtls_mpi; + +/** + * \brief Initialize an MPI context. + * + * This makes the MPI ready to be set or freed, + * but does not define a value for the MPI. + * + * \param X The MPI context to initialize. This must not be \c NULL. + */ +void mbedtls_mpi_init(mbedtls_mpi *X); + +/** + * \brief This function frees the components of an MPI context. + * + * \param X The MPI context to be cleared. This may be \c NULL, + * in which case this function is a no-op. If it is + * not \c NULL, it must point to an initialized MPI. + */ +void mbedtls_mpi_free(mbedtls_mpi *X); + +/** + * \brief Enlarge an MPI to the specified number of limbs. + * + * \note This function does nothing if the MPI is + * already large enough. + * + * \param X The MPI to grow. It must be initialized. + * \param nblimbs The target number of limbs. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs); + +/** + * \brief This function resizes an MPI downwards, keeping at least the + * specified number of limbs. + * + * If \c X is smaller than \c nblimbs, it is resized up + * instead. + * + * \param X The MPI to shrink. This must point to an initialized MPI. + * \param nblimbs The minimum number of limbs to keep. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed + * (this can only happen when resizing up). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs); + +/** + * \brief Make a copy of an MPI. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param Y The source MPI. This must point to an initialized MPI. + * + * \note The limb-buffer in the destination MPI is enlarged + * if necessary to hold the value in the source MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y); + +/** + * \brief Swap the contents of two MPIs. + * + * \param X The first MPI. It must be initialized. + * \param Y The second MPI. It must be initialized. + */ +void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y); + +/** + * \brief Perform a safe conditional copy of MPI which doesn't + * reveal whether the condition was true or not. + * + * \param X The MPI to conditionally assign to. This must point + * to an initialized MPI. + * \param Y The MPI to be assigned from. This must point to an + * initialized MPI. + * \param assign The condition deciding whether to perform the + * assignment or not. Must be either 0 or 1: + * * \c 1: Perform the assignment `X = Y`. + * * \c 0: Keep the original value of \p X. + * + * \note This function is equivalent to + * `if( assign ) mbedtls_mpi_copy( X, Y );` + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + * + * \warning If \p assign is neither 0 nor 1, the result of this function + * is indeterminate, and the resulting value in \p X might be + * neither its original value nor the value in \p Y. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign); + +/** + * \brief Perform a safe conditional swap which doesn't + * reveal whether the condition was true or not. + * + * \param X The first MPI. This must be initialized. + * \param Y The second MPI. This must be initialized. + * \param swap The condition deciding whether to perform + * the swap or not. Must be either 0 or 1: + * * \c 1: Swap the values of \p X and \p Y. + * * \c 0: Keep the original values of \p X and \p Y. + * + * \note This function is equivalent to + * if( swap ) mbedtls_mpi_swap( X, Y ); + * except that it avoids leaking any information about whether + * the swap was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + * + * \warning If \p swap is neither 0 nor 1, the result of this function + * is indeterminate, and both \p X and \p Y might end up with + * values different to either of the original ones. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + * + */ +int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap); + +/** + * \brief Store integer value in MPI. + * + * \param X The MPI to set. This must be initialized. + * \param z The value to use. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z); + +/** + * \brief Get a specific bit from an MPI. + * + * \param X The MPI to query. This must be initialized. + * \param pos Zero-based index of the bit to query. + * + * \return \c 0 or \c 1 on success, depending on whether bit \c pos + * of \c X is unset or set. + * \return A negative error code on failure. + */ +int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos); + +/** + * \brief Modify a specific bit in an MPI. + * + * \note This function will grow the target MPI if necessary to set a + * bit to \c 1 in a not yet existing limb. It will not grow if + * the bit should be set to \c 0. + * + * \param X The MPI to modify. This must be initialized. + * \param pos Zero-based index of the bit to modify. + * \param val The desired value of bit \c pos: \c 0 or \c 1. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val); + +/** + * \brief Return the number of bits of value \c 0 before the + * least significant bit of value \c 1. + * + * \note This is the same as the zero-based index of + * the least significant bit of value \c 1. + * + * \param X The MPI to query. + * + * \return The number of bits of value \c 0 before the least significant + * bit of value \c 1 in \p X. + */ +size_t mbedtls_mpi_lsb(const mbedtls_mpi *X); + +/** + * \brief Return the number of bits up to and including the most + * significant bit of value \c 1. + * + * * \note This is same as the one-based index of the most + * significant bit of value \c 1. + * + * \param X The MPI to query. This must point to an initialized MPI. + * + * \return The number of bits up to and including the most + * significant bit of value \c 1. + */ +size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X); + +/** + * \brief Return the total size of an MPI value in bytes. + * + * \param X The MPI to use. This must point to an initialized MPI. + * + * \note The value returned by this function may be less than + * the number of bytes used to store \p X internally. + * This happens if and only if there are trailing bytes + * of value zero. + * + * \return The least number of bytes capable of storing + * the absolute value of \p X. + */ +size_t mbedtls_mpi_size(const mbedtls_mpi *X); + +/** + * \brief Import an MPI from an ASCII string. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param radix The numeric base of the input string. + * \param s Null-terminated string buffer. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s); + +/** + * \brief Export an MPI to an ASCII string. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param radix The numeric base of the output string. + * \param buf The buffer to write the string to. This must be writable + * buffer of length \p buflen Bytes. + * \param buflen The available size in Bytes of \p buf. + * \param olen The address at which to store the length of the string + * written, including the final \c NULL byte. This must + * not be \c NULL. + * + * \note You can call this function with `buflen == 0` to obtain the + * minimum required buffer size in `*olen`. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the target buffer \p buf + * is too small to hold the value of \p X in the desired base. + * In this case, `*olen` is nonetheless updated to contain the + * size of \p buf required for a successful call. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix, + char *buf, size_t buflen, size_t *olen); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief Read an MPI from a line in an opened file. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param radix The numeric base of the string representation used + * in the source line. + * \param fin The input file handle to use. This must not be \c NULL. + * + * \note On success, this function advances the file stream + * to the end of the current line or to EOF. + * + * The function returns \c 0 on an empty line. + * + * Leading whitespaces are ignored, as is a + * '0x' prefix for radix \c 16. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if the file read buffer + * is too small. + * \return Another negative error code on failure. + */ +int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin); + +/** + * \brief Export an MPI into an opened file. + * + * \param p A string prefix to emit prior to the MPI data. + * For example, this might be a label, or "0x" when + * printing in base \c 16. This may be \c NULL if no prefix + * is needed. + * \param X The source MPI. This must point to an initialized MPI. + * \param radix The numeric base to be used in the emitted string. + * \param fout The output file handle. This may be \c NULL, in which case + * the output is written to \c stdout. + * + * \return \c 0 if successful. + * \return A negative error code on failure. + */ +int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, + int radix, FILE *fout); +#endif /* MBEDTLS_FS_IO */ + +/** + * \brief Import an MPI from unsigned big endian binary data. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param buf The input buffer. This must be a readable buffer of length + * \p buflen Bytes. + * \param buflen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, + size_t buflen); + +/** + * \brief Import X from unsigned binary data, little endian + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param buf The input buffer. This must be a readable buffer of length + * \p buflen Bytes. + * \param buflen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_read_binary_le(mbedtls_mpi *X, + const unsigned char *buf, size_t buflen); + +/** + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param buf The output buffer. This must be a writable buffer of length + * \p buflen Bytes. + * \param buflen The size of the output buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't + * large enough to hold the value of \p X. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_binary(const mbedtls_mpi *X, unsigned char *buf, + size_t buflen); + +/** + * \brief Export X into unsigned binary data, little endian. + * Always fills the whole buffer, which will end with zeros + * if the number is smaller. + * + * \param X The source MPI. This must point to an initialized MPI. + * \param buf The output buffer. This must be a writable buffer of length + * \p buflen Bytes. + * \param buflen The size of the output buffer \p buf in Bytes. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't + * large enough to hold the value of \p X. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X, + unsigned char *buf, size_t buflen); + +/** + * \brief Perform a left-shift on an MPI: X <<= count + * + * \param X The MPI to shift. This must point to an initialized MPI. + * The MPI pointed by \p X may be resized to fit + * the resulting number. + * \param count The number of bits to shift by. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count); + +/** + * \brief Perform a right-shift on an MPI: X >>= count + * + * \param X The MPI to shift. This must point to an initialized MPI. + * \param count The number of bits to shift by. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count); + +/** + * \brief Compare the absolute values of two MPIs. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param Y The right-hand MPI. This must point to an initialized MPI. + * + * \return \c 1 if `|X|` is greater than `|Y|`. + * \return \c -1 if `|X|` is lesser than `|Y|`. + * \return \c 0 if `|X|` is equal to `|Y|`. + */ +int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y); + +/** + * \brief Compare two MPIs. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param Y The right-hand MPI. This must point to an initialized MPI. + * + * \return \c 1 if \p X is greater than \p Y. + * \return \c -1 if \p X is lesser than \p Y. + * \return \c 0 if \p X is equal to \p Y. + */ +int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y); + +/** + * \brief Check if an MPI is less than the other in constant time. + * + * \param X The left-hand MPI. This must point to an initialized MPI + * with the same allocated length as Y. + * \param Y The right-hand MPI. This must point to an initialized MPI + * with the same allocated length as X. + * \param ret The result of the comparison: + * \c 1 if \p X is less than \p Y. + * \c 0 if \p X is greater than or equal to \p Y. + * + * \return 0 on success. + * \return MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the allocated length of + * the two input MPIs is not the same. + */ +int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, const mbedtls_mpi *Y, + unsigned *ret); + +/** + * \brief Compare an MPI with an integer. + * + * \param X The left-hand MPI. This must point to an initialized MPI. + * \param z The integer value to compare \p X to. + * + * \return \c 1 if \p X is greater than \p z. + * \return \c -1 if \p X is lesser than \p z. + * \return \c 0 if \p X is equal to \p z. + */ +int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z); + +/** + * \brief Perform an unsigned addition of MPIs: X = |A| + |B| + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param B The second summand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform an unsigned subtraction of MPIs: X = |A| - |B| + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param B The subtrahend. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is greater than \p A. + * \return Another negative error code on different kinds of failure. + * + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a signed addition of MPIs: X = A + B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param B The second summand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a signed subtraction of MPIs: X = A - B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param B The subtrahend. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a signed addition of an MPI and an integer: X = A + b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first summand. This must point to an initialized MPI. + * \param b The second summand. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_sint b); + +/** + * \brief Perform a signed subtraction of an MPI and an integer: + * X = A - b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The minuend. This must point to an initialized MPI. + * \param b The subtrahend. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_sint b); + +/** + * \brief Perform a multiplication of two MPIs: X = A * B + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first factor. This must point to an initialized MPI. + * \param B The second factor. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + * + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a multiplication of an MPI with an unsigned integer: + * X = A * b + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The first factor. This must point to an initialized MPI. + * \param b The second factor. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + * + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, + mbedtls_mpi_uint b); + +/** + * \brief Perform a division with remainder of two MPIs: + * A = Q * B + R + * + * \param Q The destination MPI for the quotient. + * This may be \c NULL if the value of the + * quotient is not needed. This must not alias A or B. + * \param R The destination MPI for the remainder value. + * This may be \c NULL if the value of the + * remainder is not needed. This must not alias A or B. + * \param A The dividend. This must point to an initialized MPI. + * \param B The divisor. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a division with remainder of an MPI by an integer: + * A = Q * b + R + * + * \param Q The destination MPI for the quotient. + * This may be \c NULL if the value of the + * quotient is not needed. This must not alias A. + * \param R The destination MPI for the remainder value. + * This may be \c NULL if the value of the + * remainder is not needed. This must not alias A. + * \param A The dividend. This must point to an initialized MPi. + * \param b The divisor. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, + mbedtls_mpi_sint b); + +/** + * \brief Perform a modular reduction. R = A mod B + * + * \param R The destination MPI for the residue value. + * This must point to an initialized MPI. + * \param A The MPI to compute the residue of. + * This must point to an initialized MPI. + * \param B The base of the modular reduction. + * This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p B equals zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p B is negative. + * \return Another negative error code on different kinds of failure. + * + */ +int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Perform a modular reduction with respect to an integer. + * r = A mod b + * + * \param r The address at which to store the residue. + * This must not be \c NULL. + * \param A The MPI to compute the residue of. + * This must point to an initialized MPi. + * \param b The integer base of the modular reduction. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p b equals zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p b is negative. + * \return Another negative error code on different kinds of failure. + */ +DATA_RAM_FUNCTION +int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, + mbedtls_mpi_sint b); + +/** + * \brief Perform a sliding-window exponentiation: X = A^E mod N + * + * \param X The destination MPI. This must point to an initialized MPI. + * This must not alias E or N. + * \param A The base of the exponentiation. + * This must point to an initialized MPI. + * \param E The exponent MPI. This must point to an initialized MPI. + * \param N The base for the modular reduction. This must point to an + * initialized MPI. + * \param prec_RR A helper MPI depending solely on \p N which can be used to + * speed-up multiple modular exponentiations for the same value + * of \p N. This may be \c NULL. If it is not \c NULL, it must + * point to an initialized MPI. If it hasn't been used after + * the call to mbedtls_mpi_init(), this function will compute + * the helper value and store it in \p prec_RR for reuse on + * subsequent calls to this function. Otherwise, the function + * will assume that \p prec_RR holds the helper value set by a + * previous call to mbedtls_mpi_exp_mod(), and reuse it. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \c N is negative or + * even, or if \c E is negative. + * \return Another negative error code on different kinds of failures. + * + */ +int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR); + +/** + * \brief Fill an MPI with a number of random bytes. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param size The number of random bytes to generate. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on failure. + * + * \note The bytes obtained from the RNG are interpreted + * as a big-endian representation of an MPI; this can + * be relevant in applications like deterministic ECDSA. + */ +int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** Generate a random number uniformly in a range. + * + * This function generates a random number between \p min inclusive and + * \p N exclusive. + * + * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) + * when the RNG is a suitably parametrized instance of HMAC_DRBG + * and \p min is \c 1. + * + * \note There are `N - min` possible outputs. The lower bound + * \p min can be reached, but the upper bound \p N cannot. + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param min The minimum value to return. + * It must be nonnegative. + * \param N The upper bound of the range, exclusive. + * In other words, this is one plus the maximum value to return. + * \p N must be strictly larger than \p min. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid + * or if they are incompatible. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was + * unable to find a suitable value within a limited number + * of attempts. This has a negligible probability if \p N + * is significantly larger than \p min, which is the case + * for all usual cryptographic applications. + * \return Another negative error code on failure. + */ +int mbedtls_mpi_random(mbedtls_mpi *X, + mbedtls_mpi_sint min, + const mbedtls_mpi *N, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief Compute the greatest common divisor: G = gcd(A, B) + * + * \param G The destination MPI. This must point to an initialized MPI. + * \param A The first operand. This must point to an initialized MPI. + * \param B The second operand. This must point to an initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, + const mbedtls_mpi *B); + +/** + * \brief Compute the modular inverse: X = A^-1 mod N + * + * \param X The destination MPI. This must point to an initialized MPI. + * \param A The MPI to calculate the modular inverse of. This must point + * to an initialized MPI. + * \param N The base of the modular inversion. This must point to an + * initialized MPI. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is less than + * or equal to one. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p A has no modular + * inverse with respect to \p N. + */ +int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *N); + +/** + * \brief Miller-Rabin primality test. + * + * \warning If \p X is potentially generated by an adversary, for example + * when validating cryptographic parameters that you didn't + * generate yourself and that are supposed to be prime, then + * \p rounds should be at least the half of the security + * strength of the cryptographic algorithm. On the other hand, + * if \p X is chosen uniformly or non-adversarially (as is the + * case when mbedtls_mpi_gen_prime calls this function), then + * \p rounds can be much lower. + * + * \param X The MPI to check for primality. + * This must point to an initialized MPI. + * \param rounds The number of bases to perform the Miller-Rabin primality + * test for. The probability of returning 0 on a composite is + * at most 2-2*\p rounds . + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't use + * a context parameter. + * + * \return \c 0 if successful, i.e. \p X is probably prime. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if \p X is not prime. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); +/** + * \brief Flags for mbedtls_mpi_gen_prime() + * + * Each of these flags is a constraint on the result X returned by + * mbedtls_mpi_gen_prime(). + */ +typedef enum { + MBEDTLS_MPI_GEN_PRIME_FLAG_DH = 0x0001, /**< (X-1)/2 is prime too */ + MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR = 0x0002, /**< lower error rate from 2-80 to 2-128 */ +} mbedtls_mpi_gen_prime_flag_t; + +/** + * \brief Generate a prime number. + * + * \param X The destination MPI to store the generated prime in. + * This must point to an initialized MPi. + * \param nbits The required size of the destination MPI in bits. + * This must be between \c 3 and #MBEDTLS_MPI_MAX_BITS. + * \param flags A mask of flags of type #mbedtls_mpi_gen_prime_flag_t. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't use + * a context parameter. + * + * \return \c 0 if successful, in which case \p X holds a + * probably prime number. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if `nbits` is not between + * \c 3 and #MBEDTLS_MPI_MAX_BITS. + */ +int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_mpi_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/build_info.h b/src/app/findmy/crypto/third-party/mbedtls/build_info.h new file mode 100644 index 0000000..c4fab12 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/build_info.h @@ -0,0 +1,146 @@ +/** + * \file mbedtls/build_info.h + * + * \brief Build-time configuration info + * + * Include this file if you need to depend on the + * configuration options defined in mbedtls_config.h or MBEDTLS_CONFIG_FILE + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_BUILD_INFO_H +#define MBEDTLS_BUILD_INFO_H + +/* + * This set of compile-time defines can be used to determine the version number + * of the Mbed TLS library used. Run-time variables for the same can be found in + * version.h + */ + +/** + * The version number x.y.z is split into three parts. + * Major, Minor, Patchlevel + */ +#define MBEDTLS_VERSION_MAJOR 3 +#define MBEDTLS_VERSION_MINOR 5 +#define MBEDTLS_VERSION_PATCH 1 + +/** + * The single version number has the following structure: + * MMNNPP00 + * Major version | Minor version | Patch version + */ +#define MBEDTLS_VERSION_NUMBER 0x03050100 +#define MBEDTLS_VERSION_STRING "3.5.1" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 3.5.1" + +/* Macros for build-time platform detection */ + +#if !defined(MBEDTLS_ARCH_IS_ARM64) && \ + (defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) +#define MBEDTLS_ARCH_IS_ARM64 +#endif + +#if !defined(MBEDTLS_ARCH_IS_ARM32) && \ + (defined(__arm__) || defined(_M_ARM) || \ + defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__)) +#define MBEDTLS_ARCH_IS_ARM32 +#endif + +#if !defined(MBEDTLS_ARCH_IS_X64) && \ + (defined(__amd64__) || defined(__x86_64__) || \ + ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))) +#define MBEDTLS_ARCH_IS_X64 +#endif + +#if !defined(MBEDTLS_ARCH_IS_X86) && \ + (defined(__i386__) || defined(_X86_) || \ + (defined(_M_IX86) && !defined(_M_I86))) +#define MBEDTLS_ARCH_IS_X86 +#endif + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/* Define `inline` on some non-C99-compliant compilers. */ +#if (defined(__ARMCC_VERSION) || defined(_MSC_VER)) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* X.509, TLS and non-PSA crypto configuration */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/mbedtls_config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CONFIG_VERSION) && ( \ + MBEDTLS_CONFIG_VERSION < 0x03000000 || \ + MBEDTLS_CONFIG_VERSION > MBEDTLS_VERSION_NUMBER) +#error "Invalid config version, defined value of MBEDTLS_CONFIG_VERSION is unsupported" +#endif + +/* Target and application specific configurations + * + * Allow user to override any previous default. + * + */ +#if defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +/* PSA crypto configuration */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG_FILE) +#include MBEDTLS_PSA_CRYPTO_CONFIG_FILE +#else +#include "psa/crypto_config.h" +#endif +#if defined(MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE) +#include MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE +#endif +#endif /* defined(MBEDTLS_PSA_CRYPTO_CONFIG) */ + +/* Auto-enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY if + * MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH and MBEDTLS_CTR_DRBG_C defined + * to ensure a 128-bit key size in CTR_DRBG. + */ +#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && defined(MBEDTLS_CTR_DRBG_C) +#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY +#endif + +/* Auto-enable MBEDTLS_MD_C if needed by a module that didn't require it + * in a previous release, to ensure backwards compatibility. + */ +#if defined(MBEDTLS_PKCS5_C) +#define MBEDTLS_MD_C +#endif + +/* PSA crypto specific configuration options + * - If config_psa.h reads a configuration option in preprocessor directive, + * this symbol should be set before its inclusion. (e.g. MBEDTLS_MD_C) + * - If config_psa.h writes a configuration option in conditional directive, + * this symbol should be consulted after its inclusion. + * (e.g. MBEDTLS_MD_LIGHT) + */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) /* PSA_WANT_xxx influences MBEDTLS_xxx */ || \ + defined(MBEDTLS_PSA_CRYPTO_C) /* MBEDTLS_xxx influences PSA_WANT_xxx */ +#include "mbedtls/config_psa.h" +#endif + +#include "mbedtls/config_adjust_legacy_crypto.h" + +#include "mbedtls/config_adjust_x509.h" + +#include "mbedtls/config_adjust_ssl.h" + +/* Make sure all configuration symbols are set before including check_config.h, + * even the ones that are calculated programmatically. */ +#include "mbedtls/check_config.h" + +#endif /* MBEDTLS_BUILD_INFO_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/ccm.h b/src/app/findmy/crypto/third-party/mbedtls/ccm.h new file mode 100644 index 0000000..a98111b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/ccm.h @@ -0,0 +1,518 @@ +/** + * \file ccm.h + * + * \brief This file provides an API for the CCM authenticated encryption + * mode for block ciphers. + * + * CCM combines Counter mode encryption with CBC-MAC authentication + * for 128-bit block ciphers. + * + * Input to CCM includes the following elements: + *
    • Payload - data that is both authenticated and encrypted.
    • + *
    • Associated data (Adata) - data that is authenticated but not + * encrypted, For example, a header.
    • + *
    • Nonce - A unique value that is assigned to the payload and the + * associated data.
    + * + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + * + * Definition of CCM*: + * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks + * Integer representation is fixed most-significant-octet-first order and + * the representation of octets is most-significant-bit-first order. This is + * consistent with RFC 3610. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CCM_H +#define MBEDTLS_CCM_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/cipher.h" + +#define MBEDTLS_CCM_DECRYPT 0 +#define MBEDTLS_CCM_ENCRYPT 1 +#define MBEDTLS_CCM_STAR_DECRYPT 2 +#define MBEDTLS_CCM_STAR_ENCRYPT 3 + +/** Bad input parameters to the function. */ +#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D +/** Authenticated decryption failed. */ +#define MBEDTLS_ERR_CCM_AUTH_FAILED -0x000F + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_CCM_ALT) +// Regular implementation +// + +/** + * \brief The CCM context-type definition. The CCM context is passed + * to the APIs called. + */ +typedef struct mbedtls_ccm_context { + unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working buffer */ + unsigned char MBEDTLS_PRIVATE(ctr)[16]; /*!< The counter buffer */ + size_t MBEDTLS_PRIVATE(plaintext_len); /*!< Total plaintext length */ + size_t MBEDTLS_PRIVATE(add_len); /*!< Total authentication data length */ + size_t MBEDTLS_PRIVATE(tag_len); /*!< Total tag length */ + size_t MBEDTLS_PRIVATE(processed); /*!< Track how many bytes of input data + were processed (chunked input). + Used independently for both auth data + and plaintext/ciphertext. + This variable is set to zero after + auth data input is finished. */ + unsigned int MBEDTLS_PRIVATE(q); /*!< The Q working value */ + unsigned int MBEDTLS_PRIVATE(mode); /*!< The operation to perform: + #MBEDTLS_CCM_ENCRYPT or + #MBEDTLS_CCM_DECRYPT or + #MBEDTLS_CCM_STAR_ENCRYPT or + #MBEDTLS_CCM_STAR_DECRYPT. */ + mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ + int MBEDTLS_PRIVATE(state); /*!< Working value holding context's + state. Used for chunked data input */ +} +mbedtls_ccm_context; + +#else /* MBEDTLS_CCM_ALT */ +#include "ccm_alt.h" +#endif /* MBEDTLS_CCM_ALT */ + +/** + * \brief This function initializes the specified CCM context, + * to make references valid, and prepare the context + * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). + * + * \param ctx The CCM context to initialize. This must not be \c NULL. + */ +void mbedtls_ccm_init(mbedtls_ccm_context *ctx); + +/** + * \brief This function initializes the CCM context set in the + * \p ctx parameter and sets the encryption key. + * + * \param ctx The CCM context to initialize. This must be an initialized + * context. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must not be \c NULL. + * \param keybits The key size in bits. This must be acceptable by the cipher. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits); + +/** + * \brief This function releases and clears the specified CCM context + * and underlying cipher sub-context. + * + * \param ctx The CCM context to clear. If this is \c NULL, the function + * has no effect. Otherwise, this must be initialized. + */ +void mbedtls_ccm_free(mbedtls_ccm_context *ctx); + +/** + * \brief This function encrypts a buffer using CCM. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param ad The additional data field. If \p ad_len is greater than + * zero, \p ad must be a readable buffer of at least that + * length. + * \param ad_len The length of additional data in Bytes. + * This must be less than `2^16 - 2^8`. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * writable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len); + +/** + * \brief This function encrypts a buffer using CCM*. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in RFC-3610: + * Counter with CBC-MAC (CCM), use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \note When using this function in a variable tag length context, + * the tag length has to be encoded into the \p iv passed to + * this function. + * + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * For tag length = 0, input length is ignored. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param ad The additional data field. This must be a readable buffer of + * at least \p ad_len Bytes. + * \param ad_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * writable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len); + +/** + * \brief This function performs a CCM authenticated decryption of a + * buffer. + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param ad The additional data field. This must be a readable buffer + * of at least that \p ad_len Bytes.. + * \param ad_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * + * \return \c 0 on success. This indicates that the message is authentic. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len); + +/** + * \brief This function performs a CCM* authenticated decryption of a + * buffer. + * + * \note When using this function in a variable tag length context, + * the tag length has to be decoded from \p iv and passed to + * this function as \p tag_len. (\p tag needs to be adjusted + * accordingly.) + * + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. + * \param length The length of the input data in Bytes. + * For tag length = 0, input length is ignored. + * \param iv The initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param ad The additional data field. This must be a readable buffer of + * at least that \p ad_len Bytes. + * \param ad_len The length of additional data in Bytes. + * This must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field in Bytes. + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing \c 0 as \p tag_len means that the message is nos + * longer authenticated. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len); + +/** + * \brief This function starts a CCM encryption or decryption + * operation. + * + * This function and mbedtls_ccm_set_lengths() must be called + * before calling mbedtls_ccm_update_ad() or + * mbedtls_ccm_update(). This function can be called before + * or after mbedtls_ccm_set_lengths(). + * + * \note This function is not implemented in Mbed TLS yet. + * + * \param ctx The CCM context. This must be initialized. + * \param mode The operation to perform: #MBEDTLS_CCM_ENCRYPT or + * #MBEDTLS_CCM_DECRYPT or #MBEDTLS_CCM_STAR_ENCRYPT or + * #MBEDTLS_CCM_STAR_DECRYPT. + * \param iv The initialization vector. This must be a readable buffer + * of at least \p iv_len Bytes. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: + * \p ctx is in an invalid state, + * \p mode is invalid, + * \p iv_len is invalid (lower than \c 7 or greater than + * \c 13). + */ +int mbedtls_ccm_starts(mbedtls_ccm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len); + +/** + * \brief This function declares the lengths of the message + * and additional data for a CCM encryption or decryption + * operation. + * + * This function and mbedtls_ccm_starts() must be called + * before calling mbedtls_ccm_update_ad() or + * mbedtls_ccm_update(). This function can be called before + * or after mbedtls_ccm_starts(). + * + * \note This function is not implemented in Mbed TLS yet. + * + * \param ctx The CCM context. This must be initialized. + * \param total_ad_len The total length of additional data in bytes. + * This must be less than `2^16 - 2^8`. + * \param plaintext_len The length in bytes of the plaintext to encrypt or + * result of the decryption (thus not encompassing the + * additional data that are not encrypted). + * \param tag_len The length of the tag to generate in Bytes: + * 4, 6, 8, 10, 12, 14 or 16. + * For CCM*, zero is also valid. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: + * \p ctx is in an invalid state, + * \p total_ad_len is greater than \c 0xFF00. + */ +int mbedtls_ccm_set_lengths(mbedtls_ccm_context *ctx, + size_t total_ad_len, + size_t plaintext_len, + size_t tag_len); + +/** + * \brief This function feeds an input buffer as associated data + * (authenticated but not encrypted data) in a CCM + * encryption or decryption operation. + * + * You may call this function zero, one or more times + * to pass successive parts of the additional data. The + * lengths \p ad_len of the data parts should eventually add + * up exactly to the total length of additional data + * \c total_ad_len passed to mbedtls_ccm_set_lengths(). You + * may not call this function after calling + * mbedtls_ccm_update(). + * + * \note This function is not implemented in Mbed TLS yet. + * + * \param ctx The CCM context. This must have been started with + * mbedtls_ccm_starts(), the lengths of the message and + * additional data must have been declared with + * mbedtls_ccm_set_lengths() and this must not have yet + * received any input with mbedtls_ccm_update(). + * \param ad The buffer holding the additional data, or \c NULL + * if \p ad_len is \c 0. + * \param ad_len The length of the additional data. If \c 0, + * \p ad may be \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: + * \p ctx is in an invalid state, + * total input length too long. + */ +int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx, + const unsigned char *ad, + size_t ad_len); + +/** + * \brief This function feeds an input buffer into an ongoing CCM + * encryption or decryption operation. + * + * You may call this function zero, one or more times + * to pass successive parts of the input: the plaintext to + * encrypt, or the ciphertext (not including the tag) to + * decrypt. After the last part of the input, call + * mbedtls_ccm_finish(). The lengths \p input_len of the + * data parts should eventually add up exactly to the + * plaintext length \c plaintext_len passed to + * mbedtls_ccm_set_lengths(). + * + * This function may produce output in one of the following + * ways: + * - Immediate output: the output length is always equal + * to the input length. + * - Buffered output: except for the last part of input data, + * the output consists of a whole number of 16-byte blocks. + * If the total input length so far (not including + * associated data) is 16 \* *B* + *A* with *A* < 16 then + * the total output length is 16 \* *B*. + * For the last part of input data, the output length is + * equal to the input length plus the number of bytes (*A*) + * buffered in the previous call to the function (if any). + * The function uses the plaintext length + * \c plaintext_len passed to mbedtls_ccm_set_lengths() + * to detect the last part of input data. + * + * In particular: + * - It is always correct to call this function with + * \p output_size >= \p input_len + 15. + * - If \p input_len is a multiple of 16 for all the calls + * to this function during an operation (not necessary for + * the last one) then it is correct to use \p output_size + * =\p input_len. + * + * \note This function is not implemented in Mbed TLS yet. + * + * \param ctx The CCM context. This must have been started with + * mbedtls_ccm_starts() and the lengths of the message and + * additional data must have been declared with + * mbedtls_ccm_set_lengths(). + * \param input The buffer holding the input data. If \p input_len + * is greater than zero, this must be a readable buffer + * of at least \p input_len bytes. + * \param input_len The length of the input data in bytes. + * \param output The buffer for the output data. If \p output_size + * is greater than zero, this must be a writable buffer of + * at least \p output_size bytes. + * \param output_size The size of the output buffer in bytes. + * See the function description regarding the output size. + * \param output_len On success, \p *output_len contains the actual + * length of the output written in \p output. + * On failure, the content of \p *output_len is + * unspecified. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: + * \p ctx is in an invalid state, + * total input length too long, + * or \p output_size too small. + */ +int mbedtls_ccm_update(mbedtls_ccm_context *ctx, + const unsigned char *input, size_t input_len, + unsigned char *output, size_t output_size, + size_t *output_len); + +/** + * \brief This function finishes the CCM operation and generates + * the authentication tag. + * + * It wraps up the CCM stream, and generates the + * tag. The tag can have a maximum length of 16 Bytes. + * + * \note This function is not implemented in Mbed TLS yet. + * + * \param ctx The CCM context. This must have been started with + * mbedtls_ccm_starts() and the lengths of the message and + * additional data must have been declared with + * mbedtls_ccm_set_lengths(). + * \param tag The buffer for holding the tag. If \p tag_len is greater + * than zero, this must be a writable buffer of at least \p + * tag_len Bytes. + * \param tag_len The length of the tag. Must match the tag length passed to + * mbedtls_ccm_set_lengths() function. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_BAD_INPUT on failure: + * \p ctx is in an invalid state, + * invalid value of \p tag_len, + * the total amount of additional data passed to + * mbedtls_ccm_update_ad() was lower than the total length of + * additional data \c total_ad_len passed to + * mbedtls_ccm_set_lengths(), + * the total amount of input data passed to + * mbedtls_ccm_update() was lower than the plaintext length + * \c plaintext_len passed to mbedtls_ccm_set_lengths(). + */ +int mbedtls_ccm_finish(mbedtls_ccm_context *ctx, + unsigned char *tag, size_t tag_len); + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief The CCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ccm_self_test(int verbose); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CCM_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/check_config.h b/src/app/findmy/crypto/third-party/mbedtls/check_config.h new file mode 100644 index 0000000..e479ef3 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/check_config.h @@ -0,0 +1,1206 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CHECK_CONFIG_H +#define MBEDTLS_CHECK_CONFIG_H + +/* *INDENT-OFF* */ +/* + * We assume CHAR_BIT is 8 in many places. In practice, this is true on our + * target platforms, so not an issue, but let's just be extra sure. + */ +#include +#if CHAR_BIT != 8 +#error "Mbed TLS requires a platform with 8-bit chars" +#endif + +#include + +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) +#if !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_C is required on Windows" +#endif + +/* Fix the config here. Not convenient to put an #ifdef _WIN32 in mbedtls_config.h as + * it would confuse config.py. */ +#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_SNPRINTF_ALT +#endif + +#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \ + !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) +#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +#endif +#endif /* _MINGW32__ || (_MSC_VER && (_MSC_VER <= 1900)) */ + +#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C) +#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS" +#endif + +#if defined(MBEDTLS_DEPRECATED_WARNING) && \ + !defined(__GNUC__) && !defined(__clang__) +#error "MBEDTLS_DEPRECATED_WARNING only works with GCC and Clang" +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_HAVE_TIME) +#error "MBEDTLS_HAVE_TIME_DATE without MBEDTLS_HAVE_TIME does not make sense" +#endif + +/* Check that each MBEDTLS_ECP_DP_xxx symbol has its PSA_WANT_ECC_xxx counterpart + * when PSA crypto is enabled. */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) || defined(MBEDTLS_PSA_CRYPTO_C) + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) +#error "MBEDTLS_ECP_DP_BP256R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) +#error "MBEDTLS_ECP_DP_BP384R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) +#error "MBEDTLS_ECP_DP_BP512R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && !defined(PSA_WANT_ECC_MONTGOMERY_255) +#error "MBEDTLS_ECP_DP_CURVE25519_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) && !defined(PSA_WANT_ECC_MONTGOMERY_448) +#error "MBEDTLS_ECP_DP_CURVE448_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_192) +#error "MBEDTLS_ECP_DP_SECP192R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_224) +#error "MBEDTLS_ECP_DP_SECP224R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_256) +#error "MBEDTLS_ECP_DP_SECP256R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_384) +#error "MBEDTLS_ECP_DP_SECP384R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && !defined(PSA_WANT_ECC_SECP_R1_521) +#error "MBEDTLS_ECP_DP_SECP521R1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_192) +#error "MBEDTLS_ECP_DP_SECP192K1_ENABLED defined, but not its PSA counterpart" +#endif + +/* SECP224K1 is buggy in PSA API so we skip this check */ +#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_224) +#error "MBEDTLS_ECP_DP_SECP224K1_ENABLED defined, but not its PSA counterpart" +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && !defined(PSA_WANT_ECC_SECP_K1_256) +#error "MBEDTLS_ECP_DP_SECP256K1_ENABLED defined, but not its PSA counterpart" +#endif + +#endif /* MBEDTLS_PSA_CRYPTO_CONFIG || MBEDTLS_PSA_CRYPTO_C */ + +/* Limitations on ECC key types acceleration: if we have any of `PUBLIC_KEY`, + * `KEY_PAIR_BASIC`, `KEY_PAIR_IMPORT`, `KEY_PAIR_EXPORT` then we must have + * all 4 of them. + */ +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) +#error "Unsupported partial support for ECC key type acceleration, see docs/driver-only-builds.md" +#endif /* not all of public, basic, import, export */ +#endif /* one of public, basic, import, export */ + +/* Limitations on ECC curves acceleration: partial curve acceleration is only + * supported with crypto excluding PK, X.509 or TLS. + * Note: no need to check X.509 as it depends on PK. */ +#if defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \ + defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) +#if defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) +#if defined(MBEDTLS_PK_C) || \ + defined(MBEDTLS_SSL_TLS_C) +#error "Unsupported partial support for ECC curves acceleration, see docs/driver-only-builds.md" +#endif /* modules beyond what's supported */ +#endif /* not all curves accelerated */ +#endif /* some curve accelerated */ + +#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) +#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C) +#error "MBEDTLS_DHM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CMAC_C) && \ + ( !defined(MBEDTLS_CIPHER_C ) || ( !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) ) ) +#error "MBEDTLS_CMAC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_NIST_KW_C) && \ + ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) +#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) +#error "MBEDTLS_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_C) && \ + ( !defined(MBEDTLS_ECP_C) || \ + !( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \ + !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_ASN1_WRITE_C) ) +#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECJPAKE_C) && \ + ( !defined(MBEDTLS_ECP_C) || \ + !( defined(MBEDTLS_MD_C) || defined(MBEDTLS_PSA_CRYPTO_C) ) ) +#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \ + defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \ + defined(MBEDTLS_ECDSA_SIGN_ALT) || \ + defined(MBEDTLS_ECDSA_VERIFY_ALT) || \ + defined(MBEDTLS_ECDSA_GENKEY_ALT) || \ + defined(MBEDTLS_ECP_INTERNAL_ALT) || \ + defined(MBEDTLS_ECP_ALT) ) +#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation" +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) && \ + !defined(MBEDTLS_ECP_C) +#error "MBEDTLS_ECP_RESTARTABLE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) +#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_C) && ( !defined(MBEDTLS_BIGNUM_C) || ( \ + !defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) && \ + !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) ) ) +#error "MBEDTLS_ECP_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS12_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_PKCS12_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PKCS5_C) && \ + !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_PKCS5_C defined, but not all prerequisites" +#endif + +/* Helpers for hash dependencies, will be undefined at the end of the file */ +/* Do SHA-256, 384, 512 to cover Entropy and TLS. */ +#if defined(MBEDTLS_SHA256_C) || \ + (defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256)) +#define MBEDTLS_MD_HAVE_SHA256 +#endif +#if defined(MBEDTLS_SHA384_C) || \ + (defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_384)) +#define MBEDTLS_MD_HAVE_SHA384 +#endif +#if defined(MBEDTLS_SHA512_C) || \ + (defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_512)) +#define MBEDTLS_MD_HAVE_SHA512 +#endif + +#if defined(MBEDTLS_ENTROPY_C) && \ + !(defined(MBEDTLS_MD_HAVE_SHA512) || defined(MBEDTLS_MD_HAVE_SHA256)) +#error "MBEDTLS_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 64) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + (defined(MBEDTLS_ENTROPY_FORCE_SHA256) || !defined(MBEDTLS_MD_HAVE_SHA512)) \ + && defined(MBEDTLS_CTR_DRBG_ENTROPY_LEN) && (MBEDTLS_CTR_DRBG_ENTROPY_LEN > 32) +#error "MBEDTLS_CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(MBEDTLS_ENTROPY_C) && \ + defined(MBEDTLS_ENTROPY_FORCE_SHA256) && !defined(MBEDTLS_MD_HAVE_SHA256) +#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define MBEDTLS_HAS_MEMSAN +#endif +#endif +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) && !defined(MBEDTLS_HAS_MEMSAN) +#error "MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN requires building with MemorySanitizer" +#endif +#undef MBEDTLS_HAS_MEMSAN + +#if defined(MBEDTLS_CCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) ) +#error "MBEDTLS_CCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_CCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_GCM_C) && ( \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) ) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_GCM_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C) +#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_POLY1305_C) +#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled" +#endif + +#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HKDF_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +/* Helper for JPAKE dependencies, will be undefined at the end of the file */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(PSA_WANT_ALG_JPAKE) && defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) +#define MBEDTLS_PK_HAVE_JPAKE +#endif +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_ECJPAKE_C) +#define MBEDTLS_PK_HAVE_JPAKE +#endif +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/* Helper for curve SECP256R1 */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(PSA_WANT_ECC_SECP_R1_256) +#define MBEDTLS_PK_HAVE_CURVE_SECP256R1 +#endif +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#define MBEDTLS_PK_HAVE_CURVE_SECP256R1 +#endif +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_CAN_ECDH) || \ + !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(MBEDTLS_DHM_C) +#error "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(MBEDTLS_CAN_ECDH) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_DHM_C) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_CAN_ECDH) || !defined(MBEDTLS_RSA_C) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(MBEDTLS_CAN_ECDH) || \ + !defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || \ + !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + ( !defined(MBEDTLS_PK_HAVE_JPAKE) || \ + !defined(MBEDTLS_PK_HAVE_CURVE_SECP256R1) ) +#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" +#endif + +/* Use of EC J-PAKE in TLS requires SHA-256. */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \ + !defined(MBEDTLS_MD_HAVE_SHA256) +#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \ + !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \ + ( !defined(MBEDTLS_SHA256_C) && \ + !defined(MBEDTLS_SHA512_C) && \ + !defined(MBEDTLS_SHA1_C) ) +#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C" +#endif + +#if defined(MBEDTLS_MD_C) && !( \ + defined(MBEDTLS_MD5_C) || \ + defined(MBEDTLS_RIPEMD160_C) || \ + defined(MBEDTLS_SHA1_C) || \ + defined(MBEDTLS_SHA224_C) || \ + defined(MBEDTLS_SHA256_C) || \ + defined(MBEDTLS_SHA384_C) || \ + defined(MBEDTLS_SHA512_C) || \ + (defined(MBEDTLS_PSA_CRYPTO_C) && \ + (defined(PSA_WANT_ALG_MD5) || \ + defined(PSA_WANT_ALG_RIPEMD160) || \ + defined(PSA_WANT_ALG_SHA_1) || \ + defined(PSA_WANT_ALG_SHA_224) || \ + defined(PSA_WANT_ALG_SHA_256) || \ + defined(PSA_WANT_ALG_SHA_384) || \ + defined(PSA_WANT_ALG_SHA_512)))) +#error "MBEDTLS_MD_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_LMS_C) && \ + ! ( defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_ALG_SHA_256) ) +#error "MBEDTLS_LMS_C requires MBEDTLS_PSA_CRYPTO_C and PSA_WANT_ALG_SHA_256" +#endif + +#if defined(MBEDTLS_LMS_PRIVATE) && \ + ( !defined(MBEDTLS_LMS_C) ) +#error "MBEDTLS_LMS_PRIVATE requires MBEDTLS_LMS_C" +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_BACKTRACE) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#error "MBEDTLS_MEMORY_BACKTRACE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_MEMORY_DEBUG) && !defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#error "MBEDTLS_MEMORY_DEBUG defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PEM_WRITE_C) && !defined(MBEDTLS_BASE64_C) +#error "MBEDTLS_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_C) && \ + !defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_PK_HAVE_ECC_KEYS) +#error "MBEDTLS_PK_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PK_WRITE_C) && !defined(MBEDTLS_PK_C) +#error "MBEDTLS_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_EXIT_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_EXIT) ||\ + defined(MBEDTLS_PLATFORM_EXIT_ALT) ) +#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SETBUF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SETBUF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_SETBUF) ||\ + defined(MBEDTLS_PLATFORM_SETBUF_ALT) ) +#error "MBEDTLS_PLATFORM_SETBUF_MACRO and MBEDTLS_PLATFORM_STD_SETBUF/MBEDTLS_PLATFORM_SETBUF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_MS_TIME_ALT) && \ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_MS_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_FPRINTF) ||\ + defined(MBEDTLS_PLATFORM_FPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_FPRINTF_MACRO and MBEDTLS_PLATFORM_STD_FPRINTF/MBEDTLS_PLATFORM_FPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_FREE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_FREE) +#error "MBEDTLS_PLATFORM_FREE_MACRO and MBEDTLS_PLATFORM_STD_FREE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && !defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO must be defined if MBEDTLS_PLATFORM_FREE_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&\ + defined(MBEDTLS_PLATFORM_STD_CALLOC) +#error "MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_STD_CALLOC cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && !defined(MBEDTLS_PLATFORM_FREE_MACRO) +#error "MBEDTLS_PLATFORM_FREE_MACRO must be defined if MBEDTLS_PLATFORM_CALLOC_MACRO is" +#endif + +#if defined(MBEDTLS_PLATFORM_MEMORY) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_MEMORY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_PRINTF) ||\ + defined(MBEDTLS_PLATFORM_PRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_PRINTF_MACRO and MBEDTLS_PLATFORM_STD_PRINTF/MBEDTLS_PLATFORM_PRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_SNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_SNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_SNPRINTF/MBEDTLS_PLATFORM_SNPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_VSNPRINTF_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) && !defined(MBEDTLS_PLATFORM_C) +#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) ||\ + defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) ) +#error "MBEDTLS_PLATFORM_VSNPRINTF_MACRO and MBEDTLS_PLATFORM_STD_VSNPRINTF/MBEDTLS_PLATFORM_VSNPRINTF_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) &&\ + !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#error "MBEDTLS_PLATFORM_STD_MEM_HDR defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_CALLOC) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_CALLOC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FREE) && !defined(MBEDTLS_PLATFORM_MEMORY) +#error "MBEDTLS_PLATFORM_STD_FREE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_EXIT) &&\ + !defined(MBEDTLS_PLATFORM_EXIT_ALT) +#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_PRINTF) &&\ + !defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_PRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_SNPRINTF) &&\ + !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ + !defined(MBEDTLS_ENTROPY_NV_SEED) +#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) && \ + !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \ + defined(MBEDTLS_ENTROPY_C) ) || \ + defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) ) +#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) && !defined(MBEDTLS_CIPHER_C ) +#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \ + ! ( defined(MBEDTLS_PSA_CRYPTO_C) && \ + defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) ) +#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_PSA_CRYPTO_SE_C is deprecated and will be removed in a future version of Mbed TLS" +#endif +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + ! defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \ + defined(MBEDTLS_ENTROPY_NV_SEED) ) +#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" +#endif + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG" +#endif + +#if defined(MBEDTLS_PSA_ITS_FILE_C) && \ + !defined(MBEDTLS_FS_IO) +#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ + !defined(MBEDTLS_OID_C) ) +#error "MBEDTLS_RSA_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" +#endif + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) +#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) && \ + defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) +#error "Must only define one of MBEDTLS_SHA512_USE_A64_CRYPTO_*" +#endif + +#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \ + defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) +#if !defined(MBEDTLS_SHA512_C) +#error "MBEDTLS_SHA512_USE_A64_CRYPTO_* defined without MBEDTLS_SHA512_C" +#endif +#if defined(MBEDTLS_SHA512_ALT) || defined(MBEDTLS_SHA512_PROCESS_ALT) +#error "MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*" +#endif + +#endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ + +#if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) && !defined(__aarch64__) +#error "MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY defined on non-Aarch64 system" +#endif + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) && \ + defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) +#error "Must only define one of MBEDTLS_SHA256_USE_A64_CRYPTO_*" +#endif + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \ + defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) +#if !defined(MBEDTLS_SHA256_C) +#error "MBEDTLS_SHA256_USE_A64_CRYPTO_* defined without MBEDTLS_SHA256_C" +#endif +#if defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA256_PROCESS_ALT) +#error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_A64_CRYPTO_*" +#endif + +#endif + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && \ + !defined(__aarch64__) && !defined(_M_ARM64) +#error "MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY defined on non-Aarch64 system" +#endif + +/* TLS 1.3 requires separate HKDF parts from PSA, + * and at least one ciphersuite, so at least SHA-256 or SHA-384 + * from PSA to use with HKDF. + * + * Note: for dependencies common with TLS 1.2 (running handshake hash), + * see MBEDTLS_SSL_TLS_C. */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ + !(defined(MBEDTLS_PSA_CRYPTO_C) && \ + defined(PSA_WANT_ALG_HKDF_EXTRACT) && \ + defined(PSA_WANT_ALG_HKDF_EXPAND) && \ + (defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384))) +#error "MBEDTLS_SSL_PROTO_TLS1_3 defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) +#if !( (defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)) && \ + defined(MBEDTLS_X509_CRT_PARSE_C) && \ + ( defined(MBEDTLS_PK_CAN_ECDSA_SIGN) || defined(MBEDTLS_PKCS1_V21) ) ) +#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED defined, but not all prerequisites" +#endif +#endif + +#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) +#if !( defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH) ) +#error "MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED defined, but not all prerequisites" +#endif +#endif + +/* + * The current implementation of TLS 1.3 requires MBEDTLS_SSL_KEEP_PEER_CERTIFICATE. + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) +#error "MBEDTLS_SSL_PROTO_TLS1_3 defined without MBEDTLS_SSL_KEEP_PEER_CERTIFICATE" +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) +#error "One or more versions of the TLS protocol are enabled " \ + "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx" +#endif + +#if defined(MBEDTLS_SSL_EARLY_DATA) && \ + ( !defined(MBEDTLS_SSL_SESSION_TICKETS) || \ + ( !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED) && \ + !defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED) ) ) +#error "MBEDTLS_SSL_EARLY_DATA defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_SRV_C) && \ + defined(MBEDTLS_SSL_MAX_EARLY_DATA_SIZE) && \ + ((MBEDTLS_SSL_MAX_EARLY_DATA_SIZE < 0) || \ + (MBEDTLS_SSL_MAX_EARLY_DATA_SIZE > UINT32_MAX)) +#error "MBEDTLS_SSL_MAX_EARLY_DATA_SIZE must be in the range(0..UINT32_MAX)" +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_PROTO_DTLS defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && !defined(MBEDTLS_X509_CRT_PARSE_C) +#error "MBEDTLS_SSL_ASYNC_PRIVATE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && !defined(MBEDTLS_CIPHER_C) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif + +/* TLS 1.2 and 1.3 require SHA-256 or SHA-384 (running handshake hash) */ +#if defined(MBEDTLS_SSL_TLS_C) +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if !(defined(PSA_WANT_ALG_SHA_256) || defined(PSA_WANT_ALG_SHA_384)) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#if !defined(MBEDTLS_MD_C) || \ + !(defined(MBEDTLS_MD_HAVE_SHA256) || defined(MBEDTLS_MD_HAVE_SHA384)) +#error "MBEDTLS_SSL_TLS_C defined, but not all prerequisites" +#endif +#endif /* MBEDTLS_USE_PSA_CRYPTO */ +#endif /* MBEDTLS_SSL_TLS_C */ + +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_TLS_C) +#error "MBEDTLS_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) && \ + !( defined(MBEDTLS_SSL_PROTO_TLS1_2) || defined(MBEDTLS_SSL_PROTO_TLS1_3) ) +#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && !defined(MBEDTLS_SSL_PROTO_DTLS) +#error "MBEDTLS_SSL_DTLS_HELLO_VERIFY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && \ + !defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +#error "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \ + MBEDTLS_SSL_CID_IN_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \ + MBEDTLS_SSL_CID_OUT_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && \ + !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT) && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 +#if defined(MBEDTLS_DEPRECATED_REMOVED) +#error "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS" +#elif defined(MBEDTLS_DEPRECATED_WARNING) +#warning "MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT is deprecated and will be removed in a future version of Mbed TLS" +#endif +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT && MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT != 0 */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_ENCRYPT_THEN_MAC defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_RENEGOTIATION defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) && ( !defined(MBEDTLS_CIPHER_C) && \ + !defined(MBEDTLS_USE_PSA_CRYPTO) ) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) && \ + !( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) ) +#error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH) && \ + MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH >= 256 +#error "MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH must be less than 256" +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && \ + !defined(MBEDTLS_X509_CRT_PARSE_C) +#error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_THREADING_PTHREAD) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_ALT) +#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites" +#endif +#define MBEDTLS_THREADING_IMPL +#endif + +#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL) +#error "MBEDTLS_THREADING_C defined, single threading implementation required" +#endif +#undef MBEDTLS_THREADING_IMPL + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C) +#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C) +#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_USE_C) && \ + (!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_PARSE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) || \ + ( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) ) +#error "MBEDTLS_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CREATE_C) && \ + (!defined(MBEDTLS_OID_C) || !defined(MBEDTLS_ASN1_WRITE_C) || \ + !defined(MBEDTLS_PK_PARSE_C) || \ + ( !defined(MBEDTLS_MD_C) && !defined(MBEDTLS_USE_PSA_CRYPTO) ) ) +#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRL_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) ) +#error "MBEDTLS_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CRT_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_CSR_WRITE_C) && ( !defined(MBEDTLS_X509_CREATE_C) ) +#error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) && \ + ( !defined(MBEDTLS_X509_CRT_PARSE_C) ) +#error "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) +#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" +#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ + +#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ + defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" +#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ + +#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) ) +#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT) && ( !defined(MBEDTLS_SSL_PROTO_TLS1_3) ) +#error "MBEDTLS_SSL_RECORD_SIZE_LIMIT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION) && !( defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) ) +#error "MBEDTLS_SSL_CONTEXT_SERIALIZATION defined, but not all prerequisites" +#endif + +/* Reject attempts to enable options that have been removed and that could + * cause a build to succeed but with features removed. */ + +#if defined(MBEDTLS_HAVEGE_C) //no-check-names +#error "MBEDTLS_HAVEGE_C was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/2599" +#endif + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) //no-check-names +#error "MBEDTLS_SSL_HW_RECORD_ACCEL was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) //no-check-names +#error "MBEDTLS_SSL_PROTO_SSL3 (SSL v3.0 support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" +#endif + +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) //no-check-names +#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO (SSL v2 ClientHello support) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" +#endif + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT) //no-check-names +#error "MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT (compatibility with the buggy implementation of truncated HMAC in Mbed TLS up to 2.7) was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" +#endif + +#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) //no-check-names +#error "MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES was removed in Mbed TLS 3.0. See the ChangeLog entry if you really need SHA-1-signed certificates." +#endif + +#if defined(MBEDTLS_ZLIB_SUPPORT) //no-check-names +#error "MBEDTLS_ZLIB_SUPPORT was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4031" +#endif + +#if defined(MBEDTLS_CHECK_PARAMS) //no-check-names +#error "MBEDTLS_CHECK_PARAMS was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4313" +#endif + +#if defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) //no-check-names +#error "MBEDTLS_SSL_CID_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335" +#endif + +#if defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY) //no-check-names +#error "MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4335" +#endif + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) //no-check-names +#error "MBEDTLS_SSL_TRUNCATED_HMAC was removed in Mbed TLS 3.0. See https://github.com/Mbed-TLS/mbedtls/issues/4341" +#endif + +#if defined(MBEDTLS_PKCS7_C) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \ + ( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLS_PK_PARSE_C) ) || \ + ( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || \ + ( !defined(MBEDTLS_X509_CRL_PARSE_C) ) || \ + ( !defined(MBEDTLS_MD_C) ) ) +#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites" +#endif + +/* Undefine helper symbols */ +#undef MBEDTLS_PK_HAVE_JPAKE +#undef MBEDTLS_MD_HAVE_SHA256 +#undef MBEDTLS_MD_HAVE_SHA384 +#undef MBEDTLS_MD_HAVE_SHA512 +#undef MBEDTLS_PK_HAVE_CURVE_SECP256R1 + +/* + * Avoid warning from -pedantic. This is a convenient place for this + * workaround since this is included by every single file before the + * #if defined(MBEDTLS_xxx_C) that results in empty translation units. + */ +typedef int mbedtls_iso_c_forbids_empty_translation_units; + +/* *INDENT-ON* */ +#endif /* MBEDTLS_CHECK_CONFIG_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/cipher.h b/src/app/findmy/crypto/third-party/mbedtls/cipher.h new file mode 100644 index 0000000..2596baa --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/cipher.h @@ -0,0 +1,1183 @@ +/** + * \file cipher.h + * + * \brief This file contains an abstraction interface for use with the cipher + * primitives provided by the library. It provides a common interface to all of + * the available cipher operations. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CIPHER_H +#define MBEDTLS_CIPHER_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include "mbedtls/platform_util.h" + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +#define MBEDTLS_CIPHER_MODE_AEAD +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_MODE_WITH_PADDING +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + defined(MBEDTLS_CHACHA20_C) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +/** The selected feature is not available. */ +#define MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 +/** Bad input parameters. */ +#define MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA -0x6100 +/** Failed to allocate memory. */ +#define MBEDTLS_ERR_CIPHER_ALLOC_FAILED -0x6180 +/** Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 +/** Decryption of block requires a full block. */ +#define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 +/** Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 +/** The context is invalid. For example, because it was freed. */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 + +#define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length. */ +#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Supported cipher types. + * + * \warning DES/3DES are considered weak ciphers and their use + * constitutes a security risk. We recommend considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_ID_NONE = 0, /**< Placeholder to mark the end of cipher ID lists. */ + MBEDTLS_CIPHER_ID_NULL, /**< The identity cipher, treated as a stream cipher. */ + MBEDTLS_CIPHER_ID_AES, /**< The AES cipher. */ + MBEDTLS_CIPHER_ID_DES, /**< The DES cipher. \warning DES is considered weak. */ + MBEDTLS_CIPHER_ID_3DES, /**< The Triple DES cipher. \warning 3DES is considered weak. */ + MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ + MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ +} mbedtls_cipher_id_t; + +/** + * \brief Supported {cipher type, cipher mode} pairs. + * + * \warning DES/3DES are considered weak ciphers and their use + * constitutes a security risk. We recommend considering stronger + * ciphers instead. + */ +typedef enum { + MBEDTLS_CIPHER_NONE = 0, /**< Placeholder to mark the end of cipher-pair lists. */ + MBEDTLS_CIPHER_NULL, /**< The identity stream cipher. */ + MBEDTLS_CIPHER_AES_128_ECB, /**< AES cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_AES_192_ECB, /**< AES cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_AES_256_ECB, /**< AES cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_AES_128_CBC, /**< AES cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_AES_192_CBC, /**< AES cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_AES_256_CBC, /**< AES cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_AES_128_CFB128, /**< AES cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_192_CFB128, /**< AES cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_256_CFB128, /**< AES cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_AES_128_CTR, /**< AES cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_AES_192_CTR, /**< AES cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_AES_256_CTR, /**< AES cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_AES_128_GCM, /**< AES cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_AES_192_GCM, /**< AES cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_AES_256_GCM, /**< AES cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_ECB, /**< Camellia cipher with 128-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_ECB, /**< Camellia cipher with 192-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_ECB, /**< Camellia cipher with 256-bit ECB mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CBC, /**< Camellia cipher with 128-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CBC, /**< Camellia cipher with 192-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CBC, /**< Camellia cipher with 256-bit CBC mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, /**< Camellia cipher with 128-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, /**< Camellia cipher with 192-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, /**< Camellia cipher with 256-bit CFB128 mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CTR, /**< Camellia cipher with 128-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CTR, /**< Camellia cipher with 192-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CTR, /**< Camellia cipher with 256-bit CTR mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_GCM, /**< Camellia cipher with 128-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_GCM, /**< Camellia cipher with 192-bit GCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_GCM, /**< Camellia cipher with 256-bit GCM mode. */ + MBEDTLS_CIPHER_DES_ECB, /**< DES cipher with ECB mode. \warning DES is considered weak. */ + MBEDTLS_CIPHER_DES_CBC, /**< DES cipher with CBC mode. \warning DES is considered weak. */ + MBEDTLS_CIPHER_DES_EDE_ECB, /**< DES cipher with EDE ECB mode. \warning 3DES is considered weak. */ + MBEDTLS_CIPHER_DES_EDE_CBC, /**< DES cipher with EDE CBC mode. \warning 3DES is considered weak. */ + MBEDTLS_CIPHER_DES_EDE3_ECB, /**< DES cipher with EDE3 ECB mode. \warning 3DES is considered weak. */ + MBEDTLS_CIPHER_DES_EDE3_CBC, /**< DES cipher with EDE3 CBC mode. \warning 3DES is considered weak. */ + MBEDTLS_CIPHER_AES_128_CCM, /**< AES cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_AES_192_CCM, /**< AES cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_AES_256_CCM, /**< AES cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, /**< AES cipher with 128-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, /**< AES cipher with 192-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, /**< AES cipher with 256-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, /**< Camellia cipher with 128-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, /**< Camellia cipher with 192-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, /**< Camellia cipher with 256-bit CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_ARIA_128_ECB, /**< Aria cipher with 128-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_192_ECB, /**< Aria cipher with 192-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_256_ECB, /**< Aria cipher with 256-bit key and ECB mode. */ + MBEDTLS_CIPHER_ARIA_128_CBC, /**< Aria cipher with 128-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_192_CBC, /**< Aria cipher with 192-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_256_CBC, /**< Aria cipher with 256-bit key and CBC mode. */ + MBEDTLS_CIPHER_ARIA_128_CFB128, /**< Aria cipher with 128-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_192_CFB128, /**< Aria cipher with 192-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_256_CFB128, /**< Aria cipher with 256-bit key and CFB-128 mode. */ + MBEDTLS_CIPHER_ARIA_128_CTR, /**< Aria cipher with 128-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_192_CTR, /**< Aria cipher with 192-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_256_CTR, /**< Aria cipher with 256-bit key and CTR mode. */ + MBEDTLS_CIPHER_ARIA_128_GCM, /**< Aria cipher with 128-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_192_GCM, /**< Aria cipher with 192-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_256_GCM, /**< Aria cipher with 256-bit key and GCM mode. */ + MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ + MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, /**< Aria cipher with 128-bit key and CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, /**< Aria cipher with 192-bit key and CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, /**< Aria cipher with 256-bit key and CCM_STAR_NO_TAG mode. */ + MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ + MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */ + MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */ + MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */ +} mbedtls_cipher_type_t; + +/** Supported cipher modes. */ +typedef enum { + MBEDTLS_MODE_NONE = 0, /**< None. */ + MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ + MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ + MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ + MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ + MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ + MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ + MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ + MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ + MBEDTLS_MODE_CCM_STAR_NO_TAG, /**< The CCM*-no-tag cipher mode. */ + MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ + MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ + MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */ + MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */ +} mbedtls_cipher_mode_t; + +/** Supported cipher padding types. */ +typedef enum { + MBEDTLS_PADDING_PKCS7 = 0, /**< PKCS7 padding (default). */ + MBEDTLS_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding. */ + MBEDTLS_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding. */ + MBEDTLS_PADDING_ZEROS, /**< Zero padding (not reversible). */ + MBEDTLS_PADDING_NONE, /**< Never pad (full blocks only). */ +} mbedtls_cipher_padding_t; + +/** Type of operation. */ +typedef enum { + MBEDTLS_OPERATION_NONE = -1, + MBEDTLS_DECRYPT = 0, + MBEDTLS_ENCRYPT, +} mbedtls_operation_t; + +enum { + /** Undefined key length. */ + MBEDTLS_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys. \warning DES is considered weak. */ + MBEDTLS_KEY_LENGTH_DES = 64, + /** Key length in bits, including parity, for DES in two-key EDE. \warning 3DES is considered weak. */ + MBEDTLS_KEY_LENGTH_DES_EDE = 128, + /** Key length in bits, including parity, for DES in three-key EDE. \warning 3DES is considered weak. */ + MBEDTLS_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined + * in library/ssl_misc.h. */ +#define MBEDTLS_MAX_IV_LENGTH 16 + +/** Maximum block size of any cipher, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in library/ssl_misc.h. */ +#define MBEDTLS_MAX_BLOCK_LENGTH 16 + +/** Maximum key length, in Bytes. */ +/* This should ideally be derived automatically from list of ciphers. + * For now, only check whether XTS is enabled which uses 64 Byte keys, + * and use 32 Bytes as an upper bound for the maximum key length otherwise. + * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined + * in library/ssl_misc.h, which however deliberately ignores the case of XTS + * since the latter isn't used in SSL/TLS. */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +#define MBEDTLS_MAX_KEY_LENGTH 64 +#else +#define MBEDTLS_MAX_KEY_LENGTH 32 +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/** + * Base cipher information (opaque struct). + */ +typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; + +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + +/** + * Cipher information. Allows calling cipher functions + * in a generic way. + * + * \note The library does not support custom cipher info structures, + * only built-in structures returned by the functions + * mbedtls_cipher_info_from_string(), + * mbedtls_cipher_info_from_type(), + * mbedtls_cipher_info_from_values(), + * mbedtls_cipher_info_from_psa(). + * + * \note Some fields store a value that has been right-shifted to save + * code-size, so should not be used directly. The accessor + * functions adjust for this and return the "natural" value. + */ +typedef struct mbedtls_cipher_info_t { + /** Name of the cipher. */ + const char *MBEDTLS_PRIVATE(name); + + /** The block size, in bytes. */ + unsigned int MBEDTLS_PRIVATE(block_size) : 5; + + /** IV or nonce size, in bytes (right shifted by #MBEDTLS_IV_SIZE_SHIFT). + * For ciphers that accept variable IV sizes, + * this is the recommended size. + */ + unsigned int MBEDTLS_PRIVATE(iv_size) : 3; + + /** The cipher key length, in bits (right shifted by #MBEDTLS_KEY_BITLEN_SHIFT). + * This is the default length for variable sized ciphers. + * Includes parity bits for ciphers like DES. + */ + unsigned int MBEDTLS_PRIVATE(key_bitlen) : 4; + + /** The cipher mode (as per mbedtls_cipher_mode_t). + * For example, MBEDTLS_MODE_CBC. + */ + unsigned int MBEDTLS_PRIVATE(mode) : 4; + + /** Full cipher identifier (as per mbedtls_cipher_type_t). + * For example, MBEDTLS_CIPHER_AES_256_CBC. + * + * This could be 7 bits, but 8 bits retains byte alignment for the + * next field, which reduces code size to access that field. + */ + unsigned int MBEDTLS_PRIVATE(type) : 8; + + /** Bitflag comprised of MBEDTLS_CIPHER_VARIABLE_IV_LEN and + * MBEDTLS_CIPHER_VARIABLE_KEY_LEN indicating whether the + * cipher supports variable IV or variable key sizes, respectively. + */ + unsigned int MBEDTLS_PRIVATE(flags) : 2; + + /** Index to LUT for base cipher information and functions. */ + unsigned int MBEDTLS_PRIVATE(base_idx) : 5; + +} mbedtls_cipher_info_t; + +/* For internal use only. + * These are used to more compactly represent the fields above. */ +#define MBEDTLS_KEY_BITLEN_SHIFT 6 +#define MBEDTLS_IV_SIZE_SHIFT 2 +/** + * Generic cipher context. + */ +typedef struct mbedtls_cipher_context_t { + /** Information about the associated cipher. */ + const mbedtls_cipher_info_t *MBEDTLS_PRIVATE(cipher_info); + + /** Key length to use. */ + int MBEDTLS_PRIVATE(key_bitlen); + + /** Operation that the key of the context has been + * initialized for. + */ + mbedtls_operation_t MBEDTLS_PRIVATE(operation); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /** Padding functions to use, if relevant for + * the specific cipher mode. + */ + void(*MBEDTLS_PRIVATE(add_padding))(unsigned char *output, size_t olen, size_t data_len); + int(*MBEDTLS_PRIVATE(get_padding))(unsigned char *input, size_t ilen, size_t *data_len); +#endif + + /** Buffer for input that has not been processed yet. */ + unsigned char MBEDTLS_PRIVATE(unprocessed_data)[MBEDTLS_MAX_BLOCK_LENGTH]; + + /** Number of Bytes that have not been processed yet. */ + size_t MBEDTLS_PRIVATE(unprocessed_len); + + /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number + * for XTS-mode. */ + unsigned char MBEDTLS_PRIVATE(iv)[MBEDTLS_MAX_IV_LENGTH]; + + /** IV size in Bytes, for ciphers with variable-length IVs. */ + size_t MBEDTLS_PRIVATE(iv_size); + + /** The cipher-specific context. */ + void *MBEDTLS_PRIVATE(cipher_ctx); + +#if defined(MBEDTLS_CMAC_C) + /** CMAC-specific context. */ + mbedtls_cmac_context_t *MBEDTLS_PRIVATE(cmac_ctx); +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + /** Indicates whether the cipher operations should be performed + * by Mbed TLS' own crypto library or an external implementation + * of the PSA Crypto API. + * This is unset if the cipher context was established through + * mbedtls_cipher_setup(), and set if it was established through + * mbedtls_cipher_setup_psa(). + */ + unsigned char MBEDTLS_PRIVATE(psa_enabled); +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +} mbedtls_cipher_context_t; + +/** + * \brief This function retrieves the list of ciphers supported + * by the generic cipher module. + * + * For any cipher identifier in the returned list, you can + * obtain the corresponding generic cipher information structure + * via mbedtls_cipher_info_from_type(), which can then be used + * to prepare a cipher context via mbedtls_cipher_setup(). + * + * + * \return A statically-allocated array of cipher identifiers + * of type cipher_type_t. The last entry is zero. + */ +const int *mbedtls_cipher_list(void); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. This must not be + * \c NULL. + * + * \return The cipher information structure associated with the + * given \p cipher_name. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(const char *cipher_name); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return The cipher information structure associated with the + * given \p cipher_type. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(const mbedtls_cipher_type_t cipher_type); + +/** + * \brief This function retrieves the cipher-information + * structure associated with the given cipher ID, + * key size and mode. + * + * \param cipher_id The ID of the cipher to search for. For example, + * #MBEDTLS_CIPHER_ID_AES. + * \param key_bitlen The length of the key in bits. + * \param mode The cipher mode. For example, #MBEDTLS_MODE_CBC. + * + * \return The cipher information structure associated with the + * given \p cipher_id. + * \return \c NULL if the associated cipher information is not found. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode); + +/** + * \brief Retrieve the identifier for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The full cipher identifier (\c MBEDTLS_CIPHER_xxx). + * \return #MBEDTLS_CIPHER_NONE if \p info is \c NULL. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_info_get_type( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return MBEDTLS_CIPHER_NONE; + } else { + return (mbedtls_cipher_type_t) info->MBEDTLS_PRIVATE(type); + } +} + +/** + * \brief Retrieve the operation mode for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The cipher mode (\c MBEDTLS_MODE_xxx). + * \return #MBEDTLS_MODE_NONE if \p info is \c NULL. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_info_get_mode( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return MBEDTLS_MODE_NONE; + } else { + return (mbedtls_cipher_mode_t) info->MBEDTLS_PRIVATE(mode); + } +} + +/** + * \brief Retrieve the key size for a cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The key length in bits. + * For variable-sized ciphers, this is the default length. + * For DES, this includes the parity bits. + * \return \c 0 if \p info is \c NULL. + */ +static inline size_t mbedtls_cipher_info_get_key_bitlen( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return 0; + } else { + return info->MBEDTLS_PRIVATE(key_bitlen) << MBEDTLS_KEY_BITLEN_SHIFT; + } +} + +/** + * \brief Retrieve the human-readable name for a + * cipher info structure. + * + * \param[in] info The cipher info structure to query. + * This may be \c NULL. + * + * \return The cipher name, which is a human readable string, + * with static storage duration. + * \return \c NULL if \p info is \c NULL. + */ +static inline const char *mbedtls_cipher_info_get_name( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return NULL; + } else { + return info->MBEDTLS_PRIVATE(name); + } +} + +/** + * \brief This function returns the size of the IV or nonce + * for the cipher info structure, in bytes. + * + * \param info The cipher info structure. This may be \c NULL. + * + * \return The recommended IV size. + * \return \c 0 for ciphers not using an IV or a nonce. + * \return \c 0 if \p info is \c NULL. + */ +static inline size_t mbedtls_cipher_info_get_iv_size( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return 0; + } + + return ((size_t) info->MBEDTLS_PRIVATE(iv_size)) << MBEDTLS_IV_SIZE_SHIFT; +} + +/** + * \brief This function returns the block size of the given + * cipher info structure in bytes. + * + * \param info The cipher info structure. This may be \c NULL. + * + * \return The block size of the cipher. + * \return \c 1 if the cipher is a stream cipher. + * \return \c 0 if \p info is \c NULL. + */ +static inline size_t mbedtls_cipher_info_get_block_size( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return 0; + } + + return (size_t) (info->MBEDTLS_PRIVATE(block_size)); +} + +/** + * \brief This function returns a non-zero value if the key length for + * the given cipher is variable. + * + * \param info The cipher info structure. This may be \c NULL. + * + * \return Non-zero if the key length is variable, \c 0 otherwise. + * \return \c 0 if the given pointer is \c NULL. + */ +static inline int mbedtls_cipher_info_has_variable_key_bitlen( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return 0; + } + + return info->MBEDTLS_PRIVATE(flags) & MBEDTLS_CIPHER_VARIABLE_KEY_LEN; +} + +/** + * \brief This function returns a non-zero value if the IV size for + * the given cipher is variable. + * + * \param info The cipher info structure. This may be \c NULL. + * + * \return Non-zero if the IV size is variable, \c 0 otherwise. + * \return \c 0 if the given pointer is \c NULL. + */ +static inline int mbedtls_cipher_info_has_variable_iv_size( + const mbedtls_cipher_info_t *info) +{ + if (info == NULL) { + return 0; + } + + return info->MBEDTLS_PRIVATE(flags) & MBEDTLS_CIPHER_VARIABLE_IV_LEN; +} + +/** + * \brief This function initializes a \p ctx as NONE. + * + * \param ctx The context to be initialized. This must not be \c NULL. + */ +void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx); + +/** + * \brief This function frees and clears the cipher-specific + * context of \p ctx. Freeing \p ctx itself remains the + * responsibility of the caller. + * + * \param ctx The context to be freed. If this is \c NULL, the + * function has no effect, otherwise this must point to an + * initialized context. + */ +void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx); + + +/** + * \brief This function prepares a cipher context for + * use with the given cipher primitive. + * + * \note After calling this function, you should call + * mbedtls_cipher_setkey() and, if the mode uses padding, + * mbedtls_cipher_set_padding_mode(), then for each + * message to encrypt or decrypt with this key, either: + * - mbedtls_cipher_crypt() for one-shot processing with + * non-AEAD modes; + * - mbedtls_cipher_auth_encrypt_ext() or + * mbedtls_cipher_auth_decrypt_ext() for one-shot + * processing with AEAD modes or NIST_KW; + * - for multi-part processing, see the documentation of + * mbedtls_cipher_reset(). + * + * \param ctx The context to prepare. This must be initialized by + * a call to mbedtls_cipher_init() first. + * \param cipher_info The cipher to use. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + */ +int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info); + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +/** + * \brief This function initializes a cipher context for + * PSA-based use with the given cipher primitive. + * + * \deprecated This function is deprecated and will be removed in a + * future version of the library. + * Please use psa_aead_xxx() / psa_cipher_xxx() directly + * instead. + * + * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA. + * + * \param ctx The context to initialize. May not be \c NULL. + * \param cipher_info The cipher to use. + * \param taglen For AEAD ciphers, the length in bytes of the + * authentication tag to use. Subsequent uses of + * mbedtls_cipher_auth_encrypt_ext() or + * mbedtls_cipher_auth_decrypt_ext() must provide + * the same tag length. + * For non-AEAD ciphers, the value must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context fails. + */ +int MBEDTLS_DEPRECATED mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + size_t taglen); +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +/** + * \brief This function returns the block size of the given cipher + * in bytes. + * + * \param ctx The context of the cipher. + * + * \return The block size of the underlying cipher. + * \return \c 1 if the cipher is a stream cipher. + * \return \c 0 if \p ctx has not been initialized. + */ +static inline unsigned int mbedtls_cipher_get_block_size( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return 0; + } + + return (unsigned int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(block_size); +} + +/** + * \brief This function returns the mode of operation for + * the cipher. For example, MBEDTLS_MODE_CBC. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The mode of operation. + * \return #MBEDTLS_MODE_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_mode_t mbedtls_cipher_get_cipher_mode( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, MBEDTLS_MODE_NONE); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return MBEDTLS_MODE_NONE; + } + + return (mbedtls_cipher_mode_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(mode); +} + +/** + * \brief This function returns the size of the IV or nonce + * of the cipher, in Bytes. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The recommended IV size if no IV has been set. + * \return \c 0 for ciphers not using an IV or a nonce. + * \return The actual size if an IV has been set. + */ +static inline int mbedtls_cipher_get_iv_size( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return 0; + } + + if (ctx->MBEDTLS_PRIVATE(iv_size) != 0) { + return (int) ctx->MBEDTLS_PRIVATE(iv_size); + } + + return (int) (((int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(iv_size)) << + MBEDTLS_IV_SIZE_SHIFT); +} + +/** + * \brief This function returns the type of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of the cipher. + * \return #MBEDTLS_CIPHER_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_cipher_type_t mbedtls_cipher_get_type( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_CIPHER_NONE); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return MBEDTLS_CIPHER_NONE; + } + + return (mbedtls_cipher_type_t) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type); +} + +/** + * \brief This function returns the name of the given cipher + * as a string. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The name of the cipher. + * \return NULL if \p ctx has not been not initialized. + */ +static inline const char *mbedtls_cipher_get_name( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET(ctx != NULL, 0); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return 0; + } + + return ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(name); +} + +/** + * \brief This function returns the key length of the cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The key length of the cipher in bits. + * \return #MBEDTLS_KEY_LENGTH_NONE if \p ctx has not been + * initialized. + */ +static inline int mbedtls_cipher_get_key_bitlen( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_KEY_LENGTH_NONE); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return MBEDTLS_KEY_LENGTH_NONE; + } + + return (int) ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(key_bitlen) << + MBEDTLS_KEY_BITLEN_SHIFT; +} + +/** + * \brief This function returns the operation of the given cipher. + * + * \param ctx The context of the cipher. This must be initialized. + * + * \return The type of operation: #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * \return #MBEDTLS_OPERATION_NONE if \p ctx has not been initialized. + */ +static inline mbedtls_operation_t mbedtls_cipher_get_operation( + const mbedtls_cipher_context_t *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE_RET( + ctx != NULL, MBEDTLS_OPERATION_NONE); + if (ctx->MBEDTLS_PRIVATE(cipher_info) == NULL) { + return MBEDTLS_OPERATION_NONE; + } + + return ctx->MBEDTLS_PRIVATE(operation); +} + +/** + * \brief This function sets the key to use with the given context. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param key The key to use. This must be a readable buffer of at + * least \p key_bitlen Bits. + * \param key_bitlen The key length to use, in Bits. + * \param operation The operation that the key will be used for: + * #MBEDTLS_ENCRYPT or #MBEDTLS_DECRYPT. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, + const unsigned char *key, + int key_bitlen, + const mbedtls_operation_t operation); + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +/** + * \brief This function sets the padding mode, for cipher modes + * that use padding. + * + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param mode The padding mode. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE + * if the selected padding mode is not supported. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, + mbedtls_cipher_padding_t mode); +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief This function sets the initialization vector (IV) + * or nonce. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, this function has no effect. + * + * \note For #MBEDTLS_CIPHER_CHACHA20, the nonce length must + * be 12, and the initial counter value is 0. + * + * \note For #MBEDTLS_CIPHER_CHACHA20_POLY1305, the nonce length + * must be 12. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a cipher information structure. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. This + * must be a readable buffer of at least \p iv_len Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size IV. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, + size_t iv_len); + +/** + * \brief This function resets the cipher state. + * + * \note With non-AEAD ciphers, the order of calls for each message + * is as follows: + * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce. + * 2. mbedtls_cipher_reset() + * 3. mbedtls_cipher_update() one or more times + * 4. mbedtls_cipher_finish() + * . + * This sequence can be repeated to encrypt or decrypt multiple + * messages with the same key. + * + * \note With AEAD ciphers, the order of calls for each message + * is as follows: + * 1. mbedtls_cipher_set_iv() if the mode uses an IV/nonce. + * 2. mbedtls_cipher_reset() + * 3. mbedtls_cipher_update_ad() + * 4. mbedtls_cipher_update() one or more times + * 5. mbedtls_cipher_finish() + * 6. mbedtls_cipher_check_tag() (for decryption) or + * mbedtls_cipher_write_tag() (for encryption). + * . + * This sequence can be repeated to encrypt or decrypt multiple + * messages with the same key. + * + * \param ctx The generic cipher context. This must be bound to a key. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + */ +int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function adds additional data for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * + * \param ctx The generic cipher context. This must be initialized. + * \param ad The additional data to use. This must be a readable + * buffer of at least \p ad_len Bytes. + * \param ad_len The length of \p ad in Bytes. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic cipher update function. It encrypts or + * decrypts using the given cipher context. Writes as + * many block-sized blocks of data as possible to output. + * Any data that cannot be written immediately is either + * added to the next block, or flushed when + * mbedtls_cipher_finish() is called. + * Exception: For MBEDTLS_MODE_ECB, expects a single block + * in size. For example, 16 Bytes for AES. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, + const unsigned char *input, + size_t ilen, unsigned char *output, + size_t *olen); + +/** + * \brief The generic cipher finalization function. If data still + * needs to be flushed from an incomplete block, the data + * contained in it is padded to the size of + * the last block, and written to the \p output buffer. + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key. + * \param output The buffer to write data to. This needs to be a writable + * buffer of at least block_size Bytes. + * \param olen The length of the data written to the \p output buffer. + * This may not be \c NULL. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen); + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +/** + * \brief This function writes a tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized, + * bound to a key, and have just completed a cipher + * operation through mbedtls_cipher_finish() the tag for + * which should be written. + * \param tag The buffer to write the tag to. This must be a writable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to write. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len); + +/** + * \brief This function checks the tag for AEAD ciphers. + * Currently supported with GCM and ChaCha20+Poly1305. + * This must be called after mbedtls_cipher_finish(). + * + * \param ctx The generic cipher context. This must be initialized. + * \param tag The buffer holding the tag. This must be a readable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to check. + * + * \return \c 0 on success. + * \return A specific error code on failure. + */ +int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len); +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/** + * \brief The generic all-in-one encryption/decryption function, + * for all ciphers except AEAD constructs. + * + * \param ctx The generic cipher context. This must be initialized. + * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers. + * This must be a readable buffer of at least \p iv_len + * Bytes. + * \param iv_len The IV length for ciphers with variable-size IV. + * This parameter is discarded by ciphers with fixed-size + * IV. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The buffer for the output data. This must be able to + * hold at least `ilen + block_size`. This must not be the + * same buffer as \p input. + * \param olen The length of the output data, to be updated with the + * actual number of Bytes written. This must not be + * \c NULL. + * + * \note Some ciphers do not use IVs nor nonce. For these + * ciphers, use \p iv = NULL and \p iv_len = 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED on decryption + * expecting a full block but not receiving one. + * \return #MBEDTLS_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen); + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note For AEAD modes, the tag will be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * must not be \c NULL. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen + \p tag_len. + * For NIST_KW, this must be at least \p ilen + 8 + * (rounded up to a multiple of 8 if KWP is used); + * \p ilen + 15 is always a safe value. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The desired length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len); + +/** + * \brief The authenticated encryption (AEAD/NIST_KW) function. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext being + * used, making this interface safer. + * + * \note For AEAD modes, the tag must be appended to the + * ciphertext, as recommended by RFC 5116. + * (NIST_KW doesn't have a separate tag.) + * + * \param ctx The generic cipher context. This must be initialized and + * bound to a key, with an AEAD algorithm or NIST_KW. + * \param iv The nonce to use. This must be a readable buffer of + * at least \p iv_len Bytes and may be \c NULL if \p + * iv_len is \c 0. + * \param iv_len The length of the nonce. For AEAD ciphers, this must + * satisfy the constraints imposed by the cipher used. + * For NIST_KW, this must be \c 0. + * \param ad The additional data to authenticate. This must be a + * readable buffer of at least \p ad_len Bytes, and may + * be \c NULL is \p ad_len is \c 0. + * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0. + * \param input The buffer holding the input data. This must be a + * readable buffer of at least \p ilen Bytes, and may be + * \c NULL if \p ilen is \c 0. + * \param ilen The length of the input data. For AEAD ciphers this + * must be at least \p tag_len. For NIST_KW this must be + * at least \c 8. + * \param output The buffer for the output data. This must be a + * writable buffer of at least \p output_len Bytes, and + * may be \c NULL if \p output_len is \c 0. + * \param output_len The length of the \p output buffer in Bytes. For AEAD + * ciphers, this must be at least \p ilen - \p tag_len. + * For NIST_KW, this must be at least \p ilen - 8. + * \param olen This will be filled with the actual number of Bytes + * written to the \p output buffer. This must point to a + * writable object of type \c size_t. + * \param tag_len The actual length of the authentication tag. For AEAD + * ciphers, this must match the constraints imposed by + * the cipher used, and in particular must not be \c 0. + * For NIST_KW, this must be \c 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on + * parameter-verification failure. + * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len); +#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/cmac.h b/src/app/findmy/crypto/third-party/mbedtls/cmac.h new file mode 100644 index 0000000..97b86fc --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/cmac.h @@ -0,0 +1,246 @@ +/** + * \file cmac.h + * + * \brief This file contains CMAC definitions and functions. + * + * The Cipher-based Message Authentication Code (CMAC) Mode for + * Authentication is defined in RFC-4493: The AES-CMAC Algorithm. + * It is supported with AES and DES. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CMAC_H +#define MBEDTLS_CMAC_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MBEDTLS_AES_BLOCK_SIZE 16 +#define MBEDTLS_DES3_BLOCK_SIZE 8 + +/* We don't support Camellia or ARIA in this module */ +#if defined(MBEDTLS_AES_C) +#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 16 /**< The longest block used by CMAC is that of AES. */ +#else +#define MBEDTLS_CMAC_MAX_BLOCK_SIZE 8 /**< The longest block used by CMAC is that of 3DES. */ +#endif + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +/** The longest block supported by the cipher module. + * + * \deprecated + * For the maximum block size of a cipher supported by the CMAC module, + * use #MBEDTLS_CMAC_MAX_BLOCK_SIZE. + * For the maximum block size of a cipher supported by the cipher module, + * use #MBEDTLS_MAX_BLOCK_LENGTH. + */ +/* Before Mbed TLS 3.5, this was the maximum block size supported by the CMAC + * module, so it didn't take Camellia or ARIA into account. Since the name + * of the macro doesn't even convey "CMAC", this was misleading. Now the size + * is sufficient for any cipher, but the name is defined in cmac.h for + * backward compatibility. */ +#define MBEDTLS_CIPHER_BLKSIZE_MAX MBEDTLS_MAX_BLOCK_LENGTH +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +#if !defined(MBEDTLS_CMAC_ALT) + +/** + * The CMAC context structure. + */ +struct mbedtls_cmac_context_t { + /** The internal state of the CMAC algorithm. */ + unsigned char MBEDTLS_PRIVATE(state)[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; + + /** Unprocessed data - either data that was not block aligned and is still + * pending processing, or the final block. */ + unsigned char MBEDTLS_PRIVATE(unprocessed_block)[MBEDTLS_CMAC_MAX_BLOCK_SIZE]; + + /** The length of data pending processing. */ + size_t MBEDTLS_PRIVATE(unprocessed_len); +}; + +#else /* !MBEDTLS_CMAC_ALT */ +#include "cmac_alt.h" +#endif /* !MBEDTLS_CMAC_ALT */ + +/** + * \brief This function starts a new CMAC computation + * by setting the CMAC key, and preparing to authenticate + * the input data. + * It must be called with an initialized cipher context. + * + * Once this function has completed, data can be supplied + * to the CMAC computation by calling + * mbedtls_cipher_cmac_update(). + * + * To start a CMAC computation using the same key as a previous + * CMAC computation, use mbedtls_cipher_cmac_finish(). + * + * \note When the CMAC implementation is supplied by an alternate + * implementation (through #MBEDTLS_CMAC_ALT), some ciphers + * may not be supported by that implementation, and thus + * return an error. Alternate implementations must support + * AES-128 and AES-256, and may support AES-192 and 3DES. + * + * \param ctx The cipher context used for the CMAC operation, initialized + * as one of the following types: MBEDTLS_CIPHER_AES_128_ECB, + * MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB, + * or MBEDTLS_CIPHER_DES_EDE3_ECB. + * \param key The CMAC key. + * \param keybits The length of the CMAC key in bits. + * Must be supported by the cipher. + * + * \return \c 0 on success. + * \return A cipher-specific error code on failure. + */ +int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx, + const unsigned char *key, size_t keybits); + +/** + * \brief This function feeds an input buffer into an ongoing CMAC + * computation. + * + * The CMAC computation must have previously been started + * by calling mbedtls_cipher_cmac_starts() or + * mbedtls_cipher_cmac_reset(). + * + * Call this function as many times as needed to input the + * data to be authenticated. + * Once all of the required data has been input, + * call mbedtls_cipher_cmac_finish() to obtain the result + * of the CMAC operation. + * + * \param ctx The cipher context used for the CMAC operation. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx, + const unsigned char *input, size_t ilen); + +/** + * \brief This function finishes an ongoing CMAC operation, and + * writes the result to the output buffer. + * + * It should be followed either by + * mbedtls_cipher_cmac_reset(), which starts another CMAC + * operation with the same key, or mbedtls_cipher_free(), + * which clears the cipher context. + * + * \param ctx The cipher context used for the CMAC operation. + * \param output The output buffer for the CMAC checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx, + unsigned char *output); + +/** + * \brief This function starts a new CMAC operation with the same + * key as the previous one. + * + * It should be called after finishing the previous CMAC + * operation with mbedtls_cipher_cmac_finish(). + * After calling this function, + * call mbedtls_cipher_cmac_update() to supply the new + * CMAC operation with data. + * + * \param ctx The cipher context used for the CMAC operation. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx); + +/** + * \brief This function calculates the full generic CMAC + * on the input buffer with the provided key. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The CMAC result is calculated as + * output = generic CMAC(cmac key, input buffer). + * + * \note When the CMAC implementation is supplied by an alternate + * implementation (through #MBEDTLS_CMAC_ALT), some ciphers + * may not be supported by that implementation, and thus + * return an error. Alternate implementations must support + * AES-128 and AES-256, and may support AES-192 and 3DES. + * + * \param cipher_info The cipher information. + * \param key The CMAC key. + * \param keylen The length of the CMAC key in bits. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The buffer for the generic CMAC result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA + * if parameter verification fails. + */ +int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info, + const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output); + +#if defined(MBEDTLS_AES_C) +/** + * \brief This function implements the AES-CMAC-PRF-128 pseudorandom + * function, as defined in + * RFC-4615: The Advanced Encryption Standard-Cipher-based + * Message Authentication Code-Pseudo-Random Function-128 + * (AES-CMAC-PRF-128) Algorithm for the Internet Key + * Exchange Protocol (IKE). + * + * \param key The key to use. + * \param key_len The key length in Bytes. + * \param input The buffer holding the input data. + * \param in_len The length of the input data in Bytes. + * \param output The buffer holding the generated 16 Bytes of + * pseudorandom output. + * + * \return \c 0 on success. + */ +int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_len, + const unsigned char *input, size_t in_len, + unsigned char output[16]); +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_SELF_TEST) && (defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C)) +/** + * \brief The CMAC checkup routine. + * + * \note In case the CMAC routines are provided by an alternative + * implementation (i.e. #MBEDTLS_CMAC_ALT is defined), the + * checkup routine will succeed even if the implementation does + * not support the less widely used AES-192 or 3DES primitives. + * The self-test requires at least AES-128 and AES-256 to be + * supported by the underlying implementation. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_cmac_self_test(int verbose); +#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CMAC_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/common.h b/src/app/findmy/crypto/third-party/mbedtls/common.h new file mode 100644 index 0000000..c6ed14b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/common.h @@ -0,0 +1,325 @@ +/** + * \file common.h + * + * \brief Utility macros for internal use in the library + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_LIBRARY_COMMON_H +#define MBEDTLS_LIBRARY_COMMON_H + +#include "mbedtls/build_info.h" +#include "alignment.h" + +#include +#include +#include +#include + +#if defined(__ARM_NEON) +#include +#endif /* __ARM_NEON */ + +/** Helper to define a function as static except when building invasive tests. + * + * If a function is only used inside its own source file and should be + * declared `static` to allow the compiler to optimize for code size, + * but that function has unit tests, define it with + * ``` + * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... } + * ``` + * and declare it in a header in the `library/` directory with + * ``` + * #if defined(MBEDTLS_TEST_HOOKS) + * int mbedtls_foo(...); + * #endif + * ``` + */ +#if defined(MBEDTLS_TEST_HOOKS) +#define MBEDTLS_STATIC_TESTABLE +#else +#define MBEDTLS_STATIC_TESTABLE static +#endif + +#if defined(MBEDTLS_TEST_HOOKS) +extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file); +#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \ + do { \ + if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \ + { \ + (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \ + } \ + } while (0) +#else +#define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) +#endif /* defined(MBEDTLS_TEST_HOOKS) */ + +/** \def ARRAY_LENGTH + * Return the number of elements of a static or stack array. + * + * \param array A value of array (not pointer) type. + * + * \return The number of elements of the array. + */ +/* A correct implementation of ARRAY_LENGTH, but which silently gives + * a nonsensical result if called with a pointer rather than an array. */ +#define ARRAY_LENGTH_UNSAFE(array) \ + (sizeof(array) / sizeof(*(array))) + +#if defined(__GNUC__) +/* Test if arg and &(arg)[0] have the same type. This is true if arg is + * an array but not if it's a pointer. */ +#define IS_ARRAY_NOT_POINTER(arg) \ + (!__builtin_types_compatible_p(__typeof__(arg), \ + __typeof__(&(arg)[0]))) +/* A compile-time constant with the value 0. If `const_expr` is not a + * compile-time constant with a nonzero value, cause a compile-time error. */ +#define STATIC_ASSERT_EXPR(const_expr) \ + (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); })) + +/* Return the scalar value `value` (possibly promoted). This is a compile-time + * constant if `value` is. `condition` must be a compile-time constant. + * If `condition` is false, arrange to cause a compile-time error. */ +#define STATIC_ASSERT_THEN_RETURN(condition, value) \ + (STATIC_ASSERT_EXPR(condition) ? 0 : (value)) + +#define ARRAY_LENGTH(array) \ + (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array), \ + ARRAY_LENGTH_UNSAFE(array))) + +#else +/* If we aren't sure the compiler supports our non-standard tricks, + * fall back to the unsafe implementation. */ +#define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array) +#endif +/** Allow library to access its structs' private members. + * + * Although structs defined in header files are publicly available, + * their members are private and should not be accessed by the user. + */ +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + +/** + * \brief Securely zeroize a buffer then free it. + * + * Similar to making consecutive calls to + * \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has + * code size savings, and potential for optimisation in the future. + * + * Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0. + * + * \param buf Buffer to be zeroized then freed. + * \param len Length of the buffer in bytes + */ +void mbedtls_zeroize_and_free(void *buf, size_t len); + +/** Return an offset into a buffer. + * + * This is just the addition of an offset to a pointer, except that this + * function also accepts an offset of 0 into a buffer whose pointer is null. + * (`p + n` has undefined behavior when `p` is null, even when `n == 0`. + * A null pointer is a valid buffer pointer when the size is 0, for example + * as the result of `malloc(0)` on some platforms.) + * + * \param p Pointer to a buffer of at least n bytes. + * This may be \p NULL if \p n is zero. + * \param n An offset in bytes. + * \return Pointer to offset \p n in the buffer \p p. + * Note that this is only a valid pointer if the size of the + * buffer is at least \p n + 1. + */ +static inline unsigned char *mbedtls_buffer_offset( + unsigned char *p, size_t n) +{ + return p == NULL ? NULL : p + n; +} + +/** Return an offset into a read-only buffer. + * + * Similar to mbedtls_buffer_offset(), but for const pointers. + * + * \param p Pointer to a buffer of at least n bytes. + * This may be \p NULL if \p n is zero. + * \param n An offset in bytes. + * \return Pointer to offset \p n in the buffer \p p. + * Note that this is only a valid pointer if the size of the + * buffer is at least \p n + 1. + */ +static inline const unsigned char *mbedtls_buffer_offset_const( + const unsigned char *p, size_t n) +{ + return p == NULL ? NULL : p + n; +} + +/** + * Perform a fast block XOR operation, such that + * r[i] = a[i] ^ b[i] where 0 <= i < n + * + * \param r Pointer to result (buffer of at least \p n bytes). \p r + * may be equal to either \p a or \p b, but behaviour when + * it overlaps in other ways is undefined. + * \param a Pointer to input (buffer of at least \p n bytes) + * \param b Pointer to input (buffer of at least \p n bytes) + * \param n Number of bytes to process. + */ +inline void mbedtls_xor(unsigned char *r, const unsigned char *a, const unsigned char *b, size_t n) +{ + size_t i = 0; +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) +#if defined(__ARM_NEON) + for (; (i + 16) <= n; i += 16) { + uint8x16_t v1 = vld1q_u8(a + i); + uint8x16_t v2 = vld1q_u8(b + i); + uint8x16_t x = veorq_u8(v1, v2); + vst1q_u8(r + i, x); + } +#elif defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) + /* This codepath probably only makes sense on architectures with 64-bit registers */ + for (; (i + 8) <= n; i += 8) { + uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); + mbedtls_put_unaligned_uint64(r + i, x); + } +#else + for (; (i + 4) <= n; i += 4) { + uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); + mbedtls_put_unaligned_uint32(r + i, x); + } +#endif +#endif + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; + } +} + +/** + * Perform a fast block XOR operation, such that + * r[i] = a[i] ^ b[i] where 0 <= i < n + * + * In some situations, this can perform better than mbedtls_xor (e.g., it's about 5% + * better in AES-CBC). + * + * \param r Pointer to result (buffer of at least \p n bytes). \p r + * may be equal to either \p a or \p b, but behaviour when + * it overlaps in other ways is undefined. + * \param a Pointer to input (buffer of at least \p n bytes) + * \param b Pointer to input (buffer of at least \p n bytes) + * \param n Number of bytes to process. + */ +static inline void mbedtls_xor_no_simd(unsigned char *r, + const unsigned char *a, + const unsigned char *b, + size_t n) +{ + size_t i = 0; +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) +#if defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) + /* This codepath probably only makes sense on architectures with 64-bit registers */ + for (; (i + 8) <= n; i += 8) { + uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i); + mbedtls_put_unaligned_uint64(r + i, x); + } +#else + for (; (i + 4) <= n; i += 4) { + uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i); + mbedtls_put_unaligned_uint32(r + i, x); + } +#endif +#endif + for (; i < n; i++) { + r[i] = a[i] ^ b[i]; + } +} + +/* Fix MSVC C99 compatible issue + * MSVC support __func__ from visual studio 2015( 1900 ) + * Use MSVC predefine macro to avoid name check fail. + */ +#if (defined(_MSC_VER) && (_MSC_VER <= 1900)) +#define /*no-check-names*/ __func__ __FUNCTION__ +#endif + +/* Define `asm` for compilers which don't define it. */ +/* *INDENT-OFF* */ +#ifndef asm +#if defined(__IAR_SYSTEMS_ICC__) +#define asm __asm +#else +#define asm __asm__ +#endif +#endif +/* *INDENT-ON* */ + +/* + * Define the constraint used for read-only pointer operands to aarch64 asm. + * + * This is normally the usual "r", but for aarch64_32 (aka ILP32, + * as found in watchos), "p" is required to avoid warnings from clang. + * + * Note that clang does not recognise '+p' or '=p', and armclang + * does not recognise 'p' at all. Therefore, to update a pointer from + * aarch64 assembly, it is necessary to use something like: + * + * uintptr_t uptr = (uintptr_t) ptr; + * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : ) + * ptr = (void*) uptr; + * + * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings. + */ +#if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM) +#if UINTPTR_MAX == 0xfffffffful +/* ILP32: Specify the pointer operand slightly differently, as per #7787. */ +#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p" +#elif UINTPTR_MAX == 0xfffffffffffffffful +/* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */ +#define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r" +#else +#error "Unrecognised pointer size for aarch64" +#endif +#endif + +/* Always provide a static assert macro, so it can be used unconditionally. + * It will expand to nothing on some systems. + * Can be used outside functions (but don't add a trailing ';' in that case: + * the semicolon is included here to avoid triggering -Wextra-semi when + * MBEDTLS_STATIC_ASSERT() expands to nothing). + * Can't use the C11-style `defined(static_assert)` on FreeBSD, since it + * defines static_assert even with -std=c99, but then complains about it. + */ +#if defined(static_assert) && !defined(__FreeBSD__) +#define MBEDTLS_STATIC_ASSERT(expr, msg) static_assert(expr, msg); +#else +#define MBEDTLS_STATIC_ASSERT(expr, msg) +#endif + +/* Define compiler branch hints */ +#if defined(__has_builtin) +#if __has_builtin(__builtin_expect) +#define MBEDTLS_LIKELY(x) __builtin_expect(!!(x), 1) +#define MBEDTLS_UNLIKELY(x) __builtin_expect(!!(x), 0) +#endif +#endif +#if !defined(MBEDTLS_LIKELY) +#define MBEDTLS_LIKELY(x) x +#define MBEDTLS_UNLIKELY(x) x +#endif + +#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && !defined(__clang__) \ + && !defined(__llvm__) && !defined(__INTEL_COMPILER) +/* Defined if the compiler really is gcc and not clang, etc */ +#define MBEDTLS_COMPILER_IS_GCC +#endif + +/* For gcc -Os, override with -O2 for a given function. + * + * This will not affect behaviour for other optimisation settings, e.g. -O0. + */ +#if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__) +#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2"))) +#else +#define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE +#endif + +#endif /* MBEDTLS_LIBRARY_COMMON_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_crypto.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_crypto.h new file mode 100644 index 0000000..f769765 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_crypto.h @@ -0,0 +1,183 @@ +/** + * \file mbedtls/config_adjust_legacy_crypto.h + * \brief Adjust legacy configuration configuration + * + * Automatically enable certain dependencies. Generally, MBEDLTS_xxx + * configurations need to be explicitly enabled by the user: enabling + * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a + * compilation error. However, we do automatically enable certain options + * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option + * used to identify parts of a module that are used by other module, and we + * don't want to make the symbol MBEDTLS_xxx_B part of the public API. + * Another case is if A didn't depend on B in earlier versions, and we + * want to use B in A but we need to preserve backward compatibility with + * configurations that explicitly activate MBEDTLS_xxx_A but not + * MBEDTLS_xxx_B. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H +#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H + +/* Auto-enable MBEDTLS_MD_LIGHT based on MBEDTLS_MD_C. + * This allows checking for MD_LIGHT rather than MD_LIGHT || MD_C. + */ +#if defined(MBEDTLS_MD_C) +#define MBEDTLS_MD_LIGHT +#endif + +/* Auto-enable MBEDTLS_MD_LIGHT if needed by a module that didn't require it + * in a previous release, to ensure backwards compatibility. + */ +#if defined(MBEDTLS_ECJPAKE_C) || \ + defined(MBEDTLS_PEM_PARSE_C) || \ + defined(MBEDTLS_ENTROPY_C) || \ + defined(MBEDTLS_PK_C) || \ + defined(MBEDTLS_PKCS12_C) || \ + defined(MBEDTLS_RSA_C) || \ + defined(MBEDTLS_SSL_TLS_C) || \ + defined(MBEDTLS_X509_USE_C) || \ + defined(MBEDTLS_X509_CREATE_C) +#define MBEDTLS_MD_LIGHT +#endif + +/* MBEDTLS_ECP_LIGHT is auto-enabled by the following symbols: + * - MBEDTLS_ECP_C because now it consists of MBEDTLS_ECP_LIGHT plus functions + * for curve arithmetic. As a consequence if MBEDTLS_ECP_C is required for + * some reason, then MBEDTLS_ECP_LIGHT should be enabled as well. + * - MBEDTLS_PK_PARSE_EC_EXTENDED and MBEDTLS_PK_PARSE_EC_COMPRESSED because + * these features are not supported in PSA so the only way to have them is + * to enable the built-in solution. + * Both of them are temporary dependencies: + * - PK_PARSE_EC_EXTENDED will be removed after #7779 and #7789 + * - support for compressed points should also be added to PSA, but in this + * case there is no associated issue to track it yet. + * - PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE because Weierstrass key derivation + * still depends on ECP_LIGHT. + * - PK_C + USE_PSA + PSA_WANT_ALG_ECDSA is a temporary dependency which will + * be fixed by #7453. + */ +#if defined(MBEDTLS_ECP_C) || \ + defined(MBEDTLS_PK_PARSE_EC_EXTENDED) || \ + defined(MBEDTLS_PK_PARSE_EC_COMPRESSED) || \ + defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE) +#define MBEDTLS_ECP_LIGHT +#endif + +/* MBEDTLS_PK_PARSE_EC_COMPRESSED is introduced in MbedTLS version 3.5, while + * in previous version compressed points were automatically supported as long + * as PK_PARSE_C and ECP_C were enabled. As a consequence, for backward + * compatibility, we auto-enable PK_PARSE_EC_COMPRESSED when these conditions + * are met. */ +#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_ECP_C) +#define MBEDTLS_PK_PARSE_EC_COMPRESSED +#endif + +/* Helper symbol to state that there is support for ECDH, either through + * library implementation (ECDH_C) or through PSA. */ +#if (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_ALG_ECDH)) || \ + (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECDH_C)) +#define MBEDTLS_CAN_ECDH +#endif + +/* PK module can achieve ECDSA functionalities by means of either software + * implementations (ECDSA_C) or through a PSA driver. The following defines + * are meant to list these capabilities in a general way which abstracts how + * they are implemented under the hood. */ +#if !defined(MBEDTLS_USE_PSA_CRYPTO) +#if defined(MBEDTLS_ECDSA_C) +#define MBEDTLS_PK_CAN_ECDSA_SIGN +#define MBEDTLS_PK_CAN_ECDSA_VERIFY +#endif /* MBEDTLS_ECDSA_C */ +#else /* MBEDTLS_USE_PSA_CRYPTO */ +#if defined(PSA_WANT_ALG_ECDSA) +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) +#define MBEDTLS_PK_CAN_ECDSA_SIGN +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */ +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) +#define MBEDTLS_PK_CAN_ECDSA_VERIFY +#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ +#endif /* PSA_WANT_ALG_ECDSA */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY) || defined(MBEDTLS_PK_CAN_ECDSA_SIGN) +#define MBEDTLS_PK_CAN_ECDSA_SOME +#endif + +/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT + * is defined as well to include all PSA code. + */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#define MBEDTLS_PSA_CRYPTO_CLIENT +#endif /* MBEDTLS_PSA_CRYPTO_C */ + +/* The PK wrappers need pk_write functions to format RSA key objects + * when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO, + * and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). */ +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C) +#define MBEDTLS_PK_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PK_PARSE_C +#endif + +/* Helpers to state that each key is supported either on the builtin or PSA side. */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521) +#define MBEDTLS_ECP_HAVE_SECP521R1 +#endif +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) +#define MBEDTLS_ECP_HAVE_BP512R1 +#endif +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_448) +#define MBEDTLS_ECP_HAVE_CURVE448 +#endif +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) +#define MBEDTLS_ECP_HAVE_BP384R1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_384) +#define MBEDTLS_ECP_HAVE_SECP384R1 +#endif +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) +#define MBEDTLS_ECP_HAVE_BP256R1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_256) +#define MBEDTLS_ECP_HAVE_SECP256K1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_256) +#define MBEDTLS_ECP_HAVE_SECP256R1 +#endif +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || defined(PSA_WANT_ECC_MONTGOMERY_255) +#define MBEDTLS_ECP_HAVE_CURVE25519 +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_224) +#define MBEDTLS_ECP_HAVE_SECP224K1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_224) +#define MBEDTLS_ECP_HAVE_SECP224R1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || defined(PSA_WANT_ECC_SECP_K1_192) +#define MBEDTLS_ECP_HAVE_SECP192K1 +#endif +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_192) +#define MBEDTLS_ECP_HAVE_SECP192R1 +#endif + +/* Helper symbol to state that the PK module has support for EC keys. This + * can either be provided through the legacy ECP solution or through the + * PSA friendly MBEDTLS_PK_USE_PSA_EC_DATA (see pk.h for its description). */ +#if defined(MBEDTLS_ECP_C) || \ + (defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) +#define MBEDTLS_PK_HAVE_ECC_KEYS +#endif /* MBEDTLS_PK_USE_PSA_EC_DATA || MBEDTLS_ECP_C */ + +/* Historically pkparse did not check the CBC padding when decrypting + * a key. This was a bug, which is now fixed. As a consequence, pkparse + * now needs PKCS7 padding support, but existing configurations might not + * enable it, so we enable it here. */ +#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_PKCS5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#endif + +#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_from_psa.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_from_psa.h new file mode 100644 index 0000000..ab18d98 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_legacy_from_psa.h @@ -0,0 +1,877 @@ +/** + * \file mbedtls/config_adjust_legacy_from_psa.h + * \brief Adjust PSA configuration: activate legacy implementations + * + * When MBEDTLS_PSA_CRYPTO_CONFIG is enabled, activate legacy implementations + * of cryptographic mechanisms as needed to fulfill the needs of the PSA + * configuration. Generally speaking, we activate a legacy mechanism if + * it's needed for a requested PSA mechanism and there is no PSA driver + * for it. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H +#define MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H + +/* Define appropriate ACCEL macros for the p256-m driver. + * In the future, those should be generated from the drivers JSON description. + */ +#if defined(MBEDTLS_PSA_P256M_DRIVER_ENABLED) +#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256 +#define MBEDTLS_PSA_ACCEL_ALG_ECDSA +#define MBEDTLS_PSA_ACCEL_ALG_ECDH +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT +#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE +#endif + +/* + * ECC: support for a feature is controlled by a triplet or a pair: + * (curve, key_type public/basic, alg) or (curve, key_type_). + * + * A triplet/pair is accelerated if all of is components are accelerated; + * otherwise each component needs to be built in. + * + * We proceed in two passes: + * 1. Check if acceleration is complete for curves, key types, algs. + * 2. Then enable built-ins for each thing that's either not accelerated of + * doesn't have complete acceleration of the other triplet/pair components. + * + * Note: this needs psa/crypto_adjust_keypair_types.h to have been included + * already, so that we know the full set of key types that are requested. + */ + +/* ECC: curves: is acceleration complete? */ +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_MONTGOMERY_255) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#endif + +#if defined(PSA_WANT_ECC_MONTGOMERY_448) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_R1_192) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_R1_224) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_R1_256) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_R1_384) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_R1_521) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_K1_192) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_K1_224) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +#if defined(PSA_WANT_ECC_SECP_K1_256) && \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES +#endif + +/* ECC: algs: is acceleration complete? */ +#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS +#endif + +#if defined(PSA_WANT_ALG_ECDH) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS +#endif + +#if defined(PSA_WANT_ALG_ECDSA) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS +#endif + +#if defined(PSA_WANT_ALG_JPAKE) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS +#endif + +/* ECC: key types: is acceleration complete? */ +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC +#endif + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC +#endif + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#endif + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#endif + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#endif + +/* Special case: we don't support cooked key derivation in drivers yet */ +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) +#undef MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE +#endif + +/* Note: the condition is always true as DERIVE can't be accelerated yet */ +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) && \ + !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) +#define MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES +#endif + +/* ECC: curves: enable built-ins as needed. + * + * We need the curve built-in: + * - if it's not accelerated, or + * - if there's a key type with missing acceleration, or + * - if there's a alg with missing acceleration. + */ +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_256) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1 +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */ + +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_384) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1 +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */ + +#if defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_BRAINPOOL_P_R1_512) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1 +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */ + +#if defined(PSA_WANT_ECC_MONTGOMERY_255) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1 +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_MONTGOMERY_255 */ + +#if defined(PSA_WANT_ECC_MONTGOMERY_448) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1 +#define MBEDTLS_ECP_DP_CURVE448_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_MONTGOMERY_448 */ + +#if defined(PSA_WANT_ECC_SECP_R1_192) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1 +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_R1_192 */ + +#if defined(PSA_WANT_ECC_SECP_R1_224) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1 +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_R1_224 */ + +#if defined(PSA_WANT_ECC_SECP_R1_256) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1 +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_R1_256 */ + +#if defined(PSA_WANT_ECC_SECP_R1_384) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1 +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_R1_384 */ + +#if defined(PSA_WANT_ECC_SECP_R1_521) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1 +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_R1_521 */ + +#if defined(PSA_WANT_ECC_SECP_K1_192) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_192) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1 +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_K1_192 */ + +#if defined(PSA_WANT_ECC_SECP_K1_224) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_224) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1 +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +/* https://github.com/Mbed-TLS/mbedtls/issues/3541 */ +#error "SECP224K1 is buggy via the PSA API in Mbed TLS." +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_K1_224 */ + +#if defined(PSA_WANT_ECC_SECP_K1_256) +#if !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1 +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#endif /* missing accel */ +#endif /* PSA_WANT_ECC_SECP_K1_256 */ + +/* ECC: algs: enable built-ins as needed. + * + * We need the alg built-in: + * - if it's not accelerated, or + * - if there's a relevant curve (see below) with missing acceleration, or + * - if there's a key type among (public, basic) with missing acceleration. + * + * Relevant curves are: + * - all curves for ECDH + * - Weierstrass curves for (deterministic) ECDSA + * - secp256r1 for EC J-PAKE + */ +#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) +#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_MD_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#endif /* missing accel */ +#endif /* PSA_WANT_ALG_DETERMINISTIC_ECDSA */ + +#if defined(PSA_WANT_ALG_ECDH) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_ALG_ECDH */ + +#if defined(PSA_WANT_ALG_ECDSA) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_WEIERSTRASS_CURVES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#endif /* missing accel */ +#endif /* PSA_WANT_ALG_ECDSA */ + +#if defined(PSA_WANT_ALG_JPAKE) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_JPAKE) || \ + !defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_KEY_TYPES_BASIC) +#define MBEDTLS_PSA_BUILTIN_PAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ECJPAKE_C +#endif /* missing accel */ +#endif /* PSA_WANT_ALG_JPAKE */ + +/* ECC: key types: enable built-ins as needed. + * + * We need the key type built-in: + * - if it's not accelerated, or + * - if there's a curve with missing acceleration, or + * - only for public/basic: if there's an alg with missing acceleration. + */ +#if defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define MBEDTLS_ECP_LIGHT +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_BASIC) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_ALGS) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 +#define MBEDTLS_ECP_LIGHT +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_IMPORT) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 +#define MBEDTLS_ECP_LIGHT +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_EXPORT) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT */ + +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_GENERATE) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 +#define MBEDTLS_ECP_C +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE */ + +/* Note: the condition is always true as DERIVE can't be accelerated yet */ +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE) || \ + defined(MBEDTLS_PSA_ECC_ACCEL_INCOMPLETE_CURVES) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 +#define MBEDTLS_ECP_LIGHT +#define MBEDTLS_BIGNUM_C +#endif /* missing accel */ +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR_DERIVE */ + +/* End of ECC section */ + +#if defined(PSA_WANT_ALG_FFDH) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_FFDH) +#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1 +#define MBEDTLS_BIGNUM_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_FFDH */ +#endif /* PSA_WANT_ALG_FFDH */ + +#if defined(PSA_WANT_ALG_HKDF) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF) +/* + * The PSA implementation has its own implementation of HKDF, separate from + * hkdf.c. No need to enable MBEDTLS_HKDF_C here. + */ +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF */ +#endif /* PSA_WANT_ALG_HKDF */ + +#if defined(PSA_WANT_ALG_HKDF_EXTRACT) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT) +/* + * The PSA implementation has its own implementation of HKDF, separate from + * hkdf.c. No need to enable MBEDTLS_HKDF_C here. + */ +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXTRACT */ +#endif /* PSA_WANT_ALG_HKDF_EXTRACT */ + +#if defined(PSA_WANT_ALG_HKDF_EXPAND) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND) +/* + * The PSA implementation has its own implementation of HKDF, separate from + * hkdf.c. No need to enable MBEDTLS_HKDF_C here. + */ +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HKDF_EXPAND */ +#endif /* PSA_WANT_ALG_HKDF_EXPAND */ + +#if defined(PSA_WANT_ALG_HMAC) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */ +#endif /* PSA_WANT_ALG_HMAC */ + +#if defined(PSA_WANT_ALG_MD5) && !defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 +#define MBEDTLS_MD5_C +#endif + +#if defined(PSA_WANT_ALG_RIPEMD160) && !defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 +#define MBEDTLS_RIPEMD160_C +#endif + +#if defined(PSA_WANT_ALG_RSA_OAEP) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V21 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_OAEP */ +#endif /* PSA_WANT_ALG_RSA_OAEP */ + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V15 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_CRYPT */ +#endif /* PSA_WANT_ALG_RSA_PKCS1V15_CRYPT */ + +#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V15 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN */ +#endif /* PSA_WANT_ALG_RSA_PKCS1V15_SIGN */ + +#if defined(PSA_WANT_ALG_RSA_PSS) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_RSA_PSS) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PKCS1_V21 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_RSA_PSS */ +#endif /* PSA_WANT_ALG_RSA_PSS */ + +#if defined(PSA_WANT_ALG_SHA_1) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 +#define MBEDTLS_SHA1_C +#endif + +#if defined(PSA_WANT_ALG_SHA_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 +#define MBEDTLS_SHA224_C +#endif + +#if defined(PSA_WANT_ALG_SHA_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 +#define MBEDTLS_SHA256_C +#endif + +#if defined(PSA_WANT_ALG_SHA_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 +#define MBEDTLS_SHA384_C +#endif + +#if defined(PSA_WANT_ALG_SHA_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 +#define MBEDTLS_SHA512_C +#endif + +#if defined(PSA_WANT_ALG_SHA3_224) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1 +#define MBEDTLS_SHA3_C +#endif + +#if defined(PSA_WANT_ALG_SHA3_256) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1 +#define MBEDTLS_SHA3_C +#endif + +#if defined(PSA_WANT_ALG_SHA3_384) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1 +#define MBEDTLS_SHA3_C +#endif + +#if defined(PSA_WANT_ALG_SHA3_512) && !defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1 +#define MBEDTLS_SHA3_C +#endif + +#if defined(PSA_WANT_ALG_PBKDF2_HMAC) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_HMAC) +#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC 1 +#define PSA_HAVE_SOFT_PBKDF2_HMAC 1 +#if !defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_HMAC */ +#endif /* !MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_HMAC */ +#endif /* PSA_WANT_ALG_PBKDF2_HMAC */ + +#if defined(PSA_WANT_ALG_TLS12_PRF) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PRF */ +#endif /* PSA_WANT_ALG_TLS12_PRF */ + +#if defined(PSA_WANT_ALG_TLS12_PSK_TO_MS) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_PSK_TO_MS */ +#endif /* PSA_WANT_ALG_TLS12_PSK_TO_MS */ + +#if defined(PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_TLS12_ECJPAKE_TO_PMS */ +#endif /* PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_IMPORT */ +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_EXPORT */ +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 +#define MBEDTLS_GENPRIME +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_BASIC */ +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC */ + +#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_IMPORT */ +#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT */ + +#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_EXPORT */ +#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT */ + +#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_GENERATE */ +#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE */ + +#if defined(PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_KEY_PAIR_BASIC */ +#endif /* PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC */ + +#if defined(PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1 +#define MBEDTLS_BIGNUM_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DH_PUBLIC_KEY */ +#endif /* PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY */ + +#if defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 +#define MBEDTLS_RSA_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_OID_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PK_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */ +#endif /* PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY */ + +/* If any of the block modes are requested that don't have an + * associated HW assist, define PSA_HAVE_SOFT_BLOCK_MODE for checking + * in the block cipher key types. */ +#if (defined(PSA_WANT_ALG_CTR) && !defined(MBEDTLS_PSA_ACCEL_ALG_CTR)) || \ + (defined(PSA_WANT_ALG_CFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_CFB)) || \ + (defined(PSA_WANT_ALG_OFB) && !defined(MBEDTLS_PSA_ACCEL_ALG_OFB)) || \ + defined(PSA_WANT_ALG_ECB_NO_PADDING) || \ + (defined(PSA_WANT_ALG_CBC_NO_PADDING) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)) || \ + (defined(PSA_WANT_ALG_CBC_PKCS7) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)) || \ + (defined(PSA_WANT_ALG_CMAC) && !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC)) +#define PSA_HAVE_SOFT_BLOCK_MODE 1 +#endif + +#if (defined(PSA_WANT_ALG_GCM) && !defined(MBEDTLS_PSA_ACCEL_ALG_GCM)) || \ + (defined(PSA_WANT_ALG_CCM) && !defined(MBEDTLS_PSA_ACCEL_ALG_CCM)) +#define PSA_HAVE_SOFT_BLOCK_AEAD 1 +#endif + +#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128) +#define MBEDTLS_PSA_BUILTIN_ALG_PBKDF2_AES_CMAC_PRF_128 1 +#define PSA_HAVE_SOFT_PBKDF2_CMAC 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_PBKDF2_AES_CMAC_PRF_128 */ +#endif /* PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 */ + +#if defined(PSA_WANT_KEY_TYPE_AES) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES) +#define PSA_HAVE_SOFT_KEY_TYPE_AES 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_AES */ +#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ + defined(PSA_HAVE_SOFT_BLOCK_MODE) || \ + defined(PSA_HAVE_SOFT_BLOCK_AEAD) || \ + defined(PSA_HAVE_SOFT_PBKDF2_CMAC) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1 +#define MBEDTLS_AES_C +#endif /* PSA_HAVE_SOFT_KEY_TYPE_AES || PSA_HAVE_SOFT_BLOCK_MODE */ +#endif /* PSA_WANT_KEY_TYPE_AES */ + +#if defined(PSA_WANT_KEY_TYPE_ARIA) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA) +#define PSA_HAVE_SOFT_KEY_TYPE_ARIA 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ARIA */ +#if defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ + defined(PSA_HAVE_SOFT_BLOCK_MODE) || \ + defined(PSA_HAVE_SOFT_BLOCK_AEAD) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1 +#define MBEDTLS_ARIA_C +#endif /* PSA_HAVE_SOFT_KEY_TYPE_ARIA || PSA_HAVE_SOFT_BLOCK_MODE */ +#endif /* PSA_WANT_KEY_TYPE_ARIA */ + +#if defined(PSA_WANT_KEY_TYPE_CAMELLIA) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA) +#define PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA */ +#if defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) || \ + defined(PSA_HAVE_SOFT_BLOCK_MODE) || \ + defined(PSA_HAVE_SOFT_BLOCK_AEAD) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1 +#define MBEDTLS_CAMELLIA_C +#endif /* PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA || PSA_HAVE_SOFT_BLOCK_MODE */ +#endif /* PSA_WANT_KEY_TYPE_CAMELLIA */ + +#if defined(PSA_WANT_KEY_TYPE_DES) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES) +#define PSA_HAVE_SOFT_KEY_TYPE_DES 1 +#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_DES */ +#if defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \ + defined(PSA_HAVE_SOFT_BLOCK_MODE) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1 +#define MBEDTLS_DES_C +#endif /*PSA_HAVE_SOFT_KEY_TYPE_DES || PSA_HAVE_SOFT_BLOCK_MODE */ +#endif /* PSA_WANT_KEY_TYPE_DES */ + +#if defined(PSA_WANT_KEY_TYPE_CHACHA20) +#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1 +#define MBEDTLS_CHACHA20_C +#endif /*!MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20 */ +#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */ + +/* If any of the software block ciphers are selected, define + * PSA_HAVE_SOFT_BLOCK_CIPHER, which can be used in any of these + * situations. */ +#if defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_DES) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) +#define PSA_HAVE_SOFT_BLOCK_CIPHER 1 +#endif + +#if defined(PSA_WANT_ALG_STREAM_CIPHER) +#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1 +#endif /* PSA_WANT_ALG_STREAM_CIPHER */ + +#if defined(PSA_WANT_ALG_CBC_MAC) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_MAC) +#error "CBC-MAC is not yet supported via the PSA API in Mbed TLS." +#define MBEDTLS_PSA_BUILTIN_ALG_CBC_MAC 1 +#endif /* !MBEDTLS_PSA_ACCEL_ALG_CBC_MAC */ +#endif /* PSA_WANT_ALG_CBC_MAC */ + +#if defined(PSA_WANT_ALG_CMAC) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) || \ + defined(PSA_HAVE_SOFT_PBKDF2_CMAC) +#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1 +#define MBEDTLS_CMAC_C +#endif /* !MBEDTLS_PSA_ACCEL_ALG_CMAC */ +#endif /* PSA_WANT_ALG_CMAC */ + +#if defined(PSA_HAVE_SOFT_PBKDF2_HMAC) || \ + defined(PSA_HAVE_SOFT_PBKDF2_CMAC) +#define PSA_HAVE_SOFT_PBKDF2 1 +#endif /* PSA_HAVE_SOFT_PBKDF2_HMAC || PSA_HAVE_SOFT_PBKDF2_CMAC */ + +#if defined(PSA_WANT_ALG_CTR) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CTR) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) +#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1 +#define MBEDTLS_CIPHER_MODE_CTR +#endif +#endif /* PSA_WANT_ALG_CTR */ + +#if defined(PSA_WANT_ALG_CFB) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CFB) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) +#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1 +#define MBEDTLS_CIPHER_MODE_CFB +#endif +#endif /* PSA_WANT_ALG_CFB */ + +#if defined(PSA_WANT_ALG_OFB) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_OFB) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) +#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1 +#define MBEDTLS_CIPHER_MODE_OFB +#endif +#endif /* PSA_WANT_ALG_OFB */ + +#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && \ + !defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING) +#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1 +#endif + +#if defined(PSA_WANT_ALG_CBC_NO_PADDING) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1 +#endif +#endif /* PSA_WANT_ALG_CBC_NO_PADDING */ + +#if defined(PSA_WANT_ALG_CBC_PKCS7) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) || \ + defined(PSA_HAVE_SOFT_BLOCK_CIPHER) +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1 +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#endif +#endif /* PSA_WANT_ALG_CBC_PKCS7 */ + +#if defined(PSA_WANT_ALG_CCM) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CCM) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) +#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1 +#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1 +#define MBEDTLS_CCM_C +#endif +#endif /* PSA_WANT_ALG_CCM */ + +#if defined(PSA_WANT_ALG_GCM) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_GCM) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_AES) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_ARIA) || \ + defined(PSA_HAVE_SOFT_KEY_TYPE_CAMELLIA) +#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1 +#define MBEDTLS_GCM_C +#endif +#endif /* PSA_WANT_ALG_GCM */ + +#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) +#if !defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305) +#if defined(PSA_WANT_KEY_TYPE_CHACHA20) +#define MBEDTLS_CHACHAPOLY_C +#define MBEDTLS_CHACHA20_C +#define MBEDTLS_POLY1305_C +#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1 +#endif /* PSA_WANT_KEY_TYPE_CHACHA20 */ +#endif /* !MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305 */ +#endif /* PSA_WANT_ALG_CHACHA20_POLY1305 */ + +#endif /* MBEDTLS_CONFIG_ADJUST_LEGACY_FROM_PSA_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_from_legacy.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_from_legacy.h new file mode 100644 index 0000000..c31a462 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_from_legacy.h @@ -0,0 +1,334 @@ +/** + * \file mbedtls/config_adjust_psa_from_legacy.h + * \brief Adjust PSA configuration: construct PSA configuration from legacy + * + * When MBEDTLS_PSA_CRYPTO_CONFIG is disabled, we automatically enable + * cryptographic mechanisms through the PSA interface when the corresponding + * legacy mechanism is enabled. In many cases, this just enables the PSA + * wrapper code around the legacy implementation, but we also do this for + * some mechanisms where PSA has its own independent implementation so + * that high-level modules that can use either cryptographic API have the + * same feature set in both cases. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H +#define MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H + +/* + * Ensure PSA_WANT_* defines are setup properly if MBEDTLS_PSA_CRYPTO_CONFIG + * is not defined + */ + +#if defined(MBEDTLS_CCM_C) +#define MBEDTLS_PSA_BUILTIN_ALG_CCM 1 +#define MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG 1 +#define PSA_WANT_ALG_CCM 1 +#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1 +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_CMAC_C) +#define MBEDTLS_PSA_BUILTIN_ALG_CMAC 1 +#define PSA_WANT_ALG_CMAC 1 +#endif /* MBEDTLS_CMAC_C */ + +#if defined(MBEDTLS_ECDH_C) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDH 1 +#define PSA_WANT_ALG_ECDH 1 +#endif /* MBEDTLS_ECDH_C */ + +#if defined(MBEDTLS_ECDSA_C) +#define MBEDTLS_PSA_BUILTIN_ALG_ECDSA 1 +#define PSA_WANT_ALG_ECDSA 1 +#define PSA_WANT_ALG_ECDSA_ANY 1 + +// Only add in DETERMINISTIC support if ECDSA is also enabled +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#define MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA 1 +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#endif /* MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_ECP_C) +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 +/* Normally we wouldn't enable this because it's not implemented in ecp.c, + * but since it used to be available any time ECP_C was enabled, let's enable + * it anyway for the sake of backwards compatibility */ +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_BASIC 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1 +/* See comment for PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE above. */ +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_DHM_C) +#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC 1 +#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 +#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 +#define PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 +#define PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY 1 +#define PSA_WANT_ALG_FFDH 1 +#define PSA_WANT_DH_FAMILY_RFC7919 1 +#define MBEDTLS_PSA_BUILTIN_ALG_FFDH 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_BASIC 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_IMPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_EXPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_KEY_PAIR_GENERATE 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DH_PUBLIC_KEY 1 +#endif /* MBEDTLS_DHM_C */ + +#if defined(MBEDTLS_GCM_C) +#define MBEDTLS_PSA_BUILTIN_ALG_GCM 1 +#define PSA_WANT_ALG_GCM 1 +#endif /* MBEDTLS_GCM_C */ + +/* Enable PSA HKDF algorithm if mbedtls HKDF is supported. + * PSA HKDF EXTRACT and PSA HKDF EXPAND have minimal cost when + * PSA HKDF is enabled, so enable both algorithms together + * with PSA HKDF. */ +#if defined(MBEDTLS_HKDF_C) +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define PSA_WANT_ALG_HMAC 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF 1 +#define PSA_WANT_ALG_HKDF 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXTRACT 1 +#define PSA_WANT_ALG_HKDF_EXTRACT 1 +#define MBEDTLS_PSA_BUILTIN_ALG_HKDF_EXPAND 1 +#define PSA_WANT_ALG_HKDF_EXPAND 1 +#endif /* MBEDTLS_HKDF_C */ + +#define MBEDTLS_PSA_BUILTIN_ALG_HMAC 1 +#define PSA_WANT_ALG_HMAC 1 +#define PSA_WANT_KEY_TYPE_HMAC 1 + +#if defined(MBEDTLS_MD_C) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF 1 +#define PSA_WANT_ALG_TLS12_PRF 1 +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS 1 +#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_MD5_C) +#define MBEDTLS_PSA_BUILTIN_ALG_MD5 1 +#define PSA_WANT_ALG_MD5 1 +#endif + +#if defined(MBEDTLS_ECJPAKE_C) +#define MBEDTLS_PSA_BUILTIN_PAKE 1 +#define MBEDTLS_PSA_BUILTIN_ALG_JPAKE 1 +#define PSA_WANT_ALG_JPAKE 1 +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#define MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160 1 +#define PSA_WANT_ALG_RIPEMD160 1 +#endif + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_PKCS1_V15) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_SIGN 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW 1 +#endif /* MBEDTLS_PKCS1_V15 */ +#if defined(MBEDTLS_PKCS1_V21) +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP 1 +#define PSA_WANT_ALG_RSA_OAEP 1 +#define MBEDTLS_PSA_BUILTIN_ALG_RSA_PSS 1 +#define PSA_WANT_ALG_RSA_PSS 1 +#endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_GENPRIME) +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE 1 +#endif /* MBEDTLS_GENPRIME */ +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_SHA1_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_1 1 +#define PSA_WANT_ALG_SHA_1 1 +#endif + +#if defined(MBEDTLS_SHA224_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_224 1 +#define PSA_WANT_ALG_SHA_224 1 +#endif + +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_256 1 +#define PSA_WANT_ALG_SHA_256 1 +#endif + +#if defined(MBEDTLS_SHA384_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_384 1 +#define PSA_WANT_ALG_SHA_384 1 +#endif + +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA_512 1 +#define PSA_WANT_ALG_SHA_512 1 +#endif + +#if defined(MBEDTLS_SHA3_C) +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_224 1 +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_256 1 +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_384 1 +#define MBEDTLS_PSA_BUILTIN_ALG_SHA3_512 1 +#define PSA_WANT_ALG_SHA3_224 1 +#define PSA_WANT_ALG_SHA3_256 1 +#define PSA_WANT_ALG_SHA3_384 1 +#define PSA_WANT_ALG_SHA3_512 1 +#endif + +#if defined(MBEDTLS_AES_C) +#define PSA_WANT_KEY_TYPE_AES 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES 1 +#endif + +#if defined(MBEDTLS_ARIA_C) +#define PSA_WANT_KEY_TYPE_ARIA 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA 1 +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#define PSA_WANT_KEY_TYPE_CAMELLIA 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA 1 +#endif + +#if defined(MBEDTLS_DES_C) +#define PSA_WANT_KEY_TYPE_DES 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES 1 +#endif + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) +#define MBEDTLS_PSA_BUILTIN_ALG_TLS12_ECJPAKE_TO_PMS 1 +#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1 +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#define PSA_WANT_KEY_TYPE_CHACHA20 1 +#define PSA_WANT_ALG_STREAM_CIPHER 1 +#define MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20 1 +#define MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER 1 +#if defined(MBEDTLS_CHACHAPOLY_C) +#define PSA_WANT_ALG_CHACHA20_POLY1305 1 +#define MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 1 +#endif +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING 1 +#define PSA_WANT_ALG_CBC_NO_PADDING 1 +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +#define MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 1 +#define PSA_WANT_ALG_CBC_PKCS7 1 +#endif +#endif + +#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) || \ + defined(MBEDTLS_ARIA_C) || defined(MBEDTLS_CAMELLIA_C) +#define MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING 1 +#define PSA_WANT_ALG_ECB_NO_PADDING 1 +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +#define MBEDTLS_PSA_BUILTIN_ALG_CFB 1 +#define PSA_WANT_ALG_CFB 1 +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +#define MBEDTLS_PSA_BUILTIN_ALG_CTR 1 +#define PSA_WANT_ALG_CTR 1 +#endif + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +#define MBEDTLS_PSA_BUILTIN_ALG_OFB 1 +#define PSA_WANT_ALG_OFB 1 +#endif + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_256 1 +#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 +#endif + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_384 1 +#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 +#endif + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_BRAINPOOL_P_R1_512 1 +#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_255 1 +#define PSA_WANT_ECC_MONTGOMERY_255 1 +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_MONTGOMERY_448 1 +#define PSA_WANT_ECC_MONTGOMERY_448 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_192 1 +#define PSA_WANT_ECC_SECP_R1_192 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_224 1 +#define PSA_WANT_ECC_SECP_R1_224 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_256 1 +#define PSA_WANT_ECC_SECP_R1_256 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_384 1 +#define PSA_WANT_ECC_SECP_R1_384 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_R1_521 1 +#define PSA_WANT_ECC_SECP_R1_521 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_192 1 +#define PSA_WANT_ECC_SECP_K1_192 1 +#endif + +/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */ +#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_224 1 +#define PSA_WANT_ECC_SECP_K1_224 1 +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define MBEDTLS_PSA_BUILTIN_ECC_SECP_K1_256 1 +#define PSA_WANT_ECC_SECP_K1_256 1 +#endif + +#endif /* MBEDTLS_CONFIG_ADJUST_PSA_FROM_LEGACY_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_superset_legacy.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_superset_legacy.h new file mode 100644 index 0000000..3a55c3f --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_psa_superset_legacy.h @@ -0,0 +1,142 @@ +/** + * \file mbedtls/config_adjust_psa_superset_legacy.h + * \brief Adjust PSA configuration: automatic enablement from legacy + * + * To simplify some edge cases, we automatically enable certain cryptographic + * mechanisms in the PSA API if they are enabled in the legacy API. The general + * idea is that if legacy module M uses mechanism A internally, and A has + * both a legacy and a PSA implementation, we enable A through PSA whenever + * it's enabled through legacy. This facilitates the transition to PSA + * implementations of A for users of M. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H +#define MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H + +/****************************************************************/ +/* Hashes that are built in are also enabled in PSA. + * This simplifies dependency declarations especially + * for modules that obey MBEDTLS_USE_PSA_CRYPTO. */ +/****************************************************************/ + +#if defined(MBEDTLS_MD5_C) +#define PSA_WANT_ALG_MD5 1 +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#define PSA_WANT_ALG_RIPEMD160 1 +#endif + +#if defined(MBEDTLS_SHA1_C) +#define PSA_WANT_ALG_SHA_1 1 +#endif + +#if defined(MBEDTLS_SHA224_C) +#define PSA_WANT_ALG_SHA_224 1 +#endif + +#if defined(MBEDTLS_SHA256_C) +#define PSA_WANT_ALG_SHA_256 1 +#endif + +#if defined(MBEDTLS_SHA384_C) +#define PSA_WANT_ALG_SHA_384 1 +#endif + +#if defined(MBEDTLS_SHA512_C) +#define PSA_WANT_ALG_SHA_512 1 +#endif + +#if defined(MBEDTLS_SHA3_C) +#define PSA_WANT_ALG_SHA3_224 1 +#define PSA_WANT_ALG_SHA3_256 1 +#define PSA_WANT_ALG_SHA3_384 1 +#define PSA_WANT_ALG_SHA3_512 1 +#endif + +/* Ensure that the PSA's supported curves (PSA_WANT_ECC_xxx) are always a + * superset of the builtin ones (MBEDTLS_ECP_DP_xxx). */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_256) +#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_256 */ +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_384) +#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_384 */ +#endif /*MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +#if !defined(PSA_WANT_ECC_BRAINPOOL_P_R1_512) +#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 +#endif /* PSA_WANT_ECC_BRAINPOOL_P_R1_512 */ +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#if !defined(PSA_WANT_ECC_MONTGOMERY_255) +#define PSA_WANT_ECC_MONTGOMERY_255 1 +#endif /* PSA_WANT_ECC_MONTGOMERY_255 */ +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#if !defined(PSA_WANT_ECC_MONTGOMERY_448) +#define PSA_WANT_ECC_MONTGOMERY_448 1 +#endif /* PSA_WANT_ECC_MONTGOMERY_448 */ +#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_R1_192) +#define PSA_WANT_ECC_SECP_R1_192 1 +#endif /* PSA_WANT_ECC_SECP_R1_192 */ +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_R1_224) +#define PSA_WANT_ECC_SECP_R1_224 1 +#endif /* PSA_WANT_ECC_SECP_R1_224 */ +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_R1_256) +#define PSA_WANT_ECC_SECP_R1_256 1 +#endif /* PSA_WANT_ECC_SECP_R1_256 */ +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_R1_384) +#define PSA_WANT_ECC_SECP_R1_384 1 +#endif /* PSA_WANT_ECC_SECP_R1_384 */ +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_R1_521) +#define PSA_WANT_ECC_SECP_R1_521 1 +#endif /* PSA_WANT_ECC_SECP_R1_521 */ +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_K1_192) +#define PSA_WANT_ECC_SECP_K1_192 1 +#endif /* PSA_WANT_ECC_SECP_K1_192 */ +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +/* SECP224K1 is buggy via the PSA API (https://github.com/Mbed-TLS/mbedtls/issues/3541) */ +#if 0 && defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_K1_224) +#define PSA_WANT_ECC_SECP_K1_224 1 +#endif /* PSA_WANT_ECC_SECP_K1_224 */ +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#if !defined(PSA_WANT_ECC_SECP_K1_256) +#define PSA_WANT_ECC_SECP_K1_256 1 +#endif /* PSA_WANT_ECC_SECP_K1_256 */ +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#endif /* MBEDTLS_CONFIG_ADJUST_PSA_SUPERSET_LEGACY_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_ssl.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_ssl.h new file mode 100644 index 0000000..8415f3e --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_ssl.h @@ -0,0 +1,76 @@ +/** + * \file mbedtls/config_adjust_ssl.h + * \brief Adjust TLS configuration + * + * Automatically enable certain dependencies. Generally, MBEDLTS_xxx + * configurations need to be explicitly enabled by the user: enabling + * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a + * compilation error. However, we do automatically enable certain options + * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option + * used to identify parts of a module that are used by other module, and we + * don't want to make the symbol MBEDTLS_xxx_B part of the public API. + * Another case is if A didn't depend on B in earlier versions, and we + * want to use B in A but we need to preserve backward compatibility with + * configurations that explicitly activate MBEDTLS_xxx_A but not + * MBEDTLS_xxx_B. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_SSL_H +#define MBEDTLS_CONFIG_ADJUST_SSL_H + +/* The following blocks make it easier to disable all of TLS, + * or of TLS 1.2 or 1.3 or DTLS, without having to manually disable all + * key exchanges, options and extensions related to them. */ + +#if !defined(MBEDTLS_SSL_TLS_C) +#undef MBEDTLS_SSL_CLI_C +#undef MBEDTLS_SSL_SRV_C +#undef MBEDTLS_SSL_PROTO_TLS1_3 +#undef MBEDTLS_SSL_PROTO_TLS1_2 +#undef MBEDTLS_SSL_PROTO_DTLS +#endif + +#if !defined(MBEDTLS_SSL_PROTO_DTLS) +#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY +#undef MBEDTLS_SSL_DTLS_CONNECTION_ID +#undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT +#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY +#undef MBEDTLS_SSL_DTLS_SRTP +#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE +#endif + +#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#undef MBEDTLS_SSL_ENCRYPT_THEN_MAC +#undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET +#undef MBEDTLS_SSL_RENEGOTIATION +#undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED +#undef MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#endif + +#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) +#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED +#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED +#undef MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED +#undef MBEDTLS_SSL_EARLY_DATA +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + (defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)) +#define MBEDTLS_SSL_TLS1_2_SOME_ECC +#endif + +#endif /* MBEDTLS_CONFIG_ADJUST_SSL_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/config_adjust_x509.h b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_x509.h new file mode 100644 index 0000000..346c8ae --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/config_adjust_x509.h @@ -0,0 +1,25 @@ +/** + * \file mbedtls/config_adjust_x509.h + * \brief Adjust X.509 configuration + * + * Automatically enable certain dependencies. Generally, MBEDLTS_xxx + * configurations need to be explicitly enabled by the user: enabling + * MBEDTLS_xxx_A but not MBEDTLS_xxx_B when A requires B results in a + * compilation error. However, we do automatically enable certain options + * in some circumstances. One case is if MBEDTLS_xxx_B is an internal option + * used to identify parts of a module that are used by other module, and we + * don't want to make the symbol MBEDTLS_xxx_B part of the public API. + * Another case is if A didn't depend on B in earlier versions, and we + * want to use B in A but we need to preserve backward compatibility with + * configurations that explicitly activate MBEDTLS_xxx_A but not + * MBEDTLS_xxx_B. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONFIG_ADJUST_X509_H +#define MBEDTLS_CONFIG_ADJUST_X509_H + +#endif /* MBEDTLS_CONFIG_ADJUST_X509_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/constant_time.h b/src/app/findmy/crypto/third-party/mbedtls/constant_time.h new file mode 100644 index 0000000..d31bff6 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/constant_time.h @@ -0,0 +1,36 @@ +/** + * Constant-time functions + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONSTANT_TIME_H +#define MBEDTLS_CONSTANT_TIME_H + +#include + +/** Constant-time buffer comparison without branches. + * + * This is equivalent to the standard memcmp function, but is likely to be + * compiled to code using bitwise operations rather than a branch, such that + * the time taken is constant w.r.t. the data pointed to by \p a and \p b, + * and w.r.t. whether \p a and \p b are equal or not. It is not constant-time + * w.r.t. \p n . + * + * This function can be used to write constant-time code by replacing branches + * with bit operations using masks. + * + * \param a Pointer to the first buffer, containing at least \p n bytes. May not be NULL. + * \param b Pointer to the second buffer, containing at least \p n bytes. May not be NULL. + * \param n The number of bytes to compare. + * + * \return Zero if the contents of the two buffers are the same, + * otherwise non-zero. + */ +int mbedtls_ct_memcmp(const void *a, + const void *b, + size_t n); + +#endif /* MBEDTLS_CONSTANT_TIME_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/debug.h b/src/app/findmy/crypto/third-party/mbedtls/debug.h new file mode 100644 index 0000000..0aef2ed --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/debug.h @@ -0,0 +1,308 @@ +/** + * \file debug.h + * + * \brief Functions for controlling and providing debug output from the library. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_DEBUG_H +#define MBEDTLS_DEBUG_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/ssl.h" + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_DEBUG_C) + +#define MBEDTLS_DEBUG_STRIP_PARENS(...) __VA_ARGS__ + +#define MBEDTLS_SSL_DEBUG_MSG(level, args) \ + mbedtls_debug_print_msg(ssl, level, __FILE__, __LINE__, \ + MBEDTLS_DEBUG_STRIP_PARENS args) + +#define MBEDTLS_SSL_DEBUG_RET(level, text, ret) \ + mbedtls_debug_print_ret(ssl, level, __FILE__, __LINE__, text, ret) + +#define MBEDTLS_SSL_DEBUG_BUF(level, text, buf, len) \ + mbedtls_debug_print_buf(ssl, level, __FILE__, __LINE__, text, buf, len) + +#if defined(MBEDTLS_BIGNUM_C) +#define MBEDTLS_SSL_DEBUG_MPI(level, text, X) \ + mbedtls_debug_print_mpi(ssl, level, __FILE__, __LINE__, text, X) +#endif + +#if defined(MBEDTLS_ECP_C) +#define MBEDTLS_SSL_DEBUG_ECP(level, text, X) \ + mbedtls_debug_print_ecp(ssl, level, __FILE__, __LINE__, text, X) +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#if !defined(MBEDTLS_X509_REMOVE_INFO) +#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) \ + mbedtls_debug_print_crt(ssl, level, __FILE__, __LINE__, text, crt) +#else +#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) do { } while (0) +#endif /* MBEDTLS_X509_REMOVE_INFO */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_ECDH_C) +#define MBEDTLS_SSL_DEBUG_ECDH(level, ecdh, attr) \ + mbedtls_debug_printf_ecdh(ssl, level, __FILE__, __LINE__, ecdh, attr) +#endif + +#else /* MBEDTLS_DEBUG_C */ + +#define MBEDTLS_SSL_DEBUG_MSG(level, args) do { } while (0) +#define MBEDTLS_SSL_DEBUG_RET(level, text, ret) do { } while (0) +#define MBEDTLS_SSL_DEBUG_BUF(level, text, buf, len) do { } while (0) +#define MBEDTLS_SSL_DEBUG_MPI(level, text, X) do { } while (0) +#define MBEDTLS_SSL_DEBUG_ECP(level, text, X) do { } while (0) +#define MBEDTLS_SSL_DEBUG_CRT(level, text, crt) do { } while (0) +#define MBEDTLS_SSL_DEBUG_ECDH(level, ecdh, attr) do { } while (0) + +#endif /* MBEDTLS_DEBUG_C */ + +/** + * \def MBEDTLS_PRINTF_ATTRIBUTE + * + * Mark a function as having printf attributes, and thus enable checking + * via -wFormat and other flags. This does nothing on builds with compilers + * that do not support the format attribute + * + * Module: library/debug.c + * Caller: + * + * This module provides debugging functions. + */ +#if defined(__has_attribute) +#if __has_attribute(format) +#if defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1 +#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(gnu_printf, string_index, first_to_check))) +#else /* defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1 */ +#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((format(printf, string_index, first_to_check))) +#endif +#else /* __has_attribute(format) */ +#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) +#endif /* __has_attribute(format) */ +#else /* defined(__has_attribute) */ +#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) +#endif + +/** + * \def MBEDTLS_PRINTF_SIZET + * + * MBEDTLS_PRINTF_xxx: Due to issues with older window compilers + * and MinGW we need to define the printf specifier for size_t + * and long long per platform. + * + * Module: library/debug.c + * Caller: + * + * This module provides debugging functions. + */ +#if (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) + #include + #define MBEDTLS_PRINTF_SIZET PRIuPTR + #define MBEDTLS_PRINTF_LONGLONG "I64d" +#else \ + /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */ + #define MBEDTLS_PRINTF_SIZET "zu" + #define MBEDTLS_PRINTF_LONGLONG "lld" +#endif \ + /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */ + +#if !defined(MBEDTLS_PRINTF_MS_TIME) +#define MBEDTLS_PRINTF_MS_TIME PRId64 +#endif /* MBEDTLS_PRINTF_MS_TIME */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Set the threshold error level to handle globally all debug output. + * Debug messages that have a level over the threshold value are + * discarded. + * (Default value: 0 = No debug ) + * + * \param threshold threshold level of messages to filter on. Messages at a + * higher level will be discarded. + * - Debug levels + * - 0 No debug + * - 1 Error + * - 2 State change + * - 3 Informational + * - 4 Verbose + */ +void mbedtls_debug_set_threshold(int threshold); + +/** + * \brief Print a message to the debug output. This function is always used + * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl + * context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the message has occurred in + * \param line line number the message has occurred at + * \param format format specifier, in printf format + * \param ... variables used by the format specifier + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *format, ...) MBEDTLS_PRINTF_ATTRIBUTE(5, 6); + +/** + * \brief Print the return value of a function to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text the name of the function that returned the error + * \param ret the return code value + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret); + +/** + * \brief Output a buffer of size len bytes to the debug output. This function + * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the buffer being dumped. Normally the + * variable or buffer name + * \param buf the buffer to be outputted + * \param len length of the buffer + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text, + const unsigned char *buf, size_t len); + +#if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Print a MPI variable to the debug output. This function is always + * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the MPI being output. Normally the + * variable name + * \param X the MPI variable + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_mpi *X); +#endif + +#if defined(MBEDTLS_ECP_C) +/** + * \brief Print an ECP point to the debug output. This function is always + * used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the ECP point being output. Normally the + * variable name + * \param X the ECP point + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_ecp_point *X); +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && !defined(MBEDTLS_X509_REMOVE_INFO) +/** + * \brief Print a X.509 certificate structure to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the certificate being output + * \param crt X.509 certificate structure + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_x509_crt *crt); +#endif + +/* Note: the MBEDTLS_ECDH_C guard here is mandatory because this debug function + only works for the built-in implementation. */ +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED) && \ + defined(MBEDTLS_ECDH_C) +typedef enum { + MBEDTLS_DEBUG_ECDH_Q, + MBEDTLS_DEBUG_ECDH_QP, + MBEDTLS_DEBUG_ECDH_Z, +} mbedtls_debug_ecdh_attr; + +/** + * \brief Print a field of the ECDH structure in the SSL context to the debug + * output. This function is always used through the + * MBEDTLS_SSL_DEBUG_ECDH() macro, which supplies the ssl context, file + * and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param ecdh the ECDH context + * \param attr the identifier of the attribute being output + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ +void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const mbedtls_ecdh_context *ecdh, + mbedtls_debug_ecdh_attr attr); +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_ANY_ENABLED && + MBEDTLS_ECDH_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* debug.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/ecdh.h b/src/app/findmy/crypto/third-party/mbedtls/ecdh.h new file mode 100644 index 0000000..792db79 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/ecdh.h @@ -0,0 +1,441 @@ +/** + * \file ecdh.h + * + * \brief This file contains ECDH definitions and functions. + * + * The Elliptic Curve Diffie-Hellman (ECDH) protocol is an anonymous + * key agreement protocol allowing two parties to establish a shared + * secret over an insecure channel. Each party must have an + * elliptic-curve public–private key pair. + * + * For more information, see NIST SP 800-56A Rev. 2: Recommendation for + * Pair-Wise Key Establishment Schemes Using Discrete Logarithm + * Cryptography. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_ECDH_H +#define MBEDTLS_ECDH_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/ecp.h" + +/* + * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context + * defined in `ecdh.h`). For most applications, the choice of format makes + * no difference, since all library functions can work with either format, + * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE. + + * The new format used when this option is disabled is smaller + * (56 bytes on a 32-bit platform). In future versions of the library, it + * will support alternative implementations of ECDH operations. + * The new format is incompatible with applications that access + * context fields directly and with restartable ECP operations. + */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#else +#undef MBEDTLS_ECDH_LEGACY_CONTEXT +#endif + +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) +#undef MBEDTLS_ECDH_LEGACY_CONTEXT +#include "everest/everest.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Defines the source of the imported EC key. + */ +typedef enum { + MBEDTLS_ECDH_OURS, /**< Our key. */ + MBEDTLS_ECDH_THEIRS, /**< The key of the peer. */ +} mbedtls_ecdh_side; + +#if !defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +/** + * Defines the ECDH implementation used. + * + * Later versions of the library may add new variants, therefore users should + * not make any assumptions about them. + */ +typedef enum { + MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */ + MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */ +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */ +#endif +} mbedtls_ecdh_variant; + +/** + * The context used by the default ECDH implementation. + * + * Later versions might change the structure of this context, therefore users + * should not make any assumptions about the structure of + * mbedtls_ecdh_context_mbed. + */ +typedef struct mbedtls_ecdh_context_mbed { + mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ + mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ + mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ +#endif +} mbedtls_ecdh_context_mbed; +#endif + +/** + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + * \brief The ECDH context structure. + */ +typedef struct mbedtls_ecdh_context { +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< The elliptic curve used. */ + mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< The private key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< The public key. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Qp); /*!< The value of the public key of the peer. */ + mbedtls_mpi MBEDTLS_PRIVATE(z); /*!< The shared secret. */ + int MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Vi); /*!< The blinding value. */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Vf); /*!< The unblinding value. */ + mbedtls_mpi MBEDTLS_PRIVATE(_d); /*!< The previous \p d. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + int MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. */ + mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(rs); /*!< The restart context for EC computations. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#else + uint8_t MBEDTLS_PRIVATE(point_format); /*!< The format of point export in TLS messages + as defined in RFC 4492. */ + mbedtls_ecp_group_id MBEDTLS_PRIVATE(grp_id);/*!< The elliptic curve used. */ + mbedtls_ecdh_variant MBEDTLS_PRIVATE(var); /*!< The ECDH implementation/structure used. */ + union { + mbedtls_ecdh_context_mbed MBEDTLS_PRIVATE(mbed_ecdh); +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + mbedtls_ecdh_context_everest MBEDTLS_PRIVATE(everest_ecdh); +#endif + } MBEDTLS_PRIVATE(ctx); /*!< Implementation-specific context. The + context in use is specified by the \c var + field. */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + uint8_t MBEDTLS_PRIVATE(restart_enabled); /*!< The flag for restartable mode. Functions of + an alternative implementation not supporting + restartable mode must return + MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED error + if this flag is set. */ +#endif /* MBEDTLS_ECP_RESTARTABLE */ +#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */ +} +mbedtls_ecdh_context; + +/** + * \brief Check whether a given group can be used for ECDH. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid); + +/** + * \brief This function generates an ECDH keypair on an elliptic + * curve. + * + * This function performs the first of two core computations + * implemented during the ECDH key exchange. The second core + * computation is performed by mbedtls_ecdh_compute_shared(). + * + * \see ecp.h + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param d The destination MPI (private key). + * This must be initialized. + * \param Q The destination point (public key). + * This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function computes the shared secret. + * + * This function performs the second of two core computations + * implemented during the ECDH key exchange. The first core + * computation is performed by mbedtls_ecdh_gen_public(). + * + * \see ecp.h + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \param grp The ECP group to use. This must be initialized and have + * domain parameters loaded, for example through + * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group(). + * \param z The destination MPI (shared secret). + * This must be initialized. + * \param Q The public key from another party. + * This must be initialized. + * \param d Our secret exponent (private key). + * This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't need a + * context argument. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX or + * \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function initializes an ECDH context. + * + * \param ctx The ECDH context to initialize. This must not be \c NULL. + */ +void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx); + +/** + * \brief This function sets up the ECDH context with the information + * given. + * + * This function should be called after mbedtls_ecdh_init() but + * before mbedtls_ecdh_make_params(). There is no need to call + * this function before mbedtls_ecdh_read_params(). + * + * This is the first function used by a TLS server for ECDHE + * ciphersuites. + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param grp_id The group id of the group to set up the context for. + * + * \return \c 0 on success. + */ +int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, + mbedtls_ecp_group_id grp_id); + +/** + * \brief This function frees a context. + * + * \param ctx The context to free. This may be \c NULL, in which + * case this function does nothing. If it is not \c NULL, + * it must point to an initialized ECDH context. + */ +void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx); + +/** + * \brief This function generates an EC key pair and exports its + * in the format used in a TLS ServerKeyExchange handshake + * message. + * + * This is the second function used by a TLS server for ECDHE + * ciphersuites. (It is called after mbedtls_ecdh_setup().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param olen The address at which to store the number of Bytes written. + * \param buf The destination buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function parses the ECDHE parameters in a + * TLS ServerKeyExchange handshake message. + * + * \note In a TLS handshake, this is the how the client + * sets up its ECDHE context from the server's public + * ECDHE key material. + * + * \see ecp.h + * + * \param ctx The ECDHE context to use. This must be initialized. + * \param buf On input, \c *buf must be the start of the input buffer. + * On output, \c *buf is updated to point to the end of the + * data that has been read. On success, this is the first byte + * past the end of the ServerKeyExchange parameters. + * On error, this is the point at which an error has been + * detected, which is usually not useful except to debug + * failures. + * \param end The end of the input buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, + const unsigned char **buf, + const unsigned char *end); + +/** + * \brief This function sets up an ECDH context from an EC key. + * + * It is used by clients and servers in place of the + * ServerKeyEchange for static ECDH, and imports ECDH + * parameters from the EC key information of a certificate. + * + * \see ecp.h + * + * \param ctx The ECDH context to set up. This must be initialized. + * \param key The EC key to use. This must be initialized. + * \param side Defines the source of the key. Possible values are: + * - #MBEDTLS_ECDH_OURS: The key is ours. + * - #MBEDTLS_ECDH_THEIRS: The key is that of the peer. + * + * \return \c 0 on success. + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + * + */ +int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side); + +/** + * \brief This function generates a public key and exports it + * as a TLS ClientKeyExchange payload. + * + * This is the second function used by a TLS client for ECDH(E) + * ciphersuites. + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, the latter usually by + * mbedtls_ecdh_read_params(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The destination buffer. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The size of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL in case \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function parses and processes the ECDHE payload of a + * TLS ClientKeyExchange message. + * + * This is the third function used by a TLS server for ECDH(E) + * ciphersuites. (It is called after mbedtls_ecdh_setup() and + * mbedtls_ecdh_make_params().) + * + * \see ecp.h + * + * \param ctx The ECDH context to use. This must be initialized + * and bound to a group, for example via mbedtls_ecdh_setup(). + * \param buf The pointer to the ClientKeyExchange payload. This must + * be a readable buffer of length \p blen Bytes. + * \param blen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen); + +/** + * \brief This function derives and exports the shared secret. + * + * This is the last function used by both TLS client + * and servers. + * + * \note If \p f_rng is not NULL, it is used to implement + * countermeasures against side-channel attacks. + * For more information, see mbedtls_ecp_mul(). + * + * \see ecp.h + + * \param ctx The ECDH context to use. This must be initialized + * and have its own private key generated and the peer's + * public key imported. + * \param olen The address at which to store the total number of + * Bytes written on success. This must not be \c NULL. + * \param buf The buffer to write the generated shared key to. This + * must be a writable buffer of size \p blen Bytes. + * \param blen The length of the destination buffer \p buf in Bytes. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context. This may be \c NULL if \p f_rng + * doesn't need a context argument. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX error code on failure. + */ +int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief This function enables restartable EC computations for this + * context. (Default: disabled.) + * + * \see \c mbedtls_ecp_set_max_ops() + * + * \note It is not possible to safely disable restartable + * computations once enabled, except by free-ing the context, + * which cancels possible in-progress operations. + * + * \param ctx The ECDH context to use. This must be initialized. + */ +void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecdh.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/ecdsa.h b/src/app/findmy/crypto/third-party/mbedtls/ecdsa.h new file mode 100644 index 0000000..2ecf349 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/ecdsa.h @@ -0,0 +1,671 @@ +/** + * \file ecdsa.h + * + * \brief This file contains ECDSA definitions and functions. + * + * The Elliptic Curve Digital Signature Algorithm (ECDSA) is defined in + * Standards for Efficient Cryptography Group (SECG): + * SEC1 Elliptic Curve Cryptography. + * The use of ECDSA for TLS is defined in RFC-4492: Elliptic Curve + * Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS). + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_ECDSA_H +#define MBEDTLS_ECDSA_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/ecp.h" +#include "mbedtls/md.h" + +/** + * \brief Maximum ECDSA signature size for a given curve bit size + * + * \param bits Curve size in bits + * \return Maximum signature size in bytes + * + * \note This macro returns a compile-time constant if its argument + * is one. It may evaluate its argument multiple times. + */ +/* + * Ecdsa-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * For each of r and s, the value (V) may include an extra initial "0" bit. + */ +#define MBEDTLS_ECDSA_MAX_SIG_LEN(bits) \ + (/*T,L of SEQUENCE*/ ((bits) >= 61 * 8 ? 3 : 2) + \ + /*T,L of r,s*/ 2 * (((bits) >= 127 * 8 ? 3 : 2) + \ + /*V of r,s*/ ((bits) + 8) / 8)) + +/** The maximal size of an ECDSA signature in Bytes. */ +#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN(MBEDTLS_ECP_MAX_BITS) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The ECDSA context structure. + * + * \warning Performing multiple operations concurrently on the same + * ECDSA context is not supported; objects of this type + * should not be shared between multiple threads. + * + * \note pk_wrap module assumes that "ecdsa_context" is identical + * to "ecp_keypair" (see for example structure + * "mbedtls_eckey_info" where ECDSA sign/verify functions + * are used also for EC key) + */ +typedef mbedtls_ecp_keypair mbedtls_ecdsa_context; + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Internal restart context for ecdsa_verify() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_ver mbedtls_ecdsa_restart_ver_ctx; + +/** + * \brief Internal restart context for ecdsa_sign() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_sig mbedtls_ecdsa_restart_sig_ctx; + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/** + * \brief Internal restart context for ecdsa_sign_det() + * + * \note Opaque struct, defined in ecdsa.c + */ +typedef struct mbedtls_ecdsa_restart_det mbedtls_ecdsa_restart_det_ctx; +#endif + +/** + * \brief General context for resuming ECDSA operations + */ +typedef struct { + mbedtls_ecp_restart_ctx MBEDTLS_PRIVATE(ecp); /*!< base context for ECP restart and + shared administrative info */ + mbedtls_ecdsa_restart_ver_ctx *MBEDTLS_PRIVATE(ver); /*!< ecdsa_verify() sub-context */ + mbedtls_ecdsa_restart_sig_ctx *MBEDTLS_PRIVATE(sig); /*!< ecdsa_sign() sub-context */ +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + mbedtls_ecdsa_restart_det_ctx *MBEDTLS_PRIVATE(det); /*!< ecdsa_sign_det() sub-context */ +#endif +} mbedtls_ecdsa_restart_ctx; + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +/* Now we can declare functions that take a pointer to that */ +typedef void mbedtls_ecdsa_restart_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief This function checks whether a given group can be used + * for ECDSA. + * + * \param gid The ECP group ID to check. + * + * \return \c 1 if the group can be used, \c 0 otherwise + */ +int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid); + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message. + * + * \note The deterministic version implemented in + * mbedtls_ecdsa_sign_det_ext() is usually preferred. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated + * as defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized. + * \param buf The content to be signed. This is usually the hash of + * the original data to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX + * or \c MBEDTLS_MPI_XXX error code on failure. + */ +int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, deterministic version. + * + * For more information, see RFC-6979: Deterministic + * Usage of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This + * may be \c NULL if \p f_rng_blind doesn't need a context + * parameter. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind); +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#if !defined(MBEDTLS_ECDSA_SIGN_ALT) +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, in a restartable way. + * + * \note The deterministic version implemented in + * mbedtls_ecdsa_sign_det_restartable() is usually + * preferred. + * + * \note This function is like \c mbedtls_ecdsa_sign() but + * it can return early and restart according to the + * limit set with \c mbedtls_ecp_set_max_ops() to + * reduce blocking. + * + * \note If the bitlength of the message hash is larger + * than the bitlength of the group order, then the + * hash is truncated as defined in Standards for + * Efficient Cryptography Group (SECG): SEC1 Elliptic + * Curve Cryptography, section 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through + * mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * \param rs_ctx The restart context to use. This may be \c NULL + * to disable restarting. If it is not \c NULL, it + * must point to an initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c + * mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c + * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_restartable( + mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, in a restartable way. + * + * \note This function is like \c + * mbedtls_ecdsa_sign_det_ext() but it can return + * early and restart according to the limit set with + * \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \note If the bitlength of the message hash is larger + * than the bitlength of the group order, then the + * hash is truncated as defined in Standards for + * Efficient Cryptography Group (SECG): SEC1 Elliptic + * Curve Cryptography, section 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through + * mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param md_alg The hash algorithm used to hash the original data. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng_blind. This may be + * \c NULL if \p f_rng_blind doesn't need a context parameter. + * \param rs_ctx The restart context to use. This may be \c NULL + * to disable restarting. If it is not \c NULL, it + * must point to an initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c + * mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c + * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det_restartable( + mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/** + * \brief This function verifies the ECDSA signature of a + * previously-hashed message. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param buf The hashed content that was signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param Q The public key to use for verification. This must be + * initialized and setup. + * \param r The first integer of the signature. + * This must be initialized. + * \param s The second integer of the signature. + * This must be initialized. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, + const mbedtls_mpi *s); + +#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) +/** + * \brief This function verifies the ECDSA signature of a + * previously-hashed message, in a restartable manner + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param buf The hashed content that was signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param Q The public key to use for verification. This must be + * initialized and setup. + * \param r The first integer of the signature. + * This must be initialized. + * \param s The second integer of the signature. + * This must be initialized. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, serialized as defined in RFC-4492: + * Elliptic Curve Cryptography (ECC) Cipher Suites for + * Transport Layer Security (TLS). + * + * \warning It is not thread-safe to use the same context in + * multiple threads. + * + * \note The deterministic version is used if + * #MBEDTLS_ECDSA_DETERMINISTIC is defined. For more + * information, see RFC-6979: Deterministic Usage + * of the Digital Signature Algorithm (DSA) and Elliptic + * Curve Digital Signature Algorithm (ECDSA). + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.3, step 5. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param sig_size The size of the \p sig buffer in bytes. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is used only for blinding and may be set to \c NULL, but + * doing so is DEPRECATED. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function computes the ECDSA signature and writes it + * to a buffer, in a restartable way. + * + * \see \c mbedtls_ecdsa_write_signature() + * + * \note This function is like \c mbedtls_ecdsa_write_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and private key bound to it, for example + * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair(). + * \param md_alg The message digest that was used to hash the message. + * \param hash The message hash to be signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The length of the hash \p hash in Bytes. + * \param sig The buffer to which to write the signature. This must be a + * writable buffer of length at least twice as large as the + * size of the curve used, plus 9. For example, 73 Bytes if + * a 256-bit curve is used. A buffer length of + * #MBEDTLS_ECDSA_MAX_LEN is always safe. + * \param sig_size The size of the \p sig buffer in bytes. + * \param slen The address at which to store the actual length of + * the signature written. Must not be \c NULL. + * \param f_rng The RNG function. This must not be \c NULL if + * #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise, + * it is unused and may be set to \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng is \c NULL or doesn't use a context. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or + * \c MBEDTLS_ERR_ASN1_XXX error code on failure. + */ +int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +/** + * \brief This function reads and verifies an ECDSA signature. + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen); + +/** + * \brief This function reads and verifies an ECDSA signature, + * in a restartable way. + * + * \see \c mbedtls_ecdsa_read_signature() + * + * \note This function is like \c mbedtls_ecdsa_read_signature() + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param ctx The ECDSA context to use. This must be initialized + * and have a group and public key bound to it. + * \param hash The message hash that was signed. This must be a readable + * buffer of length \p hlen Bytes. + * \param hlen The size of the hash \p hash. + * \param sig The signature to read and verify. This must be a readable + * buffer of length \p slen Bytes. + * \param slen The size of \p sig in Bytes. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. + * \return #MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if there is a valid + * signature in \p sig, but its length is less than \p siglen. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_ERR_MPI_XXX + * error code on failure for any other reason. + */ +int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +/** + * \brief This function generates an ECDSA keypair on the given curve. + * + * \see ecp.h + * + * \param ctx The ECDSA context to store the keypair in. + * This must be initialized. + * \param gid The elliptic curve to use. One of the various + * \c MBEDTLS_ECP_DP_XXX macros depending on configuration. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +/** + * \brief This function sets up an ECDSA context from an EC key pair. + * + * \see ecp.h + * + * \param ctx The ECDSA context to setup. This must be initialized. + * \param key The EC key to use. This must be initialized and hold + * a private-public key pair or a public key. In the former + * case, the ECDSA context may be used for signature creation + * and verification after this call. In the latter case, it + * may be used for signature verification. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX code on failure. + */ +int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, + const mbedtls_ecp_keypair *key); + +/** + * \brief This function initializes an ECDSA context. + * + * \param ctx The ECDSA context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx); + +/** + * \brief This function frees an ECDSA context. + * + * \param ctx The ECDSA context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. + * This must not be \c NULL. + */ +void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx); + +/** + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, + * in which case this function does nothing. If it + * is not \c NULL, it must be initialized. + */ +void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecdsa.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/ecp.h b/src/app/findmy/crypto/third-party/mbedtls/ecp.h new file mode 100644 index 0000000..7f5e880 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/ecp.h @@ -0,0 +1,1362 @@ +/** + * \file ecp.h + * + * \brief This file provides an API for Elliptic Curves over GF(P) (ECP). + * + * The use of ECP in cryptography and TLS is defined in + * Standards for Efficient Cryptography Group (SECG): SEC1 + * Elliptic Curve Cryptography and + * RFC-4492: Elliptic Curve Cryptography (ECC) Cipher Suites + * for Transport Layer Security (TLS). + * + * RFC-2409: The Internet Key Exchange (IKE) defines ECP + * group types. + * + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_ECP_H +#define MBEDTLS_ECP_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/bignum.h" + +/* + * ECP error codes + */ +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_ECP_BAD_INPUT_DATA -0x4F80 +/** The buffer is too small to write to. */ +#define MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 +/** The requested feature is not available, for example, the requested curve is not supported. */ +#define MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 +/** The signature is not valid. */ +#define MBEDTLS_ERR_ECP_VERIFY_FAILED -0x4E00 +/** Memory allocation failed. */ +#define MBEDTLS_ERR_ECP_ALLOC_FAILED -0x4D80 +/** Generation of random value, such as ephemeral key, failed. */ +#define MBEDTLS_ERR_ECP_RANDOM_FAILED -0x4D00 +/** Invalid private or public key. */ +#define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 +/** The buffer contains a valid signature followed by more data. */ +#define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 +/** Operation in progress, call again with the same parameters to continue. */ +#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00 + +/* Flags indicating whether to include code that is specific to certain + * types of curves. These flags are for internal library use only. */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED +#endif +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \ + defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define MBEDTLS_ECP_MONTGOMERY_ENABLED +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Domain-parameter identifiers: curve, subgroup, and generator. + * + * \note Only curves over prime fields are supported. + * + * \warning This library does not support validation of arbitrary domain + * parameters. Therefore, only standardized domain parameters from trusted + * sources should be used. See mbedtls_ecp_group_load(). + */ +/* Note: when adding a new curve: + * - Add it at the end of this enum, otherwise you'll break the ABI by + * changing the numerical value for existing curves. + * - Increment MBEDTLS_ECP_DP_MAX below if needed. + * - Update the calculation of MBEDTLS_ECP_MAX_BITS below. + * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to + * mbedtls_config.h. + * - List the curve as a dependency of MBEDTLS_ECP_C and + * MBEDTLS_ECDSA_C if supported in check_config.h. + * - Add the curve to the appropriate curve type macro + * MBEDTLS_ECP_yyy_ENABLED above. + * - Add the necessary definitions to ecp_curves.c. + * - Add the curve to the ecp_supported_curves array in ecp.c. + * - Add the curve to applicable profiles in x509_crt.c. + * - Add the curve to applicable presets in ssl_tls.c. + */ +typedef enum { + MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */ + MBEDTLS_ECP_DP_SECP192R1, /*!< Domain parameters for the 192-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP224R1, /*!< Domain parameters for the 224-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP256R1, /*!< Domain parameters for the 256-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP384R1, /*!< Domain parameters for the 384-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_SECP521R1, /*!< Domain parameters for the 521-bit curve defined by FIPS 186-4 and SEC1. */ + MBEDTLS_ECP_DP_BP256R1, /*!< Domain parameters for 256-bit Brainpool curve. */ + MBEDTLS_ECP_DP_BP384R1, /*!< Domain parameters for 384-bit Brainpool curve. */ + MBEDTLS_ECP_DP_BP512R1, /*!< Domain parameters for 512-bit Brainpool curve. */ + MBEDTLS_ECP_DP_CURVE25519, /*!< Domain parameters for Curve25519. */ + MBEDTLS_ECP_DP_SECP192K1, /*!< Domain parameters for 192-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_SECP224K1, /*!< Domain parameters for 224-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_SECP256K1, /*!< Domain parameters for 256-bit "Koblitz" curve. */ + MBEDTLS_ECP_DP_CURVE448, /*!< Domain parameters for Curve448. */ +} mbedtls_ecp_group_id; + +/** + * The number of supported curves, plus one for #MBEDTLS_ECP_DP_NONE. + */ +#define MBEDTLS_ECP_DP_MAX 14 + +/* + * Curve types + */ +typedef enum { + MBEDTLS_ECP_TYPE_NONE = 0, + MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} mbedtls_ecp_curve_type; + +/** + * Curve information, for use by other modules. + * + * The fields of this structure are part of the public API and can be + * accessed directly by applications. Future versions of the library may + * add extra fields or reorder existing fields. + */ +typedef struct mbedtls_ecp_curve_info { + mbedtls_ecp_group_id grp_id; /*!< An internal identifier. */ + uint16_t tls_id; /*!< The TLS NamedCurve identifier. */ + uint16_t bit_size; /*!< The curve size in bits. */ + const char *name; /*!< A human-friendly name. */ +} mbedtls_ecp_curve_info; + +/** + * \brief The ECP point structure, in Jacobian coordinates. + * + * \note All functions expect and return points satisfying + * the following condition: Z == 0 or + * Z == 1. Other values of \p Z are + * used only by internal functions. + * The point is zero, or "at infinity", if Z == 0. + * Otherwise, \p X and \p Y are its standard (affine) + * coordinates. + */ +typedef struct mbedtls_ecp_point { + mbedtls_mpi MBEDTLS_PRIVATE(X); /*!< The X coordinate of the ECP point. */ + mbedtls_mpi MBEDTLS_PRIVATE(Y); /*!< The Y coordinate of the ECP point. */ + mbedtls_mpi MBEDTLS_PRIVATE(Z); /*!< The Z coordinate of the ECP point. */ +} +mbedtls_ecp_point; + +#if !defined(MBEDTLS_ECP_ALT) +/* + * default Mbed TLS elliptic curve arithmetic implementation + * + * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an + * alternative implementation for the whole module and it will replace this + * one.) + */ + +/** + * \brief The ECP group structure. + * + * We consider two types of curve equations: + *
    • Short Weierstrass: y^2 = x^3 + A x + B mod P + * (SEC1 + RFC-4492)
    • + *
    • Montgomery: y^2 = x^3 + A x^2 + x mod P (Curve25519, + * Curve448)
    + * In both cases, the generator (\p G) for a prime-order subgroup is fixed. + * + * For Short Weierstrass, this subgroup is the whole curve, and its + * cardinality is denoted by \p N. Our code requires that \p N is an + * odd prime as mbedtls_ecp_mul() requires an odd number, and + * mbedtls_ecdsa_sign() requires that it is prime for blinding purposes. + * + * The default implementation only initializes \p A without setting it to the + * authentic value for curves with A = -3(SECP256R1, etc), in which + * case you need to load \p A by yourself when using domain parameters directly, + * for example: + * \code + * mbedtls_mpi_init(&A); + * mbedtls_ecp_group_init(&grp); + * CHECK_RETURN(mbedtls_ecp_group_load(&grp, grp_id)); + * if (mbedtls_ecp_group_a_is_minus_3(&grp)) { + * CHECK_RETURN(mbedtls_mpi_sub_int(&A, &grp.P, 3)); + * } else { + * CHECK_RETURN(mbedtls_mpi_copy(&A, &grp.A)); + * } + * + * do_something_with_a(&A); + * + * cleanup: + * mbedtls_mpi_free(&A); + * mbedtls_ecp_group_free(&grp); + * \endcode + * + * For Montgomery curves, we do not store \p A, but (A + 2) / 4, + * which is the quantity used in the formulas. Additionally, \p nbits is + * not the size of \p N but the required size for private keys. + * + * If \p modp is NULL, reduction modulo \p P is done using a generic algorithm. + * Otherwise, \p modp must point to a function that takes an \p mbedtls_mpi in the + * range of 0..2^(2*pbits)-1, and transforms it in-place to an integer + * which is congruent mod \p P to the given MPI, and is close enough to \p pbits + * in size, so that it may be efficiently brought in the 0..P-1 range by a few + * additions or subtractions. Therefore, it is only an approximative modular + * reduction. It must return 0 on success and non-zero on failure. + * + * \note Alternative implementations of the ECP module must obey the + * following constraints. + * * Group IDs must be distinct: if two group structures have + * the same ID, then they must be identical. + * * The fields \c id, \c P, \c A, \c B, \c G, \c N, + * \c pbits and \c nbits must have the same type and semantics + * as in the built-in implementation. + * They must be available for reading, but direct modification + * of these fields does not need to be supported. + * They do not need to be at the same offset in the structure. + */ +typedef struct mbedtls_ecp_group { + mbedtls_ecp_group_id id; /*!< An internal group identifier. */ + mbedtls_mpi P; /*!< The prime modulus of the base field. */ + mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. Note that + \p A is not set to the authentic value in some cases. + Refer to detailed description of ::mbedtls_ecp_group if + using domain parameters in the structure. + For Montgomery curves: (A + 2) / 4. */ + mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation. + For Montgomery curves: unused. */ + mbedtls_ecp_point G; /*!< The generator of the subgroup used. */ + mbedtls_mpi N; /*!< The order of \p G. */ + size_t pbits; /*!< The number of bits in \p P.*/ + size_t nbits; /*!< For Short Weierstrass: The number of bits in \p P. + For Montgomery curves: the number of bits in the + private keys. */ + /* End of public fields */ + + unsigned int MBEDTLS_PRIVATE(h); /*!< \internal 1 if the constants are static. */ + int(*MBEDTLS_PRIVATE(modp))(mbedtls_mpi *); /*!< The function for fast pseudo-reduction + mod \p P (see above).*/ + int(*MBEDTLS_PRIVATE(t_pre))(mbedtls_ecp_point *, void *); /*!< Unused. */ + int(*MBEDTLS_PRIVATE(t_post))(mbedtls_ecp_point *, void *); /*!< Unused. */ + void *MBEDTLS_PRIVATE(t_data); /*!< Unused. */ + mbedtls_ecp_point *MBEDTLS_PRIVATE(T); /*!< Pre-computed points for ecp_mul_comb(). */ + size_t MBEDTLS_PRIVATE(T_size); /*!< The number of dynamic allocated pre-computed points. */ +} +mbedtls_ecp_group; + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in mbedtls_config.h, or define them using the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: a point where higher memory usage yields diminishing performance + * returns. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< The maximum window size used. */ +#endif /* MBEDTLS_ECP_WINDOW_SIZE */ + +#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) +/* + * Trade code size for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * For each n-bit Short Weierstrass curve that is enabled, this adds 4n bytes + * of code size if n < 384 and 8n otherwise. + * + * Change this value to 0 to reduce code size. + */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ + +/** \} name SECTION: Module settings */ + +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + +/** + * The maximum size of the groups, that is, of \c N and \c P. + */ +#if !defined(MBEDTLS_ECP_LIGHT) +/* Dummy definition to help code that has optional ECP support and + * defines an MBEDTLS_ECP_MAX_BYTES-sized array unconditionally. */ +#define MBEDTLS_ECP_MAX_BITS 1 +/* Note: the curves must be listed in DECREASING size! */ +#elif defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 521 +#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 512 +#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 448 +#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 384 +#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 384 +#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 256 +#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 256 +#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 256 +#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 255 +#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 225 // n is slightly above 2^224 +#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 224 +#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 192 +#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +#define MBEDTLS_ECP_MAX_BITS 192 +#else /* !MBEDTLS_ECP_LIGHT */ +#error "Missing definition of MBEDTLS_ECP_MAX_BITS" +#endif /* !MBEDTLS_ECP_LIGHT */ + +#define MBEDTLS_ECP_MAX_BYTES ((MBEDTLS_ECP_MAX_BITS + 7) / 8) +#define MBEDTLS_ECP_MAX_PT_LEN (2 * MBEDTLS_ECP_MAX_BYTES + 1) + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/** + * \brief Internal restart context for multiplication + * + * \note Opaque struct + */ +typedef struct mbedtls_ecp_restart_mul mbedtls_ecp_restart_mul_ctx; + +/** + * \brief Internal restart context for ecp_muladd() + * + * \note Opaque struct + */ +typedef struct mbedtls_ecp_restart_muladd mbedtls_ecp_restart_muladd_ctx; + +/** + * \brief General context for resuming ECC operations + */ +typedef struct { + unsigned MBEDTLS_PRIVATE(ops_done); /*!< current ops count */ + unsigned MBEDTLS_PRIVATE(depth); /*!< call depth (0 = top-level) */ + mbedtls_ecp_restart_mul_ctx *MBEDTLS_PRIVATE(rsm); /*!< ecp_mul_comb() sub-context */ + mbedtls_ecp_restart_muladd_ctx *MBEDTLS_PRIVATE(ma); /*!< ecp_muladd() sub-context */ +} mbedtls_ecp_restart_ctx; + +/* + * Operation counts for restartable functions + */ +#define MBEDTLS_ECP_OPS_CHK 3 /*!< basic ops count for ecp_check_pubkey() */ +#define MBEDTLS_ECP_OPS_DBL 8 /*!< basic ops count for ecp_double_jac() */ +#define MBEDTLS_ECP_OPS_ADD 11 /*!< basic ops count for see ecp_add_mixed() */ +#define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv() */ + +/** + * \brief Internal; for restartable functions in other modules. + * Check and update basic ops budget. + * + * \param grp Group structure + * \param rs_ctx Restart context + * \param ops Number of basic ops to do + * + * \return \c 0 if doing \p ops basic ops is still allowed, + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS otherwise. + */ +int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp, + mbedtls_ecp_restart_ctx *rs_ctx, + unsigned ops); + +/* Utility macro for checking and updating ops budget */ +#define MBEDTLS_ECP_BUDGET(ops) \ + MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, rs_ctx, \ + (unsigned) (ops))); + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +#define MBEDTLS_ECP_BUDGET(ops) /* no-op; for compatibility */ + +/* We want to declare restartable versions of existing functions anyway */ +typedef void mbedtls_ecp_restart_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief The ECP key-pair structure. + * + * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. + * + * \note Members are deliberately in the same order as in the + * ::mbedtls_ecdsa_context structure. + */ +typedef struct mbedtls_ecp_keypair { + mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /*!< Elliptic curve and base point */ + mbedtls_mpi MBEDTLS_PRIVATE(d); /*!< our secret value */ + mbedtls_ecp_point MBEDTLS_PRIVATE(Q); /*!< our public value */ +} +mbedtls_ecp_keypair; + +/** + * The uncompressed point format for Short Weierstrass curves + * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX). + */ +#define MBEDTLS_ECP_PF_UNCOMPRESSED 0 +/** + * The compressed point format for Short Weierstrass curves + * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX). + * + * \warning While this format is supported for all concerned curves for + * writing, when it comes to parsing, it is not supported for all + * curves. Specifically, parsing compressed points on + * MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1 is not + * supported. + */ +#define MBEDTLS_ECP_PF_COMPRESSED 1 + +/* + * Some other constants from RFC 4492 + */ +#define MBEDTLS_ECP_TLS_NAMED_CURVE 3 /**< The named_curve of ECCurveType. */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Set the maximum number of basic operations done in a row. + * + * If more operations are needed to complete a computation, + * #MBEDTLS_ERR_ECP_IN_PROGRESS will be returned by the + * function performing the computation. It is then the + * caller's responsibility to either call again with the same + * parameters until it returns 0 or an error code; or to free + * the restart context if the operation is to be aborted. + * + * It is strictly required that all input parameters and the + * restart context be the same on successive calls for the + * same operation, but output parameters need not be the + * same; they must not be used until the function finally + * returns 0. + * + * This only applies to functions whose documentation + * mentions they may return #MBEDTLS_ERR_ECP_IN_PROGRESS (or + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS for functions in the + * SSL module). For functions that accept a "restart context" + * argument, passing NULL disables restart and makes the + * function equivalent to the function with the same name + * with \c _restartable removed. For functions in the ECDH + * module, restart is disabled unless the function accepts + * an "ECDH context" argument and + * mbedtls_ecdh_enable_restart() was previously called on + * that context. For function in the SSL module, restart is + * only enabled for specific sides and key exchanges + * (currently only for clients and ECDHE-ECDSA). + * + * \warning Using the PSA interruptible interfaces with keys in local + * storage and no accelerator driver will also call this + * function to set the values specified via those interfaces, + * overwriting values previously set. Care should be taken if + * mixing these two interfaces. + * + * \param max_ops Maximum number of basic operations done in a row. + * Default: 0 (unlimited). + * Lower (non-zero) values mean ECC functions will block for + * a lesser maximum amount of time. + * + * \note A "basic operation" is defined as a rough equivalent of a + * multiplication in GF(p) for the NIST P-256 curve. + * As an indication, with default settings, a scalar + * multiplication (full run of \c mbedtls_ecp_mul()) is: + * - about 3300 basic operations for P-256 + * - about 9400 basic operations for P-384 + * + * \note Very low values are not always respected: sometimes + * functions need to block for a minimum number of + * operations, and will do so even if max_ops is set to a + * lower value. That minimum depends on the curve size, and + * can be made lower by decreasing the value of + * \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, here is the + * lowest effective value for various curves and values of + * that parameter (w for short): + * w=6 w=5 w=4 w=3 w=2 + * P-256 208 208 160 136 124 + * P-384 682 416 320 272 248 + * P-521 1364 832 640 544 496 + * + * \note This setting is currently ignored by Curve25519. + */ +void mbedtls_ecp_set_max_ops(unsigned max_ops); + +/** + * \brief Check if restart is enabled (max_ops != 0) + * + * \return \c 0 if \c max_ops == 0 (restart disabled) + * \return \c 1 otherwise (restart enabled) + */ +int mbedtls_ecp_restart_is_enabled(void); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/* + * Get the type of a curve + */ +mbedtls_ecp_curve_type mbedtls_ecp_get_type(const mbedtls_ecp_group *grp); + +/** + * \brief This function retrieves the information defined in + * mbedtls_ecp_curve_info() for all supported curves. + * + * \note This function returns information about all curves + * supported by the library. Some curves may not be + * supported for all algorithms. Call mbedtls_ecdh_can_do() + * or mbedtls_ecdsa_can_do() to check if a curve is + * supported for ECDH or ECDSA. + * + * \return A statically allocated array. The last entry is 0. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list(void); + +/** + * \brief This function retrieves the list of internal group + * identifiers of all supported curves in the order of + * preference. + * + * \note This function returns information about all curves + * supported by the library. Some curves may not be + * supported for all algorithms. Call mbedtls_ecdh_can_do() + * or mbedtls_ecdsa_can_do() to check if a curve is + * supported for ECDH or ECDSA. + * + * \return A statically allocated array, + * terminated with MBEDTLS_ECP_DP_NONE. + */ +const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list(void); + +/** + * \brief This function retrieves curve information from an internal + * group identifier. + * + * \param grp_id An \c MBEDTLS_ECP_DP_XXX value. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id); + +/** + * \brief This function retrieves curve information from a TLS + * NamedCurve value. + * + * \param tls_id An \c MBEDTLS_ECP_DP_XXX value. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id); + +/** + * \brief This function retrieves curve information from a + * human-readable name. + * + * \param name The human-readable name. + * + * \return The associated curve information on success. + * \return NULL on failure. + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name(const char *name); + +/** + * \brief This function initializes a point as zero. + * + * \param pt The point to initialize. + */ +void mbedtls_ecp_point_init(mbedtls_ecp_point *pt); + +/** + * \brief This function initializes an ECP group context + * without loading any domain parameters. + * + * \note After this function is called, domain parameters + * for various ECP groups can be loaded through the + * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() + * functions. + */ +void mbedtls_ecp_group_init(mbedtls_ecp_group *grp); + +/** + * \brief This function initializes a key pair as an invalid one. + * + * \param key The key pair to initialize. + */ +void mbedtls_ecp_keypair_init(mbedtls_ecp_keypair *key); + +/** + * \brief This function frees the components of a point. + * + * \param pt The point to free. + */ +void mbedtls_ecp_point_free(mbedtls_ecp_point *pt); + +/** + * \brief This function frees the components of an ECP group. + * + * \param grp The group to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP group. + */ +void mbedtls_ecp_group_free(mbedtls_ecp_group *grp); + +/** + * \brief This function frees the components of a key pair. + * + * \param key The key pair to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP key pair. + */ +void mbedtls_ecp_keypair_free(mbedtls_ecp_keypair *key); + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/** + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. This must + * not be \c NULL. + */ +void mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx *ctx); + +/** + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, in which + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized restart context. + */ +void mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx *ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief This function copies the contents of point \p Q into + * point \p P. + * + * \param P The destination point. This must be initialized. + * \param Q The source point. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code for other kinds of failure. + */ +int mbedtls_ecp_copy(mbedtls_ecp_point *P, const mbedtls_ecp_point *Q); + +/** + * \brief This function copies the contents of group \p src into + * group \p dst. + * + * \param dst The destination group. This must be initialized. + * \param src The source group. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_group_copy(mbedtls_ecp_group *dst, + const mbedtls_ecp_group *src); + +/** + * \brief This function sets a point to the point at infinity. + * + * \param pt The point to set. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_set_zero(mbedtls_ecp_point *pt); + +/** + * \brief This function checks if a point is the point at infinity. + * + * \param pt The point to test. This must be initialized. + * + * \return \c 1 if the point is zero. + * \return \c 0 if the point is non-zero. + * \return A negative error code on failure. + */ +int mbedtls_ecp_is_zero(mbedtls_ecp_point *pt); + +/** + * \brief This function compares two points. + * + * \note This assumes that the points are normalized. Otherwise, + * they may compare as "not equal" even if they are. + * + * \param P The first point to compare. This must be initialized. + * \param Q The second point to compare. This must be initialized. + * + * \return \c 0 if the points are equal. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. + */ +int mbedtls_ecp_point_cmp(const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q); + +/** + * \brief This function imports a non-zero point from two ASCII + * strings. + * + * \param P The destination point. This must be initialized. + * \param radix The numeric base of the input. + * \param x The first affine coordinate, as a null-terminated string. + * \param y The second affine coordinate, as a null-terminated string. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_MPI_XXX error code on failure. + */ +int mbedtls_ecp_point_read_string(mbedtls_ecp_point *P, int radix, + const char *x, const char *y); + +/** + * \brief This function exports a point into unsigned binary data. + * + * \param grp The group to which the point should belong. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param P The point to export. This must be initialized. + * \param format The point format. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * (For groups without these formats, this parameter is + * ignored. But it still has to be either of the above + * values.) + * \param olen The address at which to store the length of + * the output in Bytes. This must not be \c NULL. + * \param buf The output buffer. This must be a writable buffer + * of length \p buflen Bytes. + * \param buflen The length of the output buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer + * is too small to hold the point. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * or the export for the given group is not implemented. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen); + +/** + * \brief This function imports a point from unsigned binary data. + * + * \note This function does not check that the point actually + * belongs to the given group, see mbedtls_ecp_check_pubkey() + * for that. + * + * \note For compressed points, see #MBEDTLS_ECP_PF_COMPRESSED for + * limitations. + * + * \param grp The group to which the point should belong. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param P The destination context to import the point to. + * This must be initialized. + * \param buf The input buffer. This must be a readable buffer + * of length \p ilen Bytes. + * \param ilen The length of the input buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the + * given group is not implemented. + */ +int mbedtls_ecp_point_read_binary(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P, + const unsigned char *buf, size_t ilen); + +/** + * \brief This function imports a point from a TLS ECPoint record. + * + * \note On function return, \p *buf is updated to point immediately + * after the ECPoint record. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The destination point. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the buffer. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization + * failure. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + */ +int mbedtls_ecp_tls_read_point(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char **buf, size_t len); + +/** + * \brief This function exports a point as a TLS ECPoint record + * defined in RFC 4492, Section 5.4. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to be exported. This must be initialized. + * \param format The point format to use. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * \param olen The address at which to store the length in Bytes + * of the data written. + * \param buf The target buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the target buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer + * is too small to hold the exported point. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen); + +/** + * \brief This function sets up an ECP group context + * from a standardized set of domain parameters. + * + * \note The index should be a value of the NamedCurve enum, + * as defined in RFC-4492: Elliptic Curve Cryptography + * (ECC) Cipher Suites for Transport Layer Security (TLS), + * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. + * + * \param grp The group context to setup. This must be initialized. + * \param id The identifier of the domain parameter set to load. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't + * correspond to a known group. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id); + +/** + * \brief This function sets up an ECP group context from a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. + * + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. + * + * \param grp The group context to setup. This must be initialized. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the input buffer \c *buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not + * recognized. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_read_group(mbedtls_ecp_group *grp, + const unsigned char **buf, size_t len); + +/** + * \brief This function extracts an elliptic curve group ID from a + * TLS ECParameters record as defined in RFC 4492, Section 5.4. + * + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. + * + * \param grp The address at which to store the group id. + * This must not be \c NULL. + * \param buf The address of the pointer to the start of the input buffer. + * \param len The length of the input buffer \c *buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not + * recognized. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id *grp, + const unsigned char **buf, + size_t len); +/** + * \brief This function exports an elliptic curve as a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. + * + * \param grp The ECP group to be exported. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The buffer to write to. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The length of the output buffer \p buf in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output + * buffer is too small to hold the exported group. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp, + size_t *olen, + unsigned char *buf, size_t blen); + +/** + * \brief This function performs a scalar multiplication of a point + * by an integer: \p R = \p m * \p P. + * + * It is not thread-safe to use same group in multiple threads. + * + * \note To prevent timing attacks, this function + * executes the exact same sequence of base-field + * operations for any valid \p m. It avoids any if-branch or + * array index depending on the value of \p m. It also uses + * \p f_rng to randomize some intermediate results. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c + * NULL if \p f_rng doesn't need a context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private + * key, or \p P is not a valid public key. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +/** + * \brief This function performs multiplication of a point by + * an integer: \p R = \p m * \p P in a restartable way. + * + * \see mbedtls_ecp_mul() + * + * \note This function does the same as \c mbedtls_ecp_mul(), but + * it can return early and restart according to the limit set + * with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c + * NULL if \p f_rng doesn't need a context. + * \param rs_ctx The restart context (NULL disables restart). + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private + * key, or \p P is not a valid public key. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx); + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +/** + * \brief This function checks if domain parameter A of the curve is + * \c -3. + * + * \note This function is only defined for short Weierstrass curves. + * It may not be included in builds without any short + * Weierstrass curve. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * + * \return \c 1 if A = -3. + * \return \c 0 Otherwise. + */ +static inline int mbedtls_ecp_group_a_is_minus_3(const mbedtls_ecp_group *grp) +{ + return grp->A.MBEDTLS_PRIVATE(p) == NULL; +} + +/** + * \brief This function performs multiplication and addition of two + * points by integers: \p R = \p m * \p P + \p n * \p Q + * + * It is not thread-safe to use same group in multiple threads. + * + * \note In contrast to mbedtls_ecp_mul(), this function does not + * guarantee a constant execution flow and timing. + * + * \note This function is only defined for short Weierstrass curves. + * It may not be included in builds without any short + * Weierstrass curve. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply \p P. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. + * \param n The integer by which to multiply \p Q. + * This must be initialized. + * \param Q The point to be multiplied by \p n. + * This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not + * valid private keys, or \p P or \p Q are not valid public + * keys. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a short Weierstrass curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q); + +/** + * \brief This function performs multiplication and addition of two + * points by integers: \p R = \p m * \p P + \p n * \p Q in a + * restartable way. + * + * \see \c mbedtls_ecp_muladd() + * + * \note This function works the same as \c mbedtls_ecp_muladd(), + * but it can return early and restart according to the limit + * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \note This function is only defined for short Weierstrass curves. + * It may not be included in builds without any short + * Weierstrass curve. + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply \p P. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. + * \param n The integer by which to multiply \p Q. + * This must be initialized. + * \param Q The point to be multiplied by \p n. + * This must be initialized. + * \param rs_ctx The restart context (NULL disables restart). + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not + * valid private keys, or \p P or \p Q are not valid public + * keys. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not + * designate a short Weierstrass curve. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_muladd_restartable( + mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q, + mbedtls_ecp_restart_ctx *rs_ctx); +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +/** + * \brief This function checks that a point is a valid public key + * on this curve. + * + * It only checks that the point is non-zero, has + * valid coordinates and lies on the curve. It does not verify + * that it is indeed a multiple of \c G. This additional + * check is computationally more expensive, is not required + * by standards, and should not be necessary if the group + * used has a small cofactor. In particular, it is useless for + * the NIST groups which all have a cofactor of 1. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure, to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group the point should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to check. This must be initialized. + * + * \return \c 0 if the point is a valid public key. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not + * a valid public key for the given curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt); + +/** + * \brief This function checks that an \c mbedtls_mpi is a + * valid private key for this curve. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group the private key should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The integer to check. This must be initialized. + * + * \return \c 0 if the point is a valid private key. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid + * private key for the given curve. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp, + const mbedtls_mpi *d); + +/** + * \brief This function generates a private key. + * + * \param grp The ECP group to generate a private key for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The destination MPI (secret part). This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp, + mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function generates a keypair with a configurable base + * point. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param G The base point to use. This must be initialized + * and belong to \p grp. It replaces the default base + * point \c grp->G used by mbedtls_ecp_gen_keypair(). + * \param d The destination MPI (secret part). + * This must be initialized. + * \param Q The destination point (public part). + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function generates an ECP keypair. + * + * \note This function uses bare components rather than an + * ::mbedtls_ecp_keypair structure to ease use with other + * structures, such as ::mbedtls_ecdh_context or + * ::mbedtls_ecdsa_context. + * + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The destination MPI (secret part). + * This must be initialized. + * \param Q The destination point (public part). + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, mbedtls_mpi *d, + mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function generates an ECP key. + * + * \param grp_id The ECP group identifier. + * \param key The destination key. This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code + * on failure. + */ +int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief This function reads an elliptic curve private key. + * + * \param grp_id The ECP group identifier. + * \param key The destination key. + * \param buf The buffer containing the binary representation of the + * key. (Big endian integer for Weierstrass curves, byte + * string for Montgomery curves.) + * \param buflen The length of the buffer in bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is + * invalid. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + const unsigned char *buf, size_t buflen); + +/** + * \brief This function exports an elliptic curve private key. + * + * \param key The private key. + * \param buf The output buffer for containing the binary representation + * of the key. (Big endian integer for Weierstrass curves, byte + * string for Montgomery curves.) + * \param buflen The total length of the buffer in bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key + representation is larger than the available space in \p buf. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for + * the group is not implemented. + * \return Another negative error code on different kinds of failure. + */ +int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, + unsigned char *buf, size_t buflen); + +/** + * \brief This function checks that the keypair objects + * \p pub and \p prv have the same group and the + * same public point, and that the private key in + * \p prv is consistent with the public key. + * + * \param pub The keypair structure holding the public key. This + * must be initialized. If it contains a private key, that + * part is ignored. + * \param prv The keypair structure holding the full keypair. + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c + * NULL if \p f_rng doesn't need a context. + * + * \return \c 0 on success, meaning that the keys are valid and match. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. + * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX + * error code on calculation failure. + */ +int mbedtls_ecp_check_pub_priv( + const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng); + +/** + * \brief This function exports generic key-pair parameters. + * + * \param key The key pair to export from. + * \param grp Slot for exported ECP group. + * It must point to an initialized ECP group. + * \param d Slot for the exported secret value. + * It must point to an initialized mpi. + * \param Q Slot for the exported public value. + * It must point to an initialized ECP point. + * + * \return \c 0 on success, + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if key id doesn't + * correspond to a known group. + * \return Another negative error code on other kinds of failure. + */ +int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The ECP checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_ecp_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* ecp.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/error.h b/src/app/findmy/crypto/third-party/mbedtls/error.h new file mode 100644 index 0000000..186589a --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/error.h @@ -0,0 +1,201 @@ +/** + * \file error.h + * + * \brief Error to string translation + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_ERROR_H +#define MBEDTLS_ERROR_H + +#include "mbedtls/build_info.h" + +#include + +/** + * Error code layout. + * + * Currently we try to keep all error codes within the negative space of 16 + * bits signed integers to support all platforms (-0x0001 - -0x7FFF). In + * addition we'd like to give two layers of information on the error if + * possible. + * + * For that purpose the error codes are segmented in the following manner: + * + * 16 bit error code bit-segmentation + * + * 1 bit - Unused (sign bit) + * 3 bits - High level module ID + * 5 bits - Module-dependent error code + * 7 bits - Low level module errors + * + * For historical reasons, low-level error codes are divided in even and odd, + * even codes were assigned first, and -1 is reserved for other errors. + * + * Low-level module errors (0x0002-0x007E, 0x0001-0x007F) + * + * Module Nr Codes assigned + * ERROR 2 0x006E 0x0001 + * MPI 7 0x0002-0x0010 + * GCM 3 0x0012-0x0016 0x0013-0x0013 + * THREADING 3 0x001A-0x001E + * AES 5 0x0020-0x0022 0x0021-0x0025 + * CAMELLIA 3 0x0024-0x0026 0x0027-0x0027 + * BASE64 2 0x002A-0x002C + * OID 1 0x002E-0x002E 0x000B-0x000B + * PADLOCK 1 0x0030-0x0030 + * DES 2 0x0032-0x0032 0x0033-0x0033 + * CTR_DBRG 4 0x0034-0x003A + * ENTROPY 3 0x003C-0x0040 0x003D-0x003F + * NET 13 0x0042-0x0052 0x0043-0x0049 + * ARIA 4 0x0058-0x005E + * ASN1 7 0x0060-0x006C + * CMAC 1 0x007A-0x007A + * PBKDF2 1 0x007C-0x007C + * HMAC_DRBG 4 0x0003-0x0009 + * CCM 3 0x000D-0x0011 + * MD5 1 0x002F-0x002F + * RIPEMD160 1 0x0031-0x0031 + * SHA1 1 0x0035-0x0035 0x0073-0x0073 + * SHA256 1 0x0037-0x0037 0x0074-0x0074 + * SHA512 1 0x0039-0x0039 0x0075-0x0075 + * SHA-3 1 0x0076-0x0076 + * CHACHA20 3 0x0051-0x0055 + * POLY1305 3 0x0057-0x005B + * CHACHAPOLY 2 0x0054-0x0056 + * PLATFORM 2 0x0070-0x0072 + * LMS 5 0x0011-0x0019 + * + * High-level module nr (3 bits - 0x0...-0x7...) + * Name ID Nr of Errors + * PEM 1 9 + * PKCS#12 1 4 (Started from top) + * X509 2 20 + * PKCS5 2 4 (Started from top) + * DHM 3 11 + * PK 3 15 (Started from top) + * RSA 4 11 + * ECP 4 10 (Started from top) + * MD 5 5 + * HKDF 5 1 (Started from top) + * PKCS7 5 12 (Started from 0x5300) + * SSL 5 2 (Started from 0x5F00) + * CIPHER 6 8 (Started from 0x6080) + * SSL 6 22 (Started from top, plus 0x6000) + * SSL 7 20 (Started from 0x7000, gaps at + * 0x7380, 0x7900-0x7980, 0x7A80-0x7E80) + * + * Module dependent error code (5 bits 0x.00.-0x.F8.) + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic error */ +#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001 +/** This is a bug in the library */ +#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E + +/** Hardware accelerator failed */ +#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED -0x0070 +/** The requested feature is not supported by the platform */ +#define MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED -0x0072 + +/** + * \brief Combines a high-level and low-level error code together. + * + * Wrapper macro for mbedtls_error_add(). See that function for + * more details. + */ +#define MBEDTLS_ERROR_ADD(high, low) \ + mbedtls_error_add(high, low, __FILE__, __LINE__) + +#if defined(MBEDTLS_TEST_HOOKS) +/** + * \brief Testing hook called before adding/combining two error codes together. + * Only used when invasive testing is enabled via MBEDTLS_TEST_HOOKS. + */ +extern void (*mbedtls_test_hook_error_add)(int, int, const char *, int); +#endif + +/** + * \brief Combines a high-level and low-level error code together. + * + * This function can be called directly however it is usually + * called via the #MBEDTLS_ERROR_ADD macro. + * + * While a value of zero is not a negative error code, it is still an + * error code (that denotes success) and can be combined with both a + * negative error code or another value of zero. + * + * \note When invasive testing is enabled via #MBEDTLS_TEST_HOOKS, also try to + * call \link mbedtls_test_hook_error_add \endlink. + * + * \param high high-level error code. See error.h for more details. + * \param low low-level error code. See error.h for more details. + * \param file file where this error code addition occurred. + * \param line line where this error code addition occurred. + */ +static inline int mbedtls_error_add(int high, int low, + const char *file, int line) +{ +#if defined(MBEDTLS_TEST_HOOKS) + if (*mbedtls_test_hook_error_add != NULL) { + (*mbedtls_test_hook_error_add)(high, low, file, line); + } +#endif + (void) file; + (void) line; + + return high + low; +} + +/** + * \brief Translate an Mbed TLS error code into a string representation. + * The result is truncated if necessary and always includes a + * terminating null byte. + * + * \param errnum error code + * \param buffer buffer to place representation in + * \param buflen length of the buffer + */ +void mbedtls_strerror(int errnum, char *buffer, size_t buflen); + +/** + * \brief Translate the high-level part of an Mbed TLS error code into a string + * representation. + * + * This function returns a const pointer to an un-modifiable string. The caller + * must not try to modify the string. It is intended to be used mostly for + * logging purposes. + * + * \param error_code error code + * + * \return The string representation of the error code, or \c NULL if the error + * code is unknown. + */ +const char *mbedtls_high_level_strerr(int error_code); + +/** + * \brief Translate the low-level part of an Mbed TLS error code into a string + * representation. + * + * This function returns a const pointer to an un-modifiable string. The caller + * must not try to modify the string. It is intended to be used mostly for + * logging purposes. + * + * \param error_code error code + * + * \return The string representation of the error code, or \c NULL if the error + * code is unknown. + */ +const char *mbedtls_low_level_strerr(int error_code); + +#ifdef __cplusplus +} +#endif + +#endif /* error.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/gcm.h b/src/app/findmy/crypto/third-party/mbedtls/gcm.h new file mode 100644 index 0000000..837cecc --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/gcm.h @@ -0,0 +1,370 @@ +/** + * \file gcm.h + * + * \brief This file contains GCM definitions and functions. + * + * The Galois/Counter Mode (GCM) for 128-bit block ciphers is defined + * in D. McGrew, J. Viega, The Galois/Counter Mode of Operation + * (GCM), Natl. Inst. Stand. Technol. + * + * For more information on GCM, see NIST SP 800-38D: Recommendation for + * Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_GCM_H +#define MBEDTLS_GCM_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/cipher.h" + +#include + +#define MBEDTLS_GCM_ENCRYPT 1 +#define MBEDTLS_GCM_DECRYPT 0 + +/** Authenticated decryption failed. */ +#define MBEDTLS_ERR_GCM_AUTH_FAILED -0x0012 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_GCM_BAD_INPUT -0x0014 +/** An output buffer is too small. */ +#define MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL -0x0016 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_GCM_ALT) + +/** + * \brief The GCM context structure. + */ +typedef struct mbedtls_gcm_context { + mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ + uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */ + uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */ + uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */ + uint64_t MBEDTLS_PRIVATE(add_len); /*!< The total length of the additional data. */ + unsigned char MBEDTLS_PRIVATE(base_ectr)[16]; /*!< The first ECTR for tag. */ + unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working value. */ + unsigned char MBEDTLS_PRIVATE(buf)[16]; /*!< The buf working value. */ + int MBEDTLS_PRIVATE(mode); /*!< The operation to perform: + #MBEDTLS_GCM_ENCRYPT or + #MBEDTLS_GCM_DECRYPT. */ +} +mbedtls_gcm_context; + +#else /* !MBEDTLS_GCM_ALT */ +#include "gcm_alt.h" +#endif /* !MBEDTLS_GCM_ALT */ + +/** + * \brief This function initializes the specified GCM context, + * to make references valid, and prepares the context + * for mbedtls_gcm_setkey() or mbedtls_gcm_free(). + * + * The function does not bind the GCM context to a particular + * cipher, nor set the key. For this purpose, use + * mbedtls_gcm_setkey(). + * + * \param ctx The GCM context to initialize. This must not be \c NULL. + */ +void mbedtls_gcm_init(mbedtls_gcm_context *ctx); + +/** + * \brief This function associates a GCM context with a + * cipher algorithm and a key. + * + * \param ctx The GCM context. This must be initialized. + * \param cipher The 128-bit block cipher to use. + * \param key The encryption key. This must be a readable buffer of at + * least \p keybits bits. + * \param keybits The key size in bits. Valid options are: + *
    • 128 bits
    • + *
    • 192 bits
    • + *
    • 256 bits
    + * + * \return \c 0 on success. + * \return A cipher-specific error code on failure. + */ +int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits); + +/** + * \brief This function performs GCM encryption or decryption of a buffer. + * + * \note For encryption, the output buffer can be the same as the + * input buffer. For decryption, the output buffer cannot be + * the same as input buffer. If the buffers overlap, the output + * buffer must trail at least 8 Bytes behind the input buffer. + * + * \warning When this function performs a decryption, it outputs the + * authentication tag and does not verify that the data is + * authentic. You should use this function to perform encryption + * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. + * + * \param ctx The GCM context to use for encryption or decryption. This + * must be initialized. + * \param mode The operation to perform: + * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. + * The ciphertext is written to \p output and the + * authentication tag is written to \p tag. + * - #MBEDTLS_GCM_DECRYPT to perform decryption. + * The plaintext is written to \p output and the + * authentication tag is written to \p tag. + * Note that this mode is not recommended, because it does + * not verify the authenticity of the data. For this reason, + * you should use mbedtls_gcm_auth_decrypt() instead of + * calling this function in decryption mode. + * \param length The length of the input data, which is equal to the length + * of the output data. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param input The buffer holding the input data. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size in Bytes. + * \param output The buffer for holding the output data. If \p length is greater + * than zero, this must be a writable buffer of at least that + * size in Bytes. + * \param tag_len The length of the tag to generate. + * \param tag The buffer for holding the tag. This must be a writable + * buffer of at least \p tag_len Bytes. + * + * \return \c 0 if the encryption or decryption was performed + * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, + * this does not indicate that the data is authentic. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the encryption + * or decryption failed. + */ +int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag); + +/** + * \brief This function performs a GCM authenticated decryption of a + * buffer. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param length The length of the ciphertext to decrypt, which is also + * the length of the decrypted plaintext. + * \param iv The initialization vector. This must be a readable buffer + * of at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * \param add The buffer holding the additional data. This must be of at + * least that size in Bytes. + * \param add_len The length of the additional data. + * \param tag The buffer holding the tag to verify. This must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to verify. + * \param input The buffer holding the ciphertext. If \p length is greater + * than zero, this must be a readable buffer of at least that + * size. + * \param output The buffer for holding the decrypted plaintext. If \p length + * is greater than zero, this must be a writable buffer of at + * least that size. + * + * \return \c 0 if successful and authenticated. + * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths or pointers are + * not valid or a cipher-specific error code if the decryption + * failed. + */ +int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function starts a GCM encryption or decryption + * operation. + * + * \param ctx The GCM context. This must be initialized. + * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or + * #MBEDTLS_GCM_DECRYPT. + * \param iv The initialization vector. This must be a readable buffer of + * at least \p iv_len Bytes. + * \param iv_len The length of the IV. + * + * \return \c 0 on success. + */ +int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len); + +/** + * \brief This function feeds an input buffer as associated data + * (authenticated but not encrypted data) in a GCM + * encryption or decryption operation. + * + * Call this function after mbedtls_gcm_starts() to pass + * the associated data. If the associated data is empty, + * you do not need to call this function. You may not + * call this function after calling mbedtls_cipher_update(). + * + * \param ctx The GCM context. This must have been started with + * mbedtls_gcm_starts() and must not have yet received + * any input with mbedtls_gcm_update(). + * \param add The buffer holding the additional data, or \c NULL + * if \p add_len is \c 0. + * \param add_len The length of the additional data. If \c 0, + * \p add may be \c NULL. + * + * \return \c 0 on success. + */ +int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, + const unsigned char *add, + size_t add_len); + +/** + * \brief This function feeds an input buffer into an ongoing GCM + * encryption or decryption operation. + * + * You may call this function zero, one or more times + * to pass successive parts of the input: the plaintext to + * encrypt, or the ciphertext (not including the tag) to + * decrypt. After the last part of the input, call + * mbedtls_gcm_finish(). + * + * This function may produce output in one of the following + * ways: + * - Immediate output: the output length is always equal + * to the input length. + * - Buffered output: the output consists of a whole number + * of 16-byte blocks. If the total input length so far + * (not including associated data) is 16 \* *B* + *A* + * with *A* < 16 then the total output length is 16 \* *B*. + * + * In particular: + * - It is always correct to call this function with + * \p output_size >= \p input_length + 15. + * - If \p input_length is a multiple of 16 for all the calls + * to this function during an operation, then it is + * correct to use \p output_size = \p input_length. + * + * \note For decryption, the output buffer cannot be the same as + * input buffer. If the buffers overlap, the output buffer + * must trail at least 8 Bytes behind the input buffer. + * + * \param ctx The GCM context. This must be initialized. + * \param input The buffer holding the input data. If \p input_length + * is greater than zero, this must be a readable buffer + * of at least \p input_length bytes. + * \param input_length The length of the input data in bytes. + * \param output The buffer for the output data. If \p output_size + * is greater than zero, this must be a writable buffer of + * of at least \p output_size bytes. + * \param output_size The size of the output buffer in bytes. + * See the function description regarding the output size. + * \param output_length On success, \p *output_length contains the actual + * length of the output written in \p output. + * On failure, the content of \p *output_length is + * unspecified. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure: + * total input length too long, + * unsupported input/output buffer overlap detected, + * or \p output_size too small. + */ +int mbedtls_gcm_update(mbedtls_gcm_context *ctx, + const unsigned char *input, size_t input_length, + unsigned char *output, size_t output_size, + size_t *output_length); + +/** + * \brief This function finishes the GCM operation and generates + * the authentication tag. + * + * It wraps up the GCM stream, and generates the + * tag. The tag can have a maximum length of 16 Bytes. + * + * \param ctx The GCM context. This must be initialized. + * \param tag The buffer for holding the tag. This must be a writable + * buffer of at least \p tag_len Bytes. + * \param tag_len The length of the tag to generate. This must be at least + * four. + * \param output The buffer for the final output. + * If \p output_size is nonzero, this must be a writable + * buffer of at least \p output_size bytes. + * \param output_size The size of the \p output buffer in bytes. + * This must be large enough for the output that + * mbedtls_gcm_update() has not produced. In particular: + * - If mbedtls_gcm_update() produces immediate output, + * or if the total input size is a multiple of \c 16, + * then mbedtls_gcm_finish() never produces any output, + * so \p output_size can be \c 0. + * - \p output_size never needs to be more than \c 15. + * \param output_length On success, \p *output_length contains the actual + * length of the output written in \p output. + * On failure, the content of \p *output_length is + * unspecified. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure: + * invalid value of \p tag_len, + * or \p output_size too small. + */ +int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, + unsigned char *output, size_t output_size, + size_t *output_length, + unsigned char *tag, size_t tag_len); + +/** + * \brief This function clears a GCM context and the underlying + * cipher sub-context. + * + * \param ctx The GCM context to clear. If this is \c NULL, the call has + * no effect. Otherwise, this must be initialized. + */ +void mbedtls_gcm_free(mbedtls_gcm_context *ctx); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The GCM checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_gcm_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + + +#endif /* gcm.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/hmac_drbg.h b/src/app/findmy/crypto/third-party/mbedtls/hmac_drbg.h new file mode 100644 index 0000000..18b1b75 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/hmac_drbg.h @@ -0,0 +1,434 @@ +/** + * \file hmac_drbg.h + * + * \brief The HMAC_DRBG pseudorandom generator. + * + * This module implements the HMAC_DRBG pseudorandom generator described + * in NIST SP 800-90A: Recommendation for Random Number Generation Using + * Deterministic Random Bit Generators. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_HMAC_DRBG_H +#define MBEDTLS_HMAC_DRBG_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/md.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +/* + * Error codes + */ +/** Too many random requested in single call. */ +#define MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 +/** Input too large (Entropy + additional). */ +#define MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 +/** Read/write error in file. */ +#define MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 +/** The entropy source failed. */ +#define MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in mbedtls_config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_HMAC_DRBG_RESEED_INTERVAL) +#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +#endif + +#if !defined(MBEDTLS_HMAC_DRBG_MAX_INPUT) +#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +#endif + +#if !defined(MBEDTLS_HMAC_DRBG_MAX_REQUEST) +#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +#endif + +#if !defined(MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) +#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +#endif + +/** \} name SECTION: Module settings */ + +#define MBEDTLS_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define MBEDTLS_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * HMAC_DRBG context. + */ +typedef struct mbedtls_hmac_drbg_context { + /* Working state: the key K is not stored explicitly, + * but is implied by the HMAC context */ + mbedtls_md_context_t MBEDTLS_PRIVATE(md_ctx); /*!< HMAC context (inc. K) */ + unsigned char MBEDTLS_PRIVATE(V)[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ + int MBEDTLS_PRIVATE(reseed_counter); /*!< reseed counter */ + + /* Administrative state */ + size_t MBEDTLS_PRIVATE(entropy_len); /*!< entropy bytes grabbed on each (re)seed */ + int MBEDTLS_PRIVATE(prediction_resistance); /*!< enable prediction resistance (Automatic + reseed before every random generation) */ + int MBEDTLS_PRIVATE(reseed_interval); /*!< reseed interval */ + + /* Callbacks */ + int(*MBEDTLS_PRIVATE(f_entropy))(void *, unsigned char *, size_t); /*!< entropy function */ + void *MBEDTLS_PRIVATE(p_entropy); /*!< context for the entropy function */ + +#if defined(MBEDTLS_THREADING_C) + /* Invariant: the mutex is initialized if and only if + * md_ctx->md_info != NULL. This means that the mutex is initialized + * during the initial seeding in mbedtls_hmac_drbg_seed() or + * mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free(). + * + * Note that this invariant may change without notice. Do not rely on it + * and do not access the mutex directly in application code. + */ + mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); +#endif +} mbedtls_hmac_drbg_context; + +/** + * \brief HMAC_DRBG context initialization. + * + * This function makes the context ready for mbedtls_hmac_drbg_seed(), + * mbedtls_hmac_drbg_seed_buf() or mbedtls_hmac_drbg_free(). + * + * \note The reseed interval is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL + * by default. Override this value by calling + * mbedtls_hmac_drbg_set_reseed_interval(). + * + * \param ctx HMAC_DRBG context to be initialized. + */ +void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx); + +/** + * \brief HMAC_DRBG initial seeding. + * + * Set the initial seed and set up the entropy source for future reseeds. + * + * A typical choice for the \p f_entropy and \p p_entropy parameters is + * to use the entropy module: + * - \p f_entropy is mbedtls_entropy_func(); + * - \p p_entropy is an instance of ::mbedtls_entropy_context initialized + * with mbedtls_entropy_init() (which registers the platform's default + * entropy sources). + * + * You can provide a personalization string in addition to the + * entropy source, to make this instantiation as unique as possible. + * + * \note By default, the security strength as defined by NIST is: + * - 128 bits if \p md_info is SHA-1; + * - 192 bits if \p md_info is SHA-224; + * - 256 bits if \p md_info is SHA-256, SHA-384 or SHA-512. + * Note that SHA-256 is just as efficient as SHA-224. + * The security strength can be reduced if a smaller + * entropy length is set with + * mbedtls_hmac_drbg_set_entropy_len(). + * + * \note The default entropy length is the security strength + * (converted from bits to bytes). You can override + * it by calling mbedtls_hmac_drbg_set_entropy_len(). + * + * \note During the initial seeding, this function calls + * the entropy source to obtain a nonce + * whose length is half the entropy length. + */ +#if defined(MBEDTLS_THREADING_C) +/** + * \note When Mbed TLS is built with threading support, + * after this function returns successfully, + * it is safe to call mbedtls_hmac_drbg_random() + * from multiple threads. Other operations, including + * reseeding, are not thread-safe. + */ +#endif /* MBEDTLS_THREADING_C */ +/** + * \param ctx HMAC_DRBG context to be seeded. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param f_entropy The entropy callback, taking as arguments the + * \p p_entropy context, the buffer to fill, and the + * length of the buffer. + * \p f_entropy is always called with a length that is + * less than or equal to the entropy length. + * \param p_entropy The entropy context to pass to \p f_entropy. + * \param custom The personalization string. + * This can be \c NULL, in which case the personalization + * string is empty regardless of the value of \p len. + * \param len The length of the personalization string. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len * 3 / 2 + * where \c entropy_len is the entropy length + * described above. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if the call to \p f_entropy failed. + */ +int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t *md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len); + +/** + * \brief Initialisation of simplified HMAC_DRBG (never reseeds). + * + * This function is meant for use in algorithms that need a pseudorandom + * input such as deterministic ECDSA. + */ +#if defined(MBEDTLS_THREADING_C) +/** + * \note When Mbed TLS is built with threading support, + * after this function returns successfully, + * it is safe to call mbedtls_hmac_drbg_random() + * from multiple threads. Other operations, including + * reseeding, are not thread-safe. + */ +#endif /* MBEDTLS_THREADING_C */ +/** + * \param ctx HMAC_DRBG context to be initialised. + * \param md_info MD algorithm to use for HMAC_DRBG. + * \param data Concatenation of the initial entropy string and + * the additional data. + * \param data_len Length of \p data in bytes. + * + * \return \c 0 if successful. or + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info is + * invalid. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED if there was not enough + * memory to allocate context data. + */ +int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t *md_info, + const unsigned char *data, size_t data_len); + +/** + * \brief This function turns prediction resistance on or off. + * The default value is off. + * + * \note If enabled, entropy is gathered at the beginning of + * every call to mbedtls_hmac_drbg_random_with_add() + * or mbedtls_hmac_drbg_random(). + * Only use this if your entropy source has sufficient + * throughput. + * + * \param ctx The HMAC_DRBG context. + * \param resistance #MBEDTLS_HMAC_DRBG_PR_ON or #MBEDTLS_HMAC_DRBG_PR_OFF. + */ +void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx, + int resistance); + +/** + * \brief This function sets the amount of entropy grabbed on each + * seed or reseed. + * + * See the documentation of mbedtls_hmac_drbg_seed() for the default value. + * + * \param ctx The HMAC_DRBG context. + * \param len The amount of entropy to grab, in bytes. + */ +void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, + size_t len); + +/** + * \brief Set the reseed interval. + * + * The reseed interval is the number of calls to mbedtls_hmac_drbg_random() + * or mbedtls_hmac_drbg_random_with_add() after which the entropy function + * is called again. + * + * The default value is #MBEDTLS_HMAC_DRBG_RESEED_INTERVAL. + * + * \param ctx The HMAC_DRBG context. + * \param interval The reseed interval. + */ +void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, + int interval); + +/** + * \brief This function updates the state of the HMAC_DRBG context. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param ctx The HMAC_DRBG context. + * \param additional The data to update the state with. + * If this is \c NULL, there is no additional data. + * \param add_len Length of \p additional in bytes. + * Unused if \p additional is \c NULL. + * + * \return \c 0 on success, or an error from the underlying + * hash calculation. + */ +int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len); + +/** + * \brief This function reseeds the HMAC_DRBG context, that is + * extracts data from the entropy source. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param ctx The HMAC_DRBG context. + * \param additional Additional data to add to the state. + * If this is \c NULL, there is no additional data + * and \p len should be \c 0. + * \param len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT + * and also at most + * #MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT - \c entropy_len + * where \c entropy_len is the entropy length + * (see mbedtls_hmac_drbg_set_entropy_len()). + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy function failed. + */ +int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, size_t len); + +/** + * \brief This function updates an HMAC_DRBG instance with additional + * data and uses it to generate random data. + * + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + * + * \note This function is not thread-safe. It is not safe + * to call this function if another thread might be + * concurrently obtaining random numbers from the same + * context or updating or reseeding the same context. + * + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \param additional Additional data to update with. + * If this is \c NULL, there is no additional data + * and \p add_len should be \c 0. + * \param add_len The length of the additional data. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_INPUT. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p output_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if + * \p add_len > #MBEDTLS_HMAC_DRBG_MAX_INPUT. + */ +int mbedtls_hmac_drbg_random_with_add(void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, + size_t add_len); + +/** + * \brief This function uses HMAC_DRBG to generate random data. + * + * This function automatically reseeds if the reseed counter is exceeded + * or prediction resistance is enabled. + */ +#if defined(MBEDTLS_THREADING_C) +/** + * \note When Mbed TLS is built with threading support, + * it is safe to call mbedtls_ctr_drbg_random() + * from multiple threads. Other operations, including + * reseeding, are not thread-safe. + */ +#endif /* MBEDTLS_THREADING_C */ +/** + * \param p_rng The HMAC_DRBG context. This must be a pointer to a + * #mbedtls_hmac_drbg_context structure. + * \param output The buffer to fill. + * \param out_len The length of the buffer in bytes. + * This must be at most #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + * if a call to the entropy source failed. + * \return #MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG if + * \p out_len > #MBEDTLS_HMAC_DRBG_MAX_REQUEST. + */ +int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len); + +/** + * \brief This function resets HMAC_DRBG context to the state immediately + * after initial call of mbedtls_hmac_drbg_init(). + * + * \param ctx The HMAC_DRBG context to free. + */ +void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function writes a seed file. + * + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on reseed + * failure. + */ +int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path); + +/** + * \brief This function reads and updates a seed file. The seed + * is added to this instance. + * + * \param ctx The HMAC_DRBG context. + * \param path The name of the file. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR on file error. + * \return #MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED on + * reseed failure. + * \return #MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG if the existing + * seed file is too large. + */ +int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path); +#endif /* MBEDTLS_FS_IO */ + + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief The HMAC_DRBG Checkup routine. + * + * \return \c 0 if successful. + * \return \c 1 if the test failed. + */ +int mbedtls_hmac_drbg_self_test(int verbose); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* hmac_drbg.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/kdf963.h b/src/app/findmy/crypto/third-party/mbedtls/kdf963.h new file mode 100644 index 0000000..cc235d5 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/kdf963.h @@ -0,0 +1,11 @@ +#include "mbedtls/platform.h" +#include "stdint.h" + +typedef enum +{ + MBED_KDF963_SHA128, + MBED_KDF963_SHA256, +} MBED_KDF963_SHA_TYPE; + +int mbed_KDF963(MBED_KDF963_SHA_TYPE type, uint8_t *secret, uint32_t secretSz, uint8_t *sinfo, + uint32_t sinfoSz, uint8_t *out, uint32_t out_size); diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/aes.c b/src/app/findmy/crypto/third-party/mbedtls/library/aes.c new file mode 100644 index 0000000..feb455b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/aes.c @@ -0,0 +1,2315 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#include "common.h" + +#if defined(MBEDTLS_AES_C) + +#include + +#include "mbedtls/aes.h" +#include "mbedtls/platform.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#if defined(MBEDTLS_ARCH_IS_ARM64) +#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY) +#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites" +#endif +#endif + +#if defined(MBEDTLS_ARCH_IS_X64) +#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY) +#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites" +#endif +#endif + +#if defined(MBEDTLS_ARCH_IS_X86) +#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C) +#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PADLOCK_C) +#if !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) +#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \ + "MBEDTLS_PADLOCK_C is set" +#endif +#endif +#endif + +#if defined(MBEDTLS_PADLOCK_C) +#include "padlock.h" +#endif +#if defined(MBEDTLS_AESNI_C) +#include "aesni.h" +#endif +#if defined(MBEDTLS_AESCE_C) +#include "aesce.h" +#endif + +#include "mbedtls/platform.h" + +#if !defined(MBEDTLS_AES_ALT) + +#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) +static int aes_padlock_ace = -1; +#endif + +#if defined(MBEDTLS_AES_ROM_TABLES) +/* + * Forward S-box + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +static const unsigned char FSb[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 +}; +#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */ + +/* + * Forward tables + */ +#define FT \ +\ + V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \ + V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \ + V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \ + V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \ + V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \ + V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \ + V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \ + V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \ + V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \ + V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \ + V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \ + V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \ + V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \ + V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \ + V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \ + V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \ + V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \ + V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \ + V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \ + V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \ + V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \ + V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \ + V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \ + V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \ + V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \ + V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \ + V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \ + V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \ + V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \ + V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \ + V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \ + V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \ + V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \ + V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \ + V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \ + V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \ + V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \ + V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \ + V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \ + V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \ + V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \ + V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \ + V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \ + V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \ + V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \ + V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \ + V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \ + V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \ + V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \ + V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \ + V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \ + V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \ + V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \ + V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \ + V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \ + V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \ + V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \ + V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \ + V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \ + V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \ + V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \ + V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \ + V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \ + V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C) + +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +#define V(a, b, c, d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + +#define V(a, b, c, d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a, b, c, d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a, b, c, d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */ + +#undef FT + +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; +#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */ + +/* + * Reverse tables + */ +#define RT \ +\ + V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \ + V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \ + V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \ + V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \ + V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \ + V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \ + V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \ + V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \ + V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \ + V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \ + V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \ + V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \ + V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \ + V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \ + V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \ + V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \ + V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \ + V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \ + V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \ + V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \ + V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \ + V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \ + V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \ + V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \ + V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \ + V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \ + V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \ + V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \ + V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \ + V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \ + V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \ + V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \ + V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \ + V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \ + V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \ + V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \ + V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \ + V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \ + V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \ + V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \ + V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \ + V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \ + V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \ + V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \ + V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \ + V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \ + V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \ + V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \ + V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \ + V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \ + V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \ + V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \ + V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \ + V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \ + V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \ + V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \ + V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \ + V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \ + V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \ + V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \ + V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \ + V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \ + V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \ + V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0) + +#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) + +#define V(a, b, c, d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + +#define V(a, b, c, d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a, b, c, d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a, b, c, d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + +#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */ + +#undef RT + +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; +#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */ + +#else /* MBEDTLS_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +static unsigned char FSb[256]; +#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +static uint32_t FT0[256]; +#if !defined(MBEDTLS_AES_FEWER_TABLES) +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; +#endif /* !MBEDTLS_AES_FEWER_TABLES */ +#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */ + +/* + * Reverse S-box & tables + */ +#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) +static unsigned char RSb[256]; +#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */ + +#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +static uint32_t RT0[256]; +#if !defined(MBEDTLS_AES_FEWER_TABLES) +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; +#endif /* !MBEDTLS_AES_FEWER_TABLES */ +#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */ + +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24) +#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00)) +#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0) + +static int aes_init_done = 0; + +static void aes_gen_tables(void) +{ + int i; + uint8_t x, y, z; + uint8_t pow[256]; + uint8_t log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for (i = 0, x = 1; i < 256; i++) { + pow[i] = x; + log[x] = (uint8_t) i; + x ^= XTIME(x); + } + + /* + * calculate the round constants + */ + for (i = 0, x = 1; i < 10; i++) { + RCON[i] = x; + x = XTIME(x); + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for (i = 1; i < 256; i++) { + x = pow[255 - log[i]]; + + y = x; y = (y << 1) | (y >> 7); + x ^= y; y = (y << 1) | (y >> 7); + x ^= y; y = (y << 1) | (y >> 7); + x ^= y; y = (y << 1) | (y >> 7); + x ^= y ^ 0x63; + + FSb[i] = x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for (i = 0; i < 256; i++) { + x = FSb[i]; + y = XTIME(x); + z = y ^ x; + + FT0[i] = ((uint32_t) y) ^ + ((uint32_t) x << 8) ^ + ((uint32_t) x << 16) ^ + ((uint32_t) z << 24); + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + FT1[i] = ROTL8(FT0[i]); + FT2[i] = ROTL8(FT1[i]); + FT3[i] = ROTL8(FT2[i]); +#endif /* !MBEDTLS_AES_FEWER_TABLES */ + + x = RSb[i]; + +#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) + RT0[i] = ((uint32_t) MUL(0x0E, x)) ^ + ((uint32_t) MUL(0x09, x) << 8) ^ + ((uint32_t) MUL(0x0D, x) << 16) ^ + ((uint32_t) MUL(0x0B, x) << 24); + +#if !defined(MBEDTLS_AES_FEWER_TABLES) + RT1[i] = ROTL8(RT0[i]); + RT2[i] = ROTL8(RT1[i]); + RT3[i] = ROTL8(RT2[i]); +#endif /* !MBEDTLS_AES_FEWER_TABLES */ +#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */ + } +} + +#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */ + +#undef ROTL8 + +#endif /* MBEDTLS_AES_ROM_TABLES */ + +#if defined(MBEDTLS_AES_FEWER_TABLES) + +#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24)) +#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16)) +#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8)) + +#define AES_RT0(idx) RT0[idx] +#define AES_RT1(idx) ROTL8(RT0[idx]) +#define AES_RT2(idx) ROTL16(RT0[idx]) +#define AES_RT3(idx) ROTL24(RT0[idx]) + +#define AES_FT0(idx) FT0[idx] +#define AES_FT1(idx) ROTL8(FT0[idx]) +#define AES_FT2(idx) ROTL16(FT0[idx]) +#define AES_FT3(idx) ROTL24(FT0[idx]) + +#else /* MBEDTLS_AES_FEWER_TABLES */ + +#define AES_RT0(idx) RT0[idx] +#define AES_RT1(idx) RT1[idx] +#define AES_RT2(idx) RT2[idx] +#define AES_RT3(idx) RT3[idx] + +#define AES_FT0(idx) FT0[idx] +#define AES_FT1(idx) FT1[idx] +#define AES_FT2(idx) FT2[idx] +#define AES_FT3(idx) FT3[idx] + +#endif /* MBEDTLS_AES_FEWER_TABLES */ + +void mbedtls_aes_init(mbedtls_aes_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_aes_context)); +} + +void mbedtls_aes_free(mbedtls_aes_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context)); +} + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx) +{ + mbedtls_aes_init(&ctx->crypt); + mbedtls_aes_init(&ctx->tweak); +} + +void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_aes_free(&ctx->crypt); + mbedtls_aes_free(&ctx->tweak); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/* Some implementations need the round keys to be aligned. + * Return an offset to be added to buf, such that (buf + offset) is + * correctly aligned. + * Note that the offset is in units of elements of buf, i.e. 32-bit words, + * i.e. an offset of 1 means 4 bytes and so on. + */ +#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \ + (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2) +#define MAY_NEED_TO_ALIGN +#endif + +#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +static unsigned mbedtls_aes_rk_offset(uint32_t *buf) +{ +#if defined(MAY_NEED_TO_ALIGN) + int align_16_bytes = 0; + +#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) + if (aes_padlock_ace == -1) { + aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE); + } + if (aes_padlock_ace) { + align_16_bytes = 1; + } +#endif + +#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2 + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { + align_16_bytes = 1; + } +#endif + + if (align_16_bytes) { + /* These implementations needs 16-byte alignment + * for the round key array. */ + unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4; + if (delta == 0) { + return 0; + } else { + return 4 - delta; // 16 bytes = 4 uint32_t + } + } +#else /* MAY_NEED_TO_ALIGN */ + (void) buf; +#endif /* MAY_NEED_TO_ALIGN */ + + return 0; +} +#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \ + !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */ + +/* + * AES key schedule (encryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits) +{ + uint32_t *RK; + + switch (keybits) { + case 128: ctx->nr = 10; break; +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; +#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ + default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + } + +#if !defined(MBEDTLS_AES_ROM_TABLES) + if (aes_init_done == 0) { + aes_gen_tables(); + aes_init_done = 1; + } +#endif + + ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf); + RK = ctx->buf + ctx->rk_offset; + +#if defined(MBEDTLS_AESNI_HAVE_CODE) + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { + return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits); + } +#endif + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits); + } +#endif + +#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + for (unsigned int i = 0; i < (keybits >> 5); i++) { + RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2); + } + + switch (ctx->nr) { + case 10: + + for (unsigned int i = 0; i < 10; i++, RK += 4) { + RK[4] = RK[0] ^ RCON[i] ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + case 12: + + for (unsigned int i = 0; i < 8; i++, RK += 6) { + RK[6] = RK[0] ^ RCON[i] ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for (unsigned int i = 0; i < 7; i++, RK += 8) { + RK[8] = RK[0] ^ RCON[i] ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; +#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ + } + + return 0; +#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ +} +#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ + +/* + * AES key schedule (decryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits) +{ +#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + uint32_t *SK; +#endif + int ret; + mbedtls_aes_context cty; + uint32_t *RK; + + + mbedtls_aes_init(&cty); + + ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf); + RK = ctx->buf + ctx->rk_offset; + + /* Also checks keybits */ + if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) { + goto exit; + } + + ctx->nr = cty.nr; + +#if defined(MBEDTLS_AESNI_HAVE_CODE) + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { + mbedtls_aesni_inverse_key((unsigned char *) RK, + (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr); + goto exit; + } +#endif + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + mbedtls_aesce_inverse_key( + (unsigned char *) RK, + (const unsigned char *) (cty.buf + cty.rk_offset), + ctx->nr); + goto exit; + } +#endif + +#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + SK = cty.buf + cty.rk_offset + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + SK -= 8; + for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) { + for (int j = 0; j < 4; j++, SK++) { + *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^ + AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^ + AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^ + AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]); + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; +#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */ +exit: + mbedtls_aes_free(&cty); + + return ret; +} +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int mbedtls_aes_xts_decode_keys(const unsigned char *key, + unsigned int keybits, + const unsigned char **key1, + unsigned int *key1bits, + const unsigned char **key2, + unsigned int *key2bits) +{ + const unsigned int half_keybits = keybits / 2; + const unsigned int half_keybytes = half_keybits / 8; + + switch (keybits) { + case 256: break; + case 512: break; + default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + } + + *key1bits = half_keybits; + *key2bits = half_keybits; + *key1 = &key[0]; + *key2 = &key[half_keybytes]; + + return 0; +} + +int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, + &key2, &key2bits); + if (ret != 0) { + return ret; + } + + /* Set the tweak key. Always set tweak key for the encryption mode. */ + ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); + if (ret != 0) { + return ret; + } + + /* Set crypt key for encryption. */ + return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits); +} + +int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits, + &key2, &key2bits); + if (ret != 0) { + return ret; + } + + /* Set the tweak key. Always set tweak key for encryption. */ + ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits); + if (ret != 0) { + return ret; + } + + /* Set crypt key for decryption. */ + return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \ + AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \ + AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \ + AES_FT3(MBEDTLS_BYTE_3(Y3)); \ + \ + (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \ + AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \ + AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \ + AES_FT3(MBEDTLS_BYTE_3(Y0)); \ + \ + (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \ + AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \ + AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \ + AES_FT3(MBEDTLS_BYTE_3(Y1)); \ + \ + (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \ + AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \ + AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \ + AES_FT3(MBEDTLS_BYTE_3(Y2)); \ + } while (0) + +#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \ + AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \ + AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \ + AES_RT3(MBEDTLS_BYTE_3(Y1)); \ + \ + (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \ + AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \ + AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \ + AES_RT3(MBEDTLS_BYTE_3(Y2)); \ + \ + (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \ + AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \ + AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \ + AES_RT3(MBEDTLS_BYTE_3(Y3)); \ + \ + (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \ + AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \ + AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \ + AES_RT3(MBEDTLS_BYTE_3(Y0)); \ + } while (0) + +/* + * AES-ECB block encryption + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16]) +{ + int i; + uint32_t *RK = ctx->buf + ctx->rk_offset; + struct { + uint32_t X[4]; + uint32_t Y[4]; + } t; + + t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++; + t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++; + t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++; + t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++; + + for (i = (ctx->nr >> 1) - 1; i > 0; i--) { + AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); + AES_FROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]); + } + + AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); + + t.X[0] = *RK++ ^ \ + ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24); + + t.X[1] = *RK++ ^ \ + ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24); + + t.X[2] = *RK++ ^ \ + ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24); + + t.X[3] = *RK++ ^ \ + ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^ + ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24); + + MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0); + MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4); + MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8); + MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12); + + mbedtls_platform_zeroize(&t, sizeof(t)); + + return 0; +} +#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ + +/* + * AES-ECB block decryption + */ +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16]) +{ + int i; + uint32_t *RK = ctx->buf + ctx->rk_offset; + struct { + uint32_t X[4]; + uint32_t Y[4]; + } t; + + t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++; + t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++; + t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++; + t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++; + + for (i = (ctx->nr >> 1) - 1; i > 0; i--) { + AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); + AES_RROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]); + } + + AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]); + + t.X[0] = *RK++ ^ \ + ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24); + + t.X[1] = *RK++ ^ \ + ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24); + + t.X[2] = *RK++ ^ \ + ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24); + + t.X[3] = *RK++ ^ \ + ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^ + ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24); + + MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0); + MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4); + MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8); + MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12); + + mbedtls_platform_zeroize(&t, sizeof(t)); + + return 0; +} +#endif /* !MBEDTLS_AES_DECRYPT_ALT */ + +#if defined(MAY_NEED_TO_ALIGN) +/* VIA Padlock and our intrinsics-based implementation of AESNI require + * the round keys to be aligned on a 16-byte boundary. We take care of this + * before creating them, but the AES context may have moved (this can happen + * if the library is called from a language with managed memory), and in later + * calls it might have a different alignment with respect to 16-byte memory. + * So we may need to realign. + */ +static void aes_maybe_realign(mbedtls_aes_context *ctx) +{ + unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf); + if (new_offset != ctx->rk_offset) { + memmove(ctx->buf + new_offset, // new address + ctx->buf + ctx->rk_offset, // current address + (ctx->nr + 1) * 16); // number of round keys * bytes per rk + ctx->rk_offset = new_offset; + } +} +#endif + +/* + * AES-ECB block encryption/decryption + */ +int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16]) +{ + if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + +#if defined(MAY_NEED_TO_ALIGN) + aes_maybe_realign(ctx); +#endif + +#if defined(MBEDTLS_AESNI_HAVE_CODE) + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { + return mbedtls_aesni_crypt_ecb(ctx, mode, input, output); + } +#endif + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + return mbedtls_aesce_crypt_ecb(ctx, mode, input, output); + } +#endif + +#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) + if (aes_padlock_ace > 0) { + return mbedtls_padlock_xcryptecb(ctx, mode, input, output); + } +#endif + +#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + if (mode == MBEDTLS_AES_ENCRYPT) { + return mbedtls_internal_aes_encrypt(ctx, input, output); + } else { + return mbedtls_internal_aes_decrypt(ctx, input, output); + } +#endif + +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + +/* + * AES-CBC buffer encryption/decryption + */ +int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char temp[16]; + + if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + /* Nothing to do if length is zero. */ + if (length == 0) { + return 0; + } + + if (length % 16) { + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + } + +#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) + if (aes_padlock_ace > 0) { + if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) { + return 0; + } + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + const unsigned char *ivp = iv; + + if (mode == MBEDTLS_AES_DECRYPT) { + while (length > 0) { + memcpy(temp, input, 16); + ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output); + if (ret != 0) { + goto exit; + } + /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on + * the result for the next block in CBC, and the cost of transferring that data from + * NEON registers, NEON is slower on aarch64. */ + mbedtls_xor_no_simd(output, output, iv, 16); + + memcpy(iv, temp, 16); + + input += 16; + output += 16; + length -= 16; + } + } else { + while (length > 0) { + mbedtls_xor_no_simd(output, input, ivp, 16); + + ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output); + if (ret != 0) { + goto exit; + } + ivp = output; + + input += 16; + output += 16; + length -= 16; + } + memcpy(iv, ivp, 16); + } + ret = 0; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + +typedef unsigned char mbedtls_be128[16]; + +/* + * GF(2^128) multiplication function + * + * This function multiplies a field element by x in the polynomial field + * representation. It uses 64-bit word operations to gain speed but compensates + * for machine endianness and hence works correctly on both big and little + * endian machines. + */ +#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C) +MBEDTLS_OPTIMIZE_FOR_PERFORMANCE +#endif +static inline void mbedtls_gf128mul_x_ble(unsigned char r[16], + const unsigned char x[16]) +{ + uint64_t a, b, ra, rb; + + a = MBEDTLS_GET_UINT64_LE(x, 0); + b = MBEDTLS_GET_UINT64_LE(x, 8); + + ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3)); + rb = (a >> 63) | (b << 1); + + MBEDTLS_PUT_UINT64_LE(ra, r, 0); + MBEDTLS_PUT_UINT64_LE(rb, r, 8); +} + +/* + * AES-XTS buffer encryption/decryption + * + * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble() + * is a 3x performance improvement for gcc -Os, if we have hardware AES support. + */ +#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C) +MBEDTLS_OPTIMIZE_FOR_PERFORMANCE +#endif +int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t blocks = length / 16; + size_t leftover = length % 16; + unsigned char tweak[16]; + unsigned char prev_tweak[16]; + unsigned char tmp[16]; + + if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + /* Data units must be at least 16 bytes long. */ + if (length < 16) { + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + } + + /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */ + if (length > (1 << 20) * 16) { + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + } + + /* Compute the tweak. */ + ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT, + data_unit, tweak); + if (ret != 0) { + return ret; + } + + while (blocks--) { + if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) { + /* We are on the last block in a decrypt operation that has + * leftover bytes, so we need to use the next tweak for this block, + * and this tweak for the leftover bytes. Save the current tweak for + * the leftovers and then update the current tweak for use on this, + * the last full block. */ + memcpy(prev_tweak, tweak, sizeof(tweak)); + mbedtls_gf128mul_x_ble(tweak, tweak); + } + + mbedtls_xor(tmp, input, tweak, 16); + + ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); + if (ret != 0) { + return ret; + } + + mbedtls_xor(output, tmp, tweak, 16); + + /* Update the tweak for the next block. */ + mbedtls_gf128mul_x_ble(tweak, tweak); + + output += 16; + input += 16; + } + + if (leftover) { + /* If we are on the leftover bytes in a decrypt operation, we need to + * use the previous tweak for these bytes (as saved in prev_tweak). */ + unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; + + /* We are now on the final part of the data unit, which doesn't divide + * evenly by 16. It's time for ciphertext stealing. */ + size_t i; + unsigned char *prev_output = output - 16; + + /* Copy ciphertext bytes from the previous block to our output for each + * byte of ciphertext we won't steal. */ + for (i = 0; i < leftover; i++) { + output[i] = prev_output[i]; + } + + /* Copy the remainder of the input for this final round. */ + mbedtls_xor(tmp, input, t, leftover); + + /* Copy ciphertext bytes from the previous block for input in this + * round. */ + mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i); + + ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp); + if (ret != 0) { + return ret; + } + + /* Write the result back to the previous block, overriding the previous + * output we copied. */ + mbedtls_xor(prev_output, tmp, t, 16); + } + + return 0; +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output) +{ + int c; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n; + + if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + n = *iv_off; + + if (n > 15) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + if (mode == MBEDTLS_AES_DECRYPT) { + while (length--) { + if (n == 0) { + ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); + if (ret != 0) { + goto exit; + } + } + + c = *input++; + *output++ = (unsigned char) (c ^ iv[n]); + iv[n] = (unsigned char) c; + + n = (n + 1) & 0x0F; + } + } else { + while (length--) { + if (n == 0) { + ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); + if (ret != 0) { + goto exit; + } + } + + iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++); + + n = (n + 1) & 0x0F; + } + } + + *iv_off = n; + ret = 0; + +exit: + return ret; +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char c; + unsigned char ov[17]; + + if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + while (length--) { + memcpy(ov, iv, 16); + ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); + if (ret != 0) { + goto exit; + } + + if (mode == MBEDTLS_AES_DECRYPT) { + ov[16] = *input; + } + + c = *output++ = (unsigned char) (iv[0] ^ *input++); + + if (mode == MBEDTLS_AES_ENCRYPT) { + ov[16] = c; + } + + memcpy(iv, ov + 1, 16); + } + ret = 0; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB (Output Feedback Mode) buffer encryption/decryption + */ +int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output) +{ + int ret = 0; + size_t n; + + n = *iv_off; + + if (n > 15) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + while (length--) { + if (n == 0) { + ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv); + if (ret != 0) { + goto exit; + } + } + *output++ = *input++ ^ iv[n]; + + n = (n + 1) & 0x0F; + } + + *iv_off = n; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output) +{ + int c, i; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n; + + n = *nc_off; + + if (n > 0x0F) { + return MBEDTLS_ERR_AES_BAD_INPUT_DATA; + } + + while (length--) { + if (n == 0) { + ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block); + if (ret != 0) { + goto exit; + } + + for (i = 16; i > 0; i--) { + if (++nonce_counter[i - 1] != 0) { + break; + } + } + } + c = *input++; + *output++ = (unsigned char) (c ^ stream_block[n]); + + n = (n + 1) & 0x0F; + } + + *nc_off = n; + ret = 0; + +exit: + return ret; +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +#endif +}; + +static const unsigned char aes_test_ecb_enc[][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +#endif +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +#endif +}; + +static const unsigned char aes_test_cbc_enc[][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +#endif +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +#endif +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +#endif +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB test vectors from: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + */ +static const unsigned char aes_test_ofb_key[][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +#endif +}; + +static const unsigned char aes_test_ofb_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_ofb_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_ofb_ct[][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, + 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, + 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, + 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, + 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, + 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, + 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, + 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, + 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, + 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, + 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, + 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, + 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, + 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, + 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, + 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } +#endif +}; +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = +{ 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/* + * AES-XTS test vectors from: + * + * IEEE P1619/D16 Annex B + * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf + * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) + */ +static const unsigned char aes_test_xts_key[][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, + { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, +}; + +static const unsigned char aes_test_xts_pt32[][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, +}; + +static const unsigned char aes_test_xts_ct32[][32] = +{ + { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, + 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, + 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, + 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, + { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, + 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, + 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, + 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, + { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, + 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, + 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, + 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, +}; + +static const unsigned char aes_test_xts_data_unit[][16] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +}; + +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +/* + * Checkup routine + */ +int mbedtls_aes_self_test(int verbose) +{ + int ret = 0, i, j, u, mode; + unsigned int keybits; + unsigned char key[32]; + unsigned char buf[64]; + const unsigned char *aes_tests; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ + defined(MBEDTLS_CIPHER_MODE_OFB) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ + defined(MBEDTLS_CIPHER_MODE_OFB) + size_t offset; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) + int len; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + mbedtls_aes_context ctx; + + memset(key, 0, 32); + mbedtls_aes_init(&ctx); + + if (verbose != 0) { +#if defined(MBEDTLS_AES_ALT) + mbedtls_printf(" AES note: alternative implementation.\n"); +#else /* MBEDTLS_AES_ALT */ +#if defined(MBEDTLS_AESNI_HAVE_CODE) +#if MBEDTLS_AESNI_HAVE_CODE == 1 + mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n"); +#elif MBEDTLS_AESNI_HAVE_CODE == 2 + mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n"); +#else +#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE" +#endif + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) { + mbedtls_printf(" AES note: using AESNI.\n"); + } else +#endif +#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) + if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) { + mbedtls_printf(" AES note: using VIA Padlock.\n"); + } else +#endif +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + mbedtls_printf(" AES note: using AESCE.\n"); + } else +#endif + { +#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY) + mbedtls_printf(" AES note: built-in implementation.\n"); +#endif + } +#endif /* MBEDTLS_AES_ALT */ + } + + /* + * ECB mode + */ + { + static const int num_tests = + sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec); + + for (i = 0; i < num_tests << 1; i++) { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-ECB-%3u (%s): ", keybits, + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memset(buf, 0, 16); + + if (mode == MBEDTLS_AES_DECRYPT) { + ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); + aes_tests = aes_test_ecb_dec[u]; + } else { + ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + aes_tests = aes_test_ecb_enc[u]; + } + + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { + mbedtls_printf("skipped\n"); + continue; + } else if (ret != 0) { + goto exit; + } + + for (j = 0; j < 10000; j++) { + ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf); + if (ret != 0) { + goto exit; + } + } + + if (memcmp(buf, aes_tests, 16) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + { + static const int num_tests = + sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec); + + for (i = 0; i < num_tests << 1; i++) { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-CBC-%3u (%s): ", keybits, + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memset(iv, 0, 16); + memset(prv, 0, 16); + memset(buf, 0, 16); + + if (mode == MBEDTLS_AES_DECRYPT) { + ret = mbedtls_aes_setkey_dec(&ctx, key, keybits); + aes_tests = aes_test_cbc_dec[u]; + } else { + ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + aes_tests = aes_test_cbc_enc[u]; + } + + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { + mbedtls_printf("skipped\n"); + continue; + } else if (ret != 0) { + goto exit; + } + + for (j = 0; j < 10000; j++) { + if (mode == MBEDTLS_AES_ENCRYPT) { + unsigned char tmp[16]; + + memcpy(tmp, prv, 16); + memcpy(prv, buf, 16); + memcpy(buf, tmp, 16); + } + + ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf); + if (ret != 0) { + goto exit; + } + + } + + if (memcmp(buf, aes_tests, 16) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + { + static const int num_tests = + sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key); + + for (i = 0; i < num_tests << 1; i++) { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits, + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memcpy(iv, aes_test_cfb128_iv, 16); + memcpy(key, aes_test_cfb128_key[u], keybits / 8); + + offset = 0; + ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { + mbedtls_printf("skipped\n"); + continue; + } else if (ret != 0) { + goto exit; + } + + if (mode == MBEDTLS_AES_DECRYPT) { + memcpy(buf, aes_test_cfb128_ct[u], 64); + aes_tests = aes_test_cfb128_pt; + } else { + memcpy(buf, aes_test_cfb128_pt, 64); + aes_tests = aes_test_cfb128_ct[u]; + } + + ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, aes_tests, 64) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /* + * OFB mode + */ + { + static const int num_tests = + sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key); + + for (i = 0; i < num_tests << 1; i++) { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-OFB-%3u (%s): ", keybits, + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memcpy(iv, aes_test_ofb_iv, 16); + memcpy(key, aes_test_ofb_key[u], keybits / 8); + + offset = 0; + ret = mbedtls_aes_setkey_enc(&ctx, key, keybits); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) { + mbedtls_printf("skipped\n"); + continue; + } else if (ret != 0) { + goto exit; + } + + if (mode == MBEDTLS_AES_DECRYPT) { + memcpy(buf, aes_test_ofb_ct[u], 64); + aes_tests = aes_test_ofb_pt; + } else { + memcpy(buf, aes_test_ofb_pt, 64); + aes_tests = aes_test_ofb_ct[u]; + } + + ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, aes_tests, 64) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + } +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + { + static const int num_tests = + sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key); + + for (i = 0; i < num_tests << 1; i++) { + u = i >> 1; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-CTR-128 (%s): ", + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16); + memcpy(key, aes_test_ctr_key[u], 16); + + offset = 0; + if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) { + goto exit; + } + + len = aes_test_ctr_len[u]; + + if (mode == MBEDTLS_AES_DECRYPT) { + memcpy(buf, aes_test_ctr_ct[u], len); + aes_tests = aes_test_ctr_pt[u]; + } else { + memcpy(buf, aes_test_ctr_pt[u], len); + aes_tests = aes_test_ctr_ct[u]; + } + + ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter, + stream_block, buf, buf); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, aes_tests, len) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + /* + * XTS mode + */ + { + static const int num_tests = + sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); + mbedtls_aes_xts_context ctx_xts; + + mbedtls_aes_xts_init(&ctx_xts); + + for (i = 0; i < num_tests << 1; i++) { + const unsigned char *data_unit; + u = i >> 1; + mode = i & 1; + + if (verbose != 0) { + mbedtls_printf(" AES-XTS-128 (%s): ", + (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc"); + } + + memset(key, 0, sizeof(key)); + memcpy(key, aes_test_xts_key[u], 32); + data_unit = aes_test_xts_data_unit[u]; + + len = sizeof(*aes_test_xts_ct32); + + if (mode == MBEDTLS_AES_DECRYPT) { + ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256); + if (ret != 0) { + goto exit; + } + memcpy(buf, aes_test_xts_ct32[u], len); + aes_tests = aes_test_xts_pt32[u]; + } else { + ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256); + if (ret != 0) { + goto exit; + } + memcpy(buf, aes_test_xts_pt32[u], len); + aes_tests = aes_test_xts_ct32[u]; + } + + + ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit, + buf, buf); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, aes_tests, len) != 0) { + ret = 1; + goto exit; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + mbedtls_aes_xts_free(&ctx_xts); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + + ret = 0; + +exit: + if (ret != 0 && verbose != 0) { + mbedtls_printf("failed\n"); + } + + mbedtls_aes_free(&ctx); + + return ret; +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AES_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/alignment.h b/src/app/findmy/crypto/third-party/mbedtls/library/alignment.h new file mode 100644 index 0000000..4bca10e --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/alignment.h @@ -0,0 +1,509 @@ +/** + * \file alignment.h + * + * \brief Utility code for dealing with unaligned memory accesses + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_LIBRARY_ALIGNMENT_H +#define MBEDTLS_LIBRARY_ALIGNMENT_H + +#include +#include +#include + +/* + * Define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS for architectures where unaligned memory + * accesses are known to be efficient. + * + * All functions defined here will behave correctly regardless, but might be less + * efficient when this is not defined. + */ +#if defined(__ARM_FEATURE_UNALIGNED) \ + || defined(__i386__) || defined(__amd64__) || defined(__x86_64__) +/* + * __ARM_FEATURE_UNALIGNED is defined where appropriate by armcc, gcc 7, clang 9 + * (and later versions) for Arm v7 and later; all x86 platforms should have + * efficient unaligned access. + */ +#define MBEDTLS_EFFICIENT_UNALIGNED_ACCESS +#endif + +/** + * Read the unsigned 16 bits integer from the given address, which need not + * be aligned. + * + * \param p pointer to 2 bytes of data + * \return Data at the given address + */ +inline uint16_t mbedtls_get_unaligned_uint16(const void *p) +{ + uint16_t r; + memcpy(&r, p, sizeof(r)); + return r; +} + +/** + * Write the unsigned 16 bits integer to the given address, which need not + * be aligned. + * + * \param p pointer to 2 bytes of data + * \param x data to write + */ +inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x) +{ + memcpy(p, &x, sizeof(x)); +} + +/** + * Read the unsigned 32 bits integer from the given address, which need not + * be aligned. + * + * \param p pointer to 4 bytes of data + * \return Data at the given address + */ +inline uint32_t mbedtls_get_unaligned_uint32(const void *p) +{ + uint32_t r; + memcpy(&r, p, sizeof(r)); + return r; +} + +/** + * Write the unsigned 32 bits integer to the given address, which need not + * be aligned. + * + * \param p pointer to 4 bytes of data + * \param x data to write + */ +inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x) +{ + memcpy(p, &x, sizeof(x)); +} + +/** + * Read the unsigned 64 bits integer from the given address, which need not + * be aligned. + * + * \param p pointer to 8 bytes of data + * \return Data at the given address + */ +inline uint64_t mbedtls_get_unaligned_uint64(const void *p) +{ + uint64_t r; + memcpy(&r, p, sizeof(r)); + return r; +} + +/** + * Write the unsigned 64 bits integer to the given address, which need not + * be aligned. + * + * \param p pointer to 8 bytes of data + * \param x data to write + */ +inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) +{ + memcpy(p, &x, sizeof(x)); +} + +/** Byte Reading Macros + * + * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th + * byte from x, where byte 0 is the least significant byte. + */ +#define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff)) +#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff)) +#define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff)) +#define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff)) +#define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff)) +#define MBEDTLS_BYTE_5(x) ((uint8_t) (((x) >> 40) & 0xff)) +#define MBEDTLS_BYTE_6(x) ((uint8_t) (((x) >> 48) & 0xff)) +#define MBEDTLS_BYTE_7(x) ((uint8_t) (((x) >> 56) & 0xff)) + +/* + * Detect GCC built-in byteswap routines + */ +#if defined(__GNUC__) && defined(__GNUC_PREREQ) +#if __GNUC_PREREQ(4, 8) +#define MBEDTLS_BSWAP16 __builtin_bswap16 +#endif /* __GNUC_PREREQ(4,8) */ +#if __GNUC_PREREQ(4, 3) +#define MBEDTLS_BSWAP32 __builtin_bswap32 +#define MBEDTLS_BSWAP64 __builtin_bswap64 +#endif /* __GNUC_PREREQ(4,3) */ +#endif /* defined(__GNUC__) && defined(__GNUC_PREREQ) */ + +/* + * Detect Clang built-in byteswap routines + */ +#if defined(__clang__) && defined(__has_builtin) +#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16) +#define MBEDTLS_BSWAP16 __builtin_bswap16 +#endif /* __has_builtin(__builtin_bswap16) */ +#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32) +#define MBEDTLS_BSWAP32 __builtin_bswap32 +#endif /* __has_builtin(__builtin_bswap32) */ +#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64) +#define MBEDTLS_BSWAP64 __builtin_bswap64 +#endif /* __has_builtin(__builtin_bswap64) */ +#endif /* defined(__clang__) && defined(__has_builtin) */ + +/* + * Detect MSVC built-in byteswap routines + */ +#if defined(_MSC_VER) +#if !defined(MBEDTLS_BSWAP16) +#define MBEDTLS_BSWAP16 _byteswap_ushort +#endif +#if !defined(MBEDTLS_BSWAP32) +#define MBEDTLS_BSWAP32 _byteswap_ulong +#endif +#if !defined(MBEDTLS_BSWAP64) +#define MBEDTLS_BSWAP64 _byteswap_uint64 +#endif +#endif /* defined(_MSC_VER) */ + +/* Detect armcc built-in byteswap routine */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32) +#if defined(__ARM_ACLE) /* ARM Compiler 6 - earlier versions don't need a header */ +#include +#endif +#define MBEDTLS_BSWAP32 __rev +#endif + +/* + * Where compiler built-ins are not present, fall back to C code that the + * compiler may be able to detect and transform into the relevant bswap or + * similar instruction. + */ +#if !defined(MBEDTLS_BSWAP16) +static inline uint16_t mbedtls_bswap16(uint16_t x) +{ + return + (x & 0x00ff) << 8 | + (x & 0xff00) >> 8; +} +#define MBEDTLS_BSWAP16 mbedtls_bswap16 +#endif /* !defined(MBEDTLS_BSWAP16) */ + +#if !defined(MBEDTLS_BSWAP32) +static inline uint32_t mbedtls_bswap32(uint32_t x) +{ + return + (x & 0x000000ff) << 24 | + (x & 0x0000ff00) << 8 | + (x & 0x00ff0000) >> 8 | + (x & 0xff000000) >> 24; +} +#define MBEDTLS_BSWAP32 mbedtls_bswap32 +#endif /* !defined(MBEDTLS_BSWAP32) */ + +#if !defined(MBEDTLS_BSWAP64) +static inline uint64_t mbedtls_bswap64(uint64_t x) +{ + return + (x & 0x00000000000000ffULL) << 56 | + (x & 0x000000000000ff00ULL) << 40 | + (x & 0x0000000000ff0000ULL) << 24 | + (x & 0x00000000ff000000ULL) << 8 | + (x & 0x000000ff00000000ULL) >> 8 | + (x & 0x0000ff0000000000ULL) >> 24 | + (x & 0x00ff000000000000ULL) >> 40 | + (x & 0xff00000000000000ULL) >> 56; +} +#define MBEDTLS_BSWAP64 mbedtls_bswap64 +#endif /* !defined(MBEDTLS_BSWAP64) */ + +#if !defined(__BYTE_ORDER__) +static const uint16_t mbedtls_byte_order_detector = { 0x100 }; +#define MBEDTLS_IS_BIG_ENDIAN (*((unsigned char *) (&mbedtls_byte_order_detector)) == 0x01) +#else +#define MBEDTLS_IS_BIG_ENDIAN ((__BYTE_ORDER__) == (__ORDER_BIG_ENDIAN__)) +#endif /* !defined(__BYTE_ORDER__) */ + +/** + * Get the unsigned 32 bits integer corresponding to four bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the four bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the four bytes to build the 32 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT32_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? mbedtls_get_unaligned_uint32((data) + (offset)) \ + : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ + ) + +/** + * Put in memory a 32 bits unsigned integer in big-endian order. + * + * \param n 32 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 32 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 32 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \ + } \ + } + +/** + * Get the unsigned 32 bits integer corresponding to four bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the four bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the four bytes to build the 32 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT32_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ + : mbedtls_get_unaligned_uint32((data) + (offset)) \ + ) + + +/** + * Put in memory a 32 bits unsigned integer in little-endian order. + * + * \param n 32 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 32 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 32 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \ + } \ + } + +/** + * Get the unsigned 16 bits integer corresponding to two bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the two bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the two bytes to build the 16 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT16_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ + : mbedtls_get_unaligned_uint16((data) + (offset)) \ + ) + +/** + * Put in memory a 16 bits unsigned integer in little-endian order. + * + * \param n 16 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 16 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 16 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ + } \ + } + +/** + * Get the unsigned 16 bits integer corresponding to two bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the two bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the two bytes to build the 16 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT16_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? mbedtls_get_unaligned_uint16((data) + (offset)) \ + : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ + ) + +/** + * Put in memory a 16 bits unsigned integer in big-endian order. + * + * \param n 16 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 16 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 16 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \ + } \ + } + +/** + * Get the unsigned 24 bits integer corresponding to three bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the three bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the three bytes to build the 24 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT24_BE(data, offset) \ + ( \ + ((uint32_t) (data)[(offset)] << 16) \ + | ((uint32_t) (data)[(offset) + 1] << 8) \ + | ((uint32_t) (data)[(offset) + 2]) \ + ) + +/** + * Put in memory a 24 bits unsigned integer in big-endian order. + * + * \param n 24 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 24 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 24 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT24_BE(n, data, offset) \ + { \ + (data)[(offset)] = MBEDTLS_BYTE_2(n); \ + (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ + (data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \ + } + +/** + * Get the unsigned 24 bits integer corresponding to three bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the three bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the three bytes to build the 24 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT24_LE(data, offset) \ + ( \ + ((uint32_t) (data)[(offset)]) \ + | ((uint32_t) (data)[(offset) + 1] << 8) \ + | ((uint32_t) (data)[(offset) + 2] << 16) \ + ) + +/** + * Put in memory a 24 bits unsigned integer in little-endian order. + * + * \param n 24 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 24 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 24 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT24_LE(n, data, offset) \ + { \ + (data)[(offset)] = MBEDTLS_BYTE_0(n); \ + (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ + (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \ + } + +/** + * Get the unsigned 64 bits integer corresponding to eight bytes in + * big-endian order (MSB first). + * + * \param data Base address of the memory to get the eight bytes from. + * \param offset Offset from \p data of the first and most significant + * byte of the eight bytes to build the 64 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT64_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? mbedtls_get_unaligned_uint64((data) + (offset)) \ + : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ + ) + +/** + * Put in memory a 64 bits unsigned integer in big-endian order. + * + * \param n 64 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 64 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the most significant + * byte of the 64 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \ + } \ + } + +/** + * Get the unsigned 64 bits integer corresponding to eight bytes in + * little-endian order (LSB first). + * + * \param data Base address of the memory to get the eight bytes from. + * \param offset Offset from \p data of the first and least significant + * byte of the eight bytes to build the 64 bits unsigned + * integer from. + */ +#define MBEDTLS_GET_UINT64_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ + ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ + : mbedtls_get_unaligned_uint64((data) + (offset)) \ + ) + +/** + * Put in memory a 64 bits unsigned integer in little-endian order. + * + * \param n 64 bits unsigned integer to put in memory. + * \param data Base address of the memory where to put the 64 + * bits unsigned integer in. + * \param offset Offset from \p data where to put the least significant + * byte of the 64 bits unsigned integer \p n. + */ +#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \ + { \ + if (MBEDTLS_IS_BIG_ENDIAN) \ + { \ + mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \ + } \ + else \ + { \ + mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ + } \ + } + +#endif /* MBEDTLS_LIBRARY_ALIGNMENT_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/asn1parse.c b/src/app/findmy/crypto/third-party/mbedtls/library/asn1parse.c new file mode 100644 index 0000000..c02b233 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/asn1parse.c @@ -0,0 +1,467 @@ +/* + * Generic ASN.1 parsing + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) + +#include "mbedtls/asn1.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +#include "mbedtls/platform.h" + +/* + * ASN.1 DER decoding routines + */ +int mbedtls_asn1_get_len(unsigned char **p, + const unsigned char *end, + size_t *len) +{ + if ((end - *p) < 1) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + + if ((**p & 0x80) == 0) { + *len = *(*p)++; + } else { + int n = (**p) & 0x7F; + if (n == 0 || n > 4) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + if ((end - *p) <= n) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + *len = 0; + (*p)++; + while (n--) { + *len = (*len << 8) | **p; + (*p)++; + } + } + + if (*len > (size_t) (end - *p)) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + + return 0; +} + +int mbedtls_asn1_get_tag(unsigned char **p, + const unsigned char *end, + size_t *len, int tag) +{ + if ((end - *p) < 1) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + + if (**p != tag) { + return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; + } + + (*p)++; + + return mbedtls_asn1_get_len(p, end, len); +} +#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */ + +#if defined(MBEDTLS_ASN1_PARSE_C) +int mbedtls_asn1_get_bool(unsigned char **p, + const unsigned char *end, + int *val) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) { + return ret; + } + + if (len != 1) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + + *val = (**p != 0) ? 1 : 0; + (*p)++; + + return 0; +} + +static int asn1_get_tagged_int(unsigned char **p, + const unsigned char *end, + int tag, int *val) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) { + return ret; + } + + /* + * len==0 is malformed (0 must be represented as 020100 for INTEGER, + * or 0A0100 for ENUMERATED tags + */ + if (len == 0) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + /* This is a cryptography library. Reject negative integers. */ + if ((**p & 0x80) != 0) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + + /* Skip leading zeros. */ + while (len > 0 && **p == 0) { + ++(*p); + --len; + } + + /* Reject integers that don't fit in an int. This code assumes that + * the int type has no padding bit. */ + if (len > sizeof(int)) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + if (len == sizeof(int) && (**p & 0x80) != 0) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + + *val = 0; + while (len-- > 0) { + *val = (*val << 8) | **p; + (*p)++; + } + + return 0; +} + +int mbedtls_asn1_get_int(unsigned char **p, + const unsigned char *end, + int *val) +{ + return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val); +} + +int mbedtls_asn1_get_enum(unsigned char **p, + const unsigned char *end, + int *val) +{ + return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val); +} + +#if defined(MBEDTLS_BIGNUM_C) +int mbedtls_asn1_get_mpi(unsigned char **p, + const unsigned char *end, + mbedtls_mpi *X) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) { + return ret; + } + + ret = mbedtls_mpi_read_binary(X, *p, len); + + *p += len; + + return ret; +} +#endif /* MBEDTLS_BIGNUM_C */ + +int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, + mbedtls_asn1_bitstring *bs) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* Certificate type is a single byte bitstring */ + if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) { + return ret; + } + + /* Check length, subtract one for actual bit string length */ + if (bs->len < 1) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + bs->len -= 1; + + /* Get number of unused bits, ensure unused bits <= 7 */ + bs->unused_bits = **p; + if (bs->unused_bits > 7) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } + (*p)++; + + /* Get actual bitstring */ + bs->p = *p; + *p += bs->len; + + if (*p != end) { + return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + } + + return 0; +} + +/* + * Traverse an ASN.1 "SEQUENCE OF " + * and call a callback for each entry found. + */ +int mbedtls_asn1_traverse_sequence_of( + unsigned char **p, + const unsigned char *end, + unsigned char tag_must_mask, unsigned char tag_must_val, + unsigned char tag_may_mask, unsigned char tag_may_val, + int (*cb)(void *ctx, int tag, + unsigned char *start, size_t len), + void *ctx) +{ + int ret; + size_t len; + + /* Get main sequence tag */ + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return ret; + } + + if (*p + len != end) { + return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + } + + while (*p < end) { + unsigned char const tag = *(*p)++; + + if ((tag & tag_must_mask) != tag_must_val) { + return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; + } + + if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) { + return ret; + } + + if ((tag & tag_may_mask) == tag_may_val) { + if (cb != NULL) { + ret = cb(ctx, tag, *p, len); + if (ret != 0) { + return ret; + } + } + } + + *p += len; + } + + return 0; +} + +/* + * Get a bit string without unused bits + */ +int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, + size_t *len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) { + return ret; + } + + if (*len == 0) { + return MBEDTLS_ERR_ASN1_INVALID_DATA; + } + --(*len); + + if (**p != 0) { + return MBEDTLS_ERR_ASN1_INVALID_DATA; + } + ++(*p); + + return 0; +} + +void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq) +{ + while (seq != NULL) { + mbedtls_asn1_sequence *next = seq->next; + mbedtls_free(seq); + seq = next; + } +} + +typedef struct { + int tag; + mbedtls_asn1_sequence *cur; +} asn1_get_sequence_of_cb_ctx_t; + +static int asn1_get_sequence_of_cb(void *ctx, + int tag, + unsigned char *start, + size_t len) +{ + asn1_get_sequence_of_cb_ctx_t *cb_ctx = + (asn1_get_sequence_of_cb_ctx_t *) ctx; + mbedtls_asn1_sequence *cur = + cb_ctx->cur; + + if (cur->buf.p != NULL) { + cur->next = + mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence)); + + if (cur->next == NULL) { + return MBEDTLS_ERR_ASN1_ALLOC_FAILED; + } + + cur = cur->next; + } + + cur->buf.p = start; + cur->buf.len = len; + cur->buf.tag = tag; + + cb_ctx->cur = cur; + return 0; +} + +/* + * Parses and splits an ASN.1 "SEQUENCE OF " + */ +int mbedtls_asn1_get_sequence_of(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_sequence *cur, + int tag) +{ + asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; + memset(cur, 0, sizeof(mbedtls_asn1_sequence)); + return mbedtls_asn1_traverse_sequence_of( + p, end, 0xFF, tag, 0, 0, + asn1_get_sequence_of_cb, &cb_ctx); +} + +int mbedtls_asn1_get_alg(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + return ret; + } + + if ((end - *p) < 1) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + + alg->tag = **p; + end = *p + len; + + if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) { + return ret; + } + + alg->p = *p; + *p += alg->len; + + if (*p == end) { + mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf)); + return 0; + } + + params->tag = **p; + (*p)++; + + if ((ret = mbedtls_asn1_get_len(p, end, ¶ms->len)) != 0) { + return ret; + } + + params->p = *p; + *p += params->len; + + if (*p != end) { + return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + } + + return 0; +} + +int mbedtls_asn1_get_alg_null(unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_asn1_buf params; + + memset(¶ms, 0, sizeof(mbedtls_asn1_buf)); + + if ((ret = mbedtls_asn1_get_alg(p, end, alg, ¶ms)) != 0) { + return ret; + } + + if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) { + return MBEDTLS_ERR_ASN1_INVALID_DATA; + } + + return 0; +} + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur) +{ + if (cur == NULL) { + return; + } + + mbedtls_free(cur->oid.p); + mbedtls_free(cur->val.p); + + mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data)); +} +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head) +{ + mbedtls_asn1_named_data *cur; + + while ((cur = *head) != NULL) { + *head = cur->next; + mbedtls_free(cur->oid.p); + mbedtls_free(cur->val.p); + mbedtls_free(cur); + } +} + +void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name) +{ + for (mbedtls_asn1_named_data *next; name != NULL; name = next) { + next = name->next; + mbedtls_free(name); + } +} + +const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list, + const char *oid, size_t len) +{ + while (list != NULL) { + if (list->oid.len == len && + memcmp(list->oid.p, oid, len) == 0) { + break; + } + + list = list->next; + } + + return list; +} + +#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/asn1write.c b/src/app/findmy/crypto/third-party/mbedtls/library/asn1write.c new file mode 100644 index 0000000..114091d --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/asn1write.c @@ -0,0 +1,436 @@ +/* + * ASN.1 buffer writing functionality + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) + +#include "mbedtls/asn1write.h" +#include "mbedtls/error.h" + +#include + +#include "mbedtls/platform.h" + +#if defined(MBEDTLS_ASN1_PARSE_C) +#include "mbedtls/asn1.h" +#endif + +int mbedtls_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len) +{ +#if SIZE_MAX > 0xFFFFFFFF + if (len > 0xFFFFFFFF) { + return MBEDTLS_ERR_ASN1_INVALID_LENGTH; + } +#endif + + int required = 1; + + if (len >= 0x80) { + for (size_t l = len; l != 0; l >>= 8) { + required++; + } + } + + if (required > (*p - start)) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + do { + *--(*p) = MBEDTLS_BYTE_0(len); + len >>= 8; + } while (len); + + if (required > 1) { + *--(*p) = (unsigned char) (0x80 + required - 1); + } + + return required; +} + +int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start, unsigned char tag) +{ + if (*p - start < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + *--(*p) = tag; + + return 1; +} +#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */ + +#if defined(MBEDTLS_ASN1_WRITE_C) +static int mbedtls_asn1_write_len_and_tag(unsigned char **p, + const unsigned char *start, + size_t len, + unsigned char tag) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, tag)); + + return (int) len; +} + +int mbedtls_asn1_write_raw_buffer(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t size) +{ + size_t len = 0; + + if (*p < start || (size_t) (*p - start) < size) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + len = size; + (*p) -= len; + memcpy(*p, buf, len); + + return (int) len; +} + +#if defined(MBEDTLS_BIGNUM_C) +int mbedtls_asn1_write_mpi(unsigned char **p, const unsigned char *start, const mbedtls_mpi *X) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + // Write the MPI + // + len = mbedtls_mpi_size(X); + + /* DER represents 0 with a sign bit (0=nonnegative) and 7 value bits, not + * as 0 digits. We need to end up with 020100, not with 0200. */ + if (len == 0) { + len = 1; + } + + if (*p < start || (size_t) (*p - start) < len) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + (*p) -= len; + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(X, *p, len)); + + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if (X->s == 1 && **p & 0x80) { + if (*p - start < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + *--(*p) = 0x00; + len += 1; + } + + ret = mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_INTEGER); + +cleanup: + return ret; +} +#endif /* MBEDTLS_BIGNUM_C */ + +int mbedtls_asn1_write_null(unsigned char **p, const unsigned char *start) +{ + // Write NULL + // + return mbedtls_asn1_write_len_and_tag(p, start, 0, MBEDTLS_ASN1_NULL); +} + +int mbedtls_asn1_write_oid(unsigned char **p, const unsigned char *start, + const char *oid, size_t oid_len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, + (const unsigned char *) oid, oid_len)); + return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OID); +} + +int mbedtls_asn1_write_algorithm_identifier(unsigned char **p, const unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len) +{ + return mbedtls_asn1_write_algorithm_identifier_ext(p, start, oid, oid_len, par_len, 1); +} + +int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p, const unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len, int has_par) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + if (has_par) { + if (par_len == 0) { + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_null(p, start)); + } else { + len += par_len; + } + } + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(p, start, oid, oid_len)); + + return mbedtls_asn1_write_len_and_tag(p, start, len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); +} + +int mbedtls_asn1_write_bool(unsigned char **p, const unsigned char *start, int boolean) +{ + size_t len = 0; + + if (*p - start < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + *--(*p) = (boolean) ? 255 : 0; + len++; + + return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BOOLEAN); +} + +static int asn1_write_tagged_int(unsigned char **p, const unsigned char *start, int val, int tag) +{ + size_t len = 0; + + do { + if (*p - start < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + len += 1; + *--(*p) = val & 0xff; + val >>= 8; + } while (val > 0); + + if (**p & 0x80) { + if (*p - start < 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + *--(*p) = 0x00; + len += 1; + } + + return mbedtls_asn1_write_len_and_tag(p, start, len, tag); +} + +int mbedtls_asn1_write_int(unsigned char **p, const unsigned char *start, int val) +{ + return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_INTEGER); +} + +int mbedtls_asn1_write_enum(unsigned char **p, const unsigned char *start, int val) +{ + return asn1_write_tagged_int(p, start, val, MBEDTLS_ASN1_ENUMERATED); +} + +int mbedtls_asn1_write_tagged_string(unsigned char **p, const unsigned char *start, int tag, + const char *text, size_t text_len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, + (const unsigned char *) text, + text_len)); + + return mbedtls_asn1_write_len_and_tag(p, start, len, tag); +} + +int mbedtls_asn1_write_utf8_string(unsigned char **p, const unsigned char *start, + const char *text, size_t text_len) +{ + return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_UTF8_STRING, text, text_len); +} + +int mbedtls_asn1_write_printable_string(unsigned char **p, const unsigned char *start, + const char *text, size_t text_len) +{ + return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_PRINTABLE_STRING, text, + text_len); +} + +int mbedtls_asn1_write_ia5_string(unsigned char **p, const unsigned char *start, + const char *text, size_t text_len) +{ + return mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len); +} + +int mbedtls_asn1_write_named_bitstring(unsigned char **p, + const unsigned char *start, + const unsigned char *buf, + size_t bits) +{ + size_t unused_bits, byte_len; + const unsigned char *cur_byte; + unsigned char cur_byte_shifted; + unsigned char bit; + + byte_len = (bits + 7) / 8; + unused_bits = (byte_len * 8) - bits; + + /* + * Named bitstrings require that trailing 0s are excluded in the encoding + * of the bitstring. Trailing 0s are considered part of the 'unused' bits + * when encoding this value in the first content octet + */ + if (bits != 0) { + cur_byte = buf + byte_len - 1; + cur_byte_shifted = *cur_byte >> unused_bits; + + for (;;) { + bit = cur_byte_shifted & 0x1; + cur_byte_shifted >>= 1; + + if (bit != 0) { + break; + } + + bits--; + if (bits == 0) { + break; + } + + if (bits % 8 == 0) { + cur_byte_shifted = *--cur_byte; + } + } + } + + return mbedtls_asn1_write_bitstring(p, start, buf, bits); +} + +int mbedtls_asn1_write_bitstring(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t bits) +{ + size_t len = 0; + size_t unused_bits, byte_len; + + byte_len = (bits + 7) / 8; + unused_bits = (byte_len * 8) - bits; + + if (*p < start || (size_t) (*p - start) < byte_len + 1) { + return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL; + } + + len = byte_len + 1; + + /* Write the bitstring. Ensure the unused bits are zeroed */ + if (byte_len > 0) { + byte_len--; + *--(*p) = buf[byte_len] & ~((0x1 << unused_bits) - 1); + (*p) -= byte_len; + memcpy(*p, buf, byte_len); + } + + /* Write unused bits */ + *--(*p) = (unsigned char) unused_bits; + + return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_BIT_STRING); +} + +int mbedtls_asn1_write_octet_string(unsigned char **p, const unsigned char *start, + const unsigned char *buf, size_t size) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, buf, size)); + + return mbedtls_asn1_write_len_and_tag(p, start, len, MBEDTLS_ASN1_OCTET_STRING); +} + + +#if !defined(MBEDTLS_ASN1_PARSE_C) +/* This is a copy of the ASN.1 parsing function mbedtls_asn1_find_named_data(), + * which is replicated to avoid a dependency ASN1_WRITE_C on ASN1_PARSE_C. */ +static mbedtls_asn1_named_data *asn1_find_named_data( + mbedtls_asn1_named_data *list, + const char *oid, size_t len) +{ + while (list != NULL) { + if (list->oid.len == len && + memcmp(list->oid.p, oid, len) == 0) { + break; + } + + list = list->next; + } + + return list; +} +#else +#define asn1_find_named_data(list, oid, len) \ + ((mbedtls_asn1_named_data *) mbedtls_asn1_find_named_data(list, oid, len)) +#endif + +mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( + mbedtls_asn1_named_data **head, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len) +{ + mbedtls_asn1_named_data *cur; + + if ((cur = asn1_find_named_data(*head, oid, oid_len)) == NULL) { + // Add new entry if not present yet based on OID + // + cur = (mbedtls_asn1_named_data *) mbedtls_calloc(1, + sizeof(mbedtls_asn1_named_data)); + if (cur == NULL) { + return NULL; + } + + cur->oid.len = oid_len; + cur->oid.p = mbedtls_calloc(1, oid_len); + if (cur->oid.p == NULL) { + mbedtls_free(cur); + return NULL; + } + + memcpy(cur->oid.p, oid, oid_len); + + cur->val.len = val_len; + if (val_len != 0) { + cur->val.p = mbedtls_calloc(1, val_len); + if (cur->val.p == NULL) { + mbedtls_free(cur->oid.p); + mbedtls_free(cur); + return NULL; + } + } + + cur->next = *head; + *head = cur; + } else if (val_len == 0) { + mbedtls_free(cur->val.p); + cur->val.p = NULL; + } else if (cur->val.len != val_len) { + /* + * Enlarge existing value buffer if needed + * Preserve old data until the allocation succeeded, to leave list in + * a consistent state in case allocation fails. + */ + void *p = mbedtls_calloc(1, val_len); + if (p == NULL) { + return NULL; + } + + mbedtls_free(cur->val.p); + cur->val.p = p; + cur->val.len = val_len; + } + + if (val != NULL && val_len != 0) { + memcpy(cur->val.p, val, val_len); + } + + return cur; +} +#endif /* MBEDTLS_ASN1_WRITE_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/base64.c b/src/app/findmy/crypto/third-party/mbedtls/library/base64.c new file mode 100644 index 0000000..1de5753 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/base64.c @@ -0,0 +1,300 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include + +#include "common.h" + +#if defined(MBEDTLS_BASE64_C) + +#include "mbedtls/base64.h" +#include "base64_internal.h" +#include "constant_time_internal.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#include +#include "mbedtls/platform.h" +#endif /* MBEDTLS_SELF_TEST */ + +MBEDTLS_STATIC_TESTABLE +unsigned char mbedtls_ct_base64_enc_char(unsigned char value) +{ + unsigned char digit = 0; + /* For each range of values, if value is in that range, mask digit with + * the corresponding value. Since value can only be in a single range, + * only at most one masking will change digit. */ + digit |= mbedtls_ct_uchar_in_range_if(0, 25, value, 'A' + value); + digit |= mbedtls_ct_uchar_in_range_if(26, 51, value, 'a' + value - 26); + digit |= mbedtls_ct_uchar_in_range_if(52, 61, value, '0' + value - 52); + digit |= mbedtls_ct_uchar_in_range_if(62, 62, value, '+'); + digit |= mbedtls_ct_uchar_in_range_if(63, 63, value, '/'); + return digit; +} + +MBEDTLS_STATIC_TESTABLE +signed char mbedtls_ct_base64_dec_value(unsigned char c) +{ + unsigned char val = 0; + /* For each range of digits, if c is in that range, mask val with + * the corresponding value. Since c can only be in a single range, + * only at most one masking will change val. Set val to one plus + * the desired value so that it stays 0 if c is in none of the ranges. */ + val |= mbedtls_ct_uchar_in_range_if('A', 'Z', c, c - 'A' + 0 + 1); + val |= mbedtls_ct_uchar_in_range_if('a', 'z', c, c - 'a' + 26 + 1); + val |= mbedtls_ct_uchar_in_range_if('0', '9', c, c - '0' + 52 + 1); + val |= mbedtls_ct_uchar_in_range_if('+', '+', c, c - '+' + 62 + 1); + val |= mbedtls_ct_uchar_in_range_if('/', '/', c, c - '/' + 63 + 1); + /* At this point, val is 0 if c is an invalid digit and v+1 if c is + * a digit with the value v. */ + return val - 1; +} + +/* + * Encode a buffer into base64 format + */ +int mbedtls_base64_encode(unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen) +{ + size_t i, n; + int C1, C2, C3; + unsigned char *p; + + if (slen == 0) { + *olen = 0; + return 0; + } + + n = slen / 3 + (slen % 3 != 0); + + if (n > (SIZE_MAX - 1) / 4) { + *olen = SIZE_MAX; + return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; + } + + n *= 4; + + if ((dlen < n + 1) || (NULL == dst)) { + *olen = n + 1; + return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; + } + + n = (slen / 3) * 3; + + for (i = 0, p = dst; i < n; i += 3) { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F); + *p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4)) + & 0x3F); + *p++ = mbedtls_ct_base64_enc_char((((C2 & 15) << 2) + (C3 >> 6)) + & 0x3F); + *p++ = mbedtls_ct_base64_enc_char(C3 & 0x3F); + } + + if (i < slen) { + C1 = *src++; + C2 = ((i + 1) < slen) ? *src++ : 0; + + *p++ = mbedtls_ct_base64_enc_char((C1 >> 2) & 0x3F); + *p++ = mbedtls_ct_base64_enc_char((((C1 & 3) << 4) + (C2 >> 4)) + + & 0x3F); + + if ((i + 1) < slen) { + *p++ = mbedtls_ct_base64_enc_char(((C2 & 15) << 2) & 0x3F); + } else { + *p++ = '='; + } + + *p++ = '='; + } + + *olen = p - dst; + *p = 0; + + return 0; +} + +/* + * Decode a base64-formatted buffer + */ +int mbedtls_base64_decode(unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen) +{ + size_t i; /* index in source */ + size_t n; /* number of digits or trailing = in source */ + uint32_t x; /* value accumulator */ + unsigned accumulated_digits = 0; + unsigned equals = 0; + int spaces_present = 0; + unsigned char *p; + + /* First pass: check for validity and get output length */ + for (i = n = 0; i < slen; i++) { + /* Skip spaces before checking for EOL */ + spaces_present = 0; + while (i < slen && src[i] == ' ') { + ++i; + spaces_present = 1; + } + + /* Spaces at end of buffer are OK */ + if (i == slen) { + break; + } + + if ((slen - i) >= 2 && + src[i] == '\r' && src[i + 1] == '\n') { + continue; + } + + if (src[i] == '\n') { + continue; + } + + /* Space inside a line is an error */ + if (spaces_present) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + + if (src[i] > 127) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + + if (src[i] == '=') { + if (++equals > 2) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + } else { + if (equals != 0) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + if (mbedtls_ct_base64_dec_value(src[i]) < 0) { + return MBEDTLS_ERR_BASE64_INVALID_CHARACTER; + } + } + n++; + } + + if (n == 0) { + *olen = 0; + return 0; + } + + /* The following expression is to calculate the following formula without + * risk of integer overflow in n: + * n = ( ( n * 6 ) + 7 ) >> 3; + */ + n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3); + n -= equals; + + if (dst == NULL || dlen < n) { + *olen = n; + return MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL; + } + + equals = 0; + for (x = 0, p = dst; i > 0; i--, src++) { + if (*src == '\r' || *src == '\n' || *src == ' ') { + continue; + } + + x = x << 6; + if (*src == '=') { + ++equals; + } else { + x |= mbedtls_ct_base64_dec_value(*src); + } + + if (++accumulated_digits == 4) { + accumulated_digits = 0; + *p++ = MBEDTLS_BYTE_2(x); + if (equals <= 1) { + *p++ = MBEDTLS_BYTE_1(x); + } + if (equals <= 0) { + *p++ = MBEDTLS_BYTE_0(x); + } + } + } + + *olen = p - dst; + + return 0; +} + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int mbedtls_base64_self_test(int verbose) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if (verbose != 0) { + mbedtls_printf(" Base64 encoding test: "); + } + + src = base64_test_dec; + + if (mbedtls_base64_encode(buffer, sizeof(buffer), &len, src, 64) != 0 || + memcmp(base64_test_enc, buffer, 88) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + return 1; + } + + if (verbose != 0) { + mbedtls_printf("passed\n Base64 decoding test: "); + } + + src = base64_test_enc; + + if (mbedtls_base64_decode(buffer, sizeof(buffer), &len, src, 88) != 0 || + memcmp(base64_test_dec, buffer, 64) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + return 1; + } + + if (verbose != 0) { + mbedtls_printf("passed\n\n"); + } + + return 0; +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_BASE64_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/base64_internal.h b/src/app/findmy/crypto/third-party/mbedtls/library/base64_internal.h new file mode 100644 index 0000000..a09bd23 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/base64_internal.h @@ -0,0 +1,45 @@ +/** + * \file base64_internal.h + * + * \brief RFC 1521 base64 encoding/decoding: interfaces for invasive testing + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_BASE64_INTERNAL +#define MBEDTLS_BASE64_INTERNAL + +#include "common.h" + +#if defined(MBEDTLS_TEST_HOOKS) + +/** Given a value in the range 0..63, return the corresponding Base64 digit. + * + * The implementation assumes that letters are consecutive (e.g. ASCII + * but not EBCDIC). + * + * \param value A value in the range 0..63. + * + * \return A base64 digit converted from \p value. + */ +unsigned char mbedtls_ct_base64_enc_char(unsigned char value); + +/** Given a Base64 digit, return its value. + * + * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'), + * return -1. + * + * The implementation assumes that letters are consecutive (e.g. ASCII + * but not EBCDIC). + * + * \param c A base64 digit. + * + * \return The value of the base64 digit \p c. + */ +signed char mbedtls_ct_base64_dec_value(unsigned char c); + +#endif /* MBEDTLS_TEST_HOOKS */ + +#endif /* MBEDTLS_BASE64_INTERNAL */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/bignum.c b/src/app/findmy/crypto/third-party/mbedtls/library/bignum.c new file mode 100644 index 0000000..09ce030 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/bignum.c @@ -0,0 +1,2806 @@ +/* + * Multi-precision integer library + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * The following sources were referenced in the design of this Multi-precision + * Integer library: + * + * [1] Handbook of Applied Cryptography - 1997 + * Menezes, van Oorschot and Vanstone + * + * [2] Multi-Precision Math + * Tom St Denis + * https://github.com/libtom/libtommath/blob/develop/tommath.pdf + * + * [3] GNU Multi-Precision Arithmetic Library + * https://gmplib.org/manual/index.html + * + */ + +#include "common.h" + +#if defined(MBEDTLS_BIGNUM_C) + +#include "mbedtls/bignum.h" +#include "bignum_core.h" +#include "bn_mul.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" +#include "constant_time_internal.h" + +#include +#include + +#include "mbedtls/platform.h" + +#define MPI_VALIDATE_RET(cond) \ + MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA) +#define MPI_VALIDATE(cond) \ + MBEDTLS_INTERNAL_VALIDATE(cond) + +/* + * Compare signed values in constant time + */ +int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, + const mbedtls_mpi *Y, + unsigned *ret) +{ + mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result; + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + MPI_VALIDATE_RET(ret != NULL); + + if (X->n != Y->n) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + /* + * Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0. + * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0. + */ + X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1); + Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1); + + /* + * If the signs are different, then the positive operand is the bigger. + * That is if X is negative (X_is_negative == 1), then X < Y is true and it + * is false if X is positive (X_is_negative == 0). + */ + different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign + result = mbedtls_ct_bool_and(different_sign, X_is_negative); + + /* + * Assuming signs are the same, compare X and Y. We switch the comparison + * order if they are negative so that we get the right result, regardles of + * sign. + */ + + /* This array is used to conditionally swap the pointers in const time */ + void * const p[2] = { X->p, Y->p }; + size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1); + mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n); + + /* + * Store in result iff the signs are the same (i.e., iff different_sign == false). If + * the signs differ, result has already been set, so we don't change it. + */ + result = mbedtls_ct_bool_or(result, + mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt)); + + *ret = mbedtls_ct_uint_if_else_0(result, 1); + + return 0; +} + +/* + * Conditionally assign X = Y, without leaking information + * about whether the assignment was made or not. + * (Leaking information about the respective sizes of X and Y is ok however.) + */ +#if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103) +/* + * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See: + * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989 + */ +__declspec(noinline) +#endif +int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, + const mbedtls_mpi *Y, + unsigned char assign) +{ + int ret = 0; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n)); + + { + mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign); + + X->s = (int) mbedtls_ct_uint_if(do_assign, Y->s, X->s); + + mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign); + + mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign); + for (size_t i = Y->n; i < X->n; i++) { + X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]); + } + } + +cleanup: + return ret; +} + +/* + * Conditionally swap X and Y, without leaking information + * about whether the swap was made or not. + * Here it is not ok to simply swap the pointers, which would lead to + * different memory access patterns when X and Y are used afterwards. + */ +int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, + mbedtls_mpi *Y, + unsigned char swap) +{ + int ret = 0; + int s; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + + if (X == Y) { + return 0; + } + + mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n)); + + s = X->s; + X->s = (int) mbedtls_ct_uint_if(do_swap, Y->s, X->s); + Y->s = (int) mbedtls_ct_uint_if(do_swap, s, Y->s); + + mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap); + +cleanup: + return ret; +} + +/* Implementation that should never be optimized out by the compiler */ +#define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n)) + +/* + * Initialize one MPI + */ +void mbedtls_mpi_init(mbedtls_mpi *X) +{ + MPI_VALIDATE(X != NULL); + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +void mbedtls_mpi_free(mbedtls_mpi *X) +{ + if (X == NULL) { + return; + } + + if (X->p != NULL) { + mbedtls_mpi_zeroize_and_free(X->p, X->n); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs) +{ + mbedtls_mpi_uint *p; + MPI_VALIDATE_RET(X != NULL); + + if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) { + return MBEDTLS_ERR_MPI_ALLOC_FAILED; + } + + if (X->n < nblimbs) { + if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) { + return MBEDTLS_ERR_MPI_ALLOC_FAILED; + } + + if (X->p != NULL) { + memcpy(p, X->p, X->n * ciL); + mbedtls_mpi_zeroize_and_free(X->p, X->n); + } + + /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS + * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ + X->n = (unsigned short) nblimbs; + X->p = p; + } + + return 0; +} + +/* + * Resize down as much as possible, + * while keeping at least the specified number of limbs + */ +int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs) +{ + mbedtls_mpi_uint *p; + size_t i; + MPI_VALIDATE_RET(X != NULL); + + if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) { + return MBEDTLS_ERR_MPI_ALLOC_FAILED; + } + + /* Actually resize up if there are currently fewer than nblimbs limbs. */ + if (X->n <= nblimbs) { + return mbedtls_mpi_grow(X, nblimbs); + } + /* After this point, then X->n > nblimbs and in particular X->n > 0. */ + + for (i = X->n - 1; i > 0; i--) { + if (X->p[i] != 0) { + break; + } + } + i++; + + if (i < nblimbs) { + i = nblimbs; + } + + if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) { + return MBEDTLS_ERR_MPI_ALLOC_FAILED; + } + + if (X->p != NULL) { + memcpy(p, X->p, i * ciL); + mbedtls_mpi_zeroize_and_free(X->p, X->n); + } + + /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS + * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ + X->n = (unsigned short) i; + X->p = p; + + return 0; +} + +/* Resize X to have exactly n limbs and set it to 0. */ +static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs) +{ + if (limbs == 0) { + mbedtls_mpi_free(X); + return 0; + } else if (X->n == limbs) { + memset(X->p, 0, limbs * ciL); + X->s = 1; + return 0; + } else { + mbedtls_mpi_free(X); + return mbedtls_mpi_grow(X, limbs); + } +} + +/* + * Copy the contents of Y into X. + * + * This function is not constant-time. Leading zeros in Y may be removed. + * + * Ensure that X does not shrink. This is not guaranteed by the public API, + * but some code in the bignum module relies on this property, for example + * in mbedtls_mpi_exp_mod(). + */ +int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y) +{ + int ret = 0; + size_t i; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + + if (X == Y) { + return 0; + } + + if (Y->n == 0) { + if (X->n != 0) { + X->s = 1; + memset(X->p, 0, X->n * ciL); + } + return 0; + } + + for (i = Y->n - 1; i > 0; i--) { + if (Y->p[i] != 0) { + break; + } + } + i++; + + X->s = Y->s; + + if (X->n < i) { + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i)); + } else { + memset(X->p + i, 0, (X->n - i) * ciL); + } + + memcpy(X->p, Y->p, i * ciL); + +cleanup: + + return ret; +} + +/* + * Swap the contents of X and Y + */ +void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y) +{ + mbedtls_mpi T; + MPI_VALIDATE(X != NULL); + MPI_VALIDATE(Y != NULL); + + memcpy(&T, X, sizeof(mbedtls_mpi)); + memcpy(X, Y, sizeof(mbedtls_mpi)); + memcpy(Y, &T, sizeof(mbedtls_mpi)); +} + +static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z) +{ + if (z >= 0) { + return z; + } + /* Take care to handle the most negative value (-2^(biL-1)) correctly. + * A naive -z would have undefined behavior. + * Write this in a way that makes popular compilers happy (GCC, Clang, + * MSVC). */ + return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z; +} + +/* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative. + * This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */ +#define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1) + +/* + * Set value from integer + */ +int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MPI_VALIDATE_RET(X != NULL); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1)); + memset(X->p, 0, X->n * ciL); + + X->p[0] = mpi_sint_abs(z); + X->s = TO_SIGN(z); + +cleanup: + + return ret; +} + +/* + * Get a specific bit + */ +int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos) +{ + MPI_VALIDATE_RET(X != NULL); + + if (X->n * biL <= pos) { + return 0; + } + + return (X->p[pos / biL] >> (pos % biL)) & 0x01; +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + MPI_VALIDATE_RET(X != NULL); + + if (val != 0 && val != 1) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + if (X->n * biL <= pos) { + if (val == 0) { + return 0; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1)); + } + + X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx); + X->p[off] |= (mbedtls_mpi_uint) val << idx; + +cleanup: + + return ret; +} + +/* + * Return the number of less significant zero-bits + */ +size_t mbedtls_mpi_lsb(const mbedtls_mpi *X) +{ + size_t i; + MBEDTLS_INTERNAL_VALIDATE_RET(X != NULL, 0); + +#if defined(__has_builtin) +#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz) + #define mbedtls_mpi_uint_ctz __builtin_ctz +#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl) + #define mbedtls_mpi_uint_ctz __builtin_ctzl +#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll) + #define mbedtls_mpi_uint_ctz __builtin_ctzll +#endif +#endif + +#if defined(mbedtls_mpi_uint_ctz) + for (i = 0; i < X->n; i++) { + if (X->p[i] != 0) { + return i * biL + mbedtls_mpi_uint_ctz(X->p[i]); + } + } +#else + size_t count = 0; + for (i = 0; i < X->n; i++) { + for (size_t j = 0; j < biL; j++, count++) { + if (((X->p[i] >> j) & 1) != 0) { + return count; + } + } + } +#endif + + return 0; +} + +/* + * Return the number of bits + */ +size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X) +{ + return mbedtls_mpi_core_bitlen(X->p, X->n); +} + +/* + * Return the total size in bytes + */ +size_t mbedtls_mpi_size(const mbedtls_mpi *X) +{ + return (mbedtls_mpi_bitlen(X) + 7) >> 3; +} + +/* + * Convert an ASCII character to digit value + */ +static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c) +{ + *d = 255; + + if (c >= 0x30 && c <= 0x39) { + *d = c - 0x30; + } + if (c >= 0x41 && c <= 0x46) { + *d = c - 0x37; + } + if (c >= 0x61 && c <= 0x66) { + *d = c - 0x57; + } + + if (*d >= (mbedtls_mpi_uint) radix) { + return MBEDTLS_ERR_MPI_INVALID_CHARACTER; + } + + return 0; +} + +/* + * Import from an ASCII string + */ +int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i, j, slen, n; + int sign = 1; + mbedtls_mpi_uint d; + mbedtls_mpi T; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(s != NULL); + + if (radix < 2 || radix > 16) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + mbedtls_mpi_init(&T); + + if (s[0] == 0) { + mbedtls_mpi_free(X); + return 0; + } + + if (s[0] == '-') { + ++s; + sign = -1; + } + + slen = strlen(s); + + if (radix == 16) { + if (slen > SIZE_MAX >> 2) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + n = BITS_TO_LIMBS(slen << 2); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); + + for (i = slen, j = 0; i > 0; i--, j++) { + MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1])); + X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2); + } + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); + + for (i = 0; i < slen; i++) { + MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i])); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d)); + } + } + + if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) { + X->s = -1; + } + +cleanup: + + mbedtls_mpi_free(&T); + + return ret; +} + +/* + * Helper to write the digits high-order first. + */ +static int mpi_write_hlp(mbedtls_mpi *X, int radix, + char **p, const size_t buflen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi_uint r; + size_t length = 0; + char *p_end = *p + buflen; + + do { + if (length >= buflen) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix)); + MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix)); + /* + * Write the residue in the current position, as an ASCII character. + */ + if (r < 0xA) { + *(--p_end) = (char) ('0' + r); + } else { + *(--p_end) = (char) ('A' + (r - 0xA)); + } + + length++; + } while (mbedtls_mpi_cmp_int(X, 0) != 0); + + memmove(*p, p_end, length); + *p += length; + +cleanup: + + return ret; +} + +/* + * Export into an ASCII string + */ +int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix, + char *buf, size_t buflen, size_t *olen) +{ + int ret = 0; + size_t n; + char *p; + mbedtls_mpi T; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(olen != NULL); + MPI_VALIDATE_RET(buflen == 0 || buf != NULL); + + if (radix < 2 || radix > 16) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */ + if (radix >= 4) { + n >>= 1; /* Number of 4-adic digits necessary to present + * `n`. If radix > 4, this might be a strict + * overapproximation of the number of + * radix-adic digits needed to present `n`. */ + } + if (radix >= 16) { + n >>= 1; /* Number of hexadecimal digits necessary to + * present `n`. */ + + } + n += 1; /* Terminating null byte */ + n += 1; /* Compensate for the divisions above, which round down `n` + * in case it's not even. */ + n += 1; /* Potential '-'-sign. */ + n += (n & 1); /* Make n even to have enough space for hexadecimal writing, + * which always uses an even number of hex-digits. */ + + if (buflen < n) { + *olen = n; + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + + p = buf; + mbedtls_mpi_init(&T); + + if (X->s == -1) { + *p++ = '-'; + buflen--; + } + + if (radix == 16) { + int c; + size_t i, j, k; + + for (i = X->n, k = 0; i > 0; i--) { + for (j = ciL; j > 0; j--) { + c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF; + + if (c == 0 && k == 0 && (i + j) != 2) { + continue; + } + + *(p++) = "0123456789ABCDEF" [c / 16]; + *(p++) = "0123456789ABCDEF" [c % 16]; + k = 1; + } + } + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X)); + + if (T.s == -1) { + T.s = 1; + } + + MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen)); + } + + *p++ = '\0'; + *olen = p - buf; + +cleanup: + + mbedtls_mpi_free(&T); + + return ret; +} + +#if defined(MBEDTLS_FS_IO) +/* + * Read X from an opened file + */ +int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin) +{ + mbedtls_mpi_uint d; + size_t slen; + char *p; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[MBEDTLS_MPI_RW_BUFFER_SIZE]; + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(fin != NULL); + + if (radix < 2 || radix > 16) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + memset(s, 0, sizeof(s)); + if (fgets(s, sizeof(s) - 1, fin) == NULL) { + return MBEDTLS_ERR_MPI_FILE_IO_ERROR; + } + + slen = strlen(s); + if (slen == sizeof(s) - 2) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + + if (slen > 0 && s[slen - 1] == '\n') { + slen--; s[slen] = '\0'; + } + if (slen > 0 && s[slen - 1] == '\r') { + slen--; s[slen] = '\0'; + } + + p = s + slen; + while (p-- > s) { + if (mpi_get_digit(&d, radix, *p) != 0) { + break; + } + } + + return mbedtls_mpi_read_string(X, radix, p + 1); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n, slen, plen; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[MBEDTLS_MPI_RW_BUFFER_SIZE]; + MPI_VALIDATE_RET(X != NULL); + + if (radix < 2 || radix > 16) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + memset(s, 0, sizeof(s)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n)); + + if (p == NULL) { + p = ""; + } + + plen = strlen(p); + slen = strlen(s); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if (fout != NULL) { + if (fwrite(p, 1, plen, fout) != plen || + fwrite(s, 1, slen, fout) != slen) { + return MBEDTLS_ERR_MPI_FILE_IO_ERROR; + } + } else { + mbedtls_printf("%s%s", p, s); + } + +cleanup: + + return ret; +} +#endif /* MBEDTLS_FS_IO */ + +/* + * Import X from unsigned binary data, little endian + * + * This function is guaranteed to return an MPI with exactly the necessary + * number of limbs (in particular, it does not skip 0s in the input). + */ +int mbedtls_mpi_read_binary_le(mbedtls_mpi *X, + const unsigned char *buf, size_t buflen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const size_t limbs = CHARS_TO_LIMBS(buflen); + + /* Ensure that target MPI has exactly the necessary number of limbs */ + MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen)); + +cleanup: + + /* + * This function is also used to import keys. However, wiping the buffers + * upon failure is not necessary because failure only can happen before any + * input is copied. + */ + return ret; +} + +/* + * Import X from unsigned binary data, big endian + * + * This function is guaranteed to return an MPI with exactly the necessary + * number of limbs (in particular, it does not skip 0s in the input). + */ +int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const size_t limbs = CHARS_TO_LIMBS(buflen); + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(buflen == 0 || buf != NULL); + + /* Ensure that target MPI has exactly the necessary number of limbs */ + MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen)); + +cleanup: + + /* + * This function is also used to import keys. However, wiping the buffers + * upon failure is not necessary because failure only can happen before any + * input is copied. + */ + return ret; +} + +/* + * Export X into unsigned binary data, little endian + */ +int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X, + unsigned char *buf, size_t buflen) +{ + return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mbedtls_mpi_write_binary(const mbedtls_mpi *X, + unsigned char *buf, size_t buflen) +{ + return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen); +} + +/* + * Left-shift: X <<= count + */ +int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + MPI_VALIDATE_RET(X != NULL); + + i = mbedtls_mpi_bitlen(X) + count; + + if (X->n * biL < i) { + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i))); + } + + ret = 0; + + mbedtls_mpi_core_shift_l(X->p, X->n, count); +cleanup: + + return ret; +} + +/* + * Right-shift: X >>= count + */ +int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count) +{ + MPI_VALIDATE_RET(X != NULL); + if (X->n != 0) { + mbedtls_mpi_core_shift_r(X->p, X->n, count); + } + return 0; +} + +/* + * Compare unsigned values + */ +int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y) +{ + size_t i, j; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + + for (i = X->n; i > 0; i--) { + if (X->p[i - 1] != 0) { + break; + } + } + + for (j = Y->n; j > 0; j--) { + if (Y->p[j - 1] != 0) { + break; + } + } + + /* If i == j == 0, i.e. abs(X) == abs(Y), + * we end up returning 0 at the end of the function. */ + + if (i > j) { + return 1; + } + if (j > i) { + return -1; + } + + for (; i > 0; i--) { + if (X->p[i - 1] > Y->p[i - 1]) { + return 1; + } + if (X->p[i - 1] < Y->p[i - 1]) { + return -1; + } + } + + return 0; +} + +/* + * Compare signed values + */ +int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y) +{ + size_t i, j; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(Y != NULL); + + for (i = X->n; i > 0; i--) { + if (X->p[i - 1] != 0) { + break; + } + } + + for (j = Y->n; j > 0; j--) { + if (Y->p[j - 1] != 0) { + break; + } + } + + if (i == 0 && j == 0) { + return 0; + } + + if (i > j) { + return X->s; + } + if (j > i) { + return -Y->s; + } + + if (X->s > 0 && Y->s < 0) { + return 1; + } + if (Y->s > 0 && X->s < 0) { + return -1; + } + + for (; i > 0; i--) { + if (X->p[i - 1] > Y->p[i - 1]) { + return X->s; + } + if (X->p[i - 1] < Y->p[i - 1]) { + return -X->s; + } + } + + return 0; +} + +/* + * Compare signed values + */ +int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z) +{ + mbedtls_mpi Y; + mbedtls_mpi_uint p[1]; + MPI_VALIDATE_RET(X != NULL); + + *p = mpi_sint_abs(z); + Y.s = TO_SIGN(z); + Y.n = 1; + Y.p = p; + + return mbedtls_mpi_cmp_mpi(X, &Y); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t j; + mbedtls_mpi_uint *p; + mbedtls_mpi_uint c; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + if (X == B) { + const mbedtls_mpi *T = A; A = X; B = T; + } + + if (X != A) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)); + } + + /* + * X must always be positive as a result of unsigned additions. + */ + X->s = 1; + + for (j = B->n; j > 0; j--) { + if (B->p[j - 1] != 0) { + break; + } + } + + /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0 + * and B is 0 (of any size). */ + if (j == 0) { + return 0; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j)); + + /* j is the number of non-zero limbs of B. Add those to X. */ + + p = X->p; + + c = mbedtls_mpi_core_add(p, p, B->p, j); + + p += j; + + /* Now propagate any carry */ + + while (c != 0) { + if (j >= X->n) { + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1)); + p = X->p + j; + } + + *p += c; c = (*p < c); j++; p++; + } + +cleanup: + + return ret; +} + +/* + * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10) + */ +int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n; + mbedtls_mpi_uint carry; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + for (n = B->n; n > 0; n--) { + if (B->p[n - 1] != 0) { + break; + } + } + if (n > A->n) { + /* B >= (2^ciL)^n > A */ + ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n)); + + /* Set the high limbs of X to match A. Don't touch the lower limbs + * because X might be aliased to B, and we must not overwrite the + * significant digits of B. */ + if (A->n > n && A != X) { + memcpy(X->p + n, A->p + n, (A->n - n) * ciL); + } + if (X->n > A->n) { + memset(X->p + A->n, 0, (X->n - A->n) * ciL); + } + + carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n); + if (carry != 0) { + /* Propagate the carry through the rest of X. */ + carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n); + + /* If we have further carry/borrow, the result is negative. */ + if (carry != 0) { + ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE; + goto cleanup; + } + } + + /* X should always be positive as a result of unsigned subtractions. */ + X->s = 1; + +cleanup: + return ret; +} + +/* Common function for signed addition and subtraction. + * Calculate A + B * flip_B where flip_B is 1 or -1. + */ +static int add_sub_mpi(mbedtls_mpi *X, + const mbedtls_mpi *A, const mbedtls_mpi *B, + int flip_B) +{ + int ret, s; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + s = A->s; + if (A->s * B->s * flip_B < 0) { + int cmp = mbedtls_mpi_cmp_abs(A, B); + if (cmp >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B)); + /* If |A| = |B|, the result is 0 and we must set the sign bit + * to +1 regardless of which of A or B was negative. Otherwise, + * since |A| > |B|, the sign is the sign of A. */ + X->s = cmp == 0 ? 1 : s; + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A)); + /* Since |A| < |B|, the sign is the opposite of A. */ + X->s = -s; + } + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B)); + X->s = s; + } + +cleanup: + + return ret; +} + +/* + * Signed addition: X = A + B + */ +int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + return add_sub_mpi(X, A, B, 1); +} + +/* + * Signed subtraction: X = A - B + */ +int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + return add_sub_mpi(X, A, B, -1); +} + +/* + * Signed addition: X = A + b + */ +int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) +{ + mbedtls_mpi B; + mbedtls_mpi_uint p[1]; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + + p[0] = mpi_sint_abs(b); + B.s = TO_SIGN(b); + B.n = 1; + B.p = p; + + return mbedtls_mpi_add_mpi(X, A, &B); +} + +/* + * Signed subtraction: X = A - b + */ +int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) +{ + mbedtls_mpi B; + mbedtls_mpi_uint p[1]; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + + p[0] = mpi_sint_abs(b); + B.s = TO_SIGN(b); + B.n = 1; + B.p = p; + + return mbedtls_mpi_sub_mpi(X, A, &B); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i, j; + mbedtls_mpi TA, TB; + int result_is_zero = 0; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + mbedtls_mpi_init(&TA); + mbedtls_mpi_init(&TB); + + if (X == A) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA; + } + if (X == B) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB; + } + + for (i = A->n; i > 0; i--) { + if (A->p[i - 1] != 0) { + break; + } + } + if (i == 0) { + result_is_zero = 1; + } + + for (j = B->n; j > 0; j--) { + if (B->p[j - 1] != 0) { + break; + } + } + if (j == 0) { + result_is_zero = 1; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0)); + + mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j); + + /* If the result is 0, we don't shortcut the operation, which reduces + * but does not eliminate side channels leaking the zero-ness. We do + * need to take care to set the sign bit properly since the library does + * not fully support an MPI object with a value of 0 and s == -1. */ + if (result_is_zero) { + X->s = 1; + } else { + X->s = A->s * B->s; + } + +cleanup: + + mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA); + + return ret; +} + +/* + * Baseline multiplication: X = A * b + */ +int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b) +{ + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + + size_t n = A->n; + while (n > 0 && A->p[n - 1] == 0) { + --n; + } + + /* The general method below doesn't work if b==0. */ + if (b == 0 || n == 0) { + return mbedtls_mpi_lset(X, 0); + } + + /* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + /* In general, A * b requires 1 limb more than b. If + * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same + * number of limbs as A and the call to grow() is not required since + * copy() will take care of the growth if needed. However, experimentally, + * making the call to grow() unconditional causes slightly fewer + * calls to calloc() in ECP code, presumably because it reuses the + * same mpi for a while and this way the mpi is more likely to directly + * grow to its final size. + * + * Note that calculating A*b as 0 + A*b doesn't work as-is because + * A,X can be the same. */ + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)); + mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1); + +cleanup: + return ret; +} + +/* + * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and + * mbedtls_mpi_uint divisor, d + */ +static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1, + mbedtls_mpi_uint u0, + mbedtls_mpi_uint d, + mbedtls_mpi_uint *r) +{ +#if defined(MBEDTLS_HAVE_UDBL) + mbedtls_t_udbl dividend, quotient; +#else + const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; + const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1; + mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; + mbedtls_mpi_uint u0_msw, u0_lsw; + size_t s; +#endif + + /* + * Check for overflow + */ + if (0 == d || u1 >= d) { + if (r != NULL) { + *r = ~(mbedtls_mpi_uint) 0u; + } + + return ~(mbedtls_mpi_uint) 0u; + } + +#if defined(MBEDTLS_HAVE_UDBL) + dividend = (mbedtls_t_udbl) u1 << biL; + dividend |= (mbedtls_t_udbl) u0; + quotient = dividend / d; + if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) { + quotient = ((mbedtls_t_udbl) 1 << biL) - 1; + } + + if (r != NULL) { + *r = (mbedtls_mpi_uint) (dividend - (quotient * d)); + } + + return (mbedtls_mpi_uint) quotient; +#else + + /* + * Algorithm D, Section 4.3.1 - The Art of Computer Programming + * Vol. 2 - Seminumerical Algorithms, Knuth + */ + + /* + * Normalize the divisor, d, and dividend, u0, u1 + */ + s = mbedtls_mpi_core_clz(d); + d = d << s; + + u1 = u1 << s; + u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1)); + u0 = u0 << s; + + d1 = d >> biH; + d0 = d & uint_halfword_mask; + + u0_msw = u0 >> biH; + u0_lsw = u0 & uint_halfword_mask; + + /* + * Find the first quotient and remainder + */ + q1 = u1 / d1; + r0 = u1 - d1 * q1; + + while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) { + q1 -= 1; + r0 += d1; + + if (r0 >= radix) { + break; + } + } + + rAX = (u1 * radix) + (u0_msw - q1 * d); + q0 = rAX / d1; + r0 = rAX - q0 * d1; + + while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) { + q0 -= 1; + r0 += d1; + + if (r0 >= radix) { + break; + } + } + + if (r != NULL) { + *r = (rAX * radix + u0_lsw - q0 * d) >> s; + } + + quotient = q1 * radix + q0; + + return quotient; +#endif +} + +/* + * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) + */ +int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, + const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i, n, t, k; + mbedtls_mpi X, Y, Z, T1, T2; + mbedtls_mpi_uint TP2[3]; + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + if (mbedtls_mpi_cmp_int(B, 0) == 0) { + return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO; + } + + mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); + mbedtls_mpi_init(&T1); + /* + * Avoid dynamic memory allocations for constant-size T2. + * + * T2 is used for comparison only and the 3 limbs are assigned explicitly, + * so nobody increase the size of the MPI and we're safe to use an on-stack + * buffer. + */ + T2.s = 1; + T2.n = sizeof(TP2) / sizeof(*TP2); + T2.p = TP2; + + if (mbedtls_mpi_cmp_abs(A, B) < 0) { + if (Q != NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0)); + } + if (R != NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A)); + } + return 0; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B)); + X.s = Y.s = 1; + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2)); + + k = mbedtls_mpi_bitlen(&Y) % biL; + if (k < biL - 1) { + k = biL - 1 - k; + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k)); + } else { + k = 0; + } + + n = X.n - 1; + t = Y.n - 1; + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t))); + + while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) { + Z.p[n - t]++; + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y)); + } + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t))); + + for (i = n; i > t; i--) { + if (X.p[i] >= Y.p[t]) { + Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u; + } else { + Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1], + Y.p[t], NULL); + } + + T2.p[0] = (i < 2) ? 0 : X.p[i - 2]; + T2.p[1] = (i < 1) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + + Z.p[i - t - 1]++; + do { + Z.p[i - t - 1]--; + + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0)); + T1.p[0] = (t < 1) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1])); + } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0); + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1])); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1))); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1)); + + if (mbedtls_mpi_cmp_int(&X, 0) < 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1))); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1)); + Z.p[i - t - 1]--; + } + } + + if (Q != NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z)); + Q->s = A->s * B->s; + } + + if (R != NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k)); + X.s = A->s; + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X)); + + if (mbedtls_mpi_cmp_int(R, 0) == 0) { + R->s = 1; + } + } + +cleanup: + + mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); + mbedtls_mpi_free(&T1); + mbedtls_platform_zeroize(TP2, sizeof(TP2)); + + return ret; +} + +/* + * Division by int: A = Q * b + R + */ +int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R, + const mbedtls_mpi *A, + mbedtls_mpi_sint b) +{ + mbedtls_mpi B; + mbedtls_mpi_uint p[1]; + MPI_VALIDATE_RET(A != NULL); + + p[0] = mpi_sint_abs(b); + B.s = TO_SIGN(b); + B.n = 1; + B.p = p; + + return mbedtls_mpi_div_mpi(Q, R, A, &B); +} + +/* + * Modulo: R = A mod B + */ +int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MPI_VALIDATE_RET(R != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + if (mbedtls_mpi_cmp_int(B, 0) < 0) { + return MBEDTLS_ERR_MPI_NEGATIVE_VALUE; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B)); + + while (mbedtls_mpi_cmp_int(R, 0) < 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B)); + } + + while (mbedtls_mpi_cmp_mpi(R, B) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B)); + } + +cleanup: + + return ret; +} + +/* + * Modulo: r = A mod b + */ +int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b) +{ + size_t i; + mbedtls_mpi_uint x, y, z; + MPI_VALIDATE_RET(r != NULL); + MPI_VALIDATE_RET(A != NULL); + + if (b == 0) { + return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO; + } + + if (b < 0) { + return MBEDTLS_ERR_MPI_NEGATIVE_VALUE; + } + + /* + * handle trivial cases + */ + if (b == 1 || A->n == 0) { + *r = 0; + return 0; + } + + if (b == 2) { + *r = A->p[0] & 1; + return 0; + } + + /* + * general case + */ + for (i = A->n, y = 0; i > 0; i--) { + x = A->p[i - 1]; + y = (y << biH) | (x >> biH); + z = y / b; + y -= z * b; + + x <<= biH; + y = (y << biH) | (x >> biH); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if (A->s < 0 && y != 0) { + y = b - y; + } + + *r = y; + + return 0; +} + +static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) +{ + *mm = mbedtls_mpi_core_montmul_init(N->p); +} + +/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + * + * \param[in,out] A One of the numbers to multiply. + * It must have at least as many limbs as N + * (A->n >= N->n), and any limbs beyond n are ignored. + * On successful completion, A contains the result of + * the multiplication A * B * R^-1 mod N where + * R = (2^ciL)^n. + * \param[in] B One of the numbers to multiply. + * It must be nonzero and must not have more limbs than N + * (B->n <= N->n). + * \param[in] N The modulus. \p N must be odd. + * \param mm The value calculated by `mpi_montg_init(&mm, N)`. + * This is -N^-1 mod 2^ciL. + * \param[in,out] T A bignum for temporary storage. + * It must be at least twice the limb size of N plus 1 + * (T->n >= 2 * N->n + 1). + * Its initial content is unused and + * its final content is indeterminate. + * It does not get reallocated. + */ +static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B, + const mbedtls_mpi *N, mbedtls_mpi_uint mm, + mbedtls_mpi *T) +{ + mbedtls_mpi_core_montmul(A->p, A->p, B->p, B->n, N->p, N->n, mm, T->p); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + * + * See mpi_montmul() regarding constraints and guarantees on the parameters. + */ +static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N, + mbedtls_mpi_uint mm, mbedtls_mpi *T) +{ + mbedtls_mpi_uint z = 1; + mbedtls_mpi U; + U.n = 1; + U.s = 1; + U.p = &z; + + mpi_montmul(A, &U, N, mm, T); +} + +/** + * Select an MPI from a table without leaking the index. + * + * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it + * reads the entire table in order to avoid leaking the value of idx to an + * attacker able to observe memory access patterns. + * + * \param[out] R Where to write the selected MPI. + * \param[in] T The table to read from. + * \param[in] T_size The number of elements in the table. + * \param[in] idx The index of the element to select; + * this must satisfy 0 <= idx < T_size. + * + * \return \c 0 on success, or a negative error code. + */ +static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + for (size_t i = 0; i < T_size; i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(R, &T[i], + (unsigned char) mbedtls_ct_uint_eq(i, idx))); + } +cleanup: + return ret; +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, + const mbedtls_mpi *E, const mbedtls_mpi *N, + mbedtls_mpi *prec_RR) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t window_bitsize; + size_t i, j, nblimbs; + size_t bufsize, nbits; + size_t exponent_bits_in_window = 0; + mbedtls_mpi_uint ei, mm, state; + mbedtls_mpi RR, T, W[(size_t) 1 << MBEDTLS_MPI_WINDOW_SIZE], WW, Apos; + int neg; + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(E != NULL); + MPI_VALIDATE_RET(N != NULL); + + if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + if (mbedtls_mpi_cmp_int(E, 0) < 0) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS || + mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + /* + * Init temps and window size + */ + mpi_montg_init(&mm, N); + mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T); + mbedtls_mpi_init(&Apos); + mbedtls_mpi_init(&WW); + memset(W, 0, sizeof(W)); + + i = mbedtls_mpi_bitlen(E); + + window_bitsize = (i > 671) ? 6 : (i > 239) ? 5 : + (i > 79) ? 4 : (i > 23) ? 3 : 1; + +#if (MBEDTLS_MPI_WINDOW_SIZE < 6) + if (window_bitsize > MBEDTLS_MPI_WINDOW_SIZE) { + window_bitsize = MBEDTLS_MPI_WINDOW_SIZE; + } +#endif + + const size_t w_table_used_size = (size_t) 1 << window_bitsize; + + /* + * This function is not constant-trace: its memory accesses depend on the + * exponent value. To defend against timing attacks, callers (such as RSA + * and DHM) should use exponent blinding. However this is not enough if the + * adversary can find the exponent in a single trace, so this function + * takes extra precautions against adversaries who can observe memory + * access patterns. + * + * This function performs a series of multiplications by table elements and + * squarings, and we want the prevent the adversary from finding out which + * table element was used, and from distinguishing between multiplications + * and squarings. Firstly, when multiplying by an element of the window + * W[i], we do a constant-trace table lookup to obfuscate i. This leaves + * squarings as having a different memory access patterns from other + * multiplications. So secondly, we put the accumulator in the table as + * well, and also do a constant-trace table lookup to multiply by the + * accumulator which is W[x_index]. + * + * This way, all multiplications take the form of a lookup-and-multiply. + * The number of lookup-and-multiply operations inside each iteration of + * the main loop still depends on the bits of the exponent, but since the + * other operations in the loop don't have an easily recognizable memory + * trace, an adversary is unlikely to be able to observe the exact + * patterns. + * + * An adversary may still be able to recover the exponent if they can + * observe both memory accesses and branches. However, branch prediction + * exploitation typically requires many traces of execution over the same + * data, which is defeated by randomized blinding. + */ + const size_t x_index = 0; + mbedtls_mpi_init(&W[x_index]); + + j = N->n + 1; + /* All W[i] including the accumulator must have at least N->n limbs for + * the mpi_montmul() and mpi_montred() calls later. Here we ensure that + * W[1] and the accumulator W[x_index] are large enough. later we'll grow + * other W[i] to the same length. They must not be shrunk midway through + * this function! + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2)); + + /* + * Compensate for negative A (and correct at the end) + */ + neg = (A->s == -1); + if (neg) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A)); + Apos.s = 1; + A = &Apos; + } + + /* + * If 1st call, pre-compute R^2 mod N + */ + if (prec_RR == NULL || prec_RR->p == NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N)); + + if (prec_RR != NULL) { + memcpy(prec_RR, &RR, sizeof(mbedtls_mpi)); + } + } else { + memcpy(&RR, prec_RR, sizeof(mbedtls_mpi)); + } + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if (mbedtls_mpi_cmp_mpi(A, N) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N)); + /* This should be a no-op because W[1] is already that large before + * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow + * in mpi_montmul() below, so let's make sure. */ + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1)); + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A)); + } + + /* Note that this is safe because W[1] always has at least N->n limbs + * (it grew above and was preserved by mbedtls_mpi_copy()). */ + mpi_montmul(&W[1], &RR, N, mm, &T); + + /* + * W[x_index] = R^2 * R^-1 mod N = R mod N + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[x_index], &RR)); + mpi_montred(&W[x_index], N, mm, &T); + + + if (window_bitsize > 1) { + /* + * W[i] = W[1] ^ i + * + * The first bit of the sliding window is always 1 and therefore we + * only need to store the second half of the table. + * + * (There are two special elements in the table: W[0] for the + * accumulator/result and W[1] for A in Montgomery form. Both of these + * are already set at this point.) + */ + j = w_table_used_size / 2; + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1])); + + for (i = 0; i < window_bitsize - 1; i++) { + mpi_montmul(&W[j], &W[j], N, mm, &T); + } + + /* + * W[i] = W[i - 1] * W[1] + */ + for (i = j + 1; i < w_table_used_size; i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1])); + + mpi_montmul(&W[i], &W[1], N, mm, &T); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + state = 0; + + while (1) { + if (bufsize == 0) { + if (nblimbs == 0) { + break; + } + + nblimbs--; + + bufsize = sizeof(mbedtls_mpi_uint) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if (ei == 0 && state == 0) { + continue; + } + + if (ei == 0 && state == 1) { + /* + * out of window, square W[x_index] + */ + MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index)); + mpi_montmul(&W[x_index], &WW, N, mm, &T); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + exponent_bits_in_window |= (ei << (window_bitsize - nbits)); + + if (nbits == window_bitsize) { + /* + * W[x_index] = W[x_index]^window_bitsize R^-1 mod N + */ + for (i = 0; i < window_bitsize; i++) { + MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, + x_index)); + mpi_montmul(&W[x_index], &WW, N, mm, &T); + } + + /* + * W[x_index] = W[x_index] * W[exponent_bits_in_window] R^-1 mod N + */ + MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, + exponent_bits_in_window)); + mpi_montmul(&W[x_index], &WW, N, mm, &T); + + state--; + nbits = 0; + exponent_bits_in_window = 0; + } + } + + /* + * process the remaining bits + */ + for (i = 0; i < nbits; i++) { + MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index)); + mpi_montmul(&W[x_index], &WW, N, mm, &T); + + exponent_bits_in_window <<= 1; + + if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) { + MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1)); + mpi_montmul(&W[x_index], &WW, N, mm, &T); + } + } + + /* + * W[x_index] = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred(&W[x_index], N, mm, &T); + + if (neg && E->n != 0 && (E->p[0] & 1) != 0) { + W[x_index].s = -1; + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&W[x_index], N, &W[x_index])); + } + + /* + * Load the result in the output variable. + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &W[x_index])); + +cleanup: + + /* The first bit of the sliding window is always 1 and therefore the first + * half of the table was unused. */ + for (i = w_table_used_size/2; i < w_table_used_size; i++) { + mbedtls_mpi_free(&W[i]); + } + + mbedtls_mpi_free(&W[x_index]); + mbedtls_mpi_free(&W[1]); + mbedtls_mpi_free(&T); + mbedtls_mpi_free(&Apos); + mbedtls_mpi_free(&WW); + + if (prec_RR == NULL || prec_RR->p == NULL) { + mbedtls_mpi_free(&RR); + } + + return ret; +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t lz, lzt; + mbedtls_mpi TA, TB; + + MPI_VALIDATE_RET(G != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(B != NULL); + + mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB); + + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); + + lz = mbedtls_mpi_lsb(&TA); + lzt = mbedtls_mpi_lsb(&TB); + + /* The loop below gives the correct result when A==0 but not when B==0. + * So have a special case for B==0. Leverage the fact that we just + * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test + * slightly more efficient than cmp_int(). */ + if (lzt == 0 && mbedtls_mpi_get_bit(&TB, 0) == 0) { + ret = mbedtls_mpi_copy(G, A); + goto cleanup; + } + + if (lzt < lz) { + lz = lzt; + } + + TA.s = TB.s = 1; + + /* We mostly follow the procedure described in HAC 14.54, but with some + * minor differences: + * - Sequences of multiplications or divisions by 2 are grouped into a + * single shift operation. + * - The procedure in HAC assumes that 0 < TB <= TA. + * - The condition TB <= TA is not actually necessary for correctness. + * TA and TB have symmetric roles except for the loop termination + * condition, and the shifts at the beginning of the loop body + * remove any significance from the ordering of TA vs TB before + * the shifts. + * - If TA = 0, the loop goes through 0 iterations and the result is + * correctly TB. + * - The case TB = 0 was short-circuited above. + * + * For the correctness proof below, decompose the original values of + * A and B as + * A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1 + * B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1 + * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'), + * and gcd(A',B') is odd or 0. + * + * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB). + * The code maintains the following invariant: + * gcd(A,B) = 2^k * gcd(TA,TB) for some k (I) + */ + + /* Proof that the loop terminates: + * At each iteration, either the right-shift by 1 is made on a nonzero + * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases + * by at least 1, or the right-shift by 1 is made on zero and then + * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted + * since in that case TB is calculated from TB-TA with the condition TB>TA). + */ + while (mbedtls_mpi_cmp_int(&TA, 0) != 0) { + /* Divisions by 2 preserve the invariant (I). */ + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA))); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB))); + + /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd, + * TA-TB is even so the division by 2 has an integer result. + * Invariant (I) is preserved since any odd divisor of both TA and TB + * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2 + * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also + * divides TA. + */ + if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1)); + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1)); + } + /* Note that one of TA or TB is still odd. */ + } + + /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k. + * At the loop exit, TA = 0, so gcd(TA,TB) = TB. + * - If there was at least one loop iteration, then one of TA or TB is odd, + * and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case, + * lz = min(a,b) so gcd(A,B) = 2^lz * TB. + * - If there was no loop iteration, then A was 0, and gcd(A,B) = B. + * In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well. + */ + + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB)); + +cleanup: + + mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB); + + return ret; +} + +/* + * Fill X with size bytes of random. + * The bytes returned from the RNG are used in a specific order which + * is suitable for deterministic ECDSA (see the specification of + * mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()). + */ +int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const size_t limbs = CHARS_TO_LIMBS(size); + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(f_rng != NULL); + + /* Ensure that target MPI has exactly the necessary number of limbs */ + MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs)); + if (size == 0) { + return 0; + } + + ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng); + +cleanup: + return ret; +} + +int mbedtls_mpi_random(mbedtls_mpi *X, + mbedtls_mpi_sint min, + const mbedtls_mpi *N, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + if (min < 0) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + if (mbedtls_mpi_cmp_int(N, min) <= 0) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + /* Ensure that target MPI has exactly the same number of limbs + * as the upper bound, even if the upper bound has leading zeros. + * This is necessary for mbedtls_mpi_core_random. */ + int ret = mbedtls_mpi_resize_clear(X, N->n); + if (ret != 0) { + return ret; + } + + return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng); +} + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(A != NULL); + MPI_VALIDATE_RET(N != NULL); + + if (mbedtls_mpi_cmp_int(N, 1) <= 0) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2); + mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV); + mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2); + + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N)); + + if (mbedtls_mpi_cmp_int(&G, 1) != 0) { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1)); + + do { + while ((TU.p[0] & 1) == 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1)); + + if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA)); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1)); + } + + while ((TV.p[0] & 1) == 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1)); + + if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA)); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1)); + } + + if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2)); + } else { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2)); + } + } while (mbedtls_mpi_cmp_int(&TU, 0) != 0); + + while (mbedtls_mpi_cmp_int(&V1, 0) < 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N)); + } + + while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N)); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1)); + +cleanup: + + mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TU); mbedtls_mpi_free(&U1); mbedtls_mpi_free(&U2); + mbedtls_mpi_free(&G); mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TV); + mbedtls_mpi_free(&V1); mbedtls_mpi_free(&V2); + + return ret; +} + +#if defined(MBEDTLS_GENPRIME) + +/* Gaps between primes, starting at 3. https://oeis.org/A001223 */ +static const unsigned char small_prime_gaps[] = { + 2, 2, 4, 2, 4, 2, 4, 6, + 2, 6, 4, 2, 4, 6, 6, 2, + 6, 4, 2, 6, 4, 6, 8, 4, + 2, 4, 2, 4, 14, 4, 6, 2, + 10, 2, 6, 6, 4, 6, 6, 2, + 10, 2, 4, 2, 12, 12, 4, 2, + 4, 6, 2, 10, 6, 6, 6, 2, + 6, 4, 2, 10, 14, 4, 2, 4, + 14, 6, 10, 2, 4, 6, 8, 6, + 6, 4, 6, 8, 4, 8, 10, 2, + 10, 2, 6, 4, 6, 8, 4, 2, + 4, 12, 8, 4, 8, 4, 6, 12, + 2, 18, 6, 10, 6, 6, 2, 6, + 10, 6, 6, 2, 6, 6, 4, 2, + 12, 10, 2, 4, 6, 6, 2, 12, + 4, 6, 8, 10, 8, 10, 8, 6, + 6, 4, 8, 6, 4, 8, 4, 14, + 10, 12, 2, 10, 2, 4, 2, 10, + 14, 4, 2, 4, 14, 4, 2, 4, + 20, 4, 8, 10, 8, 4, 6, 6, + 14, 4, 6, 6, 8, 6, /*reaches 997*/ + 0 /* the last entry is effectively unused */ +}; + +/* + * Small divisors test (X must be positive) + * + * Return values: + * 0: no small factor (possible prime, more tests needed) + * 1: certain prime + * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime + * other negative: error + */ +static int mpi_check_small_factors(const mbedtls_mpi *X) +{ + int ret = 0; + size_t i; + mbedtls_mpi_uint r; + unsigned p = 3; /* The first odd prime */ + + if ((X->p[0] & 1) == 0) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + + for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p)); + if (r == 0) { + if (mbedtls_mpi_cmp_int(X, p) == 0) { + return 1; + } else { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + } + } + +cleanup: + return ret; +} + +/* + * Miller-Rabin pseudo-primality test (HAC 4.24) + */ +static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret, count; + size_t i, j, k, s; + mbedtls_mpi W, R, T, A, RR; + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(f_rng != NULL); + + mbedtls_mpi_init(&W); mbedtls_mpi_init(&R); + mbedtls_mpi_init(&T); mbedtls_mpi_init(&A); + mbedtls_mpi_init(&RR); + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1)); + s = mbedtls_mpi_lsb(&W); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s)); + + for (i = 0; i < rounds; i++) { + /* + * pick a random A, 1 < A < |X| - 1 + */ + count = 0; + do { + MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng)); + + j = mbedtls_mpi_bitlen(&A); + k = mbedtls_mpi_bitlen(&W); + if (j > k) { + A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1; + } + + if (count++ > 30) { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 || + mbedtls_mpi_cmp_int(&A, 1) <= 0); + + /* + * A = A^R mod |X| + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR)); + + if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 || + mbedtls_mpi_cmp_int(&A, 1) == 0) { + continue; + } + + j = 1; + while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) { + /* + * A = A * A mod |X| + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X)); + + if (mbedtls_mpi_cmp_int(&A, 1) == 0) { + break; + } + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 || + mbedtls_mpi_cmp_int(&A, 1) == 0) { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + mbedtls_mpi_free(&W); mbedtls_mpi_free(&R); + mbedtls_mpi_free(&T); mbedtls_mpi_free(&A); + mbedtls_mpi_free(&RR); + + return ret; +} + +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi XX; + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(f_rng != NULL); + + XX.s = 1; + XX.n = X->n; + XX.p = X->p; + + if (mbedtls_mpi_cmp_int(&XX, 0) == 0 || + mbedtls_mpi_cmp_int(&XX, 1) == 0) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + + if (mbedtls_mpi_cmp_int(&XX, 2) == 0) { + return 0; + } + + if ((ret = mpi_check_small_factors(&XX)) != 0) { + if (ret == 1) { + return 0; + } + + return ret; + } + + return mpi_miller_rabin(&XX, rounds, f_rng, p_rng); +} + +/* + * Prime number generation + * + * To generate an RSA key in a way recommended by FIPS 186-4, both primes must + * be either 1024 bits or 1536 bits long, and flags must contain + * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR. + */ +int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ +#ifdef MBEDTLS_HAVE_INT64 +// ceil(2^63.5) +#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL +#else +// ceil(2^31.5) +#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U +#endif + int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + size_t k, n; + int rounds; + mbedtls_mpi_uint r; + mbedtls_mpi Y; + + MPI_VALIDATE_RET(X != NULL); + MPI_VALIDATE_RET(f_rng != NULL); + + if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + mbedtls_mpi_init(&Y); + + n = BITS_TO_LIMBS(nbits); + + if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) { + /* + * 2^-80 error probability, number of rounds chosen per HAC, table 4.4 + */ + rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 : + (nbits >= 650) ? 4 : (nbits >= 350) ? 8 : + (nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27); + } else { + /* + * 2^-100 error probability, number of rounds computed based on HAC, + * fact 4.48 + */ + rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 : + (nbits >= 1000) ? 6 : (nbits >= 850) ? 7 : + (nbits >= 750) ? 8 : (nbits >= 500) ? 13 : + (nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51); + } + + while (1) { + MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng)); + /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */ + if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) { + continue; + } + + k = n * biL; + if (k > nbits) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits)); + } + X->p[0] |= 1; + + if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) { + ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng); + + if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { + goto cleanup; + } + } else { + /* + * A necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 + */ + + X->p[0] |= 2; + + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3)); + if (r == 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8)); + } else if (r == 1) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4)); + } + + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1)); + + while (1) { + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if ((ret = mpi_check_small_factors(X)) == 0 && + (ret = mpi_check_small_factors(&Y)) == 0 && + (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng)) + == 0 && + (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng)) + == 0) { + goto cleanup; + } + + if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { + goto cleanup; + } + + /* + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6)); + } + } + } + +cleanup: + + mbedtls_mpi_free(&Y); + + return ret; +} + +#endif /* MBEDTLS_GENPRIME */ + +#if defined(MBEDTLS_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mbedtls_mpi_self_test(int verbose) +{ + int ret, i; + mbedtls_mpi A, E, N, X, Y, U, V; + + mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X); + mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6")); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E")); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5")); + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E")); + + if (verbose != 0) { + mbedtls_printf(" MPI test #1 (mul_mpi): "); + } + + if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto cleanup; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, + "256567336059E52CAE22925474705F39A94")); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642")); + + if (verbose != 0) { + mbedtls_printf(" MPI test #2 (div_mpi): "); + } + + if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 || + mbedtls_mpi_cmp_mpi(&Y, &V) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto cleanup; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87")); + + if (verbose != 0) { + mbedtls_printf(" MPI test #3 (exp_mod): "); + } + + if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto cleanup; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61")); + + if (verbose != 0) { + mbedtls_printf(" MPI test #4 (inv_mod): "); + } + + if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + + ret = 1; + goto cleanup; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + if (verbose != 0) { + mbedtls_printf(" MPI test #5 (simple gcd): "); + } + + for (i = 0; i < GCD_PAIR_COUNT; i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0])); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1])); + + MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y)); + + if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) { + if (verbose != 0) { + mbedtls_printf("failed at %d\n", i); + } + + ret = 1; + goto cleanup; + } + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + +cleanup: + + if (ret != 0 && verbose != 0) { + mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret); + } + + mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X); + mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V); + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + return ret; +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_BIGNUM_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.c b/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.c new file mode 100644 index 0000000..dfed60d --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.c @@ -0,0 +1,894 @@ +/* + * Core bignum functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_BIGNUM_C) + +#include + +#include "mbedtls/error.h" +#include "mbedtls/platform_util.h" +#include "constant_time_internal.h" + +#include "mbedtls/platform.h" + +#include "bignum_core.h" +#include "bn_mul.h" +#include "constant_time_internal.h" + +size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a) +{ +#if defined(__has_builtin) +#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_clz) + #define core_clz __builtin_clz +#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_clzl) + #define core_clz __builtin_clzl +#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_clzll) + #define core_clz __builtin_clzll +#endif +#endif +#if defined(core_clz) + return (size_t) core_clz(a); +#else + size_t j; + mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); + + for (j = 0; j < biL; j++) { + if (a & mask) { + break; + } + + mask >>= 1; + } + + return j; +#endif +} + +size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs) +{ + int i; + size_t j; + + for (i = ((int) A_limbs) - 1; i >= 0; i--) { + if (A[i] != 0) { + j = biL - mbedtls_mpi_core_clz(A[i]); + return (i * biL) + j; + } + } + + return 0; +} + +static mbedtls_mpi_uint mpi_bigendian_to_host(mbedtls_mpi_uint a) +{ + if (MBEDTLS_IS_BIG_ENDIAN) { + /* Nothing to do on bigendian systems. */ + return a; + } else { +#if defined(MBEDTLS_HAVE_INT32) + return (mbedtls_mpi_uint) MBEDTLS_BSWAP32(a); +#elif defined(MBEDTLS_HAVE_INT64) + return (mbedtls_mpi_uint) MBEDTLS_BSWAP64(a); +#endif + } +} + +void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A, + size_t A_limbs) +{ + mbedtls_mpi_uint *cur_limb_left; + mbedtls_mpi_uint *cur_limb_right; + if (A_limbs == 0) { + return; + } + + /* + * Traverse limbs and + * - adapt byte-order in each limb + * - swap the limbs themselves. + * For that, simultaneously traverse the limbs from left to right + * and from right to left, as long as the left index is not bigger + * than the right index (it's not a problem if limbs is odd and the + * indices coincide in the last iteration). + */ + for (cur_limb_left = A, cur_limb_right = A + (A_limbs - 1); + cur_limb_left <= cur_limb_right; + cur_limb_left++, cur_limb_right--) { + mbedtls_mpi_uint tmp; + /* Note that if cur_limb_left == cur_limb_right, + * this code effectively swaps the bytes only once. */ + tmp = mpi_bigendian_to_host(*cur_limb_left); + *cur_limb_left = mpi_bigendian_to_host(*cur_limb_right); + *cur_limb_right = tmp; + } +} + +/* Whether min <= A, in constant time. + * A_limbs must be at least 1. */ +mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min, + const mbedtls_mpi_uint *A, + size_t A_limbs) +{ + /* min <= least significant limb? */ + mbedtls_ct_condition_t min_le_lsl = mbedtls_ct_uint_ge(A[0], min); + + /* limbs other than the least significant one are all zero? */ + mbedtls_ct_condition_t msll_mask = MBEDTLS_CT_FALSE; + for (size_t i = 1; i < A_limbs; i++) { + msll_mask = mbedtls_ct_bool_or(msll_mask, mbedtls_ct_bool(A[i])); + } + + /* min <= A iff the lowest limb of A is >= min or the other limbs + * are not all zero. */ + return mbedtls_ct_bool_or(msll_mask, min_le_lsl); +} + +mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs) +{ + mbedtls_ct_condition_t ret = MBEDTLS_CT_FALSE, cond = MBEDTLS_CT_FALSE, done = MBEDTLS_CT_FALSE; + + for (size_t i = limbs; i > 0; i--) { + /* + * If B[i - 1] < A[i - 1] then A < B is false and the result must + * remain 0. + * + * Again even if we can make a decision, we just mark the result and + * the fact that we are done and continue looping. + */ + cond = mbedtls_ct_uint_lt(B[i - 1], A[i - 1]); + done = mbedtls_ct_bool_or(done, cond); + + /* + * If A[i - 1] < B[i - 1] then A < B is true. + * + * Again even if we can make a decision, we just mark the result and + * the fact that we are done and continue looping. + */ + cond = mbedtls_ct_uint_lt(A[i - 1], B[i - 1]); + ret = mbedtls_ct_bool_or(ret, mbedtls_ct_bool_and(cond, mbedtls_ct_bool_not(done))); + done = mbedtls_ct_bool_or(done, cond); + } + + /* + * If all the limbs were equal, then the numbers are equal, A < B is false + * and leaving the result 0 is correct. + */ + + return ret; +} + +void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + size_t limbs, + mbedtls_ct_condition_t assign) +{ + if (X == A) { + return; + } + + /* This function is very performance-sensitive for RSA. For this reason + * we have the loop below, instead of calling mbedtls_ct_memcpy_if + * (this is more optimal since here we don't have to handle the case where + * we copy awkwardly sized data). + */ + for (size_t i = 0; i < limbs; i++) { + X[i] = mbedtls_ct_mpi_uint_if(assign, A[i], X[i]); + } +} + +void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X, + mbedtls_mpi_uint *Y, + size_t limbs, + mbedtls_ct_condition_t swap) +{ + if (X == Y) { + return; + } + + for (size_t i = 0; i < limbs; i++) { + mbedtls_mpi_uint tmp = X[i]; + X[i] = mbedtls_ct_mpi_uint_if(swap, Y[i], X[i]); + Y[i] = mbedtls_ct_mpi_uint_if(swap, tmp, Y[i]); + } +} + +int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X, + size_t X_limbs, + const unsigned char *input, + size_t input_length) +{ + const size_t limbs = CHARS_TO_LIMBS(input_length); + + if (X_limbs < limbs) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + + if (X != NULL) { + memset(X, 0, X_limbs * ciL); + + for (size_t i = 0; i < input_length; i++) { + size_t offset = ((i % ciL) << 3); + X[i / ciL] |= ((mbedtls_mpi_uint) input[i]) << offset; + } + } + + return 0; +} + +int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X, + size_t X_limbs, + const unsigned char *input, + size_t input_length) +{ + const size_t limbs = CHARS_TO_LIMBS(input_length); + + if (X_limbs < limbs) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + + /* If X_limbs is 0, input_length must also be 0 (from previous test). + * Nothing to do. */ + if (X_limbs == 0) { + return 0; + } + + memset(X, 0, X_limbs * ciL); + + /* memcpy() with (NULL, 0) is undefined behaviour */ + if (input_length != 0) { + size_t overhead = (X_limbs * ciL) - input_length; + unsigned char *Xp = (unsigned char *) X; + memcpy(Xp + overhead, input, input_length); + } + + mbedtls_mpi_core_bigendian_to_host(X, X_limbs); + + return 0; +} + +int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A, + size_t A_limbs, + unsigned char *output, + size_t output_length) +{ + size_t stored_bytes = A_limbs * ciL; + size_t bytes_to_copy; + + if (stored_bytes < output_length) { + bytes_to_copy = stored_bytes; + } else { + bytes_to_copy = output_length; + + /* The output buffer is smaller than the allocated size of A. + * However A may fit if its leading bytes are zero. */ + for (size_t i = bytes_to_copy; i < stored_bytes; i++) { + if (GET_BYTE(A, i) != 0) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + } + } + + for (size_t i = 0; i < bytes_to_copy; i++) { + output[i] = GET_BYTE(A, i); + } + + if (stored_bytes < output_length) { + /* Write trailing 0 bytes */ + memset(output + stored_bytes, 0, output_length - stored_bytes); + } + + return 0; +} + +int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *X, + size_t X_limbs, + unsigned char *output, + size_t output_length) +{ + size_t stored_bytes; + size_t bytes_to_copy; + unsigned char *p; + + stored_bytes = X_limbs * ciL; + + if (stored_bytes < output_length) { + /* There is enough space in the output buffer. Write initial + * null bytes and record the position at which to start + * writing the significant bytes. In this case, the execution + * trace of this function does not depend on the value of the + * number. */ + bytes_to_copy = stored_bytes; + p = output + output_length - stored_bytes; + memset(output, 0, output_length - stored_bytes); + } else { + /* The output buffer is smaller than the allocated size of X. + * However X may fit if its leading bytes are zero. */ + bytes_to_copy = output_length; + p = output; + for (size_t i = bytes_to_copy; i < stored_bytes; i++) { + if (GET_BYTE(X, i) != 0) { + return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL; + } + } + } + + for (size_t i = 0; i < bytes_to_copy; i++) { + p[bytes_to_copy - i - 1] = GET_BYTE(X, i); + } + + return 0; +} + +void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, + size_t count) +{ + size_t i, v0, v1; + mbedtls_mpi_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if (v0 > limbs || (v0 == limbs && v1 > 0)) { + memset(X, 0, limbs * ciL); + return; + } + + /* + * shift by count / limb_size + */ + if (v0 > 0) { + for (i = 0; i < limbs - v0; i++) { + X[i] = X[i + v0]; + } + + for (; i < limbs; i++) { + X[i] = 0; + } + } + + /* + * shift by count % limb_size + */ + if (v1 > 0) { + for (i = limbs; i > 0; i--) { + r1 = X[i - 1] << (biL - v1); + X[i - 1] >>= v1; + X[i - 1] |= r0; + r0 = r1; + } + } +} + +void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs, + size_t count) +{ + size_t i, v0, v1; + mbedtls_mpi_uint r0 = 0, r1; + + v0 = count / (biL); + v1 = count & (biL - 1); + + /* + * shift by count / limb_size + */ + if (v0 > 0) { + for (i = limbs; i > v0; i--) { + X[i - 1] = X[i - v0 - 1]; + } + + for (; i > 0; i--) { + X[i - 1] = 0; + } + } + + /* + * shift by count % limb_size + */ + if (v1 > 0) { + for (i = v0; i < limbs; i++) { + r1 = X[i] >> (biL - v1); + X[i] <<= v1; + X[i] |= r0; + r0 = r1; + } + } +} + +mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs) +{ + mbedtls_mpi_uint c = 0; + + for (size_t i = 0; i < limbs; i++) { + mbedtls_mpi_uint t = c + A[i]; + c = (t < A[i]); + t += B[i]; + c += (t < B[i]); + X[i] = t; + } + + return c; +} + +mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + size_t limbs, + unsigned cond) +{ + mbedtls_mpi_uint c = 0; + + mbedtls_ct_condition_t do_add = mbedtls_ct_bool(cond); + + for (size_t i = 0; i < limbs; i++) { + mbedtls_mpi_uint add = mbedtls_ct_mpi_uint_if_else_0(do_add, A[i]); + mbedtls_mpi_uint t = c + X[i]; + c = (t < X[i]); + t += add; + c += (t < add); + X[i] = t; + } + + return c; +} + +mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs) +{ + mbedtls_mpi_uint c = 0; + + for (size_t i = 0; i < limbs; i++) { + mbedtls_mpi_uint z = (A[i] < c); + mbedtls_mpi_uint t = A[i] - c; + c = (t < B[i]) + z; + X[i] = t - B[i]; + } + + return c; +} + +mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *d, size_t d_len, + const mbedtls_mpi_uint *s, size_t s_len, + mbedtls_mpi_uint b) +{ + mbedtls_mpi_uint c = 0; /* carry */ + /* + * It is a documented precondition of this function that d_len >= s_len. + * If that's not the case, we swap these round: this turns what would be + * a buffer overflow into an incorrect result. + */ + if (d_len < s_len) { + s_len = d_len; + } + size_t excess_len = d_len - s_len; + size_t steps_x8 = s_len / 8; + size_t steps_x1 = s_len & 7; + + while (steps_x8--) { + MULADDC_X8_INIT + MULADDC_X8_CORE + MULADDC_X8_STOP + } + + while (steps_x1--) { + MULADDC_X1_INIT + MULADDC_X1_CORE + MULADDC_X1_STOP + } + + while (excess_len--) { + *d += c; + c = (*d < c); + d++; + } + + return c; +} + +void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, size_t A_limbs, + const mbedtls_mpi_uint *B, size_t B_limbs) +{ + memset(X, 0, (A_limbs + B_limbs) * ciL); + + for (size_t i = 0; i < B_limbs; i++) { + (void) mbedtls_mpi_core_mla(X + i, A_limbs + 1, A, A_limbs, B[i]); + } +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis). + */ +mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N) +{ + mbedtls_mpi_uint x = N[0]; + + x += ((N[0] + 2) & 4) << 1; + + for (unsigned int i = biL; i >= 8; i /= 2) { + x *= (2 - (N[0] * x)); + } + + return ~x + 1; +} + +void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t B_limbs, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + mbedtls_mpi_uint *T) +{ + memset(T, 0, (2 * AN_limbs + 1) * ciL); + + for (size_t i = 0; i < AN_limbs; i++) { + /* T = (T + u0*B + u1*N) / 2^biL */ + mbedtls_mpi_uint u0 = A[i]; + mbedtls_mpi_uint u1 = (T[0] + u0 * B[0]) * mm; + + (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, B, B_limbs, u0); + (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, N, AN_limbs, u1); + + T++; + } + + /* + * The result we want is (T >= N) ? T - N : T. + * + * For better constant-time properties in this function, we always do the + * subtraction, with the result in X. + * + * We also look to see if there was any carry in the final additions in the + * loop above. + */ + + mbedtls_mpi_uint carry = T[AN_limbs]; + mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, T, N, AN_limbs); + + /* + * Using R as the Montgomery radix (auxiliary modulus) i.e. 2^(biL*AN_limbs): + * + * T can be in one of 3 ranges: + * + * 1) T < N : (carry, borrow) = (0, 1): we want T + * 2) N <= T < R : (carry, borrow) = (0, 0): we want X + * 3) T >= R : (carry, borrow) = (1, 1): we want X + * + * and (carry, borrow) = (1, 0) can't happen. + * + * So the correct return value is already in X if (carry ^ borrow) = 0, + * but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1. + */ + mbedtls_ct_memcpy_if(mbedtls_ct_bool(carry ^ borrow), + (unsigned char *) X, + (unsigned char *) T, + NULL, + AN_limbs * sizeof(mbedtls_mpi_uint)); +} + +int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X, + const mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, N->n * 2 * biL)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(X, N->n)); + +cleanup: + return ret; +} + +MBEDTLS_STATIC_TESTABLE +void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest, + const mbedtls_mpi_uint *table, + size_t limbs, + size_t count, + size_t index) +{ + for (size_t i = 0; i < count; i++, table += limbs) { + mbedtls_ct_condition_t assign = mbedtls_ct_uint_eq(i, index); + mbedtls_mpi_core_cond_assign(dest, table, limbs, assign); + } +} + +/* Fill X with n_bytes random bytes. + * X must already have room for those bytes. + * The ordering of the bytes returned from the RNG is suitable for + * deterministic ECDSA (see RFC 6979 §3.3 and the specification of + * mbedtls_mpi_core_random()). + */ +int mbedtls_mpi_core_fill_random( + mbedtls_mpi_uint *X, size_t X_limbs, + size_t n_bytes, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const size_t limbs = CHARS_TO_LIMBS(n_bytes); + const size_t overhead = (limbs * ciL) - n_bytes; + + if (X_limbs < limbs) { + return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + } + + memset(X, 0, overhead); + memset((unsigned char *) X + limbs * ciL, 0, (X_limbs - limbs) * ciL); + MBEDTLS_MPI_CHK(f_rng(p_rng, (unsigned char *) X + overhead, n_bytes)); + mbedtls_mpi_core_bigendian_to_host(X, limbs); + +cleanup: + return ret; +} + +int mbedtls_mpi_core_random(mbedtls_mpi_uint *X, + mbedtls_mpi_uint min, + const mbedtls_mpi_uint *N, + size_t limbs, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + mbedtls_ct_condition_t ge_lower = MBEDTLS_CT_TRUE, lt_upper = MBEDTLS_CT_FALSE; + size_t n_bits = mbedtls_mpi_core_bitlen(N, limbs); + size_t n_bytes = (n_bits + 7) / 8; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* + * When min == 0, each try has at worst a probability 1/2 of failing + * (the msb has a probability 1/2 of being 0, and then the result will + * be < N), so after 30 tries failure probability is a most 2**(-30). + * + * When N is just below a power of 2, as is the case when generating + * a random scalar on most elliptic curves, 1 try is enough with + * overwhelming probability. When N is just above a power of 2, + * as when generating a random scalar on secp224k1, each try has + * a probability of failing that is almost 1/2. + * + * The probabilities are almost the same if min is nonzero but negligible + * compared to N. This is always the case when N is crypto-sized, but + * it's convenient to support small N for testing purposes. When N + * is small, use a higher repeat count, otherwise the probability of + * failure is macroscopic. + */ + int count = (n_bytes > 4 ? 30 : 250); + + /* + * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA) + * when f_rng is a suitably parametrized instance of HMAC_DRBG: + * - use the same byte ordering; + * - keep the leftmost n_bits bits of the generated octet string; + * - try until result is in the desired range. + * This also avoids any bias, which is especially important for ECDSA. + */ + do { + MBEDTLS_MPI_CHK(mbedtls_mpi_core_fill_random(X, limbs, + n_bytes, + f_rng, p_rng)); + mbedtls_mpi_core_shift_r(X, limbs, 8 * n_bytes - n_bits); + + if (--count == 0) { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + ge_lower = mbedtls_mpi_core_uint_le_mpi(min, X, limbs); + lt_upper = mbedtls_mpi_core_lt_ct(X, N, limbs); + } while (mbedtls_ct_bool_and(ge_lower, lt_upper) == MBEDTLS_CT_FALSE); + +cleanup: + return ret; +} + +static size_t exp_mod_get_window_size(size_t Ebits) +{ +#if MBEDTLS_MPI_WINDOW_SIZE >= 6 + return (Ebits > 671) ? 6 : (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1; +#elif MBEDTLS_MPI_WINDOW_SIZE == 5 + return (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1; +#elif MBEDTLS_MPI_WINDOW_SIZE > 1 + return (Ebits > 79) ? MBEDTLS_MPI_WINDOW_SIZE : 1; +#else + (void) Ebits; + return 1; +#endif +} + +size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs) +{ + const size_t wsize = exp_mod_get_window_size(E_limbs * biL); + const size_t welem = ((size_t) 1) << wsize; + + /* How big does each part of the working memory pool need to be? */ + const size_t table_limbs = welem * AN_limbs; + const size_t select_limbs = AN_limbs; + const size_t temp_limbs = 2 * AN_limbs + 1; + + return table_limbs + select_limbs + temp_limbs; +} + +static void exp_mod_precompute_window(const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + const mbedtls_mpi_uint *RR, + size_t welem, + mbedtls_mpi_uint *Wtable, + mbedtls_mpi_uint *temp) +{ + /* W[0] = 1 (in Montgomery presentation) */ + memset(Wtable, 0, AN_limbs * ciL); + Wtable[0] = 1; + mbedtls_mpi_core_montmul(Wtable, Wtable, RR, AN_limbs, N, AN_limbs, mm, temp); + + /* W[1] = A (already in Montgomery presentation) */ + mbedtls_mpi_uint *W1 = Wtable + AN_limbs; + memcpy(W1, A, AN_limbs * ciL); + + /* W[i+1] = W[i] * W[1], i >= 2 */ + mbedtls_mpi_uint *Wprev = W1; + for (size_t i = 2; i < welem; i++) { + mbedtls_mpi_uint *Wcur = Wprev + AN_limbs; + mbedtls_mpi_core_montmul(Wcur, Wprev, W1, AN_limbs, N, AN_limbs, mm, temp); + Wprev = Wcur; + } +} + +/* Exponentiation: X := A^E mod N. + * + * A must already be in Montgomery form. + * + * As in other bignum functions, assume that AN_limbs and E_limbs are nonzero. + * + * RR must contain 2^{2*biL} mod N. + * + * The algorithm is a variant of Left-to-right k-ary exponentiation: HAC 14.82 + * (The difference is that the body in our loop processes a single bit instead + * of a full window.) + */ +void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + const mbedtls_mpi_uint *E, + size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T) +{ + const size_t wsize = exp_mod_get_window_size(E_limbs * biL); + const size_t welem = ((size_t) 1) << wsize; + + /* This is how we will use the temporary storage T, which must have space + * for table_limbs, select_limbs and (2 * AN_limbs + 1) for montmul. */ + const size_t table_limbs = welem * AN_limbs; + const size_t select_limbs = AN_limbs; + + /* Pointers to specific parts of the temporary working memory pool */ + mbedtls_mpi_uint *const Wtable = T; + mbedtls_mpi_uint *const Wselect = Wtable + table_limbs; + mbedtls_mpi_uint *const temp = Wselect + select_limbs; + + /* + * Window precomputation + */ + + const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N); + + /* Set Wtable[i] = A^(2^i) (in Montgomery representation) */ + exp_mod_precompute_window(A, N, AN_limbs, + mm, RR, + welem, Wtable, temp); + + /* + * Fixed window exponentiation + */ + + /* X = 1 (in Montgomery presentation) initially */ + memcpy(X, Wtable, AN_limbs * ciL); + + /* We'll process the bits of E from most significant + * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant + * (limb_index=0, E_bit_index=0). */ + size_t E_limb_index = E_limbs; + size_t E_bit_index = 0; + /* At any given time, window contains window_bits bits from E. + * window_bits can go up to wsize. */ + size_t window_bits = 0; + mbedtls_mpi_uint window = 0; + + do { + /* Square */ + mbedtls_mpi_core_montmul(X, X, X, AN_limbs, N, AN_limbs, mm, temp); + + /* Move to the next bit of the exponent */ + if (E_bit_index == 0) { + --E_limb_index; + E_bit_index = biL - 1; + } else { + --E_bit_index; + } + /* Insert next exponent bit into window */ + ++window_bits; + window <<= 1; + window |= (E[E_limb_index] >> E_bit_index) & 1; + + /* Clear window if it's full. Also clear the window at the end, + * when we've finished processing the exponent. */ + if (window_bits == wsize || + (E_bit_index == 0 && E_limb_index == 0)) { + /* Select Wtable[window] without leaking window through + * memory access patterns. */ + mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable, + AN_limbs, welem, window); + /* Multiply X by the selected element. */ + mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm, + temp); + window = 0; + window_bits = 0; + } + } while (!(E_bit_index == 0 && E_limb_index == 0)); +} + +mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + mbedtls_mpi_uint c, /* doubles as carry */ + size_t limbs) +{ + for (size_t i = 0; i < limbs; i++) { + mbedtls_mpi_uint s = A[i]; + mbedtls_mpi_uint t = s - c; + c = (t > s); + X[i] = t; + } + + return c; +} + +mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A, + size_t limbs) +{ + mbedtls_mpi_uint bits = 0; + + for (size_t i = 0; i < limbs; i++) { + bits |= A[i]; + } + + return bits; +} + +void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + const mbedtls_mpi_uint *rr, + mbedtls_mpi_uint *T) +{ + mbedtls_mpi_core_montmul(X, A, rr, AN_limbs, N, AN_limbs, mm, T); +} + +void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + mbedtls_mpi_uint *T) +{ + const mbedtls_mpi_uint Rinv = 1; /* 1/R in Mont. rep => 1 */ + + mbedtls_mpi_core_montmul(X, A, &Rinv, 1, N, AN_limbs, mm, T); +} + +#endif /* MBEDTLS_BIGNUM_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.h b/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.h new file mode 100644 index 0000000..b56be0a --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/bignum_core.h @@ -0,0 +1,763 @@ +/** + * Core bignum functions + * + * This interface should only be used by the legacy bignum module (bignum.h) + * and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other + * modules should use the high-level modular bignum interface (bignum_mod.h) + * or the legacy bignum interface (bignum.h). + * + * This module is about processing non-negative integers with a fixed upper + * bound that's of the form 2^n-1 where n is a multiple of #biL. + * These can be thought of integers written in base 2^#biL with a fixed + * number of digits. Digits in this base are called *limbs*. + * Many operations treat these numbers as the principal representation of + * a number modulo 2^n or a smaller bound. + * + * The functions in this module obey the following conventions unless + * explicitly indicated otherwise: + * + * - **Overflow**: some functions indicate overflow from the range + * [0, 2^n-1] by returning carry parameters, while others operate + * modulo and so cannot overflow. This should be clear from the function + * documentation. + * - **Bignum parameters**: Bignums are passed as pointers to an array of + * limbs. A limb has the type #mbedtls_mpi_uint. Unless otherwise specified: + * - Bignum parameters called \p A, \p B, ... are inputs, and are + * not modified by the function. + * - For operations modulo some number, the modulus is called \p N + * and is input-only. + * - Bignum parameters called \p X, \p Y are outputs or input-output. + * The initial content of output-only parameters is ignored. + * - Some functions use different names that reflect traditional + * naming of operands of certain operations (e.g. + * divisor/dividend/quotient/remainder). + * - \p T is a temporary storage area. The initial content of such + * parameter is ignored and the final content is unspecified. + * - **Bignum sizes**: bignum sizes are always expressed in limbs. + * Most functions work on bignums of a given size and take a single + * \p limbs parameter that applies to all parameters that are limb arrays. + * All bignum sizes must be at least 1 and must be significantly less than + * #SIZE_MAX. The behavior if a size is 0 is undefined. The behavior if the + * total size of all parameters overflows #SIZE_MAX is undefined. + * - **Parameter ordering**: for bignum parameters, outputs come before inputs. + * Temporaries come last. + * - **Aliasing**: in general, output bignums may be aliased to one or more + * inputs. As an exception, parameters that are documented as a modulus value + * may not be aliased to an output. Outputs may not be aliased to one another. + * Temporaries may not be aliased to any other parameter. + * - **Overlap**: apart from aliasing of limb array pointers (where two + * arguments are equal pointers), overlap is not supported and may result + * in undefined behavior. + * - **Error handling**: This is a low-level module. Functions generally do not + * try to protect against invalid arguments such as nonsensical sizes or + * null pointers. Note that some functions that operate on bignums of + * different sizes have constraints about their size, and violating those + * constraints may lead to buffer overflows. + * - **Modular representatives**: functions that operate modulo \p N expect + * all modular inputs to be in the range [0, \p N - 1] and guarantee outputs + * in the range [0, \p N - 1]. If an input is out of range, outputs are + * fully unspecified, though bignum values out of range should not cause + * buffer overflows (beware that this is not extensively tested). + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_BIGNUM_CORE_H +#define MBEDTLS_BIGNUM_CORE_H + +#include "common.h" + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +#include "constant_time_internal.h" + +#define ciL (sizeof(mbedtls_mpi_uint)) /** chars in limb */ +#define biL (ciL << 3) /** bits in limb */ +#define biH (ciL << 2) /** half limb size */ + +/* + * Convert between bits/chars and number of limbs + * Divide first in order to avoid potential overflows + */ +#define BITS_TO_LIMBS(i) ((i) / biL + ((i) % biL != 0)) +#define CHARS_TO_LIMBS(i) ((i) / ciL + ((i) % ciL != 0)) +/* Get a specific byte, without range checks. */ +#define GET_BYTE(X, i) \ + (((X)[(i) / ciL] >> (((i) % ciL) * 8)) & 0xff) + +/** Count leading zero bits in a given integer. + * + * \warning The result is undefined if \p a == 0 + * + * \param a Integer to count leading zero bits. + * + * \return The number of leading zero bits in \p a, if \p a != 0. + * If \p a == 0, the result is undefined. + */ +size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a); + +/** Return the minimum number of bits required to represent the value held + * in the MPI. + * + * \note This function returns 0 if all the limbs of \p A are 0. + * + * \param[in] A The address of the MPI. + * \param A_limbs The number of limbs of \p A. + * + * \return The number of bits in \p A. + */ +size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs); + +/** Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint + * into the storage form used by mbedtls_mpi. + * + * \param[in,out] A The address of the MPI. + * \param A_limbs The number of limbs of \p A. + */ +void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A, + size_t A_limbs); + +/** \brief Compare a machine integer with an MPI. + * + * This function operates in constant time with respect + * to the values of \p min and \p A. + * + * \param min A machine integer. + * \param[in] A An MPI. + * \param A_limbs The number of limbs of \p A. + * This must be at least 1. + * + * \return MBEDTLS_CT_TRUE if \p min is less than or equal to \p A, otherwise MBEDTLS_CT_FALSE. + */ +mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min, + const mbedtls_mpi_uint *A, + size_t A_limbs); + +/** + * \brief Check if one unsigned MPI is less than another in constant + * time. + * + * \param A The left-hand MPI. This must point to an array of limbs + * with the same allocated length as \p B. + * \param B The right-hand MPI. This must point to an array of limbs + * with the same allocated length as \p A. + * \param limbs The number of limbs in \p A and \p B. + * This must not be 0. + * + * \return MBEDTLS_CT_TRUE if \p A is less than \p B. + * MBEDTLS_CT_FALSE if \p A is greater than or equal to \p B. + */ +mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs); + +/** + * \brief Perform a safe conditional copy of an MPI which doesn't reveal + * whether assignment was done or not. + * + * \param[out] X The address of the destination MPI. + * This must be initialized. Must have enough limbs to + * store the full value of \p A. + * \param[in] A The address of the source MPI. This must be initialized. + * \param limbs The number of limbs of \p A. + * \param assign The condition deciding whether to perform the + * assignment or not. Callers will need to use + * the constant time interface (e.g. `mbedtls_ct_bool()`) + * to construct this argument. + * + * \note This function avoids leaking any information about whether + * the assignment was done or not. + */ +void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + size_t limbs, + mbedtls_ct_condition_t assign); + +/** + * \brief Perform a safe conditional swap of two MPIs which doesn't reveal + * whether the swap was done or not. + * + * \param[in,out] X The address of the first MPI. + * This must be initialized. + * \param[in,out] Y The address of the second MPI. + * This must be initialized. + * \param limbs The number of limbs of \p X and \p Y. + * \param swap The condition deciding whether to perform + * the swap or not. + * + * \note This function avoids leaking any information about whether + * the swap was done or not. + */ +void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X, + mbedtls_mpi_uint *Y, + size_t limbs, + mbedtls_ct_condition_t swap); + +/** Import X from unsigned binary data, little-endian. + * + * The MPI needs to have enough limbs to store the full value (including any + * most significant zero bytes in the input). + * + * \param[out] X The address of the MPI. + * \param X_limbs The number of limbs of \p X. + * \param[in] input The input buffer to import from. + * \param input_length The length bytes of \p input. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't + * large enough to hold the value in \p input. + */ +int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X, + size_t X_limbs, + const unsigned char *input, + size_t input_length); + +/** Import X from unsigned binary data, big-endian. + * + * The MPI needs to have enough limbs to store the full value (including any + * most significant zero bytes in the input). + * + * \param[out] X The address of the MPI. + * May only be #NULL if \p X_limbs is 0 and \p input_length + * is 0. + * \param X_limbs The number of limbs of \p X. + * \param[in] input The input buffer to import from. + * May only be #NULL if \p input_length is 0. + * \param input_length The length in bytes of \p input. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't + * large enough to hold the value in \p input. + */ +int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X, + size_t X_limbs, + const unsigned char *input, + size_t input_length); + +/** Export A into unsigned binary data, little-endian. + * + * \note If \p output is shorter than \p A the export is still successful if the + * value held in \p A fits in the buffer (that is, if enough of the most + * significant bytes of \p A are 0). + * + * \param[in] A The address of the MPI. + * \param A_limbs The number of limbs of \p A. + * \param[out] output The output buffer to export to. + * \param output_length The length in bytes of \p output. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't + * large enough to hold the value of \p A. + */ +int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A, + size_t A_limbs, + unsigned char *output, + size_t output_length); + +/** Export A into unsigned binary data, big-endian. + * + * \note If \p output is shorter than \p A the export is still successful if the + * value held in \p A fits in the buffer (that is, if enough of the most + * significant bytes of \p A are 0). + * + * \param[in] A The address of the MPI. + * \param A_limbs The number of limbs of \p A. + * \param[out] output The output buffer to export to. + * \param output_length The length in bytes of \p output. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't + * large enough to hold the value of \p A. + */ +int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *A, + size_t A_limbs, + unsigned char *output, + size_t output_length); + +/** \brief Shift an MPI in-place right by a number of bits. + * + * Shifting by more bits than there are bit positions + * in \p X is valid and results in setting \p X to 0. + * + * This function's execution time depends on the value + * of \p count (and of course \p limbs). + * + * \param[in,out] X The number to shift. + * \param limbs The number of limbs of \p X. This must be at least 1. + * \param count The number of bits to shift by. + */ +void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs, + size_t count); + +/** + * \brief Shift an MPI in-place left by a number of bits. + * + * Shifting by more bits than there are bit positions + * in \p X will produce an unspecified result. + * + * This function's execution time depends on the value + * of \p count (and of course \p limbs). + * \param[in,out] X The number to shift. + * \param limbs The number of limbs of \p X. This must be at least 1. + * \param count The number of bits to shift by. + */ +void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs, + size_t count); + +/** + * \brief Add two fixed-size large unsigned integers, returning the carry. + * + * Calculates `A + B` where `A` and `B` have the same size. + * + * This function operates modulo `2^(biL*limbs)` and returns the carry + * (1 if there was a wraparound, and 0 otherwise). + * + * \p X may be aliased to \p A or \p B. + * + * \param[out] X The result of the addition. + * \param[in] A Little-endian presentation of the left operand. + * \param[in] B Little-endian presentation of the right operand. + * \param limbs Number of limbs of \p X, \p A and \p B. + * + * \return 1 if `A + B >= 2^(biL*limbs)`, 0 otherwise. + */ +mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs); + +/** + * \brief Conditional addition of two fixed-size large unsigned integers, + * returning the carry. + * + * Functionally equivalent to + * + * ``` + * if( cond ) + * X += A; + * return carry; + * ``` + * + * This function operates modulo `2^(biL*limbs)`. + * + * \param[in,out] X The pointer to the (little-endian) array + * representing the bignum to accumulate onto. + * \param[in] A The pointer to the (little-endian) array + * representing the bignum to conditionally add + * to \p X. This may be aliased to \p X but may not + * overlap otherwise. + * \param limbs Number of limbs of \p X and \p A. + * \param cond Condition bit dictating whether addition should + * happen or not. This must be \c 0 or \c 1. + * + * \warning If \p cond is neither 0 nor 1, the result of this function + * is unspecified, and the resulting value in \p X might be + * neither its original value nor \p X + \p A. + * + * \return 1 if `X + cond * A >= 2^(biL*limbs)`, 0 otherwise. + */ +mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + size_t limbs, + unsigned cond); + +/** + * \brief Subtract two fixed-size large unsigned integers, returning the borrow. + * + * Calculate `A - B` where \p A and \p B have the same size. + * This function operates modulo `2^(biL*limbs)` and returns the carry + * (1 if there was a wraparound, i.e. if `A < B`, and 0 otherwise). + * + * \p X may be aliased to \p A or \p B, or even both, but may not overlap + * either otherwise. + * + * \param[out] X The result of the subtraction. + * \param[in] A Little-endian presentation of left operand. + * \param[in] B Little-endian presentation of right operand. + * \param limbs Number of limbs of \p X, \p A and \p B. + * + * \return 1 if `A < B`. + * 0 if `A >= B`. + */ +mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, + size_t limbs); + +/** + * \brief Perform a fixed-size multiply accumulate operation: X += b * A + * + * \p X may be aliased to \p A (when \p X_limbs == \p A_limbs), but may not + * otherwise overlap. + * + * This function operates modulo `2^(biL*X_limbs)`. + * + * \param[in,out] X The pointer to the (little-endian) array + * representing the bignum to accumulate onto. + * \param X_limbs The number of limbs of \p X. This must be + * at least \p A_limbs. + * \param[in] A The pointer to the (little-endian) array + * representing the bignum to multiply with. + * This may be aliased to \p X but may not overlap + * otherwise. + * \param A_limbs The number of limbs of \p A. + * \param b X scalar to multiply with. + * + * \return The carry at the end of the operation. + */ +mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *X, size_t X_limbs, + const mbedtls_mpi_uint *A, size_t A_limbs, + mbedtls_mpi_uint b); + +/** + * \brief Perform a known-size multiplication + * + * \p X may not be aliased to any of the inputs for this function. + * \p A may be aliased to \p B. + * + * \param[out] X The pointer to the (little-endian) array to receive + * the product of \p A_limbs and \p B_limbs. + * This must be of length \p A_limbs + \p B_limbs. + * \param[in] A The pointer to the (little-endian) array + * representing the first factor. + * \param A_limbs The number of limbs in \p A. + * \param[in] B The pointer to the (little-endian) array + * representing the second factor. + * \param B_limbs The number of limbs in \p B. + */ +void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, size_t A_limbs, + const mbedtls_mpi_uint *B, size_t B_limbs); + +/** + * \brief Calculate initialisation value for fast Montgomery modular + * multiplication + * + * \param[in] N Little-endian presentation of the modulus. This must have + * at least one limb. + * + * \return The initialisation value for fast Montgomery modular multiplication + */ +mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N); + +/** + * \brief Montgomery multiplication: X = A * B * R^-1 mod N (HAC 14.36) + * + * \p A and \p B must be in canonical form. That is, < \p N. + * + * \p X may be aliased to \p A or \p N, or even \p B (if \p AN_limbs == + * \p B_limbs) but may not overlap any parameters otherwise. + * + * \p A and \p B may alias each other, if \p AN_limbs == \p B_limbs. They may + * not alias \p N (since they must be in canonical form, they cannot == \p N). + * + * \param[out] X The destination MPI, as a little-endian array of + * length \p AN_limbs. + * On successful completion, X contains the result of + * the multiplication `A * B * R^-1` mod N where + * `R = 2^(biL*AN_limbs)`. + * \param[in] A Little-endian presentation of first operand. + * Must have the same number of limbs as \p N. + * \param[in] B Little-endian presentation of second operand. + * \param[in] B_limbs The number of limbs in \p B. + * Must be <= \p AN_limbs. + * \param[in] N Little-endian presentation of the modulus. + * This must be odd, and have exactly the same number + * of limbs as \p A. + * It may alias \p X, but must not alias or otherwise + * overlap any of the other parameters. + * \param[in] AN_limbs The number of limbs in \p X, \p A and \p N. + * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. + * This can be calculated by `mbedtls_mpi_core_montmul_init()`. + * \param[in,out] T Temporary storage of size at least 2*AN_limbs+1 limbs. + * Its initial content is unused and + * its final content is indeterminate. + * It must not alias or otherwise overlap any of the + * other parameters. + */ +void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *B, size_t B_limbs, + const mbedtls_mpi_uint *N, size_t AN_limbs, + mbedtls_mpi_uint mm, mbedtls_mpi_uint *T); + +/** + * \brief Calculate the square of the Montgomery constant. (Needed + * for conversion and operations in Montgomery form.) + * + * \param[out] X A pointer to the result of the calculation of + * the square of the Montgomery constant: + * 2^{2*n*biL} mod N. + * \param[in] N Little-endian presentation of the modulus, which must be odd. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space + * to store the value of Montgomery constant squared. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative. + */ +int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X, + const mbedtls_mpi *N); + +#if defined(MBEDTLS_TEST_HOOKS) +/** + * Copy an MPI from a table without leaking the index. + * + * \param dest The destination buffer. This must point to a writable + * buffer of at least \p limbs limbs. + * \param table The address of the table. This must point to a readable + * array of \p count elements of \p limbs limbs each. + * \param limbs The number of limbs in each table entry. + * \param count The number of entries in \p table. + * \param index The (secret) table index to look up. This must be in the + * range `0 .. count-1`. + */ +void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest, + const mbedtls_mpi_uint *table, + size_t limbs, + size_t count, + size_t index); +#endif /* MBEDTLS_TEST_HOOKS */ + +/** + * \brief Fill an integer with a number of random bytes. + * + * \param X The destination MPI. + * \param X_limbs The number of limbs of \p X. + * \param bytes The number of random bytes to generate. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p X does not have + * enough room for \p bytes bytes. + * \return A negative error code on RNG failure. + * + * \note The bytes obtained from the RNG are interpreted + * as a big-endian representation of an MPI; this can + * be relevant in applications like deterministic ECDSA. + */ +int mbedtls_mpi_core_fill_random(mbedtls_mpi_uint *X, size_t X_limbs, + size_t bytes, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** Generate a random number uniformly in a range. + * + * This function generates a random number between \p min inclusive and + * \p N exclusive. + * + * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA) + * when the RNG is a suitably parametrized instance of HMAC_DRBG + * and \p min is \c 1. + * + * \note There are `N - min` possible outputs. The lower bound + * \p min can be reached, but the upper bound \p N cannot. + * + * \param X The destination MPI, with \p limbs limbs. + * It must not be aliased with \p N or otherwise overlap it. + * \param min The minimum value to return. + * \param N The upper bound of the range, exclusive, with \p limbs limbs. + * In other words, this is one plus the maximum value to return. + * \p N must be strictly larger than \p min. + * \param limbs The number of limbs of \p N and \p X. + * This must not be 0. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was + * unable to find a suitable value within a limited number + * of attempts. This has a negligible probability if \p N + * is significantly larger than \p min, which is the case + * for all usual cryptographic applications. + */ +int mbedtls_mpi_core_random(mbedtls_mpi_uint *X, + mbedtls_mpi_uint min, + const mbedtls_mpi_uint *N, + size_t limbs, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +/** + * \brief Returns the number of limbs of working memory required for + * a call to `mbedtls_mpi_core_exp_mod()`. + * + * \note This will always be at least + * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)`, + * i.e. sufficient for a call to `mbedtls_mpi_core_montmul()`. + * + * \param AN_limbs The number of limbs in the input `A` and the modulus `N` + * (they must be the same size) that will be given to + * `mbedtls_mpi_core_exp_mod()`. + * \param E_limbs The number of limbs in the exponent `E` that will be given + * to `mbedtls_mpi_core_exp_mod()`. + * + * \return The number of limbs of working memory required by + * `mbedtls_mpi_core_exp_mod()`. + */ +size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs); + +/** + * \brief Perform a modular exponentiation with secret exponent: + * X = A^E mod N, where \p A is already in Montgomery form. + * + * \p X may be aliased to \p A, but not to \p RR or \p E, even if \p E_limbs == + * \p AN_limbs. + * + * \param[out] X The destination MPI, as a little endian array of length + * \p AN_limbs. + * \param[in] A The base MPI, as a little endian array of length \p AN_limbs. + * Must be in Montgomery form. + * \param[in] N The modulus, as a little endian array of length \p AN_limbs. + * \param AN_limbs The number of limbs in \p X, \p A, \p N, \p RR. + * \param[in] E The exponent, as a little endian array of length \p E_limbs. + * \param E_limbs The number of limbs in \p E. + * \param[in] RR The precomputed residue of 2^{2*biL} modulo N, as a little + * endian array of length \p AN_limbs. + * \param[in,out] T Temporary storage of at least the number of limbs returned + * by `mbedtls_mpi_core_exp_mod_working_limbs()`. + * Its initial content is unused and its final content is + * indeterminate. + * It must not alias or otherwise overlap any of the other + * parameters. + * It is up to the caller to zeroize \p T when it is no + * longer needed, and before freeing it if it was dynamically + * allocated. + */ +void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, size_t AN_limbs, + const mbedtls_mpi_uint *E, size_t E_limbs, + const mbedtls_mpi_uint *RR, + mbedtls_mpi_uint *T); + +/** + * \brief Subtract unsigned integer from known-size large unsigned integers. + * Return the borrow. + * + * \param[out] X The result of the subtraction. + * \param[in] A The left operand. + * \param b The unsigned scalar to subtract. + * \param limbs Number of limbs of \p X and \p A. + * + * \return 1 if `A < b`. + * 0 if `A >= b`. + */ +mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + mbedtls_mpi_uint b, + size_t limbs); + +/** + * \brief Determine if a given MPI has the value \c 0 in constant time with + * respect to the value (but not with respect to the number of limbs). + * + * \param[in] A The MPI to test. + * \param limbs Number of limbs in \p A. + * + * \return 0 if `A == 0` + * non-0 (may be any value) if `A != 0`. + */ +mbedtls_mpi_uint mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A, + size_t limbs); + +/** + * \brief Returns the number of limbs of working memory required for + * a call to `mbedtls_mpi_core_montmul()`. + * + * \param AN_limbs The number of limbs in the input `A` and the modulus `N` + * (they must be the same size) that will be given to + * `mbedtls_mpi_core_montmul()` or one of the other functions + * that specifies this as the amount of working memory needed. + * + * \return The number of limbs of working memory required by + * `mbedtls_mpi_core_montmul()` (or other similar function). + */ +static inline size_t mbedtls_mpi_core_montmul_working_limbs(size_t AN_limbs) +{ + return 2 * AN_limbs + 1; +} + +/** Convert an MPI into Montgomery form. + * + * \p X may be aliased to \p A, but may not otherwise overlap it. + * + * \p X may not alias \p N (it is in canonical form, so must be strictly less + * than \p N). Nor may it alias or overlap \p rr (this is unlikely to be + * required in practice.) + * + * This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is + * an alternative to calling `mbedtls_mpi_mod_raw_to_mont_rep()` when we + * don't want to allocate memory. + * + * \param[out] X The result of the conversion. + * Must have the same number of limbs as \p A. + * \param[in] A The MPI to convert into Montgomery form. + * Must have the same number of limbs as the modulus. + * \param[in] N The address of the modulus, which gives the size of + * the base `R` = 2^(biL*N->limbs). + * \param[in] AN_limbs The number of limbs in \p X, \p A, \p N and \p rr. + * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. + * This can be determined by calling + * `mbedtls_mpi_core_montmul_init()`. + * \param[in] rr The residue for `2^{2*n*biL} mod N`. + * \param[in,out] T Temporary storage of size at least + * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)` + * limbs. + * Its initial content is unused and + * its final content is indeterminate. + * It must not alias or otherwise overlap any of the + * other parameters. + */ +void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + const mbedtls_mpi_uint *rr, + mbedtls_mpi_uint *T); + +/** Convert an MPI from Montgomery form. + * + * \p X may be aliased to \p A, but may not otherwise overlap it. + * + * \p X may not alias \p N (it is in canonical form, so must be strictly less + * than \p N). + * + * This function is a thin wrapper around `mbedtls_mpi_core_montmul()` that is + * an alternative to calling `mbedtls_mpi_mod_raw_from_mont_rep()` when we + * don't want to allocate memory. + * + * \param[out] X The result of the conversion. + * Must have the same number of limbs as \p A. + * \param[in] A The MPI to convert from Montgomery form. + * Must have the same number of limbs as the modulus. + * \param[in] N The address of the modulus, which gives the size of + * the base `R` = 2^(biL*N->limbs). + * \param[in] AN_limbs The number of limbs in \p X, \p A and \p N. + * \param mm The Montgomery constant for \p N: -N^-1 mod 2^biL. + * This can be determined by calling + * `mbedtls_mpi_core_montmul_init()`. + * \param[in,out] T Temporary storage of size at least + * `mbedtls_mpi_core_montmul_working_limbs(AN_limbs)` + * limbs. + * Its initial content is unused and + * its final content is indeterminate. + * It must not alias or otherwise overlap any of the + * other parameters. + */ +void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X, + const mbedtls_mpi_uint *A, + const mbedtls_mpi_uint *N, + size_t AN_limbs, + mbedtls_mpi_uint mm, + mbedtls_mpi_uint *T); + +#endif /* MBEDTLS_BIGNUM_CORE_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/bn_mul.h b/src/app/findmy/crypto/third-party/mbedtls/library/bn_mul.h new file mode 100644 index 0000000..0738469 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/bn_mul.h @@ -0,0 +1,1094 @@ +/** + * \file bn_mul.h + * + * \brief Multi-precision integer library + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +/* + * Multiply source vector [s] with b, add result + * to destination vector [d] and set carry c. + * + * Currently supports: + * + * . IA-32 (386+) . AMD64 / EM64T + * . IA-32 (SSE2) . Motorola 68000 + * . PowerPC, 32-bit . MicroBlaze + * . PowerPC, 64-bit . TriCore + * . SPARC v8 . ARM v3+ + * . Alpha . MIPS32 + * . C, longlong . C, generic + */ +#ifndef MBEDTLS_BN_MUL_H +#define MBEDTLS_BN_MUL_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/bignum.h" + + +/* + * Conversion macros for embedded constants: + * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(MBEDTLS_HAVE_INT32) + +#define MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d) \ + ((mbedtls_mpi_uint) (a) << 0) | \ + ((mbedtls_mpi_uint) (b) << 8) | \ + ((mbedtls_mpi_uint) (c) << 16) | \ + ((mbedtls_mpi_uint) (d) << 24) + +#define MBEDTLS_BYTES_TO_T_UINT_2(a, b) \ + MBEDTLS_BYTES_TO_T_UINT_4(a, b, 0, 0) + +#define MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, e, f, g, h) \ + MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d), \ + MBEDTLS_BYTES_TO_T_UINT_4(e, f, g, h) + +#else /* 64-bits */ + +#define MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, e, f, g, h) \ + ((mbedtls_mpi_uint) (a) << 0) | \ + ((mbedtls_mpi_uint) (b) << 8) | \ + ((mbedtls_mpi_uint) (c) << 16) | \ + ((mbedtls_mpi_uint) (d) << 24) | \ + ((mbedtls_mpi_uint) (e) << 32) | \ + ((mbedtls_mpi_uint) (f) << 40) | \ + ((mbedtls_mpi_uint) (g) << 48) | \ + ((mbedtls_mpi_uint) (h) << 56) + +#define MBEDTLS_BYTES_TO_T_UINT_4(a, b, c, d) \ + MBEDTLS_BYTES_TO_T_UINT_8(a, b, c, d, 0, 0, 0, 0) + +#define MBEDTLS_BYTES_TO_T_UINT_2(a, b) \ + MBEDTLS_BYTES_TO_T_UINT_8(a, b, 0, 0, 0, 0, 0, 0) + +#endif /* bits in mbedtls_mpi_uint */ + +/* *INDENT-OFF* */ +#if defined(MBEDTLS_HAVE_ASM) + +/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ +#if defined(__GNUC__) && \ + ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) + +/* + * GCC < 5.0 treated the x86 ebx (which is used for the GOT) as a + * fixed reserved register when building as PIC, leading to errors + * like: bn_mul.h:46:13: error: PIC register clobbered by 'ebx' in 'asm' + * + * This is fixed by an improved register allocator in GCC 5+. From the + * release notes: + * Register allocation improvements: Reuse of the PIC hard register, + * instead of using a fixed register, was implemented on x86/x86-64 + * targets. This improves generated PIC code performance as more hard + * registers can be used. + */ +#if defined(__GNUC__) && __GNUC__ < 5 && defined(__PIC__) +#define MULADDC_CANNOT_USE_EBX +#endif + +/* + * Disable use of the i386 assembly code below if option -O0, to disable all + * compiler optimisations, is passed, detected with __OPTIMIZE__ + * This is done as the number of registers used in the assembly code doesn't + * work with the -O0 option. + */ +#if defined(__i386__) && defined(__OPTIMIZE__) && !defined(MULADDC_CANNOT_USE_EBX) + +#define MULADDC_X1_INIT \ + { mbedtls_mpi_uint t; \ + asm( \ + "movl %%ebx, %0 \n\t" \ + "movl %5, %%esi \n\t" \ + "movl %6, %%edi \n\t" \ + "movl %7, %%ecx \n\t" \ + "movl %8, %%ebx \n\t" + +#define MULADDC_X1_CORE \ + "lodsl \n\t" \ + "mull %%ebx \n\t" \ + "addl %%ecx, %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "addl (%%edi), %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "movl %%edx, %%ecx \n\t" \ + "stosl \n\t" + +#define MULADDC_X1_STOP \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ebx", "ecx", "edx", "esi", "edi" \ + ); } + +#if defined(MBEDTLS_HAVE_SSE2) + +#define MULADDC_X8_INIT MULADDC_X1_INIT + +#define MULADDC_X8_CORE \ + "movd %%ecx, %%mm1 \n\t" \ + "movd %%ebx, %%mm0 \n\t" \ + "movd (%%edi), %%mm3 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd (%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "movd 4(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "movd 8(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd 12(%%esi), %%mm7 \n\t" \ + "pmuludq %%mm0, %%mm7 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 4(%%edi), %%mm3 \n\t" \ + "paddq %%mm4, %%mm3 \n\t" \ + "movd 8(%%edi), %%mm5 \n\t" \ + "paddq %%mm6, %%mm5 \n\t" \ + "movd 12(%%edi), %%mm4 \n\t" \ + "paddq %%mm4, %%mm7 \n\t" \ + "movd %%mm1, (%%edi) \n\t" \ + "movd 16(%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 20(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd 24(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd %%mm1, 4(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 28(%%esi), %%mm3 \n\t" \ + "pmuludq %%mm0, %%mm3 \n\t" \ + "paddq %%mm5, %%mm1 \n\t" \ + "movd 16(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm2 \n\t" \ + "movd %%mm1, 8(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm7, %%mm1 \n\t" \ + "movd 20(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm4 \n\t" \ + "movd %%mm1, 12(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 24(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm6 \n\t" \ + "movd %%mm1, 16(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm4, %%mm1 \n\t" \ + "movd 28(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm3 \n\t" \ + "movd %%mm1, 20(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm6, %%mm1 \n\t" \ + "movd %%mm1, 24(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd %%mm1, 28(%%edi) \n\t" \ + "addl $32, %%edi \n\t" \ + "addl $32, %%esi \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd %%mm1, %%ecx \n\t" + +#define MULADDC_X8_STOP \ + "emms \n\t" \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ebx", "ecx", "edx", "esi", "edi" \ + ); } \ + +#endif /* SSE2 */ + +#endif /* i386 */ + +#if defined(__amd64__) || defined (__x86_64__) + +#define MULADDC_X1_INIT \ + asm( \ + "xorq %%r8, %%r8\n" + +#define MULADDC_X1_CORE \ + "movq (%%rsi), %%rax\n" \ + "mulq %%rbx\n" \ + "addq $8, %%rsi\n" \ + "addq %%rcx, %%rax\n" \ + "movq %%r8, %%rcx\n" \ + "adcq $0, %%rdx\n" \ + "nop \n" \ + "addq %%rax, (%%rdi)\n" \ + "adcq %%rdx, %%rcx\n" \ + "addq $8, %%rdi\n" + +#define MULADDC_X1_STOP \ + : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \ + : "b" (b), "m" (*(const uint64_t (*)[16]) s) \ + : "rax", "rdx", "r8" \ + ); + +#endif /* AMD64 */ + +// The following assembly code assumes that a pointer will fit in a 64-bit register +// (including ILP32 __aarch64__ ABIs such as on watchOS, hence the 2^32 - 1) +#if defined(__aarch64__) && (UINTPTR_MAX == 0xfffffffful || UINTPTR_MAX == 0xfffffffffffffffful) + +/* + * There are some issues around different compilers requiring different constraint + * syntax for updating pointers from assembly code (see notes for + * MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT in common.h), especially on aarch64_32 (aka ILP32). + * + * For this reason we cast the pointers to/from uintptr_t here. + */ +#define MULADDC_X1_INIT \ + do { uintptr_t muladdc_d = (uintptr_t) d, muladdc_s = (uintptr_t) s; asm( + +#define MULADDC_X1_CORE \ + "ldr x4, [%x2], #8 \n\t" \ + "ldr x5, [%x1] \n\t" \ + "mul x6, x4, %4 \n\t" \ + "umulh x7, x4, %4 \n\t" \ + "adds x5, x5, x6 \n\t" \ + "adc x7, x7, xzr \n\t" \ + "adds x5, x5, %0 \n\t" \ + "adc %0, x7, xzr \n\t" \ + "str x5, [%x1], #8 \n\t" + +#define MULADDC_X1_STOP \ + : "+r" (c), \ + "+r" (muladdc_d), \ + "+r" (muladdc_s), \ + "+m" (*(uint64_t (*)[16]) d) \ + : "r" (b), "m" (*(const uint64_t (*)[16]) s) \ + : "x4", "x5", "x6", "x7", "cc" \ + ); d = (mbedtls_mpi_uint *)muladdc_d; s = (mbedtls_mpi_uint *)muladdc_s; } while (0); + +#endif /* Aarch64 */ + +#if defined(__mc68020__) || defined(__mcpu32__) + +#define MULADDC_X1_INIT \ + asm( \ + "movl %3, %%a2 \n\t" \ + "movl %4, %%a3 \n\t" \ + "movl %5, %%d3 \n\t" \ + "movl %6, %%d2 \n\t" \ + "moveq #0, %%d0 \n\t" + +#define MULADDC_X1_CORE \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "moveq #0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d4, %%d3 \n\t" + +#define MULADDC_X1_STOP \ + "movl %%d3, %0 \n\t" \ + "movl %%a3, %1 \n\t" \ + "movl %%a2, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ + ); + +#define MULADDC_X8_INIT MULADDC_X1_INIT + +#define MULADDC_X8_CORE \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d0, %%d3 \n\t" + +#define MULADDC_X8_STOP MULADDC_X1_STOP + +#endif /* MC68000 */ + +#if defined(__powerpc64__) || defined(__ppc64__) + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_X1_INIT \ + asm( \ + "ld r3, %3 \n\t" \ + "ld r4, %4 \n\t" \ + "ld r5, %5 \n\t" \ + "ld r6, %6 \n\t" \ + "addi r3, r3, -8 \n\t" \ + "addi r4, r4, -8 \n\t" \ + "addic r5, r5, 0 \n\t" + +#define MULADDC_X1_CORE \ + "ldu r7, 8(r3) \n\t" \ + "mulld r8, r7, r6 \n\t" \ + "mulhdu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "ld r7, 8(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stdu r8, 8(r4) \n\t" + +#define MULADDC_X1_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 8 \n\t" \ + "addi r3, r3, 8 \n\t" \ + "std r5, %0 \n\t" \ + "std r4, %1 \n\t" \ + "std r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + + +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_X1_INIT \ + asm( \ + "ld %%r3, %3 \n\t" \ + "ld %%r4, %4 \n\t" \ + "ld %%r5, %5 \n\t" \ + "ld %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -8 \n\t" \ + "addi %%r4, %%r4, -8 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_X1_CORE \ + "ldu %%r7, 8(%%r3) \n\t" \ + "mulld %%r8, %%r7, %%r6 \n\t" \ + "mulhdu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "ld %%r7, 8(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stdu %%r8, 8(%%r4) \n\t" + +#define MULADDC_X1_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 8 \n\t" \ + "addi %%r3, %%r3, 8 \n\t" \ + "std %%r5, %0 \n\t" \ + "std %%r4, %1 \n\t" \ + "std %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#endif /* __MACH__ && __APPLE__ */ + +#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_X1_INIT \ + asm( \ + "lwz r3, %3 \n\t" \ + "lwz r4, %4 \n\t" \ + "lwz r5, %5 \n\t" \ + "lwz r6, %6 \n\t" \ + "addi r3, r3, -4 \n\t" \ + "addi r4, r4, -4 \n\t" \ + "addic r5, r5, 0 \n\t" + +#define MULADDC_X1_CORE \ + "lwzu r7, 4(r3) \n\t" \ + "mullw r8, r7, r6 \n\t" \ + "mulhwu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "lwz r7, 4(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stwu r8, 4(r4) \n\t" + +#define MULADDC_X1_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 4 \n\t" \ + "addi r3, r3, 4 \n\t" \ + "stw r5, %0 \n\t" \ + "stw r4, %1 \n\t" \ + "stw r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_X1_INIT \ + asm( \ + "lwz %%r3, %3 \n\t" \ + "lwz %%r4, %4 \n\t" \ + "lwz %%r5, %5 \n\t" \ + "lwz %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -4 \n\t" \ + "addi %%r4, %%r4, -4 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_X1_CORE \ + "lwzu %%r7, 4(%%r3) \n\t" \ + "mullw %%r8, %%r7, %%r6 \n\t" \ + "mulhwu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "lwz %%r7, 4(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stwu %%r8, 4(%%r4) \n\t" + +#define MULADDC_X1_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 4 \n\t" \ + "addi %%r3, %%r3, 4 \n\t" \ + "stw %%r5, %0 \n\t" \ + "stw %%r4, %1 \n\t" \ + "stw %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#endif /* __MACH__ && __APPLE__ */ + +#endif /* PPC32 */ + +/* + * The Sparc(64) assembly is reported to be broken. + * Disable it for now, until we're able to fix it. + */ +#if 0 && defined(__sparc__) +#if defined(__sparc64__) + +#define MULADDC_X1_INIT \ + asm( \ + "ldx %3, %%o0 \n\t" \ + "ldx %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_X1_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + +#define MULADDC_X1_STOP \ + "st %%o2, %0 \n\t" \ + "stx %%o1, %1 \n\t" \ + "stx %%o0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); + +#else /* __sparc64__ */ + +#define MULADDC_X1_INIT \ + asm( \ + "ld %3, %%o0 \n\t" \ + "ld %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_X1_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + +#define MULADDC_X1_STOP \ + "st %%o2, %0 \n\t" \ + "st %%o1, %1 \n\t" \ + "st %%o0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); + +#endif /* __sparc64__ */ +#endif /* __sparc__ */ + +#if defined(__microblaze__) || defined(microblaze) + +#define MULADDC_X1_INIT \ + asm( \ + "lwi r3, %3 \n\t" \ + "lwi r4, %4 \n\t" \ + "lwi r5, %5 \n\t" \ + "lwi r6, %6 \n\t" \ + "andi r7, r6, 0xffff \n\t" \ + "bsrli r6, r6, 16 \n\t" + +#if(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define MULADDC_LHUI \ + "lhui r9, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "lhui r8, r3, 0 \n\t" +#else +#define MULADDC_LHUI \ + "lhui r8, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "lhui r9, r3, 0 \n\t" +#endif + +#define MULADDC_X1_CORE \ + MULADDC_LHUI \ + "addi r3, r3, 2 \n\t" \ + "mul r10, r9, r6 \n\t" \ + "mul r11, r8, r7 \n\t" \ + "mul r12, r9, r7 \n\t" \ + "mul r13, r8, r6 \n\t" \ + "bsrli r8, r10, 16 \n\t" \ + "bsrli r9, r11, 16 \n\t" \ + "add r13, r13, r8 \n\t" \ + "add r13, r13, r9 \n\t" \ + "bslli r10, r10, 16 \n\t" \ + "bslli r11, r11, 16 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r11 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "lwi r10, r4, 0 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r5 \n\t" \ + "addc r5, r13, r0 \n\t" \ + "swi r12, r4, 0 \n\t" \ + "addi r4, r4, 4 \n\t" + +#define MULADDC_X1_STOP \ + "swi r5, %0 \n\t" \ + "swi r4, %1 \n\t" \ + "swi r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", \ + "r9", "r10", "r11", "r12", "r13" \ + ); + +#endif /* MicroBlaze */ + +#if defined(__tricore__) + +#define MULADDC_X1_INIT \ + asm( \ + "ld.a %%a2, %3 \n\t" \ + "ld.a %%a3, %4 \n\t" \ + "ld.w %%d4, %5 \n\t" \ + "ld.w %%d1, %6 \n\t" \ + "xor %%d5, %%d5 \n\t" + +#define MULADDC_X1_CORE \ + "ld.w %%d0, [%%a2+] \n\t" \ + "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ + "ld.w %%d0, [%%a3] \n\t" \ + "addx %%d2, %%d2, %%d0 \n\t" \ + "addc %%d3, %%d3, 0 \n\t" \ + "mov %%d4, %%d3 \n\t" \ + "st.w [%%a3+], %%d2 \n\t" + +#define MULADDC_X1_STOP \ + "st.w %0, %%d4 \n\t" \ + "st.a %1, %%a3 \n\t" \ + "st.a %2, %%a2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "e2", "d4", "a2", "a3" \ + ); + +#endif /* TriCore */ + +#if defined(__arm__) + +#if defined(__thumb__) && !defined(__thumb2__) +#if defined(MBEDTLS_COMPILER_IS_GCC) +/* + * Thumb 1 ISA. This code path has only been tested successfully on gcc; + * it does not compile on clang or armclang. + */ + +#if !defined(__OPTIMIZE__) && defined(__GNUC__) +/* + * Note, gcc -O0 by default uses r7 for the frame pointer, so it complains about + * our use of r7 below, unless -fomit-frame-pointer is passed. + * + * On the other hand, -fomit-frame-pointer is implied by any -Ox options with + * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by + * clang and armcc5 under the same conditions). + * + * If gcc needs to use r7, we use r1 as a scratch register and have a few extra + * instructions to preserve/restore it; otherwise, we can use r7 and avoid + * the preserve/restore overhead. + */ +#define MULADDC_SCRATCH "RS .req r1 \n\t" +#define MULADDC_PRESERVE_SCRATCH "mov r10, r1 \n\t" +#define MULADDC_RESTORE_SCRATCH "mov r1, r10 \n\t" +#define MULADDC_SCRATCH_CLOBBER "r10" +#else /* !defined(__OPTIMIZE__) && defined(__GNUC__) */ +#define MULADDC_SCRATCH "RS .req r7 \n\t" +#define MULADDC_PRESERVE_SCRATCH "" +#define MULADDC_RESTORE_SCRATCH "" +#define MULADDC_SCRATCH_CLOBBER "r7" +#endif /* !defined(__OPTIMIZE__) && defined(__GNUC__) */ + +#define MULADDC_X1_INIT \ + asm( \ + MULADDC_SCRATCH \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" \ + "lsr r4, r3, #16 \n\t" \ + "mov r9, r4 \n\t" \ + "lsl r4, r3, #16 \n\t" \ + "lsr r4, r4, #16 \n\t" \ + "mov r8, r4 \n\t" \ + + +#define MULADDC_X1_CORE \ + MULADDC_PRESERVE_SCRATCH \ + "ldmia r0!, {r6} \n\t" \ + "lsr RS, r6, #16 \n\t" \ + "lsl r6, r6, #16 \n\t" \ + "lsr r6, r6, #16 \n\t" \ + "mov r4, r8 \n\t" \ + "mul r4, r6 \n\t" \ + "mov r3, r9 \n\t" \ + "mul r6, r3 \n\t" \ + "mov r5, r9 \n\t" \ + "mul r5, RS \n\t" \ + "mov r3, r8 \n\t" \ + "mul RS, r3 \n\t" \ + "lsr r3, r6, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "lsr r3, RS, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "add r4, r4, r2 \n\t" \ + "mov r2, #0 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, r6, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, RS, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + MULADDC_RESTORE_SCRATCH \ + "ldr r3, [r1] \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r2, r5 \n\t" \ + "stmia r1!, {r4} \n\t" + +#define MULADDC_X1_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", MULADDC_SCRATCH_CLOBBER, "r8", "r9", "cc" \ + ); +#endif /* !defined(__ARMCC_VERSION) && !defined(__clang__) */ + +#elif (__ARM_ARCH >= 6) && \ + defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1) +/* Armv6-M (or later) with DSP Instruction Set Extensions. + * Requires support for either Thumb 2 or Arm ISA. + */ + +#define MULADDC_X1_INIT \ + { \ + mbedtls_mpi_uint tmp_a, tmp_b; \ + asm volatile ( + +#define MULADDC_X1_CORE \ + ".p2align 2 \n\t" \ + "ldr %[a], [%[in]], #4 \n\t" \ + "ldr %[b], [%[acc]] \n\t" \ + "umaal %[b], %[carry], %[scalar], %[a] \n\t" \ + "str %[b], [%[acc]], #4 \n\t" + +#define MULADDC_X1_STOP \ + : [a] "=&r" (tmp_a), \ + [b] "=&r" (tmp_b), \ + [in] "+r" (s), \ + [acc] "+r" (d), \ + [carry] "+l" (c) \ + : [scalar] "r" (b) \ + : "memory" \ + ); \ + } + +#define MULADDC_X2_INIT \ + { \ + mbedtls_mpi_uint tmp_a0, tmp_b0; \ + mbedtls_mpi_uint tmp_a1, tmp_b1; \ + asm volatile ( + + /* - Make sure loop is 4-byte aligned to avoid stalls + * upon repeated non-word aligned instructions in + * some microarchitectures. + * - Don't use ldm with post-increment or back-to-back + * loads with post-increment and same address register + * to avoid stalls on some microarchitectures. + * - Bunch loads and stores to reduce latency on some + * microarchitectures. E.g., on Cortex-M4, the first + * in a series of load/store operations has latency + * 2 cycles, while subsequent loads/stores are single-cycle. */ +#define MULADDC_X2_CORE \ + ".p2align 2 \n\t" \ + "ldr %[a0], [%[in]], #+8 \n\t" \ + "ldr %[b0], [%[acc]], #+8 \n\t" \ + "ldr %[a1], [%[in], #-4] \n\t" \ + "ldr %[b1], [%[acc], #-4] \n\t" \ + "umaal %[b0], %[carry], %[scalar], %[a0] \n\t" \ + "umaal %[b1], %[carry], %[scalar], %[a1] \n\t" \ + "str %[b0], [%[acc], #-8] \n\t" \ + "str %[b1], [%[acc], #-4] \n\t" + +#define MULADDC_X2_STOP \ + : [a0] "=&r" (tmp_a0), \ + [b0] "=&r" (tmp_b0), \ + [a1] "=&r" (tmp_a1), \ + [b1] "=&r" (tmp_b1), \ + [in] "+r" (s), \ + [acc] "+r" (d), \ + [carry] "+l" (c) \ + : [scalar] "r" (b) \ + : "memory" \ + ); \ + } + +#else /* Thumb 2 or Arm ISA, without DSP extensions */ + +#define MULADDC_X1_INIT \ + asm( \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" + +#define MULADDC_X1_CORE \ + "ldr r4, [r0], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r1] \n\t" \ + "umlal r2, r5, r3, r4 \n\t" \ + "adds r4, r6, r2 \n\t" \ + "adc r2, r5, #0 \n\t" \ + "str r4, [r1], #4 \n\t" + +#define MULADDC_X1_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", "cc" \ + ); + +#endif /* ISA codepath selection */ + +#endif /* defined(__arm__) */ + +#if defined(__alpha__) + +#define MULADDC_X1_INIT \ + asm( \ + "ldq $1, %3 \n\t" \ + "ldq $2, %4 \n\t" \ + "ldq $3, %5 \n\t" \ + "ldq $4, %6 \n\t" + +#define MULADDC_X1_CORE \ + "ldq $6, 0($1) \n\t" \ + "addq $1, 8, $1 \n\t" \ + "mulq $6, $4, $7 \n\t" \ + "umulh $6, $4, $6 \n\t" \ + "addq $7, $3, $7 \n\t" \ + "cmpult $7, $3, $3 \n\t" \ + "ldq $5, 0($2) \n\t" \ + "addq $7, $5, $7 \n\t" \ + "cmpult $7, $5, $5 \n\t" \ + "stq $7, 0($2) \n\t" \ + "addq $2, 8, $2 \n\t" \ + "addq $6, $3, $3 \n\t" \ + "addq $5, $3, $3 \n\t" + +#define MULADDC_X1_STOP \ + "stq $3, %0 \n\t" \ + "stq $2, %1 \n\t" \ + "stq $1, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ + ); +#endif /* Alpha */ + +#if defined(__mips__) && !defined(__mips64) + +#define MULADDC_X1_INIT \ + asm( \ + "lw $10, %3 \n\t" \ + "lw $11, %4 \n\t" \ + "lw $12, %5 \n\t" \ + "lw $13, %6 \n\t" + +#define MULADDC_X1_CORE \ + "lw $14, 0($10) \n\t" \ + "multu $13, $14 \n\t" \ + "addi $10, $10, 4 \n\t" \ + "mflo $14 \n\t" \ + "mfhi $9 \n\t" \ + "addu $14, $12, $14 \n\t" \ + "lw $15, 0($11) \n\t" \ + "sltu $12, $14, $12 \n\t" \ + "addu $15, $14, $15 \n\t" \ + "sltu $14, $15, $14 \n\t" \ + "addu $12, $12, $9 \n\t" \ + "sw $15, 0($11) \n\t" \ + "addu $12, $12, $14 \n\t" \ + "addi $11, $11, 4 \n\t" + +#define MULADDC_X1_STOP \ + "sw $12, %0 \n\t" \ + "sw $11, %1 \n\t" \ + "sw $10, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \ + ); + +#endif /* MIPS */ +#endif /* GNUC */ + +#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + +#define MULADDC_X1_INIT \ + __asm mov esi, s \ + __asm mov edi, d \ + __asm mov ecx, c \ + __asm mov ebx, b + +#define MULADDC_X1_CORE \ + __asm lodsd \ + __asm mul ebx \ + __asm add eax, ecx \ + __asm adc edx, 0 \ + __asm add eax, [edi] \ + __asm adc edx, 0 \ + __asm mov ecx, edx \ + __asm stosd + +#define MULADDC_X1_STOP \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi + +#if defined(MBEDTLS_HAVE_SSE2) + +#define EMIT __asm _emit + +#define MULADDC_X8_INIT MULADDC_X1_INIT + +#define MULADDC_X8_CORE \ + EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ + EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ + EMIT 0x0F EMIT 0x6E EMIT 0x1F \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x16 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ + EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ + EMIT 0x0F EMIT 0x7E EMIT 0x0F \ + EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ + EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ + EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x7E EMIT 0xC9 + +#define MULADDC_X8_STOP \ + EMIT 0x0F EMIT 0x77 \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi + +#endif /* SSE2 */ +#endif /* MSVC */ + +#endif /* MBEDTLS_HAVE_ASM */ + +#if !defined(MULADDC_X1_CORE) +#if defined(MBEDTLS_HAVE_UDBL) + +#define MULADDC_X1_INIT \ +{ \ + mbedtls_t_udbl r; \ + mbedtls_mpi_uint r0, r1; + +#define MULADDC_X1_CORE \ + r = *(s++) * (mbedtls_t_udbl) b; \ + r0 = (mbedtls_mpi_uint) r; \ + r1 = (mbedtls_mpi_uint)( r >> biL ); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_X1_STOP \ +} + +#else /* MBEDTLS_HAVE_UDBL */ + +#define MULADDC_X1_INIT \ +{ \ + mbedtls_mpi_uint s0, s1, b0, b1; \ + mbedtls_mpi_uint r0, r1, rx, ry; \ + b0 = ( b << biH ) >> biH; \ + b1 = ( b >> biH ); + +#define MULADDC_X1_CORE \ + s0 = ( *s << biH ) >> biH; \ + s1 = ( *s >> biH ); s++; \ + rx = s0 * b1; r0 = s0 * b0; \ + ry = s1 * b0; r1 = s1 * b1; \ + r1 += ( rx >> biH ); \ + r1 += ( ry >> biH ); \ + rx <<= biH; ry <<= biH; \ + r0 += rx; r1 += (r0 < rx); \ + r0 += ry; r1 += (r0 < ry); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_X1_STOP \ +} + +#endif /* C (longlong) */ +#endif /* C (generic) */ + +#if !defined(MULADDC_X2_CORE) +#define MULADDC_X2_INIT MULADDC_X1_INIT +#define MULADDC_X2_STOP MULADDC_X1_STOP +#define MULADDC_X2_CORE MULADDC_X1_CORE MULADDC_X1_CORE +#endif /* MULADDC_X2_CORE */ + +#if !defined(MULADDC_X4_CORE) +#define MULADDC_X4_INIT MULADDC_X2_INIT +#define MULADDC_X4_STOP MULADDC_X2_STOP +#define MULADDC_X4_CORE MULADDC_X2_CORE MULADDC_X2_CORE +#endif /* MULADDC_X4_CORE */ + +#if !defined(MULADDC_X8_CORE) +#define MULADDC_X8_INIT MULADDC_X4_INIT +#define MULADDC_X8_STOP MULADDC_X4_STOP +#define MULADDC_X8_CORE MULADDC_X4_CORE MULADDC_X4_CORE +#endif /* MULADDC_X8_CORE */ + +/* *INDENT-ON* */ +#endif /* bn_mul.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/cipher.c b/src/app/findmy/crypto/third-party/mbedtls/library/cipher.c new file mode 100644 index 0000000..e9ad2ba --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/cipher.c @@ -0,0 +1,1664 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for Mbed TLS + * + * \author Adriaan de Jong + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher.h" +#include "cipher_wrap.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" +#include "mbedtls/constant_time.h" +#include "constant_time_internal.h" + +#include +#include + +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) +#include "psa/crypto.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_NIST_KW_C) +#include "mbedtls/nist_kw.h" +#endif + +#include "mbedtls/platform.h" + +static int supported_init = 0; + +static inline const mbedtls_cipher_base_t *mbedtls_cipher_get_base( + const mbedtls_cipher_info_t *info) +{ + return mbedtls_cipher_base_lookup_table[info->base_idx]; +} + +const int *mbedtls_cipher_list(void) +{ + const mbedtls_cipher_definition_t *def; + int *type; + + if (!supported_init) { + def = mbedtls_cipher_definitions; + type = mbedtls_cipher_supported; + + while (def->type != 0) { + *type++ = (*def++).type; + } + + *type = 0; + + supported_init = 1; + } + + return mbedtls_cipher_supported; +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( + const mbedtls_cipher_type_t cipher_type) +{ + const mbedtls_cipher_definition_t *def; + + for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { + if (def->type == cipher_type) { + return def->info; + } + } + + return NULL; +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( + const char *cipher_name) +{ + const mbedtls_cipher_definition_t *def; + + if (NULL == cipher_name) { + return NULL; + } + + for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { + if (!strcmp(def->info->name, cipher_name)) { + return def->info; + } + } + + return NULL; +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( + const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode) +{ + const mbedtls_cipher_definition_t *def; + + for (def = mbedtls_cipher_definitions; def->info != NULL; def++) { + if (mbedtls_cipher_get_base(def->info)->cipher == cipher_id && + mbedtls_cipher_info_get_key_bitlen(def->info) == (unsigned) key_bitlen && + def->info->mode == mode) { + return def->info; + } + } + + return NULL; +} + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) +static inline psa_key_type_t mbedtls_psa_translate_cipher_type( + mbedtls_cipher_type_t cipher) +{ + switch (cipher) { + case MBEDTLS_CIPHER_AES_128_CCM: + case MBEDTLS_CIPHER_AES_192_CCM: + case MBEDTLS_CIPHER_AES_256_CCM: + case MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_AES_128_GCM: + case MBEDTLS_CIPHER_AES_192_GCM: + case MBEDTLS_CIPHER_AES_256_GCM: + case MBEDTLS_CIPHER_AES_128_CBC: + case MBEDTLS_CIPHER_AES_192_CBC: + case MBEDTLS_CIPHER_AES_256_CBC: + case MBEDTLS_CIPHER_AES_128_ECB: + case MBEDTLS_CIPHER_AES_192_ECB: + case MBEDTLS_CIPHER_AES_256_ECB: + return PSA_KEY_TYPE_AES; + + /* ARIA not yet supported in PSA. */ + /* case MBEDTLS_CIPHER_ARIA_128_CCM: + case MBEDTLS_CIPHER_ARIA_192_CCM: + case MBEDTLS_CIPHER_ARIA_256_CCM: + case MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG: + case MBEDTLS_CIPHER_ARIA_128_GCM: + case MBEDTLS_CIPHER_ARIA_192_GCM: + case MBEDTLS_CIPHER_ARIA_256_GCM: + case MBEDTLS_CIPHER_ARIA_128_CBC: + case MBEDTLS_CIPHER_ARIA_192_CBC: + case MBEDTLS_CIPHER_ARIA_256_CBC: + return( PSA_KEY_TYPE_ARIA ); */ + + default: + return 0; + } +} + +static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode( + mbedtls_cipher_mode_t mode, size_t taglen) +{ + switch (mode) { + case MBEDTLS_MODE_ECB: + return PSA_ALG_ECB_NO_PADDING; + case MBEDTLS_MODE_GCM: + return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, taglen); + case MBEDTLS_MODE_CCM: + return PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, taglen); + case MBEDTLS_MODE_CCM_STAR_NO_TAG: + return PSA_ALG_CCM_STAR_NO_TAG; + case MBEDTLS_MODE_CBC: + if (taglen == 0) { + return PSA_ALG_CBC_NO_PADDING; + } else { + return 0; + } + default: + return 0; + } +} +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +void mbedtls_cipher_init(mbedtls_cipher_context_t *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); +} + +void mbedtls_cipher_free(mbedtls_cipher_context_t *ctx) +{ + if (ctx == NULL) { + return; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + if (ctx->cipher_ctx != NULL) { + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + if (cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED) { + /* xxx_free() doesn't allow to return failures. */ + (void) psa_destroy_key(cipher_psa->slot); + } + + mbedtls_zeroize_and_free(cipher_psa, sizeof(*cipher_psa)); + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); + return; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_CMAC_C) + if (ctx->cmac_ctx) { + mbedtls_zeroize_and_free(ctx->cmac_ctx, + sizeof(mbedtls_cmac_context_t)); + } +#endif + + if (ctx->cipher_ctx) { + mbedtls_cipher_get_base(ctx->cipher_info)->ctx_free_func(ctx->cipher_ctx); + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_cipher_context_t)); +} + +int mbedtls_cipher_setup(mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info) +{ + if (cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); + + if (NULL == (ctx->cipher_ctx = mbedtls_cipher_get_base(cipher_info)->ctx_alloc_func())) { + return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; + } + + ctx->cipher_info = cipher_info; + + return 0; +} + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) +int mbedtls_cipher_setup_psa(mbedtls_cipher_context_t *ctx, + const mbedtls_cipher_info_t *cipher_info, + size_t taglen) +{ + psa_algorithm_t alg; + mbedtls_cipher_context_psa *cipher_psa; + + if (NULL == cipher_info || NULL == ctx) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + /* Check that the underlying cipher mode and cipher type are + * supported by the underlying PSA Crypto implementation. */ + alg = mbedtls_psa_translate_cipher_mode(((mbedtls_cipher_mode_t) cipher_info->mode), taglen); + if (alg == 0) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + if (mbedtls_psa_translate_cipher_type(((mbedtls_cipher_type_t) cipher_info->type)) == 0) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + memset(ctx, 0, sizeof(mbedtls_cipher_context_t)); + + cipher_psa = mbedtls_calloc(1, sizeof(mbedtls_cipher_context_psa)); + if (cipher_psa == NULL) { + return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; + } + cipher_psa->alg = alg; + ctx->cipher_ctx = cipher_psa; + ctx->cipher_info = cipher_info; + ctx->psa_enabled = 1; + return 0; +} +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +int mbedtls_cipher_setkey(mbedtls_cipher_context_t *ctx, + const unsigned char *key, + int key_bitlen, + const mbedtls_operation_t operation) +{ + if (operation != MBEDTLS_ENCRYPT && operation != MBEDTLS_DECRYPT) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + size_t const key_bytelen = ((size_t) key_bitlen + 7) / 8; + + psa_status_t status; + psa_key_type_t key_type; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* PSA Crypto API only accepts byte-aligned keys. */ + if (key_bitlen % 8 != 0) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + /* Don't allow keys to be set multiple times. */ + if (cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + key_type = mbedtls_psa_translate_cipher_type( + ((mbedtls_cipher_type_t) ctx->cipher_info->type)); + if (key_type == 0) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + psa_set_key_type(&attributes, key_type); + + /* Mbed TLS' cipher layer doesn't enforce the mode of operation + * (encrypt vs. decrypt): it is possible to setup a key for encryption + * and use it for AEAD decryption. Until tests relying on this + * are changed, allow any usage in PSA. */ + psa_set_key_usage_flags(&attributes, + PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, cipher_psa->alg); + + status = psa_import_key(&attributes, key, key_bytelen, + &cipher_psa->slot); + switch (status) { + case PSA_SUCCESS: + break; + case PSA_ERROR_INSUFFICIENT_MEMORY: + return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; + case PSA_ERROR_NOT_SUPPORTED: + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + default: + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + /* Indicate that we own the key slot and need to + * destroy it in mbedtls_cipher_free(). */ + cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED; + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + return 0; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN) == 0 && + (int) mbedtls_cipher_info_get_key_bitlen(ctx->cipher_info) != key_bitlen) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + + /* + * For OFB, CFB and CTR mode always use the encryption key schedule + */ + if (MBEDTLS_ENCRYPT == operation || + MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_enc_func(ctx->cipher_ctx, key, + ctx->key_bitlen); + } + + if (MBEDTLS_DECRYPT == operation) { + return mbedtls_cipher_get_base(ctx->cipher_info)->setkey_dec_func(ctx->cipher_ctx, key, + ctx->key_bitlen); + } + + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; +} + +int mbedtls_cipher_set_iv(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, + size_t iv_len) +{ + size_t actual_iv_size; + + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + /* avoid buffer overflow in ctx->iv */ + if (iv_len > MBEDTLS_MAX_IV_LENGTH) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + if ((ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN) != 0) { + actual_iv_size = iv_len; + } else { + actual_iv_size = mbedtls_cipher_info_get_iv_size(ctx->cipher_info); + + /* avoid reading past the end of input buffer */ + if (actual_iv_size > iv_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + } + +#if defined(MBEDTLS_CHACHA20_C) + if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20) { + /* Even though the actual_iv_size is overwritten with a correct value + * of 12 from the cipher info, return an error to indicate that + * the input iv_len is wrong. */ + if (iv_len != 12) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (0 != mbedtls_chacha20_starts((mbedtls_chacha20_context *) ctx->cipher_ctx, + iv, + 0U)) { /* Initial counter value */ + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + } +#if defined(MBEDTLS_CHACHAPOLY_C) + if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305 && + iv_len != 12) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } +#endif +#endif + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + return mbedtls_gcm_starts((mbedtls_gcm_context *) ctx->cipher_ctx, + ctx->operation, + iv, iv_len); + } +#endif + +#if defined(MBEDTLS_CCM_C) + if (MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + int set_lengths_result; + int ccm_star_mode; + + set_lengths_result = mbedtls_ccm_set_lengths( + (mbedtls_ccm_context *) ctx->cipher_ctx, + 0, 0, 0); + if (set_lengths_result != 0) { + return set_lengths_result; + } + + if (ctx->operation == MBEDTLS_DECRYPT) { + ccm_star_mode = MBEDTLS_CCM_STAR_DECRYPT; + } else if (ctx->operation == MBEDTLS_ENCRYPT) { + ccm_star_mode = MBEDTLS_CCM_STAR_ENCRYPT; + } else { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_ccm_starts((mbedtls_ccm_context *) ctx->cipher_ctx, + ccm_star_mode, + iv, iv_len); + } +#endif + + if (actual_iv_size != 0) { + memcpy(ctx->iv, iv, actual_iv_size); + ctx->iv_size = actual_iv_size; + } + + return 0; +} + +int mbedtls_cipher_reset(mbedtls_cipher_context_t *ctx) +{ + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* We don't support resetting PSA-based + * cipher contexts, yet. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + ctx->unprocessed_len = 0; + + return 0; +} + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +int mbedtls_cipher_update_ad(mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len) +{ + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + return mbedtls_gcm_update_ad((mbedtls_gcm_context *) ctx->cipher_ctx, + ad, ad_len); + } +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { + int result; + mbedtls_chachapoly_mode_t mode; + + mode = (ctx->operation == MBEDTLS_ENCRYPT) + ? MBEDTLS_CHACHAPOLY_ENCRYPT + : MBEDTLS_CHACHAPOLY_DECRYPT; + + result = mbedtls_chachapoly_starts((mbedtls_chachapoly_context *) ctx->cipher_ctx, + ctx->iv, + mode); + if (result != 0) { + return result; + } + + return mbedtls_chachapoly_update_aad((mbedtls_chachapoly_context *) ctx->cipher_ctx, + ad, ad_len); + } +#endif + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +int mbedtls_cipher_update(mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t block_size; + + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + *olen = 0; + block_size = mbedtls_cipher_get_block_size(ctx); + if (0 == block_size) { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_ECB) { + if (ilen != block_size) { + return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; + } + + *olen = ilen; + + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ecb_func(ctx->cipher_ctx, + ctx->operation, input, + output))) { + return ret; + } + + return 0; + } + +#if defined(MBEDTLS_GCM_C) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_GCM) { + return mbedtls_gcm_update((mbedtls_gcm_context *) ctx->cipher_ctx, + input, ilen, + output, ilen, olen); + } +#endif + +#if defined(MBEDTLS_CCM_C) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CCM_STAR_NO_TAG) { + return mbedtls_ccm_update((mbedtls_ccm_context *) ctx->cipher_ctx, + input, ilen, + output, ilen, olen); + } +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if (((mbedtls_cipher_type_t) ctx->cipher_info->type) == MBEDTLS_CIPHER_CHACHA20_POLY1305) { + *olen = ilen; + return mbedtls_chachapoly_update((mbedtls_chachapoly_context *) ctx->cipher_ctx, + ilen, input, output); + } +#endif + + if (input == output && + (ctx->unprocessed_len != 0 || ilen % block_size)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CBC) { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if ((ctx->operation == MBEDTLS_DECRYPT && NULL != ctx->add_padding && + ilen <= block_size - ctx->unprocessed_len) || + (ctx->operation == MBEDTLS_DECRYPT && NULL == ctx->add_padding && + ilen < block_size - ctx->unprocessed_len) || + (ctx->operation == MBEDTLS_ENCRYPT && + ilen < block_size - ctx->unprocessed_len)) { + memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, + ilen); + + ctx->unprocessed_len += ilen; + return 0; + } + + /* + * Process cached data first + */ + if (0 != ctx->unprocessed_len) { + copy_len = block_size - ctx->unprocessed_len; + + memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input, + copy_len); + + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, + ctx->operation, + block_size, ctx->iv, + ctx-> + unprocessed_data, + output))) { + return ret; + } + + *olen += block_size; + output += block_size; + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if (0 != ilen) { + /* Encryption: only cache partial blocks + * Decryption w/ padding: always keep at least one whole block + * Decryption w/o padding: only cache partial blocks + */ + copy_len = ilen % block_size; + if (copy_len == 0 && + ctx->operation == MBEDTLS_DECRYPT && + NULL != ctx->add_padding) { + copy_len = block_size; + } + + memcpy(ctx->unprocessed_data, &(input[ilen - copy_len]), + copy_len); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if (ilen) { + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, + ctx->operation, + ilen, ctx->iv, + input, + output))) { + return ret; + } + + *olen += ilen; + } + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CFB) { + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cfb_func(ctx->cipher_ctx, + ctx->operation, ilen, + &ctx->unprocessed_len, + ctx->iv, + input, output))) { + return ret; + } + + *olen = ilen; + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_OFB) { + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ofb_func(ctx->cipher_ctx, + ilen, + &ctx->unprocessed_len, + ctx->iv, + input, output))) { + return ret; + } + + *olen = ilen; + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_CTR) { + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->ctr_func(ctx->cipher_ctx, + ilen, + &ctx->unprocessed_len, + ctx->iv, + ctx->unprocessed_data, + input, output))) { + return ret; + } + + *olen = ilen; + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_XTS) { + if (ctx->unprocessed_len > 0) { + /* We can only process an entire data unit at a time. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + ret = mbedtls_cipher_get_base(ctx->cipher_info)->xts_func(ctx->cipher_ctx, + ctx->operation, + ilen, + ctx->iv, + input, + output); + if (ret != 0) { + return ret; + } + + *olen = ilen; + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) == MBEDTLS_MODE_STREAM) { + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->stream_func(ctx->cipher_ctx, + ilen, input, + output))) { + return ret; + } + + *olen = ilen; + + return 0; + } +#endif /* MBEDTLS_CIPHER_MODE_STREAM */ + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding(unsigned char *output, size_t output_len, + size_t data_len) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for (i = 0; i < padding_len; i++) { + output[data_len + i] = (unsigned char) padding_len; + } +} + +static int get_pkcs_padding(unsigned char *input, size_t input_len, + size_t *data_len) +{ + size_t i, pad_idx; + unsigned char padding_len; + + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + mbedtls_ct_condition_t bad = mbedtls_ct_uint_gt(padding_len, input_len); + bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for (i = 0; i < input_len; i++) { + mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx); + mbedtls_ct_condition_t different = mbedtls_ct_uint_ne(input[i], padding_len); + bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different)); + } + + return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); +} +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ + +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding(unsigned char *output, + size_t output_len, size_t data_len) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for (i = 1; i < padding_len; i++) { + output[data_len + i] = 0x00; + } +} + +static int get_one_and_zeros_padding(unsigned char *input, size_t input_len, + size_t *data_len) +{ + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + mbedtls_ct_condition_t in_padding = MBEDTLS_CT_TRUE; + mbedtls_ct_condition_t bad = MBEDTLS_CT_TRUE; + + *data_len = 0; + + for (ptrdiff_t i = (ptrdiff_t) (input_len) - 1; i >= 0; i--) { + mbedtls_ct_condition_t is_nonzero = mbedtls_ct_bool(input[i]); + + mbedtls_ct_condition_t hit_first_nonzero = mbedtls_ct_bool_and(is_nonzero, in_padding); + + *data_len = mbedtls_ct_size_if(hit_first_nonzero, i, *data_len); + + bad = mbedtls_ct_bool_if(hit_first_nonzero, mbedtls_ct_uint_ne(input[i], 0x80), bad); + + in_padding = mbedtls_ct_bool_and(in_padding, mbedtls_ct_bool_not(is_nonzero)); + } + + return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); +} +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding(unsigned char *output, + size_t output_len, size_t data_len) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for (i = 1; i < padding_len; i++) { + output[data_len + i - 1] = 0x00; + } + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding(unsigned char *input, size_t input_len, + size_t *data_len) +{ + size_t i, pad_idx; + unsigned char padding_len; + mbedtls_ct_condition_t bad; + + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad = mbedtls_ct_uint_gt(padding_len, input_len); + bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0)); + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for (i = 0; i < input_len - 1; i++) { + mbedtls_ct_condition_t is_padding = mbedtls_ct_uint_ge(i, pad_idx); + mbedtls_ct_condition_t nonzero_pad_byte; + nonzero_pad_byte = mbedtls_ct_bool_if_else_0(is_padding, mbedtls_ct_bool(input[i])); + bad = mbedtls_ct_bool_or(bad, nonzero_pad_byte); + } + + return mbedtls_ct_error_if_else_0(bad, MBEDTLS_ERR_CIPHER_INVALID_PADDING); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding(unsigned char *output, + size_t output_len, size_t data_len) +{ + memset(output + data_len, 0, output_len - data_len); +} + +static int get_zeros_padding(unsigned char *input, size_t input_len, + size_t *data_len) +{ + size_t i; + mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE, prev_done; + + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + *data_len = 0; + for (i = input_len; i > 0; i--) { + prev_done = done; + done = mbedtls_ct_bool_or(done, mbedtls_ct_uint_ne(input[i-1], 0)); + *data_len = mbedtls_ct_size_if(mbedtls_ct_bool_ne(done, prev_done), i, *data_len); + } + + return 0; +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in mbedtls_cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding(unsigned char *input, size_t input_len, + size_t *data_len) +{ + if (NULL == input || NULL == data_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + *data_len = input_len; + + return 0; +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +int mbedtls_cipher_finish(mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen) +{ + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + *olen = 0; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /* CBC mode requires padding so we make sure a call to + * mbedtls_cipher_set_padding_mode has been done successfully. */ + if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + if (ctx->get_padding == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + } +#endif + + if (MBEDTLS_MODE_CFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_OFB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_CTR == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_CCM_STAR_NO_TAG == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_XTS == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_STREAM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + return 0; + } + + if ((MBEDTLS_CIPHER_CHACHA20 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) || + (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type))) { + return 0; + } + + if (MBEDTLS_MODE_ECB == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + if (ctx->unprocessed_len != 0) { + return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; + } + + return 0; + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if (MBEDTLS_MODE_CBC == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + int ret = 0; + + if (MBEDTLS_ENCRYPT == ctx->operation) { + /* check for 'no padding' mode */ + if (NULL == ctx->add_padding) { + if (0 != ctx->unprocessed_len) { + return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; + } + + return 0; + } + + ctx->add_padding(ctx->unprocessed_data, mbedtls_cipher_get_iv_size(ctx), + ctx->unprocessed_len); + } else if (mbedtls_cipher_get_block_size(ctx) != ctx->unprocessed_len) { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if (NULL == ctx->add_padding && 0 == ctx->unprocessed_len) { + return 0; + } + + return MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED; + } + + /* cipher block */ + if (0 != (ret = mbedtls_cipher_get_base(ctx->cipher_info)->cbc_func(ctx->cipher_ctx, + ctx->operation, + mbedtls_cipher_get_block_size( + ctx), + ctx->iv, + ctx->unprocessed_data, + output))) { + return ret; + } + + /* Set output size for decryption */ + if (MBEDTLS_DECRYPT == ctx->operation) { + return ctx->get_padding(output, mbedtls_cipher_get_block_size(ctx), + olen); + } + + /* Set output size for encryption */ + *olen = mbedtls_cipher_get_block_size(ctx); + return 0; + } +#else + ((void) output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int mbedtls_cipher_set_padding_mode(mbedtls_cipher_context_t *ctx, + mbedtls_cipher_padding_t mode) +{ + if (NULL == ctx->cipher_info || + MBEDTLS_MODE_CBC != ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto knows about CBC padding + * schemes, we currently don't make them + * accessible through the cipher layer. */ + if (mode != MBEDTLS_PADDING_NONE) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + return 0; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + switch (mode) { +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + case MBEDTLS_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + case MBEDTLS_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + case MBEDTLS_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + case MBEDTLS_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case MBEDTLS_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + return 0; +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) +int mbedtls_cipher_write_tag(mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len) +{ + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (MBEDTLS_ENCRYPT != ctx->operation) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + size_t output_length; + /* The code here doesn't yet support alternative implementations + * that can delay up to a block of output. */ + return mbedtls_gcm_finish((mbedtls_gcm_context *) ctx->cipher_ctx, + NULL, 0, &output_length, + tag, tag_len); + } +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { + /* Don't allow truncated MAC for Poly1305 */ + if (tag_len != 16U) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_chachapoly_finish( + (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag); + } +#endif + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} + +int mbedtls_cipher_check_tag(mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len) +{ + unsigned char check_tag[16]; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (ctx->cipher_info == NULL) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (MBEDTLS_DECRYPT != ctx->operation) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* While PSA Crypto has an API for multipart + * operations, we currently don't make it + * accessible through the cipher layer. */ + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + /* Status to return on a non-authenticated algorithm. */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + size_t output_length; + /* The code here doesn't yet support alternative implementations + * that can delay up to a block of output. */ + + if (tag_len > sizeof(check_tag)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (0 != (ret = mbedtls_gcm_finish( + (mbedtls_gcm_context *) ctx->cipher_ctx, + NULL, 0, &output_length, + check_tag, tag_len))) { + return ret; + } + + /* Check the tag in "constant-time" */ + if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + goto exit; + } + } +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { + /* Don't allow truncated MAC for Poly1305 */ + if (tag_len != sizeof(check_tag)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + ret = mbedtls_chachapoly_finish( + (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag); + if (ret != 0) { + return ret; + } + + /* Check the tag in "constant-time" */ + if (mbedtls_ct_memcmp(tag, check_tag, tag_len) != 0) { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + goto exit; + } + } +#endif /* MBEDTLS_CHACHAPOLY_C */ + +exit: + mbedtls_platform_zeroize(check_tag, tag_len); + return ret; +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int mbedtls_cipher_crypt(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t finish_olen; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT; + size_t part_len; + + if (ctx->operation == MBEDTLS_DECRYPT) { + status = psa_cipher_decrypt_setup(&cipher_op, + cipher_psa->slot, + cipher_psa->alg); + } else if (ctx->operation == MBEDTLS_ENCRYPT) { + status = psa_cipher_encrypt_setup(&cipher_op, + cipher_psa->slot, + cipher_psa->alg); + } else { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + /* In the following, we can immediately return on an error, + * because the PSA Crypto API guarantees that cipher operations + * are terminated by unsuccessful calls to psa_cipher_update(), + * and by any call to psa_cipher_finish(). */ + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + if (((mbedtls_cipher_mode_t) ctx->cipher_info->mode) != MBEDTLS_MODE_ECB) { + status = psa_cipher_set_iv(&cipher_op, iv, iv_len); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + } + + status = psa_cipher_update(&cipher_op, + input, ilen, + output, ilen, olen); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + status = psa_cipher_finish(&cipher_op, + output + *olen, ilen - *olen, + &part_len); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + *olen += part_len; + return 0; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + + if ((ret = mbedtls_cipher_set_iv(ctx, iv, iv_len)) != 0) { + return ret; + } + + if ((ret = mbedtls_cipher_reset(ctx)) != 0) { + return ret; + } + + if ((ret = mbedtls_cipher_update(ctx, input, ilen, + output, olen)) != 0) { + return ret; + } + + if ((ret = mbedtls_cipher_finish(ctx, output + *olen, + &finish_olen)) != 0) { + return ret; + } + + *olen += finish_olen; + + return 0; +} + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes: internal function used by + * mbedtls_cipher_auth_encrypt_ext(). + */ +static int mbedtls_cipher_aead_encrypt(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len) +{ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + + /* PSA Crypto API always writes the authentication tag + * at the end of the encrypted message. */ + if (output == NULL || tag != output + ilen) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + status = psa_aead_encrypt(cipher_psa->slot, + cipher_psa->alg, + iv, iv_len, + ad, ad_len, + input, ilen, + output, ilen + tag_len, olen); + if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + *olen -= tag_len; + return 0; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + *olen = ilen; + return mbedtls_gcm_crypt_and_tag(ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, + ilen, iv, iv_len, ad, ad_len, + input, output, tag_len, tag); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + *olen = ilen; + return mbedtls_ccm_encrypt_and_tag(ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len); + } +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { + /* ChachaPoly has fixed length nonce and MAC (tag) */ + if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) || + (tag_len != 16U)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + *olen = ilen; + return mbedtls_chachapoly_encrypt_and_tag(ctx->cipher_ctx, + ilen, iv, ad, ad_len, input, output, tag); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} + +/* + * Packet-oriented encryption for AEAD modes: internal function used by + * mbedtls_cipher_auth_encrypt_ext(). + */ +static int mbedtls_cipher_aead_decrypt(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len) +{ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + if (ctx->psa_enabled == 1) { + /* As in the non-PSA case, we don't check that + * a key has been set. If not, the key slot will + * still be in its default state of 0, which is + * guaranteed to be invalid, hence the PSA-call + * below will gracefully fail. */ + mbedtls_cipher_context_psa * const cipher_psa = + (mbedtls_cipher_context_psa *) ctx->cipher_ctx; + + psa_status_t status; + + /* PSA Crypto API always writes the authentication tag + * at the end of the encrypted message. */ + if (input == NULL || tag != input + ilen) { + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + } + + status = psa_aead_decrypt(cipher_psa->slot, + cipher_psa->alg, + iv, iv_len, + ad, ad_len, + input, ilen + tag_len, + output, ilen, olen); + if (status == PSA_ERROR_INVALID_SIGNATURE) { + return MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } else if (status != PSA_SUCCESS) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + return 0; + } +#endif /* MBEDTLS_USE_PSA_CRYPTO && !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_GCM_C) + if (MBEDTLS_MODE_GCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + *olen = ilen; + ret = mbedtls_gcm_auth_decrypt(ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output); + + if (ret == MBEDTLS_ERR_GCM_AUTH_FAILED) { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + return ret; + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if (MBEDTLS_MODE_CCM == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + *olen = ilen; + ret = mbedtls_ccm_auth_decrypt(ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len); + + if (ret == MBEDTLS_ERR_CCM_AUTH_FAILED) { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + return ret; + } +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ((mbedtls_cipher_type_t) ctx->cipher_info->type)) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* ChachaPoly has fixed length nonce and MAC (tag) */ + if ((iv_len != mbedtls_cipher_info_get_iv_size(ctx->cipher_info)) || + (tag_len != 16U)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + *olen = ilen; + ret = mbedtls_chachapoly_auth_decrypt(ctx->cipher_ctx, ilen, + iv, ad, ad_len, tag, input, output); + + if (ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + return ret; + } +#endif /* MBEDTLS_CHACHAPOLY_C */ + + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C) +/* + * Packet-oriented encryption for AEAD/NIST_KW: public function. + */ +int mbedtls_cipher_auth_encrypt_ext(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len) +{ +#if defined(MBEDTLS_NIST_KW_C) + if ( +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + ctx->psa_enabled == 0 && +#endif + (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) { + mbedtls_nist_kw_mode_t mode = + (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ? + MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; + + /* There is no iv, tag or ad associated with KW and KWP, + * so these length should be 0 as documented. */ + if (iv_len != 0 || tag_len != 0 || ad_len != 0) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + (void) iv; + (void) ad; + + return mbedtls_nist_kw_wrap(ctx->cipher_ctx, mode, input, ilen, + output, olen, output_len); + } +#endif /* MBEDTLS_NIST_KW_C */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) + /* AEAD case: check length before passing on to shared function */ + if (output_len < ilen + tag_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + int ret = mbedtls_cipher_aead_encrypt(ctx, iv, iv_len, ad, ad_len, + input, ilen, output, olen, + output + ilen, tag_len); + *olen += tag_len; + return ret; +#else + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ +} + +/* + * Packet-oriented decryption for AEAD/NIST_KW: public function. + */ +int mbedtls_cipher_auth_decrypt_ext(mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t output_len, + size_t *olen, size_t tag_len) +{ +#if defined(MBEDTLS_NIST_KW_C) + if ( +#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_DEPRECATED_REMOVED) + ctx->psa_enabled == 0 && +#endif + (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode) || + MBEDTLS_MODE_KWP == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode))) { + mbedtls_nist_kw_mode_t mode = + (MBEDTLS_MODE_KW == ((mbedtls_cipher_mode_t) ctx->cipher_info->mode)) ? + MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP; + + /* There is no iv, tag or ad associated with KW and KWP, + * so these length should be 0 as documented. */ + if (iv_len != 0 || tag_len != 0 || ad_len != 0) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + (void) iv; + (void) ad; + + return mbedtls_nist_kw_unwrap(ctx->cipher_ctx, mode, input, ilen, + output, olen, output_len); + } +#endif /* MBEDTLS_NIST_KW_C */ + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) + /* AEAD case: check length before passing on to shared function */ + if (ilen < tag_len || output_len < ilen - tag_len) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_cipher_aead_decrypt(ctx, iv, iv_len, ad, ad_len, + input, ilen - tag_len, output, olen, + input + ilen - tag_len, tag_len); +#else + return MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */ + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.c b/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.c new file mode 100644 index 0000000..7e12de6 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.c @@ -0,0 +1,2422 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for Mbed TLS + * + * \author Adriaan de Jong + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_CIPHER_C) + +#include "cipher_wrap.h" +#include "mbedtls/error.h" + +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_ARIA_C) +#include "mbedtls/aria.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_NIST_KW_C) +#include "mbedtls/nist_kw.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#include "mbedtls/platform.h" + +enum mbedtls_cipher_base_index { +#if defined(MBEDTLS_AES_C) + MBEDTLS_CIPHER_BASE_INDEX_AES, +#endif +#if defined(MBEDTLS_ARIA_C) + MBEDTLS_CIPHER_BASE_INDEX_ARIA, +#endif +#if defined(MBEDTLS_CAMELLIA_C) + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C) + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_ARIA_C) + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CAMELLIA_C) + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA, +#endif +#if defined(MBEDTLS_CHACHA20_C) + MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE, +#endif +#if defined(MBEDTLS_CHACHAPOLY_C) + MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE, +#endif +#if defined(MBEDTLS_DES_C) + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3, +#endif +#if defined(MBEDTLS_DES_C) + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE, +#endif +#if defined(MBEDTLS_DES_C) + MBEDTLS_CIPHER_BASE_INDEX_DES, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C) + MBEDTLS_CIPHER_BASE_INDEX_GCM_AES, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_ARIA_C) + MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_CAMELLIA_C) + MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA, +#endif +#if defined(MBEDTLS_NIST_KW_C) + MBEDTLS_CIPHER_BASE_INDEX_KW_AES, +#endif +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) && defined(MBEDTLS_AES_C) + MBEDTLS_CIPHER_BASE_INDEX_XTS_AES, +#endif + /* Prevent compile failure due to empty enum */ + MBEDTLS_CIPHER_BASE_PREVENT_EMPTY_ENUM +}; + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc(void) +{ + void *ctx = mbedtls_calloc(1, sizeof(mbedtls_gcm_context)); + + if (ctx != NULL) { + mbedtls_gcm_init((mbedtls_gcm_context *) ctx); + } + + return ctx; +} + +static void gcm_ctx_free(void *ctx) +{ + mbedtls_gcm_free(ctx); + mbedtls_free(ctx); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc(void) +{ + void *ctx = mbedtls_calloc(1, sizeof(mbedtls_ccm_context)); + + if (ctx != NULL) { + mbedtls_ccm_init((mbedtls_ccm_context *) ctx); + } + + return ctx; +} + +static void ccm_ctx_free(void *ctx) +{ + mbedtls_ccm_free(ctx); + mbedtls_free(ctx); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +static int aes_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aes_crypt_ecb((mbedtls_aes_context *) ctx, operation, input, output); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output) +{ + return mbedtls_aes_crypt_cbc((mbedtls_aes_context *) ctx, operation, length, iv, input, + output); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aes_crypt_cfb128((mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static int aes_crypt_ofb_wrap(void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, unsigned char *output) +{ + return mbedtls_aes_crypt_ofb((mbedtls_aes_context *) ctx, length, iv_off, + iv, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aes_crypt_ctr((mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int aes_crypt_xts_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + int mode; + + switch (operation) { + case MBEDTLS_ENCRYPT: + mode = MBEDTLS_AES_ENCRYPT; + break; + case MBEDTLS_DECRYPT: + mode = MBEDTLS_AES_DECRYPT; + break; + default: + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_aes_crypt_xts(xts_ctx, mode, length, + data_unit, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +static int aes_setkey_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_aes_setkey_dec((mbedtls_aes_context *) ctx, key, key_bitlen); +} + +static int aes_setkey_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_aes_setkey_enc((mbedtls_aes_context *) ctx, key, key_bitlen); +} + +static void *aes_ctx_alloc(void) +{ + mbedtls_aes_context *aes = mbedtls_calloc(1, sizeof(mbedtls_aes_context)); + + if (aes == NULL) { + return NULL; + } + + mbedtls_aes_init(aes); + + return aes; +} + +static void aes_ctx_free(void *ctx) +{ + mbedtls_aes_free((mbedtls_aes_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + aes_crypt_ofb_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + "AES-128-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_AES_128_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_ecb_info = { + "AES-192-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_AES_192_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + "AES-256-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_AES_256_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + "AES-128-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_AES_128_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_cbc_info = { + "AES-192-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_AES_192_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + "AES-256-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_AES_256_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; +#endif +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + "AES-128-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_AES_128_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + "AES-192-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_AES_192_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + "AES-256-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_AES_256_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; +#endif +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static const mbedtls_cipher_info_t aes_128_ofb_info = { + "AES-128-OFB", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_OFB, + MBEDTLS_CIPHER_AES_128_OFB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_ofb_info = { + "AES-192-OFB", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_OFB, + MBEDTLS_CIPHER_AES_192_OFB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +static const mbedtls_cipher_info_t aes_256_ofb_info = { + "AES-256-OFB", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_OFB, + MBEDTLS_CIPHER_AES_256_OFB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; +#endif +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + "AES-128-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_AES_128_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_ctr_info = { + "AES-192-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_AES_192_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + "AES-256-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_AES_256_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_AES +}; +#endif +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int xts_aes_setkey_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return mbedtls_aes_xts_setkey_enc(xts_ctx, key, key_bitlen); +} + +static int xts_aes_setkey_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return mbedtls_aes_xts_setkey_dec(xts_ctx, key, key_bitlen); +} + +static void *xts_aes_ctx_alloc(void) +{ + mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc(1, sizeof(*xts_ctx)); + + if (xts_ctx != NULL) { + mbedtls_aes_xts_init(xts_ctx); + } + + return xts_ctx; +} + +static void xts_aes_ctx_free(void *ctx) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + + if (xts_ctx == NULL) { + return; + } + + mbedtls_aes_xts_free(xts_ctx); + mbedtls_free(xts_ctx); +} + +static const mbedtls_cipher_base_t xts_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + aes_crypt_xts_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + xts_aes_setkey_enc_wrap, + xts_aes_setkey_dec_wrap, + xts_aes_ctx_alloc, + xts_aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_xts_info = { + "AES-128-XTS", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_XTS, + MBEDTLS_CIPHER_AES_128_XTS, + 0, + MBEDTLS_CIPHER_BASE_INDEX_XTS_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_256_xts_info = { + "AES-256-XTS", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 512 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_XTS, + MBEDTLS_CIPHER_AES_256_XTS, + 0, + MBEDTLS_CIPHER_BASE_INDEX_XTS_AES +}; +#endif +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + "AES-128-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_gcm_info = { + "AES-192-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_AES +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + "AES-256-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_AES +}; +#endif +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + "AES-128-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_ccm_info = { + "AES-192-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + "AES-256-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; +#endif + +static const mbedtls_cipher_info_t aes_128_ccm_star_no_tag_info = { + "AES-128-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_ccm_star_no_tag_info = { + "AES-192-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; + +static const mbedtls_cipher_info_t aes_256_ccm_star_no_tag_info = { + "AES-256-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_AES +}; +#endif +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_camellia_crypt_ecb((mbedtls_camellia_context *) ctx, operation, input, + output); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_camellia_crypt_cbc((mbedtls_camellia_context *) ctx, operation, length, iv, + input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_camellia_crypt_cfb128((mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_camellia_crypt_ctr((mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_camellia_setkey_dec((mbedtls_camellia_context *) ctx, key, key_bitlen); +} + +static int camellia_setkey_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_camellia_setkey_enc((mbedtls_camellia_context *) ctx, key, key_bitlen); +} + +static void *camellia_ctx_alloc(void) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc(1, sizeof(mbedtls_camellia_context)); + + if (ctx == NULL) { + return NULL; + } + + mbedtls_camellia_init(ctx); + + return ctx; +} + +static void camellia_ctx_free(void *ctx) +{ + mbedtls_camellia_free((mbedtls_camellia_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + "CAMELLIA-128-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + "CAMELLIA-192-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + "CAMELLIA-256-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + "CAMELLIA-128-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + "CAMELLIA-192-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + "CAMELLIA-256-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + "CAMELLIA-128-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + "CAMELLIA-192-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + "CAMELLIA-256-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + "CAMELLIA-128-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + "CAMELLIA-192-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + "CAMELLIA-256-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + "CAMELLIA-128-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + "CAMELLIA-192-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + "CAMELLIA-256-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + "CAMELLIA-128-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + "CAMELLIA-192-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + "CAMELLIA-256-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_star_no_tag_info = { + "CAMELLIA-128-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_star_no_tag_info = { + "CAMELLIA-192-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_star_no_tag_info = { + "CAMELLIA-256-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_ARIA_C) + +static int aria_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output) +{ + (void) operation; + return mbedtls_aria_crypt_ecb((mbedtls_aria_context *) ctx, input, + output); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aria_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aria_crypt_cbc((mbedtls_aria_context *) ctx, operation, length, iv, + input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aria_crypt_cfb128_wrap(void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aria_crypt_cfb128((mbedtls_aria_context *) ctx, operation, length, + iv_off, iv, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aria_crypt_ctr_wrap(void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output) +{ + return mbedtls_aria_crypt_ctr((mbedtls_aria_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aria_setkey_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_aria_setkey_dec((mbedtls_aria_context *) ctx, key, key_bitlen); +} + +static int aria_setkey_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_aria_setkey_enc((mbedtls_aria_context *) ctx, key, key_bitlen); +} + +static void *aria_ctx_alloc(void) +{ + mbedtls_aria_context *ctx; + ctx = mbedtls_calloc(1, sizeof(mbedtls_aria_context)); + + if (ctx == NULL) { + return NULL; + } + + mbedtls_aria_init(ctx); + + return ctx; +} + +static void aria_ctx_free(void *ctx) +{ + mbedtls_aria_free((mbedtls_aria_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + aria_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aria_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aria_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aria_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aria_setkey_enc_wrap, + aria_setkey_dec_wrap, + aria_ctx_alloc, + aria_ctx_free +}; + +static const mbedtls_cipher_info_t aria_128_ecb_info = { + "ARIA-128-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_ARIA_128_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_ecb_info = { + "ARIA-192-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_ARIA_192_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_ecb_info = { + "ARIA-256-ECB", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_ARIA_256_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aria_128_cbc_info = { + "ARIA-128-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_ARIA_128_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_cbc_info = { + "ARIA-192-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_ARIA_192_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_cbc_info = { + "ARIA-256-CBC", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_ARIA_256_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aria_128_cfb128_info = { + "ARIA-128-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_ARIA_128_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_cfb128_info = { + "ARIA-192-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_ARIA_192_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_cfb128_info = { + "ARIA-256-CFB128", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CFB, + MBEDTLS_CIPHER_ARIA_256_CFB128, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aria_128_ctr_info = { + "ARIA-128-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_ARIA_128_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_ctr_info = { + "ARIA-192-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_ARIA_192_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_ctr_info = { + "ARIA-256-CTR", + 16, + 16 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CTR, + MBEDTLS_CIPHER_ARIA_256_CTR, + 0, + MBEDTLS_CIPHER_BASE_INDEX_ARIA +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aria_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_gcm_setkey((mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t gcm_aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aria_setkey_wrap, + gcm_aria_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aria_128_gcm_info = { + "ARIA-128-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_ARIA_128_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_gcm_info = { + "ARIA-192-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_ARIA_192_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_gcm_info = { + "ARIA-256-GCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_GCM, + MBEDTLS_CIPHER_ARIA_256_GCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aria_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_ccm_setkey((mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_ARIA, + key, key_bitlen); +} + +static const mbedtls_cipher_base_t ccm_aria_info = { + MBEDTLS_CIPHER_ID_ARIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aria_setkey_wrap, + ccm_aria_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aria_128_ccm_info = { + "ARIA-128-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_ARIA_128_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_ccm_info = { + "ARIA-192-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_ARIA_192_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_ccm_info = { + "ARIA-256-CCM", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM, + MBEDTLS_CIPHER_ARIA_256_CCM, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_128_ccm_star_no_tag_info = { + "ARIA-128-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_192_ccm_star_no_tag_info = { + "ARIA-192-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; + +static const mbedtls_cipher_info_t aria_256_ccm_star_no_tag_info = { + "ARIA-256-CCM*-NO-TAG", + 16, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_ARIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output) +{ + ((void) operation); + return mbedtls_des_crypt_ecb((mbedtls_des_context *) ctx, input, output); +} + +static int des3_crypt_ecb_wrap(void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb((mbedtls_des3_context *) ctx, input, output); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output) +{ + return mbedtls_des_crypt_cbc((mbedtls_des_context *) ctx, operation, length, iv, input, + output); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap(void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output) +{ + return mbedtls_des3_crypt_cbc((mbedtls_des3_context *) ctx, operation, length, iv, input, + output); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec((mbedtls_des_context *) ctx, key); +} + +static int des_setkey_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc((mbedtls_des_context *) ctx, key); +} + +static int des3_set2key_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec((mbedtls_des3_context *) ctx, key); +} + +static int des3_set2key_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc((mbedtls_des3_context *) ctx, key); +} + +static int des3_set3key_dec_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec((mbedtls_des3_context *) ctx, key); +} + +static int des3_set3key_enc_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc((mbedtls_des3_context *) ctx, key); +} + +static void *des_ctx_alloc(void) +{ + mbedtls_des_context *des = mbedtls_calloc(1, sizeof(mbedtls_des_context)); + + if (des == NULL) { + return NULL; + } + + mbedtls_des_init(des); + + return des; +} + +static void des_ctx_free(void *ctx) +{ + mbedtls_des_free((mbedtls_des_context *) ctx); + mbedtls_free(ctx); +} + +static void *des3_ctx_alloc(void) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc(1, sizeof(mbedtls_des3_context)); + + if (des3 == NULL) { + return NULL; + } + + mbedtls_des3_init(des3); + + return des3; +} + +static void des3_ctx_free(void *ctx) +{ + mbedtls_des3_free((mbedtls_des3_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + "DES-ECB", + 8, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_DES_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + "DES-CBC", + 8, + 8 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_DES_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + "DES-EDE-ECB", + 8, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES_EDE >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_DES_EDE_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + "DES-EDE-CBC", + 8, + 8 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES_EDE >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_DES_EDE_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + "DES-EDE3-ECB", + 8, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES_EDE3 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_ECB, + MBEDTLS_CIPHER_DES_EDE3_ECB, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3 +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + "DES-EDE3-CBC", + 8, + 8 >> MBEDTLS_IV_SIZE_SHIFT, + MBEDTLS_KEY_LENGTH_DES_EDE3 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CBC, + MBEDTLS_CIPHER_DES_EDE3_CBC, + 0, + MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3 +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CHACHA20_C) + +static int chacha20_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + if (key_bitlen != 256U) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (0 != mbedtls_chacha20_setkey((mbedtls_chacha20_context *) ctx, key)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return 0; +} + +static int chacha20_stream_wrap(void *ctx, size_t length, + const unsigned char *input, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_chacha20_update(ctx, length, input, output); + if (ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return ret; +} + +static void *chacha20_ctx_alloc(void) +{ + mbedtls_chacha20_context *ctx; + ctx = mbedtls_calloc(1, sizeof(mbedtls_chacha20_context)); + + if (ctx == NULL) { + return NULL; + } + + mbedtls_chacha20_init(ctx); + + return ctx; +} + +static void chacha20_ctx_free(void *ctx) +{ + mbedtls_chacha20_free((mbedtls_chacha20_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t chacha20_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + chacha20_stream_wrap, +#endif + chacha20_setkey_wrap, + chacha20_setkey_wrap, + chacha20_ctx_alloc, + chacha20_ctx_free +}; +static const mbedtls_cipher_info_t chacha20_info = { + "CHACHA20", + 1, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_STREAM, + MBEDTLS_CIPHER_CHACHA20, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE +}; +#endif /* MBEDTLS_CHACHA20_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + +static int chachapoly_setkey_wrap(void *ctx, + const unsigned char *key, + unsigned int key_bitlen) +{ + if (key_bitlen != 256U) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + if (0 != mbedtls_chachapoly_setkey((mbedtls_chachapoly_context *) ctx, key)) { + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return 0; +} + +static void *chachapoly_ctx_alloc(void) +{ + mbedtls_chachapoly_context *ctx; + ctx = mbedtls_calloc(1, sizeof(mbedtls_chachapoly_context)); + + if (ctx == NULL) { + return NULL; + } + + mbedtls_chachapoly_init(ctx); + + return ctx; +} + +static void chachapoly_ctx_free(void *ctx) +{ + mbedtls_chachapoly_free((mbedtls_chachapoly_context *) ctx); + mbedtls_free(ctx); +} + +static const mbedtls_cipher_base_t chachapoly_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + chachapoly_setkey_wrap, + chachapoly_setkey_wrap, + chachapoly_ctx_alloc, + chachapoly_ctx_free +}; +static const mbedtls_cipher_info_t chachapoly_info = { + "CHACHA20-POLY1305", + 1, + 12 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_CHACHAPOLY, + MBEDTLS_CIPHER_CHACHA20_POLY1305, + 0, + MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE +}; +#endif /* MBEDTLS_CHACHAPOLY_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream(void *ctx, size_t length, + const unsigned char *input, + unsigned char *output) +{ + ((void) ctx); + memmove(output, input, length); + return 0; +} + +static int null_setkey(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return 0; +} + +static void *null_ctx_alloc(void) +{ + return (void *) 1; +} + +static void null_ctx_free(void *ctx) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + "NULL", + 1, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 0 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_STREAM, + MBEDTLS_CIPHER_NULL, + 0, + MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +#if defined(MBEDTLS_NIST_KW_C) +static void *kw_ctx_alloc(void) +{ + void *ctx = mbedtls_calloc(1, sizeof(mbedtls_nist_kw_context)); + + if (ctx != NULL) { + mbedtls_nist_kw_init((mbedtls_nist_kw_context *) ctx); + } + + return ctx; +} + +static void kw_ctx_free(void *ctx) +{ + mbedtls_nist_kw_free(ctx); + mbedtls_free(ctx); +} + +static int kw_aes_setkey_wrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_nist_kw_setkey((mbedtls_nist_kw_context *) ctx, + MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1); +} + +static int kw_aes_setkey_unwrap(void *ctx, const unsigned char *key, + unsigned int key_bitlen) +{ + return mbedtls_nist_kw_setkey((mbedtls_nist_kw_context *) ctx, + MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0); +} + +static const mbedtls_cipher_base_t kw_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + kw_aes_setkey_wrap, + kw_aes_setkey_unwrap, + kw_ctx_alloc, + kw_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_nist_kw_info = { + "AES-128-KW", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KW, + MBEDTLS_CIPHER_AES_128_KW, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_nist_kw_info = { + "AES-192-KW", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KW, + MBEDTLS_CIPHER_AES_192_KW, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; + +static const mbedtls_cipher_info_t aes_256_nist_kw_info = { + "AES-256-KW", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KW, + MBEDTLS_CIPHER_AES_256_KW, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; +#endif + +static const mbedtls_cipher_info_t aes_128_nist_kwp_info = { + "AES-128-KWP", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 128 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KWP, + MBEDTLS_CIPHER_AES_128_KWP, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; + +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) +static const mbedtls_cipher_info_t aes_192_nist_kwp_info = { + "AES-192-KWP", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 192 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KWP, + MBEDTLS_CIPHER_AES_192_KWP, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; + +static const mbedtls_cipher_info_t aes_256_nist_kwp_info = { + "AES-256-KWP", + 16, + 0 >> MBEDTLS_IV_SIZE_SHIFT, + 256 >> MBEDTLS_KEY_BITLEN_SHIFT, + MBEDTLS_MODE_KWP, + MBEDTLS_CIPHER_AES_256_KWP, + 0, + MBEDTLS_CIPHER_BASE_INDEX_KW_AES +}; +#endif +#endif /* MBEDTLS_NIST_KW_C */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, + { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, +#endif +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, +#endif +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif + { MBEDTLS_CIPHER_AES_128_CCM_STAR_NO_TAG, &aes_128_ccm_star_no_tag_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_CCM_STAR_NO_TAG, &aes_192_ccm_star_no_tag_info }, + { MBEDTLS_CIPHER_AES_256_CCM_STAR_NO_TAG, &aes_256_ccm_star_no_tag_info }, +#endif +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_128_CCM_STAR_NO_TAG, &camellia_128_ccm_star_no_tag_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM_STAR_NO_TAG, &camellia_192_ccm_star_no_tag_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM_STAR_NO_TAG, &camellia_256_ccm_star_no_tag_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_ARIA_C) + { MBEDTLS_CIPHER_ARIA_128_ECB, &aria_128_ecb_info }, + { MBEDTLS_CIPHER_ARIA_192_ECB, &aria_192_ecb_info }, + { MBEDTLS_CIPHER_ARIA_256_ECB, &aria_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_ARIA_128_CBC, &aria_128_cbc_info }, + { MBEDTLS_CIPHER_ARIA_192_CBC, &aria_192_cbc_info }, + { MBEDTLS_CIPHER_ARIA_256_CBC, &aria_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_ARIA_128_CFB128, &aria_128_cfb128_info }, + { MBEDTLS_CIPHER_ARIA_192_CFB128, &aria_192_cfb128_info }, + { MBEDTLS_CIPHER_ARIA_256_CFB128, &aria_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_ARIA_128_CTR, &aria_128_ctr_info }, + { MBEDTLS_CIPHER_ARIA_192_CTR, &aria_192_ctr_info }, + { MBEDTLS_CIPHER_ARIA_256_CTR, &aria_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_ARIA_128_GCM, &aria_128_gcm_info }, + { MBEDTLS_CIPHER_ARIA_192_GCM, &aria_192_gcm_info }, + { MBEDTLS_CIPHER_ARIA_256_GCM, &aria_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_ARIA_128_CCM, &aria_128_ccm_info }, + { MBEDTLS_CIPHER_ARIA_192_CCM, &aria_192_ccm_info }, + { MBEDTLS_CIPHER_ARIA_256_CCM, &aria_256_ccm_info }, + { MBEDTLS_CIPHER_ARIA_128_CCM_STAR_NO_TAG, &aria_128_ccm_star_no_tag_info }, + { MBEDTLS_CIPHER_ARIA_192_CCM_STAR_NO_TAG, &aria_192_ccm_star_no_tag_info }, + { MBEDTLS_CIPHER_ARIA_256_CCM_STAR_NO_TAG, &aria_256_ccm_star_no_tag_info }, +#endif +#endif /* MBEDTLS_ARIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CHACHA20_C) + { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, +#endif + +#if defined(MBEDTLS_CHACHAPOLY_C) + { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, +#endif + +#if defined(MBEDTLS_NIST_KW_C) + { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info }, + { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info }, +#endif + { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info }, + { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info }, +#endif +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS (sizeof(mbedtls_cipher_definitions) / \ + sizeof(mbedtls_cipher_definitions[0])) +int mbedtls_cipher_supported[NUM_CIPHERS]; + +const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[] = { +#if defined(MBEDTLS_AES_C) + [MBEDTLS_CIPHER_BASE_INDEX_AES] = &aes_info, +#endif +#if defined(MBEDTLS_ARIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_ARIA] = &aria_info, +#endif +#if defined(MBEDTLS_CAMELLIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_CAMELLIA] = &camellia_info, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_AES_C) + [MBEDTLS_CIPHER_BASE_INDEX_CCM_AES] = &ccm_aes_info, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_ARIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_CCM_ARIA] = &ccm_aria_info, +#endif +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_CAMELLIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_CCM_CAMELLIA] = &ccm_camellia_info, +#endif +#if defined(MBEDTLS_CHACHA20_C) + [MBEDTLS_CIPHER_BASE_INDEX_CHACHA20_BASE] = &chacha20_base_info, +#endif +#if defined(MBEDTLS_CHACHAPOLY_C) + [MBEDTLS_CIPHER_BASE_INDEX_CHACHAPOLY_BASE] = &chachapoly_base_info, +#endif +#if defined(MBEDTLS_DES_C) + [MBEDTLS_CIPHER_BASE_INDEX_DES_EDE3] = &des_ede3_info, +#endif +#if defined(MBEDTLS_DES_C) + [MBEDTLS_CIPHER_BASE_INDEX_DES_EDE] = &des_ede_info, +#endif +#if defined(MBEDTLS_DES_C) + [MBEDTLS_CIPHER_BASE_INDEX_DES] = &des_info, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_AES_C) + [MBEDTLS_CIPHER_BASE_INDEX_GCM_AES] = &gcm_aes_info, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_ARIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_GCM_ARIA] = &gcm_aria_info, +#endif +#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_CAMELLIA_C) + [MBEDTLS_CIPHER_BASE_INDEX_GCM_CAMELLIA] = &gcm_camellia_info, +#endif +#if defined(MBEDTLS_NIST_KW_C) + [MBEDTLS_CIPHER_BASE_INDEX_KW_AES] = &kw_aes_info, +#endif +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + [MBEDTLS_CIPHER_BASE_INDEX_NULL_BASE] = &null_base_info, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) && defined(MBEDTLS_AES_C) + [MBEDTLS_CIPHER_BASE_INDEX_XTS_AES] = &xts_aes_info +#endif +}; + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.h b/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.h new file mode 100644 index 0000000..ab10aa2 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/cipher_wrap.h @@ -0,0 +1,132 @@ +/** + * \file cipher_wrap.h + * + * \brief Cipher wrappers. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_CIPHER_WRAP_H +#define MBEDTLS_CIPHER_WRAP_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/cipher.h" + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +#include "psa/crypto.h" +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Base cipher information. The non-mode specific functions and values. + */ +struct mbedtls_cipher_base_t { + /** Base Cipher type (e.g. MBEDTLS_CIPHER_ID_AES) */ + mbedtls_cipher_id_t cipher; + + /** Encrypt using ECB */ + int (*ecb_func)(void *ctx, mbedtls_operation_t mode, + const unsigned char *input, unsigned char *output); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /** Encrypt using CBC */ + int (*cbc_func)(void *ctx, mbedtls_operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /** Encrypt using CFB (Full length) */ + int (*cfb_func)(void *ctx, mbedtls_operation_t mode, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, + unsigned char *output); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /** Encrypt using OFB (Full length) */ + int (*ofb_func)(void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, + const unsigned char *input, + unsigned char *output); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /** Encrypt using CTR */ + int (*ctr_func)(void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_XTS) + /** Encrypt or decrypt using XTS. */ + int (*xts_func)(void *ctx, mbedtls_operation_t mode, size_t length, + const unsigned char data_unit[16], + const unsigned char *input, unsigned char *output); +#endif + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + /** Encrypt using STREAM */ + int (*stream_func)(void *ctx, size_t length, + const unsigned char *input, unsigned char *output); +#endif + + /** Set key for encryption purposes */ + int (*setkey_enc_func)(void *ctx, const unsigned char *key, + unsigned int key_bitlen); + + /** Set key for decryption purposes */ + int (*setkey_dec_func)(void *ctx, const unsigned char *key, + unsigned int key_bitlen); + + /** Allocate a new context */ + void * (*ctx_alloc_func)(void); + + /** Free the given context */ + void (*ctx_free_func)(void *ctx); + +}; + +typedef struct { + mbedtls_cipher_type_t type; + const mbedtls_cipher_info_t *info; +} mbedtls_cipher_definition_t; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) +typedef enum { + MBEDTLS_CIPHER_PSA_KEY_UNSET = 0, + MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */ + /* use raw key material internally imported */ + /* as a volatile key, and which hence need */ + /* to destroy that key when the context is */ + /* freed. */ + MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */ + /* which use a key provided by the */ + /* user, and which hence will not be */ + /* destroyed when the context is freed. */ +} mbedtls_cipher_psa_key_ownership; + +typedef struct { + psa_algorithm_t alg; + mbedtls_svc_key_id_t slot; + mbedtls_cipher_psa_key_ownership slot_state; +} mbedtls_cipher_context_psa; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ + +extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[]; + +extern int mbedtls_cipher_supported[]; + +extern const mbedtls_cipher_base_t *mbedtls_cipher_base_lookup_table[]; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CIPHER_WRAP_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/constant_time.c b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time.c new file mode 100644 index 0000000..c7077c3 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time.c @@ -0,0 +1,261 @@ +/** + * Constant-time functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * The following functions are implemented without using comparison operators, as those + * might be translated to branches by some compilers on some platforms. + */ + +#include +#include + +#include "common.h" +#include "constant_time_internal.h" +#include "mbedtls/constant_time.h" +#include "mbedtls/error.h" +#include "mbedtls/platform_util.h" + +#include + +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC) +#include "psa/crypto.h" +/* Define a local translating function to save code size by not using too many + * arguments in each translating place. */ +static int local_err_translation(psa_status_t status) +{ + return psa_status_to_mbedtls(status, psa_to_ssl_errors, + ARRAY_LENGTH(psa_to_ssl_errors), + psa_generic_status_to_mbedtls); +} +#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) +#endif + +#if !defined(MBEDTLS_CT_ASM) +/* + * Define an object with the value zero, such that the compiler cannot prove that it + * has the value zero (because it is volatile, it "may be modified in ways unknown to + * the implementation"). + */ +volatile mbedtls_ct_uint_t mbedtls_ct_zero = 0; +#endif + +/* + * Define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS where assembly is present to + * perform fast unaligned access to volatile data. + * + * This is needed because mbedtls_get_unaligned_uintXX etc don't support volatile + * memory accesses. + * + * Some of these definitions could be moved into alignment.h but for now they are + * only used here. + */ +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && \ + ((defined(MBEDTLS_CT_ARM_ASM) && (UINTPTR_MAX == 0xfffffffful)) || \ + defined(MBEDTLS_CT_AARCH64_ASM)) +/* We check pointer sizes to avoid issues with them not matching register size requirements */ +#define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS + +static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsigned char *p) +{ + /* This is UB, even where it's safe: + * return *((volatile uint32_t*)p); + * so instead the same thing is expressed in assembly below. + */ + uint32_t r; +#if defined(MBEDTLS_CT_ARM_ASM) + asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :); +#elif defined(MBEDTLS_CT_AARCH64_ASM) + asm volatile ("ldr %w0, [%1]" : "=r" (r) : MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT(p) :); +#else +#error "No assembly defined for mbedtls_get_unaligned_volatile_uint32" +#endif + return r; +} +#endif /* defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && + (defined(MBEDTLS_CT_ARM_ASM) || defined(MBEDTLS_CT_AARCH64_ASM)) */ + +int mbedtls_ct_memcmp(const void *a, + const void *b, + size_t n) +{ + size_t i = 0; + /* + * `A` and `B` are cast to volatile to ensure that the compiler + * generates code that always fully reads both buffers. + * Otherwise it could generate a test to exit early if `diff` has all + * bits set early in the loop. + */ + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + uint32_t diff = 0; + +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS) + for (; (i + 4) <= n; i += 4) { + uint32_t x = mbedtls_get_unaligned_volatile_uint32(A + i); + uint32_t y = mbedtls_get_unaligned_volatile_uint32(B + i); + diff |= x ^ y; + } +#endif + + for (; i < n; i++) { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + +#if (INT_MAX < INT32_MAX) + /* We don't support int smaller than 32-bits, but if someone tried to build + * with this configuration, there is a risk that, for differing data, the + * only bits set in diff are in the top 16-bits, and would be lost by a + * simple cast from uint32 to int. + * This would have significant security implications, so protect against it. */ +#error "mbedtls_ct_memcmp() requires minimum 32-bit ints" +#else + /* The bit-twiddling ensures that when we cast uint32_t to int, we are casting + * a value that is in the range 0..INT_MAX - a value larger than this would + * result in implementation defined behaviour. + * + * This ensures that the value returned by the function is non-zero iff + * diff is non-zero. + */ + return (int) ((diff & 0xffff) | (diff >> 16)); +#endif +} + +#if defined(MBEDTLS_NIST_KW_C) + +int mbedtls_ct_memcmp_partial(const void *a, + const void *b, + size_t n, + size_t skip_head, + size_t skip_tail) +{ + unsigned int diff = 0; + + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + + size_t valid_end = n - skip_tail; + + for (size_t i = 0; i < n; i++) { + unsigned char x = A[i], y = B[i]; + unsigned int d = x ^ y; + mbedtls_ct_condition_t valid = mbedtls_ct_bool_and(mbedtls_ct_uint_ge(i, skip_head), + mbedtls_ct_uint_lt(i, valid_end)); + diff |= mbedtls_ct_uint_if_else_0(valid, d); + } + + /* Since we go byte-by-byte, the only bits set will be in the bottom 8 bits, so the + * cast from uint to int is safe. */ + return (int) diff; +} + +#endif + +#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) + +void mbedtls_ct_memmove_left(void *start, size_t total, size_t offset) +{ + volatile unsigned char *buf = start; + for (size_t i = 0; i < total; i++) { + mbedtls_ct_condition_t no_op = mbedtls_ct_uint_gt(total - offset, i); + /* The first `total - offset` passes are a no-op. The last + * `offset` passes shift the data one byte to the left and + * zero out the last byte. */ + for (size_t n = 0; n < total - 1; n++) { + unsigned char current = buf[n]; + unsigned char next = buf[n+1]; + buf[n] = mbedtls_ct_uint_if(no_op, current, next); + } + buf[total-1] = mbedtls_ct_uint_if_else_0(no_op, buf[total-1]); + } +} + +#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */ + +void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, + unsigned char *dest, + const unsigned char *src1, + const unsigned char *src2, + size_t len) +{ +#if defined(MBEDTLS_CT_SIZE_64) + const uint64_t mask = (uint64_t) condition; + const uint64_t not_mask = (uint64_t) ~mbedtls_ct_compiler_opaque(condition); +#else + const uint32_t mask = (uint32_t) condition; + const uint32_t not_mask = (uint32_t) ~mbedtls_ct_compiler_opaque(condition); +#endif + + /* If src2 is NULL, setup src2 so that we read from the destination address. + * + * This means that if src2 == NULL && condition is false, the result will be a + * no-op because we read from dest and write the same data back into dest. + */ + if (src2 == NULL) { + src2 = dest; + } + + /* dest[i] = c1 == c2 ? src[i] : dest[i] */ + size_t i = 0; +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) +#if defined(MBEDTLS_CT_SIZE_64) + for (; (i + 8) <= len; i += 8) { + uint64_t a = mbedtls_get_unaligned_uint64(src1 + i) & mask; + uint64_t b = mbedtls_get_unaligned_uint64(src2 + i) & not_mask; + mbedtls_put_unaligned_uint64(dest + i, a | b); + } +#else + for (; (i + 4) <= len; i += 4) { + uint32_t a = mbedtls_get_unaligned_uint32(src1 + i) & mask; + uint32_t b = mbedtls_get_unaligned_uint32(src2 + i) & not_mask; + mbedtls_put_unaligned_uint32(dest + i, a | b); + } +#endif /* defined(MBEDTLS_CT_SIZE_64) */ +#endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */ + for (; i < len; i++) { + dest[i] = (src1[i] & mask) | (src2[i] & not_mask); + } +} + +void mbedtls_ct_memcpy_offset(unsigned char *dest, + const unsigned char *src, + size_t offset, + size_t offset_min, + size_t offset_max, + size_t len) +{ + size_t offsetval; + + for (offsetval = offset_min; offsetval <= offset_max; offsetval++) { + mbedtls_ct_memcpy_if(mbedtls_ct_uint_eq(offsetval, offset), dest, src + offsetval, NULL, + len); + } +} + +#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) + +void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len) +{ + uint32_t mask = (uint32_t) ~condition; + uint8_t *p = (uint8_t *) buf; + size_t i = 0; +#if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) + for (; (i + 4) <= len; i += 4) { + mbedtls_put_unaligned_uint32((void *) (p + i), + mbedtls_get_unaligned_uint32((void *) (p + i)) & mask); + } +#endif + for (; i < len; i++) { + p[i] = p[i] & mask; + } +} + +#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_impl.h b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_impl.h new file mode 100644 index 0000000..7d2d885 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_impl.h @@ -0,0 +1,554 @@ +/** + * Constant-time functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONSTANT_TIME_IMPL_H +#define MBEDTLS_CONSTANT_TIME_IMPL_H + +#include + +#include "common.h" + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +/* + * To improve readability of constant_time_internal.h, the static inline + * definitions are here, and constant_time_internal.h has only the declarations. + * + * This results in duplicate declarations of the form: + * static inline void f(); // from constant_time_internal.h + * static inline void f() { ... } // from constant_time_impl.h + * when constant_time_internal.h is included. + * + * This appears to behave as if the declaration-without-definition was not present + * (except for warnings if gcc -Wredundant-decls or similar is used). + * + * Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled + * at the bottom of this file. + */ +//#ifdef __GNUC__ +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wredundant-decls" +//#endif + +/* Disable asm under Memsan because it confuses Memsan and generates false errors. + * + * We also disable under Valgrind by default, because it's more useful + * for Valgrind to test the plain C implementation. MBEDTLS_TEST_CONSTANT_FLOW_ASM //no-check-names + * may be set to permit building asm under Valgrind. + */ +#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN) || \ + (defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND) && !defined(MBEDTLS_TEST_CONSTANT_FLOW_ASM)) //no-check-names +#define MBEDTLS_CT_NO_ASM +#elif defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define MBEDTLS_CT_NO_ASM +#endif +#endif + +/* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ +#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && (!defined(__ARMCC_VERSION) || \ + __ARMCC_VERSION >= 6000000) && !defined(MBEDTLS_CT_NO_ASM) +#define MBEDTLS_CT_ASM +#if (defined(__arm__) || defined(__thumb__) || defined(__thumb2__)) +#define MBEDTLS_CT_ARM_ASM +#elif defined(__aarch64__) +#define MBEDTLS_CT_AARCH64_ASM +#elif defined(__amd64__) || defined(__x86_64__) +#define MBEDTLS_CT_X86_64_ASM +#elif defined(__i386__) +#define MBEDTLS_CT_X86_ASM +#endif +#endif + +#define MBEDTLS_CT_SIZE (sizeof(mbedtls_ct_uint_t) * 8) + + +/* ============================================================================ + * Core const-time primitives + */ + +/* Ensure that the compiler cannot know the value of x (i.e., cannot optimise + * based on its value) after this function is called. + * + * If we are not using assembly, this will be fairly inefficient, so its use + * should be minimised. + */ + +#if !defined(MBEDTLS_CT_ASM) +extern volatile mbedtls_ct_uint_t mbedtls_ct_zero; +#endif + +/** + * \brief Ensure that a value cannot be known at compile time. + * + * \param x The value to hide from the compiler. + * \return The same value that was passed in, such that the compiler + * cannot prove its value (even for calls of the form + * x = mbedtls_ct_compiler_opaque(1), x will be unknown). + * + * \note This is mainly used in constructing mbedtls_ct_condition_t + * values and performing operations over them, to ensure that + * there is no way for the compiler to ever know anything about + * the value of an mbedtls_ct_condition_t. + */ +static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x) +{ +#if defined(MBEDTLS_CT_ASM) + asm volatile ("" : [x] "+r" (x) :); + return x; +#else + return x ^ mbedtls_ct_zero; +#endif +} + +/* + * Selecting unified syntax is needed for gcc, and harmless on clang. + * + * This is needed because on Thumb 1, condition flags are always set, so + * e.g. "negs" is supported but "neg" is not (on Thumb 2, both exist). + * + * Under Thumb 1 unified syntax, only the "negs" form is accepted, and + * under divided syntax, only the "neg" form is accepted. clang only + * supports unified syntax. + * + * On Thumb 2 and Arm, both compilers are happy with the "s" suffix, + * although we don't actually care about setting the flags. + * + * For gcc, restore divided syntax afterwards - otherwise old versions of gcc + * seem to apply unified syntax globally, which breaks other asm code. + */ +#if !defined(__clang__) +#define RESTORE_ASM_SYNTAX ".syntax divided \n\t" +#else +#define RESTORE_ASM_SYNTAX +#endif + +/* Convert a number into a condition in constant time. */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) +{ + /* + * Define mask-generation code that, as far as possible, will not use branches or conditional instructions. + * + * For some platforms / type sizes, we define assembly to assure this. + * + * Otherwise, we define a plain C fallback which (in May 2023) does not get optimised into + * conditional instructions or branches by trunk clang, gcc, or MSVC v19. + */ +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + mbedtls_ct_uint_t s; + asm volatile ("neg %x[s], %x[x] \n\t" + "orr %x[x], %x[s], %x[x] \n\t" + "asr %x[x], %x[x], 63 \n\t" + : + [s] "=&r" (s), + [x] "+&r" (x) + : + : + ); + return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s; + asm volatile (".syntax unified \n\t" + "negs %[s], %[x] \n\t" + "orrs %[x], %[x], %[s] \n\t" + "asrs %[x], %[x], #31 \n\t" + RESTORE_ASM_SYNTAX + : + [s] "=&l" (s), + [x] "+&l" (x) + : + : + "cc" /* clobbers flag bits */ + ); + return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + uint64_t s; + asm volatile ("mov %[x], %[s] \n\t" + "neg %[s] \n\t" + "or %[x], %[s] \n\t" + "sar $63, %[s] \n\t" + : + [s] "=&a" (s) + : + [x] "D" (x) + : + ); + return (mbedtls_ct_condition_t) s; +#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s; + asm volatile ("mov %[x], %[s] \n\t" + "neg %[s] \n\t" + "or %[s], %[x] \n\t" + "sar $31, %[x] \n\t" + : + [s] "=&c" (s), + [x] "+&a" (x) + : + : + ); + return (mbedtls_ct_condition_t) x; +#else + const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); +#if defined(_MSC_VER) + /* MSVC has a warning about unary minus on unsigned, but this is + * well-defined and precisely what we want to do here */ +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + // y is negative (i.e., top bit set) iff x is non-zero + mbedtls_ct_int_t y = (-xo) | -(xo >> 1); + + // extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero) + y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1)); + + // -y has all bits set (if x is non-zero), or all bits clear (if x is zero) + return (mbedtls_ct_condition_t) (-y); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif +#endif +} + +static inline mbedtls_ct_uint_t mbedtls_ct_if(mbedtls_ct_condition_t condition, + mbedtls_ct_uint_t if1, + mbedtls_ct_uint_t if0) +{ +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t" + "mvn %x[condition], %x[condition] \n\t" + "and %x[condition], %x[condition], %x[if0] \n\t" + "orr %x[condition], %x[if1], %x[condition]" + : + [condition] "+&r" (condition), + [if1] "+&r" (if1) + : + [if0] "r" (if0) + : + ); + return (mbedtls_ct_uint_t) condition; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + asm volatile (".syntax unified \n\t" + "ands %[if1], %[if1], %[condition] \n\t" + "mvns %[condition], %[condition] \n\t" + "ands %[condition], %[condition], %[if0] \n\t" + "orrs %[condition], %[if1], %[condition] \n\t" + RESTORE_ASM_SYNTAX + : + [condition] "+&l" (condition), + [if1] "+&l" (if1) + : + [if0] "l" (if0) + : + "cc" + ); + return (mbedtls_ct_uint_t) condition; +#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + asm volatile ("and %[condition], %[if1] \n\t" + "not %[condition] \n\t" + "and %[condition], %[if0] \n\t" + "or %[if1], %[if0] \n\t" + : + [condition] "+&D" (condition), + [if1] "+&S" (if1), + [if0] "+&a" (if0) + : + : + ); + return if0; +#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) + asm volatile ("and %[condition], %[if1] \n\t" + "not %[condition] \n\t" + "and %[if0], %[condition] \n\t" + "or %[condition], %[if1] \n\t" + : + [condition] "+&c" (condition), + [if1] "+&a" (if1) + : + [if0] "b" (if0) + : + ); + return if1; +#else + mbedtls_ct_condition_t not_cond = + (mbedtls_ct_condition_t) (~mbedtls_ct_compiler_opaque(condition)); + return (mbedtls_ct_uint_t) ((condition & if1) | (not_cond & if0)); +#endif +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) +{ +#if defined(MBEDTLS_CT_AARCH64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + uint64_t s1; + asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" + "sub %x[x], %x[x], %x[y] \n\t" + "bic %x[x], %x[x], %x[s1] \n\t" + "and %x[s1], %x[s1], %x[y] \n\t" + "orr %x[s1], %x[x], %x[s1] \n\t" + "asr %x[x], %x[s1], 63" + : + [s1] "=&r" (s1), + [x] "+&r" (x) + : + [y] "r" (y) + : + ); + return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_ARM_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s1; + asm volatile ( + ".syntax unified \n\t" +#if defined(__thumb__) && !defined(__thumb2__) + "movs %[s1], %[x] \n\t" + "eors %[s1], %[s1], %[y] \n\t" +#else + "eors %[s1], %[x], %[y] \n\t" +#endif + "subs %[x], %[x], %[y] \n\t" + "bics %[x], %[x], %[s1] \n\t" + "ands %[y], %[s1], %[y] \n\t" + "orrs %[x], %[x], %[y] \n\t" + "asrs %[x], %[x], #31 \n\t" + RESTORE_ASM_SYNTAX + : + [s1] "=&l" (s1), + [x] "+&l" (x), + [y] "+&l" (y) + : + : + "cc" + ); + return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_X86_64_ASM) && (defined(MBEDTLS_CT_SIZE_32) || defined(MBEDTLS_CT_SIZE_64)) + uint64_t s; + asm volatile ("mov %[x], %[s] \n\t" + "xor %[y], %[s] \n\t" + "sub %[y], %[x] \n\t" + "and %[s], %[y] \n\t" + "not %[s] \n\t" + "and %[s], %[x] \n\t" + "or %[y], %[x] \n\t" + "sar $63, %[x] \n\t" + : + [s] "=&a" (s), + [x] "+&D" (x), + [y] "+&S" (y) + : + : + ); + return (mbedtls_ct_condition_t) x; +#elif defined(MBEDTLS_CT_X86_ASM) && defined(MBEDTLS_CT_SIZE_32) + uint32_t s; + asm volatile ("mov %[x], %[s] \n\t" + "xor %[y], %[s] \n\t" + "sub %[y], %[x] \n\t" + "and %[s], %[y] \n\t" + "not %[s] \n\t" + "and %[s], %[x] \n\t" + "or %[y], %[x] \n\t" + "sar $31, %[x] \n\t" + : + [s] "=&b" (s), + [x] "+&a" (x), + [y] "+&c" (y) + : + : + ); + return (mbedtls_ct_condition_t) x; +#else + /* Ensure that the compiler cannot optimise the following operations over x and y, + * even if it knows the value of x and y. + */ + const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); + const mbedtls_ct_uint_t yo = mbedtls_ct_compiler_opaque(y); + /* + * Check if the most significant bits (MSB) of the operands are different. + * cond is true iff the MSBs differ. + */ + mbedtls_ct_condition_t cond = mbedtls_ct_bool((xo ^ yo) >> (MBEDTLS_CT_SIZE - 1)); + + /* + * If the MSB are the same then the difference x-y will be negative (and + * have its MSB set to 1 during conversion to unsigned) if and only if x> (MBEDTLS_CT_SIZE - 1); + + // Convert to a condition (i.e., all bits set iff non-zero) + return mbedtls_ct_bool(ret); +#endif +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) +{ + /* diff = 0 if x == y, non-zero otherwise */ + const mbedtls_ct_uint_t diff = mbedtls_ct_compiler_opaque(x) ^ mbedtls_ct_compiler_opaque(y); + + /* all ones if x != y, 0 otherwise */ + return mbedtls_ct_bool(diff); +} + +static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, + unsigned char high, + unsigned char c, + unsigned char t) +{ + const unsigned char co = (unsigned char) mbedtls_ct_compiler_opaque(c); + const unsigned char to = (unsigned char) mbedtls_ct_compiler_opaque(t); + + /* low_mask is: 0 if low <= c, 0x...ff if low > c */ + unsigned low_mask = ((unsigned) co - low) >> 8; + /* high_mask is: 0 if c <= high, 0x...ff if c > high */ + unsigned high_mask = ((unsigned) high - co) >> 8; + + return (unsigned char) (~(low_mask | high_mask)) & to; +} + +/* ============================================================================ + * Everything below here is trivial wrapper functions + */ + +static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, + size_t if1, + size_t if0) +{ + return (size_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0); +} + +static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, + unsigned if1, + unsigned if0) +{ + return (unsigned) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, (mbedtls_ct_uint_t) if0); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, + mbedtls_ct_condition_t if1, + mbedtls_ct_condition_t if0) +{ + return (mbedtls_ct_condition_t) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) if1, + (mbedtls_ct_uint_t) if0); +} + +#if defined(MBEDTLS_BIGNUM_C) + +static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, + mbedtls_mpi_uint if1, + mbedtls_mpi_uint if0) +{ + return (mbedtls_mpi_uint) mbedtls_ct_if(condition, + (mbedtls_ct_uint_t) if1, + (mbedtls_ct_uint_t) if0); +} + +#endif + +static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1) +{ + return (size_t) (condition & if1); +} + +static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1) +{ + return (unsigned) (condition & if1); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, + mbedtls_ct_condition_t if1) +{ + return (mbedtls_ct_condition_t) (condition & if1); +} + +#if defined(MBEDTLS_BIGNUM_C) + +static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, + mbedtls_mpi_uint if1) +{ + return (mbedtls_mpi_uint) (condition & if1); +} + +#endif /* MBEDTLS_BIGNUM_C */ + +static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0) +{ + /* Coverting int -> uint -> int here is safe, because we require if1 and if0 to be + * in the range -32767..0, and we require 32-bit int and uint types. + * + * This means that (0 <= -if0 < INT_MAX), so negating if0 is safe, and similarly for + * converting back to int. + */ + return -((int) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) (-if1), + (mbedtls_ct_uint_t) (-if0))); +} + +static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1) +{ + return -((int) (condition & (-if1))); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y) +{ + return ~mbedtls_ct_uint_ne(x, y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y) +{ + return mbedtls_ct_uint_lt(y, x); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y) +{ + return ~mbedtls_ct_uint_lt(x, y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y) +{ + return ~mbedtls_ct_uint_gt(x, y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y) +{ + return (mbedtls_ct_condition_t) (x ^ y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y) +{ + return (mbedtls_ct_condition_t) (x & y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y) +{ + return (mbedtls_ct_condition_t) (x | y); +} + +static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x) +{ + return (mbedtls_ct_condition_t) (~x); +} + +//#ifdef __GNUC__ +///* Restore warnings for -Wredundant-decls on gcc */ +// #pragma GCC diagnostic pop +//#endif + +#endif /* MBEDTLS_CONSTANT_TIME_IMPL_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_internal.h b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_internal.h new file mode 100644 index 0000000..61a5c6d --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/constant_time_internal.h @@ -0,0 +1,579 @@ +/** + * Constant-time functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H +#define MBEDTLS_CONSTANT_TIME_INTERNAL_H + +#include +#include + +#include "common.h" + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +/* The constant-time interface provides various operations that are likely + * to result in constant-time code that does not branch or use conditional + * instructions for secret data (for secret pointers, this also applies to + * the data pointed to). + * + * It has three main parts: + * + * - boolean operations + * These are all named mbedtls_ct__. + * They operate over and return mbedtls_ct_condition_t. + * All arguments are considered secret. + * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z) + * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z) + * + * - conditional data selection + * These are all named mbedtls_ct__if and mbedtls_ct__if_else_0 + * All arguments are considered secret. + * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c) + * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b) + * + * - block memory operations + * Only some arguments are considered secret, as documented for each + * function. + * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...) + * + * mbedtls_ct_condition_t must be treated as opaque and only created and + * manipulated via the functions in this header. The compiler should never + * be able to prove anything about its value at compile-time. + * + * mbedtls_ct_uint_t is an unsigned integer type over which constant time + * operations may be performed via the functions in this header. It is as big + * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast + * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other + * not-larger integer types). + * + * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations + * are used to ensure that the generated code is constant time. For other + * architectures, it uses a plain C fallback designed to yield constant-time code + * (this has been observed to be constant-time on latest gcc, clang and MSVC + * as of May 2023). + * + * For readability, the static inline definitions are separated out into + * constant_time_impl.h. + */ + +#if (SIZE_MAX > 0xffffffffffffffffULL) +/* Pointer size > 64-bit */ +typedef size_t mbedtls_ct_condition_t; +typedef size_t mbedtls_ct_uint_t; +typedef ptrdiff_t mbedtls_ct_int_t; +#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX)) +#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64) +/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */ +typedef uint64_t mbedtls_ct_condition_t; +typedef uint64_t mbedtls_ct_uint_t; +typedef int64_t mbedtls_ct_int_t; +#define MBEDTLS_CT_SIZE_64 +#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX)) +#else +/* Pointer size <= 32-bit, and no 64-bit MPIs */ +typedef uint32_t mbedtls_ct_condition_t; +typedef uint32_t mbedtls_ct_uint_t; +typedef int32_t mbedtls_ct_int_t; +#define MBEDTLS_CT_SIZE_32 +#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX)) +#endif +#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0)) + +/* ============================================================================ + * Boolean operations + */ + +/** Convert a number into a mbedtls_ct_condition_t. + * + * \param x Number to convert. + * + * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0 + * + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x); + +/** Boolean "not equal" operation. + * + * Functionally equivalent to: + * + * \p x != \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); + +/** Boolean "equals" operation. + * + * Functionally equivalent to: + * + * \p x == \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y); + +/** Boolean "less than" operation. + * + * Functionally equivalent to: + * + * \p x < \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y); + +/** Boolean "greater than" operation. + * + * Functionally equivalent to: + * + * \p x > \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y); + +/** Boolean "greater or equal" operation. + * + * Functionally equivalent to: + * + * \p x >= \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x >= \p y, + * otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y); + +/** Boolean "less than or equal" operation. + * + * Functionally equivalent to: + * + * \p x <= \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x <= \p y, + * otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, + mbedtls_ct_uint_t y); + +/** Boolean not-equals operation. + * + * Functionally equivalent to: + * + * \p x != \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are + * mbedtls_ct_condition_t. + * + * \return MBEDTLS_CT_TRUE if \p x != \p y, + * otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y); + +/** Boolean "and" operation. + * + * Functionally equivalent to: + * + * \p x && \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x && \p y, + * otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y); + +/** Boolean "or" operation. + * + * Functionally equivalent to: + * + * \p x || \p y + * + * \param x The first value to analyze. + * \param y The second value to analyze. + * + * \return MBEDTLS_CT_TRUE if \p x || \p y, + * otherwise MBEDTLS_CT_FALSE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, + mbedtls_ct_condition_t y); + +/** Boolean "not" operation. + * + * Functionally equivalent to: + * + * ! \p x + * + * \param x The value to invert + * + * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x); + + +/* ============================================================================ + * Data selection operations + */ + +/** Choose between two size_t values. + * + * Functionally equivalent to: + * + * condition ? if1 : if0. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. + */ +static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition, + size_t if1, + size_t if0); + +/** Choose between two unsigned values. + * + * Functionally equivalent to: + * + * condition ? if1 : if0. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. + */ +static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition, + unsigned if1, + unsigned if0); + +/** Choose between two mbedtls_ct_condition_t values. + * + * Functionally equivalent to: + * + * condition ? if1 : if0. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition, + mbedtls_ct_condition_t if1, + mbedtls_ct_condition_t if0); + +#if defined(MBEDTLS_BIGNUM_C) + +/** Choose between two mbedtls_mpi_uint values. + * + * Functionally equivalent to: + * + * condition ? if1 : if0. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. + */ +static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \ + mbedtls_mpi_uint if1, \ + mbedtls_mpi_uint if0); + +#endif + +/** Choose between an unsigned value and 0. + * + * Functionally equivalent to: + * + * condition ? if1 : 0. + * + * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but + * results in smaller code size. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. + */ +static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1); + +/** Choose between an mbedtls_ct_condition_t and 0. + * + * Functionally equivalent to: + * + * condition ? if1 : 0. + * + * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but + * results in smaller code size. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. + */ +static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition, + mbedtls_ct_condition_t if1); + +/** Choose between a size_t value and 0. + * + * Functionally equivalent to: + * + * condition ? if1 : 0. + * + * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but + * results in smaller code size. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. + */ +static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1); + +#if defined(MBEDTLS_BIGNUM_C) + +/** Choose between an mbedtls_mpi_uint value and 0. + * + * Functionally equivalent to: + * + * condition ? if1 : 0. + * + * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but + * results in smaller code size. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. + */ +static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition, + mbedtls_mpi_uint if1); + +#endif + +/** Constant-flow char selection + * + * \param low Secret. Bottom of range + * \param high Secret. Top of range + * \param c Secret. Value to compare to range + * \param t Secret. Value to return, if in range + * + * \return \p t if \p low <= \p c <= \p high, 0 otherwise. + */ +static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low, + unsigned char high, + unsigned char c, + unsigned char t); + +/** Choose between two error values. The values must be in the range [-32767..0]. + * + * Functionally equivalent to: + * + * condition ? if1 : if0. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0. + */ +static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0); + +/** Choose between an error value and 0. The error value must be in the range [-32767..0]. + * + * Functionally equivalent to: + * + * condition ? if1 : 0. + * + * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but + * results in smaller code size. + * + * \param condition Condition to test. + * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE. + * + * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0. + */ +static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1); + +/* ============================================================================ + * Block memory operations + */ + +#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) + +/** Conditionally set a block of memory to zero. + * + * Regardless of the condition, every byte will be read once and written to + * once. + * + * \param condition Secret. Condition to test. + * \param buf Secret. Pointer to the start of the buffer. + * \param len Number of bytes to set to zero. + * + * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees + * about not being optimised away if the memory is never read again. + */ +void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len); + +/** Shift some data towards the left inside a buffer. + * + * Functionally equivalent to: + * + * memmove(start, start + offset, total - offset); + * memset(start + (total - offset), 0, offset); + * + * Timing independence comes at the expense of performance. + * + * \param start Secret. Pointer to the start of the buffer. + * \param total Total size of the buffer. + * \param offset Secret. Offset from which to copy \p total - \p offset bytes. + */ +void mbedtls_ct_memmove_left(void *start, + size_t total, + size_t offset); + +#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */ + +/** Conditional memcpy. + * + * Functionally equivalent to: + * + * if (condition) { + * memcpy(dest, src1, len); + * } else { + * if (src2 != NULL) + * memcpy(dest, src2, len); + * } + * + * It will always read len bytes from src1. + * If src2 != NULL, it will always read len bytes from src2. + * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest). + * + * \param condition The condition + * \param dest Secret. Destination pointer. + * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). + * This may be equal to \p dest, but may not overlap in other ways. + * \param src2 Secret (contents only - may branch to determine if this parameter is NULL). + * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL. + * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1. + * \param len Number of bytes to copy. + */ +void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition, + unsigned char *dest, + const unsigned char *src1, + const unsigned char *src2, + size_t len + ); + +/** Copy data from a secret position. + * + * Functionally equivalent to: + * + * memcpy(dst, src + offset, len) + * + * This function copies \p len bytes from \p src + \p offset to + * \p dst, with a code flow and memory access pattern that does not depend on + * \p offset, but only on \p offset_min, \p offset_max and \p len. + * + * \note This function reads from \p dest, but the value that + * is read does not influence the result and this + * function's behavior is well-defined regardless of the + * contents of the buffers. This may result in false + * positives from static or dynamic analyzers, especially + * if \p dest is not initialized. + * + * \param dest Secret. The destination buffer. This must point to a writable + * buffer of at least \p len bytes. + * \param src Secret. The base of the source buffer. This must point to a + * readable buffer of at least \p offset_max + \p len + * bytes. Shouldn't overlap with \p dest + * \param offset Secret. The offset in the source buffer from which to copy. + * This must be no less than \p offset_min and no greater + * than \p offset_max. + * \param offset_min The minimal value of \p offset. + * \param offset_max The maximal value of \p offset. + * \param len The number of bytes to copy. + */ +void mbedtls_ct_memcpy_offset(unsigned char *dest, + const unsigned char *src, + size_t offset, + size_t offset_min, + size_t offset_max, + size_t len); + +/* Documented in include/mbedtls/constant_time.h. a and b are secret. + + int mbedtls_ct_memcmp(const void *a, + const void *b, + size_t n); + */ + +#if defined(MBEDTLS_NIST_KW_C) + +/** Constant-time buffer comparison without branches. + * + * Similar to mbedtls_ct_memcmp, except that the result only depends on part of + * the input data - differences in the head or tail are ignored. Functionally equivalent to: + * + * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail) + * + * Time taken depends on \p n, but not on \p skip_head or \p skip_tail . + * + * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n. + * + * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL. + * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL. + * \param n The number of bytes to examine (total size of the buffers). + * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer. + * These bytes will still be read. + * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer. + * These bytes will still be read. + * + * \return Zero if the contents of the two buffers are the same, otherwise non-zero. + */ +int mbedtls_ct_memcmp_partial(const void *a, + const void *b, + size_t n, + size_t skip_head, + size_t skip_tail); + +#endif + +/* Include the implementation of static inline functions above. */ +#include "constant_time_impl.h" + +#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecdh.c b/src/app/findmy/crypto/third-party/mbedtls/library/ecdh.c new file mode 100644 index 0000000..e060b18 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecdh.c @@ -0,0 +1,685 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * References: + * + * SEC1 https://www.secg.org/sec1-v2.pdf + * RFC 4492 + */ + +#include "common.h" + +#if defined(MBEDTLS_ECDH_C) + +#include "mbedtls/ecdh.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) +typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; +#endif + +static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( + const mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ctx->grp.id; +#else + return ctx->grp_id; +#endif +} + +int mbedtls_ecdh_can_do(mbedtls_ecp_group_id gid) +{ + /* At this time, all groups support ECDH. */ + (void) gid; + return 1; +} + +#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) +/* + * Generate public key (restartable version) + * + * Note: this internal function relies on its caller preserving the value of + * the output parameter 'd' across continuation calls. This would not be + * acceptable for a public function but is OK here as we control call sites. + */ +static int ecdh_gen_public_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + int restarting = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); +#endif + /* If multiplication is in progress, we already generated a privkey */ + if (!restarting) { + MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); + } + + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, Q, d, &grp->G, + f_rng, p_rng, rs_ctx)); + +cleanup: + return ret; +} + +/* + * Generate public key + */ +int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return ecdh_gen_public_restartable(grp, d, Q, f_rng, p_rng, NULL); +} +#endif /* !MBEDTLS_ECDH_GEN_PUBLIC_ALT */ + +#if !defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) +/* + * Compute shared secret (SEC1 3.3.1) + */ +static int ecdh_compute_shared_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point P; + + mbedtls_ecp_point_init(&P); + + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &P, d, Q, + f_rng, p_rng, rs_ctx)); + + if (mbedtls_ecp_is_zero(&P)) { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(z, &P.X)); + +cleanup: + mbedtls_ecp_point_free(&P); + + return ret; +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return ecdh_compute_shared_restartable(grp, z, Q, d, + f_rng, p_rng, NULL); +} +#endif /* !MBEDTLS_ECDH_COMPUTE_SHARED_ALT */ + +static void ecdh_init_internal(mbedtls_ecdh_context_mbed *ctx) +{ + mbedtls_ecp_group_init(&ctx->grp); + mbedtls_mpi_init(&ctx->d); + mbedtls_ecp_point_init(&ctx->Q); + mbedtls_ecp_point_init(&ctx->Qp); + mbedtls_mpi_init(&ctx->z); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_init(&ctx->rs); +#endif +} + +/* + * Initialize context + */ +void mbedtls_ecdh_init(mbedtls_ecdh_context *ctx) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + ecdh_init_internal(ctx); + mbedtls_ecp_point_init(&ctx->Vi); + mbedtls_ecp_point_init(&ctx->Vf); + mbedtls_mpi_init(&ctx->_d); +#else + memset(ctx, 0, sizeof(mbedtls_ecdh_context)); + + ctx->var = MBEDTLS_ECDH_VARIANT_NONE; +#endif + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + ctx->restart_enabled = 0; +#endif +} + +static int ecdh_setup_internal(mbedtls_ecdh_context_mbed *ctx, + mbedtls_ecp_group_id grp_id) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_ecp_group_load(&ctx->grp, grp_id); + if (ret != 0) { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } + + return 0; +} + +/* + * Setup context + */ +int mbedtls_ecdh_setup(mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_setup_internal(ctx, grp_id); +#else + switch (grp_id) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST; + ctx->grp_id = grp_id; + return mbedtls_everest_setup(&ctx->ctx.everest_ecdh, grp_id); +#endif + default: + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0; + ctx->grp_id = grp_id; + ecdh_init_internal(&ctx->ctx.mbed_ecdh); + return ecdh_setup_internal(&ctx->ctx.mbed_ecdh, grp_id); + } +#endif +} + +static void ecdh_free_internal(mbedtls_ecdh_context_mbed *ctx) +{ + mbedtls_ecp_group_free(&ctx->grp); + mbedtls_mpi_free(&ctx->d); + mbedtls_ecp_point_free(&ctx->Q); + mbedtls_ecp_point_free(&ctx->Qp); + mbedtls_mpi_free(&ctx->z); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_free(&ctx->rs); +#endif +} + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/* + * Enable restartable operations for context + */ +void mbedtls_ecdh_enable_restart(mbedtls_ecdh_context *ctx) +{ + ctx->restart_enabled = 1; +} +#endif + +/* + * Free context + */ +void mbedtls_ecdh_free(mbedtls_ecdh_context *ctx) +{ + if (ctx == NULL) { + return; + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + mbedtls_ecp_point_free(&ctx->Vi); + mbedtls_ecp_point_free(&ctx->Vf); + mbedtls_mpi_free(&ctx->_d); + ecdh_free_internal(ctx); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + mbedtls_everest_free(&ctx->ctx.everest_ecdh); + break; +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + ecdh_free_internal(&ctx->ctx.mbed_ecdh); + break; + default: + break; + } + + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + ctx->var = MBEDTLS_ECDH_VARIANT_NONE; + ctx->grp_id = MBEDTLS_ECP_DP_NONE; +#endif +} + +static int ecdh_make_params_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, int point_format, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t grp_len, pt_len; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng, rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + if ((ret = mbedtls_ecp_tls_write_group(&ctx->grp, &grp_len, buf, + blen)) != 0) { + return ret; + } + + buf += grp_len; + blen -= grp_len; + + if ((ret = mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, + &pt_len, buf, blen)) != 0) { + return ret; + } + + *olen = grp_len + pt_len; + return 0; +} + +/* + * Setup and write the ServerKeyExchange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_make_params(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_make_params_internal(ctx, olen, ctx->point_format, buf, blen, + f_rng, p_rng, restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_make_params(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_make_params_internal(&ctx->ctx.mbed_ecdh, olen, + ctx->point_format, buf, blen, + f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_read_params_internal(mbedtls_ecdh_context_mbed *ctx, + const unsigned char **buf, + const unsigned char *end) +{ + return mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, buf, + end - *buf); +} + +/* + * Read the ServerKeyExchange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_read_params(mbedtls_ecdh_context *ctx, + const unsigned char **buf, + const unsigned char *end) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_group_id grp_id; + if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, end - *buf)) + != 0) { + return ret; + } + + if ((ret = mbedtls_ecdh_setup(ctx, grp_id)) != 0) { + return ret; + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_read_params_internal(ctx, buf, end); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_read_params(&ctx->ctx.everest_ecdh, + buf, end); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_read_params_internal(&ctx->ctx.mbed_ecdh, + buf, end); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_get_params_internal(mbedtls_ecdh_context_mbed *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* If it's not our key, just import the public part as Qp */ + if (side == MBEDTLS_ECDH_THEIRS) { + return mbedtls_ecp_copy(&ctx->Qp, &key->Q); + } + + /* Our key: import public (as Q) and private parts */ + if (side != MBEDTLS_ECDH_OURS) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if ((ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0 || + (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0) { + return ret; + } + + return 0; +} + +/* + * Get parameters from a keypair + */ +int mbedtls_ecdh_get_params(mbedtls_ecdh_context *ctx, + const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + if (side != MBEDTLS_ECDH_OURS && side != MBEDTLS_ECDH_THEIRS) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if (mbedtls_ecdh_grp_id(ctx) == MBEDTLS_ECP_DP_NONE) { + /* This is the first call to get_params(). Set up the context + * for use with the group. */ + if ((ret = mbedtls_ecdh_setup(ctx, key->grp.id)) != 0) { + return ret; + } + } else { + /* This is not the first call to get_params(). Check that the + * current key's group is the same as the context's, which was set + * from the first key's group. */ + if (mbedtls_ecdh_grp_id(ctx) != key->grp.id) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + } + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_get_params_internal(ctx, key, side); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + { + mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ? + MBEDTLS_EVEREST_ECDH_OURS : + MBEDTLS_EVEREST_ECDH_THEIRS; + return mbedtls_everest_get_params(&ctx->ctx.everest_ecdh, + key, s); + } +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_get_params_internal(&ctx->ctx.mbed_ecdh, + key, side); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_make_public_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, int point_format, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_gen_public_restartable(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng, rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_gen_public(&ctx->grp, &ctx->d, &ctx->Q, + f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + return mbedtls_ecp_tls_write_point(&ctx->grp, &ctx->Q, point_format, olen, + buf, blen); +} + +/* + * Setup and export the client public value + */ +int mbedtls_ecdh_make_public(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_make_public_internal(ctx, olen, ctx->point_format, buf, blen, + f_rng, p_rng, restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_make_public(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_make_public_internal(&ctx->ctx.mbed_ecdh, olen, + ctx->point_format, buf, blen, + f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_read_public_internal(mbedtls_ecdh_context_mbed *ctx, + const unsigned char *buf, size_t blen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const unsigned char *p = buf; + + if ((ret = mbedtls_ecp_tls_read_point(&ctx->grp, &ctx->Qp, &p, + blen)) != 0) { + return ret; + } + + if ((size_t) (p - buf) != blen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + return 0; +} + +/* + * Parse and import the client's public value + */ +int mbedtls_ecdh_read_public(mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_read_public_internal(ctx, buf, blen); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_read_public(&ctx->ctx.everest_ecdh, + buf, blen); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_read_public_internal(&ctx->ctx.mbed_ecdh, + buf, blen); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} + +static int ecdh_calc_secret_internal(mbedtls_ecdh_context_mbed *ctx, + size_t *olen, unsigned char *buf, + size_t blen, + int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng, + int restart_enabled) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecp_restart_ctx *rs_ctx = NULL; +#endif + + if (ctx == NULL || ctx->grp.pbits == 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (restart_enabled) { + rs_ctx = &ctx->rs; + } +#else + (void) restart_enabled; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if ((ret = ecdh_compute_shared_restartable(&ctx->grp, &ctx->z, &ctx->Qp, + &ctx->d, f_rng, p_rng, + rs_ctx)) != 0) { + return ret; + } +#else + if ((ret = mbedtls_ecdh_compute_shared(&ctx->grp, &ctx->z, &ctx->Qp, + &ctx->d, f_rng, p_rng)) != 0) { + return ret; + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + if (mbedtls_mpi_size(&ctx->z) > blen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + *olen = ctx->grp.pbits / 8 + ((ctx->grp.pbits % 8) != 0); + + if (mbedtls_ecp_get_type(&ctx->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + return mbedtls_mpi_write_binary_le(&ctx->z, buf, *olen); + } + + return mbedtls_mpi_write_binary(&ctx->z, buf, *olen); +} + +/* + * Derive and export the shared secret + */ +int mbedtls_ecdh_calc_secret(mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int restart_enabled = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restart_enabled = ctx->restart_enabled; +#endif + +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return ecdh_calc_secret_internal(ctx, olen, buf, blen, f_rng, p_rng, + restart_enabled); +#else + switch (ctx->var) { +#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) + case MBEDTLS_ECDH_VARIANT_EVEREST: + return mbedtls_everest_calc_secret(&ctx->ctx.everest_ecdh, olen, + buf, blen, f_rng, p_rng); +#endif + case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0: + return ecdh_calc_secret_internal(&ctx->ctx.mbed_ecdh, olen, buf, + blen, f_rng, p_rng, + restart_enabled); + default: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } +#endif +} +#endif /* MBEDTLS_ECDH_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecdsa.c b/src/app/findmy/crypto/third-party/mbedtls/library/ecdsa.c new file mode 100644 index 0000000..2f7a996 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecdsa.c @@ -0,0 +1,867 @@ +/* + * Elliptic curve DSA + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * References: + * + * SEC1 https://www.secg.org/sec1-v2.pdf + */ + +#include "common.h" + +#if defined(MBEDTLS_ECDSA_C) + +#include "mbedtls/ecdsa.h" +#include "mbedtls/asn1write.h" + +#include + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#include "mbedtls/hmac_drbg.h" +#endif + +#include "mbedtls/platform.h" + +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#if defined(MBEDTLS_ECP_RESTARTABLE) + +/* + * Sub-context for ecdsa_verify() + */ +struct mbedtls_ecdsa_restart_ver { + mbedtls_mpi u1, u2; /* intermediate values */ + enum { /* what to do next? */ + ecdsa_ver_init = 0, /* getting started */ + ecdsa_ver_muladd, /* muladd step */ + } state; +}; + +/* + * Init verify restart sub-context + */ +static void ecdsa_restart_ver_init(mbedtls_ecdsa_restart_ver_ctx *ctx) +{ + mbedtls_mpi_init(&ctx->u1); + mbedtls_mpi_init(&ctx->u2); + ctx->state = ecdsa_ver_init; +} + +/* + * Free the components of a verify restart sub-context + */ +static void ecdsa_restart_ver_free(mbedtls_ecdsa_restart_ver_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_mpi_free(&ctx->u1); + mbedtls_mpi_free(&ctx->u2); + + ecdsa_restart_ver_init(ctx); +} + +/* + * Sub-context for ecdsa_sign() + */ +struct mbedtls_ecdsa_restart_sig { + int sign_tries; + int key_tries; + mbedtls_mpi k; /* per-signature random */ + mbedtls_mpi r; /* r value */ + enum { /* what to do next? */ + ecdsa_sig_init = 0, /* getting started */ + ecdsa_sig_mul, /* doing ecp_mul() */ + ecdsa_sig_modn, /* mod N computations */ + } state; +}; + +/* + * Init verify sign sub-context + */ +static void ecdsa_restart_sig_init(mbedtls_ecdsa_restart_sig_ctx *ctx) +{ + ctx->sign_tries = 0; + ctx->key_tries = 0; + mbedtls_mpi_init(&ctx->k); + mbedtls_mpi_init(&ctx->r); + ctx->state = ecdsa_sig_init; +} + +/* + * Free the components of a sign restart sub-context + */ +static void ecdsa_restart_sig_free(mbedtls_ecdsa_restart_sig_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_mpi_free(&ctx->k); + mbedtls_mpi_free(&ctx->r); +} + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/* + * Sub-context for ecdsa_sign_det() + */ +struct mbedtls_ecdsa_restart_det { + mbedtls_hmac_drbg_context rng_ctx; /* DRBG state */ + enum { /* what to do next? */ + ecdsa_det_init = 0, /* getting started */ + ecdsa_det_sign, /* make signature */ + } state; +}; + +/* + * Init verify sign_det sub-context + */ +static void ecdsa_restart_det_init(mbedtls_ecdsa_restart_det_ctx *ctx) +{ + mbedtls_hmac_drbg_init(&ctx->rng_ctx); + ctx->state = ecdsa_det_init; +} + +/* + * Free the components of a sign_det restart sub-context + */ +static void ecdsa_restart_det_free(mbedtls_ecdsa_restart_det_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_hmac_drbg_free(&ctx->rng_ctx); + + ecdsa_restart_det_init(ctx); +} +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#define ECDSA_RS_ECP (rs_ctx == NULL ? NULL : &rs_ctx->ecp) + +/* Utility macro for checking and updating ops budget */ +#define ECDSA_BUDGET(ops) \ + MBEDTLS_MPI_CHK(mbedtls_ecp_check_budget(grp, ECDSA_RS_ECP, ops)); + +/* Call this when entering a function that needs its own sub-context */ +#define ECDSA_RS_ENTER(SUB) do { \ + /* reset ops count for this call if top-level */ \ + if (rs_ctx != NULL && rs_ctx->ecp.depth++ == 0) \ + rs_ctx->ecp.ops_done = 0; \ + \ + /* set up our own sub-context if needed */ \ + if (mbedtls_ecp_restart_is_enabled() && \ + rs_ctx != NULL && rs_ctx->SUB == NULL) \ + { \ + rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \ + if (rs_ctx->SUB == NULL) \ + return MBEDTLS_ERR_ECP_ALLOC_FAILED; \ + \ + ecdsa_restart_## SUB ##_init(rs_ctx->SUB); \ + } \ +} while (0) + +/* Call this when leaving a function that needs its own sub-context */ +#define ECDSA_RS_LEAVE(SUB) do { \ + /* clear our sub-context when not in progress (done or error) */ \ + if (rs_ctx != NULL && rs_ctx->SUB != NULL && \ + ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \ + { \ + ecdsa_restart_## SUB ##_free(rs_ctx->SUB); \ + mbedtls_free(rs_ctx->SUB); \ + rs_ctx->SUB = NULL; \ + } \ + \ + if (rs_ctx != NULL) \ + rs_ctx->ecp.depth--; \ +} while (0) + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +#define ECDSA_RS_ECP NULL + +#define ECDSA_BUDGET(ops) /* no-op; for compatibility */ + +#define ECDSA_RS_ENTER(SUB) (void) rs_ctx +#define ECDSA_RS_LEAVE(SUB) (void) rs_ctx + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) || \ + !defined(MBEDTLS_ECDSA_SIGN_ALT) || \ + !defined(MBEDTLS_ECDSA_VERIFY_ALT) +/* + * Derive a suitable integer for group grp from a buffer of length len + * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 + */ +static int derive_mpi(const mbedtls_ecp_group *grp, mbedtls_mpi *x, + const unsigned char *buf, size_t blen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t n_size = (grp->nbits + 7) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(x, buf, use_size)); + if (use_size * 8 > grp->nbits) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(x, use_size * 8 - grp->nbits)); + } + + /* While at it, reduce modulo N */ + if (mbedtls_mpi_cmp_mpi(x, &grp->N) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(x, x, &grp->N)); + } + +cleanup: + return ret; +} +#endif /* ECDSA_DETERMINISTIC || !ECDSA_SIGN_ALT || !ECDSA_VERIFY_ALT */ + +int mbedtls_ecdsa_can_do(mbedtls_ecp_group_id gid) +{ + switch (gid) { +#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED + case MBEDTLS_ECP_DP_CURVE25519: return 0; +#endif +#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED + case MBEDTLS_ECP_DP_CURVE448: return 0; +#endif + default: return 1; + } +} + +#if !defined(MBEDTLS_ECDSA_SIGN_ALT) +/* + * Compute ECDSA signature of a hashed message (SEC1 4.1.3) + * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) + */ +int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret, key_tries, sign_tries; + int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; + mbedtls_ecp_point R; + mbedtls_mpi k, e, t; + mbedtls_mpi *pk = &k, *pr = r; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* Make sure d is in range 1..n-1 */ + if (mbedtls_mpi_cmp_int(d, 1) < 0 || mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + mbedtls_ecp_point_init(&R); + mbedtls_mpi_init(&k); mbedtls_mpi_init(&e); mbedtls_mpi_init(&t); + + ECDSA_RS_ENTER(sig); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->sig != NULL) { + /* redirect to our context */ + p_sign_tries = &rs_ctx->sig->sign_tries; + p_key_tries = &rs_ctx->sig->key_tries; + pk = &rs_ctx->sig->k; + pr = &rs_ctx->sig->r; + + /* jump to current step */ + if (rs_ctx->sig->state == ecdsa_sig_mul) { + goto mul; + } + if (rs_ctx->sig->state == ecdsa_sig_modn) { + goto modn; + } + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + *p_sign_tries = 0; + do { + if ((*p_sign_tries)++ > 10) { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + + /* + * Steps 1-3: generate a suitable ephemeral keypair + * and set r = xR mod n + */ + *p_key_tries = 0; + do { + if ((*p_key_tries)++ > 10) { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + + MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, pk, f_rng, p_rng)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->sig != NULL) { + rs_ctx->sig->state = ecdsa_sig_mul; + } + +mul: +#endif + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_restartable(grp, &R, pk, &grp->G, + f_rng_blind, + p_rng_blind, + ECDSA_RS_ECP)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pr, &R.X, &grp->N)); + } while (mbedtls_mpi_cmp_int(pr, 0) == 0); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->sig != NULL) { + rs_ctx->sig->state = ecdsa_sig_modn; + } + +modn: +#endif + /* + * Accounting for everything up to the end of the loop + * (step 6, but checking now avoids saving e and t) + */ + ECDSA_BUDGET(MBEDTLS_ECP_OPS_INV + 4); + + /* + * Step 5: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen)); + + /* + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, &t, f_rng_blind, + p_rng_blind)); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, pr, d)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&e, &e, s)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&e, &e, &t)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pk, pk, &t)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pk, pk, &grp->N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(s, pk, &grp->N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(s, s, &e)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(s, s, &grp->N)); + } while (mbedtls_mpi_cmp_int(s, 0) == 0); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->sig != NULL) { + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(r, pr)); + } +#endif + +cleanup: + mbedtls_ecp_point_free(&R); + mbedtls_mpi_free(&k); mbedtls_mpi_free(&e); mbedtls_mpi_free(&t); + + ECDSA_RS_LEAVE(sig); + + return ret; +} + +/* + * Compute ECDSA signature of a hashed message + */ +int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + /* Use the same RNG for both blinding and ephemeral key generation */ + return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, + f_rng, p_rng, f_rng, p_rng, NULL); +} +#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + * + * note: The f_rng_blind parameter must not be NULL. + * + */ +int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_hmac_drbg_context rng_ctx; + mbedtls_hmac_drbg_context *p_rng = &rng_ctx; + unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; + size_t grp_len = (grp->nbits + 7) / 8; + const mbedtls_md_info_t *md_info; + mbedtls_mpi h; + + if ((md_info = mbedtls_md_info_from_type(md_alg)) == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + mbedtls_mpi_init(&h); + mbedtls_hmac_drbg_init(&rng_ctx); + + ECDSA_RS_ENTER(det); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->det != NULL) { + /* redirect to our context */ + p_rng = &rs_ctx->det->rng_ctx; + + /* jump to current step */ + if (rs_ctx->det->state == ecdsa_det_sign) { + goto sign; + } + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(d, data, grp_len)); + MBEDTLS_MPI_CHK(derive_mpi(grp, &h, buf, blen)); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, data + grp_len, grp_len)); + MBEDTLS_MPI_CHK(mbedtls_hmac_drbg_seed_buf(p_rng, md_info, data, 2 * grp_len)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->det != NULL) { + rs_ctx->det->state = ecdsa_det_sign; + } + +sign: +#endif +#if defined(MBEDTLS_ECDSA_SIGN_ALT) + (void) f_rng_blind; + (void) p_rng_blind; + ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, + mbedtls_hmac_drbg_random, p_rng); +#else + ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, + mbedtls_hmac_drbg_random, p_rng, + f_rng_blind, p_rng_blind, rs_ctx); +#endif /* MBEDTLS_ECDSA_SIGN_ALT */ + +cleanup: + mbedtls_hmac_drbg_free(&rng_ctx); + mbedtls_mpi_free(&h); + + ECDSA_RS_LEAVE(det); + + return ret; +} + +/* + * Deterministic signature wrapper + */ +int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, + mbedtls_mpi *s, const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, + size_t), + void *p_rng_blind) +{ + return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg, + f_rng_blind, p_rng_blind, NULL); +} +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) +/* + * Verify ECDSA signature of hashed message (SEC1 4.1.4) + * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) + */ +int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi e, s_inv, u1, u2; + mbedtls_ecp_point R; + mbedtls_mpi *pu1 = &u1, *pu2 = &u2; + + mbedtls_ecp_point_init(&R); + mbedtls_mpi_init(&e); mbedtls_mpi_init(&s_inv); + mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2); + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if (!mbedtls_ecdsa_can_do(grp->id) || grp->N.p == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + ECDSA_RS_ENTER(ver); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ver != NULL) { + /* redirect to our context */ + pu1 = &rs_ctx->ver->u1; + pu2 = &rs_ctx->ver->u2; + + /* jump to current step */ + if (rs_ctx->ver->state == ecdsa_ver_muladd) { + goto muladd; + } + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + /* + * Step 1: make sure r and s are in range 1..n-1 + */ + if (mbedtls_mpi_cmp_int(r, 1) < 0 || mbedtls_mpi_cmp_mpi(r, &grp->N) >= 0 || + mbedtls_mpi_cmp_int(s, 1) < 0 || mbedtls_mpi_cmp_mpi(s, &grp->N) >= 0) { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 3: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK(derive_mpi(grp, &e, buf, blen)); + + /* + * Step 4: u1 = e / s mod n, u2 = r / s mod n + */ + ECDSA_BUDGET(MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2); + + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&s_inv, s, &grp->N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu1, &e, &s_inv)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu1, pu1, &grp->N)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(pu2, r, &s_inv)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(pu2, pu2, &grp->N)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ver != NULL) { + rs_ctx->ver->state = ecdsa_ver_muladd; + } + +muladd: +#endif + /* + * Step 5: R = u1 G + u2 Q + */ + MBEDTLS_MPI_CHK(mbedtls_ecp_muladd_restartable(grp, + &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP)); + + if (mbedtls_ecp_is_zero(&R)) { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 6: convert xR to an integer (no-op) + * Step 7: reduce xR mod n (gives v) + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&R.X, &R.X, &grp->N)); + + /* + * Step 8: check if v (that is, R.X) is equal to r + */ + if (mbedtls_mpi_cmp_mpi(&R.X, r) != 0) { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free(&R); + mbedtls_mpi_free(&e); mbedtls_mpi_free(&s_inv); + mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2); + + ECDSA_RS_LEAVE(ver); + + return ret; +} + +/* + * Verify ECDSA signature of hashed message + */ +int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s) +{ + return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL); +} +#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ + +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, + unsigned char *sig, size_t sig_size, + size_t *slen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 }; + unsigned char *p = buf + sizeof(buf); + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r)); + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); + + if (len > sig_size) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + memcpy(sig, p, len); + *slen = len; + + return 0; +} + +/* + * Compute and write signature + */ +int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi r, s; + if (f_rng == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d, + hash, hlen, md_alg, f_rng, + p_rng, rs_ctx)); +#else + (void) md_alg; + +#if defined(MBEDTLS_ECDSA_SIGN_ALT) + (void) rs_ctx; + + MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ctx->grp, &r, &s, &ctx->d, + hash, hlen, f_rng, p_rng)); +#else + /* Use the same RNG for both blinding and ephemeral key generation */ + MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d, + hash, hlen, f_rng, p_rng, f_rng, + p_rng, rs_ctx)); +#endif /* MBEDTLS_ECDSA_SIGN_ALT */ +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + + MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen)); + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return ret; +} + +/* + * Compute and write signature + */ +int mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return mbedtls_ecdsa_write_signature_restartable( + ctx, md_alg, hash, hlen, sig, sig_size, slen, + f_rng, p_rng, NULL); +} + +/* + * Read and check signature + */ +int mbedtls_ecdsa_read_signature(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen) +{ + return mbedtls_ecdsa_read_signature_restartable( + ctx, hash, hlen, sig, slen, NULL); +} + +/* + * Restartable read and check signature + */ +int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + mbedtls_mpi r, s; + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if (p + len != end) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + goto cleanup; + } + + if ((ret = mbedtls_asn1_get_mpi(&p, end, &r)) != 0 || + (ret = mbedtls_asn1_get_mpi(&p, end, &s)) != 0) { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } +#if defined(MBEDTLS_ECDSA_VERIFY_ALT) + (void) rs_ctx; + + if ((ret = mbedtls_ecdsa_verify(&ctx->grp, hash, hlen, + &ctx->Q, &r, &s)) != 0) { + goto cleanup; + } +#else + if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen, + &ctx->Q, &r, &s, rs_ctx)) != 0) { + goto cleanup; + } +#endif /* MBEDTLS_ECDSA_VERIFY_ALT */ + + /* At this point we know that the buffer starts with a valid signature. + * Return 0 if the buffer just contains the signature, and a specific + * error code if the valid signature is followed by more data. */ + if (p != end) { + ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; + } + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return ret; +} + +#if !defined(MBEDTLS_ECDSA_GENKEY_ALT) +/* + * Generate key pair + */ +int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret = 0; + ret = mbedtls_ecp_group_load(&ctx->grp, gid); + if (ret != 0) { + return ret; + } + + return mbedtls_ecp_gen_keypair(&ctx->grp, &ctx->d, + &ctx->Q, f_rng, p_rng); +} +#endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ + +/* + * Set context from an mbedtls_ecp_keypair + */ +int mbedtls_ecdsa_from_keypair(mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + if ((ret = mbedtls_ecp_group_copy(&ctx->grp, &key->grp)) != 0 || + (ret = mbedtls_mpi_copy(&ctx->d, &key->d)) != 0 || + (ret = mbedtls_ecp_copy(&ctx->Q, &key->Q)) != 0) { + mbedtls_ecdsa_free(ctx); + } + + return ret; +} + +/* + * Initialize context + */ +void mbedtls_ecdsa_init(mbedtls_ecdsa_context *ctx) +{ + mbedtls_ecp_keypair_init(ctx); +} + +/* + * Free context + */ +void mbedtls_ecdsa_free(mbedtls_ecdsa_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_ecp_keypair_free(ctx); +} + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/* + * Initialize a restart context + */ +void mbedtls_ecdsa_restart_init(mbedtls_ecdsa_restart_ctx *ctx) +{ + mbedtls_ecp_restart_init(&ctx->ecp); + + ctx->ver = NULL; + ctx->sig = NULL; +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + ctx->det = NULL; +#endif +} + +/* + * Free the components of a restart context + */ +void mbedtls_ecdsa_restart_free(mbedtls_ecdsa_restart_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_ecp_restart_free(&ctx->ecp); + + ecdsa_restart_ver_free(ctx->ver); + mbedtls_free(ctx->ver); + ctx->ver = NULL; + + ecdsa_restart_sig_free(ctx->sig); + mbedtls_free(ctx->sig); + ctx->sig = NULL; + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + ecdsa_restart_det_free(ctx->det); + mbedtls_free(ctx->det); + ctx->det = NULL; +#endif +} +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#endif /* MBEDTLS_ECDSA_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecp.c b/src/app/findmy/crypto/third-party/mbedtls/library/ecp.c new file mode 100644 index 0000000..dad744c --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecp.c @@ -0,0 +1,3631 @@ +/* + * Elliptic curves over GF(p): generic functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * References: + * + * SEC1 https://www.secg.org/sec1-v2.pdf + * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone + * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf + * RFC 4492 for the related TLS structures and constants + * - https://www.rfc-editor.org/rfc/rfc4492 + * RFC 7748 for the Curve448 and Curve25519 curve definitions + * - https://www.rfc-editor.org/rfc/rfc7748 + * + * [Curve25519] https://cr.yp.to/ecdh/curve25519-20060209.pdf + * + * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + */ + +#include "common.h" + +/** + * \brief Function level alternative implementation. + * + * The MBEDTLS_ECP_INTERNAL_ALT macro enables alternative implementations to + * replace certain functions in this module. The alternative implementations are + * typically hardware accelerators and need to activate the hardware before the + * computation starts and deactivate it after it finishes. The + * mbedtls_internal_ecp_init() and mbedtls_internal_ecp_free() functions serve + * this purpose. + * + * To preserve the correct functionality the following conditions must hold: + * + * - The alternative implementation must be activated by + * mbedtls_internal_ecp_init() before any of the replaceable functions is + * called. + * - mbedtls_internal_ecp_free() must \b only be called when the alternative + * implementation is activated. + * - mbedtls_internal_ecp_init() must \b not be called when the alternative + * implementation is activated. + * - Public functions must not return while the alternative implementation is + * activated. + * - Replaceable functions are guarded by \c MBEDTLS_ECP_XXX_ALT macros and + * before calling them an \code if( mbedtls_internal_ecp_grp_capable( grp ) ) + * \endcode ensures that the alternative implementation supports the current + * group. + */ +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +#endif + +#if defined(MBEDTLS_ECP_LIGHT) + +#include "mbedtls/ecp.h" +#include "mbedtls/threading.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include "bn_mul.h" +#include "ecp_invasive.h" + +#include + +#if !defined(MBEDTLS_ECP_ALT) + +#include "mbedtls/platform.h" + +#include "ecp_internal_alt.h" + +#if defined(MBEDTLS_SELF_TEST) +/* + * Counts of point addition and doubling, and field multiplications. + * Used to test resistance of point multiplication to simple timing attacks. + */ +#if defined(MBEDTLS_ECP_C) +static unsigned long add_count, dbl_count; +#endif /* MBEDTLS_ECP_C */ +static unsigned long mul_count; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) +/* + * Maximum number of "basic operations" to be done in a row. + * + * Default value 0 means that ECC operations will not yield. + * Note that regardless of the value of ecp_max_ops, always at + * least one step is performed before yielding. + * + * Setting ecp_max_ops=1 can be suitable for testing purposes + * as it will interrupt computation at all possible points. + */ +static unsigned ecp_max_ops = 0; + +/* + * Set ecp_max_ops + */ +void mbedtls_ecp_set_max_ops(unsigned max_ops) +{ + ecp_max_ops = max_ops; +} + +/* + * Check if restart is enabled + */ +int mbedtls_ecp_restart_is_enabled(void) +{ + return ecp_max_ops != 0; +} + +/* + * Restart sub-context for ecp_mul_comb() + */ +struct mbedtls_ecp_restart_mul { + mbedtls_ecp_point R; /* current intermediate result */ + size_t i; /* current index in various loops, 0 outside */ + mbedtls_ecp_point *T; /* table for precomputed points */ + unsigned char T_size; /* number of points in table T */ + enum { /* what were we doing last time we returned? */ + ecp_rsm_init = 0, /* nothing so far, dummy initial state */ + ecp_rsm_pre_dbl, /* precompute 2^n multiples */ + ecp_rsm_pre_norm_dbl, /* normalize precomputed 2^n multiples */ + ecp_rsm_pre_add, /* precompute remaining points by adding */ + ecp_rsm_pre_norm_add, /* normalize all precomputed points */ + ecp_rsm_comb_core, /* ecp_mul_comb_core() */ + ecp_rsm_final_norm, /* do the final normalization */ + } state; +}; + +/* + * Init restart_mul sub-context + */ +static void ecp_restart_rsm_init(mbedtls_ecp_restart_mul_ctx *ctx) +{ + mbedtls_ecp_point_init(&ctx->R); + ctx->i = 0; + ctx->T = NULL; + ctx->T_size = 0; + ctx->state = ecp_rsm_init; +} + +/* + * Free the components of a restart_mul sub-context + */ +static void ecp_restart_rsm_free(mbedtls_ecp_restart_mul_ctx *ctx) +{ + unsigned char i; + + if (ctx == NULL) { + return; + } + + mbedtls_ecp_point_free(&ctx->R); + + if (ctx->T != NULL) { + for (i = 0; i < ctx->T_size; i++) { + mbedtls_ecp_point_free(ctx->T + i); + } + mbedtls_free(ctx->T); + } + + ecp_restart_rsm_init(ctx); +} + +/* + * Restart context for ecp_muladd() + */ +struct mbedtls_ecp_restart_muladd { + mbedtls_ecp_point mP; /* mP value */ + mbedtls_ecp_point R; /* R intermediate result */ + enum { /* what should we do next? */ + ecp_rsma_mul1 = 0, /* first multiplication */ + ecp_rsma_mul2, /* second multiplication */ + ecp_rsma_add, /* addition */ + ecp_rsma_norm, /* normalization */ + } state; +}; + +/* + * Init restart_muladd sub-context + */ +static void ecp_restart_ma_init(mbedtls_ecp_restart_muladd_ctx *ctx) +{ + mbedtls_ecp_point_init(&ctx->mP); + mbedtls_ecp_point_init(&ctx->R); + ctx->state = ecp_rsma_mul1; +} + +/* + * Free the components of a restart_muladd sub-context + */ +static void ecp_restart_ma_free(mbedtls_ecp_restart_muladd_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_ecp_point_free(&ctx->mP); + mbedtls_ecp_point_free(&ctx->R); + + ecp_restart_ma_init(ctx); +} + +/* + * Initialize a restart context + */ +void mbedtls_ecp_restart_init(mbedtls_ecp_restart_ctx *ctx) +{ + ctx->ops_done = 0; + ctx->depth = 0; + ctx->rsm = NULL; + ctx->ma = NULL; +} + +/* + * Free the components of a restart context + */ +void mbedtls_ecp_restart_free(mbedtls_ecp_restart_ctx *ctx) +{ + if (ctx == NULL) { + return; + } + + ecp_restart_rsm_free(ctx->rsm); + mbedtls_free(ctx->rsm); + + ecp_restart_ma_free(ctx->ma); + mbedtls_free(ctx->ma); + + mbedtls_ecp_restart_init(ctx); +} + +/* + * Check if we can do the next step + */ +int mbedtls_ecp_check_budget(const mbedtls_ecp_group *grp, + mbedtls_ecp_restart_ctx *rs_ctx, + unsigned ops) +{ + if (rs_ctx != NULL && ecp_max_ops != 0) { + /* scale depending on curve size: the chosen reference is 256-bit, + * and multiplication is quadratic. Round to the closest integer. */ + if (grp->pbits >= 512) { + ops *= 4; + } else if (grp->pbits >= 384) { + ops *= 2; + } + + /* Avoid infinite loops: always allow first step. + * Because of that, however, it's not generally true + * that ops_done <= ecp_max_ops, so the check + * ops_done > ecp_max_ops below is mandatory. */ + if ((rs_ctx->ops_done != 0) && + (rs_ctx->ops_done > ecp_max_ops || + ops > ecp_max_ops - rs_ctx->ops_done)) { + return MBEDTLS_ERR_ECP_IN_PROGRESS; + } + + /* update running count */ + rs_ctx->ops_done += ops; + } + + return 0; +} + +/* Call this when entering a function that needs its own sub-context */ +#define ECP_RS_ENTER(SUB) do { \ + /* reset ops count for this call if top-level */ \ + if (rs_ctx != NULL && rs_ctx->depth++ == 0) \ + rs_ctx->ops_done = 0; \ + \ + /* set up our own sub-context if needed */ \ + if (mbedtls_ecp_restart_is_enabled() && \ + rs_ctx != NULL && rs_ctx->SUB == NULL) \ + { \ + rs_ctx->SUB = mbedtls_calloc(1, sizeof(*rs_ctx->SUB)); \ + if (rs_ctx->SUB == NULL) \ + return MBEDTLS_ERR_ECP_ALLOC_FAILED; \ + \ + ecp_restart_## SUB ##_init(rs_ctx->SUB); \ + } \ +} while (0) + +/* Call this when leaving a function that needs its own sub-context */ +#define ECP_RS_LEAVE(SUB) do { \ + /* clear our sub-context when not in progress (done or error) */ \ + if (rs_ctx != NULL && rs_ctx->SUB != NULL && \ + ret != MBEDTLS_ERR_ECP_IN_PROGRESS) \ + { \ + ecp_restart_## SUB ##_free(rs_ctx->SUB); \ + mbedtls_free(rs_ctx->SUB); \ + rs_ctx->SUB = NULL; \ + } \ + \ + if (rs_ctx != NULL) \ + rs_ctx->depth--; \ +} while (0) + +#else /* MBEDTLS_ECP_RESTARTABLE */ + +#define ECP_RS_ENTER(sub) (void) rs_ctx; +#define ECP_RS_LEAVE(sub) (void) rs_ctx; + +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +#if defined(MBEDTLS_ECP_C) +static void mpi_init_many(mbedtls_mpi *arr, size_t size) +{ + while (size--) { + mbedtls_mpi_init(arr++); + } +} + +static void mpi_free_many(mbedtls_mpi *arr, size_t size) +{ + while (size--) { + mbedtls_mpi_free(arr++); + } +} +#endif /* MBEDTLS_ECP_C */ + +/* + * List of supported curves: + * - internal ID + * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7) + * - size in bits + * - readable name + * + * Curves are listed in order: largest curves first, and for a given size, + * fastest curves first. + * + * Reminder: update profiles in x509_crt.c and ssl_tls.c when adding a new curve! + */ +static const mbedtls_ecp_curve_info ecp_supported_curves[] = +{ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" }, +#endif +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" }, +#endif + { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, +}; + +#define ECP_NB_CURVES sizeof(ecp_supported_curves) / \ + sizeof(ecp_supported_curves[0]) + +static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; + +/* + * List of supported curves and associated info + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list(void) +{ + return ecp_supported_curves; +} + +/* + * List of supported curves, group ID only + */ +const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list(void) +{ + static int init_done = 0; + + if (!init_done) { + size_t i = 0; + const mbedtls_ecp_curve_info *curve_info; + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + ecp_supported_grp_id[i++] = curve_info->grp_id; + } + ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; + + init_done = 1; + } + + return ecp_supported_grp_id; +} + +/* + * Get the curve info for the internal identifier + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id(mbedtls_ecp_group_id grp_id) +{ + const mbedtls_ecp_curve_info *curve_info; + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + if (curve_info->grp_id == grp_id) { + return curve_info; + } + } + + return NULL; +} + +/* + * Get the curve info from the TLS identifier + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id(uint16_t tls_id) +{ + const mbedtls_ecp_curve_info *curve_info; + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + if (curve_info->tls_id == tls_id) { + return curve_info; + } + } + + return NULL; +} + +/* + * Get the curve info from the name + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name(const char *name) +{ + const mbedtls_ecp_curve_info *curve_info; + + if (name == NULL) { + return NULL; + } + + for (curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++) { + if (strcmp(curve_info->name, name) == 0) { + return curve_info; + } + } + + return NULL; +} + +/* + * Get the type of a curve + */ +mbedtls_ecp_curve_type mbedtls_ecp_get_type(const mbedtls_ecp_group *grp) +{ + if (grp->G.X.p == NULL) { + return MBEDTLS_ECP_TYPE_NONE; + } + + if (grp->G.Y.p == NULL) { + return MBEDTLS_ECP_TYPE_MONTGOMERY; + } else { + return MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS; + } +} + +/* + * Initialize (the components of) a point + */ +void mbedtls_ecp_point_init(mbedtls_ecp_point *pt) +{ + mbedtls_mpi_init(&pt->X); + mbedtls_mpi_init(&pt->Y); + mbedtls_mpi_init(&pt->Z); +} + +/* + * Initialize (the components of) a group + */ +void mbedtls_ecp_group_init(mbedtls_ecp_group *grp) +{ + grp->id = MBEDTLS_ECP_DP_NONE; + mbedtls_mpi_init(&grp->P); + mbedtls_mpi_init(&grp->A); + mbedtls_mpi_init(&grp->B); + mbedtls_ecp_point_init(&grp->G); + mbedtls_mpi_init(&grp->N); + grp->pbits = 0; + grp->nbits = 0; + grp->h = 0; + grp->modp = NULL; + grp->t_pre = NULL; + grp->t_post = NULL; + grp->t_data = NULL; + grp->T = NULL; + grp->T_size = 0; +} + +/* + * Initialize (the components of) a key pair + */ +void mbedtls_ecp_keypair_init(mbedtls_ecp_keypair *key) +{ + mbedtls_ecp_group_init(&key->grp); + mbedtls_mpi_init(&key->d); + mbedtls_ecp_point_init(&key->Q); +} + +/* + * Unallocate (the components of) a point + */ +void mbedtls_ecp_point_free(mbedtls_ecp_point *pt) +{ + if (pt == NULL) { + return; + } + + mbedtls_mpi_free(&(pt->X)); + mbedtls_mpi_free(&(pt->Y)); + mbedtls_mpi_free(&(pt->Z)); +} + +/* + * Check that the comb table (grp->T) is static initialized. + */ +static int ecp_group_is_static_comb_table(const mbedtls_ecp_group *grp) +{ +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 + return grp->T != NULL && grp->T_size == 0; +#else + (void) grp; + return 0; +#endif +} + +/* + * Unallocate (the components of) a group + */ +void mbedtls_ecp_group_free(mbedtls_ecp_group *grp) +{ + size_t i; + + if (grp == NULL) { + return; + } + + if (grp->h != 1) { + mbedtls_mpi_free(&grp->A); + mbedtls_mpi_free(&grp->B); + mbedtls_ecp_point_free(&grp->G); + +#if !defined(MBEDTLS_ECP_WITH_MPI_UINT) + mbedtls_mpi_free(&grp->N); + mbedtls_mpi_free(&grp->P); +#endif + } + + if (!ecp_group_is_static_comb_table(grp) && grp->T != NULL) { + for (i = 0; i < grp->T_size; i++) { + mbedtls_ecp_point_free(&grp->T[i]); + } + mbedtls_free(grp->T); + } + + mbedtls_platform_zeroize(grp, sizeof(mbedtls_ecp_group)); +} + +/* + * Unallocate (the components of) a key pair + */ +void mbedtls_ecp_keypair_free(mbedtls_ecp_keypair *key) +{ + if (key == NULL) { + return; + } + + mbedtls_ecp_group_free(&key->grp); + mbedtls_mpi_free(&key->d); + mbedtls_ecp_point_free(&key->Q); +} + +/* + * Copy the contents of a point + */ +int mbedtls_ecp_copy(mbedtls_ecp_point *P, const mbedtls_ecp_point *Q) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->X, &Q->X)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Y, &Q->Y)); + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&P->Z, &Q->Z)); + +cleanup: + return ret; +} + +/* + * Copy the contents of a group object + */ +int mbedtls_ecp_group_copy(mbedtls_ecp_group *dst, const mbedtls_ecp_group *src) +{ + return mbedtls_ecp_group_load(dst, src->id); +} + +/* + * Set point to zero + */ +int mbedtls_ecp_set_zero(mbedtls_ecp_point *pt) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->X, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Y, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 0)); + +cleanup: + return ret; +} + +/* + * Tell if a point is zero + */ +int mbedtls_ecp_is_zero(mbedtls_ecp_point *pt) +{ + return mbedtls_mpi_cmp_int(&pt->Z, 0) == 0; +} + +/* + * Compare two points lazily + */ +int mbedtls_ecp_point_cmp(const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q) +{ + if (mbedtls_mpi_cmp_mpi(&P->X, &Q->X) == 0 && + mbedtls_mpi_cmp_mpi(&P->Y, &Q->Y) == 0 && + mbedtls_mpi_cmp_mpi(&P->Z, &Q->Z) == 0) { + return 0; + } + + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +} + +/* + * Import a non-zero point from ASCII strings + */ +int mbedtls_ecp_point_read_string(mbedtls_ecp_point *P, int radix, + const char *x, const char *y) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->X, radix, x)); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&P->Y, radix, y)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&P->Z, 1)); + +cleanup: + return ret; +} + +/* + * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748) + */ +int mbedtls_ecp_point_write_binary(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen) +{ + int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + size_t plen; + if (format != MBEDTLS_ECP_PF_UNCOMPRESSED && + format != MBEDTLS_ECP_PF_COMPRESSED) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + plen = mbedtls_mpi_size(&grp->P); + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + (void) format; /* Montgomery curves always use the same point format */ + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + *olen = plen; + if (buflen < *olen) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&P->X, buf, plen)); + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + /* + * Common case: P == 0 + */ + if (mbedtls_mpi_cmp_int(&P->Z, 0) == 0) { + if (buflen < 1) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + buf[0] = 0x00; + *olen = 1; + + return 0; + } + + if (format == MBEDTLS_ECP_PF_UNCOMPRESSED) { + *olen = 2 * plen + 1; + + if (buflen < *olen) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + buf[0] = 0x04; + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen)); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->Y, buf + 1 + plen, plen)); + } else if (format == MBEDTLS_ECP_PF_COMPRESSED) { + *olen = plen + 1; + + if (buflen < *olen) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + buf[0] = 0x02 + mbedtls_mpi_get_bit(&P->Y, 0); + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&P->X, buf + 1, plen)); + } + } +#endif + +cleanup: + return ret; +} + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp, + const mbedtls_mpi *X, + mbedtls_mpi *Y, + int parity_bit); +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +/* + * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748) + */ +int mbedtls_ecp_point_read_binary(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char *buf, size_t ilen) +{ + int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + size_t plen; + if (ilen < 1) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + plen = mbedtls_mpi_size(&grp->P); + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + if (plen != ilen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&pt->X, buf, plen)); + mbedtls_mpi_free(&pt->Y); + + if (grp->id == MBEDTLS_ECP_DP_CURVE25519) { + /* Set most significant bit to 0 as prescribed in RFC7748 §5 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&pt->X, plen * 8 - 1, 0)); + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1)); + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + if (buf[0] == 0x00) { + if (ilen == 1) { + return mbedtls_ecp_set_zero(pt); + } else { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + } + + if (ilen < 1 + plen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, buf + 1, plen)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&pt->Z, 1)); + + if (buf[0] == 0x04) { + /* format == MBEDTLS_ECP_PF_UNCOMPRESSED */ + if (ilen != 1 + plen * 2) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + return mbedtls_mpi_read_binary(&pt->Y, buf + 1 + plen, plen); + } else if (buf[0] == 0x02 || buf[0] == 0x03) { + /* format == MBEDTLS_ECP_PF_COMPRESSED */ + if (ilen != 1 + plen) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + return mbedtls_ecp_sw_derive_y(grp, &pt->X, &pt->Y, + (buf[0] & 1)); + } else { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + } +#endif + +cleanup: + return ret; +} + +/* + * Import a point from a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int mbedtls_ecp_tls_read_point(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char **buf, size_t buf_len) +{ + unsigned char data_len; + const unsigned char *buf_start; + /* + * We must have at least two bytes (1 for length, at least one for data) + */ + if (buf_len < 2) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + data_len = *(*buf)++; + if (data_len < 1 || data_len > buf_len - 1) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * Save buffer start for read_binary and update buf + */ + buf_start = *buf; + *buf += data_len; + + return mbedtls_ecp_point_read_binary(grp, pt, buf_start, data_len); +} + +/* + * Export a point as a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int mbedtls_ecp_tls_write_point(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + if (format != MBEDTLS_ECP_PF_UNCOMPRESSED && + format != MBEDTLS_ECP_PF_COMPRESSED) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * buffer length must be at least one, for our length byte + */ + if (blen < 1) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if ((ret = mbedtls_ecp_point_write_binary(grp, pt, format, + olen, buf + 1, blen - 1)) != 0) { + return ret; + } + + /* + * write length to the first byte and update total length + */ + buf[0] = (unsigned char) *olen; + ++*olen; + + return 0; +} + +/* + * Set a group from an ECParameters record (RFC 4492) + */ +int mbedtls_ecp_tls_read_group(mbedtls_ecp_group *grp, + const unsigned char **buf, size_t len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_group_id grp_id; + if ((ret = mbedtls_ecp_tls_read_group_id(&grp_id, buf, len)) != 0) { + return ret; + } + + return mbedtls_ecp_group_load(grp, grp_id); +} + +/* + * Read a group id from an ECParameters record (RFC 4492) and convert it to + * mbedtls_ecp_group_id. + */ +int mbedtls_ecp_tls_read_group_id(mbedtls_ecp_group_id *grp, + const unsigned char **buf, size_t len) +{ + uint16_t tls_id; + const mbedtls_ecp_curve_info *curve_info; + /* + * We expect at least three bytes (see below) + */ + if (len < 3) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * First byte is curve_type; only named_curve is handled + */ + if (*(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * Next two bytes are the namedcurve value + */ + tls_id = MBEDTLS_GET_UINT16_BE(*buf, 0); + *buf += 2; + + if ((curve_info = mbedtls_ecp_curve_info_from_tls_id(tls_id)) == NULL) { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } + + *grp = curve_info->grp_id; + + return 0; +} + +/* + * Write the ECParameters record corresponding to a group (RFC 4492) + */ +int mbedtls_ecp_tls_write_group(const mbedtls_ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen) +{ + const mbedtls_ecp_curve_info *curve_info; + if ((curve_info = mbedtls_ecp_curve_info_from_grp_id(grp->id)) == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * We are going to write 3 bytes (see below) + */ + *olen = 3; + if (blen < *olen) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + /* + * First byte is curve_type, always named_curve + */ + *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; + + /* + * Next two bytes are the namedcurve value + */ + MBEDTLS_PUT_UINT16_BE(curve_info->tls_id, buf, 0); + + return 0; +} + +/* + * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. + * See the documentation of struct mbedtls_ecp_group. + * + * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. + */ +static int ecp_modp(mbedtls_mpi *N, const mbedtls_ecp_group *grp) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (grp->modp == NULL) { + return mbedtls_mpi_mod_mpi(N, N, &grp->P); + } + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + if ((N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) || + mbedtls_mpi_bitlen(N) > 2 * grp->pbits) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + MBEDTLS_MPI_CHK(grp->modp(N)); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + while (N->s < 0 && mbedtls_mpi_cmp_int(N, 0) != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &grp->P)); + } + + while (mbedtls_mpi_cmp_mpi(N, &grp->P) >= 0) { + /* we known P, N and the result are positive */ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(N, N, &grp->P)); + } + +cleanup: + return ret; +} + +/* + * Fast mod-p functions expect their argument to be in the 0..p^2 range. + * + * In order to guarantee that, we need to ensure that operands of + * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will + * bring the result back to this range. + * + * The following macros are shortcuts for doing that. + */ + +/* + * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi + */ +#if defined(MBEDTLS_SELF_TEST) +#define INC_MUL_COUNT mul_count++; +#else +#define INC_MUL_COUNT +#endif + +#define MOD_MUL(N) \ + do \ + { \ + MBEDTLS_MPI_CHK(ecp_modp(&(N), grp)); \ + INC_MUL_COUNT \ + } while (0) + +static inline int mbedtls_mpi_mul_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(X, A, B)); + MOD_MUL(*X); +cleanup: + return ret; +} + +/* + * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi + * N->s < 0 is a very fast test, which fails only if N is 0 + */ +#define MOD_SUB(N) \ + do { \ + while ((N)->s < 0 && mbedtls_mpi_cmp_int((N), 0) != 0) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi((N), (N), &grp->P)); \ + } while (0) + +#if (defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \ + !(defined(MBEDTLS_ECP_NO_FALLBACK) && \ + defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \ + defined(MBEDTLS_ECP_ADD_MIXED_ALT))) || \ + (defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) && \ + !(defined(MBEDTLS_ECP_NO_FALLBACK) && \ + defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT))) +static inline int mbedtls_mpi_sub_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, A, B)); + MOD_SUB(X); +cleanup: + return ret; +} +#endif /* All functions referencing mbedtls_mpi_sub_mod() are alt-implemented without fallback */ + +/* + * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. + * We known P, N and the result are positive, so sub_abs is correct, and + * a bit faster. + */ +#define MOD_ADD(N) \ + while (mbedtls_mpi_cmp_mpi((N), &grp->P) >= 0) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs((N), (N), &grp->P)) + +static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + const mbedtls_mpi *B) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B)); + MOD_ADD(X); +cleanup: + return ret; +} + +static inline int mbedtls_mpi_mul_int_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + mbedtls_mpi_uint c) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(X, A, c)); + MOD_ADD(X); +cleanup: + return ret; +} + +static inline int mbedtls_mpi_sub_int_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + mbedtls_mpi_uint c) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(X, A, c)); + MOD_SUB(X); +cleanup: + return ret; +} + +#define MPI_ECP_SUB_INT(X, A, c) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int_mod(grp, X, A, c)) + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \ + !(defined(MBEDTLS_ECP_NO_FALLBACK) && \ + defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \ + defined(MBEDTLS_ECP_ADD_MIXED_ALT)) +static inline int mbedtls_mpi_shift_l_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + size_t count) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, count)); + MOD_ADD(X); +cleanup: + return ret; +} +#endif \ + /* All functions referencing mbedtls_mpi_shift_l_mod() are alt-implemented without fallback */ + +/* + * Macro wrappers around ECP modular arithmetic + * + * Currently, these wrappers are defined via the bignum module. + */ + +#define MPI_ECP_ADD(X, A, B) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mod(grp, X, A, B)) + +#define MPI_ECP_SUB(X, A, B) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mod(grp, X, A, B)) + +#define MPI_ECP_MUL(X, A, B) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, B)) + +#define MPI_ECP_SQR(X, A) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mod(grp, X, A, A)) + +#define MPI_ECP_MUL_INT(X, A, c) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int_mod(grp, X, A, c)) + +#define MPI_ECP_INV(dst, src) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod((dst), (src), &grp->P)) + +#define MPI_ECP_MOV(X, A) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A)) + +#define MPI_ECP_SHIFT_L(X, count) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l_mod(grp, X, count)) + +#define MPI_ECP_LSET(X, c) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, c)) + +#define MPI_ECP_CMP_INT(X, c) \ + mbedtls_mpi_cmp_int(X, c) + +#define MPI_ECP_CMP(X, Y) \ + mbedtls_mpi_cmp_mpi(X, Y) + +/* Needs f_rng, p_rng to be defined. */ +#define MPI_ECP_RAND(X) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_random((X), 2, &grp->P, f_rng, p_rng)) + +/* Conditional negation + * Needs grp and a temporary MPI tmp to be defined. */ +#define MPI_ECP_COND_NEG(X, cond) \ + do \ + { \ + unsigned char nonzero = mbedtls_mpi_cmp_int((X), 0) != 0; \ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&tmp, &grp->P, (X))); \ + MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), &tmp, \ + nonzero & cond)); \ + } while (0) + +#define MPI_ECP_NEG(X) MPI_ECP_COND_NEG((X), 1) + +#define MPI_ECP_VALID(X) \ + ((X)->p != NULL) + +#define MPI_ECP_COND_ASSIGN(X, Y, cond) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign((X), (Y), (cond))) + +#define MPI_ECP_COND_SWAP(X, Y, cond) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_swap((X), (Y), (cond))) + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + +/* + * Computes the right-hand side of the Short Weierstrass equation + * RHS = X^3 + A X + B + */ +static int ecp_sw_rhs(const mbedtls_ecp_group *grp, + mbedtls_mpi *rhs, + const mbedtls_mpi *X) +{ + int ret; + + /* Compute X^3 + A X + B as X (X^2 + A) + B */ + MPI_ECP_SQR(rhs, X); + + /* Special case for A = -3 */ + if (mbedtls_ecp_group_a_is_minus_3(grp)) { + MPI_ECP_SUB_INT(rhs, rhs, 3); + } else { + MPI_ECP_ADD(rhs, rhs, &grp->A); + } + + MPI_ECP_MUL(rhs, rhs, X); + MPI_ECP_ADD(rhs, rhs, &grp->B); + +cleanup: + return ret; +} + +/* + * Derive Y from X and a parity bit + */ +static int mbedtls_ecp_sw_derive_y(const mbedtls_ecp_group *grp, + const mbedtls_mpi *X, + mbedtls_mpi *Y, + int parity_bit) +{ + /* w = y^2 = x^3 + ax + b + * y = sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) + * + * Note: this method for extracting square root does not validate that w + * was indeed a square so this function will return garbage in Y if X + * does not correspond to a point on the curve. + */ + + /* Check prerequisite p = 3 mod 4 */ + if (mbedtls_mpi_get_bit(&grp->P, 0) != 1 || + mbedtls_mpi_get_bit(&grp->P, 1) != 1) { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } + + int ret; + mbedtls_mpi exp; + mbedtls_mpi_init(&exp); + + /* use Y to store intermediate result, actually w above */ + MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, Y, X)); + + /* w = y^2 */ /* Y contains y^2 intermediate result */ + /* exp = ((p+1)/4) */ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&exp, &grp->P, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&exp, 2)); + /* sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(Y, Y /*y^2*/, &exp, &grp->P, NULL)); + + /* check parity bit match or else invert Y */ + /* This quick inversion implementation is valid because Y != 0 for all + * Short Weierstrass curves supported by mbedtls, as each supported curve + * has an order that is a large prime, so each supported curve does not + * have any point of order 2, and a point with Y == 0 would be of order 2 */ + if (mbedtls_mpi_get_bit(Y, 0) != parity_bit) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(Y, &grp->P, Y)); + } + +cleanup: + + mbedtls_mpi_free(&exp); + return ret; +} +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +/* + * For curves in short Weierstrass form, we do all the internal operations in + * Jacobian coordinates. + * + * For multiplication, we'll use a comb method with countermeasures against + * SPA, hence timing attacks. + */ + +/* + * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) + * Cost: 1N := 1I + 3M + 1S + */ +static int ecp_normalize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt) +{ + if (MPI_ECP_CMP_INT(&pt->Z, 0) == 0) { + return 0; + } + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_normalize_jac(grp, pt); + } +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi T; + mbedtls_mpi_init(&T); + + MPI_ECP_INV(&T, &pt->Z); /* T <- 1 / Z */ + MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y' <- Y*T = Y / Z */ + MPI_ECP_SQR(&T, &T); /* T <- T^2 = 1 / Z^2 */ + MPI_ECP_MUL(&pt->X, &pt->X, &T); /* X <- X * T = X / Z^2 */ + MPI_ECP_MUL(&pt->Y, &pt->Y, &T); /* Y'' <- Y' * T = Y / Z^3 */ + + MPI_ECP_LSET(&pt->Z, 1); + +cleanup: + + mbedtls_mpi_free(&T); + + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */ +} + +/* + * Normalize jacobian coordinates of an array of (pointers to) points, + * using Montgomery's trick to perform only one inversion mod P. + * (See for example Cohen's "A Course in Computational Algebraic Number + * Theory", Algorithm 10.3.4.) + * + * Warning: fails (returning an error) if one of the points is zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * Cost: 1N(t) := 1I + (6t - 3)M + 1S + */ +static int ecp_normalize_jac_many(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *T[], size_t T_size) +{ + if (T_size < 2) { + return ecp_normalize_jac(grp, *T); + } + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_normalize_jac_many(grp, T, T_size); + } +#endif + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + mbedtls_mpi *c, t; + + if ((c = mbedtls_calloc(T_size, sizeof(mbedtls_mpi))) == NULL) { + return MBEDTLS_ERR_ECP_ALLOC_FAILED; + } + + mbedtls_mpi_init(&t); + + mpi_init_many(c, T_size); + /* + * c[i] = Z_0 * ... * Z_i, i = 0,..,n := T_size-1 + */ + MPI_ECP_MOV(&c[0], &T[0]->Z); + for (i = 1; i < T_size; i++) { + MPI_ECP_MUL(&c[i], &c[i-1], &T[i]->Z); + } + + /* + * c[n] = 1 / (Z_0 * ... * Z_n) mod P + */ + MPI_ECP_INV(&c[T_size-1], &c[T_size-1]); + + for (i = T_size - 1;; i--) { + /* At the start of iteration i (note that i decrements), we have + * - c[j] = Z_0 * .... * Z_j for j < i, + * - c[j] = 1 / (Z_0 * .... * Z_j) for j == i, + * + * This is maintained via + * - c[i-1] <- c[i] * Z_i + * + * We also derive 1/Z_i = c[i] * c[i-1] for i>0 and use that + * to do the actual normalization. For i==0, we already have + * c[0] = 1 / Z_0. + */ + + if (i > 0) { + /* Compute 1/Z_i and establish invariant for the next iteration. */ + MPI_ECP_MUL(&t, &c[i], &c[i-1]); + MPI_ECP_MUL(&c[i-1], &c[i], &T[i]->Z); + } else { + MPI_ECP_MOV(&t, &c[0]); + } + + /* Now t holds 1 / Z_i; normalize as in ecp_normalize_jac() */ + MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t); + MPI_ECP_SQR(&t, &t); + MPI_ECP_MUL(&T[i]->X, &T[i]->X, &t); + MPI_ECP_MUL(&T[i]->Y, &T[i]->Y, &t); + + /* + * Post-precessing: reclaim some memory by shrinking coordinates + * - not storing Z (always 1) + * - shrinking other coordinates, but still keeping the same number of + * limbs as P, as otherwise it will too likely be regrown too fast. + */ + MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->X, grp->P.n)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(&T[i]->Y, grp->P.n)); + + MPI_ECP_LSET(&T[i]->Z, 1); + + if (i == 0) { + break; + } + } + +cleanup: + + mbedtls_mpi_free(&t); + mpi_free_many(c, T_size); + mbedtls_free(c); + + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */ +} + +/* + * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. + * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid + */ +static int ecp_safe_invert_jac(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *Q, + unsigned char inv) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi tmp; + mbedtls_mpi_init(&tmp); + + MPI_ECP_COND_NEG(&Q->Y, inv); + +cleanup: + mbedtls_mpi_free(&tmp); + return ret; +} + +/* + * Point doubling R = 2 P, Jacobian coordinates + * + * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . + * + * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR + * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. + * + * Standard optimizations are applied when curve parameter A is one of { 0, -3 }. + * + * Cost: 1D := 3M + 4S (A == 0) + * 4M + 4S (A == -3) + * 3M + 6S + 1a otherwise + */ +static int ecp_double_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, + mbedtls_mpi tmp[4]) +{ +#if defined(MBEDTLS_SELF_TEST) + dbl_count++; +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_double_jac(grp, R, P); + } +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* Special case for A = -3 */ + if (mbedtls_ecp_group_a_is_minus_3(grp)) { + /* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */ + MPI_ECP_SQR(&tmp[1], &P->Z); + MPI_ECP_ADD(&tmp[2], &P->X, &tmp[1]); + MPI_ECP_SUB(&tmp[3], &P->X, &tmp[1]); + MPI_ECP_MUL(&tmp[1], &tmp[2], &tmp[3]); + MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3); + } else { + /* tmp[0] <- M = 3.X^2 + A.Z^4 */ + MPI_ECP_SQR(&tmp[1], &P->X); + MPI_ECP_MUL_INT(&tmp[0], &tmp[1], 3); + + /* Optimize away for "koblitz" curves with A = 0 */ + if (MPI_ECP_CMP_INT(&grp->A, 0) != 0) { + /* M += A.Z^4 */ + MPI_ECP_SQR(&tmp[1], &P->Z); + MPI_ECP_SQR(&tmp[2], &tmp[1]); + MPI_ECP_MUL(&tmp[1], &tmp[2], &grp->A); + MPI_ECP_ADD(&tmp[0], &tmp[0], &tmp[1]); + } + } + + /* tmp[1] <- S = 4.X.Y^2 */ + MPI_ECP_SQR(&tmp[2], &P->Y); + MPI_ECP_SHIFT_L(&tmp[2], 1); + MPI_ECP_MUL(&tmp[1], &P->X, &tmp[2]); + MPI_ECP_SHIFT_L(&tmp[1], 1); + + /* tmp[3] <- U = 8.Y^4 */ + MPI_ECP_SQR(&tmp[3], &tmp[2]); + MPI_ECP_SHIFT_L(&tmp[3], 1); + + /* tmp[2] <- T = M^2 - 2.S */ + MPI_ECP_SQR(&tmp[2], &tmp[0]); + MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]); + MPI_ECP_SUB(&tmp[2], &tmp[2], &tmp[1]); + + /* tmp[1] <- S = M(S - T) - U */ + MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[2]); + MPI_ECP_MUL(&tmp[1], &tmp[1], &tmp[0]); + MPI_ECP_SUB(&tmp[1], &tmp[1], &tmp[3]); + + /* tmp[3] <- U = 2.Y.Z */ + MPI_ECP_MUL(&tmp[3], &P->Y, &P->Z); + MPI_ECP_SHIFT_L(&tmp[3], 1); + + /* Store results */ + MPI_ECP_MOV(&R->X, &tmp[2]); + MPI_ECP_MOV(&R->Y, &tmp[1]); + MPI_ECP_MOV(&R->Z, &tmp[3]); + +cleanup: + + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */ +} + +/* + * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * P,Q,R may alias, but only at the level of EC points: they must be either + * equal as pointers, or disjoint (including the coordinate data buffers). + * Fine-grained aliasing at the level of coordinates is not supported. + * + * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. + * None of these cases can happen as intermediate step in ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base point, the factor + * being less than its order, so none of them is zero; + * - Q is an odd multiple of the base point, P an even multiple, + * due to the choice of precomputed points in the modified comb method. + * So branches for these cases do not leak secret information. + * + * Cost: 1A := 8M + 3S + */ +static int ecp_add_mixed(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, + mbedtls_mpi tmp[4]) +{ +#if defined(MBEDTLS_SELF_TEST) + add_count++; +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_add_mixed(grp, R, P, Q); + } +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* NOTE: Aliasing between input and output is allowed, so one has to make + * sure that at the point X,Y,Z are written, {P,Q}->{X,Y,Z} are no + * longer read from. */ + mbedtls_mpi * const X = &R->X; + mbedtls_mpi * const Y = &R->Y; + mbedtls_mpi * const Z = &R->Z; + + if (!MPI_ECP_VALID(&Q->Z)) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* + * Trivial cases: P == 0 or Q == 0 (case 1) + */ + if (MPI_ECP_CMP_INT(&P->Z, 0) == 0) { + return mbedtls_ecp_copy(R, Q); + } + + if (MPI_ECP_CMP_INT(&Q->Z, 0) == 0) { + return mbedtls_ecp_copy(R, P); + } + + /* + * Make sure Q coordinates are normalized + */ + if (MPI_ECP_CMP_INT(&Q->Z, 1) != 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + MPI_ECP_SQR(&tmp[0], &P->Z); + MPI_ECP_MUL(&tmp[1], &tmp[0], &P->Z); + MPI_ECP_MUL(&tmp[0], &tmp[0], &Q->X); + MPI_ECP_MUL(&tmp[1], &tmp[1], &Q->Y); + MPI_ECP_SUB(&tmp[0], &tmp[0], &P->X); + MPI_ECP_SUB(&tmp[1], &tmp[1], &P->Y); + + /* Special cases (2) and (3) */ + if (MPI_ECP_CMP_INT(&tmp[0], 0) == 0) { + if (MPI_ECP_CMP_INT(&tmp[1], 0) == 0) { + ret = ecp_double_jac(grp, R, P, tmp); + goto cleanup; + } else { + ret = mbedtls_ecp_set_zero(R); + goto cleanup; + } + } + + /* {P,Q}->Z no longer used, so OK to write to Z even if there's aliasing. */ + MPI_ECP_MUL(Z, &P->Z, &tmp[0]); + MPI_ECP_SQR(&tmp[2], &tmp[0]); + MPI_ECP_MUL(&tmp[3], &tmp[2], &tmp[0]); + MPI_ECP_MUL(&tmp[2], &tmp[2], &P->X); + + MPI_ECP_MOV(&tmp[0], &tmp[2]); + MPI_ECP_SHIFT_L(&tmp[0], 1); + + /* {P,Q}->X no longer used, so OK to write to X even if there's aliasing. */ + MPI_ECP_SQR(X, &tmp[1]); + MPI_ECP_SUB(X, X, &tmp[0]); + MPI_ECP_SUB(X, X, &tmp[3]); + MPI_ECP_SUB(&tmp[2], &tmp[2], X); + MPI_ECP_MUL(&tmp[2], &tmp[2], &tmp[1]); + MPI_ECP_MUL(&tmp[3], &tmp[3], &P->Y); + /* {P,Q}->Y no longer used, so OK to write to Y even if there's aliasing. */ + MPI_ECP_SUB(Y, &tmp[2], &tmp[3]); + +cleanup: + + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */ +} + +/* + * Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_jac(). + * + * This countermeasure was first suggested in [2]. + */ +static int ecp_randomize_jac(const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_randomize_jac(grp, pt, f_rng, p_rng); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi l; + + mbedtls_mpi_init(&l); + + /* Generate l such that 1 < l < p */ + MPI_ECP_RAND(&l); + + /* Z' = l * Z */ + MPI_ECP_MUL(&pt->Z, &pt->Z, &l); + + /* Y' = l * Y */ + MPI_ECP_MUL(&pt->Y, &pt->Y, &l); + + /* X' = l^2 * X */ + MPI_ECP_SQR(&l, &l); + MPI_ECP_MUL(&pt->X, &pt->X, &l); + + /* Y'' = l^2 * Y' = l^3 * Y */ + MPI_ECP_MUL(&pt->Y, &pt->Y, &l); + +cleanup: + mbedtls_mpi_free(&l); + + if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + } + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */ +} + +/* + * Check and define parameters used by the comb method (see below for details) + */ +#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 +#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" +#endif + +/* d = ceil( n / w ) */ +#define COMB_MAX_D (MBEDTLS_ECP_MAX_BITS + 1) / 2 + +/* number of precomputed points */ +#define COMB_MAX_PRE (1 << (MBEDTLS_ECP_WINDOW_SIZE - 1)) + +/* + * Compute the representation of m that will be used with our comb method. + * + * The basic comb method is described in GECC 3.44 for example. We use a + * modified version that provides resistance to SPA by avoiding zero + * digits in the representation as in [3]. We modify the method further by + * requiring that all K_i be odd, which has the small cost that our + * representation uses one more K_i, due to carries, but saves on the size of + * the precomputed table. + * + * Summary of the comb method and its modifications: + * + * - The goal is to compute m*P for some w*d-bit integer m. + * + * - The basic comb method splits m into the w-bit integers + * x[0] .. x[d-1] where x[i] consists of the bits in m whose + * index has residue i modulo d, and computes m * P as + * S[x[0]] + 2 * S[x[1]] + .. + 2^(d-1) S[x[d-1]], where + * S[i_{w-1} .. i_0] := i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + i_0 P. + * + * - If it happens that, say, x[i+1]=0 (=> S[x[i+1]]=0), one can replace the sum by + * .. + 2^{i-1} S[x[i-1]] - 2^i S[x[i]] + 2^{i+1} S[x[i]] + 2^{i+2} S[x[i+2]] .., + * thereby successively converting it into a form where all summands + * are nonzero, at the cost of negative summands. This is the basic idea of [3]. + * + * - More generally, even if x[i+1] != 0, we can first transform the sum as + * .. - 2^i S[x[i]] + 2^{i+1} ( S[x[i]] + S[x[i+1]] ) + 2^{i+2} S[x[i+2]] .., + * and then replace S[x[i]] + S[x[i+1]] = S[x[i] ^ x[i+1]] + 2 S[x[i] & x[i+1]]. + * Performing and iterating this procedure for those x[i] that are even + * (keeping track of carry), we can transform the original sum into one of the form + * S[x'[0]] +- 2 S[x'[1]] +- .. +- 2^{d-1} S[x'[d-1]] + 2^d S[x'[d]] + * with all x'[i] odd. It is therefore only necessary to know S at odd indices, + * which is why we are only computing half of it in the first place in + * ecp_precompute_comb and accessing it with index abs(i) / 2 in ecp_select_comb. + * + * - For the sake of compactness, only the seven low-order bits of x[i] + * are used to represent its absolute value (K_i in the paper), and the msb + * of x[i] encodes the sign (s_i in the paper): it is set if and only if + * if s_i == -1; + * + * Calling conventions: + * - x is an array of size d + 1 + * - w is the size, ie number of teeth, of the comb, and must be between + * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) + * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d + * (the result will be incorrect if these assumptions are not satisfied) + */ +static void ecp_comb_recode_core(unsigned char x[], size_t d, + unsigned char w, const mbedtls_mpi *m) +{ + size_t i, j; + unsigned char c, cc, adjust; + + memset(x, 0, d+1); + + /* First get the classical comb values (except for x_d = 0) */ + for (i = 0; i < d; i++) { + for (j = 0; j < w; j++) { + x[i] |= mbedtls_mpi_get_bit(m, i + d * j) << j; + } + } + + /* Now make sure x_1 .. x_d are odd */ + c = 0; + for (i = 1; i <= d; i++) { + /* Add carry and update it */ + cc = x[i] & c; + x[i] = x[i] ^ c; + c = cc; + + /* Adjust if needed, avoiding branches */ + adjust = 1 - (x[i] & 0x01); + c |= x[i] & (x[i-1] * adjust); + x[i] = x[i] ^ (x[i-1] * adjust); + x[i-1] |= adjust << 7; + } +} + +/* + * Precompute points for the adapted comb method + * + * Assumption: T must be able to hold 2^{w - 1} elements. + * + * Operation: If i = i_{w-1} ... i_1 is the binary representation of i, + * sets T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P. + * + * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) + * + * Note: Even comb values (those where P would be omitted from the + * sum defining T[i] above) are not needed in our adaption + * the comb method. See ecp_comb_recode_core(). + * + * This function currently works in four steps: + * (1) [dbl] Computation of intermediate T[i] for 2-power values of i + * (2) [norm_dbl] Normalization of coordinates of these T[i] + * (3) [add] Computation of all T[i] + * (4) [norm_add] Normalization of all T[i] + * + * Step 1 can be interrupted but not the others; together with the final + * coordinate normalization they are the largest steps done at once, depending + * on the window size. Here are operation counts for P-256: + * + * step (2) (3) (4) + * w = 5 142 165 208 + * w = 4 136 77 160 + * w = 3 130 33 136 + * w = 2 124 11 124 + * + * So if ECC operations are blocking for too long even with a low max_ops + * value, it's useful to set MBEDTLS_ECP_WINDOW_SIZE to a lower value in order + * to minimize maximum blocking time. + */ +static int ecp_precompute_comb(const mbedtls_ecp_group *grp, + mbedtls_ecp_point T[], const mbedtls_ecp_point *P, + unsigned char w, size_t d, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char i; + size_t j = 0; + const unsigned char T_size = 1U << (w - 1); + mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1] = { NULL }; + + mbedtls_mpi tmp[4]; + + mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) { + goto dbl; + } + if (rs_ctx->rsm->state == ecp_rsm_pre_norm_dbl) { + goto norm_dbl; + } + if (rs_ctx->rsm->state == ecp_rsm_pre_add) { + goto add; + } + if (rs_ctx->rsm->state == ecp_rsm_pre_norm_add) { + goto norm_add; + } + } +#else + (void) rs_ctx; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + rs_ctx->rsm->state = ecp_rsm_pre_dbl; + + /* initial state for the loop */ + rs_ctx->rsm->i = 0; + } + +dbl: +#endif + /* + * Set T[0] = P and + * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) + */ + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&T[0], P)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) { + j = rs_ctx->rsm->i; + } else +#endif + j = 0; + + for (; j < d * (w - 1); j++) { + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL); + + i = 1U << (j / d); + cur = T + i; + + if (j % d == 0) { + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(cur, T + (i >> 1))); + } + + MBEDTLS_MPI_CHK(ecp_double_jac(grp, cur, cur, tmp)); + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + rs_ctx->rsm->state = ecp_rsm_pre_norm_dbl; + } + +norm_dbl: +#endif + /* + * Normalize current elements in T to allow them to be used in + * ecp_add_mixed() below, which requires one normalized input. + * + * As T has holes, use an auxiliary array of pointers to elements in T. + * + */ + j = 0; + for (i = 1; i < T_size; i <<= 1) { + TT[j++] = T + i; + } + + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2); + + MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + rs_ctx->rsm->state = ecp_rsm_pre_add; + } + +add: +#endif + /* + * Compute the remaining ones using the minimal number of additions + * Be careful to update T[2^l] only after using it! + */ + MBEDTLS_ECP_BUDGET((T_size - 1) * MBEDTLS_ECP_OPS_ADD); + + for (i = 1; i < T_size; i <<= 1) { + j = i; + while (j--) { + MBEDTLS_MPI_CHK(ecp_add_mixed(grp, &T[i + j], &T[j], &T[i], tmp)); + } + } + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + rs_ctx->rsm->state = ecp_rsm_pre_norm_add; + } + +norm_add: +#endif + /* + * Normalize final elements in T. Even though there are no holes now, we + * still need the auxiliary array for homogeneity with the previous + * call. Also, skip T[0] which is already normalised, being a copy of P. + */ + for (j = 0; j + 1 < T_size; j++) { + TT[j] = T + j + 1; + } + + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV + 6 * j - 2); + + MBEDTLS_MPI_CHK(ecp_normalize_jac_many(grp, TT, j)); + + /* Free Z coordinate (=1 after normalization) to save RAM. + * This makes T[i] invalid as mbedtls_ecp_points, but this is OK + * since from this point onwards, they are only accessed indirectly + * via the getter function ecp_select_comb() which does set the + * target's Z coordinate to 1. */ + for (i = 0; i < T_size; i++) { + mbedtls_mpi_free(&T[i].Z); + } + +cleanup: + + mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL && + ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { + if (rs_ctx->rsm->state == ecp_rsm_pre_dbl) { + rs_ctx->rsm->i = j; + } + } +#endif + + return ret; +} + +/* + * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] + * + * See ecp_comb_recode_core() for background + */ +static int ecp_select_comb(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point T[], unsigned char T_size, + unsigned char i) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char ii, j; + + /* Ignore the "sign" bit and scale down */ + ii = (i & 0x7Fu) >> 1; + + /* Read the whole table to thwart cache-based timing attacks */ + for (j = 0; j < T_size; j++) { + MPI_ECP_COND_ASSIGN(&R->X, &T[j].X, j == ii); + MPI_ECP_COND_ASSIGN(&R->Y, &T[j].Y, j == ii); + } + + /* Safely invert result if i is "negative" */ + MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, R, i >> 7)); + + MPI_ECP_LSET(&R->Z, 1); + +cleanup: + return ret; +} + +/* + * Core multiplication algorithm for the (modified) comb method. + * This part is actually common with the basic comb method (GECC 3.44) + * + * Cost: d A + d D + 1 R + */ +static int ecp_mul_comb_core(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point T[], unsigned char T_size, + const unsigned char x[], size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point Txi; + mbedtls_mpi tmp[4]; + size_t i; + + mbedtls_ecp_point_init(&Txi); + mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + +#if !defined(MBEDTLS_ECP_RESTARTABLE) + (void) rs_ctx; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL && + rs_ctx->rsm->state != ecp_rsm_comb_core) { + rs_ctx->rsm->i = 0; + rs_ctx->rsm->state = ecp_rsm_comb_core; + } + + /* new 'if' instead of nested for the sake of the 'else' branch */ + if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->i != 0) { + /* restore current index (R already pointing to rs_ctx->rsm->R) */ + i = rs_ctx->rsm->i; + } else +#endif + { + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MBEDTLS_MPI_CHK(ecp_select_comb(grp, R, T, T_size, x[i])); + if (f_rng != 0) { + MBEDTLS_MPI_CHK(ecp_randomize_jac(grp, R, f_rng, p_rng)); + } + } + + while (i != 0) { + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_DBL + MBEDTLS_ECP_OPS_ADD); + --i; + + MBEDTLS_MPI_CHK(ecp_double_jac(grp, R, R, tmp)); + MBEDTLS_MPI_CHK(ecp_select_comb(grp, &Txi, T, T_size, x[i])); + MBEDTLS_MPI_CHK(ecp_add_mixed(grp, R, R, &Txi, tmp)); + } + +cleanup: + + mbedtls_ecp_point_free(&Txi); + mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL && + ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { + rs_ctx->rsm->i = i; + /* no need to save R, already pointing to rs_ctx->rsm->R */ + } +#endif + + return ret; +} + +/* + * Recode the scalar to get constant-time comb multiplication + * + * As the actual scalar recoding needs an odd scalar as a starting point, + * this wrapper ensures that by replacing m by N - m if necessary, and + * informs the caller that the result of multiplication will be negated. + * + * This works because we only support large prime order for Short Weierstrass + * curves, so N is always odd hence either m or N - m is. + * + * See ecp_comb_recode_core() for background. + */ +static int ecp_comb_recode_scalar(const mbedtls_ecp_group *grp, + const mbedtls_mpi *m, + unsigned char k[COMB_MAX_D + 1], + size_t d, + unsigned char w, + unsigned char *parity_trick) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi M, mm; + + mbedtls_mpi_init(&M); + mbedtls_mpi_init(&mm); + + /* N is always odd (see above), just make extra sure */ + if (mbedtls_mpi_get_bit(&grp->N, 0) != 1) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* do we need the parity trick? */ + *parity_trick = (mbedtls_mpi_get_bit(m, 0) == 0); + + /* execute parity fix in constant time */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&M, m)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&mm, &grp->N, m)); + MBEDTLS_MPI_CHK(mbedtls_mpi_safe_cond_assign(&M, &mm, *parity_trick)); + + /* actual scalar recoding */ + ecp_comb_recode_core(k, d, w, &M); + +cleanup: + mbedtls_mpi_free(&mm); + mbedtls_mpi_free(&M); + + return ret; +} + +/* + * Perform comb multiplication (for short Weierstrass curves) + * once the auxiliary table has been pre-computed. + * + * Scalar recoding may use a parity trick that makes us compute -m * P, + * if that is the case we'll need to recover m * P at the end. + */ +static int ecp_mul_comb_after_precomp(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *T, + unsigned char T_size, + unsigned char w, + size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char parity_trick; + unsigned char k[COMB_MAX_D + 1]; + mbedtls_ecp_point *RR = R; + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + RR = &rs_ctx->rsm->R; + + if (rs_ctx->rsm->state == ecp_rsm_final_norm) { + goto final_norm; + } + } +#endif + + MBEDTLS_MPI_CHK(ecp_comb_recode_scalar(grp, m, k, d, w, + &parity_trick)); + MBEDTLS_MPI_CHK(ecp_mul_comb_core(grp, RR, T, T_size, k, d, + f_rng, p_rng, rs_ctx)); + MBEDTLS_MPI_CHK(ecp_safe_invert_jac(grp, RR, parity_trick)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + rs_ctx->rsm->state = ecp_rsm_final_norm; + } + +final_norm: + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV); +#endif + /* + * Knowledge of the jacobian coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + if (f_rng != 0) { + MBEDTLS_MPI_CHK(ecp_randomize_jac(grp, RR, f_rng, p_rng)); + } + + MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, RR)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL) { + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, RR)); + } +#endif + +cleanup: + return ret; +} + +/* + * Pick window size based on curve size and whether we optimize for base point + */ +static unsigned char ecp_pick_window_size(const mbedtls_ecp_group *grp, + unsigned char p_eq_g) +{ + unsigned char w; + + /* + * Minimize the number of multiplications, that is minimize + * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) + * (see costs of the various parts, with 1S = 1M) + */ + w = grp->nbits >= 384 ? 5 : 4; + + /* + * If P == G, pre-compute a bit more, since this may be re-used later. + * Just adding one avoids upping the cost of the first mul too much, + * and the memory cost too. + */ + if (p_eq_g) { + w++; + } + + /* + * If static comb table may not be used (!p_eq_g) or static comb table does + * not exists, make sure w is within bounds. + * (The last test is useful only for very small curves in the test suite.) + * + * The user reduces MBEDTLS_ECP_WINDOW_SIZE does not changes the size of + * static comb table, because the size of static comb table is fixed when + * it is generated. + */ +#if (MBEDTLS_ECP_WINDOW_SIZE < 6) + if ((!p_eq_g || !ecp_group_is_static_comb_table(grp)) && w > MBEDTLS_ECP_WINDOW_SIZE) { + w = MBEDTLS_ECP_WINDOW_SIZE; + } +#endif + if (w >= grp->nbits) { + w = 2; + } + + return w; +} + +/* + * Multiplication using the comb method - for curves in short Weierstrass form + * + * This function is mainly responsible for administrative work: + * - managing the restart context if enabled + * - managing the table of precomputed points (passed between the below two + * functions): allocation, computation, ownership transfer, freeing. + * + * It delegates the actual arithmetic work to: + * ecp_precompute_comb() and ecp_mul_comb_with_precomp() + * + * See comments on ecp_comb_recode_core() regarding the computation strategy. + */ +static int ecp_mul_comb(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char w, p_eq_g, i; + size_t d; + unsigned char T_size = 0, T_ok = 0; + mbedtls_ecp_point *T = NULL; + + ECP_RS_ENTER(rsm); + + /* Is P the base point ? */ +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = (MPI_ECP_CMP(&P->Y, &grp->G.Y) == 0 && + MPI_ECP_CMP(&P->X, &grp->G.X) == 0); +#else + p_eq_g = 0; +#endif + + /* Pick window size and deduce related sizes */ + w = ecp_pick_window_size(grp, p_eq_g); + T_size = 1U << (w - 1); + d = (grp->nbits + w - 1) / w; + + /* Pre-computed table: do we have it already for the base point? */ + if (p_eq_g && grp->T != NULL) { + /* second pointer to the same table, will be deleted on exit */ + T = grp->T; + T_ok = 1; + } else +#if defined(MBEDTLS_ECP_RESTARTABLE) + /* Pre-computed table: do we have one in progress? complete? */ + if (rs_ctx != NULL && rs_ctx->rsm != NULL && rs_ctx->rsm->T != NULL) { + /* transfer ownership of T from rsm to local function */ + T = rs_ctx->rsm->T; + rs_ctx->rsm->T = NULL; + rs_ctx->rsm->T_size = 0; + + /* This effectively jumps to the call to mul_comb_after_precomp() */ + T_ok = rs_ctx->rsm->state >= ecp_rsm_comb_core; + } else +#endif + /* Allocate table if we didn't have any */ + { + T = mbedtls_calloc(T_size, sizeof(mbedtls_ecp_point)); + if (T == NULL) { + ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; + goto cleanup; + } + + for (i = 0; i < T_size; i++) { + mbedtls_ecp_point_init(&T[i]); + } + + T_ok = 0; + } + + /* Compute table (or finish computing it) if not done already */ + if (!T_ok) { + MBEDTLS_MPI_CHK(ecp_precompute_comb(grp, T, P, w, d, rs_ctx)); + + if (p_eq_g) { + /* almost transfer ownership of T to the group, but keep a copy of + * the pointer to use for calling the next function more easily */ + grp->T = T; + grp->T_size = T_size; + } + } + + /* Actual comb multiplication using precomputed points */ + MBEDTLS_MPI_CHK(ecp_mul_comb_after_precomp(grp, R, m, + T, T_size, w, d, + f_rng, p_rng, rs_ctx)); + +cleanup: + + /* does T belong to the group? */ + if (T == grp->T) { + T = NULL; + } + + /* does T belong to the restart context? */ +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->rsm != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS && T != NULL) { + /* transfer ownership of T from local function to rsm */ + rs_ctx->rsm->T_size = T_size; + rs_ctx->rsm->T = T; + T = NULL; + } +#endif + + /* did T belong to us? then let's destroy it! */ + if (T != NULL) { + for (i = 0; i < T_size; i++) { + mbedtls_ecp_point_free(&T[i]); + } + mbedtls_free(T); + } + + /* prevent caller from using invalid value */ + int should_free_R = (ret != 0); +#if defined(MBEDTLS_ECP_RESTARTABLE) + /* don't free R while in progress in case R == P */ + if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { + should_free_R = 0; + } +#endif + if (should_free_R) { + mbedtls_ecp_point_free(R); + } + + ECP_RS_LEAVE(rsm); + + return ret; +} + +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) +/* + * For Montgomery curves, we do all the internal arithmetic in projective + * coordinates. Import/export of points uses only the x coordinates, which is + * internally represented as X / Z. + * + * For scalar multiplication, we'll use a Montgomery ladder. + */ + +/* + * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 + * Cost: 1M + 1I + */ +static int ecp_normalize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P) +{ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_normalize_mxz(grp, P); + } +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MPI_ECP_INV(&P->Z, &P->Z); + MPI_ECP_MUL(&P->X, &P->X, &P->Z); + MPI_ECP_LSET(&P->Z, 1); + +cleanup: + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */ +} + +/* + * Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_mxz(). + * + * This countermeasure was first suggested in [2]. + * Cost: 2M + */ +static int ecp_randomize_mxz(const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_randomize_mxz(grp, P, f_rng, p_rng); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi l; + mbedtls_mpi_init(&l); + + /* Generate l such that 1 < l < p */ + MPI_ECP_RAND(&l); + + MPI_ECP_MUL(&P->X, &P->X, &l); + MPI_ECP_MUL(&P->Z, &P->Z, &l); + +cleanup: + mbedtls_mpi_free(&l); + + if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + } + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */ +} + +/* + * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), + * for Montgomery curves in x/z coordinates. + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 + * with + * d = X1 + * P = (X2, Z2) + * Q = (X3, Z3) + * R = (X4, Z4) + * S = (X5, Z5) + * and eliminating temporary variables tO, ..., t4. + * + * Cost: 5M + 4S + */ +static int ecp_double_add_mxz(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, mbedtls_ecp_point *S, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, + const mbedtls_mpi *d, + mbedtls_mpi T[4]) +{ +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + if (mbedtls_internal_ecp_grp_capable(grp)) { + return mbedtls_internal_ecp_double_add_mxz(grp, R, S, P, Q, d); + } +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ + +#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MPI_ECP_ADD(&T[0], &P->X, &P->Z); /* Pp := PX + PZ */ + MPI_ECP_SUB(&T[1], &P->X, &P->Z); /* Pm := PX - PZ */ + MPI_ECP_ADD(&T[2], &Q->X, &Q->Z); /* Qp := QX + XZ */ + MPI_ECP_SUB(&T[3], &Q->X, &Q->Z); /* Qm := QX - QZ */ + MPI_ECP_MUL(&T[3], &T[3], &T[0]); /* Qm * Pp */ + MPI_ECP_MUL(&T[2], &T[2], &T[1]); /* Qp * Pm */ + MPI_ECP_SQR(&T[0], &T[0]); /* Pp^2 */ + MPI_ECP_SQR(&T[1], &T[1]); /* Pm^2 */ + MPI_ECP_MUL(&R->X, &T[0], &T[1]); /* Pp^2 * Pm^2 */ + MPI_ECP_SUB(&T[0], &T[0], &T[1]); /* Pp^2 - Pm^2 */ + MPI_ECP_MUL(&R->Z, &grp->A, &T[0]); /* A * (Pp^2 - Pm^2) */ + MPI_ECP_ADD(&R->Z, &T[1], &R->Z); /* [ A * (Pp^2-Pm^2) ] + Pm^2 */ + MPI_ECP_ADD(&S->X, &T[3], &T[2]); /* Qm*Pp + Qp*Pm */ + MPI_ECP_SQR(&S->X, &S->X); /* (Qm*Pp + Qp*Pm)^2 */ + MPI_ECP_SUB(&S->Z, &T[3], &T[2]); /* Qm*Pp - Qp*Pm */ + MPI_ECP_SQR(&S->Z, &S->Z); /* (Qm*Pp - Qp*Pm)^2 */ + MPI_ECP_MUL(&S->Z, d, &S->Z); /* d * ( Qm*Pp - Qp*Pm )^2 */ + MPI_ECP_MUL(&R->Z, &T[0], &R->Z); /* [A*(Pp^2-Pm^2)+Pm^2]*(Pp^2-Pm^2) */ + +cleanup: + + return ret; +#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */ +} + +/* + * Multiplication with Montgomery ladder in x/z coordinates, + * for curves in Montgomery form + */ +static int ecp_mul_mxz(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + unsigned char b; + mbedtls_ecp_point RP; + mbedtls_mpi PX; + mbedtls_mpi tmp[4]; + mbedtls_ecp_point_init(&RP); mbedtls_mpi_init(&PX); + + mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + + if (f_rng == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* Save PX and read from P before writing to R, in case P == R */ + MPI_ECP_MOV(&PX, &P->X); + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(&RP, P)); + + /* Set R to zero in modified x/z coordinates */ + MPI_ECP_LSET(&R->X, 1); + MPI_ECP_LSET(&R->Z, 0); + mbedtls_mpi_free(&R->Y); + + /* RP.X might be slightly larger than P, so reduce it */ + MOD_ADD(&RP.X); + + /* Randomize coordinates of the starting point */ + MBEDTLS_MPI_CHK(ecp_randomize_mxz(grp, &RP, f_rng, p_rng)); + + /* Loop invariant: R = result so far, RP = R + P */ + i = grp->nbits + 1; /* one past the (zero-based) required msb for private keys */ + while (i-- > 0) { + b = mbedtls_mpi_get_bit(m, i); + /* + * if (b) R = 2R + P else R = 2R, + * which is: + * if (b) double_add( RP, R, RP, R ) + * else double_add( R, RP, R, RP ) + * but using safe conditional swaps to avoid leaks + */ + MPI_ECP_COND_SWAP(&R->X, &RP.X, b); + MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b); + MBEDTLS_MPI_CHK(ecp_double_add_mxz(grp, R, &RP, R, &RP, &PX, tmp)); + MPI_ECP_COND_SWAP(&R->X, &RP.X, b); + MPI_ECP_COND_SWAP(&R->Z, &RP.Z, b); + } + + /* + * Knowledge of the projective coordinates may leak the last few bits of the + * scalar [1], and since our MPI implementation isn't constant-flow, + * inversion (used for coordinate normalization) may leak the full value + * of its input via side-channels [2]. + * + * [1] https://eprint.iacr.org/2003/191 + * [2] https://eprint.iacr.org/2020/055 + * + * Avoid the leak by randomizing coordinates before we normalize them. + */ + MBEDTLS_MPI_CHK(ecp_randomize_mxz(grp, R, f_rng, p_rng)); + MBEDTLS_MPI_CHK(ecp_normalize_mxz(grp, R)); + +cleanup: + mbedtls_ecp_point_free(&RP); mbedtls_mpi_free(&PX); + + mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + return ret; +} + +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +/* + * Restartable multiplication R = m * P + * + * This internal function can be called without an RNG in case where we know + * the inputs are not sensitive. + */ +static int ecp_mul_restartable_internal(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + +#if defined(MBEDTLS_ECP_RESTARTABLE) + /* reset ops count for this call if top-level */ + if (rs_ctx != NULL && rs_ctx->depth++ == 0) { + rs_ctx->ops_done = 0; + } +#else + (void) rs_ctx; +#endif + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) { + MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp)); + } +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + + int restarting = 0; +#if defined(MBEDTLS_ECP_RESTARTABLE) + restarting = (rs_ctx != NULL && rs_ctx->rsm != NULL); +#endif + /* skip argument check when restarting */ + if (!restarting) { + /* check_privkey is free */ + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_CHK); + + /* Common sanity checks */ + MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(grp, m)); + MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); + } + + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + MBEDTLS_MPI_CHK(ecp_mul_mxz(grp, R, m, P, f_rng, p_rng)); + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + MBEDTLS_MPI_CHK(ecp_mul_comb(grp, R, m, P, f_rng, p_rng, rs_ctx)); + } +#endif + +cleanup: + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if (is_grp_capable) { + mbedtls_internal_ecp_free(grp); + } +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL) { + rs_ctx->depth--; + } +#endif + + return ret; +} + +/* + * Restartable multiplication R = m * P + */ +int mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + if (f_rng == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + return ecp_mul_restartable_internal(grp, R, m, P, f_rng, p_rng, rs_ctx); +} + +/* + * Multiplication R = m * P + */ +int mbedtls_ecp_mul(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + return mbedtls_ecp_mul_restartable(grp, R, m, P, f_rng, p_rng, NULL); +} +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +/* + * Check that an affine point is valid as a public key, + * short weierstrass curves (SEC1 3.2.3.1) + */ +static int ecp_check_pubkey_sw(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi YY, RHS; + + /* pt coordinates must be normalized for our checks */ + if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0 || + mbedtls_mpi_cmp_int(&pt->Y, 0) < 0 || + mbedtls_mpi_cmp_mpi(&pt->X, &grp->P) >= 0 || + mbedtls_mpi_cmp_mpi(&pt->Y, &grp->P) >= 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + mbedtls_mpi_init(&YY); mbedtls_mpi_init(&RHS); + + /* + * YY = Y^2 + * RHS = X^3 + A X + B + */ + MPI_ECP_SQR(&YY, &pt->Y); + MBEDTLS_MPI_CHK(ecp_sw_rhs(grp, &RHS, &pt->X)); + + if (MPI_ECP_CMP(&YY, &RHS) != 0) { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + } + +cleanup: + + mbedtls_mpi_free(&YY); mbedtls_mpi_free(&RHS); + + return ret; +} +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +#if defined(MBEDTLS_ECP_C) +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +/* + * R = m * P with shortcuts for m == 0, m == 1 and m == -1 + * NOT constant-time - ONLY for short Weierstrass! + */ +static int mbedtls_ecp_mul_shortcuts(mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi tmp; + mbedtls_mpi_init(&tmp); + + if (mbedtls_mpi_cmp_int(m, 0) == 0) { + MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); + MBEDTLS_MPI_CHK(mbedtls_ecp_set_zero(R)); + } else if (mbedtls_mpi_cmp_int(m, 1) == 0) { + MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P)); + } else if (mbedtls_mpi_cmp_int(m, -1) == 0) { + MBEDTLS_MPI_CHK(mbedtls_ecp_check_pubkey(grp, P)); + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P)); + MPI_ECP_NEG(&R->Y); + } else { + MBEDTLS_MPI_CHK(ecp_mul_restartable_internal(grp, R, m, P, + NULL, NULL, rs_ctx)); + } + +cleanup: + mbedtls_mpi_free(&tmp); + + return ret; +} + +/* + * Restartable linear combination + * NOT constant-time + */ +int mbedtls_ecp_muladd_restartable( + mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q, + mbedtls_ecp_restart_ctx *rs_ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point mP; + mbedtls_ecp_point *pmP = &mP; + mbedtls_ecp_point *pR = R; + mbedtls_mpi tmp[4]; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + if (mbedtls_ecp_get_type(grp) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } + + mbedtls_ecp_point_init(&mP); + mpi_init_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + + ECP_RS_ENTER(ma); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ma != NULL) { + /* redirect intermediate results to restart context */ + pmP = &rs_ctx->ma->mP; + pR = &rs_ctx->ma->R; + + /* jump to next operation */ + if (rs_ctx->ma->state == ecp_rsma_mul2) { + goto mul2; + } + if (rs_ctx->ma->state == ecp_rsma_add) { + goto add; + } + if (rs_ctx->ma->state == ecp_rsma_norm) { + goto norm; + } + } +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pmP, m, P, rs_ctx)); +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ma != NULL) { + rs_ctx->ma->state = ecp_rsma_mul2; + } + +mul2: +#endif + MBEDTLS_MPI_CHK(mbedtls_ecp_mul_shortcuts(grp, pR, n, Q, rs_ctx)); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ((is_grp_capable = mbedtls_internal_ecp_grp_capable(grp))) { + MBEDTLS_MPI_CHK(mbedtls_internal_ecp_init(grp)); + } +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ma != NULL) { + rs_ctx->ma->state = ecp_rsma_add; + } + +add: +#endif + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_ADD); + MBEDTLS_MPI_CHK(ecp_add_mixed(grp, pR, pmP, pR, tmp)); +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ma != NULL) { + rs_ctx->ma->state = ecp_rsma_norm; + } + +norm: +#endif + MBEDTLS_ECP_BUDGET(MBEDTLS_ECP_OPS_INV); + MBEDTLS_MPI_CHK(ecp_normalize_jac(grp, pR)); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + if (rs_ctx != NULL && rs_ctx->ma != NULL) { + MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, pR)); + } +#endif + +cleanup: + + mpi_free_many(tmp, sizeof(tmp) / sizeof(mbedtls_mpi)); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if (is_grp_capable) { + mbedtls_internal_ecp_free(grp); + } +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + + mbedtls_ecp_point_free(&mP); + + ECP_RS_LEAVE(ma); + + return ret; +} + +/* + * Linear combination + * NOT constant-time + */ +int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q) +{ + return mbedtls_ecp_muladd_restartable(grp, R, m, P, n, Q, NULL); +} +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } +#define ECP_MPI_INIT_ARRAY(x) \ + ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) +/* + * Constants for the two points other than 0, 1, -1 (mod p) in + * https://cr.yp.to/ecdh.html#validate + * See ecp_check_pubkey_x25519(). + */ +static const mbedtls_mpi_uint x25519_bad_point_1[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a), + MBEDTLS_BYTES_TO_T_UINT_8(0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00), +}; +static const mbedtls_mpi_uint x25519_bad_point_2[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57), +}; +static const mbedtls_mpi ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY( + x25519_bad_point_1); +static const mbedtls_mpi ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY( + x25519_bad_point_2); +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +/* + * Check that the input point is not one of the low-order points. + * This is recommended by the "May the Fourth" paper: + * https://eprint.iacr.org/2017/806.pdf + * Those points are never sent by an honest peer. + */ +static int ecp_check_bad_points_mx(const mbedtls_mpi *X, const mbedtls_mpi *P, + const mbedtls_ecp_group_id grp_id) +{ + int ret; + mbedtls_mpi XmP; + + mbedtls_mpi_init(&XmP); + + /* Reduce X mod P so that we only need to check values less than P. + * We know X < 2^256 so we can proceed by subtraction. */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&XmP, X)); + while (mbedtls_mpi_cmp_mpi(&XmP, P) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&XmP, &XmP, P)); + } + + /* Check against the known bad values that are less than P. For Curve448 + * these are 0, 1 and -1. For Curve25519 we check the values less than P + * from the following list: https://cr.yp.to/ecdh.html#validate */ + if (mbedtls_mpi_cmp_int(&XmP, 1) <= 0) { /* takes care of 0 and 1 */ + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + if (grp_id == MBEDTLS_ECP_DP_CURVE25519) { + if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_1) == 0) { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + + if (mbedtls_mpi_cmp_mpi(&XmP, &ecp_x25519_bad_point_2) == 0) { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + } +#else + (void) grp_id; +#endif + + /* Final check: check if XmP + 1 is P (final because it changes XmP!) */ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&XmP, &XmP, 1)); + if (mbedtls_mpi_cmp_mpi(&XmP, P) == 0) { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + + ret = 0; + +cleanup: + mbedtls_mpi_free(&XmP); + + return ret; +} + +/* + * Check validity of a public key for Montgomery curves with x-only schemes + */ +static int ecp_check_pubkey_mx(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt) +{ + /* [Curve25519 p. 5] Just check X is the correct number of bytes */ + /* Allow any public value, if it's too big then we'll just reduce it mod p + * (RFC 7748 sec. 5 para. 3). */ + if (mbedtls_mpi_size(&pt->X) > (grp->nbits + 7) / 8) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + /* Implicit in all standards (as they don't consider negative numbers): + * X must be non-negative. This is normally ensured by the way it's + * encoded for transmission, but let's be extra sure. */ + if (mbedtls_mpi_cmp_int(&pt->X, 0) < 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + return ecp_check_bad_points_mx(&pt->X, &grp->P, grp->id); +} +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +/* + * Check that a point is valid as a public key + */ +int mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt) +{ + /* Must use affine coordinates */ + if (mbedtls_mpi_cmp_int(&pt->Z, 1) != 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + return ecp_check_pubkey_mx(grp, pt); + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + return ecp_check_pubkey_sw(grp, pt); + } +#endif + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +} + +/* + * Check that an mbedtls_mpi is valid as a private key + */ +int mbedtls_ecp_check_privkey(const mbedtls_ecp_group *grp, + const mbedtls_mpi *d) +{ +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + /* see RFC 7748 sec. 5 para. 5 */ + if (mbedtls_mpi_get_bit(d, 0) != 0 || + mbedtls_mpi_get_bit(d, 1) != 0 || + mbedtls_mpi_bitlen(d) - 1 != grp->nbits) { /* mbedtls_mpi_bitlen is one-based! */ + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + /* see [Curve25519] page 5 */ + if (grp->nbits == 254 && mbedtls_mpi_get_bit(d, 2) != 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + return 0; + } +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + /* see SEC1 3.2 */ + if (mbedtls_mpi_cmp_int(d, 1) < 0 || + mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } else { + return 0; + } + } +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +} + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_gen_privkey_mx(size_t high_bit, + mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + size_t n_random_bytes = high_bit / 8 + 1; + + /* [Curve25519] page 5 */ + /* Generate a (high_bit+1)-bit random number by generating just enough + * random bytes, then shifting out extra bits from the top (necessary + * when (high_bit+1) is not a multiple of 8). */ + MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(d, n_random_bytes, + f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(d, 8 * n_random_bytes - high_bit - 1)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, high_bit, 1)); + + /* Make sure the last two bits are unset for Curve448, three bits for + Curve25519 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 0, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 1, 0)); + if (high_bit == 254) { + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(d, 2, 0)); + } + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) +static int mbedtls_ecp_gen_privkey_sw( + const mbedtls_mpi *N, mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret = mbedtls_mpi_random(d, 1, N, f_rng, p_rng); + switch (ret) { + case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: + return MBEDTLS_ERR_ECP_RANDOM_FAILED; + default: + return ret; + } +} +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +/* + * Generate a private key + */ +int mbedtls_ecp_gen_privkey(const mbedtls_ecp_group *grp, + mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + return mbedtls_ecp_gen_privkey_mx(grp->nbits, d, f_rng, p_rng); + } +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + return mbedtls_ecp_gen_privkey_sw(&grp->N, d, f_rng, p_rng); + } +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +} + +#if defined(MBEDTLS_ECP_C) +/* + * Generate a keypair with configurable base point + */ +int mbedtls_ecp_gen_keypair_base(mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + MBEDTLS_MPI_CHK(mbedtls_ecp_gen_privkey(grp, d, f_rng, p_rng)); + MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, Q, d, G, f_rng, p_rng)); + +cleanup: + return ret; +} + +/* + * Generate key pair, wrapper for conventional base point + */ +int mbedtls_ecp_gen_keypair(mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return mbedtls_ecp_gen_keypair_base(grp, &grp->G, d, Q, f_rng, p_rng); +} + +/* + * Generate a keypair, prettier wrapper + */ +int mbedtls_ecp_gen_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { + return ret; + } + + return mbedtls_ecp_gen_keypair(&key->grp, &key->d, &key->Q, f_rng, p_rng); +} +#endif /* MBEDTLS_ECP_C */ + +#define ECP_CURVE25519_KEY_SIZE 32 +#define ECP_CURVE448_KEY_SIZE 56 +/* + * Read a private key. + */ +int mbedtls_ecp_read_key(mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + const unsigned char *buf, size_t buflen) +{ + int ret = 0; + + if ((ret = mbedtls_ecp_group_load(&key->grp, grp_id)) != 0) { + return ret; + } + + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + /* + * Mask the key as mandated by RFC7748 for Curve25519 and Curve448. + */ + if (grp_id == MBEDTLS_ECP_DP_CURVE25519) { + if (buflen != ECP_CURVE25519_KEY_SIZE) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen)); + + /* Set the three least significant bits to 0 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 2, 0)); + + /* Set the most significant bit to 0 */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit(&key->d, + ECP_CURVE25519_KEY_SIZE * 8 - 1, 0) + ); + + /* Set the second most significant bit to 1 */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit(&key->d, + ECP_CURVE25519_KEY_SIZE * 8 - 2, 1) + ); + } else if (grp_id == MBEDTLS_ECP_DP_CURVE448) { + if (buflen != ECP_CURVE448_KEY_SIZE) { + return MBEDTLS_ERR_ECP_INVALID_KEY; + } + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary_le(&key->d, buf, buflen)); + + /* Set the two least significant bits to 0 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 0, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&key->d, 1, 0)); + + /* Set the most significant bit to 1 */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit(&key->d, + ECP_CURVE448_KEY_SIZE * 8 - 1, 1) + ); + } + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&key->d, buf, buflen)); + } +#endif + MBEDTLS_MPI_CHK(mbedtls_ecp_check_privkey(&key->grp, &key->d)); + +cleanup: + + if (ret != 0) { + mbedtls_mpi_free(&key->d); + } + + return ret; +} + +/* + * Write a private key. + */ +int mbedtls_ecp_write_key(mbedtls_ecp_keypair *key, + unsigned char *buf, size_t buflen) +{ + int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { + if (key->grp.id == MBEDTLS_ECP_DP_CURVE25519) { + if (buflen < ECP_CURVE25519_KEY_SIZE) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + } else if (key->grp.id == MBEDTLS_ECP_DP_CURVE448) { + if (buflen < ECP_CURVE448_KEY_SIZE) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + } + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&key->d, buf, buflen)); + } +#endif +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + if (mbedtls_ecp_get_type(&key->grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&key->d, buf, buflen)); + } + +#endif +cleanup: + + return ret; +} + +#if defined(MBEDTLS_ECP_C) +/* + * Check a public-private key pair + */ +int mbedtls_ecp_check_pub_priv( + const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_point Q; + mbedtls_ecp_group grp; + if (pub->grp.id == MBEDTLS_ECP_DP_NONE || + pub->grp.id != prv->grp.id || + mbedtls_mpi_cmp_mpi(&pub->Q.X, &prv->Q.X) || + mbedtls_mpi_cmp_mpi(&pub->Q.Y, &prv->Q.Y) || + mbedtls_mpi_cmp_mpi(&pub->Q.Z, &prv->Q.Z)) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + mbedtls_ecp_point_init(&Q); + mbedtls_ecp_group_init(&grp); + + /* mbedtls_ecp_mul() needs a non-const group... */ + mbedtls_ecp_group_copy(&grp, &prv->grp); + + /* Also checks d is valid */ + MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &Q, &prv->d, &prv->grp.G, f_rng, p_rng)); + + if (mbedtls_mpi_cmp_mpi(&Q.X, &prv->Q.X) || + mbedtls_mpi_cmp_mpi(&Q.Y, &prv->Q.Y) || + mbedtls_mpi_cmp_mpi(&Q.Z, &prv->Q.Z)) { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free(&Q); + mbedtls_ecp_group_free(&grp); + + return ret; +} +#endif /* MBEDTLS_ECP_C */ + +/* + * Export generic key-pair parameters. + */ +int mbedtls_ecp_export(const mbedtls_ecp_keypair *key, mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_ecp_group_copy(grp, &key->grp)) != 0) { + return ret; + } + + if ((ret = mbedtls_mpi_copy(d, &key->d)) != 0) { + return ret; + } + + if ((ret = mbedtls_ecp_copy(Q, &key->Q)) != 0) { + return ret; + } + + return 0; +} + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_ECP_C) +/* + * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!! + * + * This is the linear congruential generator from numerical recipes, + * except we only use the low byte as the output. See + * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use + */ +static int self_test_rng(void *ctx, unsigned char *out, size_t len) +{ + static uint32_t state = 42; + + (void) ctx; + + for (size_t i = 0; i < len; i++) { + state = state * 1664525u + 1013904223u; + out[i] = (unsigned char) state; + } + + return 0; +} + +/* Adjust the exponent to be a valid private point for the specified curve. + * This is sometimes necessary because we use a single set of exponents + * for all curves but the validity of values depends on the curve. */ +static int self_test_adjust_exponent(const mbedtls_ecp_group *grp, + mbedtls_mpi *m) +{ + int ret = 0; + switch (grp->id) { + /* If Curve25519 is available, then that's what we use for the + * Montgomery test, so we don't need the adjustment code. */ +#if !defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + case MBEDTLS_ECP_DP_CURVE448: + /* Move highest bit from 254 to N-1. Setting bit N-1 is + * necessary to enforce the highest-bit-set constraint. */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, 254, 0)); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(m, grp->nbits, 1)); + /* Copy second-highest bit from 253 to N-2. This is not + * necessary but improves the test variety a bit. */ + MBEDTLS_MPI_CHK( + mbedtls_mpi_set_bit(m, grp->nbits - 1, + mbedtls_mpi_get_bit(m, 253))); + break; +#endif +#endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */ + default: + /* Non-Montgomery curves and Curve25519 need no adjustment. */ + (void) grp; + (void) m; + goto cleanup; + } +cleanup: + return ret; +} + +/* Calculate R = m.P for each m in exponents. Check that the number of + * basic operations doesn't depend on the value of m. */ +static int self_test_point(int verbose, + mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + mbedtls_mpi *m, + const mbedtls_ecp_point *P, + const char *const *exponents, + size_t n_exponents) +{ + int ret = 0; + size_t i = 0; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[0])); + MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m)); + MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL)); + + for (i = 1; i < n_exponents; i++) { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(m, 16, exponents[i])); + MBEDTLS_MPI_CHK(self_test_adjust_exponent(grp, m)); + MBEDTLS_MPI_CHK(mbedtls_ecp_mul(grp, R, m, P, self_test_rng, NULL)); + + if (add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev) { + ret = 1; + break; + } + } + +cleanup: + if (verbose != 0) { + if (ret != 0) { + mbedtls_printf("failed (%u)\n", (unsigned int) i); + } else { + mbedtls_printf("passed\n"); + } + } + return ret; +} +#endif /* MBEDTLS_ECP_C */ + +/* + * Checkup routine + */ +int mbedtls_ecp_self_test(int verbose) +{ +#if defined(MBEDTLS_ECP_C) + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_ecp_group grp; + mbedtls_ecp_point R, P; + mbedtls_mpi m; + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + /* Exponents especially adapted for secp192k1, which has the lowest + * order n of all supported curves (secp192r1 is in a slightly larger + * field but the order of its base point is slightly smaller). */ + const char *sw_exponents[] = + { + "000000000000000000000000000000000000000000000001", /* one */ + "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */ + "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ + }; +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + const char *m_exponents[] = + { + /* Valid private values for Curve25519. In a build with Curve448 + * but not Curve25519, they will be adjusted in + * self_test_adjust_exponent(). */ + "4000000000000000000000000000000000000000000000000000000000000000", + "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30", + "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8", + "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460", + "5555555555555555555555555555555555555555555555555555555555555550", + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8", + }; +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + + mbedtls_ecp_group_init(&grp); + mbedtls_ecp_point_init(&R); + mbedtls_ecp_point_init(&P); + mbedtls_mpi_init(&m); + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + /* Use secp192r1 if available, or any available curve */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP192R1)); +#else + MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, mbedtls_ecp_curve_list()->grp_id)); +#endif + + if (verbose != 0) { + mbedtls_printf(" ECP SW test #1 (constant op_count, base point G): "); + } + /* Do a dummy multiplication first to trigger precomputation */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&m, 2)); + MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&grp, &P, &m, &grp.G, self_test_rng, NULL)); + ret = self_test_point(verbose, + &grp, &R, &m, &grp.G, + sw_exponents, + sizeof(sw_exponents) / sizeof(sw_exponents[0])); + if (ret != 0) { + goto cleanup; + } + + if (verbose != 0) { + mbedtls_printf(" ECP SW test #2 (constant op_count, other point): "); + } + /* We computed P = 2G last time, use it */ + ret = self_test_point(verbose, + &grp, &R, &m, &P, + sw_exponents, + sizeof(sw_exponents) / sizeof(sw_exponents[0])); + if (ret != 0) { + goto cleanup; + } + + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&R); +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + if (verbose != 0) { + mbedtls_printf(" ECP Montgomery test (constant op_count): "); + } +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE25519)); +#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_CURVE448)); +#else +#error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test" +#endif + ret = self_test_point(verbose, + &grp, &R, &m, &grp.G, + m_exponents, + sizeof(m_exponents) / sizeof(m_exponents[0])); + if (ret != 0) { + goto cleanup; + } +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +cleanup: + + if (ret < 0 && verbose != 0) { + mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret); + } + + mbedtls_ecp_group_free(&grp); + mbedtls_ecp_point_free(&R); + mbedtls_ecp_point_free(&P); + mbedtls_mpi_free(&m); + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + return ret; +#else /* MBEDTLS_ECP_C */ + (void) verbose; + return 0; +#endif /* MBEDTLS_ECP_C */ +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* !MBEDTLS_ECP_ALT */ + +#endif /* MBEDTLS_ECP_LIGHT */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecp_curves.c b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_curves.c new file mode 100644 index 0000000..577e23b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_curves.c @@ -0,0 +1,5467 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if !defined(MBEDTLS_ECP_WITH_MPI_UINT) + +#if defined(MBEDTLS_ECP_LIGHT) + +#include "mbedtls/ecp.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include "bn_mul.h" +#include "bignum_core.h" +#include "ecp_invasive.h" + +#include + +#if !defined(MBEDTLS_ECP_ALT) + +/* Parameter validation macros based on platform_util.h */ +#define ECP_VALIDATE_RET(cond) \ + MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA) +#define ECP_VALIDATE(cond) \ + MBEDTLS_INTERNAL_VALIDATE(cond) + +#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } + +#define ECP_MPI_INIT_ARRAY(x) \ + ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) + +#define ECP_POINT_INIT_XY_Z0(x, y) { \ + ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(NULL, 0) } +#define ECP_POINT_INIT_XY_Z1(x, y) { \ + ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(mpi_one, 1) } + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* For these curves, we build the group parameters dynamically. */ +#define ECP_LOAD_GROUP +static mbedtls_mpi_uint mpi_one[] = { 1 }; +#endif + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static const mbedtls_mpi_uint secp192r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp192r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64), +}; +static const mbedtls_mpi_uint secp192r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), +}; +static const mbedtls_mpi_uint secp192r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), +}; +static const mbedtls_mpi_uint secp192r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp192r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18), +}; +static const mbedtls_mpi_uint secp192r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07), +}; +static const mbedtls_mpi_uint secp192r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x9E, 0xE3, 0x60, 0x59, 0xD1, 0xC4, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBD, 0x22, 0xD7, 0x2D, 0x07, 0xBD, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x2A, 0xCF, 0x33, 0xF0, 0xBE, 0xD1, 0xED), +}; +static const mbedtls_mpi_uint secp192r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x71, 0x4B, 0xA8, 0xED, 0x7E, 0xC9, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x2A, 0xF6, 0xDF, 0x0E, 0xE8, 0x4C, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x35, 0xF7, 0x8A, 0xC3, 0xEC, 0xDE, 0x1E), +}; +static const mbedtls_mpi_uint secp192r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0xC2, 0x1D, 0x32, 0x8F, 0x10, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x2D, 0x17, 0xF3, 0xE4, 0xFE, 0xD8, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x45, 0x10, 0x70, 0x2C, 0x3E, 0x52, 0x3E), +}; +static const mbedtls_mpi_uint secp192r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF1, 0x04, 0x5D, 0xEE, 0xD4, 0x56, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xB7, 0x38, 0x27, 0x61, 0xAA, 0x81, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0xD7, 0x0E, 0x29, 0x0E, 0x11, 0x14), +}; +static const mbedtls_mpi_uint secp192r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x35, 0x52, 0xC6, 0x31, 0xB7, 0x27, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xD4, 0x15, 0x98, 0x0F, 0xE7, 0xF3, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x31, 0x70, 0x35, 0x09, 0xA0, 0x2B, 0xC2), +}; +static const mbedtls_mpi_uint secp192r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x75, 0xA7, 0x4C, 0x88, 0xCF, 0x5B, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x17, 0x48, 0x8D, 0xF2, 0xF0, 0x86, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCF, 0xFE, 0x6B, 0xB0, 0xA5, 0x06, 0xAB), +}; +static const mbedtls_mpi_uint secp192r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x6A, 0xDC, 0x9A, 0x6D, 0x7B, 0x47, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xFC, 0x51, 0x12, 0x62, 0x66, 0x0B, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x40, 0x93, 0xA0, 0xB5, 0x5A, 0x58, 0xD7), +}; +static const mbedtls_mpi_uint secp192r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCB, 0xAF, 0xDC, 0x0B, 0xA1, 0x26, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x36, 0x9D, 0xA3, 0xD7, 0x3B, 0xAD, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x3B, 0x05, 0x9A, 0xA8, 0xAA, 0x69, 0xB2), +}; +static const mbedtls_mpi_uint secp192r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD9, 0xD1, 0x4D, 0x4A, 0x6E, 0x96, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x66, 0x32, 0x39, 0xC6, 0x57, 0x7D, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xA0, 0x36, 0xC2, 0x45, 0xF9, 0x00, 0x62), +}; +static const mbedtls_mpi_uint secp192r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xEF, 0x59, 0x46, 0xDC, 0x60, 0xD9, 0x8F), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xB0, 0xE9, 0x41, 0xA4, 0x87, 0x76, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xD4, 0x0E, 0xB2, 0xFA, 0x16, 0x56, 0xDC), +}; +static const mbedtls_mpi_uint secp192r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x62, 0xD2, 0xB1, 0x34, 0xB2, 0xF1, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xED, 0x55, 0xC5, 0x47, 0xB5, 0x07, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF6, 0x2F, 0x94, 0xC3, 0xDD, 0x54, 0x2F), +}; +static const mbedtls_mpi_uint secp192r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xA6, 0xD4, 0x8C, 0xA9, 0xCE, 0x4D, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x4B, 0x46, 0xCC, 0xB2, 0x55, 0xC8, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x31, 0xED, 0x89, 0x65, 0x59, 0x55), +}; +static const mbedtls_mpi_uint secp192r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x0A, 0xD1, 0x1A, 0xC5, 0xF6, 0xEA, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xFC, 0x0C, 0x1A, 0xFB, 0xA0, 0xC8, 0x70), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xFD, 0x53, 0x6F, 0x6D, 0xBF, 0xBA, 0xAF), +}; +static const mbedtls_mpi_uint secp192r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xB0, 0x7D, 0x83, 0x96, 0xE3, 0xCB, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x6E, 0x55, 0x2C, 0x20, 0x53, 0x2F, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x66, 0x00, 0x17, 0x08, 0xFE, 0xAC, 0x31), +}; +static const mbedtls_mpi_uint secp192r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x12, 0x97, 0x3A, 0xC7, 0x57, 0x45, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x25, 0x99, 0x00, 0xF6, 0x97, 0xB4, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x74, 0xE6, 0xE6, 0xA3, 0xDF, 0x9C, 0xCC), +}; +static const mbedtls_mpi_uint secp192r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xF4, 0x76, 0xD5, 0x5F, 0x2A, 0xFD, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x80, 0x7E, 0x3E, 0xE5, 0xE8, 0xD6, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xAD, 0x1E, 0x70, 0x79, 0x3E, 0x3D, 0x83), +}; +static const mbedtls_mpi_uint secp192r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x15, 0xBB, 0xB3, 0x42, 0x6A, 0xA1, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x58, 0xCB, 0x43, 0x25, 0x00, 0x14, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x4E, 0x93, 0x11, 0xE0, 0x32, 0x54, 0x98), +}; +static const mbedtls_mpi_uint secp192r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x52, 0xA2, 0xB4, 0x57, 0x32, 0xB9, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x43, 0xA1, 0xB1, 0xFB, 0x01, 0xE1, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xFB, 0x5A, 0x11, 0xB8, 0xC2, 0x03, 0xE5), +}; +static const mbedtls_mpi_uint secp192r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x2B, 0x71, 0x26, 0x4E, 0x7C, 0xC5, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF5, 0xD3, 0xA8, 0xE4, 0x95, 0x48, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAE, 0xD9, 0x5D, 0x9F, 0x6A, 0x22, 0xAD), +}; +static const mbedtls_mpi_uint secp192r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xCC, 0xA3, 0x4D, 0xA0, 0x1C, 0x34, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x3C, 0x62, 0xF8, 0x5E, 0xA6, 0x58, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x6E, 0x66, 0x8A, 0x3D, 0x17, 0xFF, 0x0F), +}; +static const mbedtls_mpi_uint secp192r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xCD, 0xA8, 0xDD, 0xD1, 0x20, 0x5C, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xFE, 0x17, 0xE2, 0xCF, 0xEA, 0x63, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x51, 0xC9, 0x16, 0xDE, 0xB4, 0xB2, 0xDD), +}; +static const mbedtls_mpi_uint secp192r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBE, 0x12, 0xD7, 0xA3, 0x0A, 0x50, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x87, 0xC5, 0x8A, 0x76, 0x57, 0x07, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x1F, 0xC6, 0x1B, 0x66, 0xC4, 0x3D, 0x8A), +}; +static const mbedtls_mpi_uint secp192r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xA4, 0x85, 0x13, 0x8F, 0xA7, 0x35, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x0D, 0xFD, 0xFF, 0x1B, 0xD1, 0xD6, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x7A, 0xD0, 0xC3, 0xB4, 0xEF, 0x39, 0x66), +}; +static const mbedtls_mpi_uint secp192r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xFE, 0xA5, 0x9C, 0x34, 0x30, 0x49, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xC5, 0x39, 0x26, 0x06, 0xE3, 0x01, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x2B, 0x66, 0xFC, 0x95, 0x5F, 0x35, 0xF7), +}; +static const mbedtls_mpi_uint secp192r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xCF, 0x54, 0x63, 0x99, 0x57, 0x05, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x6F, 0x00, 0x5F, 0x65, 0x08, 0x47, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x2A, 0x90, 0x6D, 0x67, 0xC6, 0xBC, 0x45), +}; +static const mbedtls_mpi_uint secp192r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x4D, 0x88, 0x0A, 0x35, 0x9E, 0x33, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x17, 0x0C, 0xF8, 0xE1, 0x7A, 0x49, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x44, 0x06, 0x8F, 0x0B, 0x70, 0x2F, 0x71), +}; +static const mbedtls_mpi_uint secp192r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4B, 0xCB, 0xF9, 0x8E, 0x6A, 0xDA, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x43, 0xA1, 0x3F, 0xCE, 0x17, 0xD2, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x0D, 0xD2, 0x6C, 0x82, 0x37, 0xE5, 0xFC), +}; +static const mbedtls_mpi_uint secp192r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x3C, 0xF4, 0x92, 0xB4, 0x8A, 0x95, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x96, 0xF1, 0x0A, 0x34, 0x2F, 0x74, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0xAA, 0xBA, 0x86, 0x77, 0x4F, 0xA2), +}; +static const mbedtls_mpi_uint secp192r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x7F, 0xEF, 0x60, 0x50, 0x80, 0xD7, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xAC, 0xC9, 0xFE, 0xEC, 0x0A, 0x1A, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x2F, 0xBE, 0x91, 0xD7, 0xB7, 0x38, 0x48), +}; +static const mbedtls_mpi_uint secp192r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xAE, 0x85, 0x98, 0xFE, 0x05, 0x7F, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBE, 0xFD, 0x11, 0x31, 0x3D, 0x14, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x75, 0xE8, 0x30, 0x01, 0xCB, 0x9B, 0x1C), +}; +static const mbedtls_ecp_point secp192r1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp192r1_T_0_X, secp192r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_1_X, secp192r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_2_X, secp192r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_3_X, secp192r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_4_X, secp192r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_5_X, secp192r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_6_X, secp192r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_7_X, secp192r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_8_X, secp192r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_9_X, secp192r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_10_X, secp192r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_11_X, secp192r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_12_X, secp192r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_13_X, secp192r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_14_X, secp192r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp192r1_T_15_X, secp192r1_T_15_Y), +}; +#else +#define secp192r1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static const mbedtls_mpi_uint secp224r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4), +}; +static const mbedtls_mpi_uint secp224r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7), +}; +static const mbedtls_mpi_uint secp224r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD), +}; +static const mbedtls_mpi_uint secp224r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), +}; +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp224r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x0C, 0x0E, 0xB7, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x63, 0x37, 0xBD, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF9, 0xB8, 0xD0, 0x3D, 0xD2, 0xD3, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xFD, 0x99, 0x26, 0x19, 0xFE, 0x13, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x0E, 0x4C, 0x48, 0x7C, 0xA2, 0x17, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA3, 0x13, 0x57, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x16, 0x5C, 0x8F, 0xAA, 0xED, 0x0F, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xC5, 0x43, 0x34, 0x93, 0x05, 0x2A, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE3, 0x6C, 0xCA, 0xC6, 0x14, 0xC2, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x43, 0x6C, 0xD7, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x5A, 0x98, 0x1E, 0xC8, 0xA5, 0x42, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x49, 0x56, 0x78, 0xF8, 0xEF, 0xED, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xBB, 0x64, 0xB6, 0x4C, 0x54, 0x5F, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x0C, 0x33, 0xCC, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x79, 0xCB, 0x2E, 0x08, 0xFF, 0xD8, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x1F, 0xD4, 0xD7, 0x57, 0xE9, 0x39, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xD6, 0x3B, 0x0A, 0x1C, 0x87, 0xB7, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x30, 0xD8, 0x05, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x79, 0x74, 0x9A, 0xE6, 0xBB, 0xC2, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x5B, 0xA6, 0x67, 0xC1, 0x91, 0xE7, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xDF, 0x38, 0x82, 0x19, 0x2C, 0x4C, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x2E, 0x39, 0xC5, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x36, 0x78, 0x4E, 0xAE, 0x5B, 0x02, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF6, 0x8B, 0xF8, 0xF4, 0x92, 0x6B, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x4D, 0x71, 0x35, 0xE7, 0x0C, 0x2C, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xA5, 0x1F, 0xAE, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x1C, 0x4B, 0xDF, 0x5B, 0xF2, 0x51, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0xB1, 0x5A, 0xC6, 0x0F, 0x0E, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x24, 0x09, 0x62, 0xAF, 0xFC, 0xDB, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xE1, 0x80, 0x55, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x82, 0xFE, 0xAD, 0xC3, 0xE5, 0xCF, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xA2, 0x62, 0x17, 0x76, 0xF0, 0x5A, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB8, 0xE5, 0xAC, 0xB7, 0x66, 0x38, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xFD, 0x86, 0x05, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0x0C, 0x3C, 0xD1, 0x66, 0xB0, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x59, 0xB4, 0x8D, 0x90, 0x10, 0xB7, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x47, 0x9B, 0xE6, 0x55, 0x8A, 0xE4, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x49, 0xDB, 0x78, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x97, 0xED, 0xDE, 0xFF, 0xB3, 0xDF, 0x48), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xB9, 0x83, 0xB7, 0xEB, 0xBE, 0x40, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xD3, 0xD3, 0xCD, 0x0E, 0x82, 0x79, 0x3D), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x83, 0x1B, 0xF0, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x22, 0xBB, 0x54, 0xD3, 0x31, 0x56, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0xE5, 0xE0, 0x89, 0x96, 0x8E, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xEF, 0x0A, 0xED, 0xD0, 0x11, 0x4A, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x00, 0x57, 0x27, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCA, 0x3D, 0xF7, 0x64, 0x9B, 0x6E, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xE3, 0x70, 0x6B, 0x41, 0xD7, 0xED, 0x8F), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x44, 0x44, 0x80, 0xCE, 0x13, 0x37, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x73, 0x80, 0x79, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x4D, 0x70, 0x7D, 0x31, 0x0F, 0x1C, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x35, 0x88, 0x47, 0xC4, 0x24, 0x78, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF0, 0xCD, 0x91, 0x81, 0xB3, 0xDE, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xCE, 0xC6, 0xF7, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x9C, 0x2D, 0xE8, 0xD2, 0x00, 0x8F, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x5E, 0x7C, 0x0E, 0x0C, 0x6E, 0x58, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x81, 0x21, 0xCE, 0x43, 0xF4, 0x24, 0x3D), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xBC, 0xF0, 0xF4, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x10, 0xC2, 0x74, 0x4A, 0x8F, 0x8A, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x67, 0xF4, 0x2B, 0x38, 0x2B, 0x35, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0C, 0xA9, 0xFA, 0x77, 0x5C, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x19, 0x2B, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x3E, 0x96, 0x22, 0x53, 0xE1, 0xE9, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x13, 0xBC, 0xA1, 0x16, 0xEC, 0x01, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x00, 0xC9, 0x7A, 0xC3, 0x73, 0xA5, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xF4, 0x5E, 0xC1, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x95, 0xD6, 0xD9, 0x32, 0x30, 0x2B, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x42, 0x09, 0x05, 0x61, 0x2A, 0x7E, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x84, 0xA2, 0x05, 0x88, 0x64, 0x65, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2D, 0x90, 0xB3, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE7, 0x2E, 0x85, 0x55, 0x80, 0x7C, 0x79), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC1, 0xAC, 0x78, 0xB4, 0xAF, 0xFB, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xC3, 0x28, 0x8E, 0x79, 0x18, 0x1F, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x46, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x5F, 0xA8, 0x6C, 0x46, 0x83, 0x43, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xA9, 0x93, 0x11, 0xB6, 0x07, 0x57, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x2A, 0x9D, 0x03, 0x89, 0x7E, 0xD7, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x8C, 0x62, 0xCF, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x2C, 0x13, 0x59, 0xCC, 0xFA, 0x84, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB9, 0x48, 0xBC, 0x57, 0xC7, 0xB3, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x0A, 0x38, 0x24, 0x2E, 0x3A, 0x28, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x0A, 0x43, 0xB8, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x25, 0xAB, 0xC1, 0xEE, 0x70, 0x3C, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xDB, 0x45, 0x1D, 0x4A, 0x80, 0x75, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1F, 0x4D, 0x2D, 0x9A, 0x05, 0xF4, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x10, 0xF0, 0x5A, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x95, 0xE1, 0xDC, 0x15, 0x86, 0xC3, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xDC, 0x27, 0xD1, 0x56, 0xA1, 0x14, 0x0D), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x0B, 0xD6, 0x77, 0x4E, 0x44, 0xA2, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x42, 0x71, 0x1F, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x86, 0xB2, 0xB0, 0xC8, 0x2F, 0x7B, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xEF, 0xCB, 0xDB, 0xBC, 0x9E, 0x3B, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x03, 0x86, 0xDD, 0x5B, 0xF5, 0x8D, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x95, 0x79, 0xD6, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x32, 0x14, 0xDA, 0x9B, 0x4F, 0x07, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x3E, 0xFB, 0x06, 0xEE, 0xA7, 0x40, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x1F, 0xDF, 0x71, 0x61, 0xFD, 0x8B, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x8B, 0xAB, 0x8B, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x34, 0xB3, 0xB4, 0xBC, 0x9F, 0xB0, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x58, 0x48, 0xA8, 0x77, 0xBB, 0x13, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC6, 0xF7, 0x34, 0xCC, 0x89, 0x21, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x33, 0xDD, 0x1F, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x81, 0xEF, 0xA4, 0xF2, 0x10, 0x0B, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF7, 0x6E, 0x72, 0x4A, 0xDF, 0xDD, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x23, 0x0A, 0x53, 0x03, 0x16, 0x62, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x76, 0xFD, 0x3C, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x14, 0xA1, 0xFA, 0xA0, 0x18, 0xBE, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x2A, 0xE1, 0xD7, 0xB0, 0x6C, 0xA0, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xC0, 0xB0, 0xC6, 0x63, 0x24, 0xCD, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x38, 0x2C, 0xB1, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCD, 0x7D, 0x20, 0x0C, 0xFE, 0xAC, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x9F, 0xA2, 0xB6, 0x45, 0xF7, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x99, 0xF3, 0xD2, 0x20, 0x02, 0xEB, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x5B, 0x7B, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xDD, 0x77, 0x91, 0x60, 0xEA, 0xFD, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xD3, 0xB5, 0xD6, 0x90, 0x17, 0x0E, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xF4, 0x28, 0xC1, 0xF2, 0x53, 0xF6, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x58, 0xDC, 0x61, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x20, 0x01, 0xFB, 0xF1, 0xBD, 0x5F, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x7F, 0x06, 0xDA, 0x11, 0xCB, 0xBA, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x41, 0x00, 0xA4, 0x1B, 0x30, 0x33, 0x79), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xFF, 0x27, 0xCA, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_ecp_point secp224r1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp224r1_T_0_X, secp224r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_1_X, secp224r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_2_X, secp224r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_3_X, secp224r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_4_X, secp224r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_5_X, secp224r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_6_X, secp224r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_7_X, secp224r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_8_X, secp224r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_9_X, secp224r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_10_X, secp224r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_11_X, secp224r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_12_X, secp224r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_13_X, secp224r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_14_X, secp224r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp224r1_T_15_X, secp224r1_T_15_Y), +}; +#else +#define secp224r1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static const mbedtls_mpi_uint secp256r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp256r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A), +}; +static const mbedtls_mpi_uint secp256r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), +}; +static const mbedtls_mpi_uint secp256r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), +}; +static const mbedtls_mpi_uint secp256r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), +}; +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp256r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B), +}; +static const mbedtls_mpi_uint secp256r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F), +}; +static const mbedtls_mpi_uint secp256r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xC8, 0xBA, 0x04, 0xB7, 0x4B, 0xD2, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC6, 0x23, 0x3A, 0xA0, 0x09, 0x3A, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x9D, 0x4C, 0xF9, 0x58, 0x23, 0xCC, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xED, 0x7B, 0x29, 0x87, 0x0F, 0xFA, 0x3C), +}; +static const mbedtls_mpi_uint secp256r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x69, 0xF2, 0x40, 0x0B, 0xA3, 0x98, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xA8, 0x48, 0x02, 0x0D, 0x1C, 0x12, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xAF, 0x09, 0x83, 0x80, 0xAA, 0x58, 0xA7), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x12, 0xBE, 0x70, 0x94, 0x76, 0xE3, 0xE4), +}; +static const mbedtls_mpi_uint secp256r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x7D, 0xEF, 0x86, 0xFF, 0xE3, 0x37, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x86, 0x8B, 0x08, 0x27, 0x7C, 0xD7, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x54, 0x4C, 0x25, 0x4F, 0x9A, 0xFE, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xFD, 0xF0, 0x6D, 0x37, 0x03, 0x69, 0xD6), +}; +static const mbedtls_mpi_uint secp256r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xD5, 0xDA, 0xAD, 0x92, 0x49, 0xF0, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x73, 0x43, 0x9E, 0xAF, 0xA7, 0xD1, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x41, 0x07, 0xDF, 0x78, 0x95, 0x3E, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x3D, 0xD1, 0xE6, 0x3C, 0xA5, 0xE2, 0x20), +}; +static const mbedtls_mpi_uint secp256r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x6A, 0x5D, 0x52, 0x35, 0xD7, 0xBF, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xA2, 0xBE, 0x96, 0xF4, 0xF8, 0x02, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x20, 0x49, 0x54, 0xEA, 0xB3, 0x82, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0xDB, 0xEA, 0x02, 0xD1, 0x75, 0x1C, 0x62), +}; +static const mbedtls_mpi_uint secp256r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x85, 0xF4, 0x9E, 0x4C, 0xDC, 0x39, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x6D, 0xC4, 0x57, 0xD8, 0x03, 0x5D, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x7F, 0x2D, 0x52, 0x6F, 0xC9, 0xDA, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x64, 0xFA, 0xB4, 0xFE, 0xA4, 0xC4, 0xD7), +}; +static const mbedtls_mpi_uint secp256r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x37, 0xB9, 0xC0, 0xAA, 0x59, 0xC6, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x58, 0xD9, 0xED, 0x58, 0x99, 0x65, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x7D, 0x26, 0x8C, 0x4A, 0xF9, 0x05, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x73, 0x9A, 0xC9, 0xE7, 0x46, 0xDC, 0x00), +}; +static const mbedtls_mpi_uint secp256r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xD0, 0x55, 0xDF, 0x00, 0x0A, 0xF5, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xBF, 0x56, 0x81, 0x2D, 0x20, 0xEB, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC1, 0x28, 0x52, 0xAB, 0xE3, 0xD1, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x34, 0x79, 0x45, 0x57, 0xA5, 0x12, 0x03), +}; +static const mbedtls_mpi_uint secp256r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xCF, 0xB8, 0x7E, 0xF7, 0x92, 0x96, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x01, 0x8C, 0x0D, 0x23, 0xF2, 0xE3, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x2E, 0xE3, 0x84, 0x52, 0x7A, 0x34, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xA1, 0xB0, 0x15, 0x90, 0xE2, 0x53, 0x3C), +}; +static const mbedtls_mpi_uint secp256r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x98, 0xE7, 0xFA, 0xA5, 0x7D, 0x8B, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x35, 0xD2, 0x00, 0xD1, 0x1B, 0x9F, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x69, 0x08, 0x9A, 0x72, 0xF0, 0xA9, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xFE, 0x0E, 0x14, 0xDA, 0x7C, 0x0E, 0xD3), +}; +static const mbedtls_mpi_uint secp256r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xF6, 0xE8, 0xF8, 0x87, 0xF7, 0xFC, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xBE, 0x7F, 0x3F, 0x7A, 0x2B, 0xD7, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x32, 0xF2, 0x2D, 0x94, 0x6D, 0x42, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x9A, 0xE3, 0x5F, 0x42, 0xBB, 0x84, 0xED), +}; +static const mbedtls_mpi_uint secp256r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x95, 0x29, 0x73, 0xA1, 0x67, 0x3E, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x30, 0x54, 0x35, 0x8E, 0x0A, 0xDD, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xD7, 0xA1, 0x97, 0x61, 0x3B, 0xF8, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x33, 0x3C, 0x58, 0x55, 0x34, 0x23, 0xA3), +}; +static const mbedtls_mpi_uint secp256r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x5D, 0x16, 0x5F, 0x7B, 0xBC, 0xBB, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xEE, 0x4E, 0x8A, 0xC1, 0x51, 0xCC, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0D, 0x4D, 0x1B, 0x53, 0x23, 0x1D, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x2A, 0x38, 0x66, 0x52, 0x84, 0xE1, 0x95), +}; +static const mbedtls_mpi_uint secp256r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x9B, 0x83, 0x0A, 0x81, 0x4F, 0xAD, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xFF, 0x42, 0x41, 0x6E, 0xA9, 0xA2, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA1, 0x4F, 0x1F, 0x89, 0x82, 0xAA, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xB8, 0x0F, 0x6B, 0x8F, 0x8C, 0xD6, 0x68), +}; +static const mbedtls_mpi_uint secp256r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0xB3, 0xBB, 0x51, 0x69, 0xA2, 0x11, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x4F, 0x0F, 0x8D, 0xBD, 0x26, 0x0F, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xCB, 0xEC, 0x6B, 0x34, 0xC3, 0x3D, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x5D, 0x1E, 0x10, 0xD5, 0x44, 0xE2, 0x54), +}; +static const mbedtls_mpi_uint secp256r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x9E, 0xB1, 0xF1, 0x6E, 0x4C, 0xAD, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE3, 0xC2, 0x58, 0xC0, 0xFB, 0x34, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x9C, 0xDF, 0x35, 0x07, 0x41, 0xBD, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x10, 0xEC, 0x0E, 0xEC, 0xBB, 0xD6), +}; +static const mbedtls_mpi_uint secp256r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xCF, 0xEF, 0x3F, 0x83, 0x1A, 0x88, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x29, 0xB5, 0xB9, 0xE0, 0xC9, 0xA3, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x46, 0x1E, 0x77, 0xCD, 0x7E, 0xB3, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x21, 0xD0, 0xD4, 0xA3, 0x16, 0x08, 0xEE), +}; +static const mbedtls_mpi_uint secp256r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xCA, 0xA8, 0xB3, 0xBF, 0x29, 0x99, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF2, 0x05, 0xC1, 0xCF, 0x5D, 0x91, 0x48), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x01, 0x49, 0xDB, 0x82, 0xDF, 0x5F, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x06, 0x90, 0xAD, 0xE3, 0x38, 0xA4, 0xC4), +}; +static const mbedtls_mpi_uint secp256r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xD2, 0x3A, 0xE8, 0x03, 0xC5, 0x6D, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x35, 0xD0, 0xAE, 0x1D, 0x7A, 0x9F, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x1E, 0xD2, 0xCB, 0xAC, 0x88, 0x27, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x9C, 0xE0, 0x31, 0xDD, 0x99, 0x86), +}; +static const mbedtls_mpi_uint secp256r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xF9, 0x9B, 0x32, 0x96, 0x41, 0x58, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x5A, 0x2A, 0xB8, 0x96, 0x0E, 0xB2, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x78, 0x2C, 0xC7, 0x08, 0x99, 0x19, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x59, 0x28, 0xE9, 0x84, 0x54, 0xE6, 0x16), +}; +static const mbedtls_mpi_uint secp256r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x38, 0x30, 0xDB, 0x70, 0x2C, 0x0A, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x5C, 0x9D, 0xE9, 0xD5, 0x46, 0x0B, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x0B, 0x60, 0x4B, 0x37, 0x7D, 0xB9, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x24, 0xF3, 0x3D, 0x79, 0x7F, 0x6C, 0x18), +}; +static const mbedtls_mpi_uint secp256r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7F, 0xE5, 0x1C, 0x4F, 0x60, 0x24, 0xF7, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xD8, 0xE2, 0x91, 0x7F, 0x89, 0x49, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xA7, 0x2E, 0x8D, 0x6A, 0xB3, 0x39, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x89, 0xB5, 0x9A, 0xB8, 0x8D, 0x42, 0x9C), +}; +static const mbedtls_mpi_uint secp256r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x45, 0xE6, 0x4B, 0x3F, 0x4F, 0x1E, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x65, 0x5E, 0x59, 0x22, 0xCC, 0x72, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x93, 0x1A, 0x27, 0x1E, 0x34, 0xC5, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xF2, 0xA5, 0x58, 0x5C, 0x15, 0x2E, 0xC6), +}; +static const mbedtls_mpi_uint secp256r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x7F, 0xBA, 0x58, 0x5A, 0x84, 0x6F, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA6, 0x36, 0x7E, 0xDC, 0xF7, 0xE1, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x4D, 0xAA, 0xEE, 0x57, 0x76, 0x3A, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x7E, 0x26, 0x18, 0x22, 0x23, 0x9F, 0xFF), +}; +static const mbedtls_mpi_uint secp256r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x4C, 0x64, 0xC7, 0x55, 0x02, 0x3F, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x02, 0x90, 0xBB, 0xC3, 0xEC, 0x30, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x6F, 0x64, 0xF4, 0x16, 0x69, 0x48, 0xA4), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x44, 0x9C, 0x95, 0x0C, 0x7D, 0x67, 0x5E), +}; +static const mbedtls_mpi_uint secp256r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x91, 0x8B, 0xD8, 0xD0, 0xD7, 0xE7, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xF9, 0x48, 0x62, 0x6F, 0xA8, 0x93, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x3A, 0x99, 0x02, 0xD5, 0x0B, 0x3D, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xD3, 0x00, 0x31, 0xE6, 0x0C, 0x9F, 0x44), +}; +static const mbedtls_mpi_uint secp256r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xB2, 0xAA, 0xFD, 0x88, 0x15, 0xDF, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0x35, 0x27, 0x31, 0x44, 0xCD, 0xC0, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xF8, 0x91, 0xA5, 0x71, 0x94, 0x84, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xCB, 0xD0, 0x93, 0xE9, 0x88, 0xDA, 0xE4), +}; +static const mbedtls_mpi_uint secp256r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC6, 0x39, 0x16, 0x5D, 0xA3, 0x1E, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x07, 0x37, 0x26, 0x36, 0x2A, 0xFE, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xBC, 0xF3, 0xD0, 0xDE, 0x50, 0xFC, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x2E, 0x06, 0x10, 0x15, 0x4D, 0xFA, 0xF7), +}; +static const mbedtls_mpi_uint secp256r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x65, 0x69, 0x5B, 0x66, 0xA2, 0x75, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x16, 0x00, 0x5A, 0xB0, 0x30, 0x25, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xFB, 0x86, 0x42, 0x80, 0xC1, 0xC4, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x1D, 0x83, 0x8E, 0x94, 0x01, 0x5F, 0x82), +}; +static const mbedtls_mpi_uint secp256r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x37, 0x70, 0xEF, 0x1F, 0xA1, 0xF0, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x5B, 0xCE, 0xC4, 0x9B, 0x6F, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x11, 0x11, 0x24, 0x4F, 0x4C, 0x79, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x3A, 0x72, 0xBC, 0xFE, 0x72, 0x58, 0x43), +}; +static const mbedtls_ecp_point secp256r1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp256r1_T_0_X, secp256r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_1_X, secp256r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_2_X, secp256r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_3_X, secp256r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_4_X, secp256r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_5_X, secp256r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_6_X, secp256r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_7_X, secp256r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_8_X, secp256r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_9_X, secp256r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_10_X, secp256r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_11_X, secp256r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_12_X, secp256r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_13_X, secp256r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_14_X, secp256r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp256r1_T_15_X, secp256r1_T_15_Y), +}; +#else +#define secp256r1_T NULL +#endif + +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static const mbedtls_mpi_uint secp384r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp384r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3), +}; +static const mbedtls_mpi_uint secp384r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), +}; +static const mbedtls_mpi_uint secp384r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), +}; +static const mbedtls_mpi_uint secp384r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp384r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA), +}; +static const mbedtls_mpi_uint secp384r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36), +}; +static const mbedtls_mpi_uint secp384r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x92, 0x00, 0x2C, 0x78, 0xDB, 0x1F, 0x37), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xF3, 0xEB, 0xB7, 0x06, 0xF7, 0xB6, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBC, 0x2C, 0xCF, 0xD8, 0xED, 0x53, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x75, 0x7B, 0xA3, 0xAB, 0xC3, 0x2C, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x9D, 0x78, 0x41, 0xF6, 0x76, 0x84, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x56, 0xE8, 0x52, 0xB3, 0xCB, 0xA8, 0xBD), +}; +static const mbedtls_mpi_uint secp384r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xF2, 0xAE, 0xA4, 0xB6, 0x89, 0x1B, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0xCE, 0x1C, 0x7C, 0xF6, 0x50, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xEB, 0x90, 0xE6, 0x4D, 0xC7, 0xD4, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x49, 0x2D, 0x8A, 0x01, 0x99, 0x60, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x80, 0x9B, 0x9B, 0x6A, 0xB0, 0x07, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xA2, 0xEE, 0x59, 0xBE, 0x95, 0xBC, 0x23), +}; +static const mbedtls_mpi_uint secp384r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x9D, 0x56, 0xAE, 0x59, 0xFB, 0x1F, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xAC, 0x91, 0x80, 0x87, 0xA8, 0x6E, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x08, 0xA7, 0x08, 0x94, 0x32, 0xFC, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x29, 0x9E, 0x84, 0xF4, 0xE5, 0x6E, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x21, 0xB9, 0x50, 0x24, 0xF8, 0x9C, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x04, 0x01, 0xC2, 0xFB, 0x77, 0x3E, 0xDE), +}; +static const mbedtls_mpi_uint secp384r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x38, 0xEE, 0xE3, 0xC7, 0x9D, 0xEC, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x88, 0xCF, 0x43, 0xFA, 0x92, 0x5E, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xCA, 0x43, 0xF8, 0x3B, 0x49, 0x7E, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xE7, 0xEB, 0x17, 0x45, 0x86, 0xC2, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x69, 0x57, 0x32, 0xE0, 0x9C, 0xD1, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x10, 0xB8, 0x4D, 0xB8, 0xF4, 0x0D, 0xE3), +}; +static const mbedtls_mpi_uint secp384r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0xDC, 0x9A, 0xB2, 0x79, 0x39, 0x27, 0x16), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x71, 0xE4, 0x3B, 0x4D, 0x60, 0x0C, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xBD, 0x19, 0x40, 0xFA, 0x19, 0x2A, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xF8, 0x1E, 0x43, 0xA1, 0x50, 0x8D, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x18, 0x7C, 0x41, 0xFA, 0x7C, 0x1B, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x24, 0xC4, 0xE9, 0xB7, 0xD3, 0xAD), +}; +static const mbedtls_mpi_uint secp384r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x01, 0x3D, 0x63, 0x54, 0x45, 0x6F, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xB2, 0x19, 0xA3, 0x86, 0x1D, 0x42, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x02, 0x87, 0x18, 0x92, 0x52, 0x1A, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x18, 0xB1, 0x5D, 0x18, 0x1B, 0x37, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x74, 0x61, 0xBA, 0x18, 0xAF, 0x40, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7D, 0x3C, 0x52, 0x0F, 0x07, 0xB0, 0x6F), +}; +static const mbedtls_mpi_uint secp384r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x39, 0x13, 0xAA, 0x60, 0x15, 0x99, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x00, 0xCB, 0xC6, 0xB1, 0xDB, 0x97, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xFA, 0x60, 0xB8, 0x24, 0xE4, 0x7D, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x75, 0xB3, 0x70, 0xB2, 0x83, 0xB1, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xE3, 0x6C, 0xCD, 0x33, 0x62, 0x7A, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x30, 0xDC, 0x0F, 0x9F, 0xBB, 0xB8, 0xAA), +}; +static const mbedtls_mpi_uint secp384r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD5, 0x0A, 0x60, 0x81, 0xB9, 0xC5, 0x16), + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xAA, 0x2F, 0xD6, 0xF2, 0x73, 0xDF, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x7B, 0x74, 0xC9, 0xB3, 0x5B, 0x95, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x04, 0xEB, 0x15, 0xC8, 0x5F, 0x00, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x50, 0x20, 0x28, 0xD1, 0x01, 0xAF, 0xF0), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x4F, 0x31, 0x81, 0x2F, 0x94, 0x48), +}; +static const mbedtls_mpi_uint secp384r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2F, 0xD8, 0xB6, 0x63, 0x7C, 0xE9, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x8C, 0xB9, 0x14, 0xD9, 0x37, 0x63, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x02, 0xB8, 0x46, 0xAD, 0xCE, 0x7B, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x47, 0x2D, 0x66, 0xA7, 0xE9, 0x33, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF9, 0x93, 0x94, 0xA8, 0x48, 0xB3, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x4A, 0xAC, 0x51, 0x08, 0x72, 0x2F, 0x1A), +}; +static const mbedtls_mpi_uint secp384r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xAD, 0xA0, 0xF9, 0x81, 0xE1, 0x78, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9A, 0x63, 0xD8, 0xBA, 0x79, 0x1A, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x31, 0x7B, 0x7A, 0x5A, 0x5D, 0x7D, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x96, 0x12, 0x4B, 0x19, 0x09, 0xE0, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8A, 0x57, 0xEE, 0x4E, 0x6E, 0x7E, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x9D, 0x69, 0xDC, 0xB3, 0xDA, 0xD8, 0x08), +}; +static const mbedtls_mpi_uint secp384r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x49, 0x03, 0x03, 0x33, 0x6F, 0x28, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xDB, 0xA7, 0x05, 0x8C, 0xF3, 0x4D, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x92, 0xB1, 0xA8, 0xEC, 0x0D, 0x64, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0xFC, 0xFD, 0xD0, 0x4B, 0x88, 0x1B, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x9C, 0x51, 0x69, 0xCE, 0x71, 0x73, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5A, 0x14, 0x23, 0x1A, 0x46, 0x63, 0x5F), +}; +static const mbedtls_mpi_uint secp384r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x4C, 0x70, 0x44, 0x18, 0xCD, 0xEF, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x49, 0xDD, 0x64, 0x7E, 0x7E, 0x4D, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x32, 0x7C, 0x09, 0xD0, 0x3F, 0xD6, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE0, 0x4F, 0x65, 0x0C, 0x7A, 0x54, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFA, 0xFB, 0x4A, 0xB4, 0x79, 0x5A, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x1B, 0x2B, 0xDA, 0xBC, 0x9A, 0x74), +}; +static const mbedtls_mpi_uint secp384r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xAC, 0x56, 0xF7, 0x5F, 0x51, 0x68, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xE0, 0x1D, 0xBC, 0x13, 0x4E, 0xAC, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF5, 0xC5, 0xE6, 0xD2, 0x88, 0xBA, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x0E, 0x28, 0x23, 0x58, 0x67, 0xFA, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x80, 0x4B, 0xD8, 0xC4, 0xDF, 0x15, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x0E, 0x58, 0xE6, 0x2C, 0x59, 0xC2, 0x03), +}; +static const mbedtls_mpi_uint secp384r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x26, 0x27, 0x99, 0x16, 0x2B, 0x22, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xF3, 0x8F, 0xC3, 0x2A, 0x9B, 0xFC, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2E, 0x83, 0x3D, 0xFE, 0x9E, 0x3C, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0xCD, 0x2D, 0xC1, 0x49, 0x38, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x42, 0x8B, 0x33, 0x89, 0x1F, 0xEA, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x1D, 0x13, 0xD7, 0x50, 0xBB, 0x3E, 0xEB), +}; +static const mbedtls_mpi_uint secp384r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x9A, 0x52, 0xD2, 0x54, 0x7C, 0x97, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x33, 0x6E, 0xED, 0xD9, 0x87, 0x50, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x35, 0x7E, 0x16, 0x40, 0x15, 0x83, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x2B, 0xA4, 0xAB, 0x03, 0x91, 0xEA, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x47, 0x39, 0xEF, 0x05, 0x59, 0xD0, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x24, 0x0D, 0x76, 0x11, 0x53, 0x08, 0xAF), +}; +static const mbedtls_mpi_uint secp384r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x2F, 0xDD, 0xBD, 0x50, 0x48, 0xB1, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x1C, 0x84, 0x55, 0x78, 0x14, 0xEB, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x5E, 0x3E, 0xA6, 0xAF, 0xF6, 0xC7, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x11, 0xE2, 0x65, 0xCA, 0x41, 0x95, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x83, 0xD8, 0xE6, 0x4D, 0x22, 0x06, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x7F, 0x25, 0x2A, 0xAA, 0x28, 0x46, 0x97), +}; +static const mbedtls_mpi_uint secp384r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xDB, 0x15, 0x56, 0x84, 0xCB, 0xC0, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xDB, 0x0E, 0x08, 0xC9, 0xF5, 0xD4, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x62, 0xD0, 0x1A, 0x7C, 0x13, 0xD5, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xAD, 0x53, 0xE0, 0x32, 0x21, 0xA0, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x38, 0x81, 0x21, 0x23, 0x0E, 0xD2, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x51, 0x05, 0xD0, 0x1E, 0x82, 0xA9, 0x71), +}; +static const mbedtls_mpi_uint secp384r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xC3, 0x27, 0xBF, 0xC6, 0xAA, 0xB7, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x65, 0x45, 0xDF, 0xB9, 0x46, 0x17, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x38, 0x3F, 0xB2, 0xB1, 0x5D, 0xCA, 0x1C), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x29, 0x6C, 0x63, 0xE9, 0xD7, 0x48, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xF1, 0xD7, 0x99, 0x8C, 0xC2, 0x05, 0x99), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE6, 0x5E, 0x82, 0x6D, 0xE5, 0x7E, 0xD5), +}; +static const mbedtls_mpi_uint secp384r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x61, 0xFA, 0x7D, 0x01, 0xDB, 0xB6, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xC6, 0x58, 0x39, 0xF4, 0xC6, 0x82, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0x7A, 0x80, 0x08, 0xCD, 0xAA, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x8C, 0xC6, 0x3F, 0x3C, 0xA5, 0x68, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xF5, 0xD5, 0x17, 0xAE, 0x36, 0xD8, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xAD, 0x92, 0xC5, 0x57, 0x6C, 0xDA, 0x91), +}; +static const mbedtls_mpi_uint secp384r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x67, 0x17, 0xC0, 0x40, 0x78, 0x8C, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x9F, 0xF4, 0xAA, 0xDA, 0x5C, 0x7E, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xDB, 0x42, 0x3E, 0x72, 0x64, 0xA0, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xF9, 0x41, 0x17, 0x43, 0xE3, 0xE8, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xDD, 0xCC, 0x43, 0x7E, 0x16, 0x05, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x4B, 0xCF, 0x48, 0x8F, 0x41, 0x90, 0xE5), +}; +static const mbedtls_mpi_uint secp384r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x0C, 0x6B, 0x9D, 0x22, 0x04, 0xBC, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x63, 0x79, 0x2F, 0x6A, 0x0E, 0x8A, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x67, 0x3F, 0x02, 0xB8, 0x91, 0x7F, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x14, 0x64, 0xA0, 0x33, 0xF4, 0x6B, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x44, 0x71, 0x87, 0xB8, 0x88, 0x3F, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x2B, 0x85, 0x05, 0xC5, 0x44, 0x53, 0x15), +}; +static const mbedtls_mpi_uint secp384r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x2B, 0xFE, 0xD1, 0x1C, 0x73, 0xE3, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x33, 0xA1, 0xD3, 0x69, 0x1C, 0x9D, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x5A, 0xBA, 0xB6, 0xAE, 0x1B, 0x94, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x74, 0x90, 0x5C, 0x57, 0xB0, 0x3A, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x2F, 0x93, 0x20, 0x24, 0x54, 0x1D, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x78, 0x9D, 0x71, 0x67, 0x5D, 0x49, 0x98), +}; +static const mbedtls_mpi_uint secp384r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xC8, 0x0E, 0x11, 0x8D, 0xE0, 0x8F, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x7F, 0x79, 0x6C, 0x5F, 0xB7, 0xBC, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xE1, 0x83, 0x3C, 0x12, 0xBB, 0xEE, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC2, 0xC4, 0x1B, 0x41, 0x71, 0xB9, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0xEE, 0xBB, 0x1D, 0x89, 0x50, 0x88, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x1C, 0x55, 0x74, 0xEB, 0xDE, 0x92, 0x3F), +}; +static const mbedtls_mpi_uint secp384r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x38, 0x92, 0x06, 0x19, 0xD0, 0xB3, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x99, 0x26, 0xA3, 0x5F, 0xE2, 0xC1, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xFC, 0xFD, 0xC3, 0xB6, 0x26, 0x24, 0x8F), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xAD, 0xE7, 0x49, 0xB7, 0x64, 0x4B, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x4E, 0x95, 0xAD, 0x07, 0xFE, 0xB6, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x15, 0xE7, 0x2D, 0x19, 0xA9, 0x08, 0x10), +}; +static const mbedtls_mpi_uint secp384r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xBD, 0xAC, 0x0A, 0x3F, 0x6B, 0xFF, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xE4, 0x74, 0x14, 0xD9, 0x70, 0x1D, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xB0, 0x71, 0xBB, 0xD8, 0x18, 0x96, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0xB8, 0x19, 0x90, 0x80, 0xB5, 0xEE, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x21, 0x20, 0xA6, 0x17, 0x48, 0x03, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0xBB, 0x6D, 0x94, 0x20, 0x34, 0xF1), +}; +static const mbedtls_mpi_uint secp384r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x82, 0x67, 0x4B, 0x8E, 0x4E, 0xBE, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xDA, 0x77, 0xF8, 0x23, 0x55, 0x2B, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x02, 0xDE, 0x25, 0x35, 0x2D, 0x74, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0C, 0xB8, 0x0B, 0x39, 0xBA, 0xAD, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x0E, 0x28, 0x4D, 0xE1, 0x3D, 0xE4, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xEC, 0x0A, 0xD4, 0xB8, 0xC4, 0x8D, 0xB0), +}; +static const mbedtls_mpi_uint secp384r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x68, 0xCE, 0xC2, 0x55, 0x4D, 0x0C, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x20, 0x93, 0x32, 0x90, 0xD6, 0xAE, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x78, 0xAB, 0x43, 0x9E, 0xEB, 0x73, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x97, 0xC3, 0x83, 0xA6, 0x3C, 0xF1, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x25, 0x25, 0x66, 0x08, 0x26, 0xFA, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xFB, 0x44, 0x5D, 0x82, 0xEC, 0x3B, 0xAC), +}; +static const mbedtls_mpi_uint secp384r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x90, 0xEA, 0xB5, 0x04, 0x99, 0xD0, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0xF2, 0x22, 0xA0, 0xEB, 0xFD, 0x45, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA4, 0x81, 0x32, 0xFC, 0xFA, 0xEE, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xBB, 0xA4, 0x6A, 0x77, 0x41, 0x5C, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x1E, 0xAA, 0x4F, 0xF0, 0x10, 0xB3, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x74, 0x13, 0x14, 0x9E, 0x90, 0xD7, 0xE6), +}; +static const mbedtls_mpi_uint secp384r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xBD, 0x70, 0x4F, 0xA8, 0xD1, 0x06, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4E, 0x2E, 0x68, 0xFC, 0x35, 0xFA, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x53, 0x75, 0xED, 0xF2, 0x5F, 0xC2, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x87, 0x6B, 0x9F, 0x05, 0xE2, 0x22, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x1A, 0xA8, 0xB7, 0x03, 0x9E, 0x6D, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD0, 0x69, 0x88, 0xA8, 0x39, 0x9E, 0x3A), +}; +static const mbedtls_mpi_uint secp384r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xEF, 0x68, 0xFE, 0xEC, 0x24, 0x08, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x4B, 0x92, 0x0D, 0xB7, 0x34, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF4, 0xDD, 0x1A, 0xA0, 0x4A, 0xE4, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x63, 0x4F, 0x4F, 0xCE, 0xBB, 0xD6, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xEE, 0x8D, 0xDF, 0x3F, 0x73, 0xB7, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x06, 0xB6, 0x80, 0x4D, 0x81, 0xD9, 0x53), +}; +static const mbedtls_mpi_uint secp384r1_T_16_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF5, 0x13, 0xDF, 0x13, 0x19, 0x97, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xF9, 0xB3, 0x33, 0x66, 0x82, 0x21, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xFC, 0x39, 0x16, 0x23, 0x43, 0x76, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x48, 0x25, 0xA1, 0x64, 0x95, 0x1C, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xAC, 0x15, 0x57, 0xD9, 0xDE, 0xA0, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x5F, 0xB8, 0x3D, 0x48, 0x91, 0x24, 0xCC), +}; +static const mbedtls_mpi_uint secp384r1_T_16_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xF2, 0xC8, 0x54, 0xD1, 0x32, 0xBD, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x3B, 0xF0, 0xAA, 0x9D, 0xD8, 0xF4, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xC3, 0xBB, 0x6C, 0x66, 0xAC, 0x25, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x25, 0x10, 0xB2, 0xE1, 0x41, 0xDE, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xE8, 0x30, 0xB8, 0x37, 0xBC, 0x2A, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x57, 0x01, 0x4A, 0x1E, 0x78, 0x9F, 0x85), +}; +static const mbedtls_mpi_uint secp384r1_T_17_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x19, 0xCD, 0x12, 0x0B, 0x51, 0x4F, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x4B, 0x3D, 0x24, 0xA4, 0x16, 0x59, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xEB, 0xD3, 0x59, 0x2E, 0x75, 0x7C, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB9, 0xB4, 0xA5, 0xD9, 0x2E, 0x29, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x16, 0x05, 0x75, 0x02, 0xB3, 0x06, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x7C, 0x9F, 0x79, 0x91, 0xF1, 0x4F, 0x23), +}; +static const mbedtls_mpi_uint secp384r1_T_17_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x98, 0x7C, 0x84, 0xE1, 0xFF, 0x30, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE2, 0xC2, 0x5F, 0x55, 0x40, 0xBD, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x65, 0x87, 0x3F, 0xC4, 0xC2, 0x24, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x30, 0x0A, 0x60, 0x15, 0xD1, 0x24, 0x48), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x99, 0xD9, 0xB6, 0xAE, 0xB1, 0xAF, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x80, 0xEE, 0xA2, 0x0F, 0x74, 0xB9, 0xF3), +}; +static const mbedtls_mpi_uint secp384r1_T_18_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xE6, 0x0F, 0x37, 0xC1, 0x10, 0x99, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xAD, 0x9D, 0x5D, 0x80, 0x01, 0xA6, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x0F, 0x10, 0x2A, 0x9D, 0x20, 0x38, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x60, 0xCB, 0xCE, 0x5A, 0xA0, 0xA7, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xCF, 0x14, 0xDF, 0xBF, 0xE5, 0x74, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x12, 0x1A, 0xDD, 0x59, 0x02, 0x5D, 0xC6), +}; +static const mbedtls_mpi_uint secp384r1_T_18_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0xF8, 0xF5, 0xB6, 0x13, 0x4D, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x45, 0xB1, 0x93, 0xB3, 0xA2, 0x79, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xF6, 0xCF, 0xF7, 0xE6, 0x29, 0x9C, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x50, 0x65, 0x80, 0xBC, 0x59, 0x0A, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xF0, 0x24, 0x35, 0xA2, 0x46, 0xF0, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x26, 0xC0, 0x9D, 0x61, 0x56, 0x62, 0x67), +}; +static const mbedtls_mpi_uint secp384r1_T_19_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xBB, 0xC2, 0x24, 0x43, 0x2E, 0x37, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xF7, 0xCE, 0x35, 0xFC, 0x77, 0xF3, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x34, 0x96, 0xD5, 0x4A, 0x76, 0x9D, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x3B, 0x0F, 0xEA, 0xA8, 0x12, 0x0B, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x3F, 0x5D, 0x2D, 0x1C, 0xD4, 0x9E, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x2E, 0xDD, 0xC7, 0x6E, 0xAB, 0xAF, 0xDC), +}; +static const mbedtls_mpi_uint secp384r1_T_19_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xB2, 0x7B, 0x0C, 0x9A, 0x83, 0x8E, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x51, 0x90, 0x92, 0x79, 0x32, 0x19, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x89, 0xF9, 0xD0, 0xCF, 0x2C, 0xA5, 0x8F), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x50, 0x21, 0xDE, 0x50, 0x41, 0x9D, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x7D, 0x2B, 0x9E, 0x9D, 0x95, 0xA8, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA5, 0x20, 0x87, 0x88, 0x97, 0x5F, 0xAA), +}; +static const mbedtls_mpi_uint secp384r1_T_20_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x59, 0xB4, 0x66, 0x7E, 0xE8, 0x5A, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x5C, 0x7E, 0xB2, 0xAD, 0xD9, 0xC9, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x97, 0x49, 0xA3, 0x13, 0x83, 0x07, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x26, 0xC7, 0x13, 0x35, 0x0D, 0xB0, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x60, 0xAB, 0xFA, 0x4B, 0x93, 0x18, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2D, 0x1C, 0x31, 0x4C, 0xE4, 0x61, 0xAE), +}; +static const mbedtls_mpi_uint secp384r1_T_20_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x4D, 0x1E, 0x51, 0x59, 0x6E, 0x91, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x54, 0x4D, 0x51, 0xED, 0x36, 0xCC, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xA8, 0x56, 0xC7, 0x78, 0x27, 0x33, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB7, 0x95, 0xC9, 0x8B, 0xC8, 0x6A, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xE9, 0x13, 0x96, 0xB3, 0xE1, 0xF9, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x46, 0xB0, 0x5E, 0xC3, 0x94, 0x03, 0x05), +}; +static const mbedtls_mpi_uint secp384r1_T_21_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x5B, 0x29, 0x30, 0x41, 0x1A, 0x9E, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xCA, 0x83, 0x31, 0x5B, 0xA7, 0xCB, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x41, 0x50, 0x44, 0x4D, 0x64, 0x31, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x84, 0xC2, 0x5D, 0x97, 0xA5, 0x3C, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x0F, 0xA5, 0xFD, 0x8E, 0x5A, 0x47, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x58, 0x02, 0x2D, 0x40, 0xB1, 0x0B, 0xBA), +}; +static const mbedtls_mpi_uint secp384r1_T_21_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x33, 0x8C, 0x67, 0xCE, 0x23, 0x43, 0x99), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x53, 0x47, 0x72, 0x44, 0x1F, 0x5B, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xC1, 0xD9, 0xA4, 0x50, 0x88, 0x63, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xF2, 0x75, 0x69, 0x73, 0x00, 0xC4, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x90, 0x1D, 0xDF, 0x1A, 0x00, 0xD8, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xB1, 0x89, 0x48, 0xA8, 0x70, 0x62, 0xEF), +}; +static const mbedtls_mpi_uint secp384r1_T_22_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x8A, 0x55, 0x50, 0x7B, 0xEF, 0x8A, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1B, 0x23, 0x48, 0x23, 0x63, 0x91, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x04, 0x54, 0x3C, 0x24, 0x9B, 0xC7, 0x9A), + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x38, 0xC3, 0x84, 0xFB, 0xFF, 0x9F, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x2A, 0xE0, 0x6D, 0x68, 0x8A, 0x5C, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x93, 0x53, 0x85, 0xA1, 0x0D, 0xAF, 0x63), +}; +static const mbedtls_mpi_uint secp384r1_T_22_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x88, 0x95, 0x4C, 0x0B, 0xD0, 0x06, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xAF, 0x8D, 0x49, 0xA2, 0xC8, 0xB4, 0xE0), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x76, 0x53, 0x09, 0x88, 0x43, 0x87, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA4, 0x77, 0x3F, 0x5E, 0x21, 0xB4, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x9E, 0x86, 0x64, 0xCC, 0x91, 0xC1, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x17, 0x56, 0xCB, 0xC3, 0x7D, 0x5B, 0xB1), +}; +static const mbedtls_mpi_uint secp384r1_T_23_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x74, 0x9F, 0xB5, 0x91, 0x21, 0xB1, 0x1C), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xED, 0xE1, 0x11, 0xEF, 0x45, 0xAF, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x31, 0xBE, 0xB2, 0xBC, 0x72, 0x65, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x4B, 0x8C, 0x77, 0xCE, 0x1E, 0x42, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC9, 0xAA, 0xB9, 0xD9, 0x86, 0x99, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x23, 0x80, 0xC6, 0x4E, 0x35, 0x0B, 0x6D), +}; +static const mbedtls_mpi_uint secp384r1_T_23_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xD8, 0xA2, 0x0A, 0x39, 0x32, 0x1D, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0xC8, 0x86, 0xF1, 0x12, 0x9A, 0x4A, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xF1, 0x7C, 0xAA, 0x70, 0x8E, 0xBC, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x01, 0x47, 0x8F, 0xDD, 0x8B, 0xA5, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x08, 0x21, 0xF4, 0xAB, 0xC7, 0xF5, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x76, 0xA5, 0x95, 0xC4, 0x0F, 0x88, 0x1D), +}; +static const mbedtls_mpi_uint secp384r1_T_24_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x42, 0x2A, 0x52, 0xCD, 0x75, 0x51, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x36, 0xE5, 0x04, 0x2B, 0x44, 0xC6, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xEE, 0x16, 0x13, 0x07, 0x83, 0xB5, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x59, 0xC6, 0xA2, 0x19, 0x05, 0xD3, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8B, 0xA8, 0x16, 0x09, 0xB7, 0xEA, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xEE, 0x14, 0xAF, 0xB5, 0xFD, 0xD0, 0xEF), +}; +static const mbedtls_mpi_uint secp384r1_T_24_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x7C, 0xCA, 0x71, 0x3E, 0x6E, 0x66, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x31, 0x0E, 0x3F, 0xE5, 0x91, 0xC4, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x3D, 0xC2, 0x3E, 0x95, 0x37, 0x58, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x1F, 0x02, 0x03, 0xF3, 0xEF, 0xEE, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x5B, 0x1A, 0xFC, 0x38, 0xCD, 0xE8, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x57, 0x42, 0x85, 0xC6, 0x21, 0x68, 0x71), +}; +static const mbedtls_mpi_uint secp384r1_T_25_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA2, 0x4A, 0x66, 0xB1, 0x0A, 0xE6, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x0C, 0x94, 0x9D, 0x5E, 0x99, 0xB2, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x03, 0x40, 0xCA, 0xB2, 0xB3, 0x30, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0x48, 0x27, 0x34, 0x1E, 0xE2, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x72, 0x5B, 0xAC, 0xC1, 0x6D, 0xE3, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAB, 0x46, 0xCB, 0xEA, 0x5E, 0x4B, 0x0B), +}; +static const mbedtls_mpi_uint secp384r1_T_25_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x08, 0xAD, 0x4E, 0x51, 0x9F, 0x2A, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5C, 0x7D, 0x4C, 0xD6, 0xCF, 0xDD, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x76, 0x26, 0xE0, 0x8B, 0x10, 0xD9, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA7, 0x23, 0x4E, 0x5F, 0xD2, 0x42, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xE5, 0xA4, 0xEC, 0x77, 0x21, 0x34, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x14, 0x65, 0xEA, 0x4A, 0x85, 0xC3, 0x2F), +}; +static const mbedtls_mpi_uint secp384r1_T_26_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xD8, 0x40, 0x27, 0x73, 0x15, 0x7E, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xBB, 0x53, 0x7E, 0x0F, 0x40, 0xC8, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x37, 0x19, 0x73, 0xEF, 0x5A, 0x5E, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x73, 0x2B, 0x49, 0x7E, 0xAC, 0x97, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xB2, 0xC3, 0x1E, 0x0E, 0xE7, 0xD2, 0x21), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x08, 0xD6, 0xDD, 0xAC, 0x21, 0xD6, 0x3E), +}; +static const mbedtls_mpi_uint secp384r1_T_26_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x26, 0xBE, 0x6D, 0x6D, 0xF2, 0x38, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6C, 0x31, 0xA7, 0x49, 0x50, 0x3A, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x99, 0xC6, 0xF5, 0xD2, 0xC2, 0x30, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE4, 0xF6, 0x8B, 0x8B, 0x97, 0xE9, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x21, 0xB7, 0x0D, 0xFC, 0x15, 0x54, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x83, 0x1C, 0xA4, 0xCD, 0x6B, 0x9D, 0xF2), +}; +static const mbedtls_mpi_uint secp384r1_T_27_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE8, 0x4C, 0x48, 0xE4, 0xAA, 0x69, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x7A, 0x27, 0xFC, 0x37, 0x96, 0x1A, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xE7, 0x30, 0xA5, 0xCF, 0x13, 0x46, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xD8, 0xAF, 0x74, 0x23, 0x4D, 0x56, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3D, 0x44, 0x14, 0x1B, 0x97, 0x83, 0xF0), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x47, 0xD7, 0x5F, 0xFD, 0x98, 0x38, 0xF7), +}; +static const mbedtls_mpi_uint secp384r1_T_27_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x73, 0x64, 0x36, 0xFD, 0x7B, 0xC1, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x5D, 0x32, 0xD2, 0x47, 0x94, 0x89, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xE9, 0x30, 0xAC, 0x06, 0xC8, 0x65, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x6C, 0xB9, 0x1B, 0xF7, 0x61, 0x49, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xFF, 0x32, 0x43, 0x80, 0xDA, 0xA6, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF8, 0x04, 0x01, 0x95, 0x35, 0xCE, 0x21), +}; +static const mbedtls_mpi_uint secp384r1_T_28_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x06, 0x46, 0x0D, 0x51, 0xE2, 0xD8, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x57, 0x1D, 0x6F, 0x79, 0xA0, 0xCD, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xFB, 0x36, 0xCA, 0xAD, 0xF5, 0x9E, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x7A, 0x1D, 0x9E, 0x1D, 0x95, 0x48, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x26, 0xA5, 0xB7, 0x15, 0x2C, 0xC2, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x42, 0x72, 0xAA, 0x11, 0xDC, 0xC9, 0xB6), +}; +static const mbedtls_mpi_uint secp384r1_T_28_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x6C, 0x64, 0xA7, 0x62, 0x3C, 0xAB, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x6A, 0x44, 0xD8, 0x60, 0xC0, 0xA8, 0x80), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x76, 0x58, 0x12, 0x57, 0x3C, 0x89, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x4F, 0x83, 0xCE, 0xCB, 0xB8, 0xD0, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0x04, 0xB0, 0xAD, 0xEB, 0xFA, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA4, 0xC3, 0x41, 0x44, 0x4E, 0x65, 0x3E), +}; +static const mbedtls_mpi_uint secp384r1_T_29_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x16, 0xA9, 0x1C, 0xE7, 0x65, 0x20, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x53, 0x32, 0xF8, 0xC0, 0xA6, 0xBD, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xF0, 0xE6, 0x57, 0x31, 0xCC, 0x26, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xE3, 0x54, 0x1C, 0x34, 0xD3, 0x17, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xAE, 0xED, 0xFB, 0xCD, 0xE7, 0x1E, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x16, 0x1C, 0x34, 0x40, 0x00, 0x1F, 0xB6), +}; +static const mbedtls_mpi_uint secp384r1_T_29_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x32, 0x00, 0xC2, 0xD4, 0x3B, 0x1A, 0x09), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xE0, 0x99, 0x8F, 0x0C, 0x4A, 0x16, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x73, 0x18, 0x1B, 0xD4, 0x94, 0x29, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA4, 0x2D, 0xB1, 0x9D, 0x74, 0x32, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0xF4, 0xB1, 0x0C, 0x37, 0x62, 0x8B, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xFF, 0xDA, 0xE2, 0x35, 0xA3, 0xB6, 0x42), +}; +static const mbedtls_mpi_uint secp384r1_T_30_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x49, 0x99, 0x65, 0xC5, 0xED, 0x16, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x42, 0x9A, 0xF3, 0xA7, 0x4E, 0x6F, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x0A, 0x7E, 0xC0, 0xD7, 0x4E, 0x07, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x7A, 0x31, 0x69, 0xA6, 0xB9, 0x15, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xE0, 0x72, 0xA4, 0x3F, 0xB9, 0xF8, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x75, 0x32, 0x85, 0xA2, 0xDE, 0x37, 0x12), +}; +static const mbedtls_mpi_uint secp384r1_T_30_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC0, 0x0D, 0xCF, 0x25, 0x41, 0xA4, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xFC, 0xB2, 0x48, 0xC3, 0x85, 0x83, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBE, 0x0B, 0x58, 0x2D, 0x7A, 0x9A, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xF3, 0x81, 0x18, 0x1B, 0x74, 0x4F, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x43, 0xA3, 0x0A, 0x16, 0x8B, 0xA3, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x18, 0x81, 0x7B, 0x8D, 0xA2, 0x35, 0x77), +}; +static const mbedtls_mpi_uint secp384r1_T_31_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xC4, 0x3F, 0x2C, 0xE7, 0x5F, 0x99, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2B, 0xB7, 0xB6, 0xAD, 0x5A, 0x56, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x00, 0xA4, 0x48, 0xC8, 0xE8, 0xBA, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xA1, 0xB5, 0x13, 0x5A, 0xCD, 0x99, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x95, 0xAD, 0xFC, 0xE2, 0x7E, 0xE7, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x6B, 0xD1, 0x34, 0x99, 0x53, 0x63, 0x0B), +}; +static const mbedtls_mpi_uint secp384r1_T_31_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x8A, 0x77, 0x5D, 0x2B, 0xAB, 0x01, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x85, 0xD0, 0xD5, 0x49, 0x83, 0x4D, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xC6, 0x91, 0x30, 0x3B, 0x00, 0xAF, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xAE, 0x61, 0x07, 0xE1, 0xB6, 0xE2, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x43, 0x41, 0xFE, 0x9B, 0xB6, 0xF0, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x97, 0xAE, 0xAD, 0x89, 0x88, 0x9E, 0x41), +}; +static const mbedtls_ecp_point secp384r1_T[32] = { + ECP_POINT_INIT_XY_Z1(secp384r1_T_0_X, secp384r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_1_X, secp384r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_2_X, secp384r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_3_X, secp384r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_4_X, secp384r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_5_X, secp384r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_6_X, secp384r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_7_X, secp384r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_8_X, secp384r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_9_X, secp384r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_10_X, secp384r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_11_X, secp384r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_12_X, secp384r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_13_X, secp384r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_14_X, secp384r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_15_X, secp384r1_T_15_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_16_X, secp384r1_T_16_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_17_X, secp384r1_T_17_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_18_X, secp384r1_T_18_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_19_X, secp384r1_T_19_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_20_X, secp384r1_T_20_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_21_X, secp384r1_T_21_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_22_X, secp384r1_T_22_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_23_X, secp384r1_T_23_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_24_X, secp384r1_T_24_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_25_X, secp384r1_T_25_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_26_X, secp384r1_T_26_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_27_X, secp384r1_T_27_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_28_X, secp384r1_T_28_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_29_X, secp384r1_T_29_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_30_X, secp384r1_T_30_Y), + ECP_POINT_INIT_XY_Z0(secp384r1_T_31_X, secp384r1_T_31_Y), +}; +#else +#define secp384r1_T NULL +#endif + +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static const mbedtls_mpi_uint secp521r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), +}; +static const mbedtls_mpi_uint secp521r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95), + MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), + MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), + MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01), +}; +static const mbedtls_mpi_uint secp521r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01), +}; +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp521r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xB1, 0x2D, 0xEB, 0x27, 0x2F, 0xE8, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x4B, 0x44, 0x25, 0xDB, 0x5C, 0x5F, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x85, 0x28, 0x78, 0x2E, 0x75, 0x34, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x57, 0x0F, 0x73, 0x78, 0x7A, 0xE3, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD8, 0xEC, 0xDC, 0xDA, 0x04, 0xAD, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x8A, 0x09, 0xF3, 0x58, 0x79, 0xD8, 0x29), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x03, 0xCB, 0x50, 0x1A, 0x7F, 0x56, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA6, 0x78, 0x38, 0x85, 0x67, 0x0B, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xD5, 0xD2, 0x22, 0xC4, 0x00, 0x3B, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x93, 0x0E, 0x7B, 0x85, 0x51, 0xC3, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA6, 0x5F, 0x54, 0x49, 0x02, 0x81, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xE9, 0x6B, 0x3A, 0x92, 0xE7, 0x72, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x5F, 0x28, 0x9E, 0x91, 0x27, 0x88, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x28, 0x31, 0xB3, 0x84, 0xCA, 0x12, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xF9, 0xAC, 0x22, 0x10, 0x0A, 0x64, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xC6, 0x33, 0x1F, 0x69, 0x19, 0x18, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x48, 0xB8, 0xC7, 0x37, 0x5A, 0x00, 0x36), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xCC, 0x32, 0xE0, 0xEE, 0x03, 0xC2, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x29, 0xC2, 0xE4, 0x6E, 0x24, 0x20, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x6B, 0x7F, 0x7B, 0xF9, 0xB0, 0xB8, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x7B, 0x3C, 0xE1, 0x19, 0xA1, 0x23, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE3, 0xC2, 0x53, 0xC0, 0x07, 0x13, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFE, 0x36, 0x35, 0x9F, 0x5E, 0x59, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x55, 0x89, 0x84, 0xBC, 0xEF, 0xA2, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x1A, 0x08, 0x67, 0xB4, 0xE7, 0x22, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x26, 0xDF, 0x81, 0x3C, 0x5F, 0x1C, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x4D, 0xD0, 0x0A, 0x48, 0x06, 0xF4, 0x48), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x18, 0x39, 0xF7, 0xD1, 0x20, 0x77, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x8F, 0x44, 0x13, 0xCB, 0x78, 0x11, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE2, 0x49, 0xEA, 0x43, 0x79, 0x08, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xD1, 0xD8, 0x73, 0x2C, 0x71, 0x2F, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE5, 0xE7, 0xF4, 0x46, 0xAB, 0x20, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x0B, 0xB9, 0x71, 0x1A, 0x27, 0xB7, 0xA7), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xA2, 0x2C, 0xD1, 0xDA, 0xBC, 0xC1, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xA3, 0x10, 0x1F, 0x90, 0xF2, 0xA5, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xFB, 0x20, 0xF4, 0xC0, 0x70, 0xC0, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xA7, 0x99, 0xF0, 0xA5, 0xD3, 0x09, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xE8, 0x14, 0x39, 0xBE, 0xCB, 0x60, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD6, 0x14, 0xA9, 0xC9, 0x20, 0xC3, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x5B, 0xFD, 0x2D, 0x96, 0xBC, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x04, 0x45, 0xBE, 0xCE, 0x75, 0x95, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xDA, 0x58, 0x49, 0x35, 0x09, 0x8D, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xF0, 0xC0, 0x36, 0xF2, 0xA6, 0x2D, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFC, 0x3D, 0xA8, 0xFB, 0x3C, 0xD2, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x4D, 0x71, 0x09, 0x18, 0x42, 0xF0, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xC1, 0xCE, 0x9E, 0x6A, 0x49, 0x60, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xB1, 0x00, 0xF7, 0xA1, 0x7A, 0x31, 0xB4), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xC3, 0x86, 0xCD, 0x20, 0x4A, 0x17, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xAB, 0x8B, 0x47, 0x8D, 0xAA, 0xA6, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x97, 0xF0, 0xBC, 0x2D, 0xDC, 0x9D, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x86, 0xB0, 0x74, 0xB2, 0xF4, 0xF6, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBD, 0xAC, 0xE3, 0x8F, 0x43, 0x5C, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xC3, 0xE2, 0x6E, 0x25, 0x49, 0xCD, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5E, 0x08, 0xB3, 0xB9, 0xAC, 0x5F, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xB7, 0xD1, 0xF4, 0xDC, 0x19, 0xE9, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xE4, 0xFA, 0xE1, 0x36, 0x3E, 0xED, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x67, 0x92, 0x84, 0x6E, 0x48, 0x03, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x95, 0xEF, 0x8F, 0xB2, 0x82, 0x6B, 0x1C), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFA, 0xB9, 0x55, 0x23, 0xFE, 0x09, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x79, 0x85, 0x4B, 0x0E, 0xD4, 0x35, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x27, 0x45, 0x81, 0xE0, 0x88, 0x52, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x63, 0xA2, 0x4B, 0xBC, 0x5D, 0xB1, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x8C, 0x83, 0xD9, 0x3E, 0xD3, 0x42, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x03, 0x3A, 0x31, 0xBA, 0xE9, 0x3A, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x10, 0xCD, 0x2D, 0x00, 0xFE, 0x32, 0xA7), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x6E, 0x1F, 0xDA, 0xF8, 0x6F, 0x4D, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x79, 0x7D, 0x09, 0xE5, 0xD3, 0x03, 0x21), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC3, 0xBE, 0xDF, 0x07, 0x65, 0x49, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x57, 0x33, 0xEF, 0xAE, 0x4F, 0x04, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xE9, 0x9B, 0xFE, 0xBF, 0xE6, 0x85, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xBA, 0xAA, 0x06, 0xC4, 0xC6, 0xB8, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x83, 0x01, 0xA9, 0xF6, 0x51, 0xE7, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xA6, 0x15, 0x8E, 0xAB, 0x1F, 0x10, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x08, 0x27, 0x1A, 0xA1, 0x21, 0xAD, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x09, 0x90, 0x6E, 0x50, 0x90, 0x9A, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x9A, 0xFE, 0xD7, 0xA1, 0xF5, 0xA2, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x7D, 0xE3, 0xDC, 0x21, 0xFB, 0xA4, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBF, 0x07, 0xFF, 0x45, 0xDF, 0x51, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x5C, 0x34, 0x02, 0x62, 0x9B, 0x08, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xCE, 0x9A, 0x6A, 0xEC, 0x75, 0xF6, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x59, 0xF4, 0x78, 0x3C, 0x60, 0xB1, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x37, 0x84, 0x6A, 0xDC, 0xF2, 0x9A, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9A, 0x9A, 0x15, 0x36, 0xE0, 0x2B, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x38, 0x9C, 0x50, 0x3D, 0x1E, 0x37, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x79, 0xF0, 0x92, 0xF2, 0x8B, 0x18, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE0, 0x82, 0x1E, 0x80, 0x82, 0x4B, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xBB, 0x59, 0x6B, 0x8A, 0x77, 0x41, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xF9, 0xD4, 0xB8, 0x4A, 0x82, 0xCF, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x8C, 0xC8, 0x9B, 0x72, 0x9E, 0xF7, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xCE, 0xE9, 0x77, 0x0A, 0x19, 0x59, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xA1, 0x41, 0x6A, 0x72, 0x4B, 0xB4, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x35, 0x43, 0xE2, 0x8C, 0xBE, 0x0D, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xEB, 0xAD, 0xF3, 0xA9, 0xA6, 0x68, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2F, 0xE2, 0x48, 0x0C, 0xDB, 0x1F, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x1E, 0x60, 0x9B, 0x2A, 0xD2, 0xC1, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x64, 0xB5, 0xD2, 0xF6, 0xF6, 0x6E, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x3D, 0x30, 0x78, 0x10, 0x18, 0x41, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x1D, 0x1C, 0xE0, 0x6D, 0x83, 0xD1, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x03, 0x0B, 0xF5, 0x2F, 0x6C, 0x04, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x3E, 0xD5, 0xFC, 0x31, 0x5B, 0x3A, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x82, 0x2F, 0xFB, 0xFE, 0xF8, 0x76, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x26, 0xDA, 0x9C, 0x36, 0xF5, 0x93, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xE7, 0x6E, 0xD2, 0x7D, 0x81, 0x09, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x03, 0xF9, 0x58, 0x48, 0x24, 0xA2, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x79, 0x0C, 0x8E, 0x6B, 0x95, 0xF3, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x10, 0x5C, 0x87, 0x03, 0x39, 0xCF, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xF0, 0xF7, 0xC1, 0x07, 0xA4, 0xF4, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE8, 0x02, 0x89, 0x65, 0xC4, 0x72, 0x36), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x88, 0xEA, 0x96, 0x67, 0x0B, 0x5D, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x75, 0x60, 0xA8, 0xBD, 0x74, 0xDF, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xE5, 0x71, 0x50, 0x67, 0xD0, 0xD2, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFC, 0xE5, 0xC7, 0x77, 0xB0, 0x7F, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x86, 0x69, 0xCD, 0x0D, 0x9A, 0xBD, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x17, 0xBC, 0xBB, 0x59, 0x85, 0x7D, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xA8, 0x76, 0xAC, 0x80, 0xA9, 0x72, 0xE0), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x78, 0xC1, 0xE2, 0x4D, 0xAF, 0xF9, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x97, 0x8E, 0x74, 0xC4, 0x4B, 0xB2, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD8, 0xF6, 0xF3, 0xAF, 0x2F, 0x52, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x57, 0xF4, 0xCE, 0xEE, 0x43, 0xED, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x46, 0x38, 0xDE, 0x20, 0xFD, 0x59, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x18, 0xE8, 0x58, 0xB9, 0x76, 0x2C, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x54, 0xE4, 0xFE, 0xC7, 0xBC, 0x31, 0x37), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF8, 0x89, 0xEE, 0x70, 0xB5, 0xB0, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x22, 0x26, 0x9A, 0x53, 0xB9, 0x38, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xA7, 0x19, 0x8C, 0x74, 0x7E, 0x88, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xDA, 0x0A, 0xE8, 0xDA, 0xA5, 0xBE, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x5C, 0xF7, 0xB1, 0x0C, 0x72, 0xFB, 0x09), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xE2, 0x23, 0xE7, 0x46, 0xB7, 0xE0, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x36, 0xBC, 0xBD, 0x48, 0x11, 0x8E, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xBB, 0xA1, 0xF7, 0x0B, 0x9E, 0xBF, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x28, 0xE1, 0xA2, 0x8F, 0xFC, 0xFC, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xFE, 0x19, 0x0A, 0xE5, 0xE7, 0x69, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xCD, 0x12, 0xF5, 0xBE, 0xD3, 0x04, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA8, 0x0D, 0x81, 0x59, 0xC4, 0x79, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xF3, 0x4B, 0x92, 0x65, 0xC3, 0x31, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xB5, 0x4F, 0x4D, 0x91, 0xD4, 0xE2, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x09, 0x41, 0x79, 0x1D, 0x4D, 0x0D, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x31, 0x18, 0xBA, 0xA0, 0xF2, 0x6E, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x5B, 0x4D, 0x4F, 0xAF, 0xC9, 0x8C, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x9C, 0x06, 0x68, 0xDE, 0xD8, 0x29), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x04, 0xE1, 0xB5, 0x9D, 0x00, 0xBC, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x95, 0x92, 0x8D, 0x72, 0xD3, 0x37, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x4B, 0x27, 0xA2, 0xE8, 0xA4, 0x26, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x45, 0x9C, 0xA9, 0xCB, 0x9F, 0xBA, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x7E, 0x1B, 0x64, 0xF4, 0xE8, 0xA5, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x20, 0xA9, 0xCA, 0xF3, 0x89, 0xE5, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xED, 0xFC, 0xAB, 0xD9, 0x0A, 0xB9, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x6F, 0x46, 0x7C, 0xCD, 0x78, 0xFF, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAB, 0x71, 0x5A, 0x94, 0xAB, 0x20, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x2E, 0xEE, 0x87, 0x57, 0x1F, 0xAD, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x4C, 0x3D, 0xFB, 0x7E, 0xA1, 0x8B, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xCF, 0x07, 0x86, 0xBA, 0x53, 0x37, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x26, 0xB2, 0xB9, 0xE2, 0x91, 0xE3, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xC9, 0x54, 0x84, 0x08, 0x3D, 0x0B, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xA8, 0x77, 0x2F, 0x64, 0x45, 0x99, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x96, 0x16, 0x1F, 0xDB, 0x96, 0x28, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x2B, 0x8D, 0xFF, 0xA2, 0x4F, 0x55, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xE6, 0x48, 0xBD, 0x99, 0x3D, 0x12, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x84, 0x59, 0xDA, 0xB9, 0xB6, 0x66, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x78, 0x41, 0x92, 0xDF, 0xF4, 0x3F, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x86, 0x6F, 0x4F, 0xBF, 0x67, 0xDF, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x2B, 0x1E, 0x5F, 0x00, 0xEA, 0xF6, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xB9, 0x6A, 0x89, 0xD8, 0xC0, 0xD7, 0xA7), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x9A, 0x32, 0x23, 0xA0, 0x02, 0x91, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x7F, 0x6A, 0x15, 0x64, 0x6A, 0x8B, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x57, 0x82, 0x58, 0xA9, 0x56, 0xB5, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x50, 0x92, 0x60, 0xCC, 0x81, 0x24, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x3D, 0xAD, 0xDA, 0xD9, 0x51, 0x3E, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xFE, 0x8F, 0xB0, 0x0B, 0xDE, 0x2E, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xD2, 0xBE, 0xEF, 0xAC, 0x76, 0x71, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xE8, 0x72, 0x0B, 0xAC, 0xFE, 0xCA, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0xC7, 0xFC, 0xE3, 0x3C, 0x7C, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x04, 0xA7, 0xB9, 0x9B, 0x93, 0xC0, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x48, 0x4B, 0x8E, 0x32, 0xC5, 0xF0, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x42, 0x07, 0xC1, 0xF2, 0xF1, 0x72, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x37, 0x54, 0x9C, 0x88, 0xD2, 0x62, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x19, 0x8A, 0x89, 0x58, 0xA2, 0x0F, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xCC, 0x4C, 0x97, 0x30, 0x66, 0x34, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x6A, 0x1E, 0x1F, 0xDB, 0xC9, 0x5E, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x4D, 0x49, 0xFF, 0x9B, 0x9C, 0xAC, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xE4, 0x4B, 0xF2, 0xD4, 0x1A, 0xD2, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xDA, 0xE8, 0x61, 0x9F, 0xC8, 0x49, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xCB, 0xF2, 0x2D, 0x85, 0xF6, 0x8D, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xC5, 0xCD, 0x2C, 0x79, 0xC6, 0x0E, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x1D, 0x55, 0x0F, 0xF8, 0x22, 0x9F, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x56, 0xBA, 0xE7, 0x57, 0x32, 0xEC, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x9A, 0xC6, 0x4C, 0x09, 0xC4, 0x52, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x1E, 0x6F, 0xF4, 0x7D, 0x27, 0xDD, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x11, 0x16, 0xEC, 0x79, 0x83, 0xAD, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x4E, 0x92, 0x1F, 0x19, 0x7D, 0x65, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xFF, 0x78, 0x15, 0x45, 0x63, 0x32, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x91, 0xD0, 0x78, 0x58, 0xDA, 0x50, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xDE, 0x40, 0xF6, 0x41, 0xB4, 0x3B, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x8D, 0xE0, 0xE1, 0xA9, 0xF0, 0x35, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xD4, 0xBA, 0x7B, 0xCC, 0x1B, 0x3A, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x5A, 0x2E, 0x74, 0x47, 0x14, 0xC3, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xF0, 0x8B, 0x06, 0x15, 0x8E, 0x0E, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xD2, 0xEB, 0x97, 0x50, 0x7D, 0x31, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x93, 0x4C, 0xDB, 0x97, 0x79, 0x44, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xA2, 0xA0, 0x0B, 0xC8, 0x3A, 0x8A, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x50, 0x92, 0x9E, 0x24, 0x1F, 0xCB, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x16, 0xC9, 0xC5, 0x3D, 0x5A, 0xAF, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xE3, 0x97, 0xE4, 0xA8, 0x50, 0xF6, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x57, 0x97, 0x42, 0x78, 0x92, 0x49, 0x0D), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEB, 0x62, 0x24, 0xFB, 0x8F, 0x32, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x0C, 0x36, 0x6E, 0x8F, 0xE8, 0xE8, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xD3, 0x7C, 0xC7, 0x8D, 0x3F, 0x5C, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x64, 0x6A, 0x73, 0x10, 0x79, 0xB8, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xF9, 0xEF, 0xA5, 0x20, 0x4A, 0x5C, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xF3, 0xF4, 0x49, 0x5B, 0x73, 0xAA, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xF2, 0xEA, 0x0F, 0x00, 0xAD, 0x53, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xB8, 0x66, 0xED, 0xC4, 0x2B, 0x4C, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x2F, 0xC1, 0x9A, 0x37, 0xD2, 0x7F, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xA7, 0x81, 0x38, 0x64, 0xC9, 0x37, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x3B, 0x6C, 0x9F, 0x5B, 0xD9, 0x8B, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x14, 0xD9, 0x08, 0xD8, 0xD2, 0x7E, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x71, 0xE6, 0x3D, 0xD1, 0xB0, 0xE7, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x81, 0x23, 0xEC, 0x2D, 0x42, 0x45, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x5B, 0x44, 0x6B, 0x89, 0x03, 0x67, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x27, 0xAE, 0x80, 0x5A, 0x33, 0xBE, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB6, 0x64, 0x1A, 0xDF, 0xD3, 0x85, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x8C, 0x22, 0xBA, 0xD0, 0xBD, 0xCC, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x3C, 0x01, 0x3A, 0xFF, 0x9D, 0xC7, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC7, 0x64, 0xB4, 0x59, 0x4E, 0x9F, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x34, 0x0A, 0x41, 0x94, 0xA8, 0xF2, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD4, 0xE4, 0xF0, 0x97, 0x45, 0x6D, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x1F, 0x4D, 0x6D, 0xFE, 0xA0, 0xC4, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x28, 0x5C, 0x40, 0xBB, 0x65, 0xD4, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xA8, 0x87, 0x35, 0x20, 0x3A, 0x89, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFD, 0x4F, 0xAB, 0x2D, 0xD1, 0xD0, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE8, 0x00, 0xFC, 0x69, 0x52, 0xF8, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x9A, 0x99, 0xE1, 0xDC, 0x9C, 0x3F, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x08, 0x98, 0xD9, 0xCA, 0x73, 0xD5, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x2C, 0xE0, 0xA7, 0x3E, 0x91, 0xD7, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x04, 0xB0, 0x54, 0x09, 0xF4, 0x72, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xEE, 0x28, 0xCC, 0xE8, 0x50, 0x78, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x91, 0x03, 0x76, 0xDB, 0x68, 0x24, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xE0, 0x56, 0xB2, 0x5D, 0x12, 0xD3, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x42, 0x59, 0x8B, 0xDF, 0x67, 0xB5, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xCC, 0xE5, 0x31, 0x53, 0x7A, 0x46, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_16_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8D, 0x59, 0xB5, 0x1B, 0x0F, 0xF4, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x2F, 0xD1, 0x2C, 0xE0, 0xD8, 0x04, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0xD7, 0xBA, 0xB0, 0xA3, 0x7E, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x08, 0x51, 0x56, 0xA6, 0x76, 0x67, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x17, 0x63, 0xFE, 0x56, 0xD0, 0xD9, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xF6, 0xC3, 0x14, 0x47, 0xC5, 0xA7, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x4C, 0x80, 0xF6, 0xA2, 0x57, 0xA7, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xB3, 0x7B, 0xF8, 0x2F, 0xE1, 0x3E, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_16_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0xF4, 0xF9, 0x6B, 0x7B, 0x90, 0xDF, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x82, 0xEF, 0x62, 0xA1, 0x4C, 0x53, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x99, 0x76, 0x01, 0xBA, 0x8D, 0x0F, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xF4, 0x58, 0x73, 0x56, 0xFE, 0xDD, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xCE, 0xF9, 0xE8, 0xA1, 0x34, 0xC3, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x5F, 0xDC, 0x6A, 0x3D, 0xD8, 0x7F, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xF4, 0x51, 0xB8, 0xB8, 0xC1, 0xD7, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x7D, 0x58, 0xD1, 0xD4, 0x1B, 0x4D, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_17_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x95, 0xDF, 0x00, 0xD8, 0x21, 0xDE, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x47, 0x3C, 0xC3, 0xB2, 0x01, 0x53, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x17, 0x43, 0x23, 0xBD, 0xCA, 0x71, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xBA, 0x0F, 0x4F, 0xDC, 0x41, 0x54, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x39, 0x26, 0x70, 0x53, 0x32, 0x18, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x46, 0x07, 0x97, 0x3A, 0x57, 0xE0, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x92, 0x4F, 0xCE, 0xDF, 0x25, 0x80, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x6F, 0x9A, 0x03, 0x05, 0x4B, 0xD1, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_17_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x01, 0x72, 0x30, 0x90, 0x17, 0x51, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xFB, 0x41, 0x65, 0x5C, 0xB4, 0x2D, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xCD, 0xCD, 0xAA, 0x41, 0xCC, 0xBB, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xCE, 0x08, 0x0A, 0x63, 0xE9, 0xA2, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xA8, 0x21, 0x7F, 0x7A, 0x5B, 0x9B, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x6B, 0x89, 0x44, 0x0A, 0x7F, 0x85, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0xDE, 0x7C, 0x19, 0x5C, 0x65, 0x26, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0xAC, 0x62, 0x29, 0x4A, 0xF1, 0xD0, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_18_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x00, 0x40, 0x87, 0xEB, 0xA9, 0x58, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x51, 0x0B, 0xFF, 0x56, 0x35, 0x51, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xAC, 0x08, 0x94, 0x71, 0xDA, 0xEC, 0x99), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x4D, 0xC5, 0x7B, 0x31, 0x8B, 0x8D, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x05, 0xF1, 0x3E, 0x9E, 0x8F, 0x17, 0x8F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x9C, 0x4B, 0x62, 0x94, 0xAD, 0x49, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xC9, 0xC6, 0x8F, 0xFD, 0x33, 0x44, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x96, 0x17, 0x7F, 0x42, 0xBE, 0xF7, 0x0D), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_18_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x29, 0x39, 0x13, 0x08, 0x8D, 0x91, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x79, 0xF9, 0x2F, 0xA9, 0x0A, 0xCF, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x87, 0x7A, 0xA3, 0x19, 0xAB, 0x55, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x0B, 0x01, 0xC5, 0x56, 0x19, 0x9D, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xDE, 0x82, 0x3B, 0xEA, 0xD3, 0x0B, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x6B, 0xC7, 0xF3, 0x0F, 0x82, 0x87, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x2E, 0x23, 0xF2, 0x39, 0x9D, 0x49, 0x70), + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0xDE, 0xAF, 0x7A, 0xEE, 0xB0, 0xDA, 0x70), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_19_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x4E, 0x2A, 0x50, 0xFD, 0x8E, 0xC0, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x0F, 0x7C, 0x76, 0x63, 0xD8, 0x89, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x2D, 0xB9, 0x4E, 0xF4, 0xEE, 0x85, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x95, 0x5C, 0x96, 0x5D, 0xAA, 0x59, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xDB, 0xD2, 0x68, 0x8E, 0x5A, 0x94, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x02, 0xBF, 0x77, 0x9F, 0xB9, 0x4C, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xDC, 0xC0, 0xCF, 0x81, 0x1E, 0xC4, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xCC, 0x37, 0x86, 0xDC, 0xE2, 0x64, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_19_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x30, 0xB1, 0x59, 0x20, 0x9D, 0x98, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x0C, 0x9D, 0xF8, 0x20, 0xDC, 0x90, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xA0, 0xF4, 0xE7, 0x3E, 0x9C, 0x9E, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x25, 0xA2, 0xB0, 0x54, 0xCD, 0x2E, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD9, 0x42, 0xB0, 0x80, 0xB0, 0xA3, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xFE, 0x9D, 0x8D, 0x40, 0xFF, 0x27, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x9D, 0xA6, 0x88, 0x3A, 0x8B, 0x6F, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x39, 0xEE, 0x1F, 0x3F, 0xB1, 0x4F, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_20_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xD7, 0x9E, 0xFF, 0xD2, 0x35, 0x67, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x4F, 0x15, 0x5D, 0xE3, 0xE8, 0x53, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xF7, 0x24, 0x98, 0xA2, 0xCB, 0x11, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x2E, 0x25, 0xE1, 0x94, 0xC5, 0xA3, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x82, 0x6E, 0xBA, 0xE7, 0x43, 0x25, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x65, 0xB4, 0x49, 0x73, 0x18, 0x35, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0x5B, 0xBC, 0x62, 0x86, 0x4C, 0xC1, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xF2, 0x95, 0xA2, 0xBB, 0xA2, 0x35, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_20_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x59, 0x62, 0xB0, 0x4B, 0x1E, 0xB4, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x55, 0xCE, 0xB0, 0x69, 0xBA, 0x63, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x69, 0x86, 0xDB, 0x34, 0x7D, 0x68, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x06, 0xCA, 0x55, 0x44, 0x36, 0x2B, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xD4, 0xC4, 0x3D, 0xCD, 0x9E, 0x69, 0xA4), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x44, 0xE4, 0xBF, 0x31, 0xE6, 0x40, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x4F, 0xFA, 0x75, 0xE3, 0xFB, 0x97, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xC0, 0xBD, 0x1C, 0x48, 0xB0, 0x26, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_21_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x7B, 0x32, 0xFA, 0xF2, 0x6D, 0x84, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x21, 0x03, 0x1D, 0x0D, 0x22, 0x55, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xF9, 0x42, 0x03, 0x9C, 0xC2, 0xCB, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xA1, 0x96, 0xD9, 0x9D, 0x11, 0x6F, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x40, 0x57, 0xEB, 0x40, 0x2D, 0xC0, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x96, 0xBB, 0x4F, 0x2F, 0x23, 0xA8, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x29, 0x85, 0x21, 0xA5, 0x50, 0x62, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x7D, 0x92, 0xCF, 0x87, 0x0C, 0x22, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_21_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x0E, 0xA5, 0x32, 0x5B, 0xDF, 0x9C, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x96, 0x37, 0x2C, 0x88, 0x35, 0x30, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xB4, 0x69, 0xFF, 0xEB, 0xC6, 0x94, 0x08), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x55, 0x60, 0xAD, 0xAA, 0x58, 0x14, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xFF, 0xF2, 0xB2, 0xD5, 0xA7, 0xD9, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xAE, 0x54, 0xD2, 0x60, 0x31, 0xF3, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x92, 0x83, 0xE3, 0xF1, 0x42, 0x83, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD2, 0xC8, 0xB7, 0x76, 0x45, 0x7F, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_22_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x11, 0xA4, 0xFB, 0x7A, 0x01, 0xBC, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x27, 0x73, 0x8D, 0x02, 0x91, 0x27, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x62, 0xF6, 0xDD, 0x6B, 0xFA, 0x5B, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xCA, 0xA2, 0x44, 0x2C, 0xF0, 0x28, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xF1, 0x7A, 0xA2, 0x42, 0x4C, 0x50, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x83, 0x3E, 0x50, 0xAB, 0x9C, 0xF7, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xED, 0x78, 0xCB, 0x76, 0x69, 0xDA, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x01, 0x1E, 0x43, 0x27, 0x47, 0x6E, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_22_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x4F, 0x54, 0xB9, 0x3E, 0xBD, 0xD5, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x40, 0x69, 0x7F, 0x74, 0x9D, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x06, 0x6F, 0x67, 0x68, 0x2B, 0x4D, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x65, 0x41, 0xFC, 0x7C, 0x1E, 0xE8, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x79, 0x37, 0xAF, 0xFD, 0xD2, 0xDA, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xA8, 0x69, 0x56, 0x62, 0xA4, 0xE4, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x71, 0x73, 0x21, 0x8A, 0x17, 0x81, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x55, 0x8F, 0x7B, 0xB8, 0xAF, 0xF7, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_23_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xD1, 0xBD, 0xBE, 0x8C, 0xBC, 0x60, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA6, 0x57, 0x8C, 0xAE, 0x5C, 0x19, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x43, 0xE4, 0xD9, 0xD8, 0x7B, 0xE7, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xB9, 0xE4, 0x85, 0x7C, 0x2E, 0xFC, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2E, 0x01, 0x2A, 0x6D, 0x56, 0xBE, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x0C, 0x25, 0x9B, 0xAE, 0x86, 0x37, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x22, 0xB3, 0xCB, 0x99, 0x66, 0xB7, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xF7, 0x90, 0xF0, 0x1B, 0x09, 0x27, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_23_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x16, 0x08, 0xEF, 0x39, 0x64, 0x49, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA0, 0xE3, 0x97, 0xA9, 0x07, 0x54, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xFF, 0xE2, 0x00, 0x07, 0x21, 0x88, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xFD, 0x59, 0x53, 0x05, 0x6C, 0x42, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xF7, 0x39, 0x5C, 0x82, 0x36, 0xE8, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x83, 0xA8, 0xE2, 0xA8, 0x43, 0x07, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xAF, 0x2B, 0x79, 0xED, 0xD8, 0x39, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x20, 0x91, 0x7A, 0xC4, 0x07, 0xEF, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_24_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x10, 0x2F, 0xAA, 0x0C, 0x94, 0x0E, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x81, 0x87, 0x41, 0x23, 0xEB, 0x55, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x53, 0xCC, 0x79, 0xB6, 0xEB, 0x6C, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x77, 0x73, 0x9D, 0xFC, 0x64, 0x6F, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x40, 0xE3, 0x6D, 0x1C, 0x16, 0x71, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xF4, 0x1B, 0xFF, 0x1C, 0x2F, 0xA5, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x0E, 0x0B, 0x11, 0xF4, 0x8D, 0x93, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xC5, 0x64, 0x6F, 0x24, 0x19, 0xF2, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_24_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xB3, 0xAF, 0xA5, 0x0E, 0x4F, 0x5E, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x77, 0xCA, 0xF2, 0x6D, 0xC5, 0xF6, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x18, 0x8E, 0x33, 0x68, 0x6C, 0xE8, 0xE0), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x8B, 0x80, 0x90, 0x19, 0x7F, 0x90, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x80, 0x6B, 0x68, 0xE2, 0x7D, 0xD4, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xC1, 0x67, 0xB3, 0x72, 0xCB, 0xBF, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xD5, 0xD3, 0x1D, 0x14, 0x58, 0x0A, 0x80), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x7A, 0x65, 0x98, 0xB3, 0x07, 0x4B, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_25_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x87, 0x0F, 0x5F, 0xCF, 0xA2, 0x01, 0x08), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xC9, 0xC8, 0x6E, 0x35, 0x87, 0xA5, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x3E, 0x91, 0xA0, 0xAB, 0x24, 0x1E, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xBC, 0x02, 0x35, 0x70, 0xC1, 0x5F, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x59, 0xA0, 0x50, 0x04, 0x80, 0x52, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x56, 0x6E, 0x42, 0x8F, 0x8C, 0x91, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xA2, 0xCB, 0xA5, 0xDE, 0x14, 0x24, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xCB, 0x74, 0x28, 0xE6, 0xA7, 0xE7, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_25_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x73, 0xA8, 0x8F, 0x9E, 0x0E, 0x63, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x1B, 0x77, 0xC7, 0xC1, 0x38, 0xF9, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x3C, 0xCF, 0xA8, 0x7A, 0xD7, 0xF3, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x5F, 0x9A, 0xC9, 0xAD, 0xE9, 0x1A, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0x2B, 0x5E, 0xD5, 0x81, 0x95, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x88, 0x75, 0x29, 0x1F, 0xC7, 0xC7, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA9, 0x5A, 0x4D, 0x63, 0x95, 0xF9, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xCD, 0x04, 0x8F, 0xCD, 0x91, 0xDE, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_26_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xD4, 0xFD, 0x25, 0x11, 0x99, 0x6E, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x83, 0x01, 0x3D, 0xFB, 0x56, 0xA5, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x3A, 0xDC, 0x74, 0xC2, 0xD7, 0xCF, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0xBD, 0xF1, 0xDD, 0xA3, 0x07, 0x03, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xBE, 0xE9, 0x2E, 0x58, 0x84, 0x66, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x20, 0x78, 0x37, 0x79, 0x0B, 0xA6, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xF2, 0xAC, 0x65, 0xC8, 0xC9, 0x2F, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x93, 0xE5, 0x0D, 0x0C, 0xC6, 0xB8, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_26_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xAD, 0x5C, 0x19, 0x12, 0x61, 0x0E, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x4F, 0x0B, 0x1F, 0x49, 0x7E, 0xCD, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2E, 0x30, 0x61, 0xDB, 0x08, 0x68, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x78, 0xAF, 0xB3, 0x08, 0xC1, 0x69, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x5F, 0x5D, 0xC1, 0x57, 0x6F, 0xD8, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xD3, 0x6A, 0xF7, 0xFD, 0x86, 0xE5, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x63, 0xBD, 0x70, 0x7B, 0x47, 0xE8, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x62, 0xC8, 0x7E, 0x9D, 0x11, 0x2B, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_27_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x84, 0xFD, 0xD5, 0x9A, 0x56, 0x7F, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBB, 0xA4, 0x6F, 0x12, 0x6E, 0x4D, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x08, 0xA1, 0x82, 0x9C, 0x62, 0x74, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x22, 0x05, 0x1D, 0x15, 0x35, 0x79), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x88, 0xCF, 0x5C, 0x05, 0x78, 0xFB, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x6B, 0x2F, 0x79, 0x09, 0x73, 0x67, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA0, 0x80, 0xD8, 0xE8, 0xEC, 0xFB, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xE7, 0x0B, 0xB7, 0x81, 0x48, 0x7B, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_27_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x53, 0xA9, 0xED, 0x61, 0x92, 0xD7, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x49, 0xD9, 0x5D, 0x9B, 0x4E, 0x89, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x12, 0xEB, 0x9A, 0xC9, 0xCB, 0xC1, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xDC, 0x95, 0x16, 0xFE, 0x29, 0x70, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x33, 0xB1, 0xD6, 0x78, 0xB9, 0xE2, 0x36), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xCE, 0x88, 0xC3, 0xFD, 0x7A, 0x6B, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x1E, 0x50, 0x1E, 0xAF, 0xB1, 0x25, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xE7, 0xD7, 0xD5, 0xBD, 0x7A, 0x12, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_28_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xAA, 0xA2, 0x80, 0x5D, 0x8F, 0xCD, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x39, 0x79, 0x64, 0xA1, 0x67, 0x3C, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xC7, 0x49, 0xFF, 0x7F, 0xAC, 0xAB, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x54, 0x3E, 0x83, 0xF0, 0x3D, 0xBC, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x92, 0x4A, 0x38, 0x42, 0x8A, 0xAB, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x0B, 0x4F, 0xEE, 0x9E, 0x92, 0xA5, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xDD, 0x19, 0x96, 0xF2, 0xF0, 0x6B, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xFC, 0xDD, 0xB2, 0x8A, 0xE5, 0x4C, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_28_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x06, 0x49, 0xAC, 0x99, 0x7E, 0xF8, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xC8, 0x01, 0x51, 0xEA, 0xF6, 0x52, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x89, 0x66, 0x2B, 0x1F, 0x9B, 0x2A, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x0F, 0x95, 0x07, 0x2B, 0x6C, 0x6E, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0xC3, 0xB4, 0xBB, 0x91, 0x1F, 0xA3, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x6E, 0x54, 0x28, 0x7B, 0x9C, 0x79, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x45, 0xFF, 0xA6, 0xDA, 0xA2, 0x83, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xDE, 0x8F, 0x17, 0x37, 0x82, 0xCB, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_29_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x94, 0x3F, 0x26, 0xC9, 0x1D, 0xD9, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x97, 0x28, 0x20, 0xCD, 0xC1, 0xF3, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC9, 0xB5, 0x60, 0x9B, 0x1E, 0xDC, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xB9, 0x5B, 0x7D, 0xA0, 0xB2, 0x8C, 0xF0), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xD1, 0x42, 0xE6, 0x39, 0x33, 0x6D, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xC0, 0xFC, 0xD2, 0x14, 0x5D, 0x3E, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x4A, 0x3E, 0x40, 0x16, 0x93, 0x15, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x24, 0xC1, 0x27, 0x27, 0xE5, 0x4B, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_29_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x50, 0xD8, 0xBC, 0xC1, 0x46, 0x22, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x0E, 0x60, 0xA1, 0xB3, 0x50, 0xD4, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xB1, 0x26, 0xB6, 0x6D, 0x47, 0x5A, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0xAC, 0x11, 0x35, 0x3E, 0xB9, 0xF4, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x97, 0xFA, 0xBB, 0x6B, 0x39, 0x13, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x34, 0x12, 0x75, 0x8E, 0x9B, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x9E, 0xCD, 0x29, 0xB6, 0xEF, 0x8D, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xAC, 0xE9, 0x25, 0x27, 0xBB, 0x78, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_30_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x7A, 0xA8, 0xD3, 0xE3, 0x66, 0xE5, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x4C, 0xC4, 0x2C, 0x76, 0x81, 0x50, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x71, 0x08, 0xB8, 0x52, 0x7C, 0xAF, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x59, 0x24, 0xDD, 0xFB, 0x2F, 0xD0, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCD, 0x56, 0xE9, 0xAC, 0x91, 0xE6, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x64, 0x20, 0xC6, 0x9F, 0xE4, 0xEF, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x2C, 0x8F, 0x8C, 0x97, 0xF6, 0x22, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xF4, 0x88, 0xAA, 0xA8, 0xD7, 0xA5, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_30_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x6C, 0xAE, 0x83, 0xB1, 0x55, 0x55, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x67, 0x84, 0x47, 0x7C, 0x83, 0x5C, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x10, 0x4D, 0xDD, 0x30, 0x60, 0xB0, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xA7, 0x36, 0x76, 0x24, 0x32, 0x9F, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x42, 0x81, 0xFB, 0xA4, 0x2E, 0x13, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x94, 0x91, 0xFF, 0x99, 0xA0, 0x09, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x83, 0xA1, 0x76, 0xAF, 0x37, 0x5C, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA8, 0x04, 0x86, 0xC4, 0xA9, 0x79, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_31_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x8C, 0xC2, 0x34, 0xFB, 0x83, 0x28, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x03, 0x7D, 0x5E, 0x9E, 0x0E, 0xB0, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x02, 0x46, 0x7F, 0xB9, 0xAC, 0xBB, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xED, 0x48, 0xC2, 0x96, 0x4D, 0x56, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xC5, 0xD1, 0xE6, 0x1C, 0x7E, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x2E, 0x18, 0x71, 0x2D, 0x7B, 0xD7, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x46, 0x9D, 0xDE, 0xAA, 0x78, 0x8E, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD7, 0x69, 0x2E, 0xE1, 0xD9, 0x48, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp521r1_T_31_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFF, 0x9E, 0x09, 0x22, 0x22, 0xE6, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x14, 0x28, 0x13, 0x1B, 0x62, 0x12, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x7F, 0x67, 0x03, 0xB0, 0xC0, 0xF3, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xC3, 0x0F, 0xFB, 0x25, 0x48, 0x3E, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x6E, 0x53, 0x98, 0x36, 0xB3, 0xD3, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x81, 0x54, 0x22, 0xA4, 0xCC, 0xC1, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xBA, 0xFC, 0xA9, 0xDF, 0x68, 0x86, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x92, 0x0E, 0xC3, 0xF2, 0x58, 0xE8, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_ecp_point secp521r1_T[32] = { + ECP_POINT_INIT_XY_Z1(secp521r1_T_0_X, secp521r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_1_X, secp521r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_2_X, secp521r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_3_X, secp521r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_4_X, secp521r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_5_X, secp521r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_6_X, secp521r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_7_X, secp521r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_8_X, secp521r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_9_X, secp521r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_10_X, secp521r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_11_X, secp521r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_12_X, secp521r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_13_X, secp521r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_14_X, secp521r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_15_X, secp521r1_T_15_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_16_X, secp521r1_T_16_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_17_X, secp521r1_T_17_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_18_X, secp521r1_T_18_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_19_X, secp521r1_T_19_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_20_X, secp521r1_T_20_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_21_X, secp521r1_T_21_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_22_X, secp521r1_T_22_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_23_X, secp521r1_T_23_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_24_X, secp521r1_T_24_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_25_X, secp521r1_T_25_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_26_X, secp521r1_T_26_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_27_X, secp521r1_T_27_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_28_X, secp521r1_T_28_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_29_X, secp521r1_T_29_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_30_X, secp521r1_T_30_Y), + ECP_POINT_INIT_XY_Z0(secp521r1_T_31_X, secp521r1_T_31_Y), +}; +#else +#define secp521r1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static const mbedtls_mpi_uint secp192k1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp192k1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), +}; +static const mbedtls_mpi_uint secp192k1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00), +}; +static const mbedtls_mpi_uint secp192k1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), +}; +static const mbedtls_mpi_uint secp192k1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), +}; +static const mbedtls_mpi_uint secp192k1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp192k1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB), +}; +static const mbedtls_mpi_uint secp192k1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B), +}; +static const mbedtls_mpi_uint secp192k1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x77, 0x3D, 0x0D, 0x85, 0x48, 0xA8, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x07, 0xDF, 0x1D, 0xB3, 0xB3, 0x01, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x86, 0xF6, 0xAF, 0x19, 0x2A, 0x88, 0x2E), +}; +static const mbedtls_mpi_uint secp192k1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x90, 0xB6, 0x2F, 0x48, 0x36, 0x4C, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x11, 0x14, 0xA6, 0xCB, 0xBA, 0x15, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB0, 0xF2, 0xD4, 0xC9, 0xDA, 0xBA, 0xD7), +}; +static const mbedtls_mpi_uint secp192k1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xC1, 0x9C, 0xE6, 0xBB, 0xFB, 0xCF, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x19, 0xAC, 0x5A, 0xC9, 0x8A, 0x1C, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xF6, 0x76, 0x86, 0x89, 0x27, 0x8D, 0x28), +}; +static const mbedtls_mpi_uint secp192k1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xE0, 0x6F, 0x34, 0xBA, 0x5E, 0xD3, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xDC, 0xA6, 0x87, 0xC9, 0x9D, 0xC0, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x11, 0x7E, 0xD6, 0xF7, 0x33, 0xFC, 0xE4), +}; +static const mbedtls_mpi_uint secp192k1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x37, 0x3E, 0xC0, 0x7F, 0x62, 0xE7, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3B, 0x69, 0x9D, 0x44, 0xBC, 0x82, 0x99), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x84, 0xB3, 0x5F, 0x2B, 0xA5, 0x9E, 0x2C), +}; +static const mbedtls_mpi_uint secp192k1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x95, 0xEB, 0x4C, 0x04, 0xB4, 0xF4, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xAD, 0x4B, 0xD5, 0x9A, 0xEB, 0xC4, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xB1, 0xC5, 0x59, 0xE3, 0xD5, 0x16, 0x2A), +}; +static const mbedtls_mpi_uint secp192k1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x2A, 0xCC, 0xAC, 0xD0, 0xEE, 0x50, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x83, 0xE0, 0x5B, 0x14, 0x44, 0x52, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x15, 0x2D, 0x78, 0xF6, 0x51, 0x32, 0xCF), +}; +static const mbedtls_mpi_uint secp192k1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x36, 0x9B, 0xDD, 0xF8, 0xDD, 0xEF, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xB1, 0x6A, 0x2B, 0xAF, 0xEB, 0x2B, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x87, 0x7A, 0x66, 0x5D, 0x5B, 0xDF, 0x8F), +}; +static const mbedtls_mpi_uint secp192k1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x45, 0xE5, 0x81, 0x9B, 0xEB, 0x37, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x29, 0xE2, 0x20, 0x64, 0x23, 0x6B, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x1D, 0x41, 0xE1, 0x9B, 0x61, 0x7B, 0xD9), +}; +static const mbedtls_mpi_uint secp192k1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x57, 0xA3, 0x0A, 0x13, 0xE4, 0x59, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x6E, 0x4A, 0x48, 0x84, 0x90, 0xAC, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB8, 0xF5, 0xF3, 0xDE, 0xA0, 0xA1, 0x1D), +}; +static const mbedtls_mpi_uint secp192k1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x32, 0x81, 0xA9, 0x91, 0x5A, 0x4E, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xA8, 0x90, 0xBE, 0x0F, 0xEC, 0xC0, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x30, 0xD7, 0x08, 0xAE, 0xC4, 0x3A, 0xA5), +}; +static const mbedtls_mpi_uint secp192k1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x55, 0xE3, 0x76, 0xB3, 0x64, 0x74, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x75, 0xD4, 0xDB, 0x98, 0xD7, 0x39, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xEB, 0x8A, 0xAB, 0x16, 0xD9, 0xD4, 0x0B), +}; +static const mbedtls_mpi_uint secp192k1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xBE, 0xF9, 0xC7, 0xC7, 0xBA, 0xF3, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x85, 0x59, 0xF3, 0x60, 0x41, 0x02, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x1C, 0x4A, 0xA4, 0xC7, 0xED, 0x66, 0xBC), +}; +static const mbedtls_mpi_uint secp192k1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x2E, 0x46, 0x52, 0x18, 0x87, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x35, 0x5A, 0x75, 0xAC, 0x4D, 0x75, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x2F, 0xAC, 0xFC, 0xBC, 0xE6, 0x93, 0x5E), +}; +static const mbedtls_mpi_uint secp192k1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x4D, 0xC9, 0x18, 0xE9, 0x00, 0xEB, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x69, 0x72, 0x07, 0x5A, 0x59, 0xA8, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x65, 0x83, 0x20, 0x10, 0xF9, 0x69, 0x82), +}; +static const mbedtls_mpi_uint secp192k1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x56, 0x7F, 0x9F, 0xBF, 0x46, 0x0C, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xCF, 0xF0, 0xDC, 0xDF, 0x2D, 0xE6, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xF0, 0x72, 0x3A, 0x7A, 0x03, 0xE5, 0x22), +}; +static const mbedtls_mpi_uint secp192k1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xAA, 0x57, 0x13, 0x37, 0xA7, 0x2C, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xAC, 0xA2, 0x23, 0xF9, 0x84, 0x60, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xEB, 0x51, 0x70, 0x64, 0x78, 0xCA, 0x05), +}; +static const mbedtls_mpi_uint secp192k1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xCC, 0x30, 0x62, 0x93, 0x46, 0x13, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x26, 0xCC, 0x6C, 0x3D, 0x5C, 0xDA, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xAA, 0xB8, 0x03, 0xA4, 0x1A, 0x00, 0x96), +}; +static const mbedtls_mpi_uint secp192k1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x9D, 0xE6, 0xCC, 0x4E, 0x2E, 0xC2, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xC3, 0x8A, 0xAE, 0x6F, 0x40, 0x05, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x8F, 0x4A, 0x4D, 0x35, 0xD3, 0x50, 0x9D), +}; +static const mbedtls_mpi_uint secp192k1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xFD, 0x98, 0xAB, 0xC7, 0x03, 0xB4, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x40, 0xD2, 0x9F, 0xCA, 0xD0, 0x53, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x84, 0x00, 0x6F, 0xC8, 0xAD, 0xED, 0x8D), +}; +static const mbedtls_mpi_uint secp192k1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xD3, 0x57, 0xD7, 0xC3, 0x07, 0xBD, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xBA, 0x47, 0x1D, 0x3D, 0xEF, 0x98, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC0, 0x6C, 0x7F, 0x12, 0xEE, 0x9F, 0x67), +}; +static const mbedtls_mpi_uint secp192k1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x02, 0xDA, 0x79, 0xAA, 0xC9, 0x27, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x79, 0xC7, 0x71, 0x84, 0xCB, 0xE5, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x37, 0x06, 0xBA, 0xB5, 0xD5, 0x18, 0x4C), +}; +static const mbedtls_mpi_uint secp192k1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x65, 0x72, 0x6C, 0xF2, 0x63, 0x27, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0xBC, 0x71, 0xDF, 0x75, 0xF8, 0x98, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x70, 0x9B, 0xDC, 0xE7, 0x18, 0x71, 0xFF), +}; +static const mbedtls_mpi_uint secp192k1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x5B, 0x9F, 0x00, 0x5A, 0xB6, 0x80, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xE0, 0xBB, 0xFC, 0x5E, 0x78, 0x9C, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x03, 0x68, 0x83, 0x3D, 0x2E, 0x4C, 0xDD), +}; +static const mbedtls_mpi_uint secp192k1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x49, 0x23, 0xA8, 0xCB, 0x3B, 0x1A, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x3D, 0xA7, 0x46, 0xCF, 0x75, 0xB6, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0xFD, 0x30, 0x01, 0xB6, 0xEF, 0xF9, 0xE8), +}; +static const mbedtls_mpi_uint secp192k1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xFA, 0xDA, 0xB8, 0x29, 0x42, 0xC9, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xD7, 0xA0, 0xE6, 0x6B, 0x86, 0x61, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0xE9, 0xD3, 0x37, 0xD8, 0xE7, 0x35, 0xA9), +}; +static const mbedtls_mpi_uint secp192k1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC8, 0x8E, 0xB1, 0xCB, 0xB1, 0xB5, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xD7, 0x46, 0x7D, 0xAF, 0xE2, 0xDC, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x46, 0xE7, 0xD8, 0x76, 0x31, 0x90, 0x76), +}; +static const mbedtls_mpi_uint secp192k1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD3, 0xF4, 0x74, 0xE1, 0x67, 0xD8, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x70, 0x3C, 0xC8, 0xAF, 0x5F, 0xF4, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x4E, 0xED, 0x5C, 0x43, 0xB3, 0x16, 0x35), +}; +static const mbedtls_mpi_uint secp192k1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAE, 0xD1, 0xDD, 0x31, 0x14, 0xD3, 0xF0), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x14, 0x06, 0x13, 0x12, 0x1C, 0x81, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xF9, 0x0C, 0x91, 0xF7, 0x67, 0x59, 0x63), +}; +static const mbedtls_mpi_uint secp192k1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x91, 0xE2, 0xF4, 0x9D, 0xEB, 0x88, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x82, 0x30, 0x9C, 0xAE, 0x18, 0x4D, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x79, 0xCF, 0x17, 0xA5, 0x1E, 0xE8, 0xC8), +}; +static const mbedtls_ecp_point secp192k1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp192k1_T_0_X, secp192k1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_1_X, secp192k1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_2_X, secp192k1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_3_X, secp192k1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_4_X, secp192k1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_5_X, secp192k1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_6_X, secp192k1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_7_X, secp192k1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_8_X, secp192k1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_9_X, secp192k1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_10_X, secp192k1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_11_X, secp192k1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_12_X, secp192k1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_13_X, secp192k1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_14_X, secp192k1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp192k1_T_15_X, secp192k1_T_15_Y), +}; +#else +#define secp192k1_T NULL +#endif + +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static const mbedtls_mpi_uint secp224k1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp224k1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1), +}; +static const mbedtls_mpi_uint secp224k1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E), +}; +static const mbedtls_mpi_uint secp224k1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp224k1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x5B, 0x45, 0xA1, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x9F, 0x08, 0x7E, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x6C, 0x22, 0x22, 0x40, 0x89, 0xAE, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x92, 0xE1, 0x87, 0x56, 0x35, 0xAF, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xAF, 0x08, 0x35, 0x27, 0xEA, 0x04, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x53, 0xFD, 0xCF, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0xD0, 0x9F, 0x8D, 0xF3, 0x63, 0x54, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xDB, 0x0F, 0x61, 0x54, 0x26, 0xD1, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x21, 0xF7, 0x1B, 0xB5, 0x1D, 0xF6, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x05, 0xDA, 0x8F, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x26, 0x73, 0xBC, 0xE4, 0x29, 0x62, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x95, 0x17, 0x8B, 0xC3, 0x9B, 0xAC, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xDB, 0x77, 0xDF, 0xDD, 0x13, 0x04, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0xFC, 0x22, 0x93, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0xF1, 0x5A, 0x37, 0xEF, 0x79, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x01, 0x37, 0xAC, 0x9A, 0x5B, 0x51, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x75, 0x13, 0xA9, 0x4A, 0xAD, 0xFE, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x82, 0x6F, 0x66, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x5E, 0xF0, 0x40, 0xC3, 0xA6, 0xE2, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x9A, 0x6F, 0xCF, 0x11, 0x26, 0x66, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0x73, 0xA8, 0xCF, 0x2B, 0x12, 0x36, 0x37), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xB3, 0x0A, 0x58, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x79, 0x00, 0x55, 0x04, 0x34, 0x90, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x54, 0x1C, 0xC2, 0x45, 0x0C, 0x1B, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x19, 0xAB, 0xA8, 0xFC, 0x73, 0xDC, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xFB, 0x93, 0xCE, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x75, 0xD0, 0x66, 0x95, 0x86, 0xCA, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xEA, 0x29, 0x16, 0x6A, 0x38, 0xDF, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xA2, 0x36, 0x2F, 0xDC, 0xBB, 0x5E, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x89, 0x59, 0x49, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xA3, 0x99, 0x9D, 0xB8, 0x77, 0x9D, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x93, 0x43, 0x47, 0xC6, 0x5C, 0xF9, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x00, 0x79, 0x42, 0x64, 0xB8, 0x25, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x54, 0xB4, 0x33, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x0C, 0x42, 0x90, 0x83, 0x0B, 0x31, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x2E, 0xAE, 0xC8, 0xC7, 0x5F, 0xD2, 0x70), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xBC, 0xAD, 0x41, 0xE7, 0x32, 0x3A, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x97, 0x52, 0x83, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x13, 0x7A, 0xBD, 0xAE, 0x94, 0x60, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x9B, 0x95, 0xB4, 0x6E, 0x68, 0xB2, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x49, 0xBE, 0x51, 0xFE, 0x66, 0x15, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x37, 0xE4, 0xFE, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x9B, 0xEE, 0x64, 0xC9, 0x1B, 0xBD, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x5F, 0x34, 0xA9, 0x0B, 0xB7, 0x25, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0x13, 0xB1, 0x38, 0xFB, 0x9D, 0x78, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xE7, 0x1B, 0xFA, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xB3, 0xB7, 0x44, 0x92, 0x6B, 0x00, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x82, 0x44, 0x3E, 0x18, 0x1A, 0x58, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0xF8, 0xC0, 0xE4, 0xEE, 0xC1, 0xBF, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x32, 0x27, 0xB2, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x9A, 0x42, 0x62, 0x8B, 0x26, 0x54, 0x21), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x85, 0x74, 0xA0, 0x79, 0xA8, 0xEE, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x36, 0x60, 0xB3, 0x28, 0x4D, 0x55, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x27, 0x82, 0x29, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xFC, 0x73, 0x77, 0xAF, 0x5C, 0xAC, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xED, 0xE5, 0xF6, 0x1D, 0xA8, 0x67, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xDE, 0x33, 0x1C, 0xF1, 0x80, 0x73, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xE2, 0xDE, 0x3C, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x3E, 0x6B, 0xFE, 0xF0, 0x04, 0x28, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xB2, 0x14, 0x9D, 0x18, 0x11, 0x7D, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC4, 0xD6, 0x2E, 0x6E, 0x57, 0x4D, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x55, 0x1B, 0xDE, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xF7, 0x17, 0xBC, 0x45, 0xAB, 0x16, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xB0, 0xEF, 0x61, 0xE3, 0x20, 0x7C, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x85, 0x41, 0x4D, 0xF1, 0x7E, 0x4D, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC2, 0x9B, 0x5E, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x2E, 0x49, 0x3D, 0x3E, 0x4B, 0xD3, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x2B, 0x9D, 0xD5, 0x27, 0xFA, 0xCA, 0xE0), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0xB3, 0x6A, 0xE0, 0x79, 0x14, 0x28, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x1E, 0xDC, 0xF5, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x44, 0x56, 0xCD, 0xFC, 0x9F, 0x09, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x8C, 0x59, 0xA4, 0x64, 0x2A, 0x3A, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xA0, 0xB5, 0x86, 0x4E, 0x69, 0xDA, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x8B, 0x11, 0x38, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x17, 0x16, 0x12, 0x17, 0xDC, 0x00, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x76, 0x24, 0x6C, 0x97, 0x2C, 0xB5, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x71, 0xE3, 0xB0, 0xBB, 0x4E, 0x50, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0x48, 0x26, 0xD5, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x5F, 0x28, 0xF6, 0x01, 0x5A, 0x60, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x95, 0xFE, 0xD0, 0xAD, 0x15, 0xD4, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x5B, 0x7A, 0xFD, 0x80, 0xF7, 0x9F, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xBC, 0x1B, 0xDF, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xE6, 0xDF, 0x14, 0x29, 0xF4, 0xD4, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x12, 0xDD, 0xEC, 0x5B, 0x8A, 0x59, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x92, 0x3E, 0x35, 0x08, 0xE9, 0xCF, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0x35, 0x29, 0x97, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xDB, 0xD6, 0x6A, 0xC5, 0x43, 0xA4, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x33, 0x50, 0x61, 0x70, 0xA1, 0xE9, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x15, 0x6E, 0x5F, 0x01, 0x0C, 0x8C, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xA1, 0x9A, 0x9D, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xC6, 0xF7, 0xE2, 0x4A, 0xCD, 0x9B, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x4D, 0x5A, 0xB8, 0xE2, 0x6D, 0xA6, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x3F, 0xB6, 0x17, 0xE3, 0x2C, 0x6F, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xA4, 0x59, 0x51, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x4F, 0x7C, 0x49, 0xCD, 0x6E, 0xEB, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xC9, 0x1F, 0xB7, 0x4D, 0x98, 0xC7, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0x4C, 0xFD, 0x98, 0x20, 0x95, 0xBB, 0x20, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xF2, 0x73, 0x92, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xEF, 0xFB, 0x30, 0xFA, 0x12, 0x1A, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x4C, 0x24, 0xB4, 0x5B, 0xC9, 0x4C, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xDD, 0x5E, 0x84, 0x95, 0x4D, 0x26, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xFA, 0xF9, 0x3A, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0xA3, 0x2E, 0x7A, 0xDC, 0xA7, 0x53, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x9F, 0x81, 0x84, 0xB2, 0x0D, 0xFE, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x89, 0x1B, 0x77, 0x0C, 0x89, 0x71, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0x7F, 0xB2, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xE9, 0x2C, 0x79, 0xA6, 0x3C, 0xAD, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xE0, 0x23, 0x02, 0x86, 0x0F, 0x77, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x93, 0x6D, 0xE9, 0xF9, 0x3C, 0xBE, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xE7, 0x24, 0x92, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x3C, 0x5B, 0x4B, 0x1B, 0x25, 0x37, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xE8, 0x38, 0x1B, 0xA1, 0x5A, 0x2E, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x19, 0xFD, 0xF4, 0x78, 0x01, 0x6B, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0x69, 0x37, 0x4F, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xE2, 0xBF, 0xD3, 0xEC, 0x95, 0x9C, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x7B, 0xFC, 0xD5, 0xD3, 0x25, 0x5E, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x55, 0x09, 0xA2, 0x58, 0x6A, 0xC9, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xCC, 0x3B, 0xD9, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_mpi_uint secp224k1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x08, 0x65, 0x5E, 0xCB, 0xAB, 0x48, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x79, 0x8B, 0xC0, 0x11, 0xC0, 0x69, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xE8, 0x8C, 0x4C, 0xC5, 0x28, 0xE4, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x1F, 0x34, 0x5C, 0x00, 0x00, 0x00, 0x00), +}; +static const mbedtls_ecp_point secp224k1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp224k1_T_0_X, secp224k1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_1_X, secp224k1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_2_X, secp224k1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_3_X, secp224k1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_4_X, secp224k1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_5_X, secp224k1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_6_X, secp224k1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_7_X, secp224k1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_8_X, secp224k1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_9_X, secp224k1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_10_X, secp224k1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_11_X, secp224k1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_12_X, secp224k1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_13_X, secp224k1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_14_X, secp224k1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp224k1_T_15_X, secp224k1_T_15_Y), +}; +#else +#define secp224k1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static const mbedtls_mpi_uint secp256k1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; +static const mbedtls_mpi_uint secp256k1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00), +}; +static const mbedtls_mpi_uint secp256k1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00), +}; +static const mbedtls_mpi_uint secp256k1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), +}; +static const mbedtls_mpi_uint secp256k1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), +}; +static const mbedtls_mpi_uint secp256k1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint secp256k1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79), +}; +static const mbedtls_mpi_uint secp256k1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48), +}; +static const mbedtls_mpi_uint secp256k1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xEE, 0xD7, 0x1E, 0x67, 0x86, 0x32, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0xB1, 0xA9, 0xD5, 0xCC, 0x27, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x0E, 0x11, 0x01, 0x71, 0xFE, 0x92, 0x73), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x28, 0x63, 0x6D, 0x72, 0x09, 0xA6, 0xC0), +}; +static const mbedtls_mpi_uint secp256k1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0x69, 0xDC, 0x3E, 0x2C, 0x75, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xB7, 0x3F, 0x30, 0x26, 0x3C, 0xDF, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xBE, 0xB9, 0x5D, 0x0E, 0xE8, 0x5E, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0xC3, 0x05, 0xD6, 0xB7, 0xD5, 0x24, 0xFC), +}; +static const mbedtls_mpi_uint secp256k1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0xCF, 0x7B, 0xDC, 0xCD, 0xC3, 0x39, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xDA, 0xB9, 0xE5, 0x64, 0xA7, 0x47, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0x46, 0xA8, 0x61, 0xF6, 0x23, 0xEB, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xC1, 0xFF, 0xE4, 0x55, 0xD5, 0xC2, 0xBF), +}; +static const mbedtls_mpi_uint secp256k1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xBE, 0xB9, 0x59, 0x24, 0x13, 0x4A, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x45, 0x12, 0xDE, 0xBA, 0x4F, 0xEF, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x08, 0xBF, 0xC1, 0x66, 0xAA, 0x0A, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xFE, 0x30, 0x55, 0x31, 0x86, 0xA7, 0xB4), +}; +static const mbedtls_mpi_uint secp256k1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBF, 0x18, 0x81, 0x67, 0x27, 0x42, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x05, 0x83, 0xA4, 0xDD, 0x57, 0xD3, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x63, 0xAB, 0xE4, 0x90, 0x70, 0xD0, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x5D, 0xFD, 0xA0, 0xEF, 0xCF, 0x1C, 0x54), +}; +static const mbedtls_mpi_uint secp256k1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x80, 0xE4, 0xF6, 0x09, 0xBC, 0x57, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x9F, 0x6E, 0x88, 0x54, 0x6E, 0x51, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x5F, 0x85, 0xFB, 0x84, 0x3E, 0x4A, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x19, 0xF5, 0x55, 0xC9, 0x07, 0xD8, 0xCE), +}; +static const mbedtls_mpi_uint secp256k1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xB4, 0xC3, 0xD9, 0x5C, 0xA0, 0xD4, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x30, 0xAF, 0x59, 0x9B, 0xF8, 0x04, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xA6, 0xFD, 0x66, 0x7B, 0xC3, 0x39, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0xE0, 0xBF, 0xF0, 0xC2, 0xE9, 0x71, 0xA4, 0x9E), +}; +static const mbedtls_mpi_uint secp256k1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x2D, 0xB9, 0x88, 0x28, 0xF1, 0xBE, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xF3, 0x1A, 0x0E, 0xB9, 0x01, 0x66, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0xA4, 0xF4, 0x05, 0xD0, 0xAA, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x39, 0x1E, 0x47, 0xE5, 0x68, 0xC8, 0xC0), +}; +static const mbedtls_mpi_uint secp256k1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xB9, 0xFC, 0xE0, 0x33, 0x8A, 0x7D, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x93, 0xA5, 0x53, 0x55, 0x16, 0xB4, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x5F, 0xEA, 0x9B, 0x29, 0x52, 0x71, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xF0, 0x24, 0xB8, 0x7D, 0xB7, 0xA0, 0x9B), +}; +static const mbedtls_mpi_uint secp256k1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x00, 0x27, 0xB2, 0xDF, 0x73, 0xA2, 0xE0), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x2E, 0x4D, 0x7C, 0xDE, 0x7A, 0x23, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x65, 0x60, 0xC7, 0x97, 0x1E, 0xA4, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x13, 0x5B, 0x77, 0x59, 0xCB, 0x36, 0xE1), +}; +static const mbedtls_mpi_uint secp256k1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xBC, 0x9F, 0x9E, 0x2D, 0x53, 0x2A, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x5F, 0x64, 0x9F, 0x1A, 0x19, 0xE6, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x7B, 0x39, 0xD2, 0xDB, 0x85, 0x84, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xC7, 0x0D, 0x58, 0x6E, 0x3F, 0x52, 0x15), +}; +static const mbedtls_mpi_uint secp256k1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x68, 0x19, 0x0B, 0x68, 0xC9, 0x1E, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x4E, 0x21, 0x49, 0x3D, 0x55, 0xCC, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xF9, 0x25, 0x45, 0x54, 0x45, 0xB1, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xF7, 0xCD, 0x80, 0xA4, 0x04, 0x05), +}; +static const mbedtls_mpi_uint secp256k1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x1E, 0x88, 0xC4, 0xAA, 0x18, 0x7E, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xAC, 0xD9, 0xB2, 0xA1, 0xC0, 0x71, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xA2, 0xF1, 0x15, 0xA6, 0x5F, 0x6C, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x5B, 0x05, 0xBC, 0xB7, 0xC6, 0x4E, 0x72), +}; +static const mbedtls_mpi_uint secp256k1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x80, 0xF8, 0x5C, 0x20, 0x2A, 0xE1, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x48, 0x2E, 0x68, 0x82, 0x7F, 0xEB, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x3B, 0x25, 0xDB, 0x32, 0x4D, 0x88, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x6E, 0xA6, 0xB6, 0x6D, 0x62, 0x78, 0x22), +}; +static const mbedtls_mpi_uint secp256k1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4D, 0x3E, 0x86, 0x58, 0xC3, 0xEB, 0xBA), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x89, 0x33, 0x18, 0x21, 0x1D, 0x9B, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x9D, 0xFF, 0xC3, 0x79, 0xC1, 0x88, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0xD4, 0x48, 0x53, 0xE8, 0xAD, 0x21, 0x16), +}; +static const mbedtls_mpi_uint secp256k1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x7B, 0xDE, 0xCB, 0xD8, 0x39, 0x17, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xF3, 0x03, 0xF2, 0x5C, 0xBC, 0xC8, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0xAE, 0x4C, 0xB0, 0x16, 0xA4, 0x93, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8B, 0x6B, 0xDC, 0xD7, 0x9A, 0x3E, 0x7E), +}; +static const mbedtls_mpi_uint secp256k1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x2D, 0x7A, 0xD2, 0x59, 0x05, 0xA2, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x56, 0x09, 0x32, 0xF1, 0xE8, 0xE3, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0xCA, 0xE5, 0x2E, 0xF0, 0xFB, 0x18, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x85, 0xA9, 0x23, 0x15, 0x31, 0x1F, 0x0E), +}; +static const mbedtls_mpi_uint secp256k1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xE5, 0xB1, 0x86, 0xB9, 0x6E, 0x8D, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x77, 0xFC, 0xC9, 0xA3, 0x3F, 0x89, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x6A, 0xDC, 0x25, 0xB0, 0xC7, 0x41, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x11, 0x6B, 0xA6, 0x11, 0x62, 0xD4, 0x2D), +}; +static const mbedtls_mpi_uint secp256k1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7D, 0x34, 0xB3, 0x20, 0x7F, 0x37, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xD4, 0x45, 0xE8, 0xC2, 0xE9, 0xC5, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x32, 0x3B, 0x25, 0x7E, 0x79, 0xAF, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xE4, 0x54, 0x71, 0xBE, 0x35, 0x4E, 0xD0), +}; +static const mbedtls_mpi_uint secp256k1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x94, 0xDD, 0x8F, 0xB5, 0xC2, 0xDD, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x49, 0xE9, 0x1C, 0x2F, 0x08, 0x49, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xB6, 0x03, 0x88, 0x6F, 0xB8, 0x15, 0x67), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xD3, 0x1C, 0xF3, 0xA5, 0xEB, 0x79, 0x01), +}; +static const mbedtls_mpi_uint secp256k1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF9, 0x43, 0x88, 0x89, 0x0D, 0x06, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x2D, 0xF5, 0x98, 0x32, 0xF6, 0xB1, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x73, 0x8F, 0x2B, 0x50, 0x27, 0x0A, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE3, 0xBD, 0x16, 0x05, 0xC8, 0x93, 0x12), +}; +static const mbedtls_mpi_uint secp256k1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0x6A, 0xF7, 0xE3, 0x3D, 0xDE, 0x5F, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA3, 0x9C, 0x22, 0x3C, 0x33, 0x36, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x24, 0x4C, 0x69, 0x45, 0x78, 0x14, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xF8, 0xD4, 0xBF, 0xB8, 0xC0, 0xA1, 0x25), +}; +static const mbedtls_mpi_uint secp256k1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x88, 0xE1, 0x91, 0x03, 0xEB, 0xB3, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x11, 0xA1, 0xEF, 0x14, 0x0D, 0xC4, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xD4, 0x0D, 0x1D, 0x96, 0x33, 0x5C, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x45, 0x2A, 0x1A, 0xE6, 0x57, 0x04, 0x9B), +}; +static const mbedtls_mpi_uint secp256k1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xB5, 0xA7, 0x80, 0xE9, 0x93, 0x97, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0xB9, 0x7C, 0xA0, 0xC9, 0x57, 0x26, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0xEF, 0x56, 0xDA, 0x66, 0xF6, 0x1B, 0x9A), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x89, 0x6B, 0x91, 0xE0, 0xA9, 0x65, 0x2B), +}; +static const mbedtls_mpi_uint secp256k1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x98, 0x96, 0x9B, 0x06, 0x7D, 0x5E, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xFA, 0xC1, 0x5F, 0x19, 0x37, 0x94, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xBE, 0x6B, 0x1A, 0x05, 0xE4, 0xBF, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xCD, 0x5D, 0x35, 0xB4, 0x51, 0xF7, 0x64), +}; +static const mbedtls_mpi_uint secp256k1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xEF, 0x96, 0xDB, 0xF2, 0x61, 0x63, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x04, 0x88, 0xC9, 0x9F, 0x1B, 0x94, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x30, 0x79, 0x7E, 0x24, 0xE7, 0x5F, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xB8, 0x90, 0xB7, 0x94, 0x25, 0xBB, 0x0F), +}; +static const mbedtls_mpi_uint secp256k1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x79, 0xEA, 0xAD, 0xC0, 0x6D, 0x18, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xA4, 0x58, 0x2A, 0x8D, 0x95, 0xB3, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC4, 0xC2, 0x12, 0x0D, 0x79, 0xE2, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6F, 0xBE, 0x97, 0x4D, 0xA4, 0x20, 0x07), +}; +static const mbedtls_mpi_uint secp256k1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x31, 0x71, 0xC6, 0xA6, 0x91, 0xEB, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x9B, 0xA8, 0x4A, 0xE7, 0x77, 0xE1, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x06, 0xD3, 0x3D, 0x94, 0x30, 0xEF, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xDF, 0xCA, 0xFA, 0xF5, 0x28, 0xF8, 0xC9), +}; +static const mbedtls_mpi_uint secp256k1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0xE1, 0x32, 0xFD, 0x3E, 0x81, 0xF8, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xF2, 0x4B, 0x1D, 0x19, 0xC9, 0x0F, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB1, 0x8A, 0x22, 0x8B, 0x05, 0x6B, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0x21, 0xEF, 0x30, 0xEC, 0x09, 0x2A, 0x89), +}; +static const mbedtls_mpi_uint secp256k1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x84, 0x4A, 0x46, 0x07, 0x6C, 0x3C, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x18, 0x3A, 0xF4, 0xCC, 0xF5, 0xB2, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0x8F, 0xCD, 0x0A, 0x9C, 0xF4, 0xBD, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x89, 0x7F, 0x8A, 0xB1, 0x52, 0x3A, 0xAB), +}; +static const mbedtls_ecp_point secp256k1_T[16] = { + ECP_POINT_INIT_XY_Z1(secp256k1_T_0_X, secp256k1_T_0_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_1_X, secp256k1_T_1_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_2_X, secp256k1_T_2_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_3_X, secp256k1_T_3_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_4_X, secp256k1_T_4_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_5_X, secp256k1_T_5_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_6_X, secp256k1_T_6_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_7_X, secp256k1_T_7_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_8_X, secp256k1_T_8_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_9_X, secp256k1_T_9_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_10_X, secp256k1_T_10_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_11_X, secp256k1_T_11_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_12_X, secp256k1_T_12_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_13_X, secp256k1_T_13_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_14_X, secp256k1_T_14_Y), + ECP_POINT_INIT_XY_Z0(secp256k1_T_15_X, secp256k1_T_15_Y), +}; +#else +#define secp256k1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP256r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), +}; +static const mbedtls_mpi_uint brainpoolP256r1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D), +}; +static const mbedtls_mpi_uint brainpoolP256r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP256r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint brainpoolP256r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xA2, 0xED, 0x52, 0xC9, 0x8C, 0xE3, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0xC9, 0xC4, 0x87, 0x3F, 0x93, 0x7A, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x12, 0x53, 0x61, 0x3E, 0x76, 0x08, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x8C, 0x74, 0xF4, 0x08, 0xC3, 0x76, 0x80), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0xDD, 0x09, 0xA6, 0xED, 0xEE, 0xC4, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xD9, 0xBE, 0x4B, 0xA5, 0xB7, 0x2B, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x20, 0x12, 0xCA, 0x0A, 0x38, 0x24, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x72, 0x71, 0x90, 0x7A, 0x2E, 0xB7, 0x23), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0xA1, 0x93, 0x10, 0x2A, 0x51, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0x10, 0x11, 0x12, 0xBC, 0xB0, 0xB6, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x58, 0xD7, 0x0A, 0x84, 0x05, 0xA3, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x8E, 0x95, 0x61, 0xD3, 0x0B, 0xDF, 0x36), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x92, 0x12, 0x0F, 0x5E, 0x87, 0x70, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0xE9, 0x9B, 0xEB, 0x3A, 0xFB, 0xCF, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0x92, 0xB9, 0xF7, 0x45, 0xD3, 0x06, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x28, 0x65, 0xE1, 0xC5, 0x6C, 0x57, 0x18), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x0E, 0x77, 0x01, 0x81, 0x9E, 0x38, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0xF0, 0xD5, 0xA5, 0x91, 0x2B, 0xDF, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xEE, 0xB6, 0x25, 0xD6, 0x98, 0xDE, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0xA1, 0x55, 0x63, 0x39, 0xEB, 0xB5, 0x47), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD6, 0xB8, 0xE3, 0x13, 0xED, 0x7F, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xE8, 0xAE, 0x36, 0xB8, 0xCD, 0x19, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x82, 0x83, 0x7A, 0x7B, 0x46, 0x56, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x60, 0x46, 0x15, 0x5A, 0xAC, 0x99, 0x30), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x61, 0x50, 0xC6, 0xFF, 0x10, 0x7D, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x51, 0xDF, 0xA9, 0x7D, 0x78, 0x26, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x15, 0x9A, 0xF7, 0x01, 0xC1, 0xBB, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x0F, 0xE6, 0x2A, 0xBD, 0x4A, 0x9E, 0x87), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF8, 0xD1, 0x77, 0xD2, 0x49, 0xB3, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x86, 0xFB, 0x9E, 0x1F, 0x5A, 0x60, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xC4, 0x8D, 0xCD, 0x86, 0x61, 0x2F, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xF6, 0xB9, 0xAC, 0x37, 0x9D, 0xE9, 0x28), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x77, 0xAA, 0x97, 0x9C, 0x0B, 0x04, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0xA6, 0x60, 0x81, 0xCE, 0x25, 0x13, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x00, 0xF3, 0xBB, 0x82, 0x99, 0x95, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x5A, 0xCE, 0x90, 0x71, 0x38, 0x2F, 0x10), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x1A, 0xC0, 0x84, 0x27, 0xD6, 0x9D, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x37, 0x52, 0x16, 0x13, 0x0E, 0xCE, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBF, 0x5A, 0xDB, 0xDB, 0x6E, 0x1E, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xB7, 0x5E, 0xF9, 0x86, 0xDD, 0x8A, 0x5C), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xAB, 0x5C, 0x8D, 0x1D, 0xF2, 0x2D, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC5, 0xF8, 0xF7, 0x1D, 0x96, 0x0B, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x4C, 0xA7, 0x45, 0x20, 0x6A, 0x1E, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x5D, 0xEF, 0xDE, 0xEE, 0x39, 0x44, 0x19), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x2F, 0x6D, 0x52, 0xC9, 0x58, 0x60, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xC9, 0x62, 0xCB, 0x38, 0x3C, 0x55, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xA5, 0x09, 0x10, 0x88, 0xDB, 0xE3, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xE0, 0x3C, 0xCE, 0x06, 0x0B, 0x4B, 0x5D), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x1D, 0xB4, 0x10, 0x76, 0x8F, 0xBA, 0x09), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x70, 0x5A, 0x07, 0xF5, 0x1A, 0x74, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xE9, 0x94, 0xA8, 0xC0, 0xD5, 0x4A, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x6D, 0xD4, 0xE8, 0x9B, 0xE9, 0x6D, 0x0E), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x00, 0x32, 0x41, 0x57, 0x84, 0x89, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC7, 0x14, 0xEC, 0xE9, 0x27, 0xFF, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x67, 0x9E, 0xFB, 0xB6, 0xB8, 0x96, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0x4A, 0xE3, 0x97, 0x4B, 0x58, 0xDE, 0x30), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0x1E, 0x5C, 0xF5, 0x7F, 0xD5, 0xD4, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x08, 0x7A, 0xF1, 0xBD, 0x89, 0xC7, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0xF9, 0x11, 0x1B, 0xF5, 0x3C, 0x6D, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x50, 0xE5, 0x69, 0x1D, 0x59, 0xFC, 0x0C), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x2F, 0xF8, 0x3F, 0xEC, 0x55, 0x99, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0xA7, 0x29, 0x90, 0x43, 0x81, 0x31, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x18, 0x44, 0x50, 0x5D, 0x76, 0xCB, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xC5, 0x5B, 0x9A, 0x03, 0xE6, 0x17, 0x39), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x89, 0xFC, 0x55, 0x94, 0x91, 0x6A, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x46, 0x35, 0xF2, 0x3A, 0x42, 0x08, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0xD2, 0x76, 0x49, 0x42, 0x87, 0xD3, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xEA, 0xA0, 0x52, 0xF1, 0x6A, 0x30, 0x57), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0xB2, 0x57, 0xA3, 0x8A, 0x4D, 0x1B, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0xA3, 0x99, 0x94, 0xB5, 0x3D, 0x64, 0x09), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC3, 0xD7, 0x53, 0xF6, 0x49, 0x1C, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x23, 0x41, 0x4D, 0xFB, 0x7A, 0x5C, 0x53), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xB8, 0x15, 0x65, 0x5C, 0x85, 0x94, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x37, 0xC7, 0xF8, 0x7E, 0xAE, 0x6C, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xD8, 0x11, 0x54, 0x98, 0x44, 0xE3, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x4D, 0xA6, 0x4B, 0x28, 0xF2, 0x57, 0x9E), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xD0, 0xEB, 0x1E, 0xAA, 0x30, 0xD3, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x9B, 0x4D, 0xA7, 0x73, 0x6E, 0xB6, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x47, 0xF6, 0xED, 0x37, 0xEF, 0x71, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xB5, 0x49, 0x61, 0x5E, 0x45, 0xF6, 0x4A), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x0E, 0xB3, 0x84, 0x3A, 0x63, 0x72, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x53, 0x5C, 0xA7, 0xC6, 0x2E, 0xAB, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x0F, 0x8F, 0x87, 0x50, 0x28, 0xB4, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x98, 0x4A, 0x98, 0x31, 0x86, 0xCA, 0x51), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC9, 0xE2, 0xFD, 0x5D, 0x1F, 0xE8, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x90, 0x91, 0xC4, 0x84, 0xF0, 0xBA, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5A, 0xB3, 0x4E, 0xFB, 0xE0, 0x57, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x0B, 0x90, 0xA6, 0xFD, 0x9D, 0x8E, 0x02), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x41, 0x8F, 0x31, 0xFA, 0x5A, 0xF6, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xE9, 0xE3, 0xF6, 0xE0, 0x4A, 0xE7, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x4E, 0xCD, 0xA2, 0x22, 0x14, 0xD4, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xED, 0x21, 0xB7, 0x0F, 0x53, 0x10, 0x17), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x06, 0x24, 0x2C, 0x4E, 0xD1, 0x1E, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x3F, 0xC1, 0x9F, 0xAB, 0xF0, 0x37, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0x03, 0x5E, 0x12, 0xCE, 0x83, 0x1B, 0x2A, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x65, 0xCF, 0xE8, 0x5C, 0xA5, 0xA2, 0x70), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x86, 0x76, 0x3A, 0x94, 0xF6, 0x1D, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xDA, 0xC9, 0xA6, 0x29, 0x93, 0x15, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x61, 0x6A, 0x7D, 0xC7, 0xA9, 0xF3, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x03, 0x71, 0xA2, 0x15, 0xCE, 0x50, 0x72), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xD0, 0xA8, 0x1E, 0x91, 0xC4, 0x4F, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x4B, 0x7E, 0xD7, 0x71, 0x58, 0x7E, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x45, 0xAF, 0x2A, 0x18, 0x93, 0x95, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x8F, 0xC7, 0xFA, 0x4C, 0x7A, 0x86, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0xAF, 0x68, 0x3A, 0x23, 0xC1, 0x2E, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x50, 0x11, 0x67, 0x39, 0xB9, 0xAF, 0x48), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x86, 0xAA, 0x1E, 0x88, 0x21, 0x29, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x28, 0xA4, 0x9D, 0x89, 0xA9, 0x9A, 0x10), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xBA, 0x04, 0x67, 0xB7, 0x01, 0x40, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xE9, 0x09, 0xA3, 0xCA, 0xA6, 0x37, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x97, 0xA8, 0xB6, 0x3C, 0xEE, 0x90, 0x3D), + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xED, 0xC4, 0xF7, 0xC3, 0x95, 0xEC, 0x85), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x84, 0xBD, 0xEB, 0xD5, 0x64, 0xBB, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x9B, 0xE2, 0x28, 0x50, 0xC2, 0x72, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0xF2, 0x74, 0xD1, 0x26, 0xBF, 0x32, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xCB, 0xAF, 0x72, 0xDB, 0x6D, 0x30, 0x98), +}; +static const mbedtls_mpi_uint brainpoolP256r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x50, 0x85, 0xF4, 0x2B, 0x48, 0xC1, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x28, 0xBB, 0x11, 0xBA, 0x5B, 0x22, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xA1, 0xE5, 0x5C, 0xC9, 0x1D, 0x44, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xE8, 0xE6, 0x6F, 0xBB, 0xC1, 0x81, 0x7F), +}; +static const mbedtls_ecp_point brainpoolP256r1_T[16] = { + ECP_POINT_INIT_XY_Z1(brainpoolP256r1_T_0_X, brainpoolP256r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_1_X, brainpoolP256r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_2_X, brainpoolP256r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_3_X, brainpoolP256r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_4_X, brainpoolP256r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_5_X, brainpoolP256r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_6_X, brainpoolP256r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_7_X, brainpoolP256r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_8_X, brainpoolP256r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_9_X, brainpoolP256r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_10_X, brainpoolP256r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_11_X, brainpoolP256r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_12_X, brainpoolP256r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_13_X, brainpoolP256r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_14_X, brainpoolP256r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP256r1_T_15_X, brainpoolP256r1_T_15_Y), +}; +#else +#define brainpoolP256r1_T NULL +#endif + +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP384r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), +}; +static const mbedtls_mpi_uint brainpoolP384r1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B), +}; +static const mbedtls_mpi_uint brainpoolP384r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), +}; +static const mbedtls_mpi_uint brainpoolP384r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint brainpoolP384r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xD8, 0x8A, 0x54, 0x41, 0xD6, 0x6B, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x3B, 0xF1, 0x22, 0xFD, 0x2D, 0x4B, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x55, 0xE3, 0x33, 0xF0, 0x73, 0x52, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x3F, 0x30, 0x26, 0xCA, 0x7F, 0x52, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0xD3, 0x6E, 0x17, 0x9B, 0xD5, 0x2A, 0x4A, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xDA, 0x6B, 0xE5, 0x03, 0x07, 0x1D, 0x2E), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x7A, 0xAF, 0x98, 0xE3, 0xA4, 0xF6, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x7D, 0xFE, 0x51, 0x40, 0x3B, 0x47, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x88, 0xEC, 0xC4, 0xE2, 0x8F, 0xCB, 0xA4), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xE2, 0x88, 0x2D, 0x4E, 0x50, 0xEB, 0x9A), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x54, 0x94, 0x5E, 0xF4, 0x7F, 0x3A, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x07, 0x1C, 0xE1, 0xBD, 0x0F, 0xF8, 0x63), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x92, 0x28, 0x2E, 0x32, 0x04, 0xB1, 0x4D), + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x82, 0x44, 0x43, 0x76, 0x0D, 0x55, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xE3, 0xFF, 0x89, 0x46, 0xDE, 0x4E, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0x22, 0xBB, 0x67, 0x1A, 0x81, 0xEE, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x54, 0xE2, 0x7A, 0xAE, 0xDA, 0x2C, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x9A, 0x90, 0xAA, 0x6E, 0x8B, 0xCC, 0x5F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x40, 0xAC, 0xED, 0x7D, 0x37, 0x87, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0xF8, 0xB1, 0x80, 0x4C, 0x8C, 0x04, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x98, 0x2C, 0xAD, 0x30, 0x69, 0x35, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x2E, 0x00, 0x2F, 0x44, 0x8C, 0xF0, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x58, 0x07, 0xD7, 0xCD, 0x60, 0xA1, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xFB, 0x7B, 0x03, 0x05, 0x5E, 0x79, 0x73), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x17, 0xCE, 0x38, 0x4B, 0x5E, 0x5B, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x0E, 0x0A, 0x61, 0x9D, 0x7C, 0x62, 0x08), + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xF0, 0x98, 0x71, 0x7F, 0x17, 0x26, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0xD3, 0xFA, 0x3C, 0xF0, 0x70, 0x07, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x47, 0x5C, 0x09, 0x43, 0xB7, 0x65, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xA7, 0x3E, 0xFA, 0xF3, 0xEC, 0x22), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x78, 0x22, 0x2B, 0x58, 0x71, 0xFA, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x30, 0xCE, 0x6A, 0xB3, 0xB0, 0x4F, 0x83), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0x95, 0x20, 0xA9, 0x23, 0xC2, 0x65, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0xCF, 0x03, 0x5B, 0x8A, 0x80, 0x44, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xF8, 0x91, 0xF7, 0xD5, 0xED, 0xEA, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x5B, 0x16, 0x10, 0x25, 0xAC, 0x2A, 0x17), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEC, 0xDC, 0xC4, 0x7B, 0x8C, 0x6B, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xBB, 0x1C, 0xD3, 0x5A, 0xEE, 0xD9, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x5D, 0x30, 0x5E, 0xF7, 0xB2, 0x41, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xCE, 0x0F, 0x1A, 0xC6, 0x41, 0x64, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x18, 0xE1, 0xE3, 0x82, 0x15, 0x66, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0xE2, 0x24, 0x04, 0x72, 0x39, 0xA0, 0x7C), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x51, 0xA2, 0x58, 0x88, 0x62, 0xE1, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xD2, 0x65, 0x14, 0xE9, 0x4C, 0x82, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE1, 0xAC, 0x87, 0xAE, 0x31, 0x1A, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0x4F, 0x96, 0x1E, 0x85, 0x7A, 0xC3, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x86, 0xBB, 0xF0, 0xC0, 0x9D, 0x08, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x53, 0x03, 0x09, 0x80, 0x91, 0xEF, 0x68), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0xD7, 0xAF, 0x6F, 0x69, 0x7B, 0x88, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x13, 0xE4, 0x30, 0xA2, 0x47, 0xB5, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD2, 0xC0, 0xDD, 0x8A, 0x1C, 0x3C, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x8C, 0xB3, 0x4C, 0xBA, 0x8B, 0x6D, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xC7, 0xA1, 0xA8, 0x6E, 0x3C, 0x4F, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x4A, 0x97, 0xC8, 0x03, 0x6F, 0x01, 0x82), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x18, 0x12, 0xA9, 0x39, 0xD5, 0x22, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0xA7, 0xC0, 0xBD, 0x9D, 0x8D, 0x78, 0x38), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xB3, 0xD0, 0x7F, 0xDF, 0xD0, 0x30, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x73, 0x96, 0xEC, 0xA8, 0x1D, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xD1, 0x65, 0x66, 0xDC, 0xD9, 0xCF, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xED, 0x7B, 0x37, 0xAD, 0xE2, 0xBE, 0x2D), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x79, 0x42, 0x6A, 0x07, 0x66, 0xB1, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x53, 0x62, 0x65, 0x92, 0x09, 0x4C, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xAF, 0xC3, 0x03, 0xF6, 0xF4, 0x2D, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xCA, 0x41, 0xD9, 0xA2, 0x69, 0x9B, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0xB2, 0xA6, 0x8D, 0xE1, 0xAA, 0x61, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xBA, 0x4D, 0x12, 0xB6, 0xBE, 0xF3, 0x7E), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x92, 0x22, 0x07, 0xCE, 0xC9, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xA1, 0x7C, 0x91, 0xDB, 0x32, 0xF7, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x49, 0x4B, 0x6D, 0xFB, 0xD9, 0x70, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xFB, 0x4E, 0x4C, 0x5E, 0x66, 0x81, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xB3, 0xE1, 0x00, 0xB7, 0xD9, 0xCC, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x36, 0x8B, 0xC4, 0x39, 0x20, 0xFD, 0x30), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x1F, 0x60, 0x03, 0xBB, 0xD7, 0x60, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x3C, 0x62, 0xDD, 0x71, 0x95, 0xE9, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x5B, 0x7A, 0x5F, 0x68, 0x81, 0xC5, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xB5, 0xB9, 0x98, 0x42, 0x28, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x29, 0x8E, 0x11, 0x49, 0xB4, 0xD7, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x3E, 0xD2, 0x30, 0xA1, 0xBA, 0xCA, 0x03), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x37, 0x64, 0x44, 0x2F, 0x03, 0xE5, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x42, 0xBC, 0xFF, 0xA2, 0x1A, 0x5F, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0x04, 0xAB, 0x04, 0xE0, 0x24, 0xAD, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x45, 0x17, 0x67, 0x1F, 0x3E, 0x53, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x0F, 0xB3, 0x1B, 0x57, 0x54, 0xC2, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xD3, 0xF8, 0xC4, 0x1B, 0x9B, 0xFA, 0x30), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x90, 0xFD, 0xFB, 0xCA, 0x49, 0x38, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xCF, 0xC6, 0xDD, 0xF0, 0xFF, 0x8C, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x69, 0x9D, 0xBD, 0x5F, 0x33, 0xE9, 0xB4), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x19, 0x82, 0x3D, 0xAC, 0x1C, 0x40, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC7, 0x02, 0x46, 0x14, 0x77, 0x00, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x05, 0xF2, 0x77, 0x3A, 0x66, 0x5C, 0x39), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xE6, 0x17, 0xDE, 0xB2, 0xA1, 0xE5, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x71, 0xEC, 0x9D, 0xD8, 0xF5, 0xD4, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xC6, 0x42, 0x5E, 0xE7, 0x18, 0xBA, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x21, 0x68, 0x5A, 0x26, 0xFB, 0xD7, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x00, 0x5C, 0xBA, 0x8A, 0x34, 0xEC, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0x9C, 0x3C, 0xAF, 0x53, 0xE8, 0x65, 0x35), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xEF, 0x28, 0xDC, 0x67, 0x05, 0xC8, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x78, 0xC3, 0x85, 0x49, 0xA0, 0xBC, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x3E, 0x2D, 0xA0, 0xCF, 0xD4, 0x7A, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x93, 0xFE, 0x60, 0xB3, 0x6E, 0x99, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0xAD, 0x04, 0xE7, 0x49, 0xAF, 0x5E, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x7A, 0xED, 0xA6, 0x9E, 0x18, 0x09, 0x31), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x05, 0x94, 0x44, 0xDC, 0xB8, 0x85, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xB7, 0x37, 0xC2, 0x50, 0x75, 0x15, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xC6, 0x0F, 0xB2, 0xA9, 0x91, 0x3E, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x81, 0xAD, 0x25, 0xA1, 0x26, 0x73, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xF1, 0xD1, 0x61, 0x7C, 0x76, 0x8F, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0xDB, 0x4A, 0xFF, 0x14, 0xA7, 0x48, 0x0B), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x73, 0xC6, 0xC2, 0xCC, 0xF1, 0x57, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0xED, 0x73, 0x27, 0x70, 0x82, 0xB6, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xBA, 0xAC, 0x3A, 0xCF, 0xF4, 0xEA, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xD6, 0xB1, 0x8F, 0x0E, 0x08, 0x2C, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xE3, 0x8F, 0x2F, 0x0E, 0xA1, 0xF3, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0xF5, 0x7C, 0x9B, 0x29, 0x0A, 0xF6, 0x28), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0xEE, 0x17, 0x47, 0x34, 0x15, 0xA3, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBE, 0x88, 0x48, 0xE7, 0xA2, 0xBB, 0xDE), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xAD, 0xDC, 0x65, 0x61, 0x37, 0x0F, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x67, 0xAD, 0xA2, 0x3A, 0x1C, 0x91, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x07, 0x0C, 0x3A, 0x41, 0x6E, 0x13, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBD, 0x7E, 0xED, 0xAA, 0x14, 0xDD, 0x61), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC3, 0xDC, 0x20, 0x01, 0x72, 0x11, 0x48, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xC4, 0x7B, 0xF8, 0x62, 0x3D, 0xF0, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xC2, 0x3D, 0x2E, 0x52, 0xA3, 0x4A, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE2, 0x53, 0x46, 0x5E, 0x21, 0xF8, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xC7, 0x8F, 0xA9, 0x26, 0x42, 0x32, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xA6, 0xA0, 0x8D, 0x4B, 0x9A, 0x19, 0x03), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xAB, 0x6D, 0x1E, 0xFB, 0xEE, 0x60, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x56, 0x3C, 0xC5, 0x5D, 0x10, 0x79, 0x1C), + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0xBC, 0x41, 0x9F, 0x71, 0xEF, 0x02, 0xF9), + MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x36, 0xC4, 0xD0, 0x88, 0x9B, 0x32, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xD4, 0x5D, 0x17, 0x39, 0xE6, 0x22, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x26, 0x01, 0xCE, 0xBE, 0x4A, 0x9C, 0x27), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x6D, 0x11, 0xCA, 0x6C, 0x5A, 0x93, 0x0C), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x96, 0x26, 0xAF, 0x2F, 0xE4, 0x30, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xC1, 0x4C, 0xC6, 0x30, 0x1F, 0x5C, 0x04), + MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xB3, 0xE8, 0xFC, 0x35, 0xEB, 0x63, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x1D, 0xCA, 0xFC, 0x50, 0x36, 0x4B, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0E, 0x23, 0x5B, 0xAF, 0xEB, 0x2D, 0x31), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0x88, 0xB6, 0xD7, 0x74, 0x4A, 0x23, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x66, 0xE2, 0xBB, 0x29, 0xA6, 0x4F, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0x6F, 0x7E, 0x68, 0x6E, 0xA0, 0x14, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x73, 0xD4, 0xE8, 0xAB, 0x5B, 0xF6, 0x0D), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xE0, 0x3C, 0x24, 0x00, 0x95, 0xE9, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x0D, 0x4F, 0x81, 0xD0, 0xF2, 0x3F, 0x00), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0x1D, 0xCD, 0x78, 0x39, 0xC4, 0x6B, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x45, 0xC7, 0xB8, 0x2F, 0xAA, 0x5D, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0x8C, 0x6E, 0xA3, 0x24, 0xB2, 0xDB, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x2D, 0xD9, 0xF1, 0xC7, 0x9B, 0x8A, 0xAF), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xE1, 0x2C, 0xB9, 0x40, 0x37, 0x91, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x2C, 0xB5, 0x23, 0x03, 0x2B, 0xAF, 0x2F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0x9D, 0x5A, 0x20, 0x10, 0xA9, 0x84, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x30, 0x89, 0x20, 0x13, 0xE9, 0xB2, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x6E, 0x52, 0xEB, 0x03, 0x18, 0x1F, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x9E, 0x1C, 0x35, 0x87, 0x92, 0x69, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0xC9, 0x88, 0xAF, 0xC6, 0x6C, 0x83, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0xD5, 0x7A, 0x54, 0x34, 0x99, 0xB6, 0x6F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0xAD, 0x45, 0x9B, 0x4B, 0x41, 0x4D, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0x5D, 0xAB, 0x7F, 0x35, 0x34, 0xE9, 0x29), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0xBE, 0x78, 0x34, 0x44, 0xF3, 0x4A, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xDE, 0xE3, 0xC4, 0xEE, 0x0B, 0xF9, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x86, 0x16, 0x48, 0x32, 0xB8, 0x74, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0xEE, 0x7C, 0xBA, 0xBD, 0x81, 0xE3, 0x55), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x6A, 0xFA, 0x84, 0xDA, 0xB8, 0xD5, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x9F, 0x8A, 0xD5, 0x1B, 0x2E, 0x1A, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0C, 0x61, 0xE2, 0xFF, 0x5B, 0xE6, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x62, 0xC1, 0x87, 0x53, 0x1B, 0x92, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x90, 0x00, 0xD1, 0x6A, 0x0C, 0x0E, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x2E, 0xB5, 0x3B, 0x44, 0xB5, 0xA0, 0x78), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x5D, 0x02, 0x58, 0xB5, 0xBE, 0x45, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xEF, 0x8E, 0x90, 0x4D, 0x2A, 0x32, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0x99, 0x75, 0x5C, 0x0A, 0x33, 0x8F, 0x36), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x6C, 0x95, 0xD4, 0x1F, 0xF3, 0xEB, 0xDA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0xE4, 0x4C, 0x91, 0x20, 0xF3, 0x25, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x95, 0xEB, 0x29, 0x6F, 0x20, 0x34, 0x81), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x15, 0xE5, 0x13, 0x7E, 0x64, 0x8B, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xBC, 0x0D, 0x18, 0x7E, 0x37, 0x9E, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x82, 0x20, 0xF7, 0x2D, 0x7A, 0x77, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x29, 0xA2, 0xDB, 0x7A, 0xE6, 0x6F, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xC6, 0x50, 0x5C, 0xBC, 0xE6, 0x4F, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x9F, 0xD5, 0xE8, 0xC5, 0x3D, 0xB7, 0x30), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_16_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x03, 0x55, 0x10, 0xDB, 0xA6, 0x8B, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x17, 0xAE, 0x78, 0xC9, 0x1D, 0x43, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x35, 0x49, 0xD4, 0x47, 0x84, 0x8D, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x95, 0x2F, 0xEA, 0xBC, 0xB4, 0x18, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x48, 0xAE, 0x89, 0xF5, 0x65, 0x3D, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xF2, 0x2B, 0x20, 0xD1, 0x75, 0x50, 0x63), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_16_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0xE6, 0x5C, 0x2C, 0xE0, 0x7D, 0xDF, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x07, 0x3E, 0xCE, 0x9F, 0x18, 0xB6, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0xF8, 0xF0, 0xD5, 0xFA, 0x42, 0x1D, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x6C, 0x1D, 0x03, 0xC9, 0x0E, 0x2B, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x18, 0x52, 0xA5, 0xB4, 0x63, 0xE1, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0xD9, 0xC4, 0xFD, 0x16, 0x60, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_17_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x7D, 0xDE, 0xDF, 0x4B, 0x4A, 0xB0, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x4E, 0x8C, 0x94, 0xC1, 0xE2, 0x85, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x4F, 0xF0, 0xEA, 0xB5, 0x9B, 0x70, 0xEF, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0xC2, 0x39, 0x5D, 0xF3, 0x2C, 0xD9, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0x1C, 0x2E, 0xCC, 0x2F, 0x54, 0x87, 0x80), + MBEDTLS_BYTES_TO_T_UINT_8(0xB0, 0x72, 0xC7, 0xB5, 0x50, 0xA3, 0x84, 0x77), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_17_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xD1, 0xAF, 0xA9, 0xB4, 0x8B, 0x5D, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xF6, 0x52, 0x8A, 0xC3, 0x56, 0xA5, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x52, 0xFF, 0xEA, 0x05, 0x42, 0x77, 0x83), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x08, 0x90, 0x72, 0x86, 0xC4, 0xC3, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x15, 0xF8, 0xF1, 0x16, 0x67, 0xC6, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x87, 0xAC, 0x8F, 0x71, 0xEC, 0x83, 0x81), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_18_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0xE1, 0xE6, 0x2D, 0x0E, 0x11, 0xA1, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xE2, 0xA8, 0x32, 0xE6, 0xE3, 0x83, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x56, 0xE5, 0xCD, 0xB7, 0x2B, 0x67, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xED, 0xC9, 0x65, 0x6D, 0x87, 0xE1, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xFD, 0x9A, 0x53, 0x0E, 0xFA, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x4C, 0x4A, 0xE2, 0x23, 0x84, 0xFA, 0x01), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_18_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFE, 0x49, 0x81, 0xD1, 0x3E, 0xF4, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x72, 0xE0, 0xEF, 0x0D, 0xB8, 0x3E, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x00, 0x0F, 0x5F, 0xCE, 0x60, 0x72, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xCC, 0xD8, 0x03, 0x07, 0x6E, 0x5A, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x3A, 0x35, 0x50, 0x4E, 0x1F, 0xCA, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0xEA, 0x88, 0x55, 0xBD, 0x6E, 0x05, 0x7F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_19_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x6D, 0xF1, 0x97, 0xA6, 0x69, 0x39, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0x41, 0x99, 0xFF, 0x3B, 0xA1, 0x26, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x2F, 0x95, 0x80, 0x12, 0x4A, 0x1B, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xBF, 0x51, 0xAA, 0xAE, 0x2D, 0xDA, 0xCF), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1C, 0xB3, 0x52, 0x36, 0x49, 0xD4, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xC1, 0x1F, 0x3A, 0xD3, 0x3E, 0x5C, 0x1A), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_19_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x51, 0xF7, 0x2B, 0xC8, 0xA9, 0xA7, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x4E, 0x7F, 0x98, 0x41, 0x66, 0xB0, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x1D, 0xC0, 0x42, 0xCD, 0xF8, 0xC3, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x41, 0x91, 0x7D, 0xCC, 0x8B, 0xCC, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xAE, 0x76, 0xED, 0x56, 0x18, 0xC5, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x6A, 0x06, 0xA3, 0x7F, 0x65, 0x10, 0x1F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_20_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xEC, 0x3C, 0x05, 0x05, 0xCA, 0xF6, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x48, 0xCD, 0x02, 0x51, 0x12, 0x16, 0x3C, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0xEB, 0xB3, 0x43, 0x7B, 0xDD, 0xB2, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x59, 0x90, 0x41, 0xDB, 0xE4, 0xF5, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x0E, 0x18, 0x2A, 0x5A, 0x83, 0x7C, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x37, 0xA1, 0x0D, 0xF1, 0x2F, 0x63, 0x79), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_20_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC0, 0xFA, 0x6F, 0x1F, 0x67, 0xCF, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x34, 0x45, 0xBB, 0xF4, 0xF9, 0x9B, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x69, 0xFE, 0x67, 0x1D, 0x64, 0x8F, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x39, 0xBF, 0xD8, 0xB3, 0xC7, 0xAD, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x93, 0xFF, 0xF3, 0x28, 0xFA, 0x39, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF9, 0xC3, 0x85, 0x26, 0x7A, 0x88, 0x89), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_21_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xD5, 0x79, 0xD8, 0x11, 0xDE, 0xEB, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x46, 0xA4, 0x6A, 0xDA, 0x74, 0x34, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xBD, 0xD3, 0xF5, 0x14, 0xEE, 0xFE, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x4C, 0xA3, 0x71, 0x43, 0x65, 0xF8, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x6C, 0x35, 0xFA, 0x90, 0x25, 0xD8, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x34, 0x84, 0x96, 0xA1, 0x43, 0x03, 0x4D), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_21_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x3B, 0x3B, 0x2F, 0xCA, 0x59, 0xF2, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0x48, 0x24, 0x74, 0xD8, 0x72, 0x90, 0xA3), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x42, 0x74, 0x8C, 0x6F, 0x52, 0x19, 0x3D), + MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x9E, 0x41, 0x63, 0x68, 0x78, 0x4C, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x94, 0xB6, 0x6B, 0x38, 0x52, 0xA8, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x30, 0x25, 0x93, 0xA1, 0x6F, 0x6E, 0x68), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_22_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x2F, 0x4B, 0x64, 0x79, 0x50, 0xFF, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0x36, 0xED, 0x57, 0x39, 0x3B, 0xE7, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x85, 0xEA, 0x35, 0xD6, 0xC0, 0xA0, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x89, 0x3A, 0xCC, 0x22, 0x1C, 0x46, 0x02), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x7A, 0xB0, 0xA1, 0x1B, 0x69, 0x62, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xB8, 0x8A, 0x6C, 0x18, 0x85, 0x0D, 0x88), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_22_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB6, 0x50, 0xE9, 0x4E, 0x7F, 0xE8, 0x07), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5B, 0x5C, 0xD1, 0x4B, 0x11, 0x9A, 0xD8), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x25, 0x56, 0x74, 0x51, 0x9C, 0xEC, 0x9C), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x7F, 0xB6, 0x8A, 0xCB, 0x3A, 0x10, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0x60, 0x33, 0x07, 0x01, 0xE9, 0x49, 0x59, 0xE6), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xA5, 0x2E, 0xF2, 0xBA, 0x32, 0x63, 0x44), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_23_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x06, 0x0B, 0xA5, 0x44, 0x27, 0x7F, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x74, 0xAC, 0x0F, 0xCC, 0x4F, 0x13, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xB1, 0xBF, 0x97, 0x49, 0xA5, 0x1C, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x64, 0x68, 0x7B, 0x0F, 0xCC, 0x77, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x39, 0xF9, 0x4E, 0x84, 0x9C, 0xF6, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xCF, 0x6D, 0xE2, 0xA1, 0x2D, 0xF9, 0x2B), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_23_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0xC4, 0x90, 0x57, 0x31, 0x01, 0x05, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x1E, 0xBB, 0xBF, 0x98, 0xA4, 0x7C, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xE3, 0xA0, 0xB2, 0xCD, 0x39, 0x9A, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x34, 0x60, 0x7A, 0x89, 0x98, 0xB5, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0x20, 0x3D, 0x3A, 0x04, 0x8F, 0x5A, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x26, 0xB6, 0x49, 0x09, 0x9C, 0x0F, 0x59), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_24_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x66, 0xD2, 0x38, 0x2A, 0x62, 0x81, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0xC8, 0x20, 0x5E, 0x28, 0xA3, 0x81, 0xA7), + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x31, 0xA4, 0xF1, 0xEA, 0x7D, 0x87, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x8F, 0x2C, 0x99, 0x09, 0x6F, 0x63, 0xEB, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x76, 0xDA, 0x1A, 0x06, 0xBE, 0xDE, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x09, 0x2E, 0x75, 0x39, 0x30, 0x2D, 0x42), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_24_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x9B, 0xC1, 0x5A, 0x17, 0xC3, 0x8C, 0x31), + MBEDTLS_BYTES_TO_T_UINT_8(0x58, 0x8D, 0x94, 0x4D, 0x3D, 0xAB, 0x60, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFD, 0x1E, 0x0F, 0x43, 0xAE, 0x9D, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF2, 0xF3, 0x20, 0x1B, 0xAA, 0xB7, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x5B, 0xA4, 0xF4, 0x90, 0x3B, 0xE3, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x78, 0x72, 0xBD, 0x65, 0x09, 0x0B, 0x01), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_25_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x37, 0x2A, 0x6C, 0x16, 0x4F, 0x64, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0xCE, 0xA3, 0x90, 0xB4, 0x9A, 0xBC, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x55, 0x63, 0x1D, 0x3A, 0x6E, 0x18), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xB4, 0xAA, 0x99, 0x22, 0x45, 0x89, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x7C, 0x8C, 0xA6, 0x3D, 0xA7, 0x3E, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x06, 0x42, 0xDC, 0xA6, 0xE3, 0xC6, 0x12), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_25_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x8C, 0x3D, 0x5D, 0x47, 0x31, 0x7C, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x85, 0xEE, 0x46, 0x7E, 0x13, 0x04, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x3C, 0x8B, 0x43, 0x2E, 0x74, 0xF5, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x88, 0x8E, 0x07, 0x29, 0x08, 0x03, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0x9B, 0x89, 0xEB, 0x08, 0xE8, 0x43, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x07, 0x67, 0xFD, 0xD9, 0x73, 0x6F, 0x18), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_26_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xEB, 0x21, 0x8D, 0x98, 0x43, 0x74, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x88, 0xCC, 0x14, 0xD8, 0x08, 0xBB, 0xA6, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x98, 0xF2, 0x6A, 0x18, 0xC3, 0xDD, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x38, 0x91, 0xA0, 0x03, 0xF2, 0x04, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xAF, 0xE8, 0xFD, 0xFB, 0x13, 0x70, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x93, 0x87, 0x98, 0x4A, 0xE0, 0x00, 0x12), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_26_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x2E, 0x69, 0x9C, 0xA2, 0x2D, 0x03, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFE, 0xF3, 0xB9, 0xC1, 0x85, 0x2A, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xFD, 0x86, 0xB1, 0xCD, 0xBF, 0x41, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xD8, 0x9A, 0x21, 0xF3, 0xFE, 0xCB, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x78, 0x04, 0x60, 0xB7, 0xA9, 0xA2, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1E, 0x66, 0x2A, 0x54, 0x51, 0xBD, 0x8B), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_27_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x16, 0x36, 0xEF, 0x61, 0x2D, 0xEE, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x5F, 0x88, 0xA0, 0x13, 0x12, 0xF7, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0xC6, 0xAD, 0x4A, 0x4A, 0x07, 0x01, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0x74, 0xB1, 0x4F, 0xEB, 0xBD, 0xD5, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xF9, 0x71, 0xA2, 0x06, 0x4F, 0xD7, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x8B, 0x4D, 0x48, 0xE0, 0x98, 0xFB, 0x6A), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_27_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xBA, 0x10, 0xA3, 0x0D, 0x52, 0xAC, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xD0, 0xE0, 0x36, 0xE6, 0x07, 0x3A, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x80, 0xF0, 0xAA, 0x49, 0x22, 0x4B, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xC7, 0xAB, 0x1C, 0x89, 0xCD, 0x24, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x82, 0x2A, 0xFC, 0xB3, 0x6D, 0x45, 0x96, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xE4, 0xDB, 0x52, 0x3F, 0xC4, 0xB4, 0x19), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_28_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5B, 0xCC, 0xC8, 0x7F, 0xBB, 0x6B, 0x87, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x21, 0x3C, 0x69, 0x7D, 0x38, 0x57, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x4C, 0x18, 0x3C, 0x53, 0xA5, 0x48, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xC3, 0x64, 0x45, 0xDB, 0xC4, 0x6D, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xCC, 0xD1, 0xBB, 0x17, 0xB8, 0x34, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x69, 0x71, 0xFA, 0xA0, 0x28, 0x4A, 0x3D), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_28_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xE8, 0x9E, 0x39, 0xEA, 0x8D, 0x38, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x9C, 0xBB, 0xCD, 0x80, 0x1A, 0xEE, 0xB7), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA0, 0x45, 0xBF, 0xD9, 0x22, 0x11, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x7C, 0x5C, 0xD9, 0xC0, 0x9F, 0x69, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x8A, 0xA6, 0x79, 0x4E, 0x35, 0xB9, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0xCC, 0x8B, 0x9A, 0x3E, 0xA1, 0xB8, 0x28, 0x10), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_29_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x2F, 0xEF, 0xBB, 0xA9, 0x72, 0x7F, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x34, 0xB7, 0x12, 0xB9, 0xE7, 0xC3, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x1D, 0xD9, 0x42, 0x77, 0x0C, 0x71, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x01, 0x59, 0xA7, 0x56, 0x03, 0x91, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x91, 0x99, 0x33, 0x30, 0x3E, 0xEF, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xC9, 0x5A, 0x9A, 0x54, 0x66, 0xF1, 0x70), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_29_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x2C, 0xB7, 0x6E, 0x71, 0x7D, 0x35, 0x30), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x0D, 0xEF, 0xD1, 0x2D, 0x99, 0x63, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x31, 0xAF, 0x2D, 0xC9, 0xC6, 0xC2, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0xC0, 0xDF, 0x80, 0x54, 0xC4, 0xAC, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x6B, 0xA0, 0x84, 0x96, 0xF7, 0x31, 0xC8), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0xE2, 0x7C, 0x7A, 0x41, 0x45, 0x75, 0x6A), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_30_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xEE, 0x58, 0x31, 0xE8, 0x68, 0xD6, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x2E, 0x48, 0xB7, 0x09, 0x9F, 0xD4, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xA9, 0x5C, 0xE7, 0x64, 0x43, 0x5D, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x9E, 0x58, 0x9F, 0x50, 0xAB, 0x68, 0xFF, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x88, 0x2D, 0xBA, 0x12, 0xBF, 0x8D, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xDF, 0x6F, 0xB3, 0x75, 0xA4, 0x55, 0x73), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_30_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x17, 0x92, 0x39, 0xB7, 0x13, 0x37, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x43, 0x71, 0xA7, 0xCA, 0x17, 0x1B, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xB9, 0xB0, 0x78, 0xEF, 0xA0, 0xDA, 0x83), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x84, 0xF2, 0x0F, 0x85, 0xA2, 0xB6, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x65, 0x2E, 0x6E, 0x45, 0xB9, 0x4C, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x6A, 0x8C, 0x2B, 0x77, 0x96, 0x36, 0x22), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_31_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x7A, 0x13, 0x4A, 0x97, 0x63, 0x02, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x1E, 0x06, 0x03, 0x8F, 0xB9, 0xEE, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0xEE, 0x8B, 0x89, 0xA9, 0x70, 0xDB, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x7B, 0x81, 0xC9, 0x70, 0x8D, 0x62, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0xDA, 0x46, 0xF8, 0xF9, 0x3A, 0xBE, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0x9C, 0x7A, 0x97, 0x62, 0xEB, 0xFA, 0x0F), +}; +static const mbedtls_mpi_uint brainpoolP384r1_T_31_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x03, 0x3D, 0x3C, 0x46, 0x27, 0x9E, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x08, 0x1C, 0xD5, 0x25, 0xAF, 0xE9, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x69, 0xDC, 0x59, 0xF4, 0x8A, 0x7C, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x9A, 0x7A, 0x99, 0x21, 0x0C, 0x4E, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xCE, 0x85, 0x5F, 0xAC, 0xAA, 0x82, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x83, 0x57, 0x69, 0x90, 0x76, 0xF3, 0x53, 0x3F), +}; +static const mbedtls_ecp_point brainpoolP384r1_T[32] = { + ECP_POINT_INIT_XY_Z1(brainpoolP384r1_T_0_X, brainpoolP384r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_1_X, brainpoolP384r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_2_X, brainpoolP384r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_3_X, brainpoolP384r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_4_X, brainpoolP384r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_5_X, brainpoolP384r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_6_X, brainpoolP384r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_7_X, brainpoolP384r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_8_X, brainpoolP384r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_9_X, brainpoolP384r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_10_X, brainpoolP384r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_11_X, brainpoolP384r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_12_X, brainpoolP384r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_13_X, brainpoolP384r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_14_X, brainpoolP384r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_15_X, brainpoolP384r1_T_15_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_16_X, brainpoolP384r1_T_16_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_17_X, brainpoolP384r1_T_17_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_18_X, brainpoolP384r1_T_18_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_19_X, brainpoolP384r1_T_19_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_20_X, brainpoolP384r1_T_20_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_21_X, brainpoolP384r1_T_21_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_22_X, brainpoolP384r1_T_22_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_23_X, brainpoolP384r1_T_23_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_24_X, brainpoolP384r1_T_24_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_25_X, brainpoolP384r1_T_25_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_26_X, brainpoolP384r1_T_26_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_27_X, brainpoolP384r1_T_27_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_28_X, brainpoolP384r1_T_28_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_29_X, brainpoolP384r1_T_29_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_30_X, brainpoolP384r1_T_30_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP384r1_T_31_X, brainpoolP384r1_T_31_Y), +}; +#else +#define brainpoolP384r1_T NULL +#endif + +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP512r1_p[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), +}; +static const mbedtls_mpi_uint brainpoolP512r1_a[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78), +}; +static const mbedtls_mpi_uint brainpoolP512r1_b[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_n[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA), +}; + +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 +static const mbedtls_mpi_uint brainpoolP512r1_T_0_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4), + MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_0_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_1_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xE9, 0x6B, 0x8C, 0x6F, 0x9D, 0x88, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x4F, 0x86, 0x96, 0xA7, 0x56, 0xD1, 0x37), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xAB, 0xFA, 0xEE, 0xA7, 0xF5, 0x0E, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x40, 0xEF, 0x9E, 0x6D, 0xD6, 0x32, 0x33), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xED, 0x56, 0x14, 0x57, 0x1A, 0x8D, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xED, 0x4D, 0x3A, 0xFA, 0x71, 0x75, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xC5, 0x76, 0x1C, 0x14, 0xBE, 0xB5, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x5A, 0xCB, 0xE7, 0x36, 0x1D, 0x52, 0x1C), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_1_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8D, 0x7A, 0xEB, 0xA3, 0x8B, 0xD5, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0xA3, 0x41, 0xF8, 0xAC, 0x9E, 0xAB, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0xE3, 0x65, 0x0D, 0x1C, 0xFE, 0x09, 0x2B), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0xCA, 0x13, 0x3F, 0xC5, 0xF9, 0x7E, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x5D, 0x63, 0x28, 0xA6, 0x89, 0xD3, 0x91), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x95, 0x3F, 0x7A, 0x82, 0xD4, 0x77, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xBB, 0x92, 0x32, 0x00, 0xF4, 0x66, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x58, 0x31, 0xD1, 0x17, 0x9F, 0x2A, 0x22), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_2_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x36, 0xA9, 0xCD, 0x80, 0xA5, 0x2D, 0x78), + MBEDTLS_BYTES_TO_T_UINT_8(0x91, 0x44, 0xAB, 0xCE, 0x71, 0xFF, 0x0C, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0x24, 0x58, 0x35, 0x5A, 0x21, 0x32, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0x1B, 0xA6, 0x28, 0xF8, 0x7A, 0x97, 0xAE, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xE7, 0x08, 0xFA, 0x47, 0xC9, 0x55, 0x09), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xAC, 0x2E, 0x84, 0xA4, 0xF5, 0x52, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x58, 0x05, 0x9D, 0xA7, 0xC8, 0x71, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x92, 0xB4, 0x92, 0xC1, 0x92, 0xEC, 0x6B), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_2_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4A, 0x48, 0x2D, 0x79, 0x5E, 0x58, 0xE5, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x85, 0x26, 0xEC, 0xE9, 0x6E, 0xD4, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x68, 0x26, 0x87, 0x38, 0xA2, 0xD2, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0x17, 0x60, 0xCE, 0x75, 0xF8, 0xA5, 0x6F), + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0x51, 0xDB, 0xA9, 0xAE, 0x87, 0xF1, 0x15), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x49, 0x92, 0x3B, 0x19, 0x96, 0xF5, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0xD5, 0x52, 0x52, 0x8C, 0xCE, 0xFD, 0xFA), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x18, 0x0A, 0xE6, 0xF6, 0xAE, 0x08, 0x41), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_3_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x2B, 0xD8, 0x54, 0xCE, 0xB0, 0x57, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xB0, 0xF8, 0x9E, 0x03, 0x03, 0x3C, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x0E, 0x29, 0x29, 0x00, 0xF3, 0x70, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x33, 0x99, 0x0E, 0x00, 0x5D, 0xFE, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0x2D, 0xF2, 0x59, 0x32, 0xCF, 0x03, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xC9, 0x72, 0xAE, 0x0C, 0xEF, 0xD1, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x5A, 0x27, 0xBF, 0x2F, 0x45, 0xF9, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0xD4, 0xBE, 0xE5, 0x2C, 0xFF, 0x5B, 0x1E, 0x88), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_3_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0xAC, 0xBB, 0xD8, 0x83, 0xC2, 0x46, 0xF6), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xDC, 0xCE, 0x15, 0xB4, 0xEF, 0xCF, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xDB, 0x5E, 0x94, 0x31, 0x0B, 0xB2, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0xB9, 0xE3, 0xE3, 0x11, 0x71, 0x41, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xE3, 0x01, 0xB7, 0x7D, 0xBC, 0x65, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x07, 0x65, 0x87, 0xA7, 0xE8, 0x48, 0xE3), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x48, 0x8F, 0xD4, 0x30, 0x8E, 0xB4, 0x6C), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0xE0, 0x73, 0xBE, 0x1E, 0xBF, 0x56, 0x36), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_4_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0x0E, 0x5E, 0x87, 0xC5, 0xAB, 0x0E, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xF9, 0x5F, 0x80, 0x24, 0x4C, 0x2A, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0x15, 0x21, 0x54, 0x92, 0x84, 0x8D, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x8A, 0x47, 0x74, 0xDC, 0x42, 0xB1, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0xF7, 0x30, 0xFD, 0xC1, 0x9B, 0x0C, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x6C, 0xCC, 0xDF, 0xC5, 0xE3, 0xA9, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x67, 0x59, 0x10, 0x5C, 0x51, 0x54, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x37, 0xFB, 0x6E, 0xB0, 0x78, 0x63, 0x8E), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_4_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0xEF, 0xC4, 0x39, 0x20, 0xF1, 0x46, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0x62, 0xAE, 0xFF, 0x10, 0xE4, 0xE2, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x5C, 0xF5, 0x2E, 0x22, 0x89, 0xE5, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x0C, 0x29, 0xA8, 0x62, 0xAE, 0xDB, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x9E, 0x0F, 0xCA, 0x87, 0x2A, 0x6F, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xDC, 0x9B, 0x9F, 0x65, 0xD4, 0xAD, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0xC3, 0x08, 0x0F, 0xCF, 0x67, 0xE9, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x5C, 0xD7, 0xFF, 0x41, 0x9C, 0xCB, 0x26), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_5_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x25, 0x05, 0x12, 0xAD, 0x73, 0x63, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x99, 0x07, 0x86, 0x57, 0xE7, 0x94, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x4B, 0xA5, 0xBF, 0x18, 0xA9, 0xEF, 0x6A), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0x4C, 0xC4, 0x09, 0xF2, 0x2F, 0x0C, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x3A, 0x04, 0xEA, 0x89, 0x6C, 0x91, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0x3A, 0xE7, 0xA3, 0xEC, 0x24, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xA1, 0x26, 0x21, 0x04, 0xE3, 0xB9, 0x40), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0x71, 0x4B, 0x7B, 0xC2, 0x89, 0xCD, 0xA2), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_5_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0xB9, 0xA8, 0x9D, 0xFD, 0x00, 0x3A, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x41, 0x6C, 0xBB, 0x5A, 0xCA, 0x1F, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0xD7, 0xE2, 0x6C, 0x6B, 0xA7, 0x48, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x19, 0xAD, 0xA7, 0xC1, 0x7E, 0x4F, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0xF7, 0x19, 0x3C, 0x06, 0x74, 0x2C, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x23, 0x4F, 0x0C, 0x09, 0xB0, 0x80, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x4E, 0x74, 0x34, 0x08, 0x44, 0x7E, 0xA3, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xCC, 0x8D, 0x12, 0x6E, 0xE1, 0x3D, 0x0B), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_6_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x18, 0xB1, 0x71, 0x02, 0x93, 0xC2, 0xA4), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x89, 0x40, 0xE2, 0x1F, 0xE7, 0x5E, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x8E, 0xAE, 0x89, 0x01, 0xD4, 0x0C, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xDA, 0x58, 0x70, 0x24, 0xF2, 0xE4, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0xC7, 0x1D, 0xD6, 0x4A, 0x6F, 0x66, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x1D, 0x7E, 0x4A, 0x2C, 0xCA, 0xEC, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x06, 0x7F, 0xA8, 0x99, 0xE4, 0xD3, 0x4E), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x1D, 0x5A, 0xDF, 0x5E, 0x58, 0x36, 0x49), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_6_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0xB9, 0x32, 0x69, 0x1F, 0x72, 0x2A, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0x73, 0xE2, 0x03, 0x39, 0x35, 0xAA, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x5E, 0x5D, 0x48, 0xEF, 0xAE, 0x30, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x7F, 0x60, 0x19, 0xAF, 0xEC, 0x9D, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0xD9, 0x19, 0xE4, 0x1B, 0x56, 0x15, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xD7, 0x33, 0x59, 0x1F, 0x43, 0x59, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xCE, 0xEE, 0xCA, 0xA4, 0x7F, 0x63, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0xBD, 0x40, 0xC0, 0xF6, 0x19, 0x89, 0x43, 0x20), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_7_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x92, 0xEA, 0x07, 0x65, 0x79, 0x86, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xB7, 0x13, 0x75, 0xD3, 0xC5, 0x0A, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x9E, 0xFA, 0xE1, 0x1F, 0x0C, 0xF9, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x8C, 0xED, 0x5C, 0x21, 0xE9, 0x09, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0x4D, 0xD8, 0x18, 0xC4, 0xF6, 0x36, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xC9, 0xAC, 0x5C, 0xFA, 0x69, 0xA4, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x8C, 0x94, 0x1C, 0x7B, 0x71, 0x36, 0x58), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xBD, 0x46, 0xCE, 0xB7, 0x1D, 0x9C, 0x5E), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_7_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xD6, 0x96, 0x4B, 0xA6, 0x47, 0xEB, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xF1, 0x5F, 0x15, 0xDE, 0x99, 0x6F, 0x66), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xBD, 0xE5, 0x04, 0xB8, 0xE6, 0xC0, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0xD3, 0xF0, 0x04, 0x00, 0xE4, 0x05, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xF3, 0x06, 0xA3, 0x1A, 0xFF, 0xEA, 0x73), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x32, 0xAA, 0x99, 0x33, 0x09, 0xB6, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xEF, 0xFC, 0x61, 0x10, 0x42, 0x31, 0x94), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF1, 0xF4, 0x33, 0xCF, 0x28, 0x90, 0x9C), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_8_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xDE, 0xF9, 0x88, 0x87, 0x7B, 0xEB, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xB8, 0xDA, 0xFA, 0xDA, 0x3D, 0xA6, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF0, 0x62, 0x82, 0x53, 0x32, 0x55, 0x03), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xA5, 0x32, 0x4A, 0x19, 0x11, 0x9C, 0x10), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xB3, 0x27, 0xE9, 0x75, 0x90, 0x05, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x1C, 0x90, 0x48, 0x77, 0x01, 0x85, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD6, 0x9B, 0x84, 0xA8, 0xD7, 0xC5, 0x28), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x7A, 0xCB, 0xB3, 0x11, 0x46, 0xD7, 0x99), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_8_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0x23, 0xBF, 0x75, 0x75, 0xA1, 0x95, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x66, 0x5D, 0x34, 0x13, 0xA9, 0x03, 0xBE), + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x80, 0x9D, 0x5F, 0xD2, 0x44, 0xE1, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x5D, 0xBD, 0xA8, 0xBF, 0xB4, 0x25, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x99, 0x1F, 0x53, 0xF1, 0x57, 0xDB, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x7C, 0xE5, 0xC5, 0x51, 0x0B, 0x4C, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0xB0, 0x1A, 0x9C, 0x16, 0xB0, 0x32, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xE3, 0xCF, 0xDD, 0x48, 0xB4, 0x7B, 0x33), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_9_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xDD, 0x9E, 0x3C, 0x98, 0x0E, 0x77, 0x65), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0xAB, 0x01, 0xD3, 0x87, 0x74, 0x25, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xA3, 0xE3, 0x76, 0x43, 0x87, 0x12, 0xBD), + MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0xB1, 0x3B, 0x60, 0x66, 0xEB, 0x98, 0x54), + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x78, 0xC8, 0xD7, 0x4E, 0x75, 0xCA, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xDF, 0x71, 0x19, 0xE7, 0x07, 0x36, 0xB5), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xC9, 0xA8, 0x5F, 0x91, 0xBF, 0x47, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x96, 0x58, 0x96, 0x18, 0xB6, 0xFA, 0x01), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_9_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x2D, 0xA9, 0x9B, 0x86, 0xDB, 0x0C, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x0B, 0x2D, 0x56, 0x4A, 0xD3, 0x93, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x15, 0xE2, 0x65, 0x12, 0x86, 0x0E, 0xB2), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x41, 0x4D, 0xC1, 0xCB, 0xE4, 0xC3, 0xD7), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x53, 0x10, 0xCA, 0xA3, 0xAC, 0x83, 0x26), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x01, 0x22, 0x96, 0x10, 0xAD, 0x69, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x46, 0x4E, 0xD8, 0xEA, 0xD6, 0x9D, 0xF3), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x2F, 0x7F, 0x62, 0x62, 0x80, 0xD0, 0x14), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_10_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xDA, 0x00, 0x63, 0x09, 0xBD, 0x6A, 0x83), + MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xD4, 0x6E, 0x48, 0x05, 0xB7, 0xF7, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0x4D, 0xD7, 0x00, 0x4A, 0x15, 0x27, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x15, 0xAA, 0x37, 0x27, 0x34, 0x18, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x20, 0x2C, 0x84, 0x1B, 0x88, 0xBA, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x09, 0xD6, 0x04, 0xA2, 0x60, 0x84, 0x72), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0x04, 0x94, 0x08, 0xD4, 0xED, 0x47, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xF3, 0xE4, 0x3E, 0xB9, 0x5B, 0x35, 0x42), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_10_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0xD8, 0xB6, 0x80, 0xD6, 0xF1, 0x30, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x14, 0xA6, 0x85, 0xEE, 0xA7, 0xD8, 0x61), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x49, 0x2A, 0x1E, 0x7C, 0xE9, 0x2D, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x3A, 0x87, 0x56, 0x91, 0x03, 0x77, 0x4D, 0x55), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0x52, 0xD4, 0xAA, 0xF7, 0xFA, 0xB0, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x5D, 0x11, 0x39, 0xB1, 0xE7, 0x76, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x13, 0xBC, 0x37, 0x5D, 0x74, 0xCD, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x48, 0x14, 0x23, 0x30, 0xF8, 0x46, 0x37), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_11_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x27, 0xB0, 0xD9, 0xB2, 0x74, 0xB4, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xEA, 0xA6, 0xB9, 0x6F, 0x9F, 0x64, 0x36, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x2E, 0x2B, 0x78, 0x40, 0x05, 0x2B, 0x7B, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x68, 0x3A, 0xB6, 0x4A, 0xE2, 0xDB, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0x33, 0xD7, 0x34, 0x8B, 0x25, 0x45, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xCE, 0xA8, 0xC9, 0x01, 0xFB, 0x0E, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF9, 0x51, 0x4C, 0x12, 0x9F, 0x60, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x85, 0xBD, 0x30, 0x37, 0x84, 0x39, 0x44), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_11_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x33, 0xAF, 0x2E, 0xB8, 0x2E, 0xCC, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xB1, 0x73, 0x59, 0x4E, 0x0C, 0x09, 0x4A), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0x24, 0x89, 0x81, 0x12, 0xFF, 0xBB, 0x6E), + MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x37, 0x1A, 0x66, 0xEE, 0xED, 0xB6, 0x9B), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0xBD, 0x04, 0x20, 0x5D, 0xFB, 0xBF, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xF8, 0x34, 0xA3, 0xFF, 0x45, 0xDE, 0x92), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x18, 0x73, 0xF1, 0x32, 0x25, 0x58, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0xC1, 0x14, 0xE3, 0x9E, 0x40, 0x0F, 0x12), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_12_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0x9D, 0x9C, 0x00, 0xF7, 0x56, 0x19), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0xBA, 0x87, 0xF9, 0x15, 0x0C, 0x66, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0x1F, 0xC1, 0x28, 0xB0, 0x47, 0x0D, 0xF5), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xCA, 0x27, 0xEE, 0x4B, 0x23, 0x2B, 0x89), + MBEDTLS_BYTES_TO_T_UINT_8(0x7E, 0xB5, 0x68, 0xC8, 0x17, 0x5D, 0xC3, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0x02, 0x08, 0xEE, 0x20, 0x9D, 0xEA, 0x64), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x14, 0x50, 0xD4, 0x7D, 0x5F, 0xCF, 0xA0), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xFA, 0xF8, 0xA7, 0xC6, 0xDC, 0x14, 0x8C), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_12_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x76, 0xBD, 0x0A, 0x1A, 0x18, 0x98, 0xDC, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0x63, 0x63, 0x02, 0xB7, 0xD5, 0x5B, 0x5A, 0xC6), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0xB1, 0xD7, 0x4B, 0x15, 0x39, 0x61, 0x5D), + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0x32, 0xE1, 0x9E, 0x70, 0x1B, 0xCE, 0x51), + MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD8, 0x18, 0x83, 0x52, 0x9B, 0x6D, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x55, 0x56, 0x19, 0x34, 0xA4, 0xEA, 0xFC), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0xA9, 0x55, 0x80, 0xE3, 0x15, 0x36, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0x06, 0xC8, 0x1D, 0x17, 0x0D, 0xAD, 0x16), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_13_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xD6, 0xF0, 0xCC, 0xF3, 0x63, 0x53, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x5A, 0xDC, 0x46, 0xBD, 0x0D, 0xAD, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x2F, 0x11, 0x60, 0x15, 0x51, 0x4A, 0xEA), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xE3, 0x93, 0x38, 0xD5, 0x83, 0xAA, 0x0D), + MBEDTLS_BYTES_TO_T_UINT_8(0x90, 0xA6, 0xCC, 0xB1, 0xFD, 0xBB, 0x1A, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0x54, 0xC8, 0x54, 0x6F, 0x79, 0x1A, 0x59), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4A, 0xDA, 0x28, 0x92, 0x97, 0x9D, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0x4B, 0xDB, 0xC7, 0x52, 0xC5, 0x66, 0x34), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_13_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7E, 0x92, 0x53, 0x30, 0x93, 0xFD, 0xFF), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0x6A, 0xB1, 0x91, 0x0A, 0xB4, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0x9D, 0x40, 0x3F, 0xE3, 0xF1, 0x01, 0x46), + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x0E, 0xD8, 0xED, 0x11, 0x8E, 0x4C, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0x86, 0x4A, 0x1B, 0x88, 0xDF, 0x8D, 0x29, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x23, 0x21, 0x11, 0xAB, 0x77, 0x81, 0x62), + MBEDTLS_BYTES_TO_T_UINT_8(0x0B, 0xAF, 0x11, 0xFA, 0xBA, 0x40, 0x63, 0xE7), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x6F, 0x8D, 0x80, 0xDF, 0x67, 0xF5, 0x44), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_14_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0x8B, 0xB7, 0x08, 0xF4, 0xD7, 0x2D, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x2B, 0x30, 0x02, 0x45, 0x71, 0x08, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x3A, 0xCA, 0x50, 0xF6, 0xC2, 0x19, 0x8C), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xB9, 0x9B, 0x3E, 0x73, 0x95, 0x1D, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x60, 0x59, 0x48, 0xCB, 0xD8, 0xD6, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0xB9, 0x6C, 0x89, 0xAB, 0x99, 0xA8, 0xF8), + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0xA1, 0x8B, 0x4E, 0x06, 0x19, 0xEC, 0x99), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x95, 0x04, 0xCF, 0xD5, 0x94, 0xB3, 0x02), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_14_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0x35, 0x93, 0x7C, 0xB3, 0xB8, 0x9E, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0xC4, 0x45, 0x5C, 0x7E, 0xBF, 0x75, 0x81, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xE8, 0x24, 0xDF, 0xEC, 0x2F, 0x7D, 0xB9), + MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x8B, 0xD5, 0x6A, 0x9B, 0xA0, 0xE0, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0xE3, 0x27, 0x82, 0xDE, 0xDD, 0xCA, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x57, 0x56, 0x46, 0x05, 0x06, 0x01, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0x35, 0xA7, 0x47, 0xE2, 0x6B, 0x2C, 0x4F), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x9D, 0x4C, 0xEC, 0x1F, 0x11, 0x75, 0x2B), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_15_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xAA, 0x41, 0xC1, 0xE9, 0x0E, 0xE9, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xCF, 0x9C, 0x4B, 0xE8, 0xED, 0x0A, 0x49), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x73, 0xCA, 0x0C, 0x46, 0x0A, 0x9C, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE1, 0x9E, 0xBC, 0xFE, 0x44, 0x63, 0x6D), + MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x43, 0x71, 0xEE, 0xF8, 0xC1, 0x8C, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x6A, 0x4B, 0xF0, 0x69, 0x25, 0xBD, 0x71, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x9A, 0xFE, 0x82, 0xE7, 0xC1, 0xC1, 0xEE), + MBEDTLS_BYTES_TO_T_UINT_8(0xFC, 0x5A, 0x6E, 0x5E, 0x97, 0x6A, 0x35, 0x8D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_15_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA2, 0x18, 0x6C, 0x7E, 0xB8, 0x9E, 0x57, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x35, 0xB9, 0xC1, 0xD0, 0xFE, 0x78, 0xFB, 0x32), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x08, 0xAE, 0x46, 0x34, 0xEA, 0x7A, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x1C, 0x56, 0xA9, 0x18, 0x37, 0xD4, 0x9E), + MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x63, 0xE9, 0x0A, 0xB6, 0x38, 0x3C, 0xC1), + MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0x4F, 0xA4, 0x6E, 0x85, 0x31, 0x23, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x0D, 0xAD, 0xC4, 0xC3, 0xB1, 0x4B, 0x1C, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x56, 0x4A, 0x38, 0xB3, 0x6B, 0x6F, 0x2C), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_16_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0xC7, 0x19, 0xDE, 0x21, 0xED, 0x89, 0xD0), + MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xBE, 0xA6, 0xAE, 0xEB, 0x9D, 0xA7, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x0E, 0x13, 0x1E, 0x86, 0x57, 0xC3, 0x3B), + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x4B, 0x30, 0x46, 0x52, 0xC1, 0xEC, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x6E, 0xD5, 0x44, 0x31, 0x96, 0x3B, 0x26, 0x27), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x68, 0xA8, 0x67, 0x78, 0x39, 0xE8, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x78, 0xB7, 0xDD, 0xF2, 0x58, 0xB6, 0x3D), + MBEDTLS_BYTES_TO_T_UINT_8(0x81, 0x3C, 0xB3, 0x26, 0xC4, 0x2C, 0x8C, 0xA5), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_16_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x24, 0xE5, 0x73, 0xEE, 0x9A, 0x02, 0xA9), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x6A, 0x65, 0x60, 0xF3, 0x62, 0xE3, 0xE9), + MBEDTLS_BYTES_TO_T_UINT_8(0xFB, 0x07, 0x84, 0xE6, 0x3B, 0x46, 0x65, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x8F, 0x0C, 0xB0, 0xE1, 0x04, 0x82, 0x9D), + MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0x13, 0xBF, 0x3D, 0xA0, 0x48, 0xA2, 0x74), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0x26, 0x76, 0x74, 0xAB, 0x0B, 0x29, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0x30, 0x6E, 0x5F, 0x03, 0x34, 0x7C, 0x38, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x72, 0xF9, 0x3B, 0x3C, 0xA4, 0xBC, 0x7C), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_17_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xCE, 0x18, 0x80, 0xB8, 0x24, 0x45, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x09, 0x03, 0xB8, 0x06, 0x64, 0xF7, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x26, 0xB1, 0x10, 0x6D, 0x71, 0x12, 0x2E), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x12, 0xC6, 0x6E, 0x1E, 0x6A, 0xC3, 0x80), + MBEDTLS_BYTES_TO_T_UINT_8(0xE5, 0xD3, 0x0A, 0xDE, 0xD8, 0x6B, 0x04, 0x5C), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x87, 0x5B, 0xAE, 0xDB, 0x3C, 0xC0, 0xC5), + MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0xF5, 0xF9, 0xC1, 0x9A, 0x89, 0xBB, 0x7E), + MBEDTLS_BYTES_TO_T_UINT_8(0xED, 0x69, 0x72, 0x8B, 0xAE, 0x32, 0x13, 0x11), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_17_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x16, 0x07, 0x50, 0xFA, 0x4C, 0xCF, 0xE8), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x50, 0x21, 0xE9, 0xDE, 0xEC, 0x7E, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x2F, 0xE8, 0x83, 0x30, 0x0B, 0x65, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x0B, 0x99, 0xAC, 0xC9, 0xBA, 0x6C, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x59, 0x5A, 0x0D, 0x7B, 0x9E, 0x08, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x91, 0xB2, 0xDC, 0x90, 0xCE, 0x67, 0xED), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x93, 0x60, 0x0C, 0xD7, 0x1F, 0x2F, 0x17), + MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x7F, 0x9D, 0x40, 0xF8, 0x78, 0x7A, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_18_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x13, 0x22, 0x95, 0xE8, 0xEF, 0x31, 0x57, 0x35), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x88, 0x53, 0xFE, 0xAF, 0x7C, 0x47, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xCE, 0xCC, 0x79, 0xE8, 0x9F, 0x8C, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0xDB, 0x16, 0xDD, 0x77, 0x6E, 0x8A, 0x73, 0x97), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x07, 0x97, 0x21, 0x3B, 0xF8, 0x5F, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0xC6, 0xB5, 0xD2, 0x81, 0x84, 0xF0, 0xE7, 0x9F), + MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x8F, 0x75, 0x09, 0x6A, 0x0E, 0x53, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x4F, 0x70, 0x97, 0xC7, 0xAC, 0x7D, 0x3F), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_18_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF9, 0x3C, 0x6A, 0xB4, 0x10, 0xA9, 0xC8, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xC5, 0xD6, 0x69, 0x16, 0xB8, 0xAC, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x44, 0xDC, 0xEB, 0x48, 0x54, 0x5D, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x48, 0x9B, 0xD7, 0x72, 0x69, 0xA4, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x0D, 0x36, 0x9A, 0x66, 0x0B, 0xEC, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0xC6, 0xD4, 0xB6, 0x60, 0xE5, 0xC3, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x29, 0x42, 0xE0, 0x9D, 0xFD, 0x7C, 0x3E), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x10, 0xBA, 0x55, 0xBC, 0x3B, 0x38, 0x5D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_19_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x25, 0x66, 0xFA, 0x05, 0x73, 0x03, 0x1B, 0x69), + MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0xA4, 0x66, 0x12, 0x96, 0x7B, 0x02, 0x4C), + MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0xB5, 0xDE, 0x6D, 0x98, 0xD1, 0xD5, 0xA8), + MBEDTLS_BYTES_TO_T_UINT_8(0xE2, 0xF5, 0x44, 0xB8, 0x8E, 0xF6, 0x8C, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x15, 0x2B, 0x72, 0xBC, 0x49, 0xE5, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x44, 0xD7, 0xDF, 0x8F, 0xEB, 0x8D, 0x80), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x64, 0x88, 0xAA, 0xB7, 0xE4, 0x70, 0x1D), + MBEDTLS_BYTES_TO_T_UINT_8(0x9C, 0x14, 0xBB, 0xE9, 0x9B, 0xB9, 0x65, 0x5D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_19_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0x8E, 0x88, 0xF5, 0xF1, 0xC1, 0x89, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x30, 0x53, 0xE6, 0xFB, 0x2D, 0x82, 0xB4), + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0xE4, 0xFF, 0xBA, 0x31, 0x79, 0xAB, 0xC2), + MBEDTLS_BYTES_TO_T_UINT_8(0x45, 0x09, 0xF7, 0xB7, 0x09, 0x78, 0x4C, 0x90), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xAE, 0xC2, 0x44, 0xDC, 0x17, 0x78, 0x47), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xD4, 0x17, 0x43, 0x19, 0x74, 0x9E, 0x23), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x64, 0x3B, 0x73, 0xA2, 0x99, 0x27, 0x76), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x74, 0x36, 0x5F, 0xD3, 0x14, 0xB1, 0x31), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_20_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0x07, 0xAB, 0xFD, 0x9B, 0x03, 0xC5, 0xD5), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0xBE, 0xB0, 0x1D, 0xF2, 0x0C, 0x73, 0x73), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xE7, 0x7B, 0x87, 0xD3, 0x34, 0xFD, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x9A, 0x25, 0x3D, 0xC7, 0x36, 0x83, 0x53, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x7C, 0xCF, 0x63, 0x55, 0x12, 0x11, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0x34, 0x4D, 0x27, 0x92, 0xAC, 0x18, 0x16), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x42, 0x61, 0x9D, 0x2E, 0xFF, 0x13, 0x16), + MBEDTLS_BYTES_TO_T_UINT_8(0xF4, 0xDE, 0x92, 0x65, 0x57, 0x0D, 0xBC, 0x0A), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_20_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x7B, 0x6E, 0xC6, 0x2A, 0x21, 0x74, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xA7, 0x53, 0x4D, 0x29, 0x36, 0xEF, 0xE5), + MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0xD6, 0x41, 0xC7, 0x99, 0xAD, 0x50, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0x99, 0xAC, 0x41, 0x9F, 0xFB, 0x4C, 0x86, 0xF1), + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xBB, 0xE6, 0x25, 0x28, 0xAA, 0xEB, 0x1E), + MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x04, 0xA2, 0xC3, 0xAA, 0x08, 0x8A, 0xCC), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x2B, 0x5B, 0xE2, 0x8D, 0x76, 0xEA, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x33, 0xD2, 0x21, 0x4D, 0x62, 0xE3, 0x8E), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_21_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x06, 0x8B, 0x2B, 0xC2, 0xC4, 0xB1, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xF5, 0xA1, 0xC0, 0x03, 0x6A, 0x29, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0xA9, 0xEF, 0x55, 0xB6, 0x1A, 0x9F, 0x6B), + MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x54, 0x32, 0xBE, 0x06, 0x43, 0xB5, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xD6, 0xD9, 0x20, 0x89, 0xBE, 0xD4, 0x1B), + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x26, 0x95, 0x10, 0xCE, 0xB4, 0x88, 0x79), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xA6, 0x27, 0xAC, 0x32, 0xBA, 0xBD, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0xA6, 0xAE, 0x9C, 0x7B, 0xBE, 0xA1, 0x63), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_21_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xCD, 0x4D, 0x3D, 0xDF, 0x96, 0xBB, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0xA7, 0x11, 0x06, 0xCC, 0x0E, 0x31, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0x20, 0xE4, 0xF4, 0xAD, 0x7B, 0x5F, 0xF1, 0xEF), + MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0x54, 0xBE, 0xF4, 0x8A, 0x03, 0x47, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x53, 0x00, 0x7F, 0xB0, 0x8A, 0x68, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x16, 0xB1, 0x73, 0x6F, 0x5B, 0x0E, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x32, 0xE3, 0x43, 0x64, 0x75, 0xFB, 0xFB), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x18, 0x55, 0x8A, 0x4E, 0x6E, 0x35, 0x54), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_22_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x80, 0x97, 0x15, 0x1E, 0xCB, 0xF2, 0x9C, 0xA5), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0xD1, 0xBB, 0xF3, 0x70, 0xAD, 0x13, 0xAD), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0x96, 0xA4, 0xC5, 0x5E, 0xDA, 0xD5, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x81, 0xE9, 0x65, 0x66, 0x76, 0x47, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x35, 0x87, 0x06, 0x73, 0xCF, 0x34, 0xD2), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x81, 0x15, 0x42, 0xA2, 0x79, 0x5B, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x08, 0xA2, 0x7D, 0x09, 0x14, 0x64, 0xC6, 0xAE), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x6D, 0xC4, 0xED, 0xF1, 0xD6, 0xE9, 0x24), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_22_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xD5, 0xBB, 0x25, 0xA3, 0xDD, 0xA3, 0x88), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xF2, 0x68, 0x67, 0x39, 0x8F, 0x73, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x76, 0x28, 0x89, 0xAD, 0x32, 0xE0, 0xDF), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0x90, 0xCC, 0x57, 0x58, 0xAA, 0xC9, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD7, 0x43, 0xD2, 0xCE, 0x5E, 0xA0, 0x08), + MBEDTLS_BYTES_TO_T_UINT_8(0x33, 0xB0, 0xB8, 0xA4, 0x9E, 0x96, 0x26, 0x86), + MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0x61, 0x1D, 0xF3, 0x65, 0x5E, 0x60, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xC7, 0x1E, 0x65, 0xED, 0xCF, 0x07, 0x60, 0x20), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_23_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x30, 0x17, 0x8A, 0x91, 0x88, 0x0A, 0xA4), + MBEDTLS_BYTES_TO_T_UINT_8(0x05, 0x7D, 0x18, 0xA4, 0xAC, 0x59, 0xFC, 0x5F), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x31, 0x8B, 0x25, 0x65, 0x39, 0x9A, 0xDC), + MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x16, 0x4B, 0x68, 0xBA, 0x59, 0x13, 0x2F), + MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xD3, 0xC5, 0x56, 0xC9, 0x8C, 0x5E), + MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xC6, 0x9F, 0xF4, 0xE6, 0xF7, 0xB4, 0x01), + MBEDTLS_BYTES_TO_T_UINT_8(0x2D, 0x7C, 0x03, 0x00, 0x26, 0x9F, 0xD8, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x1D, 0x6E, 0x00, 0xB9, 0x00, 0x6E, 0x93), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_23_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x63, 0xDA, 0x03, 0x2B, 0xD5, 0x0B, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x46, 0xFC, 0xE2, 0xC8, 0x47, 0xF0, 0xAE, 0xF2), + MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x4C, 0xF7, 0x50, 0x0C, 0x48, 0x06, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2B, 0x32, 0x98, 0x0E, 0x7E, 0x61, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x02, 0x27, 0xFE, 0x75, 0x86, 0xDF, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0x2B, 0x30, 0xB1, 0x22, 0x32, 0x1B, 0xFE, 0x24), + MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x27, 0xF7, 0x78, 0x6F, 0xD7, 0xFD, 0xE4), + MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x78, 0xCC, 0xEA, 0xC0, 0x50, 0x24, 0x44), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_24_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x2B, 0x4F, 0x7F, 0x58, 0xE6, 0xC2, 0x70), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x43, 0xD5, 0xA7, 0x35, 0x3C, 0x80, 0xB8), + MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x6D, 0x4B, 0x12, 0x00, 0x7B, 0xE6, 0xA6), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x15, 0xBD, 0xD0, 0x9B, 0xCA, 0xAA, 0x81), + MBEDTLS_BYTES_TO_T_UINT_8(0xCF, 0xCE, 0x9C, 0xE3, 0x8B, 0x60, 0x7A, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0xDA, 0x4B, 0x03, 0xA7, 0x8D, 0x43, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0xAF, 0x00, 0x2B, 0x32, 0xF0, 0x22, 0x68), + MBEDTLS_BYTES_TO_T_UINT_8(0xDC, 0xD9, 0x99, 0x99, 0xBE, 0x43, 0x99, 0x3E), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_24_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x71, 0x41, 0xF4, 0xB5, 0xFD, 0xDD, 0x36), + MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xE2, 0x20, 0x4C, 0xD1, 0x2E, 0x1F, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0x43, 0x48, 0x76, 0x8A, 0x49, 0xAC, 0x87), + MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x1A, 0x55, 0xA8, 0xA3, 0xD4, 0x57, 0x75), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0xA6, 0x84, 0x39, 0xC9, 0x13, 0xBB, 0x60), + MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xFA, 0xA9, 0x70, 0xDE, 0x83, 0xDD, 0xC9), + MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0xC9, 0xD9, 0x3E, 0x44, 0x91, 0x68, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x9F, 0x85, 0x6D, 0xF7, 0x54, 0x36, 0x82), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_25_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x6B, 0xA6, 0xA3, 0xE5, 0xD4, 0x46, 0xDB), + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x3E, 0xDC, 0x84, 0x7C, 0x7B, 0x24, 0x34), + MBEDTLS_BYTES_TO_T_UINT_8(0x14, 0xED, 0x7F, 0x86, 0x07, 0x6C, 0x57, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0x95, 0x06, 0xFE, 0x52, 0x12, 0x79, 0x69, 0x56), + MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0xD1, 0x44, 0x5F, 0x21, 0x3A, 0xC3, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0xD9, 0x4A, 0xC0, 0x75, 0xAB, 0x17, 0xAC), + MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x81, 0x94, 0xB6, 0x80, 0x6B, 0x6F, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBE, 0x8E, 0xA5, 0xAA, 0xBC, 0x1E, 0x3E), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_25_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0xC7, 0x85, 0xA6, 0x59, 0x9B, 0xB1, 0x52), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xCE, 0x40, 0xD1, 0xFB, 0xDF, 0x94, 0xF7), + MBEDTLS_BYTES_TO_T_UINT_8(0x18, 0xB8, 0x5E, 0xBF, 0x45, 0xA8, 0x2D, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9C, 0x06, 0x1B, 0xA9, 0x57, 0xB9, 0x79), + MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xE9, 0xCE, 0xA2, 0xD3, 0x74, 0xA1, 0x3C), + MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x5F, 0x34, 0x78, 0xDB, 0xAE, 0x3A, 0x14), + MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x32, 0x84, 0x3E, 0x68, 0x6A, 0x43, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0xBC, 0x39, 0x36, 0xA4, 0xC5, 0xBB, 0x11), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_26_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x8C, 0x07, 0xA2, 0xB5, 0xC9, 0x0F, 0x4D, 0x0F), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x1D, 0x67, 0xE6, 0xF1, 0x46, 0xEB, 0x71), + MBEDTLS_BYTES_TO_T_UINT_8(0xD7, 0x41, 0x23, 0x95, 0xE7, 0xE0, 0x10, 0xDD), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x69, 0xFE, 0x68, 0x8C, 0xC6, 0x5F, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0xB9, 0x2B, 0x3D, 0xD2, 0x4F, 0xD8, 0x1A), + MBEDTLS_BYTES_TO_T_UINT_8(0xA3, 0x09, 0xF5, 0x5F, 0xCF, 0xF6, 0x91, 0x57), + MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x15, 0x42, 0x6B, 0x6D, 0xB5, 0xF3, 0xB6), + MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x56, 0x9D, 0xC5, 0xFF, 0xCA, 0x13, 0x9B), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_26_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0x38, 0xE6, 0x23, 0x63, 0x48, 0x3C, 0xCA), + MBEDTLS_BYTES_TO_T_UINT_8(0xD2, 0x68, 0x3C, 0xD1, 0x3B, 0xE9, 0x3B, 0x82), + MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0x08, 0x54, 0x49, 0xD1, 0x46, 0x45, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x70, 0x52, 0x6E, 0x79, 0xC4, 0x5E, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xDF, 0xE8, 0x5A, 0x32, 0x81, 0xDA, 0xD3), + MBEDTLS_BYTES_TO_T_UINT_8(0x3C, 0x2D, 0x94, 0x5B, 0xB5, 0x35, 0x9F, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x2A, 0x12, 0x8D, 0xC3, 0x36, 0x36, 0xB2, 0x2A), + MBEDTLS_BYTES_TO_T_UINT_8(0x39, 0x2F, 0x22, 0x38, 0x5B, 0x18, 0x4C, 0x35), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_27_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC1, 0x22, 0x0E, 0xF0, 0x73, 0x11, 0x05), + MBEDTLS_BYTES_TO_T_UINT_8(0xB2, 0xAE, 0xA4, 0x56, 0x18, 0x61, 0x66, 0x12), + MBEDTLS_BYTES_TO_T_UINT_8(0x79, 0xFB, 0x72, 0x08, 0x84, 0x38, 0x51, 0xB0), + MBEDTLS_BYTES_TO_T_UINT_8(0xDA, 0x86, 0xA8, 0xB9, 0x31, 0x99, 0x29, 0xC3), + MBEDTLS_BYTES_TO_T_UINT_8(0x8A, 0xFB, 0xC3, 0x42, 0xB3, 0xC7, 0x6F, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0xD8, 0xF8, 0xE1, 0x09, 0xBE, 0x75, 0xB0, 0x22), + MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x7D, 0xFF, 0xF4, 0x99, 0xFC, 0x13, 0xAB), + MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x1B, 0x84, 0x81, 0x42, 0x22, 0xC6, 0x3D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_27_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xE0, 0x37, 0xA4, 0xA0, 0x2F, 0x38, 0x7F), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x3D, 0xB7, 0x40, 0x2F, 0x39, 0x3C, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0x3B, 0x8A, 0x51, 0xAE, 0x40, 0x49, 0x7A), + MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0x20, 0x9F, 0xDD, 0xA9, 0xD0, 0x77, 0xC7), + MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0x1D, 0x64, 0xDA, 0xA0, 0x53, 0xC7, 0x7D), + MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x7B, 0x66, 0x55, 0x94, 0xD1, 0x51, 0x44), + MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xA9, 0xB5, 0x5B, 0x38, 0x35, 0x40, 0xC0), + MBEDTLS_BYTES_TO_T_UINT_8(0xC8, 0xC9, 0x0F, 0xF0, 0x73, 0x79, 0x43, 0x61), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_28_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x47, 0x45, 0x69, 0x80, 0x72, 0x72, 0x42), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x11, 0x99, 0x59, 0xDB, 0x48, 0x80, 0x39), + MBEDTLS_BYTES_TO_T_UINT_8(0x75, 0x6E, 0x3D, 0xFC, 0x37, 0x15, 0xF4, 0xBF), + MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xBB, 0x5B, 0xA6, 0x35, 0x8D, 0x28, 0x20), + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0x1A, 0x3B, 0x2C, 0x8F, 0xD3, 0xAA, 0x2D), + MBEDTLS_BYTES_TO_T_UINT_8(0x55, 0x1C, 0x1A, 0xF8, 0x02, 0xD9, 0x7B, 0x41), + MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0x69, 0xAC, 0xF8, 0x54, 0x31, 0x14, 0xA1), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x8A, 0xE6, 0xDE, 0x58, 0xB9, 0xC4, 0x7A), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_28_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x83, 0x52, 0xFE, 0xF9, 0x7B, 0xE9, 0x1F), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xA2, 0x55, 0x46, 0x15, 0x49, 0xC1, 0x3A), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xBC, 0x5C, 0x91, 0xBD, 0xB9, 0x9C, 0xF4), + MBEDTLS_BYTES_TO_T_UINT_8(0xBB, 0xFD, 0xB1, 0x4E, 0x5F, 0x74, 0xEE, 0x53), + MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0x8B, 0xD8, 0x8B, 0x17, 0x73, 0x1B, 0x96), + MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x92, 0xD7, 0x67, 0x06, 0xAD, 0x25, 0xCD), + MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x0F, 0x80, 0x24, 0xE2, 0x27, 0x5F, 0x8B), + MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x1C, 0xCE, 0xD0, 0x67, 0xCA, 0xD4, 0x0B), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_29_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0xF1, 0xDD, 0x33, 0x66, 0xF9, 0x05, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x1D, 0xE5, 0x6B, 0x79, 0xBD, 0x48, 0x42, 0xAA), + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x14, 0x52, 0xE3, 0x53, 0xB4, 0x50, 0xD4), + MBEDTLS_BYTES_TO_T_UINT_8(0x32, 0x84, 0x6C, 0xCF, 0xDA, 0xB2, 0x20, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0xD6, 0x1A, 0xE5, 0xE2, 0x29, 0x70, 0xCE), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x61, 0xFE, 0xBB, 0x21, 0x82, 0xD1, 0xFE), + MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0xF0, 0x9C, 0x8B, 0x1A, 0x42, 0x30, 0x06), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0xD6, 0x49, 0x81, 0x92, 0xF1, 0xD0, 0x90), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_29_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x91, 0x93, 0x6A, 0xA6, 0x22, 0xE9, 0xD6), + MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0xDC, 0xC3, 0x69, 0x11, 0x95, 0x7D, 0xEC), + MBEDTLS_BYTES_TO_T_UINT_8(0x1C, 0xA3, 0x9D, 0x87, 0x5E, 0x64, 0x41, 0xA2), + MBEDTLS_BYTES_TO_T_UINT_8(0xBE, 0x87, 0x5A, 0x15, 0xBD, 0x6E, 0x3C, 0x8D), + MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0x8D, 0x50, 0xCC, 0xCF, 0xB7, 0x8F, 0x0B), + MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x65, 0xCD, 0x31, 0x30, 0xF1, 0x68, 0x13), + MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x5C, 0x66, 0x67, 0x92, 0x30, 0x57, 0x95), + MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x9B, 0x01, 0x3D, 0x20, 0x8B, 0xD1, 0x0D), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_30_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xAB, 0xC0, 0xE6, 0x4F, 0xDE, 0x62, 0xAB, 0xB3), + MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0x48, 0xB3, 0x1C, 0x0F, 0x16, 0x93, 0x45), + MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x63, 0xBD, 0x1F, 0x16, 0x50, 0x56, 0x98), + MBEDTLS_BYTES_TO_T_UINT_8(0x5D, 0x06, 0xBC, 0xE9, 0x27, 0x1C, 0x9A, 0x7B), + MBEDTLS_BYTES_TO_T_UINT_8(0xF8, 0xFE, 0x21, 0xC5, 0x39, 0x55, 0xE1, 0xFD), + MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xA8, 0xD0, 0x96, 0x0E, 0xB5, 0xB2, 0x84), + MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0xE7, 0x4B, 0xF3, 0x11, 0x0C, 0xC9, 0x5B), + MBEDTLS_BYTES_TO_T_UINT_8(0x43, 0x3A, 0xC4, 0x87, 0x71, 0xEE, 0xFA, 0x18), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_30_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x77, 0xEE, 0x81, 0x5E, 0x96, 0xEA, 0x4B), + MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0xDF, 0xA9, 0xF4, 0x4F, 0x7C, 0xB2, 0x43), + MBEDTLS_BYTES_TO_T_UINT_8(0x9F, 0xD4, 0xDF, 0x35, 0x63, 0x47, 0x25, 0x8A), + MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x3D, 0xFF, 0xA4, 0x02, 0xC3, 0x95, 0x11), + MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x10, 0x78, 0xD1, 0x2B, 0xB7, 0xBE, 0x0E), + MBEDTLS_BYTES_TO_T_UINT_8(0x0A, 0xE9, 0x57, 0xF9, 0xE0, 0xD8, 0xFC, 0xBC), + MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0xC4, 0x01, 0xD6, 0xB4, 0xE7, 0x78, 0xE2), + MBEDTLS_BYTES_TO_T_UINT_8(0x02, 0x6C, 0xB9, 0x13, 0xA4, 0xE8, 0x6D, 0x6F), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_31_X[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0xB0, 0xC9, 0xCD, 0xBF, 0xA2, 0x1E, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0x4F, 0x86, 0x22, 0x9B, 0xEA, 0xE8, 0xBB), + MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x46, 0xDF, 0x43, 0xB9, 0x82, 0x2D, 0x0A), + MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x32, 0xF1, 0x4E, 0x95, 0x41, 0xAE, 0x8E), + MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0x93, 0x26, 0xFC, 0xD3, 0x90, 0xDC, 0xEB), + MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0x05, 0x45, 0xCA, 0xF9, 0x5A, 0x89, 0x93), + MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x82, 0x63, 0x4E, 0x55, 0x1D, 0x3A, 0x08), + MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x69, 0x52, 0x49, 0xE9, 0xED, 0x57, 0x34), +}; +static const mbedtls_mpi_uint brainpoolP512r1_T_31_Y[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x64, 0xE9, 0xAC, 0x4C, 0x4A, 0xEA, 0x25), + MBEDTLS_BYTES_TO_T_UINT_8(0xE9, 0xE9, 0x0B, 0x99, 0xE7, 0xF9, 0xA9, 0x2C), + MBEDTLS_BYTES_TO_T_UINT_8(0x24, 0x0C, 0xC1, 0xF4, 0x8D, 0x07, 0xB6, 0xB1), + MBEDTLS_BYTES_TO_T_UINT_8(0xAD, 0x68, 0xFA, 0x35, 0xE4, 0x9E, 0xAE, 0xD9), + MBEDTLS_BYTES_TO_T_UINT_8(0xF0, 0x2D, 0x1A, 0x13, 0x8E, 0x02, 0xE2, 0x63), + MBEDTLS_BYTES_TO_T_UINT_8(0x27, 0x38, 0x28, 0x86, 0x46, 0x7B, 0x3A, 0xE1), + MBEDTLS_BYTES_TO_T_UINT_8(0x3F, 0x4C, 0x64, 0x59, 0x0A, 0xF9, 0x02, 0xC4), + MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x4F, 0x23, 0xA2, 0xC3, 0xD5, 0xEF, 0x42), +}; +static const mbedtls_ecp_point brainpoolP512r1_T[32] = { + ECP_POINT_INIT_XY_Z1(brainpoolP512r1_T_0_X, brainpoolP512r1_T_0_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_1_X, brainpoolP512r1_T_1_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_2_X, brainpoolP512r1_T_2_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_3_X, brainpoolP512r1_T_3_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_4_X, brainpoolP512r1_T_4_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_5_X, brainpoolP512r1_T_5_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_6_X, brainpoolP512r1_T_6_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_7_X, brainpoolP512r1_T_7_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_8_X, brainpoolP512r1_T_8_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_9_X, brainpoolP512r1_T_9_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_10_X, brainpoolP512r1_T_10_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_11_X, brainpoolP512r1_T_11_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_12_X, brainpoolP512r1_T_12_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_13_X, brainpoolP512r1_T_13_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_14_X, brainpoolP512r1_T_14_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_15_X, brainpoolP512r1_T_15_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_16_X, brainpoolP512r1_T_16_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_17_X, brainpoolP512r1_T_17_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_18_X, brainpoolP512r1_T_18_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_19_X, brainpoolP512r1_T_19_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_20_X, brainpoolP512r1_T_20_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_21_X, brainpoolP512r1_T_21_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_22_X, brainpoolP512r1_T_22_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_23_X, brainpoolP512r1_T_23_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_24_X, brainpoolP512r1_T_24_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_25_X, brainpoolP512r1_T_25_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_26_X, brainpoolP512r1_T_26_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_27_X, brainpoolP512r1_T_27_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_28_X, brainpoolP512r1_T_28_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_29_X, brainpoolP512r1_T_29_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_30_X, brainpoolP512r1_T_30_Y), + ECP_POINT_INIT_XY_Z0(brainpoolP512r1_T_31_X, brainpoolP512r1_T_31_Y), +}; +#else +#define brainpoolP512r1_T NULL +#endif +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +#if defined(ECP_LOAD_GROUP) +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint)) + */ +static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) +{ + X->s = 1; + X->n = (unsigned short) (len / sizeof(mbedtls_mpi_uint)); + X->p = (mbedtls_mpi_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +static inline void ecp_mpi_set1(mbedtls_mpi *X) +{ + X->s = 1; + X->n = 1; + X->p = mpi_one; +} + +/* + * Make group available from embedded constants + */ +static int ecp_group_load(mbedtls_ecp_group *grp, + const mbedtls_mpi_uint *p, size_t plen, + const mbedtls_mpi_uint *a, size_t alen, + const mbedtls_mpi_uint *b, size_t blen, + const mbedtls_mpi_uint *gx, size_t gxlen, + const mbedtls_mpi_uint *gy, size_t gylen, + const mbedtls_mpi_uint *n, size_t nlen, + const mbedtls_ecp_point *T) +{ + ecp_mpi_load(&grp->P, p, plen); + if (a != NULL) { + ecp_mpi_load(&grp->A, a, alen); + } + ecp_mpi_load(&grp->B, b, blen); + ecp_mpi_load(&grp->N, n, nlen); + + ecp_mpi_load(&grp->G.X, gx, gxlen); + ecp_mpi_load(&grp->G.Y, gy, gylen); + ecp_mpi_set1(&grp->G.Z); + + grp->pbits = mbedtls_mpi_bitlen(&grp->P); + grp->nbits = mbedtls_mpi_bitlen(&grp->N); + + grp->h = 1; + + grp->T = (mbedtls_ecp_point *) T; + /* + * Set T_size to 0 to prevent T free by mbedtls_ecp_group_free. + */ + grp->T_size = 0; + + return 0; +} +#endif /* ECP_LOAD_GROUP */ + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521(mbedtls_mpi *); +#endif + +#define NIST_MODP(P) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP(P) +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +static int ecp_mod_p255(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +static int ecp_mod_p448(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1(mbedtls_mpi *); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1(mbedtls_mpi *); +#endif + +#if defined(ECP_LOAD_GROUP) +#define LOAD_GROUP_A(G) ecp_group_load(grp, \ + G ## _p, sizeof(G ## _p), \ + G ## _a, sizeof(G ## _a), \ + G ## _b, sizeof(G ## _b), \ + G ## _gx, sizeof(G ## _gx), \ + G ## _gy, sizeof(G ## _gy), \ + G ## _n, sizeof(G ## _n), \ + G ## _T \ + ) + +#define LOAD_GROUP(G) ecp_group_load(grp, \ + G ## _p, sizeof(G ## _p), \ + NULL, 0, \ + G ## _b, sizeof(G ## _b), \ + G ## _gx, sizeof(G ## _gx), \ + G ## _gy, sizeof(G ## _gy), \ + G ## _n, sizeof(G ## _n), \ + G ## _T \ + ) +#endif /* ECP_LOAD_GROUP */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +/* Constants used by ecp_use_curve25519() */ +static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42; +static const unsigned char curve25519_part_of_n[] = { + 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6, + 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED, +}; + +/* + * Specialized function for creating the Curve25519 group + */ +static int ecp_use_curve25519(mbedtls_ecp_group *grp) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* Actually ( A + 2 ) / 4 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24)); + + /* P = 2^255 - 19 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19)); + grp->pbits = mbedtls_mpi_bitlen(&grp->P); + + /* N = 2^252 + 27742317777372353535851937790883648493 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N, + curve25519_part_of_n, sizeof(curve25519_part_of_n))); + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1)); + + /* Y intentionally not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); + mbedtls_mpi_free(&grp->G.Y); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if (ret != 0) { + mbedtls_ecp_group_free(grp); + } + + return ret; +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +/* Constants used by ecp_use_curve448() */ +static const mbedtls_mpi_sint curve448_a24 = 0x98AA; +static const unsigned char curve448_part_of_n[] = { + 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24, + 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93, + 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC, + 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D, +}; + +/* + * Specialized function for creating the Curve448 group + */ +static int ecp_use_curve448(mbedtls_ecp_group *grp) +{ + mbedtls_mpi Ns; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + mbedtls_mpi_init(&Ns); + + /* Actually ( A + 2 ) / 4 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24)); + + /* P = 2^448 - 2^224 - 1 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224)); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1)); + grp->pbits = mbedtls_mpi_bitlen(&grp->P); + + /* Y intentionally not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5)); + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1)); + mbedtls_mpi_free(&grp->G.Y); + + /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns, + curve448_part_of_n, sizeof(curve448_part_of_n))); + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns)); + + /* Actually, the required msb for private keys */ + grp->nbits = 447; + +cleanup: + mbedtls_mpi_free(&Ns); + if (ret != 0) { + mbedtls_ecp_group_free(grp); + } + + return ret; +} +#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id) +{ + ECP_VALIDATE_RET(grp != NULL); + mbedtls_ecp_group_free(grp); + + mbedtls_ecp_group_init(grp); + + grp->id = id; + + switch (id) { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + case MBEDTLS_ECP_DP_SECP192R1: + NIST_MODP(p192); + return LOAD_GROUP(secp192r1); +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + case MBEDTLS_ECP_DP_SECP224R1: + NIST_MODP(p224); + return LOAD_GROUP(secp224r1); +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + case MBEDTLS_ECP_DP_SECP256R1: + NIST_MODP(p256); + return LOAD_GROUP(secp256r1); +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + case MBEDTLS_ECP_DP_SECP384R1: + NIST_MODP(p384); + return LOAD_GROUP(secp384r1); +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + case MBEDTLS_ECP_DP_SECP521R1: + NIST_MODP(p521); + return LOAD_GROUP(secp521r1); +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + case MBEDTLS_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return LOAD_GROUP_A(secp192k1); +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + case MBEDTLS_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return LOAD_GROUP_A(secp224k1); +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + case MBEDTLS_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return LOAD_GROUP_A(secp256k1); +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + case MBEDTLS_ECP_DP_BP256R1: + return LOAD_GROUP_A(brainpoolP256r1); +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + case MBEDTLS_ECP_DP_BP384R1: + return LOAD_GROUP_A(brainpoolP384r1); +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + case MBEDTLS_ECP_DP_BP512R1: + return LOAD_GROUP_A(brainpoolP512r1); +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + grp->modp = ecp_mod_p255; + return ecp_use_curve25519(grp); +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + case MBEDTLS_ECP_DP_CURVE448: + grp->modp = ecp_mod_p448; + return ecp_use_curve448(grp); +#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ + + default: + grp->id = MBEDTLS_ECP_DP_NONE; + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } +} + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic mbedtls_mpi_uint, we can + * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry) +{ + unsigned char i; + mbedtls_mpi_uint c = 0; + for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) { + *dst += c; c = (*dst < c); + *dst += *src; c += (*dst < *src); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry) +{ + unsigned char i; + for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) { + *dst += *carry; + *carry = (*dst < *carry); + } +} + +#define WIDTH 8 / sizeof(mbedtls_mpi_uint) +#define A(i) N->p + (i) * WIDTH +#define ADD(i) add64(p, A(i), &c) +#define NEXT p += WIDTH; carry64(p, &c) +#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +static int ecp_mod_p192(mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi_uint c = 0; + mbedtls_mpi_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH)); + + p = N->p; + end = p + N->n; + + ADD(3); ADD(5); NEXT; // A0 += A3 + A5 + ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5 + ADD(4); ADD(5); LAST; // A2 += A4 + A5 + +cleanup: + return ret; +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A(i); + +#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A(j) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \ + (uint32_t) (N->p[(j)/2]) +#define STORE32 \ + if (i % 2) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (mbedtls_mpi_uint) cur; \ + } + +#endif /* sizeof( mbedtls_mpi_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32(uint32_t *dst, uint32_t src, signed char *carry) +{ + *dst += src; + *carry += (*dst < src); +} + +static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry) +{ + *carry -= (*dst < src); + *dst -= src; +} + +#define ADD(j) add32(&cur, A(j), &c); +#define SUB(j) sub32(&cur, A(j), &c); + +/* + * Helpers for the main 'loop' + */ +#define INIT(b) \ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = (b); \ + /* N is the size of the product of two b-bit numbers, plus one */ \ + /* limb for fix_negative */ \ + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if (cc < 0) \ + sub32(&cur, -cc, &c); \ + else \ + add32(&cur, cc, &c); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while (++i < MAX32) { STORE32; } \ + if (c < 0) mbedtls_ecp_fix_negative(N, c, bits); + +/* + * If the result is negative, we get it in the form + * c * 2^bits + N, with c negative and N positive shorter than 'bits' + */ +static void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits) +{ + size_t i; + + /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so + * set the absolute value to 0xfff...fff - N. There is no carry + * since we're subtracting from all-bits-one. */ + for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) { + N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i]; + } + /* Add 1, taking care of the carry. */ + i = 0; + do { + ++N->p[i]; + } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint)); + /* Invert the sign. + * Now N = N0 - 2^bits where N0 is the initial value of N. */ + N->s = -1; + + /* Add |c| * 2^bits to the absolute value. Since c and N are + * negative, this adds c * 2^bits. */ + mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c; +#if defined(MBEDTLS_HAVE_INT64) + if (bits == 224) { + msw <<= 32; + } +#endif + N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw; +} + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224(mbedtls_mpi *N) +{ + INIT(224); + + SUB(7); SUB(11); NEXT; // A0 += -A7 - A11 + SUB(8); SUB(12); NEXT; // A1 += -A8 - A12 + SUB(9); SUB(13); NEXT; // A2 += -A9 - A13 + SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 + SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 + SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 + SUB(13); ADD(10); LAST; // A6 += -A13 + A10 + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +static int ecp_mod_p256(mbedtls_mpi *N) +{ + INIT(256); + + ADD(8); ADD(9); + SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0 + + ADD(9); ADD(10); + SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1 + + ADD(10); ADD(11); + SUB(13); SUB(14); SUB(15); NEXT; // A2 + + ADD(11); ADD(11); ADD(12); ADD(12); ADD(13); + SUB(15); SUB(8); SUB(9); NEXT; // A3 + + ADD(12); ADD(12); ADD(13); ADD(13); ADD(14); + SUB(9); SUB(10); NEXT; // A4 + + ADD(13); ADD(13); ADD(14); ADD(14); ADD(15); + SUB(10); SUB(11); NEXT; // A5 + + ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13); + SUB(8); SUB(9); NEXT; // A6 + + ADD(15); ADD(15); ADD(15); ADD(8); + SUB(10); SUB(11); SUB(12); SUB(13); LAST; // A7 + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +static int ecp_mod_p384(mbedtls_mpi *N) +{ + INIT(384); + + ADD(12); ADD(21); ADD(20); + SUB(23); NEXT; // A0 + + ADD(13); ADD(22); ADD(23); + SUB(12); SUB(20); NEXT; // A2 + + ADD(14); ADD(23); + SUB(13); SUB(21); NEXT; // A2 + + ADD(15); ADD(12); ADD(20); ADD(21); + SUB(14); SUB(22); SUB(23); NEXT; // A3 + + ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22); + SUB(15); SUB(23); SUB(23); NEXT; // A4 + + ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23); + SUB(16); NEXT; // A5 + + ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22); + SUB(17); NEXT; // A6 + + ADD(19); ADD(16); ADD(15); ADD(23); + SUB(18); NEXT; // A7 + + ADD(20); ADD(17); ADD(16); + SUB(19); NEXT; // A8 + + ADD(21); ADD(18); ADD(17); + SUB(20); NEXT; // A9 + + ADD(22); ADD(19); ADD(18); + SUB(21); NEXT; // A10 + + ADD(23); ADD(20); ADD(19); + SUB(22); LAST; // A11 + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || + MBEDTLS_ECP_DP_SECP256R1_ENABLED || + MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of mbedtls_mpi_uint */ +#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) + +/* Bits to keep in the most significant mbedtls_mpi_uint */ +#define P521_MASK 0x01FF + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +static int ecp_mod_p521(mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + mbedtls_mpi M; + mbedtls_mpi_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if (N->n < P521_WIDTH) { + return 0; + } + + /* M = A1 */ + M.s = 1; + M.n = N->n - (P521_WIDTH - 1); + if (M.n > P521_WIDTH + 1) { + M.n = P521_WIDTH + 1; + } + M.p = Mp; + memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint)))); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for (i = P521_WIDTH; i < N->n; i++) { + N->p[i] = 0; + } + + /* N = A0 + A1 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); + +cleanup: + return ret; +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + +/* Size of p255 in terms of mbedtls_mpi_uint */ +#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^256 A1, return A0 + 38 * A1 + */ +static int ecp_mod_p255(mbedtls_mpi *N) +{ + mbedtls_mpi_uint Mp[P255_WIDTH]; + + /* Helper references for top part of N */ + mbedtls_mpi_uint * const NT_p = N->p + P255_WIDTH; + const size_t NT_n = N->n - P255_WIDTH; + if (N->n <= P255_WIDTH) { + return 0; + } + if (NT_n > P255_WIDTH) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* Split N as N + 2^256 M */ + memcpy(Mp, NT_p, sizeof(mbedtls_mpi_uint) * NT_n); + memset(NT_p, 0, sizeof(mbedtls_mpi_uint) * NT_n); + + /* N = A0 + 38 * A1 */ + mbedtls_mpi_core_mla(N->p, P255_WIDTH + 1, + Mp, NT_n, + 38); + + return 0; +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + +/* Size of p448 in terms of mbedtls_mpi_uint */ +#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint)) + +/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */ +#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y)) +#define P224_SIZE (224 / 8) +#define P224_WIDTH_MIN (P224_SIZE / sizeof(mbedtls_mpi_uint)) +#define P224_WIDTH_MAX DIV_ROUND_UP(P224_SIZE, sizeof(mbedtls_mpi_uint)) +#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224) + +/* + * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 + * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return + * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference + * implementation of Curve448, which uses its own special 56-bit limbs rather + * than a generic bignum library. We could squeeze some extra speed out on + * 32-bit machines by splitting N up into 32-bit limbs and doing the + * arithmetic using the limbs directly as we do for the NIST primes above, + * but for 64-bit targets it should use half the number of operations if we do + * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds. + */ +static int ecp_mod_p448(mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + mbedtls_mpi M, Q; + mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH]; + + if (N->n <= P448_WIDTH) { + return 0; + } + + /* M = A1 */ + M.s = 1; + M.n = N->n - (P448_WIDTH); + if (M.n > P448_WIDTH) { + /* Shouldn't be called with N larger than 2^896! */ + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + M.p = Mp; + memset(Mp, 0, sizeof(Mp)); + memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint)); + + /* N = A0 */ + for (i = P448_WIDTH; i < N->n; i++) { + N->p[i] = 0; + } + + /* N += A1 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M)); + + /* Q = B1, N += B1 */ + Q = M; + Q.p = Qp; + memcpy(Qp, Mp, sizeof(Qp)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q)); + + /* M = (B0 + B1) * 2^224, N += M */ + if (sizeof(mbedtls_mpi_uint) > 4) { + Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS); + } + for (i = P224_WIDTH_MAX; i < M.n; ++i) { + Mp[i] = 0; + } + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q)); + M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */ + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M)); + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P +#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R +static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, mbedtls_mpi_uint mask) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t i; + mbedtls_mpi M, R; + mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; + + if (N->n < p_limbs) { + return 0; + } + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = (unsigned short) (N->n - (p_limbs - adjust)); + if (M.n > p_limbs + adjust) { + M.n = (unsigned short) (p_limbs + adjust); + } + memset(Mp, 0, sizeof(Mp)); + memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint)); + if (shift != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift)); + } + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if (mask != 0) { + N->p[p_limbs - 1] &= mask; + } + for (i = p_limbs; i < N->n; i++) { + N->p[i] = 0; + } + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); + + /* Second pass */ + + /* M = A1 */ + M.n = (unsigned short) (N->n - (p_limbs - adjust)); + if (M.n > p_limbs + adjust) { + M.n = (unsigned short) (p_limbs + adjust); + } + memset(Mp, 0, sizeof(Mp)); + memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint)); + if (shift != 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift)); + } + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if (mask != 0) { + N->p[p_limbs - 1] &= mask; + } + for (i = p_limbs; i < N->n; i++) { + N->p[i] = 0; + } + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R)); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); + +cleanup: + return ret; +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || + MBEDTLS_ECP_DP_SECP224K1_ENABLED) || + MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 + */ +static int ecp_mod_p192k1(mbedtls_mpi *N) +{ + static mbedtls_mpi_uint Rp[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00) + }; + + return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, + 0); +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +static int ecp_mod_p224k1(mbedtls_mpi *N) +{ + static mbedtls_mpi_uint Rp[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00) + }; + +#if defined(MBEDTLS_HAVE_INT64) + return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF); +#else + return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, + 0); +#endif +} + +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +static int ecp_mod_p256k1(mbedtls_mpi *N) +{ + static mbedtls_mpi_uint Rp[] = { + MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00) + }; + return ecp_mod_koblitz(N, Rp, 256 / 8 / sizeof(mbedtls_mpi_uint), 0, 0, + 0); +} +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#if defined(MBEDTLS_TEST_HOOKS) + +MBEDTLS_STATIC_TESTABLE +mbedtls_ecp_variant mbedtls_ecp_get_variant(void) +{ + return MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT; +} + +#endif /* MBEDTLS_TEST_HOOKS */ + +#endif /* !MBEDTLS_ECP_ALT */ + +#endif /* MBEDTLS_ECP_LIGHT */ +#endif /* MBEDTLS_ECP_WITH_MPI_UINT */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecp_internal_alt.h b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_internal_alt.h new file mode 100644 index 0000000..668edc7 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_internal_alt.h @@ -0,0 +1,287 @@ +/** + * \file ecp_internal_alt.h + * + * \brief Function declarations for alternative implementation of elliptic curve + * point arithmetic. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * References: + * + * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records. + * + * + * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + * + * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters. + * + * + * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic + * Curve Cryptography. + * + * [6] Digital Signature Standard (DSS), FIPS 186-4. + * + * + * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer + * Security (TLS), RFC 4492. + * + * + * [8] + * + * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory. + * Springer Science & Business Media, 1 Aug 2000 + */ + +#ifndef MBEDTLS_ECP_INTERNAL_H +#define MBEDTLS_ECP_INTERNAL_H + +#include "mbedtls/build_info.h" + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + +/** + * \brief Indicate if the Elliptic Curve Point module extension can + * handle the group. + * + * \param grp The pointer to the elliptic curve group that will be the + * basis of the cryptographic computations. + * + * \return Non-zero if successful. + */ +unsigned char mbedtls_internal_ecp_grp_capable(const mbedtls_ecp_group *grp); + +/** + * \brief Initialise the Elliptic Curve Point module extension. + * + * If mbedtls_internal_ecp_grp_capable returns true for a + * group, this function has to be able to initialise the + * module for it. + * + * This module can be a driver to a crypto hardware + * accelerator, for which this could be an initialise function. + * + * \param grp The pointer to the group the module needs to be + * initialised for. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_init(const mbedtls_ecp_group *grp); + +/** + * \brief Frees and deallocates the Elliptic Curve Point module + * extension. + * + * \param grp The pointer to the group the module was initialised for. + */ +void mbedtls_internal_ecp_free(const mbedtls_ecp_group *grp); + +#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) +/** + * \brief Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l. + * + * \param grp Pointer to the group representing the curve. + * + * \param pt The point on the curve to be randomised, given with Jacobian + * coordinates. + * + * \param f_rng A function pointer to the random number generator. + * + * \param p_rng A pointer to the random number generator state. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_randomize_jac(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng); +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) +/** + * \brief Addition: R = P + Q, mixed affine-Jacobian coordinates. + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * This function is used only as a subrutine of + * ecp_mul_comb(). + * + * Special cases: (1) P or Q is zero, (2) R is zero, + * (3) P == Q. + * None of these cases can happen as intermediate step in + * ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base + * point, the factor being less than its order, so none of + * them is zero; + * - Q is an odd multiple of the base point, P an even + * multiple, due to the choice of precomputed points in the + * modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as + * meaning 1. + * + * Cost in field operations if done by [5] 3.22: + * 1A := 8M + 3S + * + * \param grp Pointer to the group representing the curve. + * + * \param R Pointer to a point structure to hold the result. + * + * \param P Pointer to the first summand, given with Jacobian + * coordinates + * + * \param Q Pointer to the second summand, given with affine + * coordinates. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_add_mixed(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q); +#endif + +/** + * \brief Point doubling R = 2 P, Jacobian coordinates. + * + * Cost: 1D := 3M + 4S (A == 0) + * 4M + 4S (A == -3) + * 3M + 6S + 1a otherwise + * when the implementation is based on the "dbl-1998-cmo-2" + * doubling formulas in [8] and standard optimizations are + * applied when curve parameter A is one of { 0, -3 }. + * + * \param grp Pointer to the group representing the curve. + * + * \param R Pointer to a point structure to hold the result. + * + * \param P Pointer to the point that has to be doubled, given with + * Jacobian coordinates. + * + * \return 0 if successful. + */ +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) +int mbedtls_internal_ecp_double_jac(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, const mbedtls_ecp_point *P); +#endif + +/** + * \brief Normalize jacobian coordinates of an array of (pointers to) + * points. + * + * Using Montgomery's trick to perform only one inversion mod P + * the cost is: + * 1N(t) := 1I + (6t - 3)M + 1S + * (See for example Algorithm 10.3.4. in [9]) + * + * This function is used only as a subrutine of + * ecp_mul_comb(). + * + * Warning: fails (returning an error) if one of the points is + * zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * \param grp Pointer to the group representing the curve. + * + * \param T Array of pointers to the points to normalise. + * + * \param t_len Number of elements in the array. + * + * \return 0 if successful, + * an error if one of the points is zero. + */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) +int mbedtls_internal_ecp_normalize_jac_many(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *T[], size_t t_len); +#endif + +/** + * \brief Normalize jacobian coordinates so that Z == 0 || Z == 1. + * + * Cost in field operations if done by [5] 3.2.1: + * 1N := 1I + 3M + 1S + * + * \param grp Pointer to the group representing the curve. + * + * \param pt pointer to the point to be normalised. This is an + * input/output parameter. + * + * \return 0 if successful. + */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) +int mbedtls_internal_ecp_normalize_jac(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt); +#endif + +#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) +int mbedtls_internal_ecp_double_add_mxz(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + mbedtls_ecp_point *S, + const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *d); +#endif + +/** + * \brief Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * + * \param grp pointer to the group representing the curve + * + * \param P the point on the curve to be randomised given with + * projective coordinates. This is an input/output parameter. + * + * \param f_rng a function pointer to the random number generator + * + * \param p_rng a pointer to the random number generator state + * + * \return 0 if successful + */ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) +int mbedtls_internal_ecp_randomize_mxz(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P, int (*f_rng)(void *, + unsigned char *, + size_t), + void *p_rng); +#endif + +/** + * \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1. + * + * \param grp pointer to the group representing the curve + * + * \param P pointer to the point to be normalised. This is an + * input/output parameter. + * + * \return 0 if successful + */ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) +int mbedtls_internal_ecp_normalize_mxz(const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P); +#endif + +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + +#endif /* ecp_internal_alt.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/ecp_invasive.h b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_invasive.h new file mode 100644 index 0000000..d12f6e0 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/ecp_invasive.h @@ -0,0 +1,325 @@ +/** + * \file ecp_invasive.h + * + * \brief ECP module: interfaces for invasive testing only. + * + * The interfaces in this file are intended for testing purposes only. + * They SHOULD NOT be made available in library integrations except when + * building the library for testing. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_ECP_INVASIVE_H +#define MBEDTLS_ECP_INVASIVE_H + +#include "common.h" +#include "mbedtls/bignum.h" +//#include "bignum_mod.h" +#include "mbedtls/ecp.h" + +/* + * Curve modulus types + */ +typedef enum { + MBEDTLS_ECP_MOD_NONE = 0, + MBEDTLS_ECP_MOD_COORDINATE, + MBEDTLS_ECP_MOD_SCALAR +} mbedtls_ecp_modulus_type; + +typedef enum { + MBEDTLS_ECP_VARIANT_NONE = 0, + MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT, + MBEDTLS_ECP_VARIANT_WITH_MPI_UINT +} mbedtls_ecp_variant; + +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT) + +/** Queries the ecp variant. + * + * \return The id of the ecp variant. + */ +MBEDTLS_STATIC_TESTABLE +mbedtls_ecp_variant mbedtls_ecp_get_variant(void); + +#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) +/** Generate a private key on a Montgomery curve (Curve25519 or Curve448). + * + * This function implements key generation for the set of secret keys + * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value + * has the lower bits masked but is not necessarily canonical. + * + * \note - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf + * - [RFC7748] https://tools.ietf.org/html/rfc7748 + * + * \p high_bit The position of the high-order bit of the key to generate. + * This is the bit-size of the key minus 1: + * 254 for Curve25519 or 447 for Curve448. + * \param d The randomly generated key. This is a number of size + * exactly \p high_bit + 1 bits, with the least significant bits + * masked as specified in [Curve25519] and in [RFC7748] §5. + * \param f_rng The RNG function. + * \param p_rng The RNG context to be passed to \p f_rng. + * + * \return \c 0 on success. + * \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure. + */ +int mbedtls_ecp_gen_privkey_mx(size_t high_bit, + mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + +/** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + * + * This operation expects a 384 bit MPI and the result of the reduction + * is a 192 bit MPI. + * + * \param[in,out] Np The address of the MPI to be converted. + * Must have twice as many limbs as the modulus. + * Upon return this holds the reduced value. The bitlength + * of the reduced value is the same as that of the modulus + * (192 bits). + * \param[in] Nn The length of \p Np in limbs. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); + +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + +/** Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 448-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (224 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the + * limb size that sores a 448-bit MPI. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + +/** Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 512-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (256 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the + * limb size that sores a 512-bit MPI. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + +/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have twice as many limbs as the modulus + * (the modulus is 521 bits long). Upon return this + * holds the reduced value. The reduced value is + * in range `0 <= X < 2 * N` (where N is the modulus). + * and its the bitlength is one plus the bitlength + * of the modulus. + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have + * twice as many limbs as the modulus. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + +/** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 768-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (384 bits). + * \param[in] X_limbs The length of \p N in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p N_n does not have + * twice as many limbs as the modulus. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + +/** Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9 + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 384-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (192 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + +/** Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 448-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (224 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + +/** Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 512-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (256 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + +/** Fast quasi-reduction modulo p255 = 2^255 - 19 + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 510-bit MPI + * (double the bitlength of the modulus). + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + +/** Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1 + * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 + + * (B0 + B1) * 2^224. + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size that stores a 896-bit MPI + * (double the bitlength of the modulus). Upon return + * holds the reduced value which is in range `0 <= X < + * N` (where N is the modulus). The bitlength of the + * reduced value is the same as that of the modulus + * (448 bits). + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on Success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have + * twice as many limbs as the modulus. + * \return #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation + * failed. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */ + +/** Initialise a modulus with hard-coded const curve data. + * + * \note The caller is responsible for the \p N modulus' memory. + * mbedtls_mpi_mod_modulus_free(&N) should be invoked at the + * end of its lifecycle. + * + * \param[in,out] N The address of the modulus structure to populate. + * Must be initialized. + * \param[in] id The mbedtls_ecp_group_id for which to initialise the modulus. + * \param[in] ctype The mbedtls_ecp_modulus_type identifier for a coordinate modulus (P) + * or a scalar modulus (N). + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not + * have the correct number of limbs. + * + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, + const mbedtls_ecp_group_id id, + const mbedtls_ecp_modulus_type ctype); + +#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */ + +#endif /* MBEDTLS_ECP_INVASIVE_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/gcm.c b/src/app/findmy/crypto/third-party/mbedtls/library/gcm.c new file mode 100644 index 0000000..42fd020 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/gcm.c @@ -0,0 +1,1168 @@ +/* + * NIST SP800-38D compliant GCM implementation + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. + */ + +#include "common.h" + +#if defined(MBEDTLS_GCM_C) + +#include "mbedtls/gcm.h" +#include "mbedtls/platform.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" +#include "mbedtls/constant_time.h" + +#include + +#if defined(MBEDTLS_AESNI_C) +#include "aesni.h" +#endif + +#if defined(MBEDTLS_AESCE_C) +#include "aesce.h" +#endif + +#if !defined(MBEDTLS_GCM_ALT) + +/* + * Initialize a context + */ +void mbedtls_gcm_init(mbedtls_gcm_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_gcm_context)); +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ +static int gcm_gen_table(mbedtls_gcm_context *ctx) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + size_t olen = 0; + + memset(h, 0, 16); + if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) { + return ret; + } + + /* pack h as two 64-bits ints, big-endian */ + hi = MBEDTLS_GET_UINT32_BE(h, 0); + lo = MBEDTLS_GET_UINT32_BE(h, 4); + vh = (uint64_t) hi << 32 | lo; + + hi = MBEDTLS_GET_UINT32_BE(h, 8); + lo = MBEDTLS_GET_UINT32_BE(h, 12); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + +#if defined(MBEDTLS_AESNI_HAVE_CODE) + /* With CLMUL support, we need only h, not the rest of the table */ + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { + return 0; + } +#endif + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + return 0; + } +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for (i = 4; i > 0; i >>= 1) { + uint32_t T = (vl & 1) * 0xe1000000U; + vl = (vh << 63) | (vl >> 1); + vh = (vh >> 1) ^ ((uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for (i = 2; i <= 8; i *= 2) { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for (j = 1; j < i; j++) { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return 0; +} + +int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const mbedtls_cipher_info_t *cipher_info; + + if (keybits != 128 && keybits != 192 && keybits != 256) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, + MBEDTLS_MODE_ECB); + if (cipher_info == NULL) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + if (mbedtls_cipher_info_get_block_size(cipher_info) != 16) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + mbedtls_cipher_free(&ctx->cipher_ctx); + + if ((ret = mbedtls_cipher_setup(&ctx->cipher_ctx, cipher_info)) != 0) { + return ret; + } + + if ((ret = mbedtls_cipher_setkey(&ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT)) != 0) { + return ret; + } + + if ((ret = gcm_gen_table(ctx)) != 0) { + return ret; + } + + return 0; +} + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint16_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult(mbedtls_gcm_context *ctx, const unsigned char x[16], + unsigned char output[16]) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + +#if defined(MBEDTLS_AESNI_HAVE_CODE) + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { + unsigned char h[16]; + + /* mbedtls_aesni_gcm_mult needs big-endian input */ + MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0); + MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4); + MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8); + MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12); + + mbedtls_aesni_gcm_mult(output, x, h); + return; + } +#endif /* MBEDTLS_AESNI_HAVE_CODE */ + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + unsigned char h[16]; + + /* mbedtls_aesce_gcm_mult needs big-endian input */ + MBEDTLS_PUT_UINT32_BE(ctx->HH[8] >> 32, h, 0); + MBEDTLS_PUT_UINT32_BE(ctx->HH[8], h, 4); + MBEDTLS_PUT_UINT32_BE(ctx->HL[8] >> 32, h, 8); + MBEDTLS_PUT_UINT32_BE(ctx->HL[8], h, 12); + + mbedtls_aesce_gcm_mult(output, x, h); + return; + } +#endif + + lo = x[15] & 0xf; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for (i = 15; i >= 0; i--) { + lo = x[i] & 0xf; + hi = (x[i] >> 4) & 0xf; + + if (i != 15) { + rem = (unsigned char) zl & 0xf; + zl = (zh << 60) | (zl >> 4); + zh = (zh >> 4); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = (zh << 60) | (zl >> 4); + zh = (zh >> 4); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + MBEDTLS_PUT_UINT32_BE(zh >> 32, output, 0); + MBEDTLS_PUT_UINT32_BE(zh, output, 4); + MBEDTLS_PUT_UINT32_BE(zl >> 32, output, 8); + MBEDTLS_PUT_UINT32_BE(zl, output, 12); +} + +int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, size_t iv_len) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char work_buf[16]; + const unsigned char *p; + size_t use_len, olen = 0; + uint64_t iv_bits; + + /* IV is limited to 2^64 bits, so 2^61 bytes */ + /* IV is not allowed to be zero length */ + if (iv_len == 0 || (uint64_t) iv_len >> 61 != 0) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + memset(ctx->y, 0x00, sizeof(ctx->y)); + memset(ctx->buf, 0x00, sizeof(ctx->buf)); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if (iv_len == 12) { + memcpy(ctx->y, iv, iv_len); + ctx->y[15] = 1; + } else { + memset(work_buf, 0x00, 16); + iv_bits = (uint64_t) iv_len * 8; + MBEDTLS_PUT_UINT64_BE(iv_bits, work_buf, 8); + + p = iv; + while (iv_len > 0) { + use_len = (iv_len < 16) ? iv_len : 16; + + mbedtls_xor(ctx->y, ctx->y, p, use_len); + + gcm_mult(ctx, ctx->y, ctx->y); + + iv_len -= use_len; + p += use_len; + } + + mbedtls_xor(ctx->y, ctx->y, work_buf, 16); + + gcm_mult(ctx, ctx->y, ctx->y); + } + + if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, + ctx->base_ectr, &olen)) != 0) { + return ret; + } + + return 0; +} + +/** + * mbedtls_gcm_context::buf contains the partial state of the computation of + * the authentication tag. + * mbedtls_gcm_context::add_len and mbedtls_gcm_context::len indicate + * different stages of the computation: + * * len == 0 && add_len == 0: initial state + * * len == 0 && add_len % 16 != 0: the first `add_len % 16` bytes have + * a partial block of AD that has been + * xored in but not yet multiplied in. + * * len == 0 && add_len % 16 == 0: the authentication tag is correct if + * the data ends now. + * * len % 16 != 0: the first `len % 16` bytes have + * a partial block of ciphertext that has + * been xored in but not yet multiplied in. + * * len > 0 && len % 16 == 0: the authentication tag is correct if + * the data ends now. + */ +int mbedtls_gcm_update_ad(mbedtls_gcm_context *ctx, + const unsigned char *add, size_t add_len) +{ + const unsigned char *p; + size_t use_len, offset; + + /* IV is limited to 2^64 bits, so 2^61 bytes */ + if ((uint64_t) add_len >> 61 != 0) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + offset = ctx->add_len % 16; + p = add; + + if (offset != 0) { + use_len = 16 - offset; + if (use_len > add_len) { + use_len = add_len; + } + + mbedtls_xor(ctx->buf + offset, ctx->buf + offset, p, use_len); + + if (offset + use_len == 16) { + gcm_mult(ctx, ctx->buf, ctx->buf); + } + + ctx->add_len += use_len; + add_len -= use_len; + p += use_len; + } + + ctx->add_len += add_len; + + while (add_len >= 16) { + mbedtls_xor(ctx->buf, ctx->buf, p, 16); + + gcm_mult(ctx, ctx->buf, ctx->buf); + + add_len -= 16; + p += 16; + } + + if (add_len > 0) { + mbedtls_xor(ctx->buf, ctx->buf, p, add_len); + } + + return 0; +} + +/* Increment the counter. */ +static void gcm_incr(unsigned char y[16]) +{ + size_t i; + for (i = 16; i > 12; i--) { + if (++y[i - 1] != 0) { + break; + } + } +} + +/* Calculate and apply the encryption mask. Process use_len bytes of data, + * starting at position offset in the mask block. */ +static int gcm_mask(mbedtls_gcm_context *ctx, + unsigned char ectr[16], + size_t offset, size_t use_len, + const unsigned char *input, + unsigned char *output) +{ + size_t olen = 0; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, + &olen)) != 0) { + mbedtls_platform_zeroize(ectr, 16); + return ret; + } + + if (ctx->mode == MBEDTLS_GCM_DECRYPT) { + mbedtls_xor(ctx->buf + offset, ctx->buf + offset, input, use_len); + } + mbedtls_xor(output, ectr + offset, input, use_len); + if (ctx->mode == MBEDTLS_GCM_ENCRYPT) { + mbedtls_xor(ctx->buf + offset, ctx->buf + offset, output, use_len); + } + + return 0; +} + +int mbedtls_gcm_update(mbedtls_gcm_context *ctx, + const unsigned char *input, size_t input_length, + unsigned char *output, size_t output_size, + size_t *output_length) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const unsigned char *p = input; + unsigned char *out_p = output; + size_t offset; + unsigned char ectr[16] = { 0 }; + + if (output_size < input_length) { + return MBEDTLS_ERR_GCM_BUFFER_TOO_SMALL; + } + *output_length = input_length; + + /* Exit early if input_length==0 so that we don't do any pointer arithmetic + * on a potentially null pointer. + * Returning early also means that the last partial block of AD remains + * untouched for mbedtls_gcm_finish */ + if (input_length == 0) { + return 0; + } + + if (output > input && (size_t) (output - input) < input_length) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if (ctx->len + input_length < ctx->len || + (uint64_t) ctx->len + input_length > 0xFFFFFFFE0ull) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + if (ctx->len == 0 && ctx->add_len % 16 != 0) { + gcm_mult(ctx, ctx->buf, ctx->buf); + } + + offset = ctx->len % 16; + if (offset != 0) { + size_t use_len = 16 - offset; + if (use_len > input_length) { + use_len = input_length; + } + + if ((ret = gcm_mask(ctx, ectr, offset, use_len, p, out_p)) != 0) { + return ret; + } + + if (offset + use_len == 16) { + gcm_mult(ctx, ctx->buf, ctx->buf); + } + + ctx->len += use_len; + input_length -= use_len; + p += use_len; + out_p += use_len; + } + + ctx->len += input_length; + + while (input_length >= 16) { + gcm_incr(ctx->y); + if ((ret = gcm_mask(ctx, ectr, 0, 16, p, out_p)) != 0) { + return ret; + } + + gcm_mult(ctx, ctx->buf, ctx->buf); + + input_length -= 16; + p += 16; + out_p += 16; + } + + if (input_length > 0) { + gcm_incr(ctx->y); + if ((ret = gcm_mask(ctx, ectr, 0, input_length, p, out_p)) != 0) { + return ret; + } + } + + mbedtls_platform_zeroize(ectr, sizeof(ectr)); + return 0; +} + +int mbedtls_gcm_finish(mbedtls_gcm_context *ctx, + unsigned char *output, size_t output_size, + size_t *output_length, + unsigned char *tag, size_t tag_len) +{ + unsigned char work_buf[16]; + uint64_t orig_len; + uint64_t orig_add_len; + + /* We never pass any output in finish(). The output parameter exists only + * for the sake of alternative implementations. */ + (void) output; + (void) output_size; + *output_length = 0; + + orig_len = ctx->len * 8; + orig_add_len = ctx->add_len * 8; + + if (ctx->len == 0 && ctx->add_len % 16 != 0) { + gcm_mult(ctx, ctx->buf, ctx->buf); + } + + if (tag_len > 16 || tag_len < 4) { + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + + if (ctx->len % 16 != 0) { + gcm_mult(ctx, ctx->buf, ctx->buf); + } + + memcpy(tag, ctx->base_ectr, tag_len); + + if (orig_len || orig_add_len) { + memset(work_buf, 0x00, 16); + + MBEDTLS_PUT_UINT32_BE((orig_add_len >> 32), work_buf, 0); + MBEDTLS_PUT_UINT32_BE((orig_add_len), work_buf, 4); + MBEDTLS_PUT_UINT32_BE((orig_len >> 32), work_buf, 8); + MBEDTLS_PUT_UINT32_BE((orig_len), work_buf, 12); + + mbedtls_xor(ctx->buf, ctx->buf, work_buf, 16); + + gcm_mult(ctx, ctx->buf, ctx->buf); + + mbedtls_xor(tag, tag, ctx->buf, tag_len); + } + + return 0; +} + +int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t olen; + + if ((ret = mbedtls_gcm_starts(ctx, mode, iv, iv_len)) != 0) { + return ret; + } + + if ((ret = mbedtls_gcm_update_ad(ctx, add, add_len)) != 0) { + return ret; + } + + if ((ret = mbedtls_gcm_update(ctx, input, length, + output, length, &olen)) != 0) { + return ret; + } + + if ((ret = mbedtls_gcm_finish(ctx, NULL, 0, &olen, tag, tag_len)) != 0) { + return ret; + } + + return 0; +} + +int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char check_tag[16]; + int diff; + + if ((ret = mbedtls_gcm_crypt_and_tag(ctx, MBEDTLS_GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag)) != 0) { + return ret; + } + + /* Check tag in "constant-time" */ + diff = mbedtls_ct_memcmp(tag, check_tag, tag_len); + + if (diff != 0) { + mbedtls_platform_zeroize(output, length); + return MBEDTLS_ERR_GCM_AUTH_FAILED; + } + + return 0; +} + +void mbedtls_gcm_free(mbedtls_gcm_context *ctx) +{ + if (ctx == NULL) { + return; + } + mbedtls_cipher_free(&ctx->cipher_ctx); + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); +} + +#endif /* !MBEDTLS_GCM_ALT */ + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * AES-GCM test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip + */ +#define MAX_TESTS 6 + +static const int key_index_test_data[MAX_TESTS] = +{ 0, 0, 1, 1, 1, 1 }; + +static const unsigned char key_test_data[][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, +}; + +static const size_t iv_len_test_data[MAX_TESTS] = +{ 12, 12, 12, 12, 8, 60 }; + +static const int iv_index_test_data[MAX_TESTS] = +{ 0, 0, 1, 1, 1, 2 }; + +static const unsigned char iv_test_data[][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b }, +}; + +static const size_t add_len_test_data[MAX_TESTS] = +{ 0, 0, 0, 20, 20, 20 }; + +static const int add_index_test_data[MAX_TESTS] = +{ 0, 0, 0, 1, 1, 1 }; + +static const unsigned char additional_test_data[][64] = +{ + { 0x00 }, + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 }, +}; + +static const size_t pt_len_test_data[MAX_TESTS] = +{ 0, 16, 64, 60, 60, 60 }; + +static const int pt_index_test_data[MAX_TESTS] = +{ 0, 0, 1, 1, 1, 1 }; + +static const unsigned char pt_test_data[][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, +}; + +static const unsigned char ct_test_data[][64] = +{ + { 0x00 }, + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 }, + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 }, + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0x00 }, + { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 }, + { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 }, + { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b }, + { 0x00 }, + { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 }, + { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f }, + { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f }, +#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ +}; + +static const unsigned char tag_test_data[][16] = +{ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, +#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) + { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, + { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, + { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, + { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, + { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, + { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, + { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, + { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, + { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, + { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, + { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, + { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, +#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */ +}; + +int mbedtls_gcm_self_test(int verbose) +{ + mbedtls_gcm_context ctx; + unsigned char buf[64]; + unsigned char tag_buf[16]; + int i, j, ret; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + size_t olen; + + if (verbose != 0) { +#if defined(MBEDTLS_GCM_ALT) + mbedtls_printf(" GCM note: alternative implementation.\n"); +#else /* MBEDTLS_GCM_ALT */ +#if defined(MBEDTLS_AESNI_HAVE_CODE) + if (mbedtls_aesni_has_support(MBEDTLS_AESNI_CLMUL)) { + mbedtls_printf(" GCM note: using AESNI.\n"); + } else +#endif + +#if defined(MBEDTLS_AESCE_HAVE_CODE) + if (MBEDTLS_AESCE_HAS_SUPPORT()) { + mbedtls_printf(" GCM note: using AESCE.\n"); + } else +#endif + + mbedtls_printf(" GCM note: built-in implementation.\n"); +#endif /* MBEDTLS_GCM_ALT */ + } + + static const int loop_limit = + (sizeof(ct_test_data) / sizeof(*ct_test_data)) / MAX_TESTS; + + for (j = 0; j < loop_limit; j++) { + int key_len = 128 + 64 * j; + + for (i = 0; i < MAX_TESTS; i++) { + if (verbose != 0) { + mbedtls_printf(" AES-GCM-%3d #%d (%s): ", + key_len, i, "enc"); + } + + mbedtls_gcm_init(&ctx); + + ret = mbedtls_gcm_setkey(&ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && key_len == 192) { + mbedtls_printf("skipped\n"); + break; + } else if (ret != 0) { + goto exit; + } + + ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + pt_test_data[pt_index_test_data[i]], + buf, 16, tag_buf); +#if defined(MBEDTLS_GCM_ALT) + /* Allow alternative implementations to only support 12-byte nonces. */ + if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && + iv_len_test_data[i] != 12) { + mbedtls_printf("skipped\n"); + break; + } +#endif /* defined(MBEDTLS_GCM_ALT) */ + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, ct_test_data[j * 6 + i], + pt_len_test_data[i]) != 0 || + memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { + ret = 1; + goto exit; + } + + mbedtls_gcm_free(&ctx); + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + mbedtls_gcm_init(&ctx); + + if (verbose != 0) { + mbedtls_printf(" AES-GCM-%3d #%d (%s): ", + key_len, i, "dec"); + } + + ret = mbedtls_gcm_setkey(&ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len); + if (ret != 0) { + goto exit; + } + + ret = mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_DECRYPT, + pt_len_test_data[i], + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i], + additional_test_data[add_index_test_data[i]], + add_len_test_data[i], + ct_test_data[j * 6 + i], buf, 16, tag_buf); + + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i]) != 0 || + memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { + ret = 1; + goto exit; + } + + mbedtls_gcm_free(&ctx); + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + mbedtls_gcm_init(&ctx); + + if (verbose != 0) { + mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc"); + } + + ret = mbedtls_gcm_setkey(&ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len); + if (ret != 0) { + goto exit; + } + + ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i]); + if (ret != 0) { + goto exit; + } + + ret = mbedtls_gcm_update_ad(&ctx, + additional_test_data[add_index_test_data[i]], + add_len_test_data[i]); + if (ret != 0) { + goto exit; + } + + if (pt_len_test_data[i] > 32) { + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update(&ctx, + pt_test_data[pt_index_test_data[i]], + 32, + buf, sizeof(buf), &olen); + if (ret != 0) { + goto exit; + } + if (olen != 32) { + goto exit; + } + + ret = mbedtls_gcm_update(&ctx, + pt_test_data[pt_index_test_data[i]] + 32, + rest_len, + buf + 32, sizeof(buf) - 32, &olen); + if (ret != 0) { + goto exit; + } + if (olen != rest_len) { + goto exit; + } + } else { + ret = mbedtls_gcm_update(&ctx, + pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i], + buf, sizeof(buf), &olen); + if (ret != 0) { + goto exit; + } + if (olen != pt_len_test_data[i]) { + goto exit; + } + } + + ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, ct_test_data[j * 6 + i], + pt_len_test_data[i]) != 0 || + memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { + ret = 1; + goto exit; + } + + mbedtls_gcm_free(&ctx); + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + + mbedtls_gcm_init(&ctx); + + if (verbose != 0) { + mbedtls_printf(" AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec"); + } + + ret = mbedtls_gcm_setkey(&ctx, cipher, + key_test_data[key_index_test_data[i]], + key_len); + if (ret != 0) { + goto exit; + } + + ret = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, + iv_test_data[iv_index_test_data[i]], + iv_len_test_data[i]); + if (ret != 0) { + goto exit; + } + ret = mbedtls_gcm_update_ad(&ctx, + additional_test_data[add_index_test_data[i]], + add_len_test_data[i]); + if (ret != 0) { + goto exit; + } + + if (pt_len_test_data[i] > 32) { + size_t rest_len = pt_len_test_data[i] - 32; + ret = mbedtls_gcm_update(&ctx, + ct_test_data[j * 6 + i], 32, + buf, sizeof(buf), &olen); + if (ret != 0) { + goto exit; + } + if (olen != 32) { + goto exit; + } + + ret = mbedtls_gcm_update(&ctx, + ct_test_data[j * 6 + i] + 32, + rest_len, + buf + 32, sizeof(buf) - 32, &olen); + if (ret != 0) { + goto exit; + } + if (olen != rest_len) { + goto exit; + } + } else { + ret = mbedtls_gcm_update(&ctx, + ct_test_data[j * 6 + i], + pt_len_test_data[i], + buf, sizeof(buf), &olen); + if (ret != 0) { + goto exit; + } + if (olen != pt_len_test_data[i]) { + goto exit; + } + } + + ret = mbedtls_gcm_finish(&ctx, NULL, 0, &olen, tag_buf, 16); + if (ret != 0) { + goto exit; + } + + if (memcmp(buf, pt_test_data[pt_index_test_data[i]], + pt_len_test_data[i]) != 0 || + memcmp(tag_buf, tag_test_data[j * 6 + i], 16) != 0) { + ret = 1; + goto exit; + } + + mbedtls_gcm_free(&ctx); + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + ret = 0; + +exit: + if (ret != 0) { + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + mbedtls_gcm_free(&ctx); + } + + return ret; +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_GCM_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/kdf963.c b/src/app/findmy/crypto/third-party/mbedtls/library/kdf963.c new file mode 100644 index 0000000..298576b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/kdf963.c @@ -0,0 +1,85 @@ +#include "mbedtls/kdf963.h" +#include "mbedtls/sha256.h" +#include "mbedtls/platform_util.h" + +static __inline void IncrementX963KdfCounter(uint8_t *inOutCtr) +{ + int i; + + /* in network byte order so start at end and work back */ + for (i = 3; i >= 0; i--) + { + if (++inOutCtr[i]) /* we're done unless we overflow */ + { + return; + } + } +} + +static __inline word32 min(int32_t a, int32_t b) +{ + return a > b ? b : a; +} + +int mbed_KDF963(MBED_KDF963_SHA_TYPE type, uint8_t *secret, uint32_t secretSz, uint8_t *sinfo, + uint32_t sinfoSz, uint8_t *out, uint32_t out_size) +{ + int ret, i; + int digestSz = 32, copySz; + int remaining = out_size; + uint8_t *outIdx; + uint8_t counter[4]; + uint8_t mbed_temp_buf[32]; + + if (secret == NULL || secretSz == 0 || out == NULL) + { + return -1; + } + + outIdx = out; + XMEMSET(counter, 0, sizeof(counter)); + + mbedtls_sha256_context ctx; + + for (i = 1; remaining > 0; i++) + { + mbedtls_sha256_init(&ctx); + ret = mbedtls_sha256_starts(&ctx, 0); + IncrementX963KdfCounter(counter); + mbedtls_sha256_update(&ctx, secret, secretSz); + if (ret != 0) + { + break; + } + + ret = mbedtls_sha256_update(&ctx, counter, sizeof(counter)); + if (ret != 0) + { + break; + } + + if (sinfo) + { + ret = mbedtls_sha256_update(&ctx, sinfo, sinfoSz); + if (ret != 0) + { + break; + } + } + + ret = mbedtls_sha256_finish(&ctx, mbed_temp_buf); + if (ret != 0) + { + break; + } + + copySz = min(remaining, digestSz); + XMEMCPY(outIdx, mbed_temp_buf, copySz); + + remaining -= copySz; + outIdx += copySz; + mbedtls_sha256_free(&ctx); + } + + return ret; +} diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/md.c b/src/app/findmy/crypto/third-party/mbedtls/library/md.c new file mode 100644 index 0000000..ec8a855 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/md.c @@ -0,0 +1,1108 @@ +/** + * \file md.c + * + * \brief Generic message digest wrapper for Mbed TLS + * + * \author Adriaan de Jong + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +/* + * Availability of functions in this module is controlled by two + * feature macros: + * - MBEDTLS_MD_C enables the whole module; + * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing + * most hash metadata (everything except string names); is it + * automatically set whenever MBEDTLS_MD_C is defined. + * + * In this file, functions from MD_LIGHT are at the top, MD_C at the end. + * + * In the future we may want to change the contract of some functions + * (behaviour with NULL arguments) depending on whether MD_C is defined or + * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary. + * + * For these reasons, we're keeping MD_LIGHT internal for now. + */ +#if defined(MBEDTLS_MD_LIGHT) + +#include "mbedtls/md.h" +#include "md_wrap.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include "mbedtls/md5.h" +#include "mbedtls/ripemd160.h" +//#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +//#include "mbedtls/sha512.h" +//#include "mbedtls/sha3.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) +#include +#include "md_psa.h" +#include "psa_util_internal.h" +#endif + +#if defined(MBEDTLS_MD_SOME_PSA) +#include "psa_crypto_core.h" +#endif + +#include "mbedtls/platform.h" + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +/* See comment above MBEDTLS_MD_MAX_SIZE in md.h */ +#if defined(MBEDTLS_PSA_CRYPTO_C) && MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE +#error "Internal error: MBEDTLS_MD_MAX_SIZE < PSA_HASH_MAX_SIZE" +#endif + +#if defined(MBEDTLS_MD_C) +#define MD_INFO(type, out_size, block_size) type, out_size, block_size, +#else +#define MD_INFO(type, out_size, block_size) type, out_size, +#endif + +#if defined(MBEDTLS_MD_CAN_MD5) +static const mbedtls_md_info_t mbedtls_md5_info = { + MD_INFO(MBEDTLS_MD_MD5, 16, 64) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_RIPEMD160) +static const mbedtls_md_info_t mbedtls_ripemd160_info = { + MD_INFO(MBEDTLS_MD_RIPEMD160, 20, 64) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA1) +static const mbedtls_md_info_t mbedtls_sha1_info = { + MD_INFO(MBEDTLS_MD_SHA1, 20, 64) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA224) +static const mbedtls_md_info_t mbedtls_sha224_info = { + MD_INFO(MBEDTLS_MD_SHA224, 28, 64) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA256) +static const mbedtls_md_info_t mbedtls_sha256_info = { + MD_INFO(MBEDTLS_MD_SHA256, 32, 64) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA384) +static const mbedtls_md_info_t mbedtls_sha384_info = { + MD_INFO(MBEDTLS_MD_SHA384, 48, 128) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA512) +static const mbedtls_md_info_t mbedtls_sha512_info = { + MD_INFO(MBEDTLS_MD_SHA512, 64, 128) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_224) +static const mbedtls_md_info_t mbedtls_sha3_224_info = { + MD_INFO(MBEDTLS_MD_SHA3_224, 28, 144) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_256) +static const mbedtls_md_info_t mbedtls_sha3_256_info = { + MD_INFO(MBEDTLS_MD_SHA3_256, 32, 136) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_384) +static const mbedtls_md_info_t mbedtls_sha3_384_info = { + MD_INFO(MBEDTLS_MD_SHA3_384, 48, 104) +}; +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_512) +static const mbedtls_md_info_t mbedtls_sha3_512_info = { + MD_INFO(MBEDTLS_MD_SHA3_512, 64, 72) +}; +#endif + +const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) +{ + switch (md_type) { +#if defined(MBEDTLS_MD_CAN_MD5) + case MBEDTLS_MD_MD5: + return &mbedtls_md5_info; +#endif +#if defined(MBEDTLS_MD_CAN_RIPEMD160) + case MBEDTLS_MD_RIPEMD160: + return &mbedtls_ripemd160_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA1) + case MBEDTLS_MD_SHA1: + return &mbedtls_sha1_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA224) + case MBEDTLS_MD_SHA224: + return &mbedtls_sha224_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA256) + case MBEDTLS_MD_SHA256: + return &mbedtls_sha256_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA384) + case MBEDTLS_MD_SHA384: + return &mbedtls_sha384_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA512) + case MBEDTLS_MD_SHA512: + return &mbedtls_sha512_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_224) + case MBEDTLS_MD_SHA3_224: + return &mbedtls_sha3_224_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_256) + case MBEDTLS_MD_SHA3_256: + return &mbedtls_sha3_256_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_384) + case MBEDTLS_MD_SHA3_384: + return &mbedtls_sha3_384_info; +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_512) + case MBEDTLS_MD_SHA3_512: + return &mbedtls_sha3_512_info; +#endif + default: + return NULL; + } +} + +#if defined(MBEDTLS_MD_SOME_PSA) +static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info) +{ + switch (info->type) { +#if defined(MBEDTLS_MD_MD5_VIA_PSA) + case MBEDTLS_MD_MD5: + return PSA_ALG_MD5; +#endif +#if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA) + case MBEDTLS_MD_RIPEMD160: + return PSA_ALG_RIPEMD160; +#endif +#if defined(MBEDTLS_MD_SHA1_VIA_PSA) + case MBEDTLS_MD_SHA1: + return PSA_ALG_SHA_1; +#endif +#if defined(MBEDTLS_MD_SHA224_VIA_PSA) + case MBEDTLS_MD_SHA224: + return PSA_ALG_SHA_224; +#endif +#if defined(MBEDTLS_MD_SHA256_VIA_PSA) + case MBEDTLS_MD_SHA256: + return PSA_ALG_SHA_256; +#endif +#if defined(MBEDTLS_MD_SHA384_VIA_PSA) + case MBEDTLS_MD_SHA384: + return PSA_ALG_SHA_384; +#endif +#if defined(MBEDTLS_MD_SHA512_VIA_PSA) + case MBEDTLS_MD_SHA512: + return PSA_ALG_SHA_512; +#endif +#if defined(MBEDTLS_MD_SHA3_224_VIA_PSA) + case MBEDTLS_MD_SHA3_224: + return PSA_ALG_SHA3_224; +#endif +#if defined(MBEDTLS_MD_SHA3_256_VIA_PSA) + case MBEDTLS_MD_SHA3_256: + return PSA_ALG_SHA3_256; +#endif +#if defined(MBEDTLS_MD_SHA3_384_VIA_PSA) + case MBEDTLS_MD_SHA3_384: + return PSA_ALG_SHA3_384; +#endif +#if defined(MBEDTLS_MD_SHA3_512_VIA_PSA) + case MBEDTLS_MD_SHA3_512: + return PSA_ALG_SHA3_512; +#endif + default: + return PSA_ALG_NONE; + } +} + +static int md_can_use_psa(const mbedtls_md_info_t *info) +{ + psa_algorithm_t alg = psa_alg_of_md(info); + if (alg == PSA_ALG_NONE) { + return 0; + } + + return psa_can_do_hash(alg); +} +#endif /* MBEDTLS_MD_SOME_PSA */ + +void mbedtls_md_init(mbedtls_md_context_t *ctx) +{ + /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */ + memset(ctx, 0, sizeof(mbedtls_md_context_t)); +} + +void mbedtls_md_free(mbedtls_md_context_t *ctx) +{ + if (ctx == NULL || ctx->md_info == NULL) { + return; + } + + if (ctx->md_ctx != NULL) { +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_hash_abort(ctx->md_ctx); + } else +#endif + switch (ctx->md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + mbedtls_md5_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + mbedtls_ripemd160_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + mbedtls_sha1_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + mbedtls_sha256_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + mbedtls_sha256_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + mbedtls_sha512_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + mbedtls_sha512_free(ctx->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + mbedtls_sha3_free(ctx->md_ctx); + break; +#endif + default: + /* Shouldn't happen */ + break; + } + mbedtls_free(ctx->md_ctx); + } + +#if defined(MBEDTLS_MD_C) + if (ctx->hmac_ctx != NULL) { + mbedtls_zeroize_and_free(ctx->hmac_ctx, + 2 * ctx->md_info->block_size); + } +#endif + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t)); +} + +int mbedtls_md_clone(mbedtls_md_context_t *dst, + const mbedtls_md_context_t *src) +{ + if (dst == NULL || dst->md_info == NULL || + src == NULL || src->md_info == NULL || + dst->md_info != src->md_info) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_MD_SOME_PSA) + if (src->engine != dst->engine) { + /* This can happen with src set to legacy because PSA wasn't ready + * yet, and dst to PSA because it became ready in the meantime. + * We currently don't support that case (we'd need to re-allocate + * md_ctx to the size of the appropriate MD context). */ + return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; + } + + if (src->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx); + return mbedtls_md_error_from_psa(status); + } +#endif + + switch (src->md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + mbedtls_md5_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + mbedtls_ripemd160_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + mbedtls_sha1_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); + break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + mbedtls_sha3_clone(dst->md_ctx, src->md_ctx); + break; +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + return 0; +} + +#define ALLOC(type) \ + do { \ + ctx->md_ctx = mbedtls_calloc(1, sizeof(mbedtls_##type##_context)); \ + if (ctx->md_ctx == NULL) \ + return MBEDTLS_ERR_MD_ALLOC_FAILED; \ + mbedtls_##type##_init(ctx->md_ctx); \ + } \ + while (0) + +int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac) +{ +#if defined(MBEDTLS_MD_C) + if (ctx == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif + if (md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + ctx->md_info = md_info; + ctx->md_ctx = NULL; +#if defined(MBEDTLS_MD_C) + ctx->hmac_ctx = NULL; +#else + if (hmac != 0) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif + +#if defined(MBEDTLS_MD_SOME_PSA) + if (md_can_use_psa(ctx->md_info)) { + ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t)); + if (ctx->md_ctx == NULL) { + return MBEDTLS_ERR_MD_ALLOC_FAILED; + } + ctx->engine = MBEDTLS_MD_ENGINE_PSA; + } else +#endif + switch (md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + ALLOC(md5); + break; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + ALLOC(ripemd160); + break; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + ALLOC(sha1); + break; +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + ALLOC(sha256); + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + ALLOC(sha256); + break; +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + ALLOC(sha512); + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + ALLOC(sha512); + break; +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + ALLOC(sha3); + break; +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_MD_C) + if (hmac != 0) { + ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size); + if (ctx->hmac_ctx == NULL) { + mbedtls_md_free(ctx); + return MBEDTLS_ERR_MD_ALLOC_FAILED; + } + } +#endif + + return 0; +} +#undef ALLOC + +int mbedtls_md_starts(mbedtls_md_context_t *ctx) +{ +#if defined(MBEDTLS_MD_C) + if (ctx == NULL || ctx->md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif + +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_algorithm_t alg = psa_alg_of_md(ctx->md_info); + psa_hash_abort(ctx->md_ctx); + psa_status_t status = psa_hash_setup(ctx->md_ctx, alg); + return mbedtls_md_error_from_psa(status); + } +#endif + + switch (ctx->md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return mbedtls_md5_starts(ctx->md_ctx); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return mbedtls_ripemd160_starts(ctx->md_ctx); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return mbedtls_sha1_starts(ctx->md_ctx); +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + return mbedtls_sha256_starts(ctx->md_ctx, 1); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + return mbedtls_sha256_starts(ctx->md_ctx, 0); +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + return mbedtls_sha512_starts(ctx->md_ctx, 1); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + return mbedtls_sha512_starts(ctx->md_ctx, 0); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_224); + case MBEDTLS_MD_SHA3_256: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_256); + case MBEDTLS_MD_SHA3_384: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_384); + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_starts(ctx->md_ctx, MBEDTLS_SHA3_512); +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +} + +int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) +{ +#if defined(MBEDTLS_MD_C) + if (ctx == NULL || ctx->md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif + +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen); + return mbedtls_md_error_from_psa(status); + } +#endif + + switch (ctx->md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return mbedtls_md5_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return mbedtls_ripemd160_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return mbedtls_sha1_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + return mbedtls_sha256_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + return mbedtls_sha256_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + return mbedtls_sha512_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + return mbedtls_sha512_update(ctx->md_ctx, input, ilen); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_update(ctx->md_ctx, input, ilen); +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +} + +int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output) +{ +#if defined(MBEDTLS_MD_C) + if (ctx == NULL || ctx->md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +#endif + +#if defined(MBEDTLS_MD_SOME_PSA) + if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { + size_t size = ctx->md_info->size; + psa_status_t status = psa_hash_finish(ctx->md_ctx, + output, size, &size); + return mbedtls_md_error_from_psa(status); + } +#endif + + switch (ctx->md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return mbedtls_md5_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return mbedtls_ripemd160_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return mbedtls_sha1_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + return mbedtls_sha256_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + return mbedtls_sha256_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + return mbedtls_sha512_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + return mbedtls_sha512_finish(ctx->md_ctx, output); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + case MBEDTLS_MD_SHA3_256: + case MBEDTLS_MD_SHA3_384: + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3_finish(ctx->md_ctx, output, ctx->md_info->size); +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +} + +int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output) +{ + if (md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + +#if defined(MBEDTLS_MD_SOME_PSA) + if (md_can_use_psa(md_info)) { + size_t size = md_info->size; + psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info), + input, ilen, + output, size, &size); + return mbedtls_md_error_from_psa(status); + } +#endif + + switch (md_info->type) { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return mbedtls_md5(input, ilen, output); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return mbedtls_ripemd160(input, ilen, output); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return mbedtls_sha1(input, ilen, output); +#endif +#if defined(MBEDTLS_SHA224_C) + case MBEDTLS_MD_SHA224: + return mbedtls_sha256(input, ilen, output, 1); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA256: + return mbedtls_sha256(input, ilen, output, 0); +#endif +#if defined(MBEDTLS_SHA384_C) + case MBEDTLS_MD_SHA384: + return mbedtls_sha512(input, ilen, output, 1); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA512: + return mbedtls_sha512(input, ilen, output, 0); +#endif +#if defined(MBEDTLS_SHA3_C) + case MBEDTLS_MD_SHA3_224: + return mbedtls_sha3(MBEDTLS_SHA3_224, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_256: + return mbedtls_sha3(MBEDTLS_SHA3_256, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_384: + return mbedtls_sha3(MBEDTLS_SHA3_384, input, ilen, output, md_info->size); + case MBEDTLS_MD_SHA3_512: + return mbedtls_sha3(MBEDTLS_SHA3_512, input, ilen, output, md_info->size); +#endif + default: + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } +} + +unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info) +{ + if (md_info == NULL) { + return 0; + } + + return md_info->size; +} + +mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info) +{ + if (md_info == NULL) { + return MBEDTLS_MD_NONE; + } + + return md_info->type; +} + +#if defined(MBEDTLS_PSA_CRYPTO_C) +int mbedtls_md_error_from_psa(psa_status_t status) +{ + return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_md_errors, + psa_generic_status_to_mbedtls); +} +#endif /* MBEDTLS_PSA_CRYPTO_C */ + + +/************************************************************************ + * Functions above this separator are part of MBEDTLS_MD_LIGHT, * + * functions below are only available when MBEDTLS_MD_C is set. * + ************************************************************************/ +#if defined(MBEDTLS_MD_C) + +/* + * Reminder: update profiles in x509_crt.c when adding a new hash! + */ +static const int supported_digests[] = { + +#if defined(MBEDTLS_MD_CAN_SHA512) + MBEDTLS_MD_SHA512, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA384) + MBEDTLS_MD_SHA384, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA256) + MBEDTLS_MD_SHA256, +#endif +#if defined(MBEDTLS_MD_CAN_SHA224) + MBEDTLS_MD_SHA224, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA1) + MBEDTLS_MD_SHA1, +#endif + +#if defined(MBEDTLS_MD_CAN_RIPEMD160) + MBEDTLS_MD_RIPEMD160, +#endif + +#if defined(MBEDTLS_MD_CAN_MD5) + MBEDTLS_MD_MD5, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_224) + MBEDTLS_MD_SHA3_224, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_256) + MBEDTLS_MD_SHA3_256, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_384) + MBEDTLS_MD_SHA3_384, +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_512) + MBEDTLS_MD_SHA3_512, +#endif + + MBEDTLS_MD_NONE +}; + +const int *mbedtls_md_list(void) +{ + return supported_digests; +} + +typedef struct { + const char *md_name; + mbedtls_md_type_t md_type; +} md_name_entry; + +static const md_name_entry md_names[] = { +#if defined(MBEDTLS_MD_CAN_MD5) + { "MD5", MBEDTLS_MD_MD5 }, +#endif +#if defined(MBEDTLS_MD_CAN_RIPEMD160) + { "RIPEMD160", MBEDTLS_MD_RIPEMD160 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA1) + { "SHA1", MBEDTLS_MD_SHA1 }, + { "SHA", MBEDTLS_MD_SHA1 }, // compatibility fallback +#endif +#if defined(MBEDTLS_MD_CAN_SHA224) + { "SHA224", MBEDTLS_MD_SHA224 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA256) + { "SHA256", MBEDTLS_MD_SHA256 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA384) + { "SHA384", MBEDTLS_MD_SHA384 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA512) + { "SHA512", MBEDTLS_MD_SHA512 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_224) + { "SHA3-224", MBEDTLS_MD_SHA3_224 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_256) + { "SHA3-256", MBEDTLS_MD_SHA3_256 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_384) + { "SHA3-384", MBEDTLS_MD_SHA3_384 }, +#endif +#if defined(MBEDTLS_MD_CAN_SHA3_512) + { "SHA3-512", MBEDTLS_MD_SHA3_512 }, +#endif + { NULL, MBEDTLS_MD_NONE }, +}; + +const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) +{ + if (NULL == md_name) { + return NULL; + } + + const md_name_entry *entry = md_names; + while (entry->md_name != NULL && + strcmp(entry->md_name, md_name) != 0) { + ++entry; + } + + return mbedtls_md_info_from_type(entry->md_type); +} + +const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info) +{ + if (md_info == NULL) { + return NULL; + } + + const md_name_entry *entry = md_names; + while (entry->md_type != MBEDTLS_MD_NONE && + entry->md_type != md_info->type) { + ++entry; + } + + return entry->md_name; +} + +const mbedtls_md_info_t *mbedtls_md_info_from_ctx( + const mbedtls_md_context_t *ctx) +{ + if (ctx == NULL) { + return NULL; + } + + return ctx->MBEDTLS_PRIVATE(md_info); +} + +#if defined(MBEDTLS_FS_IO) +int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + FILE *f; + size_t n; + mbedtls_md_context_t ctx; + unsigned char buf[1024]; + + if (md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + if ((f = fopen(path, "rb")) == NULL) { + return MBEDTLS_ERR_MD_FILE_IO_ERROR; + } + + /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ + mbedtls_setbuf(f, NULL); + + mbedtls_md_init(&ctx); + + if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) { + goto cleanup; + } + + if ((ret = mbedtls_md_starts(&ctx)) != 0) { + goto cleanup; + } + + while ((n = fread(buf, 1, sizeof(buf), f)) > 0) { + if ((ret = mbedtls_md_update(&ctx, buf, n)) != 0) { + goto cleanup; + } + } + + if (ferror(f) != 0) { + ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; + } else { + ret = mbedtls_md_finish(&ctx, output); + } + +cleanup: + mbedtls_platform_zeroize(buf, sizeof(buf)); + fclose(f); + mbedtls_md_free(&ctx); + + return ret; +} +#endif /* MBEDTLS_FS_IO */ + +int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char sum[MBEDTLS_MD_MAX_SIZE]; + unsigned char *ipad, *opad; + + if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + if (keylen > (size_t) ctx->md_info->block_size) { + if ((ret = mbedtls_md_starts(ctx)) != 0) { + goto cleanup; + } + if ((ret = mbedtls_md_update(ctx, key, keylen)) != 0) { + goto cleanup; + } + if ((ret = mbedtls_md_finish(ctx, sum)) != 0) { + goto cleanup; + } + + keylen = ctx->md_info->size; + key = sum; + } + + ipad = (unsigned char *) ctx->hmac_ctx; + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; + + memset(ipad, 0x36, ctx->md_info->block_size); + memset(opad, 0x5C, ctx->md_info->block_size); + + mbedtls_xor(ipad, ipad, key, keylen); + mbedtls_xor(opad, opad, key, keylen); + + if ((ret = mbedtls_md_starts(ctx)) != 0) { + goto cleanup; + } + if ((ret = mbedtls_md_update(ctx, ipad, + ctx->md_info->block_size)) != 0) { + goto cleanup; + } + +cleanup: + mbedtls_platform_zeroize(sum, sizeof(sum)); + + return ret; +} + +int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) +{ + if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + return mbedtls_md_update(ctx, input, ilen); +} + +int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; + unsigned char *opad; + + if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; + + if ((ret = mbedtls_md_finish(ctx, tmp)) != 0) { + return ret; + } + if ((ret = mbedtls_md_starts(ctx)) != 0) { + return ret; + } + if ((ret = mbedtls_md_update(ctx, opad, + ctx->md_info->block_size)) != 0) { + return ret; + } + if ((ret = mbedtls_md_update(ctx, tmp, + ctx->md_info->size)) != 0) { + return ret; + } + return mbedtls_md_finish(ctx, output); +} + +int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char *ipad; + + if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + ipad = (unsigned char *) ctx->hmac_ctx; + + if ((ret = mbedtls_md_starts(ctx)) != 0) { + return ret; + } + return mbedtls_md_update(ctx, ipad, ctx->md_info->block_size); +} + +int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, + const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output) +{ + mbedtls_md_context_t ctx; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + if (md_info == NULL) { + return MBEDTLS_ERR_MD_BAD_INPUT_DATA; + } + + mbedtls_md_init(&ctx); + + if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0) { + goto cleanup; + } + + if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0) { + goto cleanup; + } + if ((ret = mbedtls_md_hmac_update(&ctx, input, ilen)) != 0) { + goto cleanup; + } + if ((ret = mbedtls_md_hmac_finish(&ctx, output)) != 0) { + goto cleanup; + } + +cleanup: + mbedtls_md_free(&ctx); + + return ret; +} + +#endif /* MBEDTLS_MD_C */ + +#endif /* MBEDTLS_MD_LIGHT */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/md_wrap.h b/src/app/findmy/crypto/third-party/mbedtls/library/md_wrap.h new file mode 100644 index 0000000..dad1235 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/md_wrap.h @@ -0,0 +1,46 @@ +/** + * \file md_wrap.h + * + * \brief Message digest wrappers. + * + * \warning This in an internal header. Do not include directly. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_MD_WRAP_H +#define MBEDTLS_MD_WRAP_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Message digest information. + * Allows message digest functions to be called in a generic way. + */ +struct mbedtls_md_info_t { + /** Digest identifier */ + mbedtls_md_type_t type; + + /** Output length of the digest function in bytes */ + unsigned char size; + +#if defined(MBEDTLS_MD_C) + /** Block length of the digest function in bytes */ + unsigned char block_size; +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_MD_WRAP_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/platform.c b/src/app/findmy/crypto/third-party/mbedtls/library/platform.c new file mode 100644 index 0000000..890c4cb --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/platform.c @@ -0,0 +1,402 @@ +/* + * Platform abstraction layer + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#if defined(MBEDTLS_PLATFORM_C) + +#include "mbedtls/platform.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +/* The compile time configuration of memory allocation via the macros + * MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime + * configuration via mbedtls_platform_set_calloc_free(). So, omit everything + * related to the latter if MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO are defined. */ +#if defined(MBEDTLS_PLATFORM_MEMORY) && \ + !(defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && \ + defined(MBEDTLS_PLATFORM_FREE_MACRO)) + +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +static void *platform_calloc_uninit(size_t n, size_t size) +{ + ((void) n); + ((void) size); + return NULL; +} + +#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit +#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ + +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +static void platform_free_uninit(void *ptr) +{ + ((void) ptr); +} + +#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FREE */ + +static void * (*mbedtls_calloc_func)(size_t, size_t) = MBEDTLS_PLATFORM_STD_CALLOC; +static void (*mbedtls_free_func)(void *) = MBEDTLS_PLATFORM_STD_FREE; + +void *mbedtls_calloc(size_t nmemb, size_t size) +{ + return (*mbedtls_calloc_func)(nmemb, size); +} + +void mbedtls_free(void *ptr) +{ + (*mbedtls_free_func)(ptr); +} + +int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t), + void (*free_func)(void *)) +{ + mbedtls_calloc_func = calloc_func; + mbedtls_free_func = free_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_MEMORY && + !( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && + defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */ + +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +#include +int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + va_list argp; + + va_start(argp, fmt); + ret = mbedtls_vsnprintf(s, n, fmt, argp); + va_end(argp); + + return ret; +} +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_snprintf_uninit(char *s, size_t n, + const char *format, ...) +{ + ((void) s); + ((void) n); + ((void) format); + return 0; +} + +#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ + +int (*mbedtls_snprintf)(char *s, size_t n, + const char *format, + ...) = MBEDTLS_PLATFORM_STD_SNPRINTF; + +int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n, + const char *format, + ...)) +{ + mbedtls_snprintf = snprintf_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#include +int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + /* Avoid calling the invalid parameter handler by checking ourselves */ + if (s == NULL || n == 0 || fmt == NULL) { + return -1; + } + +#if defined(_TRUNCATE) + ret = vsnprintf_s(s, n, _TRUNCATE, fmt, arg); +#else + ret = vsnprintf(s, n, fmt, arg); + if (ret < 0 || (size_t) ret == n) { + s[n-1] = '\0'; + ret = -1; + } +#endif + + return ret; +} +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_vsnprintf_uninit(char *s, size_t n, + const char *format, va_list arg) +{ + ((void) s); + ((void) n); + ((void) format); + ((void) arg); + return -1; +} + +#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */ + +int (*mbedtls_vsnprintf)(char *s, size_t n, + const char *format, + va_list arg) = MBEDTLS_PLATFORM_STD_VSNPRINTF; + +int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n, + const char *format, + va_list arg)) +{ + mbedtls_vsnprintf = vsnprintf_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit(const char *format, ...) +{ + ((void) format); + return 0; +} + +#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ + +int (*mbedtls_printf)(const char *, ...) = MBEDTLS_PLATFORM_STD_PRINTF; + +int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...)) +{ + mbedtls_printf = printf_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit(FILE *stream, const char *format, ...) +{ + ((void) stream); + ((void) format); + return 0; +} + +#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ + +int (*mbedtls_fprintf)(FILE *, const char *, ...) = + MBEDTLS_PLATFORM_STD_FPRINTF; + +int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *, const char *, ...)) +{ + mbedtls_fprintf = fprintf_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_SETBUF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static void platform_setbuf_uninit(FILE *stream, char *buf) +{ + ((void) stream); + ((void) buf); +} + +#define MBEDTLS_PLATFORM_STD_SETBUF platform_setbuf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_SETBUF */ +void (*mbedtls_setbuf)(FILE *stream, char *buf) = MBEDTLS_PLATFORM_STD_SETBUF; + +int mbedtls_platform_set_setbuf(void (*setbuf_func)(FILE *stream, char *buf)) +{ + mbedtls_setbuf = setbuf_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static void platform_exit_uninit(int status) +{ + ((void) status); +} + +#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit +#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ + +void (*mbedtls_exit)(int status) = MBEDTLS_PLATFORM_STD_EXIT; + +int mbedtls_platform_set_exit(void (*exit_func)(int status)) +{ + mbedtls_exit = exit_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +#if defined(MBEDTLS_HAVE_TIME) + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static mbedtls_time_t platform_time_uninit(mbedtls_time_t *timer) +{ + ((void) timer); + return 0; +} + +#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit +#endif /* !MBEDTLS_PLATFORM_STD_TIME */ + +mbedtls_time_t (*mbedtls_time)(mbedtls_time_t *timer) = MBEDTLS_PLATFORM_STD_TIME; + +int mbedtls_platform_set_time(mbedtls_time_t (*time_func)(mbedtls_time_t *timer)) +{ + mbedtls_time = time_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Default implementations for the platform independent seed functions use + * standard libc file functions to read from and write to a pre-defined filename + */ +int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len) +{ + FILE *file; + size_t n; + + if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb")) == NULL) { + return -1; + } + + /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ + mbedtls_setbuf(file, NULL); + + if ((n = fread(buf, 1, buf_len, file)) != buf_len) { + fclose(file); + mbedtls_platform_zeroize(buf, buf_len); + return -1; + } + + fclose(file); + return (int) n; +} + +int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len) +{ + FILE *file; + size_t n; + + if ((file = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w")) == NULL) { + return -1; + } + + /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ + mbedtls_setbuf(file, NULL); + + if ((n = fwrite(buf, 1, buf_len, file)) != buf_len) { + fclose(file); + return -1; + } + + fclose(file); + return (int) n; +} +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_read_uninit(unsigned char *buf, size_t buf_len) +{ + ((void) buf); + ((void) buf_len); + return -1; +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ + +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_write_uninit(unsigned char *buf, size_t buf_len) +{ + ((void) buf); + ((void) buf_len); + return -1; +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ + +int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len) = + MBEDTLS_PLATFORM_STD_NV_SEED_READ; +int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len) = + MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; + +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len), + int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len)) +{ + mbedtls_nv_seed_read = nv_seed_read_func; + mbedtls_nv_seed_write = nv_seed_write_func; + return 0; +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) +/* + * Placeholder platform setup that does nothing by default + */ +int mbedtls_platform_setup(mbedtls_platform_context *ctx) +{ + (void) ctx; + + return 0; +} + +/* + * Placeholder platform teardown that does nothing by default + */ +void mbedtls_platform_teardown(mbedtls_platform_context *ctx) +{ + (void) ctx; +} +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +#endif /* MBEDTLS_PLATFORM_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/platform_util.c b/src/app/findmy/crypto/third-party/mbedtls/library/platform_util.c new file mode 100644 index 0000000..b9bc743 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/platform_util.c @@ -0,0 +1,303 @@ +/* + * Common and shared functions used by multiple modules in the Mbed TLS + * library. + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/* + * Ensure gmtime_r is available even with -std=c99; must be defined before + * mbedtls_config.h, which pulls in glibc's features.h. Harmless on other platforms + * except OpenBSD, where it stops us accessing explicit_bzero. + */ +#if !defined(_POSIX_C_SOURCE) && !defined(__OpenBSD__) +#define _POSIX_C_SOURCE 200112L +#endif + +#if !defined(_GNU_SOURCE) +/* Clang requires this to get support for explicit_bzero */ +#define _GNU_SOURCE +#endif + +#include "common.h" + +#include "mbedtls/platform_util.h" +#include "mbedtls/platform.h" +#include "mbedtls/threading.h" + +#include + +#ifndef __STDC_WANT_LIB_EXT1__ +#define __STDC_WANT_LIB_EXT1__ 1 /* Ask for the C11 gmtime_s() and memset_s() if available */ +#endif +#include + +#if defined(_WIN32) +#include +#endif + +// Detect platforms known to support explicit_bzero() +#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25) +#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1 +#elif (defined(__FreeBSD__) && (__FreeBSD_version >= 1100037)) || defined(__OpenBSD__) +#define MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO 1 +#endif + +#if !defined(MBEDTLS_PLATFORM_ZEROIZE_ALT) + +#undef HAVE_MEMORY_SANITIZER +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#define HAVE_MEMORY_SANITIZER +#endif +#endif + +/* + * Where possible, we try to detect the presence of a platform-provided + * secure memset, such as explicit_bzero(), that is safe against being optimized + * out, and use that. + * + * For other platforms, we provide an implementation that aims not to be + * optimized out by the compiler. + * + * This implementation for mbedtls_platform_zeroize() was inspired from Colin + * Percival's blog article at: + * + * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html + * + * It uses a volatile function pointer to the standard memset(). Because the + * pointer is volatile the compiler expects it to change at + * any time and will not optimize out the call that could potentially perform + * other operations on the input buffer instead of just setting it to 0. + * Nevertheless, as pointed out by davidtgoldblatt on Hacker News + * (refer to http://www.daemonology.net/blog/2014-09-05-erratum.html for + * details), optimizations of the following form are still possible: + * + * if (memset_func != memset) + * memset_func(buf, 0, len); + * + * Note that it is extremely difficult to guarantee that + * the memset() call will not be optimized out by aggressive compilers + * in a portable way. For this reason, Mbed TLS also provides the configuration + * option MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure + * mbedtls_platform_zeroize() to use a suitable implementation for their + * platform and needs. + */ +#if !defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) && !(defined(__STDC_LIB_EXT1__) && \ + !defined(__IAR_SYSTEMS_ICC__)) \ + && !defined(_WIN32) +static void *(*const volatile memset_func)(void *, int, size_t) = memset; +#endif + +void mbedtls_platform_zeroize(void *buf, size_t len) +{ + MBEDTLS_INTERNAL_VALIDATE(len == 0 || buf != NULL); + + if (len > 0) { +#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) + explicit_bzero(buf, len); +#if defined(HAVE_MEMORY_SANITIZER) + /* You'd think that Msan would recognize explicit_bzero() as + * equivalent to bzero(), but it actually doesn't on several + * platforms, including Linux (Ubuntu 20.04). + * https://github.com/google/sanitizers/issues/1507 + * https://github.com/openssh/openssh-portable/commit/74433a19bb6f4cef607680fa4d1d7d81ca3826aa + */ + __msan_unpoison(buf, len); +#endif +#elif defined(__STDC_LIB_EXT1__) && !defined(__IAR_SYSTEMS_ICC__) + memset_s(buf, len, 0, len); +#elif defined(_WIN32) + SecureZeroMemory(buf, len); +#else + memset_func(buf, 0, len); +#endif + +#if defined(__GNUC__) + /* For clang and recent gcc, pretend that we have some assembly that reads the + * zero'd memory as an additional protection against being optimised away. */ +#if defined(__clang__) || (__GNUC__ >= 10) +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvla" +#elif defined(MBEDTLS_COMPILER_IS_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wvla" +#endif + asm volatile ("" : : "m" (*(char (*)[len]) buf) :); +#if defined(__clang__) +#pragma clang diagnostic pop +#elif defined(MBEDTLS_COMPILER_IS_GCC) +#pragma GCC diagnostic pop +#endif +#endif +#endif + } +} +#endif /* MBEDTLS_PLATFORM_ZEROIZE_ALT */ + +void mbedtls_zeroize_and_free(void *buf, size_t len) +{ + if (buf != NULL) { + mbedtls_platform_zeroize(buf, len); + } + + mbedtls_free(buf); +} + +int mbedtls_platform_frng(void *p_rng, unsigned char *output, size_t output_len) +{ + size_t use_len = (output_len / 4 + 1) * 4; + + unsigned char buf[use_len]; + + memset(buf, 0, use_len); + + for (int i = 0; i < (use_len / 4); ++i) + { + *(uint32_t *)(buf + i * 4) = rand(); + } + + memcpy(output, buf, output_len); + + return (0); +} + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) +#include +#if !defined(_WIN32) && (defined(unix) || \ + defined(__unix) || defined(__unix__) || (defined(__APPLE__) && \ + defined(__MACH__))) +#include +#endif /* !_WIN32 && (unix || __unix || __unix__ || + * (__APPLE__ && __MACH__)) */ + +#if !((defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L) || \ + (defined(_POSIX_THREAD_SAFE_FUNCTIONS) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L)) +/* + * This is a convenience shorthand macro to avoid checking the long + * preprocessor conditions above. Ideally, we could expose this macro in + * platform_util.h and simply use it in platform_util.c, threading.c and + * threading.h. However, this macro is not part of the Mbed TLS public API, so + * we keep it private by only defining it in this file + */ +#if !(defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)) || \ + (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +#define PLATFORM_UTIL_USE_GMTIME +#endif + +#endif /* !( ( defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L ) || \ + ( defined(_POSIX_THREAD_SAFE_FUNCTIONS ) && \ + _POSIX_THREAD_SAFE_FUNCTIONS >= 200112L ) ) */ + +struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, + struct tm *tm_buf) +{ +#if defined(_WIN32) && !defined(PLATFORM_UTIL_USE_GMTIME) +#if defined(__STDC_LIB_EXT1__) + return (gmtime_s(tt, tm_buf) == 0) ? NULL : tm_buf; +#else + /* MSVC and mingw64 argument order and return value are inconsistent with the C11 standard */ + return (gmtime_s(tm_buf, tt) == 0) ? tm_buf : NULL; +#endif +#elif !defined(PLATFORM_UTIL_USE_GMTIME) + return gmtime_r(tt, tm_buf); +#else + struct tm *lt; + +#if defined(MBEDTLS_THREADING_C) + if (mbedtls_mutex_lock(&mbedtls_threading_gmtime_mutex) != 0) { + return NULL; + } +#endif /* MBEDTLS_THREADING_C */ + + lt = gmtime(tt); + + if (lt != NULL) { + memcpy(tm_buf, lt, sizeof(struct tm)); + } + +#if defined(MBEDTLS_THREADING_C) + if (mbedtls_mutex_unlock(&mbedtls_threading_gmtime_mutex) != 0) { + return NULL; + } +#endif /* MBEDTLS_THREADING_C */ + + return (lt == NULL) ? NULL : tm_buf; +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +} +#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */ + +#if defined(MBEDTLS_TEST_HOOKS) +void (*mbedtls_test_hook_test_fail)(const char *, int, const char *); +#endif /* MBEDTLS_TEST_HOOKS */ + +/* + * Provide external definitions of some inline functions so that the compiler + * has the option to not inline them + */ +extern inline void mbedtls_xor(unsigned char *r, + const unsigned char *a, + const unsigned char *b, + size_t n); + +extern inline uint16_t mbedtls_get_unaligned_uint16(const void *p); + +extern inline void mbedtls_put_unaligned_uint16(void *p, uint16_t x); + +extern inline uint32_t mbedtls_get_unaligned_uint32(const void *p); + +extern inline void mbedtls_put_unaligned_uint32(void *p, uint32_t x); + +extern inline uint64_t mbedtls_get_unaligned_uint64(const void *p); + +extern inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x); + +#if defined(MBEDTLS_HAVE_TIME) && !defined(MBEDTLS_PLATFORM_MS_TIME_ALT) + +#include +#if !defined(_WIN32) && \ + (defined(unix) || defined(__unix) || defined(__unix__) || \ + (defined(__APPLE__) && defined(__MACH__))) +#include +#endif /* !_WIN32 && (unix || __unix || __unix__ || (__APPLE__ && __MACH__)) */ +#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 199309L) +mbedtls_ms_time_t mbedtls_ms_time(void) +{ + int ret; + struct timespec tv; + mbedtls_ms_time_t current_ms; + +#if defined(__linux__) + ret = clock_gettime(CLOCK_BOOTTIME, &tv); +#else + ret = clock_gettime(CLOCK_MONOTONIC, &tv); +#endif + if (ret) { + return time(NULL) * 1000; + } + + current_ms = tv.tv_sec; + + return current_ms*1000 + tv.tv_nsec / 1000000; +} +#elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(_WIN64) +#include +mbedtls_ms_time_t mbedtls_ms_time(void) +{ + FILETIME ct; + mbedtls_ms_time_t current_ms; + + GetSystemTimeAsFileTime(&ct); + current_ms = ((mbedtls_ms_time_t) ct.dwLowDateTime + + ((mbedtls_ms_time_t) (ct.dwHighDateTime) << 32LL))/10000; + return current_ms; +} +#else +#error "No mbedtls_ms_time available" +#endif +#endif /* MBEDTLS_HAVE_TIME && !MBEDTLS_PLATFORM_MS_TIME_ALT */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/library/sha256.c b/src/app/findmy/crypto/third-party/mbedtls/library/sha256.c new file mode 100644 index 0000000..2466625 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/library/sha256.c @@ -0,0 +1,1008 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +/* + * The SHA-256 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \ + defined(__clang__) && __clang_major__ >= 4 +/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. + * + * The intrinsic declaration are guarded by predefined ACLE macros in clang: + * these are normally only enabled by the -march option on the command line. + * By defining the macros ourselves we gain access to those declarations without + * requiring -march on the command line. + * + * `arm_neon.h` could be included by any header file, so we put these defines + * at the top of this file, before any includes. + */ +#define __ARM_FEATURE_CRYPTO 1 +/* See: https://arm-software.github.io/acle/main/acle.html#cryptographic-extensions + * + * `__ARM_FEATURE_CRYPTO` is deprecated, but we need to continue to specify it + * for older compilers. + */ +#define __ARM_FEATURE_SHA2 1 +#define MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG +#endif + +#include "common.h" + +#if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C) + +#include "mbedtls/sha256.h" +#include "mbedtls/platform_util.h" +#include "mbedtls/error.h" + +#include + +#include "mbedtls/platform.h" + +#if defined(__aarch64__) + +# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \ + defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) + +/* *INDENT-OFF* */ + +# ifdef __ARM_NEON +# include +# else +# error "Target does not support NEON instructions" +# endif + +# if !defined(__ARM_FEATURE_CRYPTO) || defined(MBEDTLS_ENABLE_ARM_CRYPTO_EXTENSIONS_COMPILER_FLAG) +# if defined(__ARMCOMPILER_VERSION) +# if __ARMCOMPILER_VERSION <= 6090000 +# error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# endif +# pragma clang attribute push (__attribute__((target("sha2"))), apply_to=function) +# define MBEDTLS_POP_TARGET_PRAGMA +# elif defined(__clang__) +# if __clang_major__ < 4 +# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# endif +# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) +# define MBEDTLS_POP_TARGET_PRAGMA +# elif defined(__GNUC__) + /* FIXME: GCC 5 claims to support Armv8 Crypto Extensions, but some + * intrinsics are missing. Missing intrinsics could be worked around. + */ +# if __GNUC__ < 6 +# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# else +# pragma GCC push_options +# pragma GCC target ("arch=armv8-a+crypto") +# define MBEDTLS_POP_TARGET_PRAGMA +# endif +# else +# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# endif +# endif +/* *INDENT-ON* */ + +# endif +# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) +# if defined(__unix__) +# if defined(__linux__) +/* Our preferred method of detection is getauxval() */ +# include +# endif +/* Use SIGILL on Unix, and fall back to it on Linux */ +# include +# endif +# endif +#elif defined(_M_ARM64) +# if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \ + defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) +# include +# endif +#else +# undef MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY +# undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT +#endif + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) +/* + * Capability detection code comes early, so we can disable + * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT if no detection mechanism found + */ +#if defined(HWCAP_SHA2) +static int mbedtls_a64_crypto_sha256_determine_support(void) +{ + return (getauxval(AT_HWCAP) & HWCAP_SHA2) ? 1 : 0; +} +#elif defined(__APPLE__) +static int mbedtls_a64_crypto_sha256_determine_support(void) +{ + return 1; +} +#elif defined(_M_ARM64) +#define WIN32_LEAN_AND_MEAN +#include +#include + +static int mbedtls_a64_crypto_sha256_determine_support(void) +{ + return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? + 1 : 0; +} +#elif defined(__unix__) && defined(SIG_SETMASK) +/* Detection with SIGILL, setjmp() and longjmp() */ +#include +#include + +static jmp_buf return_from_sigill; + +/* + * A64 SHA256 support detection via SIGILL + */ +static void sigill_handler(int signal) +{ + (void) signal; + longjmp(return_from_sigill, 1); +} + +static int mbedtls_a64_crypto_sha256_determine_support(void) +{ + struct sigaction old_action, new_action; + + sigset_t old_mask; + if (sigprocmask(0, NULL, &old_mask)) { + return 0; + } + + sigemptyset(&new_action.sa_mask); + new_action.sa_flags = 0; + new_action.sa_handler = sigill_handler; + + sigaction(SIGILL, &new_action, &old_action); + + static int ret = 0; + + if (setjmp(return_from_sigill) == 0) { /* First return only */ + /* If this traps, we will return a second time from setjmp() with 1 */ + asm ("sha256h q0, q0, v0.4s" : : : "v0"); + ret = 1; + } + + sigaction(SIGILL, &old_action, NULL); + sigprocmask(SIG_SETMASK, &old_mask, NULL); + + return ret; +} +#else +#warning "No mechanism to detect A64_CRYPTO found, using C code only" +#undef MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT +#endif /* HWCAP_SHA2, __APPLE__, __unix__ && SIG_SETMASK */ + +#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */ + +#if !defined(MBEDTLS_SHA256_ALT) + +#define SHA256_BLOCK_SIZE 64 + +void mbedtls_sha256_init(mbedtls_sha256_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_free(mbedtls_sha256_context *ctx) +{ + if (ctx == NULL) { + return; + } + + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + *dst = *src; +} + +/* + * SHA-256 context setup + */ +int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) +{ +#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) + if (is224 != 0 && is224 != 1) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#elif defined(MBEDTLS_SHA256_C) + if (is224 != 0) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#else /* defined MBEDTLS_SHA224_C only */ + if (is224 == 0) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#endif + + ctx->total[0] = 0; + ctx->total[1] = 0; + + if (is224 == 0) { +#if defined(MBEDTLS_SHA256_C) + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +#endif + } else { +#if defined(MBEDTLS_SHA224_C) + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; +#endif + } + +#if defined(MBEDTLS_SHA224_C) + ctx->is224 = is224; +#endif + + return 0; +} + +#if !defined(MBEDTLS_SHA256_PROCESS_ALT) +static const uint32_t K[] = +{ + 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, +}; + +#endif + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \ + defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) +# define mbedtls_internal_sha256_process_many_a64_crypto mbedtls_internal_sha256_process_many +# define mbedtls_internal_sha256_process_a64_crypto mbedtls_internal_sha256_process +#endif + +static size_t mbedtls_internal_sha256_process_many_a64_crypto( + mbedtls_sha256_context *ctx, const uint8_t *msg, size_t len) +{ + uint32x4_t abcd = vld1q_u32(&ctx->state[0]); + uint32x4_t efgh = vld1q_u32(&ctx->state[4]); + + size_t processed = 0; + + for (; + len >= SHA256_BLOCK_SIZE; + processed += SHA256_BLOCK_SIZE, + msg += SHA256_BLOCK_SIZE, + len -= SHA256_BLOCK_SIZE) { + uint32x4_t tmp, abcd_prev; + + uint32x4_t abcd_orig = abcd; + uint32x4_t efgh_orig = efgh; + + uint32x4_t sched0 = (uint32x4_t) vld1q_u8(msg + 16 * 0); + uint32x4_t sched1 = (uint32x4_t) vld1q_u8(msg + 16 * 1); + uint32x4_t sched2 = (uint32x4_t) vld1q_u8(msg + 16 * 2); + uint32x4_t sched3 = (uint32x4_t) vld1q_u8(msg + 16 * 3); + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* Will be true if not defined */ + /* Untested on BE */ + sched0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched0))); + sched1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched1))); + sched2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched2))); + sched3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(sched3))); +#endif + + /* Rounds 0 to 3 */ + tmp = vaddq_u32(sched0, vld1q_u32(&K[0])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds 4 to 7 */ + tmp = vaddq_u32(sched1, vld1q_u32(&K[4])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds 8 to 11 */ + tmp = vaddq_u32(sched2, vld1q_u32(&K[8])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds 12 to 15 */ + tmp = vaddq_u32(sched3, vld1q_u32(&K[12])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + for (int t = 16; t < 64; t += 16) { + /* Rounds t to t + 3 */ + sched0 = vsha256su1q_u32(vsha256su0q_u32(sched0, sched1), sched2, sched3); + tmp = vaddq_u32(sched0, vld1q_u32(&K[t])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds t + 4 to t + 7 */ + sched1 = vsha256su1q_u32(vsha256su0q_u32(sched1, sched2), sched3, sched0); + tmp = vaddq_u32(sched1, vld1q_u32(&K[t + 4])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds t + 8 to t + 11 */ + sched2 = vsha256su1q_u32(vsha256su0q_u32(sched2, sched3), sched0, sched1); + tmp = vaddq_u32(sched2, vld1q_u32(&K[t + 8])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + + /* Rounds t + 12 to t + 15 */ + sched3 = vsha256su1q_u32(vsha256su0q_u32(sched3, sched0), sched1, sched2); + tmp = vaddq_u32(sched3, vld1q_u32(&K[t + 12])); + abcd_prev = abcd; + abcd = vsha256hq_u32(abcd_prev, efgh, tmp); + efgh = vsha256h2q_u32(efgh, abcd_prev, tmp); + } + + abcd = vaddq_u32(abcd, abcd_orig); + efgh = vaddq_u32(efgh, efgh_orig); + } + + vst1q_u32(&ctx->state[0], abcd); + vst1q_u32(&ctx->state[4], efgh); + + return processed; +} + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) +/* + * This function is for internal use only if we are building both C and A64 + * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process() + */ +static +#endif +int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx, + const unsigned char data[SHA256_BLOCK_SIZE]) +{ + return (mbedtls_internal_sha256_process_many_a64_crypto(ctx, data, + SHA256_BLOCK_SIZE) == + SHA256_BLOCK_SIZE) ? 0 : -1; +} + +#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ + +#if defined(MBEDTLS_POP_TARGET_PRAGMA) +#if defined(__clang__) +#pragma clang attribute pop +#elif defined(__GNUC__) +#pragma GCC pop_options +#endif +#undef MBEDTLS_POP_TARGET_PRAGMA +#endif + +#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) +#define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many +#define mbedtls_internal_sha256_process_c mbedtls_internal_sha256_process +#endif + + +#if !defined(MBEDTLS_SHA256_PROCESS_ALT) && \ + !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) + +#define SHR(x, n) (((x) & 0xFFFFFFFF) >> (n)) +#define ROTR(x, n) (SHR(x, n) | ((x) << (32 - (n)))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) + +#define F0(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) + +#define R(t) \ + ( \ + local.W[t] = S1(local.W[(t) - 2]) + local.W[(t) - 7] + \ + S0(local.W[(t) - 15]) + local.W[(t) - 16] \ + ) + +#define P(a, b, c, d, e, f, g, h, x, K) \ + do \ + { \ + local.temp1 = (h) + S3(e) + F1((e), (f), (g)) + (K) + (x); \ + local.temp2 = S2(a) + F0((a), (b), (c)); \ + (d) += local.temp1; (h) = local.temp1 + local.temp2; \ + } while (0) + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) +/* + * This function is for internal use only if we are building both C and A64 + * versions, otherwise it is renamed to be the public mbedtls_internal_sha256_process() + */ +static +#endif +int mbedtls_internal_sha256_process_c(mbedtls_sha256_context *ctx, + const unsigned char data[SHA256_BLOCK_SIZE]) +{ + struct { + uint32_t temp1, temp2, W[64]; + uint32_t A[8]; + } local; + + unsigned int i; + + for (i = 0; i < 8; i++) { + local.A[i] = ctx->state[i]; + } + +#if defined(MBEDTLS_SHA256_SMALLER) + for (i = 0; i < 64; i++) { + if (i < 16) { + local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i); + } else { + R(i); + } + + P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i], K[i]); + + local.temp1 = local.A[7]; local.A[7] = local.A[6]; + local.A[6] = local.A[5]; local.A[5] = local.A[4]; + local.A[4] = local.A[3]; local.A[3] = local.A[2]; + local.A[2] = local.A[1]; local.A[1] = local.A[0]; + local.A[0] = local.temp1; + } +#else /* MBEDTLS_SHA256_SMALLER */ + for (i = 0; i < 16; i++) { + local.W[i] = MBEDTLS_GET_UINT32_BE(data, 4 * i); + } + + for (i = 0; i < 16; i += 8) { + P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], local.W[i+0], K[i+0]); + P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], + local.A[4], local.A[5], local.A[6], local.W[i+1], K[i+1]); + P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], + local.A[3], local.A[4], local.A[5], local.W[i+2], K[i+2]); + P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], + local.A[2], local.A[3], local.A[4], local.W[i+3], K[i+3]); + P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], + local.A[1], local.A[2], local.A[3], local.W[i+4], K[i+4]); + P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], + local.A[0], local.A[1], local.A[2], local.W[i+5], K[i+5]); + P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], + local.A[7], local.A[0], local.A[1], local.W[i+6], K[i+6]); + P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], + local.A[6], local.A[7], local.A[0], local.W[i+7], K[i+7]); + } + + for (i = 16; i < 64; i += 8) { + P(local.A[0], local.A[1], local.A[2], local.A[3], local.A[4], + local.A[5], local.A[6], local.A[7], R(i+0), K[i+0]); + P(local.A[7], local.A[0], local.A[1], local.A[2], local.A[3], + local.A[4], local.A[5], local.A[6], R(i+1), K[i+1]); + P(local.A[6], local.A[7], local.A[0], local.A[1], local.A[2], + local.A[3], local.A[4], local.A[5], R(i+2), K[i+2]); + P(local.A[5], local.A[6], local.A[7], local.A[0], local.A[1], + local.A[2], local.A[3], local.A[4], R(i+3), K[i+3]); + P(local.A[4], local.A[5], local.A[6], local.A[7], local.A[0], + local.A[1], local.A[2], local.A[3], R(i+4), K[i+4]); + P(local.A[3], local.A[4], local.A[5], local.A[6], local.A[7], + local.A[0], local.A[1], local.A[2], R(i+5), K[i+5]); + P(local.A[2], local.A[3], local.A[4], local.A[5], local.A[6], + local.A[7], local.A[0], local.A[1], R(i+6), K[i+6]); + P(local.A[1], local.A[2], local.A[3], local.A[4], local.A[5], + local.A[6], local.A[7], local.A[0], R(i+7), K[i+7]); + } +#endif /* MBEDTLS_SHA256_SMALLER */ + + for (i = 0; i < 8; i++) { + ctx->state[i] += local.A[i]; + } + + /* Zeroise buffers and variables to clear sensitive data from memory. */ + mbedtls_platform_zeroize(&local, sizeof(local)); + + return 0; +} + +#endif /* !MBEDTLS_SHA256_PROCESS_ALT && !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ + + +#if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) + +static size_t mbedtls_internal_sha256_process_many_c( + mbedtls_sha256_context *ctx, const uint8_t *data, size_t len) +{ + size_t processed = 0; + + while (len >= SHA256_BLOCK_SIZE) { + if (mbedtls_internal_sha256_process_c(ctx, data) != 0) { + return 0; + } + + data += SHA256_BLOCK_SIZE; + len -= SHA256_BLOCK_SIZE; + + processed += SHA256_BLOCK_SIZE; + } + + return processed; +} + +#endif /* !MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ + + +#if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) + +static int mbedtls_a64_crypto_sha256_has_support(void) +{ + static int done = 0; + static int supported = 0; + + if (!done) { + supported = mbedtls_a64_crypto_sha256_determine_support(); + done = 1; + } + + return supported; +} + +static size_t mbedtls_internal_sha256_process_many(mbedtls_sha256_context *ctx, + const uint8_t *msg, size_t len) +{ + if (mbedtls_a64_crypto_sha256_has_support()) { + return mbedtls_internal_sha256_process_many_a64_crypto(ctx, msg, len); + } else { + return mbedtls_internal_sha256_process_many_c(ctx, msg, len); + } +} + +int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, + const unsigned char data[SHA256_BLOCK_SIZE]) +{ + if (mbedtls_a64_crypto_sha256_has_support()) { + return mbedtls_internal_sha256_process_a64_crypto(ctx, data); + } else { + return mbedtls_internal_sha256_process_c(ctx, data); + } +} + +#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT */ + + +/* + * SHA-256 process buffer + */ +int mbedtls_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t fill; + uint32_t left; + + if (ilen == 0) { + return 0; + } + + left = ctx->total[0] & 0x3F; + fill = SHA256_BLOCK_SIZE - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if (ctx->total[0] < (uint32_t) ilen) { + ctx->total[1]++; + } + + if (left && ilen >= fill) { + memcpy((void *) (ctx->buffer + left), input, fill); + + if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { + return ret; + } + + input += fill; + ilen -= fill; + left = 0; + } + + while (ilen >= SHA256_BLOCK_SIZE) { + size_t processed = + mbedtls_internal_sha256_process_many(ctx, input, ilen); + if (processed < SHA256_BLOCK_SIZE) { + return MBEDTLS_ERR_ERROR_GENERIC_ERROR; + } + + input += processed; + ilen -= processed; + } + + if (ilen > 0) { + memcpy((void *) (ctx->buffer + left), input, ilen); + } + + return 0; +} + +/* + * SHA-256 final digest + */ +int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char *output) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + uint32_t used; + uint32_t high, low; + int truncated = 0; + + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->total[0] & 0x3F; + + ctx->buffer[used++] = 0x80; + + if (used <= 56) { + /* Enough room for padding + length in current block */ + memset(ctx->buffer + used, 0, 56 - used); + } else { + /* We'll need an extra block */ + memset(ctx->buffer + used, 0, SHA256_BLOCK_SIZE - used); + + if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { + goto exit; + } + + memset(ctx->buffer, 0, 56); + } + + /* + * Add message length + */ + high = (ctx->total[0] >> 29) + | (ctx->total[1] << 3); + low = (ctx->total[0] << 3); + + MBEDTLS_PUT_UINT32_BE(high, ctx->buffer, 56); + MBEDTLS_PUT_UINT32_BE(low, ctx->buffer, 60); + + if ((ret = mbedtls_internal_sha256_process(ctx, ctx->buffer)) != 0) { + goto exit; + } + + /* + * Output final state + */ + MBEDTLS_PUT_UINT32_BE(ctx->state[0], output, 0); + MBEDTLS_PUT_UINT32_BE(ctx->state[1], output, 4); + MBEDTLS_PUT_UINT32_BE(ctx->state[2], output, 8); + MBEDTLS_PUT_UINT32_BE(ctx->state[3], output, 12); + MBEDTLS_PUT_UINT32_BE(ctx->state[4], output, 16); + MBEDTLS_PUT_UINT32_BE(ctx->state[5], output, 20); + MBEDTLS_PUT_UINT32_BE(ctx->state[6], output, 24); + +#if defined(MBEDTLS_SHA224_C) + truncated = ctx->is224; +#endif + if (!truncated) { + MBEDTLS_PUT_UINT32_BE(ctx->state[7], output, 28); + } + + ret = 0; + +exit: + mbedtls_sha256_free(ctx); + return ret; +} + +/* + * output = SHA-256( input buffer ) + */ +int mbedtls_sha256(const unsigned char *input, + size_t ilen, + unsigned char *output, + int is224) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_sha256_context ctx; + +#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) + if (is224 != 0 && is224 != 1) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#elif defined(MBEDTLS_SHA256_C) + if (is224 != 0) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#else /* defined MBEDTLS_SHA224_C only */ + if (is224 == 0) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } +#endif + + mbedtls_sha256_init(&ctx); + + if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) { + goto exit; + } + + if ((ret = mbedtls_sha256_update(&ctx, input, ilen)) != 0) { + goto exit; + } + + if ((ret = mbedtls_sha256_finish(&ctx, output)) != 0) { + goto exit; + } + +exit: + mbedtls_sha256_free(&ctx); + + return ret; +} +#else + +void mbedtls_sha256_init(mbedtls_sha256_context *ctx) +{ + MBEDTLS_INTERNAL_VALIDATE(ctx != NULL); + memset(ctx, 0, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_free(mbedtls_sha256_context *ctx) +{ + if (ctx == NULL) + { + return; + } + mbedtls_platform_zeroize(ctx, sizeof(mbedtls_sha256_context)); +} + +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + MBEDTLS_INTERNAL_VALIDATE(dst != NULL); + MBEDTLS_INTERNAL_VALIDATE(src != NULL); + *dst = *src; +} + +int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) +{ + SHA256_Init(ctx); + return (0); +} + +int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, + const unsigned char data[64]) +{ + SHA256_Update(ctx, data, 64); + return (0); +} + +int mbedtls_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen) +{ + SHA256_Update(ctx, input, ilen); + return (0); +} + +int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char output[32]) +{ + SHA256_Final(ctx, (unsigned char *)output); + return (0); +} + +int mbedtls_sha256(const unsigned char *input, + size_t ilen, + unsigned char output[32], + int is224) +{ + SHA256((uint8_t *)input, ilen, output); + return (0); +} + +#endif /* !MBEDTLS_SHA256_ALT */ + + +#if defined(MBEDTLS_SELF_TEST) +/* + * FIPS-180-2 test vectors + */ +static const unsigned char sha_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const size_t sha_test_buflen[3] = +{ + 3, 56, 1000 +}; + +typedef const unsigned char (sha_test_sum_t)[32]; + +/* + * SHA-224 test vectors + */ +#if defined(MBEDTLS_SHA224_C) +static sha_test_sum_t sha224_test_sum[] = +{ + { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, + 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, + 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, + 0xE3, 0x6C, 0x9D, 0xA7 }, + { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, + 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, + 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, + 0x52, 0x52, 0x25, 0x25 }, + { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, + 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, + 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, + 0x4E, 0xE7, 0xAD, 0x67 } +}; +#endif + +/* + * SHA-256 test vectors + */ +#if defined(MBEDTLS_SHA256_C) +static sha_test_sum_t sha256_test_sum[] = +{ + { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, + { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, + { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } +}; +#endif + +/* + * Checkup routine + */ +static int mbedtls_sha256_common_self_test(int verbose, int is224) +{ + int i, buflen, ret = 0; + unsigned char *buf; + unsigned char sha256sum[32]; + mbedtls_sha256_context ctx; + +#if defined(MBEDTLS_SHA224_C) && defined(MBEDTLS_SHA256_C) + sha_test_sum_t *sha_test_sum = (is224) ? sha224_test_sum : sha256_test_sum; +#elif defined(MBEDTLS_SHA256_C) + sha_test_sum_t *sha_test_sum = sha256_test_sum; +#else + sha_test_sum_t *sha_test_sum = sha224_test_sum; +#endif + + buf = mbedtls_calloc(1024, sizeof(unsigned char)); + if (NULL == buf) { + if (verbose != 0) { + mbedtls_printf("Buffer allocation failed\n"); + } + + return 1; + } + + mbedtls_sha256_init(&ctx); + + for (i = 0; i < 3; i++) { + if (verbose != 0) { + mbedtls_printf(" SHA-%d test #%d: ", 256 - is224 * 32, i + 1); + } + + if ((ret = mbedtls_sha256_starts(&ctx, is224)) != 0) { + goto fail; + } + + if (i == 2) { + memset(buf, 'a', buflen = 1000); + + for (int j = 0; j < 1000; j++) { + ret = mbedtls_sha256_update(&ctx, buf, buflen); + if (ret != 0) { + goto fail; + } + } + + } else { + ret = mbedtls_sha256_update(&ctx, sha_test_buf[i], + sha_test_buflen[i]); + if (ret != 0) { + goto fail; + } + } + + if ((ret = mbedtls_sha256_finish(&ctx, sha256sum)) != 0) { + goto fail; + } + + + if (memcmp(sha256sum, sha_test_sum[i], 32 - is224 * 4) != 0) { + ret = 1; + goto fail; + } + + if (verbose != 0) { + mbedtls_printf("passed\n"); + } + } + + if (verbose != 0) { + mbedtls_printf("\n"); + } + + goto exit; + +fail: + if (verbose != 0) { + mbedtls_printf("failed\n"); + } + +exit: + mbedtls_sha256_free(&ctx); + mbedtls_free(buf); + + return ret; +} + +#if defined(MBEDTLS_SHA256_C) +int mbedtls_sha256_self_test(int verbose) +{ + return mbedtls_sha256_common_self_test(verbose, 0); +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA224_C) +int mbedtls_sha224_self_test(int verbose) +{ + return mbedtls_sha256_common_self_test(verbose, 1); +} +#endif /* MBEDTLS_SHA224_C */ + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA256_C || MBEDTLS_SHA224_C */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/mbedtls_config.h b/src/app/findmy/crypto/third-party/mbedtls/mbedtls_config.h new file mode 100644 index 0000000..36f9f3c --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/mbedtls_config.h @@ -0,0 +1,4118 @@ +/** + * \file mbedtls_config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +/** + * This is an optional version symbol that enables compatibility handling of + * config files. + * + * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that + * introduced the config format we want to be compatible with. + */ +//#define MBEDTLS_CONFIG_VERSION 0x03000000 + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aesni.h + * library/aria.c + * library/bn_mul.h + * library/constant_time.c + * library/padlock.h + * + * Required by: + * MBEDTLS_AESCE_C + * MBEDTLS_AESNI_C (on some platforms) + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +//#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions. + * + * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing + * interface - timing.c will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default Mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling #MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling #MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * An overview of how the value of mbedtls_calloc is determined: + * + * - if !MBEDTLS_PLATFORM_MEMORY + * - mbedtls_calloc = calloc + * - if MBEDTLS_PLATFORM_MEMORY + * - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): + * - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO + * - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): + * - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC. + * - How is MBEDTLS_PLATFORM_STD_CALLOC handled? + * - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: + * - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything; + * - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present; + * - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: + * - if MBEDTLS_PLATFORM_STD_CALLOC is present: + * - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected; + * - if !MBEDTLS_PLATFORM_STD_CALLOC: + * - MBEDTLS_PLATFORM_STD_CALLOC = calloc + * + * - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked. + * - if !MBEDTLS_PLATFORM_STD_CALLOC + * - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc + * + * - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC. + * + * Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible. + * MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time. + * #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used, + * dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases. + * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. + * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let Mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, Mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_SETBUF_ALT +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT +//#define MBEDTLS_PLATFORM_MS_TIME_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(), to wipe sensitive data in memory. This replaces + * the default implementation in platform_util.c. + * + * By default, the library uses a system function such as memset_s() + * (optional feature of C11), explicit_bzero() (BSD and compatible), or + * SecureZeroMemory (Windows). If no such function is detected, the library + * falls back to a plain C implementation. Compilers are technically + * permitted to optimize this implementation out, meaning that the memory is + * not actually wiped. The library tries to prevent that, but the C language + * makes it impossible to guarantee that the memory will always be wiped. + * + * If your platform provides a guaranteed method to wipe memory which + * `platform_util.c` does not detect, define this macro to the name of + * a function that takes two arguments, a `void *` pointer and a length, + * and wipes that many bytes starting at the specified address. For example, + * if your platform has explicit_bzero() but `platform_util.c` does not + * detect its presence, define `MBEDTLS_PLATFORM_ZEROIZE_ALT` to be + * `explicit_bzero` to use that function as mbedtls_platform_zeroize(). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions and features so that they generate a warning if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions and features so that they generate an error if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * Uncomment to get errors on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/** \} name SECTION: System support */ + +/** + * \name SECTION: Mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let Mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, Mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD5, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT + +/* + * When replacing the elliptic curve module, please consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_SHA256_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from Mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, Mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note If you use the AES_xxx_ALT macros, then it is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are + * enabled, then the deterministic ECDH signature functions pass the + * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore + * alternative implementations should use the RNG only for generating + * the ephemeral key and nothing else. If this is not possible, then + * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative + * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). + * + */ +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from Mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * The original implementation can in addition be removed by setting the + * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the + * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be + * able to fallback to curves not supported by the alternative implementation. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, Mbed TLS will still provide the ecp_double_jac() + * function, but will use your mbedtls_internal_ecp_double_jac() if the group + * for the operation is supported by your implementation (i.e. your + * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the + * group is not supported by your implementation, then the original Mbed TLS + * implementation of ecp_double_jac() is used instead, unless this fallback + * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case + * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). + * + * The function prototypes and the definition of mbedtls_ecp_group and + * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your + * implementation of mbedtls_internal_ecp__function_name__ must be compatible + * with their definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Turn off software fallback for curves not supported in hardware */ +//#define MBEDTLS_ECP_NO_FALLBACK +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let Mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in library/entropy_poll.h, and accept NULL as first + * argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + */ +#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH + * + * Use only 128-bit keys in AES operations to save ROM. + * + * Uncomment this macro to remove support for AES operations that use 192- + * or 256-bit keys. + * + * Uncommenting this macro reduces the size of AES code by ~300 bytes + * on v8-M/Thumb2. + * + * Module: library/aes.c + * + * Requires: MBEDTLS_AES_C + */ +//#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH + +/* + * Disable plain C implementation for AES. + * + * When the plain C implementation is enabled, and an implementation using a + * special CPU feature (such as MBEDTLS_AESCE_C) is also enabled, runtime + * detection will be used to select between them. + * + * If only one implementation is present, runtime detection will not be used. + * This configuration will crash at runtime if running on a CPU without the + * necessary features. It will not build unless at least one of MBEDTLS_AESCE_C + * and/or MBEDTLS_AESNI_C is enabled & present in the build. + */ +//#define MBEDTLS_AES_USE_HARDWARE_ONLY + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CHECK_RETURN_WARNING + * + * If this macro is defined, emit a compile-time warning if application code + * calls a function without checking its return value, but the return value + * should generally be checked in portable applications. + * + * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is + * implemented. Otherwise this option has no effect. + * + * Uncomment to get warnings on using fallible functions without checking + * their return value. + * + * \note This feature is a work in progress. + * Warnings will be added to more functions in the future. + * + * \note A few functions are considered critical, and ignoring the return + * value of these functions will trigger a warning even if this + * macro is not defined. To completely disable return value check + * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. + */ +//#define MBEDTLS_CHECK_RETURN_WARNING + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +//#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +//#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * To enable the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +//#define MBEDTLS_CIPHER_PADDING_PKCS7 +//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +//#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + * + * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. + * Without this, CTR_DRBG uses a 256-bit key + * unless \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. + */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + +/** + * Enable the verified implementations of ECDH primitives from Project Everest + * (currently only Curve25519). This feature changes the layout of ECDH + * contexts and therefore is a compatibility break for applications that access + * fields of a mbedtls_ecdh_context structure directly. See also + * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. + * + * The Everest code is provided under the Apache 2.0 license only; therefore enabling this + * option is not compatible with taking the library under the GPL v2.0-or-later license. + */ +//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ +//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +//#define MBEDTLS_ECP_DP_BP256R1_ENABLED +//#define MBEDTLS_ECP_DP_BP384R1_ENABLED +//#define MBEDTLS_ECP_DP_BP512R1_ENABLED +/* Montgomery curves (supporting ECP) */ +//#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +//#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in + * order to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum + * number of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * This option: + * - Adds xxx_restartable() variants of existing operations in the + * following modules, with corresponding restart context types: + * - ECP (for Short Weierstrass curves only): scalar multiplication (mul), + * linear combination (muladd); + * - ECDSA: signature generation & verification; + * - PK: signature generation & verification; + * - X509: certificate chain verification. + * - Adds mbedtls_ecdh_enable_restart() in the ECDH module. + * - Changes the behaviour of TLS 1.2 clients (not servers) when using the + * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC + * computations restartable: + * - ECDH operations from the key exchange, only for Short Weierstrass + * curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled. + * - verification of the server's key exchange signature; + * - verification of the server's certificate chain; + * - generation of the client's signature if client authentication is used, + * with an ECC key/certificate. + * + * \note In the cases above, the usual SSL/TLS functions, such as + * mbedtls_ssl_handshake(), can now return + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS. + * + * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled, + * restartable operations in PK, X.509 and TLS (see above) are not + * using PSA. On the other hand, ECDH computations in TLS are using + * PSA, and are not restartable. These are temporary limitations that + * should be lifted in the future. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. + * + * Requires: MBEDTLS_ECP_C + * + * Uncomment this macro to enable restartable ECC computations. + */ +#define MBEDTLS_ECP_RESTARTABLE + +/** + * Uncomment to enable using new bignum code in the ECC modules. + * + * \warning This is currently experimental, incomplete and therefore should not + * be used in production. + */ +//#define MBEDTLS_ECP_WITH_MPI_UINT + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + */ +//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_RSA_C + * MBEDTLS_PKCS1_V15 + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_RSA_C + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + * + * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Requires: MBEDTLS_ECJPAKE_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_JPAKE) + * SHA-256 (via MBEDTLS_SHA256_C or a PSA driver) + * MBEDTLS_ECP_DP_SECP256R1_ENABLED + * + * \warning If SHA-256 is provided only by a PSA driver, you must call + * psa_crypto_init() before the first hanshake (even if + * MBEDTLS_USE_PSA_CRYPTO is disabled). + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_PK_PARSE_EC_COMPRESSED + * + * Enable the support for parsing public keys of type Short Weierstrass + * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX) which are using the + * compressed point format. This parsing is done through ECP module's functions. + * + * \note As explained in the description of MBEDTLS_ECP_PF_COMPRESSED (in ecp.h) + * the only unsupported curves are MBEDTLS_ECP_DP_SECP224R1 and + * MBEDTLS_ECP_DP_SECP224K1. + */ +//#define MBEDTLS_PK_PARSE_EC_COMPRESSED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +//#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources in mbedtls_entropy_init(). + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + * + * Enable key identifiers that encode a key owner identifier. + * + * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t + * which is currently hard-coded to be int32_t. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() and backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +//#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +//#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS#1 v2.1 operation. + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define MBEDTLS_PKCS1_V21 + +/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + * + * Enable support for platform built-in keys. If you enable this feature, + * you must implement the function mbedtls_psa_platform_get_builtin_key(). + * See the documentation of that function for more information. + * + * Built-in keys are typically derived from a hardware unique key or + * stored in a secure element. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + +/** \def MBEDTLS_PSA_CRYPTO_CLIENT + * + * Enable support for PSA crypto client. + * + * \note This option allows to include the code necessary for a PSA + * crypto client when the PSA crypto implementation is not included in + * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the + * code to set and get PSA key attributes. + * The development of PSA drivers partially relying on the library to + * fulfill the hardware gaps is another possible usage of this option. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_CLIENT + +/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + * + * Make the PSA Crypto module use an external random generator provided + * by a driver, instead of Mbed TLS's entropy and DRBG modules. + * + * \note This random generator must deliver random numbers with cryptographic + * quality and high performance. It must supply unpredictable numbers + * with a uniform distribution. The implementation of this function + * is responsible for ensuring that the random generator is seeded + * with sufficient entropy. If you have a hardware TRNG which is slow + * or delivers non-uniform output, declare it as an entropy source + * with mbedtls_entropy_add_source() instead of enabling this option. + * + * If you enable this option, you must configure the type + * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h + * and define a function called mbedtls_psa_external_get_random() + * with the following prototype: + * ``` + * psa_status_t mbedtls_psa_external_get_random( + * mbedtls_psa_external_random_context_t *context, + * uint8_t *output, size_t output_size, size_t *output_length); + * ); + * ``` + * The \c context value is initialized to 0 before the first call. + * The function must fill the \c output buffer with \c output_size bytes + * of random data and set \c *output_length to \c output_size. + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \warning If you enable this option, code that uses the PSA cryptography + * interface will not use any of the entropy sources set up for + * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED + * enables. + * + * \note This option is experimental and may be removed without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * If you enable this option, your build environment must include a header + * file `"crypto_spe.h"` (either in the `psa` subdirectory of the Mbed TLS + * header files, or in another directory on the compiler's include search + * path). Alternatively, your platform may customize the header + * `psa/crypto_platform.h`, in which case it can skip or replace the + * inclusion of `"crypto_spe.h"`. + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * Uncomment to enable p256-m. This is an alternative implementation of + * key generation, ECDH and (randomized) ECDSA on the curve SECP256R1. + * Compared to the default implementation: + * + * - p256-m has a much smaller code size and RAM footprint. + * - p256-m is only available via the PSA API. This includes the pk module + * when #MBEDTLS_USE_PSA_CRYPTO is enabled. + * - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols + * over the core arithmetic, or deterministic derivation of keys. + * + * We recommend enabling this option if your application uses the PSA API + * and the only elliptic curve support it needs is ECDH and ECDSA over + * SECP256R1. + * + * If you enable this option, you do not need to enable any ECC-related + * MBEDTLS_xxx option. You do need to separately request support for the + * cryptographic mechanisms through the PSA API: + * - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based + * configuration; + * - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS; + * - #PSA_WANT_ECC_SECP_R1_256; + * - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed; + * - #PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY, #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC, + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT, + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed. + * + * \note To benefit from the smaller code size of p256-m, make sure that you + * do not enable any ECC-related option not supported by p256-m: this + * would cause the built-in ECC implementation to be built as well, in + * order to provide the required option. + * Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than + * SECP256R1 are disabled as they are not supported by this driver. + * Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or + * #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of + * the built-in ECC implementation, see docs/driver-only-builds.md. + */ +//#define MBEDTLS_PSA_P256M_DRIVER_ENABLED + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SHA512_SMALLER + * + * Enable an implementation of SHA-512 that has lower ROM footprint but also + * lower performance. + * + * Uncomment to enable the smaller implementation of SHA512. + */ +//#define MBEDTLS_SHA512_SMALLER + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, Mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +//#define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID + * + * Enable support for the DTLS Connection ID (CID) extension, + * which allows to identify DTLS connections across changes + * in the underlying transport. The CID functionality is described + * in RFC 9146. + * + * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, + * mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and + * `mbedtls_ssl_conf_cid()`. See the corresponding documentation for + * more information. + * + * The maximum lengths of outgoing and incoming CIDs can be configured + * through the options + * - MBEDTLS_SSL_CID_OUT_LEN_MAX + * - MBEDTLS_SSL_CID_IN_LEN_MAX. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment to enable the Connection ID extension. + */ +//#define MBEDTLS_SSL_DTLS_CONNECTION_ID + + +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT + * + * Defines whether RFC 9146 (default) or the legacy version + * (version draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) + * is used. + * + * Set the value to 0 for the standard version, and + * 1 for the legacy draft version. + * + * \deprecated Support for the legacy version of the DTLS + * Connection ID feature is deprecated. Please + * switch to the standardized version defined + * in RFC 9146 enabled by utilizing + * MBEDTLS_SSL_DTLS_CONNECTION_ID without use + * of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT. + * + * Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID + */ +//#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0 + +/** + * \def MBEDTLS_SSL_ASYNC_PRIVATE + * + * Enable asynchronous external private key operations in SSL. This allows + * you to configure an SSL connection to call an external cryptographic + * module to perform private key operations instead of performing the + * operation inside the library. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + */ +//#define MBEDTLS_SSL_ASYNC_PRIVATE + +/** + * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION + * + * Enable serialization of the TLS context structures, through use of the + * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). + * + * This pair of functions allows one side of a connection to serialize the + * context associated with the connection, then free or re-use that context + * while the serialized state is persisted elsewhere, and finally deserialize + * that state to a live context for resuming read/write operations on the + * connection. From a protocol perspective, the state of the connection is + * unaffected, in particular this is entirely transparent to the peer. + * + * Note: this is distinct from TLS session resumption, which is part of the + * protocol and fully visible by the peer. TLS session resumption enables + * establishing new connections associated to a saved session with shorter, + * lighter handshakes, while context serialization is a local optimization in + * handling a single, potentially long-lived connection. + * + * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are + * saved after the handshake to allow for more efficient serialization, so if + * you don't need this feature you'll save RAM by disabling it. + * + * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C + * + * Comment to disable the context serialization APIs. + */ +//#define MBEDTLS_SSL_CONTEXT_SERIALIZATION + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +//#define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for RFC 7627: Session Hash and Extended Master Secret + * Extension. + * + * This was introduced as "the proper fix" to the Triple Handshake family of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +//#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * + * This option controls the availability of the API mbedtls_ssl_get_peer_cert() + * giving access to the peer's certificate after completion of the handshake. + * + * Unless you need mbedtls_ssl_peer_cert() in your application, it is + * recommended to disable this option for reduced RAM usage. + * + * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still + * defined, but always returns \c NULL. + * + * \note This option has no influence on the protection against the + * triple handshake attack. Even if it is disabled, Mbed TLS will + * still ensure that certificates do not change during renegotiation, + * for example by keeping a hash of the peer's certificate. + * + * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set. + * + * Comment this macro to disable storing the peer's certificate + * after the handshake. + */ +//#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Enable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this to disable support for renegotiation. + * + * \note Even if this option is disabled, both client and server are aware + * of the Renegotiation Indication Extension (RFC 5746) used to + * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). + * (See \c mbedtls_ssl_conf_legacy_renegotiation for the + * configuration of this extension). + * + */ +//#define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_RECORD_SIZE_LIMIT + * + * Enable support for RFC 8449 record_size_limit extension in SSL (TLS 1.3 only). + * + * \warning This extension is currently in development and must NOT be used except + * for testing purposes. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_3 + * + * Uncomment this macro to enable support for the record_size_limit extension + */ +//#define MBEDTLS_SSL_RECORD_SIZE_LIMIT + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: Without MBEDTLS_USE_PSA_CRYPTO: MBEDTLS_MD_C and + * (MBEDTLS_SHA256_C or MBEDTLS_SHA384_C or + * SHA-256 or SHA-512 provided by a PSA driver) + * With MBEDTLS_USE_PSA_CRYPTO: + * PSA_WANT_ALG_SHA_256 or PSA_WANT_ALG_SHA_384 + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, or if the hash(es) used + * are only provided by PSA drivers, you must call psa_crypto_init() before + * doing any TLS operations. + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +//#define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_3 + * + * Enable support for TLS 1.3. + * + * \note See docs/architecture/tls13-support.md for a description of the TLS + * 1.3 support that this option enables. + * + * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \note TLS 1.3 uses PSA crypto for cryptographic operations that are + * directly performed by TLS 1.3 code. As a consequence, you must + * call psa_crypto_init() before the first TLS 1.3 handshake. + * + * \note Cryptographic operations performed indirectly via another module + * (X.509, PK) or by code shared with TLS 1.2 (record protection, + * running handshake hash) only use PSA crypto if + * #MBEDTLS_USE_PSA_CRYPTO is enabled. + * + * Uncomment this macro to enable the support for TLS 1.3. + */ +//#define MBEDTLS_SSL_PROTO_TLS1_3 + +/** + * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE + * + * Enable TLS 1.3 middlebox compatibility mode. + * + * As specified in Section D.4 of RFC 8446, TLS 1.3 offers a compatibility + * mode to make a TLS 1.3 connection more likely to pass through middle boxes + * expecting TLS 1.2 traffic. + * + * Turning on the compatibility mode comes at the cost of a few added bytes + * on the wire, but it doesn't affect compatibility with TLS 1.3 implementations + * that don't use it. Therefore, unless transmission bandwidth is critical and + * you know that middlebox compatibility issues won't occur, it is therefore + * recommended to set this option. + * + * Comment to disable compatibility mode for TLS 1.3. If + * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +//#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED + * + * Enable TLS 1.3 PSK key exchange mode. + * + * Comment to disable support for the PSK key exchange mode in TLS 1.3. If + * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +//#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED + * + * Enable TLS 1.3 ephemeral key exchange mode. + * + * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH + * MBEDTLS_X509_CRT_PARSE_C + * and at least one of: + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_PKCS1_V21 + * + * Comment to disable support for the ephemeral key exchange mode in TLS 1.3. + * If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +//#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + * + * Enable TLS 1.3 PSK ephemeral key exchange mode. + * + * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH + * + * Comment to disable support for the PSK ephemeral key exchange mode in + * TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not + * have any effect on the build. + * + */ +//#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + +/** + * \def MBEDTLS_SSL_EARLY_DATA + * + * Enable support for RFC 8446 TLS 1.3 early data. + * + * Requires: MBEDTLS_SSL_SESSION_TICKETS and either + * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or + * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + * + * Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3 + * is not enabled, this option does not have any effect on the build. + * + * This feature is experimental, not completed and thus not ready for + * production. + * + * \note The maximum amount of early data can be set with + * MBEDTLS_SSL_MAX_EARLY_DATA_SIZE. + * + */ +//#define MBEDTLS_SSL_EARLY_DATA + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +//#define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +//#define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can be a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotiation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +//#define MBEDTLS_SSL_DTLS_SRTP + +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.2.8 of RFC 6347. This + * flag enables that support. + * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Comment this to disable support for clients reusing the source port. + */ +//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintenance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +//#define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +//#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + * + * When this option is enabled, the SSL buffer will be resized automatically + * based on the negotiated maximum fragment length in each direction. + * + * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + */ +//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + * + * Enable testing of the constant-flow nature of some sensitive functions with + * clang's MemorySanitizer. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires compiling with clang -fsanitize=memory. The test + * suites can then be run normally. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + * + * Enable testing of the constant-flow nature of some sensitive functions with + * valgrind's memcheck tool. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires valgrind headers for building, and is only useful for + * testing if the tests suites are run with valgrind's memcheck. This can be + * done for an individual test suite with 'valgrind ./test_suite_xxx', or when + * using CMake, this can be done for all test suites with 'make memcheck'. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + +/** + * \def MBEDTLS_TEST_HOOKS + * + * Enable features for invasive testing such as introspection functions and + * hooks for fault injection. This enables additional unit tests. + * + * Merely enabling this feature should not change the behavior of the product. + * It only adds new code, and new branching points where the default behavior + * is the same as when this feature is disabled. + * However, this feature increases the attack surface: there is an added + * risk of vulnerabilities, and more gadgets that can make exploits easier. + * Therefore this feature must never be enabled in production. + * + * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more + * information. + * + * Uncomment to enable invasive tests. + */ +//#define MBEDTLS_TEST_HOOKS + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS libraries use PSA for cryptographic operations as + * much as possible, and enable new APIs for using keys handled by PSA Crypto. + * + * \note Development of this option is currently in progress, and parts of Mbed + * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts + * will still continue to work as usual, so enabling this option should not + * break backwards compatibility. + * + * \warning If you enable this option, you need to call `psa_crypto_init()` + * before calling any function from the SSL/TLS, X.509 or PK modules, except + * for the various mbedtls_xxx_init() functions which can be called at any time. + * + * \note An important and desirable effect of this option is that it allows + * PK, X.509 and TLS to take advantage of PSA drivers. For example, enabling + * this option is what allows use of drivers for ECDSA, ECDH and EC J-PAKE in + * those modules. However, note that even with this option disabled, some code + * in PK, X.509, TLS or the crypto library might still use PSA drivers, if it + * can determine it's safe to do so; currently that's the case for hashes. + * + * \note See docs/use-psa-crypto.md for a complete description this option. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * Uncomment this to enable internal use of PSA Crypto and new associated APIs. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG + * + * This setting allows support for cryptographic mechanisms through the PSA + * API to be configured separately from support through the mbedtls API. + * + * When this option is disabled, the PSA API exposes the cryptographic + * mechanisms that can be implemented on top of the `mbedtls_xxx` API + * configured with `MBEDTLS_XXX` symbols. + * + * When this option is enabled, the PSA API exposes the cryptographic + * mechanisms requested by the `PSA_WANT_XXX` symbols defined in + * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are + * automatically enabled if required (i.e. if no PSA driver provides the + * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols + * in mbedtls_config.h. + * + * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies + * an alternative header to include instead of include/psa/crypto_config.h. + * + * \warning This option is experimental, in that the set of `PSA_WANT_XXX` + * symbols is not completely finalized yet, and the configuration + * tooling is not ideally adapted to having two separate configuration + * files. + * Future minor releases of Mbed TLS may make minor changes to those + * symbols, but we will endeavor to provide a transition path. + * Nonetheless, this option is considered mature enough to use in + * production, as long as you accept that you may need to make + * minor changes to psa/crypto_config.h when upgrading Mbed TLS. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + * + * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` + * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure + * the set of trusted certificates through a callback instead of a linked + * list. + * + * This is useful for example in environments where a large number of trusted + * certificates is present and storing them in a linked list isn't efficient + * enough, or when the set of trusted certificates changes frequently. + * + * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and + * `mbedtls_ssl_conf_ca_cb()` for more information. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Uncomment to enable trusted certificate callbacks. + */ +//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + +/** + * \def MBEDTLS_X509_REMOVE_INFO + * + * Disable mbedtls_x509_*_info() and related APIs. + * + * Uncomment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() + * and other functions/constants only used by these functions, thus reducing + * the code footprint by several KB. + */ +//#define MBEDTLS_X509_REMOVE_INFO + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT +/** \} name SECTION: Mbed TLS feature support */ + +/** + * \name SECTION: Mbed TLS modules + * + * This section enables or disables entire modules in Mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64 or x86-32. + * + * \note AESNI is only supported with certain compilers and target options: + * - Visual Studio 2013: supported. + * - GCC, x86-64, target not explicitly supporting AESNI: + * requires MBEDTLS_HAVE_ASM. + * - GCC, x86-32, target not explicitly supporting AESNI: + * not supported. + * - GCC, x86-64 or x86-32, target supporting AESNI: supported. + * For this assembly-less implementation, you must currently compile + * `library/aesni.c` and `library/aes.c` with machine options to enable + * SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or + * `clang -maes -mpclmul`. + * - Non-x86 targets: this option is silently ignored. + * - Other compilers: this option is silently ignored. + * + * \note + * Above, "GCC" includes compatible compilers such as Clang. + * The limitations on target support are likely to be relaxed in the future. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM (on some platforms, see note) + * + * This modules adds support for the AES-NI instructions on x86. + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AESCE_C + * + * Enable AES cryptographic extension support on 64-bit Arm. + * + * Module: library/aesce.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_AES_C + * + * \warning Runtime detection only works on Linux. For non-Linux operating + * system, Armv8-A Cryptographic Extensions must be supported by + * the CPU when this option is enabled. + * + * \note Minimum compiler versions for this feature are Clang 4.0, + * armclang 6.6, GCC 6.0 or MSVC 2019 version 16.11.2. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems. + */ +//#define MBEDTLS_AESCE_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * library/bignum_core.c + * library/bignum_mod.c + * library/bignum_mod_raw.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_alt_helpers.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * + * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +//#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +//#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +//#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ccm.c + * library/cmac.c + * library/gcm.c + * library/nist_kw.c + * library/pkcs12.c + * library/pkcs5.c + * library/psa_crypto_aead.c + * library/psa_crypto_mac.c + * library/ssl_ciphersuites.c + * library/ssl_msg.c + * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying + * implementation of the CMAC algorithm is provided by an alternate + * implementation, that alternate implementation may opt to not support + * AES-192 or 3DES as underlying block ciphers for the CMAC operation. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. + * + * \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. + * + * \note To achieve a 256-bit security strength with CTR_DRBG, + * you must use AES-256 *and* use sufficient entropy. + * See ctr_drbg.h for more details. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +//#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_msg.c + * library/ssl_tls.c + * library/ssl_tls12_*.c + * library/ssl_tls13_*.c + * + * This module provides debugging functions. + */ +//#define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +//#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +//#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/psa_crypto.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, + * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a + * short Weierstrass curve. + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \note EC J-PAKE support is based on the Thread v1.0.0 specification. + * It has not been reviewed for compliance with newer standards such as + * Thread v1.1 or RFC 8236. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any EC J-PAKE operations. + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM). + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +//#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number generator. + */ +#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_LMS_C + * + * Enable the LMS stateful-hash asymmetric signature algorithm. + * + * Module: library/lms.c + * Caller: + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * Uncomment to enable the LMS verification algorithm and public key operations. + */ +//#define MBEDTLS_LMS_C + +/** + * \def MBEDTLS_LMS_PRIVATE + * + * Enable LMS private-key operations and signing code. Functions enabled by this + * option are experimental, and should not be used in production. + * + * Requires: MBEDTLS_LMS_C + * + * Uncomment to enable the LMS signature algorithm and private key operations. + */ +//#define MBEDTLS_LMS_PRIVATE + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic layer for message digest (hashing) and HMAC. + * + * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C, + * MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C, + * MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least + * one hash. + * Module: library/md.c + * Caller: library/constant_time.c + * library/ecdsa.c + * library/ecjpake.c + * library/hkdf.c + * library/hmac_drbg.c + * library/pk.c + * library/pkcs5.c + * library/pkcs12.c + * library/psa_crypto_ecp.c + * library/psa_crypto_rsa.c + * library/rsa.c + * library/ssl_cookie.c + * library/ssl_msg.c + * library/ssl_tls.c + * library/x509.c + * library/x509_crt.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for TLS 1.2 depending on the handshake parameters. + * Further, it is used for checking MD5-signed certificates, and for PBKDF1 + * when decrypting PEM-encoded encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within Mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP and UDP over IPv6/IPv4 networking routines. + * + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. + */ +//#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +//#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * optionally MBEDTLS_MD5_C, or PSA Crypto with MD5 (see below) + * + * \warning When parsing password-protected files, if MD5 is provided only by + * a PSA driver, you must call psa_crypto_init() before the first file. + * + * This modules adds support for decoding / parsing PEM files. + */ +//#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +//#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymmetric) key layer. + * + * Module: library/pk.c + * Caller: library/psa_crypto_rsa.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * library/x509.c + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +//#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymmetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +//#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymmetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +//#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_CIPHER_C + * Auto-enables: MBEDTLS_MD_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS5 operations. + * + * This module adds support for the PKCS#5 functions. + */ +//#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS7_C + * + * Enable PKCS #7 core for using PKCS #7-formatted signatures. + * RFC Link - https://tools.ietf.org/html/rfc2315 + * + * Module: library/pkcs7.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C, + * MBEDTLS_BIGNUM_C, MBEDTLS_MD_C + * + * This module is required for the PKCS #7 parsing modules. + */ +//#define MBEDTLS_PKCS7_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C and either + * MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C. + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS12 operations. + * + * This module enables PKCS#12 functions. + */ +//#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other modules rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +//#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CIPHER_C, + * either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. + * + */ +//#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_SE_C + * + * Enable dynamic secure element support in the Platform Security Architecture + * cryptography API. + * + * \deprecated This feature is deprecated. Please switch to the PSA driver + * interface. + * + * Module: library/psa_crypto_se.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SE_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_alt_helpers.c + * Caller: library/pk.c + * library/psa_crypto.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +//#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/psa_crypto_hash.c + * + * This module is required for TLS 1.2 depending on the handshake parameters, + * and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA224_C + * + * Enable the SHA-224 cryptographic hash algorithm. + * + * Module: library/sha256.c + * Caller: library/md.c + * library/ssl_cookie.c + * + * This module adds support for SHA-224. + */ +#define MBEDTLS_SHA224_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-256 cryptographic hash algorithm. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module adds support for SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building + * for a non-Aarch64 build it will be silently ignored. + * + * \note Minimum compiler versions for this feature are Clang 4.0, + * armclang 6.6 or GCC 6.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library check for the A64 SHA-256 crypto extensions + * and use them if available. + */ +//#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + * + * \note Minimum compiler versions for this feature are Clang 4.0, + * armclang 6.6 or GCC 6.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library use the A64 SHA-256 crypto extensions + * unconditionally. + */ +//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + +/** + * \def MBEDTLS_SHA384_C + * + * Enable the SHA-384 cryptographic hash algorithm. + * + * Module: library/sha512.c + * Caller: library/md.c + * library/psa_crypto_hash.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * Comment to disable SHA-384 + */ +//#define MBEDTLS_SHA384_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_tls.c + * library/ssl_cookie.c + * + * This module adds support for SHA-512. + */ +//#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SHA3_C + * + * Enable the SHA3 cryptographic hash algorithm. + * + * Module: library/sha3.c + * + * This module adds support for SHA3. + */ +//#define MBEDTLS_SHA3_C + +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building + * for a non-Aarch64 build it will be silently ignored. + * + * \note Minimum compiler versions for this feature are Clang 7.0, + * armclang 6.9 or GCC 8.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for + * armclang 6.9 + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library check for the A64 SHA-512 crypto extensions + * and use them if available. + */ +//#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * \note Minimum compiler versions for this feature are Clang 7.0, + * armclang 6.9 or GCC 8.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for + * armclang 6.9 + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library use the A64 SHA-512 crypto extensions + * unconditionally. + */ +//#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +//#define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +//#define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: (MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO) && + * (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) + */ +//#define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl*_client.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +//#define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl*_server.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl*_client.c + * library/ssl*_server.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ +//#define MBEDTLS_SSL_TLS_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default Mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within Mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note The timing module will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +//#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call + * psa_crypto_init() before doing any X.509 operation. + * + * This module is required for the X.509 parsing modules. + */ +//#define MBEDTLS_X509_USE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +//#define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +//#define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +//#define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call + * psa_crypto_init() before doing any X.509 create operation. + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +//#define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +//#define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +//#define MBEDTLS_X509_CSR_WRITE_C + +/** \} name SECTION: Mbed TLS modules */ + +/** + * \name SECTION: General configuration options + * + * This section contains Mbed TLS build settings that are not associated + * with a particular module. + * + * \{ + */ + +/** + * \def MBEDTLS_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"mbedtls/mbedtls_config.h"`. + * This header file specifies the compile-time configuration of Mbed TLS. + * Unlike other configuration options, this one must be defined on the + * compiler command line: a definition in `mbedtls_config.h` would have + * no effect. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" + +/** + * \def MBEDTLS_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_config.h"`. + * This header file specifies which cryptographic mechanisms are available + * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and + * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" + +/** + * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_platform.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the platform on + * which the library code will run. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_struct.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the environment + * in which the library code will run. The typical use for this feature + * is to provide alternative type definitions on the client side in + * client-server integrations of PSA crypto, where operation structures + * contain handles instead of cryptographic data. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h" + +/** \} name SECTION: General configuration options */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * \{ + */ +/* The Doxygen documentation here is used when a user comments out a + * setting and runs doxygen themselves. On the other hand, when we typeset + * the full documentation including disabled settings, the documentation + * in specific modules' header files is used if present. When editing this + * file, make sure that each option is documented in exactly one place, + * plus optionally a same-line Doxygen comment here if there is a Doxygen + * comment in the specific module. */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ + +/** \def MBEDTLS_PLATFORM_STD_CALLOC + * + * Default allocator to use, can be undefined. + * It must initialize the allocated buffer memory to zeroes. + * The size of the buffer is the product of the two parameters. + * The calloc function returns either a null pointer or a pointer to the allocated space. + * If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function. + * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. + * See the description of #MBEDTLS_PLATFORM_MEMORY for more details. + * The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE. + */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc + +/** \def MBEDTLS_PLATFORM_STD_FREE + * + * Default free to use, can be undefined. + * NULL is a valid parameter, and the function must do nothing. + * A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed. + * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. + * See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply). + */ +//#define MBEDTLS_PLATFORM_STD_FREE free +//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +#include "os_mem.h" +#define MBEDTLS_PLATFORM_CALLOC_MACRO(n, size) os_mem_zalloc(RAM_TYPE_DATA_ON, n * size) /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */ +#define MBEDTLS_PLATFORM_FREE_MACRO os_mem_free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +#include "trace.h" +#define MBEDTLS_PLATFORM_PRINTF_MACRO DBG_DIRECT /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t /**< Default milliseconds time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled. It must be signed, and at least 64 bits. If it is changed from the default, MBEDTLS_PRINTF_MS_TIME must be updated to match.*/ +//#define MBEDTLS_PRINTF_MS_TIME PRId64 /**< Default fmt for printf. That's avoid compiler warning if mbedtls_ms_time_t is redefined */ + +/** \def MBEDTLS_CHECK_RETURN + * + * This macro is used at the beginning of the declaration of a function + * to indicate that its return value should be checked. It should + * instruct the compiler to emit a warning or an error if the function + * is called without checking its return value. + * + * There is a default implementation for popular compilers in platform_util.h. + * You can override the default implementation by defining your own here. + * + * If the implementation here is empty, this will effectively disable the + * checking of functions' return values. + */ +//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) + +/** \def MBEDTLS_IGNORE_RETURN + * + * This macro requires one argument, which should be a C function call. + * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this + * warning is suppressed. + */ +//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) + +/* PSA options */ +/** + * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the + * PSA crypto subsystem. + * + * If this option is unset: + * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG. + * - Otherwise, the PSA subsystem uses HMAC_DRBG with either + * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and + * on unspecified heuristics. + */ +//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 + +/** \def MBEDTLS_PSA_KEY_SLOT_COUNT + * Restrict the PSA library to supporting a maximum amount of simultaneously + * loaded keys. A loaded key is a key stored by the PSA Crypto core as a + * volatile key, or a persistent key which is loaded temporarily by the + * library as part of a crypto operation in flight. + * + * If this option is unset, the library will fall back to a default value of + * 32 keys. + */ +//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 + +/* RSA OPTIONS */ +//#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 /**< Minimum RSA key size that can be generated in bits (Minimum possible value is 128 bits) */ + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ + +/** \def MBEDTLS_SSL_IN_CONTENT_LEN + * + * Maximum length (in bytes) of incoming plaintext fragments. + * + * This determines the size of the incoming TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * \note When using a value less than the default of 16KB on the client, it is + * recommended to use the Maximum Fragment Length (MFL) extension to + * inform the server about this limitation. On the server, there + * is no supported, standardized way of informing the client about + * restriction on the maximum size of incoming messages, and unless + * the limitation has been communicated by other means, it is recommended + * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN + * while keeping the default value of 16KB for the incoming buffer. + * + * Uncomment to set the maximum plaintext size of the incoming I/O buffer. + */ +//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_CID_IN_LEN_MAX + * + * The maximum length of CIDs used for incoming DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX + * + * The maximum length of CIDs used for outgoing DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + */ +//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 + +/** \def MBEDTLS_SSL_OUT_CONTENT_LEN + * + * Maximum length (in bytes) of outgoing plaintext fragments. + * + * This determines the size of the outgoing TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * It is possible to save RAM by setting a smaller outward buffer, while keeping + * the default inward 16384 byte buffer to conform to the TLS specification. + * + * The minimum required outward buffer size is determined by the handshake + * protocol's usage. Handshaking will fail if the outward buffer is too small. + * The specific size requirement depends on the configured ciphers and any + * certificate data which is sent during the handshake. + * + * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. + */ +//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING + * + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + * + * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN + * to account for a reassembled handshake message of maximum size, + * together with its reassembly bitmap. + * + * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) + * should be sufficient for all practical situations as it allows + * to reassembly a large handshake message (such as a certificate) + * while buffering multiple smaller handshake messages. + * + */ +//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 + +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/** + * \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE + * + * The default maximum amount of 0-RTT data. See the documentation of + * \c mbedtls_ssl_tls13_conf_max_early_data_size() for more information. + * + * It must be positive and smaller than UINT32_MAX. + * + * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not + * have any impact on the build. + * + * This feature is experimental, not completed and thus not ready for + * production. + * + */ +//#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 + +/** + * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + * + * Maximum time difference in milliseconds tolerated between the age of a + * ticket from the server and client point of view. + * From the client point of view, the age of a ticket is the time difference + * between the time when the client proposes to the server to use the ticket + * (time of writing of the Pre-Shared Key Extension including the ticket) and + * the time the client received the ticket from the server. + * From the server point of view, the age of a ticket is the time difference + * between the time when the server receives a proposition from the client + * to use the ticket and the time when the ticket was created by the server. + * The server age is expected to be always greater than the client one and + * MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the + * maximum difference tolerated for the server to accept the ticket. + * This is not used in TLS 1.2. + * + */ +//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 + +/** + * \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH + * + * Size in bytes of a ticket nonce. This is not used in TLS 1.2. + * + * This must be less than 256. + */ +//#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32 + +/** + * \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS + * + * Default number of NewSessionTicket messages to be sent by a TLS 1.3 server + * after handshake completion. This is not used in TLS 1.2 and relevant only if + * the MBEDTLS_SSL_SESSION_TICKETS option is enabled. + * + */ +//#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1 + +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ + +/** \} name SECTION: Module configuration options */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/md.h b/src/app/findmy/crypto/third-party/mbedtls/md.h new file mode 100644 index 0000000..ff7b133 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/md.h @@ -0,0 +1,640 @@ +/** + * \file md.h + * + * \brief This file contains the generic functions for message-digest + * (hashing) and HMAC. + * + * \author Adriaan de Jong + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_MD_H +#define MBEDTLS_MD_H +#include "mbedtls/private_access.h" + +#include + +#include "mbedtls/build_info.h" +#include "mbedtls/platform_util.h" + +#if defined(MBEDTLS_MD_LIGHT) + +/* + * - MBEDTLS_MD_CAN_xxx is defined if the md module can perform xxx. + * - MBEDTLS_MD_xxx_VIA_PSA is defined if the md module may perform xxx via PSA + * (see below). + * - MBEDTLS_MD_SOME_PSA is defined if at least one algorithm may be performed + * via PSA (see below). + * - MBEDTLS_MD_SOME_LEGACY is defined if at least one algorithm may be performed + * via a direct legacy call (see below). + * + * The md module performs an algorithm via PSA if there is a PSA hash + * accelerator and the PSA driver subsytem is initialized at the time the + * operation is started, and makes a direct legacy call otherwise. + */ + +/* PSA accelerated implementations */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_PSA_ACCEL_ALG_MD5) +#define MBEDTLS_MD_CAN_MD5 +#define MBEDTLS_MD_MD5_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1) +#define MBEDTLS_MD_CAN_SHA1 +#define MBEDTLS_MD_SHA1_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224) +#define MBEDTLS_MD_CAN_SHA224 +#define MBEDTLS_MD_SHA224_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256) +#define MBEDTLS_MD_CAN_SHA256 +#define MBEDTLS_MD_SHA256_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384) +#define MBEDTLS_MD_CAN_SHA384 +#define MBEDTLS_MD_SHA384_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512) +#define MBEDTLS_MD_CAN_SHA512 +#define MBEDTLS_MD_SHA512_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_RIPEMD160) +#define MBEDTLS_MD_CAN_RIPEMD160 +#define MBEDTLS_MD_RIPEMD160_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_224) +#define MBEDTLS_MD_CAN_SHA3_224 +#define MBEDTLS_MD_SHA3_224_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_256) +#define MBEDTLS_MD_CAN_SHA3_256 +#define MBEDTLS_MD_SHA3_256_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_384) +#define MBEDTLS_MD_CAN_SHA3_384 +#define MBEDTLS_MD_SHA3_384_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#if defined(MBEDTLS_PSA_ACCEL_ALG_SHA3_512) +#define MBEDTLS_MD_CAN_SHA3_512 +#define MBEDTLS_MD_SHA3_512_VIA_PSA +#define MBEDTLS_MD_SOME_PSA +#endif +#endif /* MBEDTLS_PSA_CRYPTO_C */ + +/* Built-in implementations */ +#if defined(MBEDTLS_MD5_C) +#define MBEDTLS_MD_CAN_MD5 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA1_C) +#define MBEDTLS_MD_CAN_SHA1 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA224_C) +#define MBEDTLS_MD_CAN_SHA224 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA256_C) +#define MBEDTLS_MD_CAN_SHA256 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA384_C) +#define MBEDTLS_MD_CAN_SHA384 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_MD_CAN_SHA512 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_SHA3_C) +#define MBEDTLS_MD_CAN_SHA3_224 +#define MBEDTLS_MD_CAN_SHA3_256 +#define MBEDTLS_MD_CAN_SHA3_384 +#define MBEDTLS_MD_CAN_SHA3_512 +#define MBEDTLS_MD_SOME_LEGACY +#endif +#if defined(MBEDTLS_RIPEMD160_C) +#define MBEDTLS_MD_CAN_RIPEMD160 +#define MBEDTLS_MD_SOME_LEGACY +#endif + +#endif /* MBEDTLS_MD_LIGHT */ + +/** The selected feature is not available. */ +#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 +/** Failed to allocate memory. */ +#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 +/** Opening or reading of file failed. */ +#define MBEDTLS_ERR_MD_FILE_IO_ERROR -0x5200 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Supported message digests. + * + * \warning MD5 and SHA-1 are considered weak message digests and + * their use constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +/* Note: these are aligned with the definitions of PSA_ALG_ macros for hashes, + * in order to enable an efficient implementation of conversion functions. + * This is tested by md_to_from_psa() in test_suite_md. */ +typedef enum { + MBEDTLS_MD_NONE=0, /**< None. */ + MBEDTLS_MD_MD5=0x03, /**< The MD5 message digest. */ + MBEDTLS_MD_RIPEMD160=0x04, /**< The RIPEMD-160 message digest. */ + MBEDTLS_MD_SHA1=0x05, /**< The SHA-1 message digest. */ + MBEDTLS_MD_SHA224=0x08, /**< The SHA-224 message digest. */ + MBEDTLS_MD_SHA256=0x09, /**< The SHA-256 message digest. */ + MBEDTLS_MD_SHA384=0x0a, /**< The SHA-384 message digest. */ + MBEDTLS_MD_SHA512=0x0b, /**< The SHA-512 message digest. */ + MBEDTLS_MD_SHA3_224=0x10, /**< The SHA3-224 message digest. */ + MBEDTLS_MD_SHA3_256=0x11, /**< The SHA3-256 message digest. */ + MBEDTLS_MD_SHA3_384=0x12, /**< The SHA3-384 message digest. */ + MBEDTLS_MD_SHA3_512=0x13, /**< The SHA3-512 message digest. */ +} mbedtls_md_type_t; + +/* Note: this should always be >= PSA_HASH_MAX_SIZE + * in all builds with both CRYPTO_C and MD_LIGHT. + * + * This is to make things easier for modules such as TLS that may define a + * buffer size using MD_MAX_SIZE in a part of the code that's common to PSA + * and legacy, then assume the buffer's size is PSA_HASH_MAX_SIZE in another + * part of the code based on PSA. + */ +#if defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA3_512) +#define MBEDTLS_MD_MAX_SIZE 64 /* longest known is SHA512 */ +#elif defined(MBEDTLS_MD_CAN_SHA384) || defined(MBEDTLS_MD_CAN_SHA3_384) +#define MBEDTLS_MD_MAX_SIZE 48 /* longest known is SHA384 */ +#elif defined(MBEDTLS_MD_CAN_SHA256) || defined(MBEDTLS_MD_CAN_SHA3_256) +#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 */ +#elif defined(MBEDTLS_MD_CAN_SHA224) || defined(MBEDTLS_MD_CAN_SHA3_224) +#define MBEDTLS_MD_MAX_SIZE 28 /* longest known is SHA224 */ +#else +#define MBEDTLS_MD_MAX_SIZE 20 /* longest known is SHA1 or RIPE MD-160 + or smaller (MD5 and earlier) */ +#endif + +#if defined(MBEDTLS_MD_CAN_SHA3_224) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 144 /* the longest known is SHA3-224 */ +#elif defined(MBEDTLS_MD_CAN_SHA3_256) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 136 +#elif defined(MBEDTLS_MD_CAN_SHA512) || defined(MBEDTLS_MD_CAN_SHA384) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 128 +#elif defined(MBEDTLS_MD_CAN_SHA3_384) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 104 +#elif defined(MBEDTLS_MD_CAN_SHA3_512) +#define MBEDTLS_MD_MAX_BLOCK_SIZE 72 +#else +#define MBEDTLS_MD_MAX_BLOCK_SIZE 64 +#endif + +/** + * Opaque struct. + * + * Constructed using either #mbedtls_md_info_from_string or + * #mbedtls_md_info_from_type. + * + * Fields can be accessed with #mbedtls_md_get_size, + * #mbedtls_md_get_type and #mbedtls_md_get_name. + */ +/* Defined internally in library/md_wrap.h. */ +typedef struct mbedtls_md_info_t mbedtls_md_info_t; + +/** + * Used internally to indicate whether a context uses legacy or PSA. + * + * Internal use only. + */ +typedef enum { + MBEDTLS_MD_ENGINE_LEGACY = 0, + MBEDTLS_MD_ENGINE_PSA, +} mbedtls_md_engine_t; + +/** + * The generic message-digest context. + */ +typedef struct mbedtls_md_context_t { + /** Information about the associated message digest. */ + const mbedtls_md_info_t *MBEDTLS_PRIVATE(md_info); + +#if defined(MBEDTLS_MD_SOME_PSA) + /** Are hash operations dispatched to PSA or legacy? */ + mbedtls_md_engine_t MBEDTLS_PRIVATE(engine); +#endif + + /** The digest-specific context (legacy) or the PSA operation. */ + void *MBEDTLS_PRIVATE(md_ctx); + +#if defined(MBEDTLS_MD_C) + /** The HMAC part of the context. */ + void *MBEDTLS_PRIVATE(hmac_ctx); +#endif +} mbedtls_md_context_t; + +/** + * \brief This function returns the message-digest information + * associated with the given digest type. + * + * \param md_type The type of digest to search for. + * + * \return The message-digest information associated with \p md_type. + * \return NULL if the associated message-digest information is not found. + */ +const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type); + +/** + * \brief This function initializes a message-digest context without + * binding it to a particular message-digest algorithm. + * + * This function should always be called first. It prepares the + * context for mbedtls_md_setup() for binding it to a + * message-digest algorithm. + */ +void mbedtls_md_init(mbedtls_md_context_t *ctx); + +/** + * \brief This function clears the internal structure of \p ctx and + * frees any embedded internal structure, but does not free + * \p ctx itself. + * + * If you have called mbedtls_md_setup() on \p ctx, you must + * call mbedtls_md_free() when you are no longer using the + * context. + * Calling this function if you have previously + * called mbedtls_md_init() and nothing else is optional. + * You must not call this function if you have not called + * mbedtls_md_init(). + */ +void mbedtls_md_free(mbedtls_md_context_t *ctx); + + +/** + * \brief This function selects the message digest algorithm to use, + * and allocates internal structures. + * + * It should be called after mbedtls_md_init() or + * mbedtls_md_free(). Makes it necessary to call + * mbedtls_md_free() later. + * + * \param ctx The context to set up. + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param hmac Defines if HMAC is used. 0: HMAC is not used (saves some memory), + * or non-zero: HMAC is used with this context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac); + +/** + * \brief This function clones the state of a message-digest + * context. + * + * \note You must call mbedtls_md_setup() on \c dst before calling + * this function. + * + * \note The two contexts must have the same type, + * for example, both are SHA-256. + * + * \warning This function clones the message-digest state, not the + * HMAC state. + * + * \param dst The destination context. + * \param src The context to be cloned. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. + * \return #MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE if both contexts are + * not using the same engine. This can be avoided by moving + * the call to psa_crypto_init() before the first call to + * mbedtls_md_setup(). + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_clone(mbedtls_md_context_t *dst, + const mbedtls_md_context_t *src); + +/** + * \brief This function extracts the message-digest size from the + * message-digest information structure. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The size of the message-digest output in Bytes. + */ +unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info); + +/** + * \brief This function gives the message-digest size associated to + * message-digest type. + * + * \param md_type The message-digest type. + * + * \return The size of the message-digest output in Bytes, + * or 0 if the message-digest type is not known. + */ +static inline unsigned char mbedtls_md_get_size_from_type(mbedtls_md_type_t md_type) +{ + return mbedtls_md_get_size(mbedtls_md_info_from_type(md_type)); +} + +/** + * \brief This function extracts the message-digest type from the + * message-digest information structure. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The type of the message digest. + */ +mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info); + +/** + * \brief This function starts a message-digest computation. + * + * You must call this function after setting up the context + * with mbedtls_md_setup(), and before passing data with + * mbedtls_md_update(). + * + * \param ctx The generic message-digest context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_starts(mbedtls_md_context_t *ctx); + +/** + * \brief This function feeds an input buffer into an ongoing + * message-digest computation. + * + * You must call mbedtls_md_starts() before calling this + * function. You may call this function multiple times. + * Afterwards, call mbedtls_md_finish(). + * + * \param ctx The generic message-digest context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen); + +/** + * \brief This function finishes the digest operation, + * and writes the result to the output buffer. + * + * Call this function after a call to mbedtls_md_starts(), + * followed by any number of calls to mbedtls_md_update(). + * Afterwards, you may either clear the context with + * mbedtls_md_free(), or call mbedtls_md_starts() to reuse + * the context for another digest operation with the same + * algorithm. + * + * \param ctx The generic message-digest context. + * \param output The buffer for the generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output); + +/** + * \brief This function calculates the message-digest of a buffer, + * with respect to a configurable message-digest algorithm + * in a single call. + * + * The result is calculated as + * Output = message_digest(input buffer). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param input The buffer holding the data. + * \param ilen The length of the input data. + * \param output The generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output); + +/** + * \brief This function returns the list of digests supported by the + * generic digest module. + * + * \note The list starts with the strongest available hashes. + * + * \return A statically allocated array of digests. Each element + * in the returned list is an integer belonging to the + * message-digest enumeration #mbedtls_md_type_t. + * The last entry is 0. + */ +const int *mbedtls_md_list(void); + +/** + * \brief This function returns the message-digest information + * associated with the given digest name. + * + * \param md_name The name of the digest to search for. + * + * \return The message-digest information associated with \p md_name. + * \return NULL if the associated message-digest information is not found. + */ +const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name); + +/** + * \brief This function returns the name of the message digest for + * the message-digest information structure given. + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * + * \return The name of the message digest. + */ +const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info); + +/** + * \brief This function returns the message-digest information + * from the given context. + * + * \param ctx The context from which to extract the information. + * This must be initialized (or \c NULL). + * + * \return The message-digest information associated with \p ctx. + * \return \c NULL if \p ctx is \c NULL. + */ +const mbedtls_md_info_t *mbedtls_md_info_from_ctx( + const mbedtls_md_context_t *ctx); + +#if defined(MBEDTLS_FS_IO) +/** + * \brief This function calculates the message-digest checksum + * result of the contents of the provided file. + * + * The result is calculated as + * Output = message_digest(file contents). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param path The input file name. + * \param output The generic message-digest checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_FILE_IO_ERROR on an I/O error accessing + * the file pointed by \p path. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, + unsigned char *output); +#endif /* MBEDTLS_FS_IO */ + +/** + * \brief This function sets the HMAC key and prepares to + * authenticate a new message. + * + * Call this function after mbedtls_md_setup(), to use + * the MD context for an HMAC calculation, then call + * mbedtls_md_hmac_update() to provide the input data, and + * mbedtls_md_hmac_finish() to get the HMAC value. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param key The HMAC secret key. + * \param keylen The length of the HMAC key in Bytes. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, + size_t keylen); + +/** + * \brief This function feeds an input buffer into an ongoing HMAC + * computation. + * + * Call mbedtls_md_hmac_starts() or mbedtls_md_hmac_reset() + * before calling this function. + * You may call this function multiple times to pass the + * input piecewise. + * Afterwards, call mbedtls_md_hmac_finish(). + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, + size_t ilen); + +/** + * \brief This function finishes the HMAC operation, and writes + * the result to the output buffer. + * + * Call this function after mbedtls_md_hmac_starts() and + * mbedtls_md_hmac_update() to get the HMAC value. Afterwards + * you may either call mbedtls_md_free() to clear the context, + * or call mbedtls_md_hmac_reset() to reuse the context with + * the same HMAC key. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * \param output The generic HMAC checksum result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output); + +/** + * \brief This function prepares to authenticate a new message with + * the same key as the previous HMAC operation. + * + * You may call this function after mbedtls_md_hmac_finish(). + * Afterwards call mbedtls_md_hmac_update() to pass the new + * input. + * + * \param ctx The message digest context containing an embedded HMAC + * context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx); + +/** + * \brief This function calculates the full generic HMAC + * on the input buffer with the provided key. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The HMAC result is calculated as + * output = generic HMAC(hmac key, input buffer). + * + * \param md_info The information structure of the message-digest algorithm + * to use. + * \param key The HMAC secret key. + * \param keylen The length of the HMAC secret key in Bytes. + * \param input The buffer holding the input data. + * \param ilen The length of the input data. + * \param output The generic HMAC result. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification + * failure. + */ +MBEDTLS_CHECK_RETURN_TYPICAL +int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_MD_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/md5.h b/src/app/findmy/crypto/third-party/mbedtls/md5.h new file mode 100644 index 0000000..6bf0754 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/md5.h @@ -0,0 +1,190 @@ +/** + * \file md5.h + * + * \brief MD5 message digest algorithm (hash function) + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. We recommend considering stronger message + * digests instead. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_MD5_H +#define MBEDTLS_MD5_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_MD5_ALT) +// Regular implementation +// + +/** + * \brief MD5 context structure + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +typedef struct mbedtls_md5_context { + uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */ + uint32_t MBEDTLS_PRIVATE(state)[4]; /*!< intermediate digest state */ + unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */ +} +mbedtls_md5_context; + +#else /* MBEDTLS_MD5_ALT */ +#include "md5_alt.h" +#endif /* MBEDTLS_MD5_ALT */ + +/** + * \brief Initialize MD5 context + * + * \param ctx MD5 context to be initialized + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +void mbedtls_md5_init(mbedtls_md5_context *ctx); + +/** + * \brief Clear MD5 context + * + * \param ctx MD5 context to be cleared + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +void mbedtls_md5_free(mbedtls_md5_context *ctx); + +/** + * \brief Clone (the state of) an MD5 context + * + * \param dst The destination context + * \param src The context to be cloned + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +void mbedtls_md5_clone(mbedtls_md5_context *dst, + const mbedtls_md5_context *src); + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + * + * \return 0 if successful + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_md5_starts(mbedtls_md5_context *ctx); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \return 0 if successful + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_md5_update(mbedtls_md5_context *ctx, + const unsigned char *input, + size_t ilen); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + * + * \return 0 if successful + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_md5_finish(mbedtls_md5_context *ctx, + unsigned char output[16]); + +/** + * \brief MD5 process data block (internal use only) + * + * \param ctx MD5 context + * \param data buffer holding one block of data + * + * \return 0 if successful + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_internal_md5_process(mbedtls_md5_context *ctx, + const unsigned char data[64]); + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + * + * \return 0 if successful + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_md5(const unsigned char *input, + size_t ilen, + unsigned char output[16]); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + * + * \warning MD5 is considered a weak message digest and its use + * constitutes a security risk. We recommend considering + * stronger message digests instead. + * + */ +int mbedtls_md5_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_md5.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/platform.h b/src/app/findmy/crypto/third-party/mbedtls/platform.h new file mode 100644 index 0000000..ae0863a --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/platform.h @@ -0,0 +1,485 @@ +/** + * \file platform.h + * + * \brief This file contains the definitions and functions of the + * Mbed TLS platform abstraction layer. + * + * The platform abstraction layer removes the need for the library + * to directly link to standard C library functions or operating + * system services, making the library easier to port and embed. + * Application developers and users of the library can provide their own + * implementations of these functions, or implementations specific to + * their platform, which can be statically linked to the library or + * dynamically configured at runtime. + * + * When all compilation options related to platform abstraction are + * disabled, this header just defines `mbedtls_xxx` function names + * as aliases to the standard `xxx` function. + * + * Most modules in the library and example programs are expected to + * include this header. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_PLATFORM_H +#define MBEDTLS_PLATFORM_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in mbedtls_config.h or define them on the compiler command line. + * \{ + */ + +/* The older Microsoft Windows common runtime provides non-conforming + * implementations of some standard library functions, including snprintf + * and vsnprintf. This affects MSVC and MinGW builds. + */ +#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900) +#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF +#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF +#endif + +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) +#include +#include +#if defined(MBEDTLS_HAVE_TIME) +#include +#endif +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */ +#else +#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF) +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */ +#else +#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */ +#endif +#endif +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< The default \c fprintf function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< The default \c calloc function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +#define MBEDTLS_PLATFORM_STD_FREE free /**< The default \c free function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_SETBUF) +#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< The default \c setbuf function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +#define MBEDTLS_PLATFORM_STD_EXIT exit /**< The default \c exit function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +#define MBEDTLS_PLATFORM_STD_TIME time /**< The default \c time function to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< The default exit value to use. */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< The default exit value to use. */ +#endif +#if defined(MBEDTLS_FS_IO) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" +#endif +#endif /* MBEDTLS_FS_IO */ +#else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) +#include MBEDTLS_PLATFORM_STD_MEM_HDR +#endif +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +/* Enable certain documented defines only when generating doxygen to avoid + * an "unrecognized define" error. */ +#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_CALLOC) +#define MBEDTLS_PLATFORM_STD_CALLOC +#endif + +#if defined(__DOXYGEN__) && !defined(MBEDTLS_PLATFORM_STD_FREE) +#define MBEDTLS_PLATFORM_STD_FREE +#endif + +/** \} name SECTION: Module settings */ + +/* + * The function pointers for calloc and free. + * Please see MBEDTLS_PLATFORM_STD_CALLOC and MBEDTLS_PLATFORM_STD_FREE + * in mbedtls_config.h for more information about behaviour and requirements. + */ +#if defined(MBEDTLS_PLATFORM_MEMORY) +#if defined(MBEDTLS_PLATFORM_FREE_MACRO) && \ + defined(MBEDTLS_PLATFORM_CALLOC_MACRO) +#undef mbedtls_free +#undef mbedtls_calloc +#define mbedtls_free MBEDTLS_PLATFORM_FREE_MACRO +#define mbedtls_calloc MBEDTLS_PLATFORM_CALLOC_MACRO +#else +/* For size_t */ +#include +extern void *mbedtls_calloc(size_t n, size_t size); +extern void mbedtls_free(void *ptr); + +/** + * \brief This function dynamically sets the memory-management + * functions used by the library, during runtime. + * + * \param calloc_func The \c calloc function implementation. + * \param free_func The \c free function implementation. + * + * \return \c 0. + */ +int mbedtls_platform_set_calloc_free(void *(*calloc_func)(size_t, size_t), + void (*free_func)(void *)); +#endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ +#else /* !MBEDTLS_PLATFORM_MEMORY */ +#undef mbedtls_free +#undef mbedtls_calloc +#define mbedtls_free free +#define mbedtls_calloc(n, size) calloc +#endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ + +/* + * The function pointers for fprintf + */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +/* We need FILE * */ +#include +extern int (*mbedtls_fprintf)(FILE *stream, const char *format, ...); + +/** + * \brief This function dynamically configures the fprintf + * function that is called when the + * mbedtls_fprintf() function is invoked by the library. + * + * \param fprintf_func The \c fprintf function implementation. + * + * \return \c 0. + */ +int mbedtls_platform_set_fprintf(int (*fprintf_func)(FILE *stream, const char *, + ...)); +#else +#undef mbedtls_fprintf +#if defined(MBEDTLS_PLATFORM_FPRINTF_MACRO) +#define mbedtls_fprintf MBEDTLS_PLATFORM_FPRINTF_MACRO +#else +#define mbedtls_fprintf fprintf +#endif /* MBEDTLS_PLATFORM_FPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +/* + * The function pointers for printf + */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +extern int (*mbedtls_printf)(const char *format, ...); + +/** + * \brief This function dynamically configures the snprintf + * function that is called when the mbedtls_snprintf() + * function is invoked by the library. + * + * \param printf_func The \c printf function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_printf(int (*printf_func)(const char *, ...)); +#else /* !MBEDTLS_PLATFORM_PRINTF_ALT */ +#undef mbedtls_printf +#if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) +#define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO +#else +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for snprintf + * + * The snprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF) +/* For Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_snprintf(char *s, size_t n, const char *fmt, ...); +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +extern int (*mbedtls_snprintf)(char *s, size_t n, const char *format, ...); + +/** + * \brief This function allows configuring a custom + * \c snprintf function pointer. + * + * \param snprintf_func The \c snprintf function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_snprintf(int (*snprintf_func)(char *s, size_t n, + const char *format, ...)); +#else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#undef mbedtls_snprintf +#if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) +#define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO +#else +#define mbedtls_snprintf MBEDTLS_PLATFORM_STD_SNPRINTF +#endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +/* + * The function pointers for vsnprintf + * + * The vsnprintf implementation should conform to C99: + * - it *must* always correctly zero-terminate the buffer + * (except when n == 0, then it must leave the buffer untouched) + * - however it is acceptable to return -1 instead of the required length when + * the destination buffer is too short. + */ +#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF) +#include +/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */ +int mbedtls_platform_win32_vsnprintf(char *s, size_t n, const char *fmt, va_list arg); +#endif + +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) +#include +extern int (*mbedtls_vsnprintf)(char *s, size_t n, const char *format, va_list arg); + +/** + * \brief Set your own snprintf function pointer + * + * \param vsnprintf_func The \c vsnprintf function implementation + * + * \return \c 0 + */ +int mbedtls_platform_set_vsnprintf(int (*vsnprintf_func)(char *s, size_t n, + const char *format, va_list arg)); +#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ +#undef mbedtls_vsnprintf +#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO) +#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO +#else +#define mbedtls_vsnprintf vsnprintf +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */ +#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */ + +/* + * The function pointers for setbuf + */ +#if defined(MBEDTLS_PLATFORM_SETBUF_ALT) +#include +/** + * \brief Function pointer to call for `setbuf()` functionality + * (changing the internal buffering on stdio calls). + * + * \note The library calls this function to disable + * buffering when reading or writing sensitive data, + * to avoid having extra copies of sensitive data + * remaining in stdio buffers after the file is + * closed. If this is not a concern, for example if + * your platform's stdio doesn't have any buffering, + * you can set mbedtls_setbuf to a function that + * does nothing. + * + * The library always calls this function with + * `buf` equal to `NULL`. + */ +extern void (*mbedtls_setbuf)(FILE *stream, char *buf); + +/** + * \brief Dynamically configure the function that is called + * when the mbedtls_setbuf() function is called by the + * library. + * + * \param setbuf_func The \c setbuf function implementation + * + * \return \c 0 + */ +int mbedtls_platform_set_setbuf(void (*setbuf_func)( + FILE *stream, char *buf)); +#else +#undef mbedtls_setbuf +#if defined(MBEDTLS_PLATFORM_SETBUF_MACRO) +/** + * \brief Macro defining the function for the library to + * call for `setbuf` functionality (changing the + * internal buffering on stdio calls). + * + * \note See extra comments on the mbedtls_setbuf() function + * pointer above. + * + * \return \c 0 on success, negative on error. + */ +#define mbedtls_setbuf MBEDTLS_PLATFORM_SETBUF_MACRO +#else +#define mbedtls_setbuf setbuf +#endif /* MBEDTLS_PLATFORM_SETBUF_MACRO */ +#endif /* MBEDTLS_PLATFORM_SETBUF_ALT */ + +/* + * The function pointers for exit + */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +extern void (*mbedtls_exit)(int status); + +/** + * \brief This function dynamically configures the exit + * function that is called when the mbedtls_exit() + * function is invoked by the library. + * + * \param exit_func The \c exit function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_exit(void (*exit_func)(int status)); +#else +#undef mbedtls_exit +#if defined(MBEDTLS_PLATFORM_EXIT_MACRO) +#define mbedtls_exit MBEDTLS_PLATFORM_EXIT_MACRO +#else +#define mbedtls_exit exit +#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +/* + * The default exit values + */ +#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS +#else +#define MBEDTLS_EXIT_SUCCESS 0 +#endif +#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE +#else +#define MBEDTLS_EXIT_FAILURE 1 +#endif + +/* + * The function pointers for reading from and writing a seed file to + * Non-Volatile storage (NV) in a platform-independent way + * + * Only enabled when the NV seed entropy source is enabled + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Internal standard platform definitions */ +int mbedtls_platform_std_nv_seed_read(unsigned char *buf, size_t buf_len); +int mbedtls_platform_std_nv_seed_write(unsigned char *buf, size_t buf_len); +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +extern int (*mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len); +extern int (*mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len); + +/** + * \brief This function allows configuring custom seed file writing and + * reading functions. + * + * \param nv_seed_read_func The seed reading function implementation. + * \param nv_seed_write_func The seed writing function implementation. + * + * \return \c 0 on success. + */ +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)(unsigned char *buf, size_t buf_len), + int (*nv_seed_write_func)(unsigned char *buf, size_t buf_len) + ); +#else +#undef mbedtls_nv_seed_read +#undef mbedtls_nv_seed_write +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ + defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) +#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO +#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO +#else +#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read +#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write +#endif +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) + +/** + * \brief The platform context structure. + * + * \note This structure may be used to assist platform-specific + * setup or teardown operations. + */ +typedef struct mbedtls_platform_context { + char MBEDTLS_PRIVATE(dummy); /**< A placeholder member, as empty structs are not portable. */ +} +mbedtls_platform_context; + +#else +#include "platform_alt.h" +#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +/** + * \brief This function performs any platform-specific initialization + * operations. + * + * \note This function should be called before any other library functions. + * + * Its implementation is platform-specific, and unless + * platform-specific code is provided, it does nothing. + * + * \note The usage and necessity of this function is dependent on the platform. + * + * \param ctx The platform context. + * + * \return \c 0 on success. + */ +int mbedtls_platform_setup(mbedtls_platform_context *ctx); +/** + * \brief This function performs any platform teardown operations. + * + * \note This function should be called after every other Mbed TLS module + * has been correctly freed using the appropriate free function. + * + * Its implementation is platform-specific, and unless + * platform-specific code is provided, it does nothing. + * + * \note The usage and necessity of this function is dependent on the platform. + * + * \param ctx The platform context. + * + */ +void mbedtls_platform_teardown(mbedtls_platform_context *ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/platform_util.h b/src/app/findmy/crypto/third-party/mbedtls/platform_util.h new file mode 100644 index 0000000..4375d0c --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/platform_util.h @@ -0,0 +1,207 @@ +/** + * \file platform_util.h + * + * \brief Common and shared functions used by multiple modules in the Mbed TLS + * library. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_PLATFORM_UTIL_H +#define MBEDTLS_PLATFORM_UTIL_H + +#include "mbedtls/build_info.h" + +#include +#if defined(MBEDTLS_HAVE_TIME_DATE) +#include "mbedtls/platform_time.h" +#include +#endif /* MBEDTLS_HAVE_TIME_DATE */ +#define XMEMCPY(d,s,l) memcpy((d),(s),(l)) +#define XMEMSET(b,c,l) memset((b),(c),(l)) +#define XMEMCMP(s1,s2,n) memcmp((s1),(s2),(n)) +#define word32 uint32_t +#define byte uint8_t + +#ifdef __cplusplus +extern "C" { +#endif + +/* Internal macros meant to be called only from within the library. */ +#define MBEDTLS_INTERNAL_VALIDATE_RET(cond, ret) do { } while (0) +#define MBEDTLS_INTERNAL_VALIDATE(cond) do { } while (0) + +/* Internal helper macros for deprecating API constants. */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +MBEDTLS_DEPRECATED typedef char const *mbedtls_deprecated_string_constant_t; +#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) \ + ((mbedtls_deprecated_string_constant_t) (VAL)) +MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t; +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) \ + ((mbedtls_deprecated_numeric_constant_t) (VAL)) +#else /* MBEDTLS_DEPRECATED_WARNING */ +#define MBEDTLS_DEPRECATED +#define MBEDTLS_DEPRECATED_STRING_CONSTANT(VAL) VAL +#define MBEDTLS_DEPRECATED_NUMERIC_CONSTANT(VAL) VAL +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/* Implementation of the check-return facility. + * See the user documentation in mbedtls_config.h. + * + * Do not use this macro directly to annotate function: instead, + * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL + * depending on how important it is to check the return value. + */ +#if !defined(MBEDTLS_CHECK_RETURN) +#if defined(__GNUC__) +#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) +#elif defined(_MSC_VER) && _MSC_VER >= 1700 +#include +#define MBEDTLS_CHECK_RETURN _Check_return_ +#else +#define MBEDTLS_CHECK_RETURN +#endif +#endif + +/** Critical-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that its return value should be checked in all applications. + * Omitting the check is very likely to indicate a bug in the application + * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN + * is implemented for the compiler in use. + * + * \note The use of this macro is a work in progress. + * This macro may be added to more functions in the future. + * Such an extension is not considered an API break, provided that + * there are near-unavoidable circumstances under which the function + * can fail. For example, signature/MAC/AEAD verification functions, + * and functions that require a random generator, are considered + * return-check-critical. + */ +#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN + +/** Ordinary-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that its return value should be generally be checked in portable + * applications. Omitting the check will result in a compile-time warning if + * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and + * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration. + * + * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value + * of a function that is annotated with #MBEDTLS_CHECK_RETURN. + * + * \note The use of this macro is a work in progress. + * This macro will be added to more functions in the future. + * Eventually this should appear before most functions returning + * an error code (as \c int in the \c mbedtls_xxx API or + * as ::psa_status_t in the \c psa_xxx API). + */ +#if defined(MBEDTLS_CHECK_RETURN_WARNING) +#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN +#else +#define MBEDTLS_CHECK_RETURN_TYPICAL +#endif + +/** Benign-failure function + * + * This macro appearing at the beginning of the declaration of a function + * indicates that it is rarely useful to check its return value. + * + * This macro has an empty expansion. It exists for documentation purposes: + * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function + * has been analyzed for return-check usefulness, whereas the lack of + * an annotation indicates that the function has not been analyzed and its + * return-check usefulness is unknown. + */ +#define MBEDTLS_CHECK_RETURN_OPTIONAL + +/** \def MBEDTLS_IGNORE_RETURN + * + * Call this macro with one argument, a function call, to suppress a warning + * from #MBEDTLS_CHECK_RETURN due to that function call. + */ +#if !defined(MBEDTLS_IGNORE_RETURN) +/* GCC doesn't silence the warning with just (void)(result). + * (void)!(result) is known to work up at least up to GCC 10, as well + * as with Clang and MSVC. + * + * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html + * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34 + */ +#define MBEDTLS_IGNORE_RETURN(result) ((void) !(result)) +#endif + +/* If the following macro is defined, the library is being built by the test + * framework, and the framework is going to provide a replacement + * mbedtls_platform_zeroize() using a preprocessor macro, so the function + * declaration should be omitted. */ +#if !defined(MBEDTLS_TEST_DEFINES_ZEROIZE) //no-check-names +/** + * \brief Securely zeroize a buffer + * + * The function is meant to wipe the data contained in a buffer so + * that it can no longer be recovered even if the program memory + * is later compromised. Call this function on sensitive data + * stored on the stack before returning from a function, and on + * sensitive data stored on the heap before freeing the heap + * object. + * + * It is extremely difficult to guarantee that calls to + * mbedtls_platform_zeroize() are not removed by aggressive + * compiler optimizations in a portable way. For this reason, Mbed + * TLS provides the configuration option + * MBEDTLS_PLATFORM_ZEROIZE_ALT, which allows users to configure + * mbedtls_platform_zeroize() to use a suitable implementation for + * their platform and needs + * + * \param buf Buffer to be zeroized + * \param len Length of the buffer in bytes + * + */ +void mbedtls_platform_zeroize(void *buf, size_t len); +int mbedtls_platform_frng(void *p_rng, unsigned char *output, size_t output_len); +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/** + * \brief Platform-specific implementation of gmtime_r() + * + * The function is a thread-safe abstraction that behaves + * similarly to the gmtime_r() function from Unix/POSIX. + * + * Mbed TLS will try to identify the underlying platform and + * make use of an appropriate underlying implementation (e.g. + * gmtime_r() for POSIX and gmtime_s() for Windows). If this is + * not possible, then gmtime() will be used. In this case, calls + * from the library to gmtime() will be guarded by the mutex + * mbedtls_threading_gmtime_mutex if MBEDTLS_THREADING_C is + * enabled. It is recommended that calls from outside the library + * are also guarded by this mutex. + * + * If MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, then Mbed TLS will + * unconditionally use the alternative implementation for + * mbedtls_platform_gmtime_r() supplied by the user at compile time. + * + * \param tt Pointer to an object containing time (in seconds) since the + * epoch to be converted + * \param tm_buf Pointer to an object where the results will be stored + * + * \return Pointer to an object of type struct tm on success, otherwise + * NULL + */ +struct tm *mbedtls_platform_gmtime_r(const mbedtls_time_t *tt, + struct tm *tm_buf); +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_PLATFORM_UTIL_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/private_access.h b/src/app/findmy/crypto/third-party/mbedtls/private_access.h new file mode 100644 index 0000000..541ad52 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/private_access.h @@ -0,0 +1,22 @@ +/** + * \file private_access.h + * + * \brief Macro wrapper for struct's members. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include "common.h" + +#ifndef MBEDTLS_PRIVATE_ACCESS_H +#define MBEDTLS_PRIVATE_ACCESS_H + +#ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS +#define MBEDTLS_PRIVATE(member) private_##member +#else +#define MBEDTLS_PRIVATE(member) member +#endif + +#endif /* MBEDTLS_PRIVATE_ACCESS_H */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/ripemd160.h b/src/app/findmy/crypto/third-party/mbedtls/ripemd160.h new file mode 100644 index 0000000..279f92b --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/ripemd160.h @@ -0,0 +1,136 @@ +/** + * \file ripemd160.h + * + * \brief RIPE MD-160 message digest + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_RIPEMD160_H +#define MBEDTLS_RIPEMD160_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_RIPEMD160_ALT) +// Regular implementation +// + +/** + * \brief RIPEMD-160 context structure + */ +typedef struct mbedtls_ripemd160_context { + uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< number of bytes processed */ + uint32_t MBEDTLS_PRIVATE(state)[5]; /*!< intermediate digest state */ + unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< data block being processed */ +} +mbedtls_ripemd160_context; + +#else /* MBEDTLS_RIPEMD160_ALT */ +#include "ripemd160_alt.h" +#endif /* MBEDTLS_RIPEMD160_ALT */ + +/** + * \brief Initialize RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be initialized + */ +void mbedtls_ripemd160_init(mbedtls_ripemd160_context *ctx); + +/** + * \brief Clear RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be cleared + */ +void mbedtls_ripemd160_free(mbedtls_ripemd160_context *ctx); + +/** + * \brief Clone (the state of) a RIPEMD-160 context + * + * \param dst The destination context + * \param src The context to be cloned + */ +void mbedtls_ripemd160_clone(mbedtls_ripemd160_context *dst, + const mbedtls_ripemd160_context *src); + +/** + * \brief RIPEMD-160 context setup + * + * \param ctx context to be initialized + * + * \return 0 if successful + */ +int mbedtls_ripemd160_starts(mbedtls_ripemd160_context *ctx); + +/** + * \brief RIPEMD-160 process buffer + * + * \param ctx RIPEMD-160 context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \return 0 if successful + */ +int mbedtls_ripemd160_update(mbedtls_ripemd160_context *ctx, + const unsigned char *input, + size_t ilen); + +/** + * \brief RIPEMD-160 final digest + * + * \param ctx RIPEMD-160 context + * \param output RIPEMD-160 checksum result + * + * \return 0 if successful + */ +int mbedtls_ripemd160_finish(mbedtls_ripemd160_context *ctx, + unsigned char output[20]); + +/** + * \brief RIPEMD-160 process data block (internal use only) + * + * \param ctx RIPEMD-160 context + * \param data buffer holding one block of data + * + * \return 0 if successful + */ +int mbedtls_internal_ripemd160_process(mbedtls_ripemd160_context *ctx, + const unsigned char data[64]); + +/** + * \brief Output = RIPEMD-160( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output RIPEMD-160 checksum result + * + * \return 0 if successful + */ +int mbedtls_ripemd160(const unsigned char *input, + size_t ilen, + unsigned char output[20]); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_ripemd160_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_ripemd160.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/rsa.h b/src/app/findmy/crypto/third-party/mbedtls/rsa.h new file mode 100644 index 0000000..df66524 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/rsa.h @@ -0,0 +1,1143 @@ +/** + * \file rsa.h + * + * \brief This file provides an API for the RSA public-key cryptosystem. + * + * The RSA public-key cryptosystem is defined in Public-Key + * Cryptography Standards (PKCS) #1 v1.5: RSA Encryption + * and Public-Key Cryptography Standards (PKCS) #1 v2.1: + * RSA Cryptography Specifications. + * + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_RSA_H +#define MBEDTLS_RSA_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include "mbedtls/bignum.h" +#include "mbedtls/md.h" + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +/* + * RSA Error codes + */ +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_RSA_BAD_INPUT_DATA -0x4080 +/** Input data contains invalid padding and is rejected. */ +#define MBEDTLS_ERR_RSA_INVALID_PADDING -0x4100 +/** Something failed during generation of a key. */ +#define MBEDTLS_ERR_RSA_KEY_GEN_FAILED -0x4180 +/** Key failed to pass the validity check of the library. */ +#define MBEDTLS_ERR_RSA_KEY_CHECK_FAILED -0x4200 +/** The public key operation failed. */ +#define MBEDTLS_ERR_RSA_PUBLIC_FAILED -0x4280 +/** The private key operation failed. */ +#define MBEDTLS_ERR_RSA_PRIVATE_FAILED -0x4300 +/** The PKCS#1 verification failed. */ +#define MBEDTLS_ERR_RSA_VERIFY_FAILED -0x4380 +/** The output buffer for decryption is not large enough. */ +#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 +/** The random generator failed to generate non-zeros. */ +#define MBEDTLS_ERR_RSA_RNG_FAILED -0x4480 + +/* + * RSA constants + */ + +#define MBEDTLS_RSA_PKCS_V15 0 /**< Use PKCS#1 v1.5 encoding. */ +#define MBEDTLS_RSA_PKCS_V21 1 /**< Use PKCS#1 v2.1 encoding. */ + +#define MBEDTLS_RSA_SIGN 1 /**< Identifier for RSA signature operations. */ +#define MBEDTLS_RSA_CRYPT 2 /**< Identifier for RSA encryption and decryption operations. */ + +#define MBEDTLS_RSA_SALT_LEN_ANY -1 + +/* + * The above constants may be used even if the RSA module is compile out, + * eg for alternative (PKCS#11) RSA implementations in the PK layers. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_RSA_ALT) +// Regular implementation +// + +#if !defined(MBEDTLS_RSA_GEN_KEY_MIN_BITS) +#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 +#elif MBEDTLS_RSA_GEN_KEY_MIN_BITS < 128 +#error "MBEDTLS_RSA_GEN_KEY_MIN_BITS must be at least 128 bits" +#endif + +/** + * \brief The RSA context structure. + */ +typedef struct mbedtls_rsa_context { + int MBEDTLS_PRIVATE(ver); /*!< Reserved for internal purposes. + * Do not set this field in application + * code. Its meaning might change without + * notice. */ + size_t MBEDTLS_PRIVATE(len); /*!< The size of \p N in Bytes. */ + + mbedtls_mpi MBEDTLS_PRIVATE(N); /*!< The public modulus. */ + mbedtls_mpi MBEDTLS_PRIVATE(E); /*!< The public exponent. */ + + mbedtls_mpi MBEDTLS_PRIVATE(D); /*!< The private exponent. */ + mbedtls_mpi MBEDTLS_PRIVATE(P); /*!< The first prime factor. */ + mbedtls_mpi MBEDTLS_PRIVATE(Q); /*!< The second prime factor. */ + + mbedtls_mpi MBEDTLS_PRIVATE(DP); /*!< D % (P - 1). */ + mbedtls_mpi MBEDTLS_PRIVATE(DQ); /*!< D % (Q - 1). */ + mbedtls_mpi MBEDTLS_PRIVATE(QP); /*!< 1 / (Q % P). */ + + mbedtls_mpi MBEDTLS_PRIVATE(RN); /*!< cached R^2 mod N. */ + + mbedtls_mpi MBEDTLS_PRIVATE(RP); /*!< cached R^2 mod P. */ + mbedtls_mpi MBEDTLS_PRIVATE(RQ); /*!< cached R^2 mod Q. */ + + mbedtls_mpi MBEDTLS_PRIVATE(Vi); /*!< The cached blinding value. */ + mbedtls_mpi MBEDTLS_PRIVATE(Vf); /*!< The cached un-blinding value. */ + + int MBEDTLS_PRIVATE(padding); /*!< Selects padding mode: + #MBEDTLS_RSA_PKCS_V15 for 1.5 padding and + #MBEDTLS_RSA_PKCS_V21 for OAEP or PSS. */ + int MBEDTLS_PRIVATE(hash_id); /*!< Hash identifier of mbedtls_md_type_t type, + as specified in md.h for use in the MGF + mask generating function used in the + EME-OAEP and EMSA-PSS encodings. */ +#if defined(MBEDTLS_THREADING_C) + /* Invariant: the mutex is initialized iff ver != 0. */ + mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< Thread-safety mutex. */ +#endif +} +mbedtls_rsa_context; + +#else /* MBEDTLS_RSA_ALT */ +#include "rsa_alt.h" +#endif /* MBEDTLS_RSA_ALT */ + +/** + * \brief This function initializes an RSA context. + * + * \note This function initializes the padding and the hash + * identifier to respectively #MBEDTLS_RSA_PKCS_V15 and + * #MBEDTLS_MD_NONE. See mbedtls_rsa_set_padding() for more + * information about those parameters. + * + * \param ctx The RSA context to initialize. This must not be \c NULL. + */ +void mbedtls_rsa_init(mbedtls_rsa_context *ctx); + +/** + * \brief This function sets padding for an already initialized RSA + * context. + * + * \note Set padding to #MBEDTLS_RSA_PKCS_V21 for the RSAES-OAEP + * encryption scheme and the RSASSA-PSS signature scheme. + * + * \note The \p hash_id parameter is ignored when using + * #MBEDTLS_RSA_PKCS_V15 padding. + * + * \note The choice of padding mode is strictly enforced for private + * key operations, since there might be security concerns in + * mixing padding modes. For public key operations it is + * a default value, which can be overridden by calling specific + * \c mbedtls_rsa_rsaes_xxx or \c mbedtls_rsa_rsassa_xxx + * functions. + * + * \note The hash selected in \p hash_id is always used for OEAP + * encryption. For PSS signatures, it is always used for + * making signatures, but can be overridden for verifying them. + * If set to #MBEDTLS_MD_NONE, it is always overridden. + * + * \param ctx The initialized RSA context to be configured. + * \param padding The padding mode to use. This must be either + * #MBEDTLS_RSA_PKCS_V15 or #MBEDTLS_RSA_PKCS_V21. + * \param hash_id The hash identifier for PSS or OAEP, if \p padding is + * #MBEDTLS_RSA_PKCS_V21. #MBEDTLS_MD_NONE is accepted by this + * function but may be not suitable for some operations. + * Ignored if \p padding is #MBEDTLS_RSA_PKCS_V15. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_RSA_INVALID_PADDING failure: + * \p padding or \p hash_id is invalid. + */ +int mbedtls_rsa_set_padding(mbedtls_rsa_context *ctx, int padding, + mbedtls_md_type_t hash_id); + +/** + * \brief This function retrieves padding mode of initialized + * RSA context. + * + * \param ctx The initialized RSA context. + * + * \return RSA padding mode. + * + */ +int mbedtls_rsa_get_padding_mode(const mbedtls_rsa_context *ctx); + +/** + * \brief This function retrieves hash identifier of mbedtls_md_type_t + * type. + * + * \param ctx The initialized RSA context. + * + * \return Hash identifier of mbedtls_md_type_t type. + * + */ +int mbedtls_rsa_get_md_alg(const mbedtls_rsa_context *ctx); + +/** + * \brief This function imports a set of core parameters into an + * RSA context. + * + * \note This function can be called multiple times for successive + * imports, if the parameters are not simultaneously present. + * + * Any sequence of calls to this function should be followed + * by a call to mbedtls_rsa_complete(), which checks and + * completes the provided information to a ready-for-use + * public or private RSA key. + * + * \note See mbedtls_rsa_complete() for more information on which + * parameters are necessary to set up a private or public + * RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus. This may be \c NULL. + * \param P The first prime factor of \p N. This may be \c NULL. + * \param Q The second prime factor of \p N. This may be \c NULL. + * \param D The private exponent. This may be \c NULL. + * \param E The public exponent. This may be \c NULL. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int mbedtls_rsa_import(mbedtls_rsa_context *ctx, + const mbedtls_mpi *N, + const mbedtls_mpi *P, const mbedtls_mpi *Q, + const mbedtls_mpi *D, const mbedtls_mpi *E); + +/** + * \brief This function imports core RSA parameters, in raw big-endian + * binary format, into an RSA context. + * + * \note This function can be called multiple times for successive + * imports, if the parameters are not simultaneously present. + * + * Any sequence of calls to this function should be followed + * by a call to mbedtls_rsa_complete(), which checks and + * completes the provided information to a ready-for-use + * public or private RSA key. + * + * \note See mbedtls_rsa_complete() for more information on which + * parameters are necessary to set up a private or public + * RSA key. + * + * \note The imported parameters are copied and need not be preserved + * for the lifetime of the RSA context being set up. + * + * \param ctx The initialized RSA context to store the parameters in. + * \param N The RSA modulus. This may be \c NULL. + * \param N_len The Byte length of \p N; it is ignored if \p N == NULL. + * \param P The first prime factor of \p N. This may be \c NULL. + * \param P_len The Byte length of \p P; it is ignored if \p P == NULL. + * \param Q The second prime factor of \p N. This may be \c NULL. + * \param Q_len The Byte length of \p Q; it is ignored if \p Q == NULL. + * \param D The private exponent. This may be \c NULL. + * \param D_len The Byte length of \p D; it is ignored if \p D == NULL. + * \param E The public exponent. This may be \c NULL. + * \param E_len The Byte length of \p E; it is ignored if \p E == NULL. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + */ +int mbedtls_rsa_import_raw(mbedtls_rsa_context *ctx, + unsigned char const *N, size_t N_len, + unsigned char const *P, size_t P_len, + unsigned char const *Q, size_t Q_len, + unsigned char const *D, size_t D_len, + unsigned char const *E, size_t E_len); + +/** + * \brief This function completes an RSA context from + * a set of imported core parameters. + * + * To setup an RSA public key, precisely \c N and \c E + * must have been imported. + * + * To setup an RSA private key, sufficient information must + * be present for the other parameters to be derivable. + * + * The default implementation supports the following: + *
    • Derive \c P, \c Q from \c N, \c D, \c E.
    • + *
    • Derive \c N, \c D from \c P, \c Q, \c E.
    + * Alternative implementations need not support these. + * + * If this function runs successfully, it guarantees that + * the RSA context can be used for RSA operations without + * the risk of failure or crash. + * + * \warning This function need not perform consistency checks + * for the imported parameters. In particular, parameters that + * are not needed by the implementation might be silently + * discarded and left unchecked. To check the consistency + * of the key material, see mbedtls_rsa_check_privkey(). + * + * \param ctx The initialized RSA context holding imported parameters. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the attempted derivations + * failed. + * + */ +int mbedtls_rsa_complete(mbedtls_rsa_context *ctx); + +/** + * \brief This function exports the core parameters of an RSA key. + * + * If this function runs successfully, the non-NULL buffers + * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully + * written, with additional unused space filled leading by + * zero Bytes. + * + * Possible reasons for returning + * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
      + *
    • An alternative RSA implementation is in use, which + * stores the key externally, and either cannot or should + * not export it into RAM.
    • + *
    • A SW or HW implementation might not support a certain + * deduction. For example, \p P, \p Q from \p N, \p D, + * and \p E if the former are not part of the + * implementation.
    + * + * If the function fails due to an unsupported operation, + * the RSA context stays intact and remains usable. + * + * \param ctx The initialized RSA context. + * \param N The MPI to hold the RSA modulus. + * This may be \c NULL if this field need not be exported. + * \param P The MPI to hold the first prime factor of \p N. + * This may be \c NULL if this field need not be exported. + * \param Q The MPI to hold the second prime factor of \p N. + * This may be \c NULL if this field need not be exported. + * \param D The MPI to hold the private exponent. + * This may be \c NULL if this field need not be exported. + * \param E The MPI to hold the public exponent. + * This may be \c NULL if this field need not be exported. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * requested parameters cannot be done due to missing + * functionality or because of security policies. + * \return A non-zero return code on any other failure. + * + */ +int mbedtls_rsa_export(const mbedtls_rsa_context *ctx, + mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q, + mbedtls_mpi *D, mbedtls_mpi *E); + +/** + * \brief This function exports core parameters of an RSA key + * in raw big-endian binary format. + * + * If this function runs successfully, the non-NULL buffers + * pointed to by \p N, \p P, \p Q, \p D, and \p E are fully + * written, with additional unused space filled leading by + * zero Bytes. + * + * Possible reasons for returning + * #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED:
      + *
    • An alternative RSA implementation is in use, which + * stores the key externally, and either cannot or should + * not export it into RAM.
    • + *
    • A SW or HW implementation might not support a certain + * deduction. For example, \p P, \p Q from \p N, \p D, + * and \p E if the former are not part of the + * implementation.
    + * If the function fails due to an unsupported operation, + * the RSA context stays intact and remains usable. + * + * \note The length parameters are ignored if the corresponding + * buffer pointers are NULL. + * + * \param ctx The initialized RSA context. + * \param N The Byte array to store the RSA modulus, + * or \c NULL if this field need not be exported. + * \param N_len The size of the buffer for the modulus. + * \param P The Byte array to hold the first prime factor of \p N, + * or \c NULL if this field need not be exported. + * \param P_len The size of the buffer for the first prime factor. + * \param Q The Byte array to hold the second prime factor of \p N, + * or \c NULL if this field need not be exported. + * \param Q_len The size of the buffer for the second prime factor. + * \param D The Byte array to hold the private exponent, + * or \c NULL if this field need not be exported. + * \param D_len The size of the buffer for the private exponent. + * \param E The Byte array to hold the public exponent, + * or \c NULL if this field need not be exported. + * \param E_len The size of the buffer for the public exponent. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED if exporting the + * requested parameters cannot be done due to missing + * functionality or because of security policies. + * \return A non-zero return code on any other failure. + */ +int mbedtls_rsa_export_raw(const mbedtls_rsa_context *ctx, + unsigned char *N, size_t N_len, + unsigned char *P, size_t P_len, + unsigned char *Q, size_t Q_len, + unsigned char *D, size_t D_len, + unsigned char *E, size_t E_len); + +/** + * \brief This function exports CRT parameters of a private RSA key. + * + * \note Alternative RSA implementations not using CRT-parameters + * internally can implement this function based on + * mbedtls_rsa_deduce_opt(). + * + * \param ctx The initialized RSA context. + * \param DP The MPI to hold \c D modulo `P-1`, + * or \c NULL if it need not be exported. + * \param DQ The MPI to hold \c D modulo `Q-1`, + * or \c NULL if it need not be exported. + * \param QP The MPI to hold modular inverse of \c Q modulo \c P, + * or \c NULL if it need not be exported. + * + * \return \c 0 on success. + * \return A non-zero error code on failure. + * + */ +int mbedtls_rsa_export_crt(const mbedtls_rsa_context *ctx, + mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP); + +/** + * \brief This function retrieves the length of RSA modulus in Bytes. + * + * \param ctx The initialized RSA context. + * + * \return The length of the RSA modulus in Bytes. + * + */ +size_t mbedtls_rsa_get_len(const mbedtls_rsa_context *ctx); + +/** + * \brief This function generates an RSA keypair. + * + * \note mbedtls_rsa_init() must be called before this function, + * to set up the RSA context. + * + * \param ctx The initialized RSA context used to hold the key. + * \param f_rng The RNG function to be used for key generation. + * This is mandatory and must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. + * This may be \c NULL if \p f_rng doesn't need a context. + * \param nbits The size of the public key in bits. + * \param exponent The public exponent to use. For example, \c 65537. + * This must be odd and greater than \c 1. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_gen_key(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent); + +/** + * \brief This function checks if a context contains at least an RSA + * public key. + * + * If the function runs successfully, it is guaranteed that + * enough information is present to perform an RSA public key + * operation using mbedtls_rsa_public(). + * + * \param ctx The initialized RSA context to check. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_check_pubkey(const mbedtls_rsa_context *ctx); + +/** + * \brief This function checks if a context contains an RSA private key + * and perform basic consistency checks. + * + * \note The consistency checks performed by this function not only + * ensure that mbedtls_rsa_private() can be called successfully + * on the given context, but that the various parameters are + * mutually consistent with high probability, in the sense that + * mbedtls_rsa_public() and mbedtls_rsa_private() are inverses. + * + * \warning This function should catch accidental misconfigurations + * like swapping of parameters, but it cannot establish full + * trust in neither the quality nor the consistency of the key + * material that was used to setup the given RSA context: + *
    • Consistency: Imported parameters that are irrelevant + * for the implementation might be silently dropped. If dropped, + * the current function does not have access to them, + * and therefore cannot check them. See mbedtls_rsa_complete(). + * If you want to check the consistency of the entire + * content of a PKCS1-encoded RSA private key, for example, you + * should use mbedtls_rsa_validate_params() before setting + * up the RSA context. + * Additionally, if the implementation performs empirical checks, + * these checks substantiate but do not guarantee consistency.
    • + *
    • Quality: This function is not expected to perform + * extended quality assessments like checking that the prime + * factors are safe. Additionally, it is the responsibility of the + * user to ensure the trustworthiness of the source of his RSA + * parameters, which goes beyond what is effectively checkable + * by the library.
    + * + * \param ctx The initialized RSA context to check. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_check_privkey(const mbedtls_rsa_context *ctx); + +/** + * \brief This function checks a public-private RSA key pair. + * + * It checks each of the contexts, and makes sure they match. + * + * \param pub The initialized RSA context holding the public key. + * \param prv The initialized RSA context holding the private key. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_check_pub_priv(const mbedtls_rsa_context *pub, + const mbedtls_rsa_context *prv); + +/** + * \brief This function performs an RSA public key operation. + * + * \param ctx The initialized RSA context to use. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \note This function does not handle message padding. + * + * \note Make sure to set \p input[0] = 0 or ensure that + * input is smaller than \c N. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_public(mbedtls_rsa_context *ctx, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function performs an RSA private key operation. + * + * \note Blinding is used if and only if a PRNG is provided. + * + * \note If blinding is used, both the base of exponentiation + * and the exponent are blinded, providing protection + * against some side-channel attacks. + * + * \warning It is deprecated and a security risk to not provide + * a PRNG here and thereby prevent the use of blinding. + * Future versions of the library may enforce the presence + * of a PRNG. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function, used for blinding. It is mandatory. + * \param p_rng The RNG context to pass to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context. + * \param input The input buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_private(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function adds the message padding, then performs an RSA + * operation. + * + * It is the generic wrapper for performing a PKCS#1 encryption + * operation. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG to use. It is used for padding generation + * and it is mandatory. + * \param p_rng The RNG context to be passed to \p f_rng. May be + * \c NULL if \p f_rng doesn't need a context argument. + * \param ilen The length of the plaintext in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_encrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + size_t ilen, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function performs a PKCS#1 v1.5 encryption operation + * (RSAES-PKCS1-v1_5-ENCRYPT). + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. It is mandatory and used for + * padding generation. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * \param ilen The length of the plaintext in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + size_t ilen, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function performs a PKCS#1 v2.1 OAEP encryption + * operation (RSAES-OAEP-ENCRYPT). + * + * \note The output buffer must be as large as the size + * of ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. This is needed for padding + * generation and is mandatory. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. + * \param label The buffer holding the custom label to use. + * This must be a readable buffer of length \p label_len + * Bytes. It may be \c NULL if \p label_len is \c 0. + * \param label_len The length of the label in Bytes. + * \param ilen The length of the plaintext buffer \p input in Bytes. + * \param input The input data to encrypt. This must be a readable + * buffer of size \p ilen Bytes. It may be \c NULL if + * `ilen == 0`. + * \param output The output buffer. This must be a writable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output); + +/** + * \brief This function performs an RSA operation, then removes the + * message padding. + * + * It is the generic wrapper for performing a PKCS#1 decryption + * operation. + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N (for example, + * 128 Bytes if RSA-1024 is used) to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns \c MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. This is used for blinding and is + * mandatory; see mbedtls_rsa_private() for more. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context. + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len); + +/** + * \brief This function performs a PKCS#1 v1.5 decryption + * operation (RSAES-PKCS1-v1_5-DECRYPT). + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for example, + * 128 Bytes if RSA-1024 is used, to be able to hold an + * arbitrary decrypted message. If it is not large enough to + * hold the decryption of the particular ciphertext provided, + * the function returns #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. This is used for blinding and is + * mandatory; see mbedtls_rsa_private() for more. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context. + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + * + */ +int mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len); + +/** + * \brief This function performs a PKCS#1 v2.1 OAEP decryption + * operation (RSAES-OAEP-DECRYPT). + * + * \note The output buffer length \c output_max_len should be + * as large as the size \p ctx->len of \p ctx->N, for + * example, 128 Bytes if RSA-1024 is used, to be able to + * hold an arbitrary decrypted message. If it is not + * large enough to hold the decryption of the particular + * ciphertext provided, the function returns + * #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. This is used for blinding and is + * mandatory. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context. + * \param label The buffer holding the custom label to use. + * This must be a readable buffer of length \p label_len + * Bytes. It may be \c NULL if \p label_len is \c 0. + * \param label_len The length of the label in Bytes. + * \param olen The address at which to store the length of + * the plaintext. This must not be \c NULL. + * \param input The ciphertext buffer. This must be a readable buffer + * of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * \param output The buffer used to hold the plaintext. This must + * be a writable buffer of length \p output_max_len Bytes. + * \param output_max_len The length in Bytes of the output buffer \p output. + * + * \return \c 0 on success. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsaes_oaep_decrypt(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len); + +/** + * \brief This function performs a private RSA operation to sign + * a message digest using PKCS#1. + * + * It is the generic wrapper for performing a PKCS#1 + * signature. + * + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_sign() for details on + * \p md_alg and \p hash_id. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function to use. This is mandatory and + * must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_sign(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v1.5 signature + * operation (RSASSA-PKCS1-v1_5-SIGN). + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. This is used for blinding and is + * mandatory; see mbedtls_rsa_private() for more. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pkcs1_v15_sign(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS signature + * operation (RSASSA-PSS-SIGN). + * + * \note The \c hash_id set in \p ctx by calling + * mbedtls_rsa_set_padding() selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * + * \note This function enforces that the provided salt length complies + * with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1 + * step 3. The constraint is that the hash length plus the salt + * length plus 2 bytes must be at most the key length. If this + * constraint is not met, this function returns + * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. It is mandatory and must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param saltlen The length of the salt that should be used. + * If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use + * the largest possible salt length up to the hash length, + * which is the largest permitted by some standards including + * FIPS 186-4 §5.5. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_sign_ext(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS signature + * operation (RSASSA-PSS-SIGN). + * + * \note The \c hash_id set in \p ctx by calling + * mbedtls_rsa_set_padding() selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * + * \note This function always uses the maximum possible salt size, + * up to the length of the payload hash. This choice of salt + * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 + * v2.2) §9.1.1 step 3. Furthermore this function enforces a + * minimum salt size which is the hash size minus 2 bytes. If + * this minimum size is too large given the key size (the salt + * size, plus the hash size, plus 2 bytes must be no more than + * the key size in bytes), this function returns + * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. It is mandatory and must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_sign(mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig); + +/** + * \brief This function performs a public RSA operation and checks + * the message digest. + * + * This is the generic wrapper for performing a PKCS#1 + * verification. + * + * \note For PKCS#1 v2.1 encoding, see comments on + * mbedtls_rsa_rsassa_pss_verify() about \c md_alg and + * \c hash_id. + * + * \param ctx The initialized RSA public key context to use. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_pkcs1_verify(mbedtls_rsa_context *ctx, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v1.5 verification + * operation (RSASSA-PKCS1-v1_5-VERIFY). + * + * \param ctx The initialized RSA public key context to use. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pkcs1_v15_verify(mbedtls_rsa_context *ctx, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS verification + * operation (RSASSA-PSS-VERIFY). + * + * \note The \c hash_id set in \p ctx by calling + * mbedtls_rsa_set_padding() selects the hash used for the + * encoding operation and for the mask generation function + * (MGF1). For more details on the encoding operation and the + * mask generation function, consult RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications. If the \c hash_id set in \p ctx by + * mbedtls_rsa_set_padding() is #MBEDTLS_MD_NONE, the \p md_alg + * parameter is used. + * + * \param ctx The initialized RSA public key context to use. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_verify(mbedtls_rsa_context *ctx, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig); + +/** + * \brief This function performs a PKCS#1 v2.1 PSS verification + * operation (RSASSA-PSS-VERIFY). + * + * \note The \p sig buffer must be as large as the size + * of \p ctx->N. For example, 128 Bytes if RSA-1024 is used. + * + * \note The \c hash_id set in \p ctx by mbedtls_rsa_set_padding() is + * ignored. + * + * \param ctx The initialized RSA public key context to use. + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest or raw data in Bytes. + * If \p md_alg is not #MBEDTLS_MD_NONE, this must match the + * output length of the corresponding hash algorithm. + * \param hash The buffer holding the message digest or raw data. + * This must be a readable buffer of at least \p hashlen Bytes. + * \param mgf1_hash_id The message digest algorithm used for the + * verification operation and the mask generation + * function (MGF1). For more details on the encoding + * operation and the mask generation function, consult + * RFC-3447: Public-Key Cryptography Standards + * (PKCS) #1 v2.1: RSA Cryptography + * Specifications. + * \param expected_salt_len The length of the salt used in padding. Use + * #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length. + * \param sig The buffer holding the signature. This must be a readable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. + * + * \return \c 0 if the verify operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_verify_ext(mbedtls_rsa_context *ctx, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + mbedtls_md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig); + +/** + * \brief This function copies the components of an RSA context. + * + * \param dst The destination context. This must be initialized. + * \param src The source context. This must be initialized. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory allocation failure. + */ +int mbedtls_rsa_copy(mbedtls_rsa_context *dst, const mbedtls_rsa_context *src); + +/** + * \brief This function frees the components of an RSA key. + * + * \param ctx The RSA context to free. May be \c NULL, in which case + * this function is a no-op. If it is not \c NULL, it must + * point to an initialized RSA context. + */ +void mbedtls_rsa_free(mbedtls_rsa_context *ctx); + +#if defined(MBEDTLS_SELF_TEST) + +/** + * \brief The RSA checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_rsa_self_test(int verbose); + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* rsa.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/sha256.h b/src/app/findmy/crypto/third-party/mbedtls/sha256.h new file mode 100644 index 0000000..65ed457 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/sha256.h @@ -0,0 +1,199 @@ +/** + * \file sha256.h + * + * \brief This file contains SHA-224 and SHA-256 definitions and functions. + * + * The Secure Hash Algorithms 224 and 256 (SHA-224 and SHA-256) cryptographic + * hash functions are defined in FIPS 180-4: Secure Hash Standard (SHS). + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_SHA256_H +#define MBEDTLS_SHA256_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include +#include + +/** SHA-256 input data was malformed. */ +#define MBEDTLS_ERR_SHA256_BAD_INPUT_DATA -0x0074 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_SHA256_ALT) +// Regular implementation +// + +/** + * \brief The SHA-256 context structure. + * + * The structure is used both for SHA-256 and for SHA-224 + * checksum calculations. The choice between these two is + * made in the call to mbedtls_sha256_starts(). + */ +typedef struct mbedtls_sha256_context { + unsigned char MBEDTLS_PRIVATE(buffer)[64]; /*!< The data block being processed. */ + uint32_t MBEDTLS_PRIVATE(total)[2]; /*!< The number of Bytes processed. */ + uint32_t MBEDTLS_PRIVATE(state)[8]; /*!< The intermediate digest state. */ + int MBEDTLS_PRIVATE(is224); /*!< Determines which function to use: + 0: Use SHA-256, or 1: Use SHA-224. */ +} +mbedtls_sha256_context; + +#else /* MBEDTLS_SHA256_ALT */ +#include "platform/sha256.h" +typedef SHA256_CTX mbedtls_sha256_context; +#endif /* MBEDTLS_SHA256_ALT */ + +/** + * \brief This function initializes a SHA-256 context. + * + * \param ctx The SHA-256 context to initialize. This must not be \c NULL. + */ +void mbedtls_sha256_init(mbedtls_sha256_context *ctx); + +/** + * \brief This function clears a SHA-256 context. + * + * \param ctx The SHA-256 context to clear. This may be \c NULL, in which + * case this function returns immediately. If it is not \c NULL, + * it must point to an initialized SHA-256 context. + */ +void mbedtls_sha256_free(mbedtls_sha256_context *ctx); + +/** + * \brief This function clones the state of a SHA-256 context. + * + * \param dst The destination context. This must be initialized. + * \param src The context to clone. This must be initialized. + */ +void mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src); + +/** + * \brief This function starts a SHA-224 or SHA-256 checksum + * calculation. + * + * \param ctx The context to use. This must be initialized. + * \param is224 This determines which function to use. This must be + * either \c 0 for SHA-256, or \c 1 for SHA-224. + * + * \note is224 must be defined accordingly to the enabled + * MBEDTLS_SHA224_C/MBEDTLS_SHA256_C symbols otherwise the + * function will return #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224); + +/** + * \brief This function feeds an input buffer into an ongoing + * SHA-256 checksum calculation. + * + * \param ctx The SHA-256 context. This must be initialized + * and have a hash operation started. + * \param input The buffer holding the data. This must be a readable + * buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen); + +/** + * \brief This function finishes the SHA-256 operation, and writes + * the result to the output buffer. + * + * \param ctx The SHA-256 context. This must be initialized + * and have a hash operation started. + * \param output The SHA-224 or SHA-256 checksum result. + * This must be a writable buffer of length \c 32 bytes + * for SHA-256, \c 28 bytes for SHA-224. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char *output); + +/** + * \brief This function processes a single data block within + * the ongoing SHA-256 computation. This function is for + * internal use only. + * + * \param ctx The SHA-256 context. This must be initialized. + * \param data The buffer holding one block of data. This must + * be a readable buffer of length \c 64 Bytes. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, + const unsigned char data[64]); + +/** + * \brief This function calculates the SHA-224 or SHA-256 + * checksum of a buffer. + * + * The function allocates the context, performs the + * calculation, and frees the context. + * + * The SHA-256 result is calculated as + * output = SHA-256(input buffer). + * + * \param input The buffer holding the data. This must be a readable + * buffer of length \p ilen Bytes. + * \param ilen The length of the input data in Bytes. + * \param output The SHA-224 or SHA-256 checksum result. + * This must be a writable buffer of length \c 32 bytes + * for SHA-256, \c 28 bytes for SHA-224. + * \param is224 Determines which function to use. This must be + * either \c 0 for SHA-256, or \c 1 for SHA-224. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_sha256(const unsigned char *input, + size_t ilen, + unsigned char *output, + int is224); + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_SHA224_C) +/** + * \brief The SHA-224 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_sha224_self_test(int verbose); +#endif /* MBEDTLS_SHA224_C */ + +#if defined(MBEDTLS_SHA256_C) +/** + * \brief The SHA-256 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_sha256_self_test(int verbose); +#endif /* MBEDTLS_SHA256_C */ + +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* mbedtls_sha256.h */ diff --git a/src/app/findmy/crypto/third-party/mbedtls/threading.h b/src/app/findmy/crypto/third-party/mbedtls/threading.h new file mode 100644 index 0000000..ed16a23 --- /dev/null +++ b/src/app/findmy/crypto/third-party/mbedtls/threading.h @@ -0,0 +1,105 @@ +/** + * \file threading.h + * + * \brief Threading abstraction layer + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#ifndef MBEDTLS_THREADING_H +#define MBEDTLS_THREADING_H +#include "mbedtls/private_access.h" + +#include "mbedtls/build_info.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Bad input parameters to function. */ +#define MBEDTLS_ERR_THREADING_BAD_INPUT_DATA -0x001C +/** Locking / unlocking / free failed with error code. */ +#define MBEDTLS_ERR_THREADING_MUTEX_ERROR -0x001E + +#if defined(MBEDTLS_THREADING_PTHREAD) +#include +typedef struct mbedtls_threading_mutex_t { + pthread_mutex_t MBEDTLS_PRIVATE(mutex); + /* is_valid is 0 after a failed init or a free, and nonzero after a + * successful init. This field is not considered part of the public + * API of Mbed TLS and may change without notice. */ + char MBEDTLS_PRIVATE(is_valid); +} mbedtls_threading_mutex_t; +#endif + +#if defined(MBEDTLS_THREADING_ALT) +/* You should define the mbedtls_threading_mutex_t type in your header */ +#include "threading_alt.h" + +/** + * \brief Set your alternate threading implementation function + * pointers and initialize global mutexes. If used, this + * function must be called once in the main thread before any + * other Mbed TLS function is called, and + * mbedtls_threading_free_alt() must be called once in the main + * thread after all other Mbed TLS functions. + * + * \note mutex_init() and mutex_free() don't return a status code. + * If mutex_init() fails, it should leave its argument (the + * mutex) in a state such that mutex_lock() will fail when + * called with this argument. + * + * \param mutex_init the init function implementation + * \param mutex_free the free function implementation + * \param mutex_lock the lock function implementation + * \param mutex_unlock the unlock function implementation + */ +void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), + void (*mutex_free)(mbedtls_threading_mutex_t *), + int (*mutex_lock)(mbedtls_threading_mutex_t *), + int (*mutex_unlock)(mbedtls_threading_mutex_t *)); + +/** + * \brief Free global mutexes. + */ +void mbedtls_threading_free_alt(void); +#endif /* MBEDTLS_THREADING_ALT */ + +#if defined(MBEDTLS_THREADING_C) +/* + * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock + * + * All these functions are expected to work or the result will be undefined. + */ +extern void (*mbedtls_mutex_init)(mbedtls_threading_mutex_t *mutex); +extern void (*mbedtls_mutex_free)(mbedtls_threading_mutex_t *mutex); +extern int (*mbedtls_mutex_lock)(mbedtls_threading_mutex_t *mutex); +extern int (*mbedtls_mutex_unlock)(mbedtls_threading_mutex_t *mutex); + +/* + * Global mutexes + */ +#if defined(MBEDTLS_FS_IO) +extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; +#endif + +#if defined(MBEDTLS_HAVE_TIME_DATE) && !defined(MBEDTLS_PLATFORM_GMTIME_R_ALT) +/* This mutex may or may not be used in the default definition of + * mbedtls_platform_gmtime_r(), but in order to determine that, + * we need to check POSIX features, hence modify _POSIX_C_SOURCE. + * With the current approach, this declaration is orphaned, lacking + * an accompanying definition, in case mbedtls_platform_gmtime_r() + * doesn't need it, but that's not a problem. */ +extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; +#endif /* MBEDTLS_HAVE_TIME_DATE && !MBEDTLS_PLATFORM_GMTIME_R_ALT */ + +#endif /* MBEDTLS_THREADING_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* threading.h */ diff --git a/src/app/findmy/custom_app.c b/src/app/findmy/custom_app.c new file mode 100644 index 0000000..de99159 --- /dev/null +++ b/src/app/findmy/custom_app.c @@ -0,0 +1,626 @@ +/** +***************************************************************************************** +* Copyright(c) 2025, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file custom_app.c + * @brief This file handles customized application routines. + * @author scarlett + * @date 2025-04-10 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2025 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "trace.h" +#include "gap_bond_le.h" +#include "gap_storage_le.h" +#include "gap_privacy.h" +#include "findmy_app.h" +#include "custom_app.h" +#include "fmna_connection.h" +#include "fmna_adv_platform.h" +#include "fmna_version.h" + +#include "aes.h" + +#include "ftl.h" +#include "fmna_constants_platform.h" +#include "fmna_state_machine.h" + +#if SUPPORT_CUSTOMIZED_APP +/*============================================================================* + * Macros + *============================================================================*/ +#if CUST_HID_SERVICE +#define CUST_ADV_NAME_OFFSET (7) +#else +#define CUST_ADV_NAME_OFFSET (15) +#endif +/*============================================================================* + * Variables + *============================================================================*/ +T_CUSTOM_DATA custom_data; + +//һ6λ +uint8_t SINGLE_ID[6] = {0}; + +//һ6λڴ洢flashжSINGLE_ID +uint8_t READ_SINGLE_ID[6] = {0}; + +//A-Z,0-9λ +void generate_random_id(uint8_t *id, uint16_t len) +{ + uint16_t i; + char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + for (i = 0; i < len; i++) + { + id[i] = charset[rand() % (sizeof(charset) - 1)]; + } + +} + +//ɺõλݴSINGLE_ID +void update_single_id(void) +{ + generate_random_id(SINGLE_ID, 6); +} + +//ɺõSINGLE_IDFLASH +void save_single_id_to_flash(void) +{ + //READ_SINGLE_IDһΪ0Ͳִд洢 + if(READ_SINGLE_ID[0] != 0 || READ_SINGLE_ID[1] != 0 || READ_SINGLE_ID[2] != 0 || READ_SINGLE_ID[3] != 0 || READ_SINGLE_ID[4] != 0 || READ_SINGLE_ID[5] != 0){ + return; + }else{ + + ftl_save(SINGLE_ID,FTL_SAVE_APP_SINGLE_ID_ADDR,FTL_SAVE_APP_SINGLE_ID_SIZE); + } +} + +/* Pairing advertisement data (max size = 31 bytes, though this is + best kept short to conserve power while advertisting) */ +static uint8_t cust_adv_data[31] = +{ + /* Flags */ + 0x02, /* length */ + GAP_ADTYPE_FLAGS, /* type="Flags" */ + GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, + + /* Service */ + 0x03, /* length */ + GAP_ADTYPE_16BIT_MORE, /* type="More 16-bit UUIDs available" */ + 0x03,0x18, + + 0x0a, + GAP_ADTYPE_SERVICE_DATA, + 0x0A,0x18, + FW_VERSION_REVISION_NUMBER,0x01, + 0x01,0x01,0x00,0x01,0x01, + + + /* Local name */ + 0x06, /* length */ + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'S', 'D','D','-','2' + +}; + +/** @brief GAP - scan response data (max size = 31 bytes) */ +static uint8_t cust_scan_rsp_data[31] = +{ + 0x03, /* length */ + GAP_ADTYPE_APPEARANCE, /* type="Appearance" */ + LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN), + HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN), + + 0x0a, + GAP_ADTYPE_SERVICE_DATA, + // AES128-ECBܽ (ֱʹ) + 0x0A,0x18, + FW_VERSION_REVISION_NUMBER,0x01, + // Ԥ16ֽڿռڴ洢̬ɵAES + 0x01, 0x01, 0x00, 0x01, 0x01, + + /* Local name */ + 0x06, /* length */ + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'S', 'D','D','-','2' + + +#if CUST_HID_SERVICE + 0x03, /* length */ + 0x19, /* type="Appearance" */ + 0xc1, 0x03, /* Keyboard */ +#endif +#if CUST_HID_SERVICE + /* Service */ + 0x03, /* length */ + 0x03, /* type="More 16-bit UUIDs available" */ + 0x12, 0x18, /* HID Service */ +#endif +// /* Service */ +// 0x03, /* length */ +// 0x03, /* type="More 16-bit UUIDs available" */ +// 0x03, 0x18, +// +// 0x03,0x03,0x02,0x18, +// 0x03,0x03,0x04,0x18, +// 0x03,0x03,0x0F,0x18, + + +}; + +//洢flashеSINGLE_IDȡcust_adv_datacust_scan_rsp_data +void read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data(void) +{ + //flashеSINGLE_IDREAD_SINGLE_ID + ftl_load(READ_SINGLE_ID,FTL_SAVE_APP_SINGLE_ID_ADDR,FTL_SAVE_APP_SINGLE_ID_SIZE); + + //READ_SINGLE_IDеmecopyecust_adv_datacust_scan_rsp_data + memcpy(&cust_adv_data[12],READ_SINGLE_ID,6); + memcpy(&cust_scan_rsp_data[9],READ_SINGLE_ID,6); + for(int i = 0; i<=31; i++){ + + APP_PRINT_INFO1("cust_adv_data------------------------------------------>%d", cust_adv_data[i]); + + } + + APP_PRINT_INFO0("-------------------------------------------------------------------->"); + + for(int i = 0; i<=31; i++){ + + APP_PRINT_INFO1("cust_scan_rsp_data------------------------------------------>%d", cust_scan_rsp_data[i]); + + } + +} + +/** + * @brief Reset data copy flag + */ +void reset_data_copy_flag(void) +{ + APP_PRINT_INFO0("Data copy flag reset"); +} + +/*============================================================================* + * Local Functions + *============================================================================*/ +static void cust_adv_update_timer_callback(void *p_timer) +{ + uint8_t cust_bt_addr[GAP_BD_ADDR_LEN]; +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (!custom_data.cust_paired) + { + return; + } +#endif + le_gen_rand_addr(GAP_RAND_ADDR_RESOLVABLE, cust_bt_addr); + + one_shot_bt_addr_set(cust_bt_addr, GAP_LOCAL_ADDR_LE_RANDOM, ADV_DATA_CUSTOMIZED); + APP_PRINT_INFO1("cust_adv_update_timer_callback: addr %s", TRACE_BDADDR(cust_bt_addr)); + + + +} + +static bool cust_check_if_fmna_owner_device(uint8_t *remote_bd) +{ + bool ret = false; + if (fmna_connection_is_fmna_paired()) + { + T_LE_KEY_ENTRY *findmy_key_entry; + findmy_key_entry = le_find_key_entry_by_idx(app_global_data.app_bond_idx[FINDMY_BOND]); + uint8_t findmy_irk[16]; + ret = le_get_dev_irk(findmy_key_entry, true, findmy_irk); + if (!ret) + { + APP_PRINT_WARN0("le_get_dev_irk failed"); + return ret; + } + ret = le_privacy_check_resolvable_private_address(remote_bd, findmy_irk); + } + APP_PRINT_INFO1("cust_check_if_fmna_owner_device ret=%d", ret); + return ret; +} + +/*============================================================================* + * Global Functions + *============================================================================*/ +void cust_adv_init(bool force_pairing) +{ + custom_data.cust_adv.p_adv_data = cust_adv_data; + custom_data.cust_adv.adv_data_len = sizeof(cust_adv_data); + custom_data.cust_adv.p_scan_rsp_data = cust_scan_rsp_data; + custom_data.cust_adv.scan_rsp_data_len = sizeof(cust_scan_rsp_data); + custom_data.cust_adv.adv_type = GAP_ADTYPE_ADV_IND; + custom_data.cust_adv.adv_interval = 320; + +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (!custom_data.cust_paired || force_pairing) + { + memcpy(custom_data.identity_address, app_global_data.mac_address, 6); + one_shot_bt_addr_set(custom_data.identity_address, GAP_LOCAL_ADDR_LE_PUBLIC, ADV_DATA_CUSTOMIZED); + APP_PRINT_INFO1("cust_adv_init identity addr %s", TRACE_BDADDR(custom_data.identity_address)); + } + else +#endif + { + uint8_t cust_bt_addr[GAP_BD_ADDR_LEN]; + le_gen_rand_addr(GAP_RAND_ADDR_RESOLVABLE, cust_bt_addr); + one_shot_bt_addr_set(cust_bt_addr, GAP_LOCAL_ADDR_LE_RANDOM, ADV_DATA_CUSTOMIZED); + APP_PRINT_INFO1("cust_adv_init RPA %s", TRACE_BDADDR(cust_bt_addr)); + + } + + + if (custom_data.cust_addr_update_timer == NULL) + { + /* customized advertising address should rotating every 15 minutes */ + if (false == os_timer_create(&custom_data.cust_addr_update_timer, "cust_addr_update_timer", 1, \ + 15 * 60000, true, cust_adv_update_timer_callback)) + { + APP_PRINT_INFO0("[cust_adv_init] init cust_addr_update_timer failed"); + } + } +} + +void cust_data_init(void) +{ + memset(&custom_data, 0, sizeof(custom_data)); + custom_data.cust_conn_id = 0xFF; + + // ڳʼʱFlashȡ֮ǰIDREAD_SINGLE_ID + ftl_load(READ_SINGLE_ID, FTL_SAVE_APP_SINGLE_ID_ADDR, FTL_SAVE_APP_SINGLE_ID_SIZE); + + // FlashID临ƵSINGLE_ID + if(READ_SINGLE_ID[0] != 0 || READ_SINGLE_ID[1] != 0 || READ_SINGLE_ID[2] != 0 || + READ_SINGLE_ID[3] != 0 || READ_SINGLE_ID[4] != 0 || READ_SINGLE_ID[5] != 0){ + memcpy(SINGLE_ID, READ_SINGLE_ID, 6); + APP_PRINT_INFO0("Loaded existing ID from Flash"); + } + +} + +void cust_factory_reset(void) +{ + APP_PRINT_INFO0("CUST factory reset"); + + // ݿ־λ + reset_data_copy_flag(); + +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (app_global_data.app_bond_idx[CUST_BOND_1] != 0xFF) + { + T_GAP_CAUSE ret = le_bond_delete_by_idx(app_global_data.app_bond_idx[CUST_BOND_1]); + APP_PRINT_INFO2("CUST delete CUST_BOND_1 idx=%#x ret=%d", app_global_data.app_bond_idx[CUST_BOND_1], + ret); + } + if (app_global_data.app_bond_idx[CUST_BOND_2] != 0xFF) + { + T_GAP_CAUSE ret = le_bond_delete_by_idx(app_global_data.app_bond_idx[CUST_BOND_2]); + APP_PRINT_INFO2("CUST delete CUST_BOND_2 idx=%#x ret=%d", app_global_data.app_bond_idx[CUST_BOND_2], + ret); + } +#endif + cust_feature_disable(); +} + +void cust_handle_connected_evt(uint8_t conn_id, uint8_t *remote_bd) +{ + APP_PRINT_INFO1("custom app connected conn_id=%d", conn_id); + cust_adv_stop(); + custom_data.cust_conn_id = conn_id; + + bool ret = cust_check_if_fmna_owner_device(remote_bd); + if (ret) + { + cust_adv_update_device_name(false); + + } +} + +bool cust_handle_disconnected_evt(uint8_t conn_id, uint16_t disc_cause) +{ + if (custom_data.cust_conn_id == conn_id) + { + APP_PRINT_INFO1("custom app disconnected conn_id=%d", conn_id); + custom_data.cust_conn_id = 0xFF; + if (disc_cause == (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)) + { +#if SUPPORT_DYNAMIC_SERVICE + cust_connection_disconnect_gatt_handler(); +#endif + } + else + { + if (fmna_connection_is_fmna_paired()) + { + cust_adv_update_device_name(true); + + } + cust_adv_start(); + } + return true; + } + else + { + return false; + } +} + +#if (CUST_APP_TYPE == CUST_APP_PAIRED) +void cust_set_paired_flag(bool flag) +{ + custom_data.cust_paired = flag; +} + +bool cust_is_paired(void) +{ + return custom_data.cust_paired; +} +#endif + +bool cust_feature_is_enabled(void) +{ + return custom_data.cust_enable; +} + +void cust_feature_enable(void) +{ + custom_data.cust_enable = true; + cust_adv_init(false); + APP_PRINT_INFO0("CUSTOM FEATURE ENABLED!"); + + for(int i = 0;i<=30;i++){ + + APP_PRINT_INFO1("--------------------------------------------------->%d",cust_adv_data[i]); + + } + + if (fmna_connection_is_fmna_paired()) + { + // set fmna connection link number to 1 + uint8_t fmna_valid_conn = 0; + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (fmna_connection_is_valid_connection(conn_handle)) + { + fmna_valid_conn = conn_handle; + APP_PRINT_INFO0("CUST APP set fmna max_connections to 1"); + fmna_connection_set_max_connections(1, fmna_valid_conn); + break; + } + } + cust_adv_update_device_name(true); + + } + else + { + cust_adv_update_device_name(false); + + } + + //start cust adv + if (!custom_data.cust_adv_enable && custom_data.cust_conn_id == 0xFF) + { + cust_adv_start(); + } + os_timer_start(&custom_data.cust_addr_update_timer); +} + +// Ͽӵĺ +void cust_connection_disconnect_this(void) +{ + if (custom_data.cust_conn_id != 0xFF) + { + le_disconnect(custom_data.cust_conn_id); + custom_data.cust_conn_id = 0xFF; + cust_adv_update_device_name(false); + cust_adv_start(); + + } +} + +void cust_feature_disable(void) +{ + custom_data.cust_enable = false; + APP_PRINT_INFO0("CUSTOM FEATURE DISABLED!"); + + if (custom_data.cust_adv_enable) + { + cust_adv_stop(); + } + + if (custom_data.cust_conn_id != 0xFF) + { + le_disconnect(custom_data.cust_conn_id); + } + + if (fmna_connection_is_fmna_paired()) + { + // set fmna connection link number to 2 + uint8_t fmna_valid_conn = 0; + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (fmna_connection_is_valid_connection(conn_handle)) + { + fmna_valid_conn = conn_handle; + break; + } + } + APP_PRINT_INFO0("CUST APP set fmna max_connections to 2"); + fmna_connection_set_max_connections(2, fmna_valid_conn); + } + os_timer_stop(&custom_data.cust_addr_update_timer); +} + +extern uint8_t find_my_loacl_apple_mac[6]; +extern uint8_t find_my_sdd_apple_mac[6]; + +//һ͵ıжfind_my_loacl_apple_macfind_my_sdd_apple_macǷ +bool mac_is_same = true; + +void cust_adv_update_device_name(bool suffix) +{ + APP_PRINT_INFO1("cust_adv_update_device_name suffix=%d", suffix); + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + uint16_t error_line = 0; + uint8_t device_name[12] = {0}; //The device name is limited to 14 characters total. + uint8_t device_name_len = 0; + + // ÿαȽǰmac_is_sameΪtrue + mac_is_same = true; + + //жfind_my_loacl_apple_macfind_my_sdd_apple_macǷ + for(int i = 0;i<6;i++){ + + if(find_my_loacl_apple_mac[i]!=find_my_sdd_apple_mac[i]){ + + mac_is_same = false; + + } + + } + + if (suffix) + { + + if(mac_is_same==false){ + + memcpy(device_name, "SDD-2 FindMy", 12); + device_name_len = 12; + + }else{ + + memcpy(device_name, "SDD-2", 5); + device_name_len = 5; + + } + } + else + { + + if(mac_is_same==false){ + + memcpy(device_name, "SDD-2 FindMy", 12); + device_name_len = 12; + + }else{ + + memcpy(device_name, "SDD-2", 5); + device_name_len = 5; + + } + + } + + ret = le_set_gap_param(GAP_PARAM_DEVICE_NAME, device_name_len, device_name); + __GAP_RET_CHECK(ret, fail); + APP_PRINT_INFO0("-------------------------------------------------------"); + + update_single_id(); + + //save_single_id_to_flash(void);ʵΨһIDĴ洢 + save_single_id_to_flash(); + + read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data(); + + cust_scan_rsp_data[CUST_ADV_NAME_OFFSET] = device_name_len + 1; + custom_data.cust_adv.adv_data_len = device_name_len + 2 + CUST_ADV_NAME_OFFSET; + memcpy(cust_scan_rsp_data + 2 + CUST_ADV_NAME_OFFSET, device_name, device_name_len); + + + ret = fmble_gap_adv_data_set(custom_data.cust_adv, ADV_DATA_CUSTOMIZED); + __GAP_RET_CHECK(ret, fail); + +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + } +} + +bool cust_adv_is_enabled(void) +{ + return custom_data.cust_adv_enable; +} + +uint8_t cust_get_conn_id(void) +{ + return custom_data.cust_conn_id; +} + +void cust_adv_start(void) +{ + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + uint16_t error_line = 0; + + ret = fmble_gap_adv_start(ADV_DATA_CUSTOMIZED); + __GAP_RET_CHECK(ret, fail); + custom_data.cust_adv_enable = true; + return; +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + } +} + +void cust_adv_stop(void) +{ + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + uint16_t error_line = 0; + ret = fmble_gap_adv_stop(ADV_DATA_CUSTOMIZED); + __GAP_RET_CHECK(ret, fail); + custom_data.cust_adv_enable = false; + return; +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + } +} + +bool cust_ble_set_to_idle(void) +{ + bool ret = false; + + if (custom_data.cust_adv_enable) + { + APP_PRINT_INFO0("cust_ble_set_to_idle: ADV pending"); + custom_data.cust_pending = true; + cust_adv_stop(); + } + + if (custom_data.cust_conn_id != 0xFF) + { + APP_PRINT_INFO0("cust_ble_set_to_idle: disconnect pending"); + custom_data.cust_pending = true; + le_disconnect(custom_data.cust_conn_id); + ret = true; //the dynamic service changing need to pending + } + + return ret; +} + +void cust_resume_pending_ble_oprations(void) +{ + if (custom_data.cust_pending) + { + APP_PRINT_INFO0("cust_resume_pending_ble_oprations"); + custom_data.cust_pending = false; + cust_adv_start(); + } +} + +#endif diff --git a/src/app/findmy/custom_app.h b/src/app/findmy/custom_app.h new file mode 100644 index 0000000..4f2501f --- /dev/null +++ b/src/app/findmy/custom_app.h @@ -0,0 +1,198 @@ +/** +***************************************************************************************** +* Copyright(c) 2025, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file custom_app.h + * @brief This file handles Find My application routines. + * @author scarlett + * @date 2025-04-10 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2025 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +#ifndef _CUSTOM_APP__ +#define _CUSTOM_APP__ + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include "fmna_gap_platform.h" + +#if SUPPORT_CUSTOMIZED_APP +/*============================================================================* + * Types + *============================================================================*/ +typedef struct +{ + bool cust_enable; //customized function is enabled + bool cust_adv_enable; //customized advertising is enabled + bool cust_pending; //customized advertising or connection is pending + bool cust_paired; + uint8_t cust_conn_id; + uint8_t identity_address[6]; + T_ADV_DATA cust_adv; + void *cust_addr_update_timer; +} T_CUSTOM_DATA; + +/*============================================================================* + * Variables + *============================================================================*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @brief Initialize custom advertising parameters + * @param force_pairing If true, forces pairing mode during initialization + */ +void cust_adv_init(bool force_pairing); + +/** + * @brief Initialize custom data structures and variables + * @note Typically called during system initialization + */ +void cust_data_init(void); + +/** + * @brief Perform factory reset operations + * @note Clears all persistent configuration and resets to default state + */ +void cust_factory_reset(void); + +/** + * @brief Handle BLE connection established event + * @param conn_id Connection identifier + * @param remote_bd Pointer to remote device's Bluetooth address (6 bytes) + */ +void cust_handle_connected_evt(uint8_t conn_id, uint8_t *remote_bd); + +/** + * @brief Handle BLE disconnection event + * @param conn_id Connection identifier + * @param disc_cause Disconnection reason code + * @return true if disconnection was expected/normal, false if abnormal + */ +bool cust_handle_disconnected_evt(uint8_t conn_id, uint16_t disc_cause); + +#if (CUST_APP_TYPE == CUST_APP_PAIRED) +/** + * @brief Set paired status flag + * @param flag true if paired, false if unpaired + */ +void cust_set_paired_flag(bool flag); + +/** + * @brief Check if device is paired + * @return true if paired, false otherwise + */ +bool cust_is_paired(void); +#endif + +/** + * @brief Initialize custom version GATT service + * @note Adds a custom GATT service to expose firmware version information + * to external applications + */ +void cust_version_service_init(void); + +/** + * @brief Check if custom feature is enabled + * @return true if feature is enabled, false otherwise + */ +bool cust_feature_is_enabled(void); + +/** + * @brief Enable the custom feature + */ +void cust_feature_enable(void); + +/** + * @brief Disable the custom feature + */ +void cust_feature_disable(void); + +/** + * @brief Update advertising data with device name + * @param suffix If true, adds additional suffix to the name + */ +void cust_adv_update_device_name(bool suffix); + +/** + * @brief Check if advertising is currently active + * @return true if advertising is enabled, false otherwise + */ +bool cust_adv_is_enabled(void); + +/** + * @brief Get current connection ID + * @return Active connection ID or 0xFF if no connection + */ +uint8_t cust_get_conn_id(void); + +/** + * @brief Start BLE advertising + */ +void cust_adv_start(void); + +/** + * @brief Stop BLE advertising + */ +void cust_adv_stop(void); + +/** + * @brief Set BLE stack to idle state + * @return true if successful, false if operation failed + */ +bool cust_ble_set_to_idle(void); + +/** + * @brief Resume pending BLE operations after callback + */ +void cust_resume_pending_ble_oprations(void); + +/** + * @brief Generate a six-digit random number using A-Z and 0-9. + */ +void generate_random_data(uint8_t *data, uint16_t len); + +/** + * @brief Store the generated six-digit data in SINGLE_ID. + */ +void update_single_id(void); + +/** + * @brief Store the generated SINGLE_ID in the Flash. + */ +void save_single_id_to_flash(void); + +/** + * @brief Read the SINGLE_ID stored in the flash and place it in the cust_adv_data and cust_scan_rsp_data. + */ +void read_single_id_copy_to_cust_adv_data_and_cust_scan_rsp_data(void); + +void cust_connection_disconnect_this(void); + +void password_verification_timeout(TimerHandle_t p_timer); + +/** + * @brief Reset data copy flag + */ +void reset_data_copy_flag(void); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/findmy_app.c b/src/app/findmy/findmy_app.c new file mode 100644 index 0000000..a9033ca --- /dev/null +++ b/src/app/findmy/findmy_app.c @@ -0,0 +1,1572 @@ +/** +***************************************************************************************** +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file findmy_app.c + * @brief This file handles findmy application routines. + * @author scarlett + * @date 2022-09-01 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2022 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfu_flash.h" +#include "otp_config.h" +#include "sdd_service.h" +#include "os_sched.h" +#include "os_timer.h" +#include "fmna_platform_includes.h" +#include "fmna_gatt_platform.h" +#include "key_handle.h" +#include "fmna_connection_platform.h" +#include "serial_number_send.h" + +#include "fmna_gatt_platform.h" +#include "fmna_version.h" + +#include "aes.h" + +#include "custom_app.h" + +#if (AON_WDG_ENABLE == 1) +#include "rtl876x_aon_wdg.h" +#endif +#if GFPS_FEATURE_SUPPORT +#include "gfps.h" +#include "app_gfps.h" +#include "app_dult.h" +#include "app_gfps_finder.h" +#include "app_gfps_finder_adv.h" +#endif +#if (CUST_APP_TYPE == CUST_APP_PAIRED) +#include "gap_privacy.h" +#endif + +/** @defgroup FINDMY_APP Application + * @brief This file handles findmy application routines. + * @{ + */ +/*============================================================================* + * Variables + *============================================================================*/ +T_APP_GLOBAL_DATA app_global_data; + +#define PASSWORD_LENGTH 6 + +// ӱҪⲿfmna_gatt_platform.cеȫֱ +extern uint8_t password[PASSWORD_LENGTH]; +//static uint8_t m_pwd[8]; +bool password_received; +extern bool password_correct; +extern T_CUSTOM_DATA custom_data; + +static int press_down = 0; +static uint32_t last_press_time = 0; +static uint32_t time_diff = 0; +extern T_CUSTOM_DATA custom_data; +bool broadcast_stop = true; + +//жǷ״̬ +bool is_enable = false; + +static uint8_t m_serial_number[SERIAL_NUMBER_RAW_BLEN]; + +//static void *button_periodic_timer; +extern TimerHandle_t double_click_detect_timer; + + +//ʱ +extern TimerHandle_t disconnection_click_timer; + +//һ͵ֵڼ¼ҡķǷ +bool find_my_in_local_apple = false; + +//һ͵ֵڼ¼SDDAPPķǷ +bool find_my_in_sdd_apple = false; + +//һڴ洢""ʱԶ豸Macַ +uint8_t find_my_loacl_apple_mac[6] = {0}; + +//һڴ洢SDDʱԶ豸ĵMacַ +uint8_t find_my_sdd_apple_mac[6] = {0}; + +#define CLICK_INTERVAL_TIMEOUT 600 +#define SINGLE_CLICK 1 +#define DOUBLE_CLICK 2 +#define FOUR_CLICK 4 +#define TEN_CLICK 10 + +/** + * @brief double_click_detect_timer + * @note + * @param[in] p_timer + * @return void + */ +/** + * @brief + * @param[in] duration + */ +static void play_beep(uint32_t duration) +{ + + play_beep_mode(300, BEEP_MODE_SINGLE); + +} + + +/** + * @brief + */ +static void handle_single_click(void) +{ + APP_PRINT_INFO0("Single click detected"); + APP_PRINT_INFO0("------------------------------------------>1"); + + if (is_enable == false){ + + APP_PRINT_INFO0("PRESS 1 SECOND:App finder start "); + + cust_feature_enable(); + + cust_adv_init(true); + + broadcast_stop = false; + + APP_PRINT_INFO0("PRESS 1 SECOND:App finder start ------------------------------------------------>RESET SUCCESSFULLY RETURN 1"); + + os_timer_start(&disconnection_click_timer); + + play_beep(300); + + is_enable = true; + + find_my_in_sdd_apple = true; + + }else{ + + play_beep(300); + + } + + + +} + +/** + * @brief + */ +static void handle_double_click(void) +{ + APP_PRINT_INFO0("Double click detected"); + APP_PRINT_INFO0("------------------------------------------>2"); + + uint8_t conn_id = cust_get_conn_id(); + T_GATT_DATA p_fmna_gatt_data = fmna_gatt_platform_get_gatt_data(); + uint8_t send_data = 1; + + for(int i = 1;i<=2; i++){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id, p_fmna_gatt_data.sdd_srv_id, send_data); + + } + + + play_beep_mode(300, BEEP_MODE_DOUBLE); + +} + +/** + * @brief + */ +static void handle_four_click(void) +{ + APP_PRINT_INFO0("Four clicks detected"); + APP_PRINT_INFO0("------------------------------------------>4"); + uint8_t conn_id = cust_get_conn_id(); + T_GATT_DATA p_fmna_gatt_data = fmna_gatt_platform_get_gatt_data(); + + uint8_t SN = fmna_connection_platform_get_serial_number(m_serial_number, SERIAL_NUMBER_RAW_BLEN); + + + sdd_send_array_value(custom_data.cust_conn_id, p_fmna_gatt_data.sdd_srv_id, m_serial_number, SERIAL_NUMBER_RAW_BLEN); + + + custom_new_adv_init(); + + + custom_new_adv_start(); + + + set_serial_number_to_adv(m_serial_number, SERIAL_NUMBER_RAW_BLEN); + + APP_PRINT_INFO1("------------------------------------------>%s",TRACE_STRING(m_serial_number)); + + APP_PRINT_INFO0("------------------------------------------>SUCCESSFUL"); + +} + +/** + * @brief + */ +// ⲿpasswordر +static void handle_ten_click(void) +{ + APP_PRINT_INFO0("Ten clicks detected"); + APP_PRINT_INFO0("------------------------------------------>10"); + uint8_t conn_id = cust_get_conn_id(); + T_GATT_DATA p_fmna_gatt_data = fmna_gatt_platform_get_gatt_data(); + + uint8_t send_data = 4; + sdd_battery_level_value_notify(custom_data.cust_conn_id, p_fmna_gatt_data.sdd_srv_id, send_data); + + broadcast_stop = true; + + custom_new_adv_stop(); + + play_beep_mode(300, BEEP_MODE_TRIPLE); + + password_correct = false; + + is_enable = false; + + cust_factory_reset(); +} + +/** + * @brief double_click_detect_timer + * @note + * @param[in] p_timer + * @return void + */ +void double_click_detect_timer_cb(TimerHandle_t p_timer) +{ + + + if (fmna_sound_is_playing()) + { + APP_PRINT_INFO0("Beep is still playing during click detection"); + } + + + switch(press_down) { + case SINGLE_CLICK: + handle_single_click(); + break; + case DOUBLE_CLICK: + handle_double_click(); + break; + case FOUR_CLICK: + handle_four_click(); + break; + case TEN_CLICK: + handle_ten_click(); + break; + default: + if (press_down > 0) { + APP_PRINT_INFO1("%d clicks detected, no specific action defined", press_down); + } + break; + } + + + press_down = 0; +} + + + + +/*============================================================================* + * Functions Declaration + *============================================================================*/ +void app_handle_gap_msg(T_IO_MSG *p_gap_msg); +void app_handle_gpio_msg(T_IO_MSG *p_gpio_msg); + +/** + * @brief Perform a factory reset operation for the FMNA module + * @note This function will clear all user configurations and restore + * the device to its original factory default settings. + * @return void + */ +void fmna_factory_reset(void) +{ + + APP_PRINT_INFO0("PRESS 10 SECOND: reset fmna------------------------------------------------>RESET SUCCESSFULLY RETURN 1"); + fmna_connection_set_is_fmna_paired(false); + os_delay(200); + DBG_DIRECT("FMNA factory reset"); + WDG_SystemReset(RESET_ALL_EXCEPT_AON, SW_RESET_APP_START); +} + +/** + * @brief Disables the FMNA module functionality + * @note After calling this function, the FMNA module will cease all activities + * and will not respond to any commands or events until re-enabled. + * @return void + */ +static void fmna_disable_handler(void) +{ + DBG_DIRECT("disable find my feature"); + WDG_SystemReset(RESET_ALL_EXCEPT_AON, RESET_REASON_POWERDOWN); +} + +/** + * @brief Restore bond information for both FMNA and custom profiles + * @note This function retrieves and restores previously bonded device + * information from non-volatile memory for both FMNA and custom + * profiles to re-establish connections without requiring re-pairing. + * @return void + */ +void app_bond_info_restore(void) +{ + uint8_t bond_idx_buffer[FTL_SAVE_BOND_IDX_SIZE]; + if (!ftl_load(bond_idx_buffer, FTL_SAVE_BOND_IDX_ADDR, FTL_SAVE_BOND_IDX_SIZE)) + { + memcpy(app_global_data.app_bond_idx, bond_idx_buffer, BLE_BOND_NUM); + APP_PRINT_INFO1("FINDMY_APP restore bond_idx=%#x", app_global_data.app_bond_idx[FINDMY_BOND]); +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + APP_PRINT_INFO2("CUSTOMIZED_APP restore bond_idx1=%#x bond_idx2=%#x", + app_global_data.app_bond_idx[CUST_BOND_1], app_global_data.app_bond_idx[CUST_BOND_2]); + if (app_global_data.app_bond_idx[CUST_BOND_1] != 0xFF || + app_global_data.app_bond_idx[CUST_BOND_2] != 0xFF) + { + cust_set_paired_flag(true); + } +#endif + } + else + { + app_global_data.app_bond_idx[FINDMY_BOND] = 0xFF; +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + app_global_data.app_bond_idx[CUST_BOND_1] = 0xFF; + app_global_data.app_bond_idx[CUST_BOND_2] = 0xFF; +#endif + APP_PRINT_WARN0("FTL load app_global_data.app_bond_idx failed!"); + } +} + +/** + * @brief All the application messages are pre-handled in this function + * @note All the IO MSGs are sent to this function, then the event handling + * function shall be called according to the MSG type. + * @param[in] io_msg IO message data + * @return void + */ +void app_handle_io_msg(T_IO_MSG io_msg) +{ + uint16_t msg_type = io_msg.type; + + switch (msg_type) + { + case IO_MSG_TYPE_BT_STATUS: + { + app_handle_gap_msg(&io_msg); + } + break; + case IO_MSG_TYPE_GPIO: + { + app_handle_gpio_msg(&io_msg); + } + break; +#ifdef USE_UARP + case IO_MSG_TYPE_DFU_VALID_FW: + { + os_delay(500); + fmna_connection_disconnect_all(); + dfu_fw_reboot(true); + } + break; +#endif +#if ONE_SHOT_ADV_EN + case IO_MSG_TYPE_ADV: + { + one_shot_adv_set_param((T_ADV_DATA_TYPE)io_msg.subtype); + } + break; +#endif + case IO_MSG_TYPE_ADV_TIMEOUT: + { + if (fmna_connection_is_fmna_paired()) + { + APP_PRINT_INFO0("FMNA fast adv timeout"); + fmna_adv_platform_stop_adv(); + } +#if GFPS_FEATURE_SUPPORT + else if (app_global_data.gfps_enable || app_global_data.fmna_enable) + { + // fmna & gfps pairing adv timeout + app_global_data.fmna_enable = false; + fmna_adv_platform_stop_adv(); + app_global_data.gfps_enable = false; + app_gfps_next_action(GFPS_ACTION_IDLE); + } +#endif + } + break; + case IO_MSG_TYPE_OTHERS: + { + T_APP_SCHED_EVT_STUCT *evt = (T_APP_SCHED_EVT_STUCT *)io_msg.u.param; + if (evt->handler != NULL) + { + evt->handler(evt->p_event_data, evt->event_size); + } + else + { + APP_PRINT_ERROR0("[FMNA] sched null handler"); + } + os_mem_free(evt->p_event_data); + os_mem_free(evt); + } + break; + case IO_MSG_TYPE_FMNA: + { + fmna_state_machine_handle_msg(io_msg); + } + break; + case IO_MSG_TYPE_TIMER: + { + crypto_enter_dlps_config(); + } + break; +#if (SUPPORT_BAT_DETECT_FEATURE && GFPS_FEATURE_SUPPORT) + case IO_MSG_TYPE_ADC: + { + bat_update_battery_info(); + } + break; +#endif +#if (ROM_WATCH_DOG_ENABLE == 1) + case IO_MSG_TYPE_RESET_WDG_TIMER: + { + APP_PRINT_INFO0("[WDG] Watch Dog Rset Timer"); + WDG_Restart(); + } + break; +#endif +#if (AON_WDG_ENABLE == 1) + case IO_MSG_TYPE_RESET_AON_WDG_TIMER: + { + uint8_t conn_id = cust_get_conn_id(); + T_GATT_DATA p_fmna_gatt_data = fmna_gatt_platform_get_gatt_data(); + if(broadcast_stop == false){ + extern uint8_t sdd_rssi_level; + // 첽ȡRSSIֵͨGAP_MSG_LE_READ_RSSIص + le_read_rssi(conn_id); + + AON_WDG_Restart(); + + }else{ + APP_PRINT_INFO0("[WDG] AON Watch Dog Rset Timer"); + AON_WDG_Restart(); + } + } + break; +#endif +#if GFPS_FEATURE_SUPPORT + case IO_MSG_TYPE_GFPS: + { + app_gfps_msg_handler(io_msg.subtype); + } + break; +#endif + case ADV_DATA_CUSTOM_NEW: + { + one_shot_adv_set_param(ADV_DATA_CUSTOM_NEW); + } + break; + + default: + break; + } +} + +/** + * @brief Initialize global application data structures + * @note This function initializes all global variables and data structures + * used throughout the application to their default values during + * system startup or reset. + * @return void + */ +void app_global_data_init(void) +{ + memset(&app_global_data, 0, sizeof(app_global_data)); + for (uint8_t i = 0; i < BLE_BOND_NUM; i++) + { + app_global_data.app_bond_idx[i] = 0xFF; + } + +#if SUPPORT_CUSTOMIZED_APP + cust_data_init(); +#endif + + gap_get_param(GAP_PARAM_BD_ADDR, app_global_data.mac_address); + APP_PRINT_INFO1("app_global_data_init MAC address: %s", TRACE_BDADDR(app_global_data.mac_address)); +} + +#if IS_PRINT_REMAINING_RAM_SIZE +/****************************************************************** + * @fn app_print_remaining_ram_size + * @brief Print the remaining ram size. + * + * @param void + * @return none + * @retval void + */ +static void app_print_remaining_ram_size(void) +{ + uint32_t data_ram_size = 0, buffer_ram_size = 0; + data_ram_size = os_mem_peek(RAM_TYPE_DATA_ON);//the remainig data ram size + buffer_ram_size = os_mem_peek(RAM_TYPE_BUFFER_ON);//the remainig buffer ram size + APP_PRINT_INFO2("[app_print_remaining_ram_size] data_ram_size = %d, buffer_ram_size = %d", + data_ram_size, buffer_ram_size); +} +#endif + +/** + * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE + * @note All the gap device state events are pre-handled in this function. + * Then the event handling function shall be called according to the new_state + * @param[in] new_state New gap device state + * @param[in] cause GAP device state change cause + * @return void + */ +void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) +{ + APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x", + new_state.gap_init_state, new_state.gap_adv_state, cause); + if (app_global_data.gap_dev_state.gap_init_state != new_state.gap_init_state) + { + if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + /*stack ready*/ + APP_PRINT_INFO0("GAP stack ready"); +#if IS_PRINT_REMAINING_RAM_SIZE + app_print_remaining_ram_size(); +#endif + le_adv_read_tx_power(); +#if SUPPORT_BAT_DETECT_FEATURE + /* update battery after stack ready */ + bat_update_battery_info(); + + if(app_global_data.reset_reason == RESET_REASON_HW){ + + if (is_enable == false){ + + APP_PRINT_INFO0("App finder start "); + + cust_feature_enable(); + + cust_adv_init(true); + + broadcast_stop = false; + + APP_PRINT_INFO0("App finder start ------------------------------------------------>THIS IS A POWER OUTAGE RECONNECTION."); + + is_enable = true; + + find_my_in_sdd_apple = true; + + os_timer_start(&disconnection_click_timer); + + } + + } +#endif + + if (app_global_data.reset_reason == RESET_REASON_POWERDOWN) + { + + if (!fmna_connection_is_fmna_paired()) + { + APP_PRINT_INFO0("FMNA remains in boot state"); + fmna_state_machine_init(); + } + } + else //reset reason is not disable + { + fmna_state_machine_init(); +#if GFPS_FEATURE_SUPPORT + app_handle_gfps_power_on(); +#endif + } + +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (cust_is_paired()) + { + cust_feature_enable(); + } +#endif + } + } + + if (app_global_data.gap_dev_state.gap_adv_state != new_state.gap_adv_state) + { +#if (!ONE_SHOT_ADV_EN) + fmble_gap_dev_state_change(new_state); +#endif + if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE + && new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN) + { + APP_PRINT_INFO0("GAP adv stoped: because connection created"); + } + } + + app_global_data.gap_dev_state = new_state; +} + +/** + * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE + * @note All the gap conn state events are pre-handled in this function. + * Then the event handling function shall be called according to the new_state + * @param[in] conn_id Connection ID + * @param[in] new_state New gap connection state + * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED + * @return void + */ +void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) +{ + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, app_global_data.gap_conn_state[conn_id], new_state, disc_cause); + app_global_data.gap_conn_state[conn_id] = new_state; + + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE)) + && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + if (fmna_handle_ble_evt(FMNA_DISCONNECTED, conn_id)) + { + return; + } +#if SUPPORT_CUSTOMIZED_APP + if (cust_handle_disconnected_evt(conn_id, disc_cause)) + { + return; + } +#endif +#if GFPS_FEATURE_SUPPORT + T_GFPS_CB cb_data = {.cb_type = GFPS_CB_DISCONNECTION, .conn_id = conn_id}; + if (app_gfps_ble_evt_callback(cb_data)) + { + return; + } +#endif + APP_PRINT_ERROR0("GAP_CONN_STATE_DISCONNECTED: conn_id don't match any app"); + } + break; + + case GAP_CONN_STATE_CONNECTED: + { + uint16_t conn_interval; + uint16_t conn_latency; + uint16_t conn_supervision_timeout; + uint8_t remote_bd[6]; + uint8_t local_bd[6]; + T_GAP_REMOTE_ADDR_TYPE remote_bd_type; + T_GAP_LOCAL_ADDR_TYPE local_bd_type; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + le_get_conn_addr(conn_id, remote_bd, (uint8_t *)&remote_bd_type); + APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED: remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x", + TRACE_BDADDR(remote_bd), remote_bd_type, + conn_interval, conn_latency, conn_supervision_timeout); + + //ΪsddΪٵʱremote_bdеݴfind_my_loacl_apple_mac + if(find_my_in_local_apple == true && find_my_in_sdd_apple == false){ + + for(int i = 0; i<=5; i++){ + + find_my_loacl_apple_mac[i] = remote_bd[i]; + + } + APP_PRINT_INFO1("------------------------------------------>FINDER Phone's Mac Addr:%s",TRACE_BDADDR(find_my_loacl_apple_mac)); + //ΪsddΪʱremote_bdеݴfind_my_sdd_apple_mac + }else if(find_my_in_local_apple == true && find_my_in_sdd_apple == true){ + + for(int i = 0; i<=5; i++){ + + find_my_sdd_apple_mac[i] = remote_bd[i]; + + } + APP_PRINT_INFO1("------------------------------------------>SDD Phone's Mac Addr:%s",TRACE_BDADDR(find_my_sdd_apple_mac)); + } + + + uint16_t conn_handle = le_get_conn_handle(conn_id); + bool ret = le_get_conn_local_addr(conn_handle, local_bd, (uint8_t *)&local_bd_type); + if (!ret) + { + APP_PRINT_ERROR0("le_get_conn_local_addr failed!"); + return; + } + + T_ADV_DATA_TYPE conn_adv_type = ADV_DATA_TYPE_MAX; +#if ONE_SHOT_ADV_EN + for (uint8_t i = 0; i < ADV_DATA_TYPE_MAX; i++) + { + if (memcmp(one_shot_adv_data.adv_data[i].bd_addr, local_bd, 6) == 0) + { + conn_adv_type = (T_ADV_DATA_TYPE)i; + break; + } + } +#else + conn_adv_type = ADV_DATA_FINDMY; +#endif + APP_PRINT_INFO4("GAP_CONN_STATE_CONNECTED: conn_id=%d type=%d local_bd %s local_bd_type = %d", + conn_id, conn_adv_type, TRACE_BDADDR(local_bd), local_bd_type); + + switch (conn_adv_type) + { + case ADV_DATA_FINDMY: +#if ONE_SHOT_ADV_EN + fmble_gap_adv_stop(ADV_DATA_FINDMY); +#endif +#if GFPS_FEATURE_SUPPORT + if (app_global_data.gfps_enable) + { + app_global_data.gfps_enable = false; + app_gfps_next_action(GFPS_ACTION_IDLE); + } +#endif + fmna_handle_ble_evt(FMNA_CONNECTED, conn_id); + break; +#if SUPPORT_CUSTOMIZED_APP + case ADV_DATA_CUSTOMIZED: + cust_handle_connected_evt(conn_id, remote_bd); + break; +#endif +#if GFPS_FEATURE_SUPPORT + case ADV_DATA_GFPS: + case ADV_DATA_FINDER: + { +#if ONE_SHOT_ADV_EN + app_gfps_adv_stop(); + gfps_finder_adv_stop(); +#endif + if (app_global_data.fmna_enable) + { + app_global_data.fmna_enable = false; + fmble_gap_adv_stop(ADV_DATA_FINDMY); + } + T_GFPS_CB cb_data = {.cb_type = GFPS_CB_CONNECTION, .conn_id = conn_id}; + app_gfps_ble_evt_callback(cb_data); + } + break; +#endif + default: + break; + } + } + break; + + default: + break; + } +} + +/** + * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE + * @note All the gap authentication state events are pre-handled in this function. + * Then the event handling function shall be called according to the new_state + * @param[in] conn_id Connection ID + * @param[in] new_state New authentication state + * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE + * @return void + */ +void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause) +{ + APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause); + + switch (new_state) + { + case GAP_AUTHEN_STATE_STARTED: + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED"); + } + break; + + case GAP_AUTHEN_STATE_COMPLETE: + { + if (cause == GAP_SUCCESS) + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success"); + /* if findmy app bonded, set to high priority */ + if (app_global_data.app_bond_idx[FINDMY_BOND] != 0xFF) + { + T_LE_KEY_ENTRY *findmy_key_entry; + findmy_key_entry = le_find_key_entry_by_idx(app_global_data.app_bond_idx[FINDMY_BOND]); + le_set_high_priority_bond_v2(findmy_key_entry); + } + fmna_handle_ble_evt(FMNA_AUTHEN_SUCCESS, conn_id); + } + else + { + APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed"); + } + } + break; + + default: + { + APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state); + } + break; + } +} + +/** + * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO + * @note This msg is used to inform APP that exchange mtu procedure is completed. + * @param[in] conn_id Connection ID + * @param[in] mtu_size New mtu size + * @return void + */ +void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size) +{ + APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size); + if (fmna_connection_is_valid_connection(conn_id)) + { + m_gatt_mtu = mtu_size - GATT_HEADER_LEN; + } +} + +/** + * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE + * @note All the connection parameter update change events are pre-handled in this function. + * @param[in] conn_id Connection ID + * @param[in] status New update state + * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL + * @return void + */ +void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause) +{ + switch (status) + { + case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS: + { + uint16_t conn_interval; + uint16_t conn_slave_latency; + uint16_t conn_supervision_timeout; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x", + conn_interval, conn_slave_latency, conn_supervision_timeout); + + fmna_handle_ble_evt(FMNA_CONN_PARAM_UPDATE, conn_id); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_FAIL: + { + APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_PENDING: + { + APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending."); + } + break; + + default: + break; + } +} + +void password_verification_timeout(TimerHandle_t p_timer){ + + APP_PRINT_INFO0("Password verification timeout - disconnecting"); + + // Ƿȷ + if (!password_received || !password_correct) + { + APP_PRINT_INFO0("Password not received or incorrect - disconnecting"); + cust_connection_disconnect_this(); + + // ״̬ + password_received = false; + password_correct = false; + + } + else + { + APP_PRINT_INFO0("Password verified successfully - connection maintained"); + } + + // ֹͣʱ + os_timer_stop(&disconnection_click_timer); + +} + + +/** + * @brief All the GPIO MSG are pre-handled in this function. + * @note Then the event handling function shall be called according to the + * subtype of T_IO_MSG + * `@param[in] p_gap_msg Pointer to GPIO msg + * @return void + */ +void app_handle_gpio_msg(T_IO_MSG *p_gpio_msg) +{ + APP_PRINT_TRACE1("app_handle_gpio_msg: subtype %d", p_gpio_msg->subtype); + switch (p_gpio_msg->subtype) + { + case IO_MSG_GPIO_TRIG_LONG_PRESS_3S: + { + fmna_sound_platform_start(SOUND_EVENT_FMNA, 500, PWM_DEFAULT_FREQ); + os_delay(100); + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + if (app_global_data.fmna_enable) + { + APP_PRINT_INFO0("SHORT PRESS: already enabled fmna"); + return; + } +#if GFPS_FEATURE_SUPPORT + else if (app_global_data.gfps_enable) + { + app_gfps_handle_button_press(); + return; + } +#endif + /* Exit the FMNA disable state */ + if (fmna_connection_is_fmna_paired()) + { + fmna_state_machine_init(); + return; + } +#if GFPS_FEATURE_SUPPORT + /* Exit the GFPS disable state */ + else if (app_gfps_finder_provisoned()) + { + app_handle_gfps_power_on(); + return; + } +#endif + + /* enter the Find My network pairing mode */ + app_global_data.fmna_enable = true; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_PAIR); +#if GFPS_FEATURE_SUPPORT + /* enter the GFPS discoverable mode */ + app_global_data.gfps_enable = true; + app_gfps_next_action(GFPS_ACTION_ADV_DISCOVERABLE_MODE); +#endif + APP_PRINT_INFO0("PRESS 3 SECOND: already enabled fmna------------------------------------------------>SUCCESSFULLY ACTIVATED RETURN 1"); + + find_my_in_local_apple = true; + + } + break; + + case IO_MSG_GPIO_TRIG_LONG_PRESS_2S: + { + if (app_global_data.fmna_enable && serial_number_read_state == false \ + && fmna_connection_is_fmna_paired()) // FMNA is paired + { + serial_number_read_state_init(); + } +#if GFPS_FEATURE_SUPPORT + else if (app_global_data.gfps_enable && app_gfps_finder_provisoned()) + { + app_dult_set_identification_mode(true); + os_timer_start(&sn_lookup_timer); + } +#endif + else + { + APP_PRINT_WARN0("LONG PRESS 2S: GFPS FNH or Apple FMNA is not paired or enable"); + } + } + break; + + case IO_MSG_GPIO_TRIG_LONG_PRESS_5S: + { + if (app_global_data.fmna_enable +#if GFPS_FEATURE_SUPPORT + || app_global_data.gfps_enable +#endif + ) + { + fmna_disable_handler(); + } + else + { + APP_PRINT_WARN0("LONG PRESS 5S: GFPS FNH or Apple FMNA is not paired"); + } + } + break; + + case IO_MSG_GPIO_TRIG_LONG_PRESS_10S: + { + + if (fmna_connection_is_fmna_paired()) // FMNA is paired + { + + } + +#if GFPS_FEATURE_SUPPORT + else if (app_gfps_finder_provisoned()) + { + app_gfps_device_handle_factory_reset(); + } +#endif + else + { + APP_PRINT_WARN0("LONG PRESS 10S: GFPS FNH or Apple FMNA is not paired"); + } + } + break; + +#if SUPPORT_CUSTOMIZED_APP + case IO_MSG_GPIO_TRIG_LONG_PRESS_1S: + { + + } + break; + + case IO_MSG_GPIO_CUST_LONG_PRESS_2S: + { +// cust_adv_init(true); + } + break; + + case IO_MSG_GPIO_TRIG_SHORT_PRESS: + { + + time_diff = os_sys_time_get() - last_press_time; + + + if (press_down > 0 && time_diff > CLICK_INTERVAL_TIMEOUT) { + APP_PRINT_INFO1("Click interval timeout, reset count from %d to 1", press_down); + press_down = 1; + } else { + + press_down++; + } + + + last_press_time = os_sys_time_get(); + + + switch(press_down) { + case SINGLE_CLICK: + APP_PRINT_INFO0("Single click detected, start timer"); + + os_timer_start(&double_click_detect_timer); + break; + + case DOUBLE_CLICK: + case FOUR_CLICK: + + APP_PRINT_INFO1("%d clicks detected, restart timer", press_down); + os_timer_stop(&double_click_detect_timer); + os_timer_start(&double_click_detect_timer); + + break; + + case TEN_CLICK: + + APP_PRINT_INFO0("Ten clicks detected, handle immediately"); + os_timer_stop(&double_click_detect_timer); + + handle_ten_click(); + press_down = 0; + break; + + default: + + if (press_down > 1) { + APP_PRINT_INFO1("%d clicks detected, continue waiting", press_down); + + os_timer_stop(&double_click_detect_timer); + os_timer_start(&double_click_detect_timer); + } + break; + } + } + break; +#endif + + default: + APP_PRINT_ERROR1("app_handle_gpio_msg: unknown subtype %d", p_gpio_msg->subtype); + break; + } +} + +/** + * @brief All the BT GAP MSG are pre-handled in this function. + * @note Then the event handling function shall be called according to the + * subtype of T_IO_MSG + * @param[in] p_gap_msg Pointer to GAP msg + * @return void + */ +void app_handle_gap_msg(T_IO_MSG *p_gap_msg) +{ + T_LE_GAP_MSG gap_msg; + uint8_t conn_id; + memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param)); + +// APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype); + switch (p_gap_msg->subtype) + { + case GAP_MSG_LE_DEV_STATE_CHANGE: + { + app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state, + gap_msg.msg_data.gap_dev_state_change.cause); + } + break; + + case GAP_MSG_LE_CONN_STATE_CHANGE: + { + app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id, + (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state, + gap_msg.msg_data.gap_conn_state_change.disc_cause); + } + break; + + case GAP_MSG_LE_CONN_MTU_INFO: + { + app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id, + gap_msg.msg_data.gap_conn_mtu_info.mtu_size); + } + break; + + case GAP_MSG_LE_CONN_PARAM_UPDATE: + { + app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id, + gap_msg.msg_data.gap_conn_param_update.status, + gap_msg.msg_data.gap_conn_param_update.cause); + } + break; + + case GAP_MSG_LE_AUTHEN_STATE_CHANGE: + { + app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id, + gap_msg.msg_data.gap_authen_state.new_state, + gap_msg.msg_data.gap_authen_state.status); + } + break; + + case GAP_MSG_LE_BOND_JUST_WORK: + { + conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id; + le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK"); + } + break; + + case GAP_MSG_LE_BOND_USER_CONFIRMATION: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id; + le_bond_get_display_key(conn_id, &display_value); + APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value); +#if GFPS_FEATURE_SUPPORT + app_gfps_handle_ble_user_confirm(conn_id, display_value); +#endif + } + break; + + case GAP_MSG_LE_BOND_PASSKEY_DISPLAY: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id; + le_bond_get_display_key(conn_id, &display_value); + APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value); + le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + + case GAP_MSG_LE_BOND_PASSKEY_INPUT: + { + uint32_t passkey = 888888; + conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id; + APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id); + le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT); + } + break; + + default: + APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype); + break; + } +} +/** @} */ /* End of group APP_GAP_MSG */ + +/****************************************************************** + * @brief handle bond modify message. + * @param T_LE_BOND_MODIFY_TYPE type + * @param T_LE_KEY_ENTRY *p_entry + * @return none + * @retval void + */ +void app_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry) +{ + APP_PRINT_INFO2("BOND local_bd_addr = %s, type = %d, ", \ + TRACE_BDADDR(p_entry->local_bd_addr), p_entry->local_bd_type); + APP_PRINT_INFO2("BOND resolved_remote_bd = %s, type = %d", \ + TRACE_BDADDR(p_entry->resolved_remote_bd.addr), p_entry->resolved_remote_bd.remote_bd_type); + + switch (type) + { + case LE_BOND_DELETE: + APP_PRINT_INFO1("LE_BOND_DELETE: idx=%d", p_entry->idx); + if (app_global_data.app_bond_idx[FINDMY_BOND] == p_entry->idx) + { + app_global_data.app_bond_idx[FINDMY_BOND] = 0xFF; + } +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + else if (app_global_data.app_bond_idx[CUST_BOND_1] == p_entry->idx) + { + app_global_data.app_bond_idx[CUST_BOND_1] = 0xFF; + } + else if (app_global_data.app_bond_idx[CUST_BOND_2] == p_entry->idx) + { + app_global_data.app_bond_idx[CUST_BOND_2] = 0xFF; + } +#endif + break; + + case LE_BOND_ADD: + { +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (memcmp(one_shot_adv_data.adv_data[ADV_DATA_FINDMY].bd_addr, p_entry->local_bd_addr, 6) == 0) + { + app_global_data.app_bond_idx[FINDMY_BOND] = p_entry->idx; + APP_PRINT_INFO1("LE_BOND_ADD: FINDMY_BOND idx=%d", p_entry->idx); + } + else if (memcmp(one_shot_adv_data.adv_data[ADV_DATA_CUSTOMIZED].bd_addr, p_entry->local_bd_addr, + 6) == 0) + { + if (app_global_data.app_bond_idx[CUST_BOND_1] == 0xFF) + { + app_global_data.app_bond_idx[CUST_BOND_1] = p_entry->idx; + APP_PRINT_INFO1("LE_BOND_ADD CUST_BOND_1 idx=%d", p_entry->idx); + } + else if (app_global_data.app_bond_idx[CUST_BOND_2] == 0xFF) + { + app_global_data.app_bond_idx[CUST_BOND_2] = p_entry->idx; + APP_PRINT_INFO1("LE_BOND_ADD CUST_BOND_2 idx=%d", p_entry->idx); + } + else + { + APP_PRINT_ERROR0("LE_BOND_ADD CUST BOND error"); + } + } + else + { + APP_PRINT_ERROR0("LE_BOND_ADD no local_bd_addr matched!"); + } +#else + app_global_data.app_bond_idx[FINDMY_BOND] = p_entry->idx; + APP_PRINT_INFO1("LE_BOND_ADD: FINDMY_BOND idx=%d", p_entry->idx); +#endif + } + break; + + case LE_BOND_CLEAR: + APP_PRINT_INFO0("LE_BOND_CLEAR"); + for (uint8_t i = 0; i < BLE_BOND_NUM; i++) + { + app_global_data.app_bond_idx[i] = 0xFF; + } + break; + + case LE_BOND_FULL: + APP_PRINT_INFO0("LE_BOND_FULL"); + { +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + if (app_global_data.app_bond_idx[CUST_BOND_1] != 0xFF) + { + T_GAP_CAUSE ret = le_bond_delete_by_idx(app_global_data.app_bond_idx[CUST_BOND_1]); + APP_PRINT_INFO2("delete CUST_BOND_1 idx=%#x ret=%d", app_global_data.app_bond_idx[CUST_BOND_1], + ret); + } + if (app_global_data.app_bond_idx[CUST_BOND_2] != 0xFF) + { + T_GAP_CAUSE ret = le_bond_delete_by_idx(app_global_data.app_bond_idx[CUST_BOND_2]); + APP_PRINT_INFO2("delete CUST_BOND_2 idx=%#x ret=%d", app_global_data.app_bond_idx[CUST_BOND_2], + ret); + } +#endif + } + break; + + default: + APP_PRINT_WARN1("[app_handle_bond_modify_msg]unknown bond msg type = %d", type); + break; + } + + uint8_t bond_idx_buffer[FTL_SAVE_BOND_IDX_SIZE]; + memcpy(bond_idx_buffer, app_global_data.app_bond_idx, BLE_BOND_NUM); + if (ftl_save(bond_idx_buffer, FTL_SAVE_BOND_IDX_ADDR, FTL_SAVE_BOND_IDX_SIZE)) + { + APP_PRINT_ERROR0("FTL save app_global_data.app_bond_idx failed!"); + } + + /* if findmy app bonded, set to high priority */ + if (app_global_data.app_bond_idx[FINDMY_BOND] != 0xFF) + { + T_LE_KEY_ENTRY *findmy_key_entry; + findmy_key_entry = le_find_key_entry_by_idx(app_global_data.app_bond_idx[FINDMY_BOND]); + le_set_high_priority_bond_v2(findmy_key_entry); + } + APP_PRINT_INFO1("[app_handle_bond_modify_msg] FINDMY_BOND idx=%d", + app_global_data.app_bond_idx[FINDMY_BOND]); +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + APP_PRINT_INFO2("[app_handle_bond_modify_msg] CUST_BOND_1 idx=%d, CUST_BOND_2 idx=%d", + app_global_data.app_bond_idx[CUST_BOND_1], app_global_data.app_bond_idx[CUST_BOND_2]); + if (app_global_data.app_bond_idx[CUST_BOND_1] != 0xFF || + app_global_data.app_bond_idx[CUST_BOND_2] != 0xFF) + { + cust_set_paired_flag(true); + } + else + { + cust_set_paired_flag(false); + } +#endif +} + +/** @defgroup APP_GAP_CALLBACK GAP Callback Event Handler + * @brief Handle GAP callback event + * @{ + */ +/** + * @brief Callback for gap le to notify app + * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types. + * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA. + * @retval result @ref T_APP_RESULT + */ +T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_DATA_LEN_CHANGE_INFO: + APP_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x", + p_data->p_le_data_len_change_info->conn_id, + p_data->p_le_data_len_change_info->max_tx_octets, + p_data->p_le_data_len_change_info->max_tx_time); + break; + + case GAP_MSG_LE_MODIFY_WHITE_LIST: + APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x", + p_data->p_le_modify_white_list_rsp->operation, + p_data->p_le_modify_white_list_rsp->cause); + break; + + case GAP_MSG_LE_ADV_READ_TX_POWER: + APP_PRINT_INFO2("GAP_MSG_LE_ADV_READ_TX_POWER: cause 0x%x, tx_power_level 0x%x", + p_data->p_le_adv_read_tx_power_rsp->cause, + p_data->p_le_adv_read_tx_power_rsp->tx_power_level); + tps_set_parameter(TPS_PARAM_TX_POWER, 1, &(p_data->p_le_adv_read_tx_power_rsp->tx_power_level)); + break; + + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", p_data->p_le_bond_modify_info->type); + app_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry); + break; + + case GAP_MSG_LE_BOND_KEY_REQ: + { + result = APP_RESULT_REJECT; + APP_PRINT_INFO4("GAP_MSG_LE_BOND_KEY_REQ: conn_handle %d bd_addr %s, remote_addr_type %d, key_type %#x", + p_data->p_le_bond_key_req->conn_handle, + TRACE_BDADDR(p_data->p_le_bond_key_req->bd_addr), + p_data->p_le_bond_key_req->remote_addr_type, + p_data->p_le_bond_key_req->key_type + ); + + T_APP_SELECT conn_app = FINDMY_APP; + T_LE_KEY_ENTRY *key_entry = NULL; +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + uint8_t local_bd[6]; + T_GAP_LOCAL_ADDR_TYPE local_bd_type; + bool ret = le_get_conn_local_addr(p_data->p_le_bond_key_req->conn_handle, local_bd, + (uint8_t *)&local_bd_type); + if (!ret) + { + APP_PRINT_ERROR0("le_get_conn_local_addr failed!"); + return result; + } + + for (uint8_t i = 0; i < ADV_DATA_TYPE_MAX; i++) + { + if (memcmp(one_shot_adv_data.adv_data[i].bd_addr, local_bd, 6) == 0) + { + conn_app = (T_APP_SELECT)i; + break; + } + } +#endif + T_LE_DEV_INFO dev_info; + T_LE_LTK *local_ltk; + memset(&dev_info, 0, sizeof(T_LE_DEV_INFO)); + + if (conn_app == FINDMY_APP) + { + key_entry = le_find_key_entry_by_idx(app_global_data.app_bond_idx[FINDMY_APP]); + } +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + else if (conn_app == CUSTOMIZED_APP) + { + for (uint8_t i = CUST_BOND_1; i <= CUST_BOND_2 ; i++) + { + if (app_global_data.app_bond_idx[i] == 0xFF) + { + continue; + } + key_entry = le_find_key_entry_by_idx(app_global_data.app_bond_idx[i]); + uint8_t cust_irk[16]; + le_get_dev_irk(key_entry, true, cust_irk); + bool ret = le_privacy_check_resolvable_private_address(p_data->p_le_bond_key_req->bd_addr, + cust_irk); + if (ret) + { + APP_PRINT_INFO1("GAP_MSG_LE_BOND_KEY_REQ CUST_BOND_%d could resolved", i); + break; + } + } + } +#endif + if ((key_entry != NULL) && le_get_dev_info(key_entry, &dev_info)) + { + APP_PRINT_INFO1("GAP_MSG_LE_BOND_KEY_REQ: found app=%d key_entry", conn_app); + local_ltk = (T_LE_LTK *)dev_info.local_ltk; + p_data->p_le_bond_key_req->key_len = local_ltk->link_key_length; + memcpy(p_data->p_le_bond_key_req->link_key, local_ltk->key, local_ltk->link_key_length); + result = APP_RESULT_ACCEPT; + } + + APP_PRINT_INFO4("GAP_MSG_LE_BOND_KEY_REQ: key_length 0x%x, key_type 0x%x, link_key %b, result 0x%x", + p_data->p_le_bond_key_req->key_len, + p_data->p_le_bond_key_req->key_type, + TRACE_BINARY(p_data->p_le_bond_key_req->key_len, p_data->p_le_bond_key_req->link_key), + result + ); + } + break; + + case GAP_MSG_LE_ADV_UPDATE_PARAM: +// APP_PRINT_INFO1("GAP_MSG_LE_ADV_UPDATE_PARAM: cause 0x%x", +// p_data->p_le_adv_update_param_rsp->cause); +#if ONE_SHOT_ADV_EN + one_shot_adv_data.waiting_adv_param_update = true; + if (!one_shot_adv_data.waiting_adv_addr_update) + { + one_shot_adv_set_addr(); + } + else + { + le_vendor_one_shot_adv(0, 0, 0); + } + one_shot_adv_data.waiting_vendor_one_shot = false; +#else + fmble_gap_adv_cb(); +#endif + break; + + case GAP_MSG_LE_VENDOR_ONE_SHOT_ADV: +// APP_PRINT_INFO1("GAP_MSG_LE_VENDOR_ONE_SHOT_ADV: cause 0x%x", p_data->le_cause.cause); +#if ONE_SHOT_ADV_EN + one_shot_adv_data.waiting_vendor_one_shot = true; + one_shot_handle_pending_adv(); +#endif + break; + + case GAP_MSG_LE_SET_RAND_ADDR: +// APP_PRINT_INFO1("GAP_MSG_LE_SET_RAND_ADDR: cause 0x%x", +// p_data->p_le_set_rand_addr_rsp->cause); +#if ONE_SHOT_ADV_EN + if (!one_shot_adv_data.waiting_adv_addr_update) + { + le_vendor_one_shot_adv(0, 0, 0); + one_shot_adv_data.waiting_adv_addr_update = true; + } +#endif + break; + + case GAP_MSG_LE_ADV_SET_TX_POWER: + APP_PRINT_INFO1("GAP_MSG_LE_ADV_SET_TX_POWER: cause 0x%x", + p_data->le_cause.cause); + break; + + case GAP_MSG_LE_READ_RSSI: + { + uint8_t conn_id = cust_get_conn_id(); + T_GATT_DATA p_fmna_gatt_data = fmna_gatt_platform_get_gatt_data(); + + APP_PRINT_INFO3("GAP_MSG_LE_READ_RSSI: conn_id %d, cause 0x%x, rssi %d", + p_data->p_le_read_rssi_rsp->conn_id, + p_data->p_le_read_rssi_rsp->cause, + p_data->p_le_read_rssi_rsp->rssi); + extern uint8_t sdd_rssi_level ; + sdd_rssi_level = 20 + (110 - 20) * (p_data->p_le_read_rssi_rsp->rssi + 100) / 100; + uint8_t sum = 130-sdd_rssi_level; + + if(sum<=80){ + + sum = 21; + + }else if(sum>95&&sum<=105){ + + sum = 100; + + }else if(sum>105&&sum<=110){ + + sum = 100; + + }else if(sum>110){ + + sum = 110; + + } + + sdd_battery_level_value_notify(custom_data.cust_conn_id, p_fmna_gatt_data.sdd_srv_id,sum); + + + APP_PRINT_INFO1("------------------------------------------>%d",sum); + + + } + break; + + default: + APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type); + break; + } + return result; +} +/** @} */ /* End of group APP_GAP_CALLBACK */ + + +/** @} */ /* End of group FINDMY_APP */ diff --git a/src/app/findmy/findmy_app.h b/src/app/findmy/findmy_app.h new file mode 100644 index 0000000..b21dd2f --- /dev/null +++ b/src/app/findmy/findmy_app.h @@ -0,0 +1,186 @@ +/** +***************************************************************************************** +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file findmy_app.h + * @brief This file handles Find My application routines. + * @author scarlett + * @date 2023-05-06 + * @version v1.1 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2023 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +#ifndef _FINDMY_APP__ +#define _FINDMY_APP__ + +#ifdef __cplusplus +extern "C" { +#endif +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include +#include +#include +#include "custom_app.h" +#include "fmna_timer_platform.h" + +/*============================================================================* + * Macros + *============================================================================*/ +#define VID 0x005D +#define PID 0x0001 + +#ifdef USE_UARP +#define OTA_SRV_NUM (1) +#else +#define OTA_SRV_NUM (0) +#endif + +#define FMNA_SRV_NUM (4) + +#if GFPS_FEATURE_SUPPORT +#define CUST_SRV_NUM (2) +#elif CUST_HID_SERVICE +#define CUST_SRV_NUM (1) +#else +#define CUST_SRV_NUM (0) +#endif + +#define GATT_SRV_NUM (OTA_SRV_NUM + FMNA_SRV_NUM + CUST_SRV_NUM) + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + FINDMY_APP = 0, +#if SUPPORT_CUSTOMIZED_APP + CUSTOMIZED_APP, +#endif +#if GFPS_FEATURE_SUPPORT + GFPS_APP, + FINDER, +#endif + MAX_APP_NUM, +} T_APP_SELECT; + +typedef enum +{ + FINDMY_BOND = 0, +#if (CUST_APP_TYPE == CUST_APP_PAIRED) + CUST_BOND_1, + CUST_BOND_2, +#endif + MAX_BOND_NUM, +} T_APP_BOND; + +/** @brief FMNA only needs 1 bond information, GFPS does not need to bond */ +#define BLE_BOND_NUM MAX_BOND_NUM +/** + * @brief APP global data struct definition. + */ +typedef struct +{ + bool fmna_enable; //Set when Apple FMNA is sending a pairing advertising or is paired +#if GFPS_FEATURE_SUPPORT + bool gfps_enable; //Set when Google FHN is sending a pairing advertising or is paired +#endif +#if SUPPORT_BAT_DETECT_FEATURE + bool low_power_mode; +#endif + T_SW_RESET_REASON reset_reason; + uint8_t mac_address[6]; + T_GAP_DEV_STATE gap_dev_state; /* to indicate the current GAP device state */ + T_GAP_CONN_STATE gap_conn_state[APP_MAX_LINKS]; /* to indicate the current GAP connection state */ + uint8_t app_bond_idx[BLE_BOND_NUM]; +} T_APP_GLOBAL_DATA; + +/*============================================================================* + * Variables + *============================================================================*/ +extern T_APP_GLOBAL_DATA app_global_data; + +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @brief Perform a factory reset operation for the FMNA module + * @note This function will clear all user configurations and restore + * the device to its original factory default settings. + * @return void + */ +void fmna_factory_reset(void); + +/** + * @brief Restore bond information for both FMNA and custom profiles + * @note This function retrieves and restores previously bonded device + * information from non-volatile memory for both FMNA and custom + * profiles to re-establish connections without requiring re-pairing. + * @return void + */ +void app_bond_info_restore(void); + +/** + * @brief Initialize global application data structures + * @note This function initializes all global variables and data structures + * used throughout the application to their default values during + * system startup or reset. + * @return void + */ +void app_global_data_init(void); + +/** + * @brief All the application messages are pre-handled in this function + * @note All the IO MSGs are sent to this function, then the event handling + * function shall be called according to the MSG type. + * @param[in] io_msg IO message data + * @return void + */ +void app_handle_io_msg(T_IO_MSG io_msg); + +/** + * @brief All the BT Profile service callback events are handled in this function + * @note Then the event handling function shall be called according to the + * service_id. + * @param[in] service_id Profile service ID + * @param[in] p_data Pointer to callback data + * @return Indicates the function call is successful or not + * @retval result @ref T_APP_RESULT + */ +T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data); + +/** + * @brief Callback for gap le to notify app + * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types. + * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA. + * @retval result @ref T_APP_RESULT + */ +T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data); + +/** + * @brief double_click_detect_timer + * @note + * @param[in] p_timer + * @return void + */ +void double_click_detect_timer_cb(TimerHandle_t p_timer); + +void password_verification_timeout(TimerHandle_t p_timer); + +void version_test_msg(void); + +void disconnection_timing_sequence(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/fmna_adk/FMNASampleUARP.c b/src/app/findmy/fmna_adk/FMNASampleUARP.c new file mode 100644 index 0000000..4b01b00 --- /dev/null +++ b/src/app/findmy/fmna_adk/FMNASampleUARP.c @@ -0,0 +1,1202 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#include "FMNASampleUARP.h" +#include "fmna_dfu_platform.h" + +#define UNUSED __attribute__ ((unused)) + +uint8_t total_payload_index; + +static uint16_t error_line; +static const char* const error_file = __FILE__; + +/* MARK: INTERNAL PROTOTYPES */ + +static uint32_t FMNASampleRequestBuffer(void *pAccessoryDelegate, uint8_t **ppBuffer, + uint32_t bufferLength); + +static void FMNASampleReturnBuffer(void *pAccessoryDelegate, uint8_t *pBuffer); + +static uint32_t FMNASampleRequestTransmitMsgBuffer(void *pAccessoryDelegate, + void *pControllerDelegate, + uint8_t **ppBuffer, uint32_t *pLength); + +static void FMNASampleReturnTransmitMsgBuffer(void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer); + +static uint32_t FMNASampleSendMessage(void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer, uint32_t length); + +static uint32_t FMNASampleDataTransferPause(void *pAccessoryDelegate, void *pControllerDelegate); + +static uint32_t FMNASampleDataTransferResume(void *pAccessoryDelegate, void *pControllerDelegate); + +static void FMNASampleSuperBinaryOffered(void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpPlatformAsset *pAsset); + +static void FMNASampleDynamicAssetOffered(void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpPlatformAsset *pAsset); + +static void FMNASampleAssetOrphaned(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASampleAssetRescinded(void *pAccessoryDelegate, void *pControllerDelegate, + void *pAssetDelegate); + +static void FMNASampleAssetCorrupt(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASampleAssetReady(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASampleAssetMetaDataTLV(void *pAccessoryDelegate, void *pAssetDelegate, + uint32_t tlvType, uint32_t tlvLength, uint8_t *pTlvValue); + +static void FMNASampleAssetMetaDataComplete(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASamplePayloadReady(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASamplePayloadMetaDataTLV(void *pAccessoryDelegate, void *pAssetDelegate, + uint32_t tlvType, uint32_t tlvLength, uint8_t *pTlvValue); + +static void FMNASamplePayloadMetaDataComplete(void *pAccessoryDelegate, void *pAssetDelegate); + +static void FMNASamplePayloadData(void *pAccessoryDelegate, void *pAssetDelegate, + uint8_t *pBuffer, uint32_t lengthBuffer, uint32_t offset, + uint8_t *pAssetState, uint32_t lengthAssetState); + +static void FMNASamplePayloadDataComplete(void *pAccessoryDelegate, void *pAssetDelegate); + +static uint32_t FMNASampleApplyStagedAssets(void *pAccessoryDelegate, void *pControllerDelegate, + uint16_t *pFlags); + +static uint32_t FMNASampleQueryManufacturerName(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength); + +static uint32_t FMNASampleQueryModelName(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength); + +static uint32_t FMNASampleQuerySerialNumber(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength); + +static uint32_t FMNASampleQueryHardwareVersion(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength); + +static uint32_t FMNASampleQueryActiveFirmwareVersion(void *pAccessoryDelegate, uint32_t assetTag, + struct UARPVersion *pVersion); + +static uint32_t FMNASampleQueryStagedFirmwareVersion(void *pAccessoryDelegate, uint32_t assetTag, + struct UARPVersion *pVersion); + +static uint32_t FMNASampleQueryLastError(void *pAccessoryDelegate, + struct UARPLastErrorAction *pLast); + +/* MARK: CONTROL */ + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleInit(struct FMNASampleAccessory *pAccessory, + const char *manufacturerName, + const char *modelName, + const char *serialNumber, + const char *hardwareVersion, + struct UARPVersion *pActiveFirmwareVersion, + struct UARPVersion *pStagedFirmwareVersion, + struct FMNASampleCallbacks *pCallbacks) +{ + size_t length; + uint32_t status; + struct uarpPlatformOptionsObj options; + struct uarpPlatformAccessoryCallbacks callbacks; + + /* initialize and copy inputs */ + memset(pAccessory, 0, sizeof(struct FMNASampleAccessory)); + + length = strlen(manufacturerName); + __UARP_Require_Action((length <= kFMNASampleInfoLength), exit, status = kUARPStatusInvalidArgument); + + memcpy(pAccessory->manufacturerName, manufacturerName, length); + + length = strlen(modelName); + __UARP_Require_Action((length <= kFMNASampleInfoLength), exit, status = kUARPStatusInvalidArgument); + + memcpy(pAccessory->modelName, modelName, length); + + length = strlen(serialNumber); + __UARP_Require_Action((length <= kFMNASampleInfoLength), exit, status = kUARPStatusInvalidArgument); + + memcpy(pAccessory->serialNumber, serialNumber, length); + + length = strlen(hardwareVersion); + __UARP_Require_Action((length <= kFMNASampleInfoLength), exit, status = kUARPStatusInvalidArgument); + + memcpy(pAccessory->hardwareVersion, hardwareVersion, length); + + __UARP_Require_Action((pActiveFirmwareVersion != NULL), exit, status = kUARPStatusInvalidArgument); + pAccessory->activeFirmwareVersion = *pActiveFirmwareVersion; + + __UARP_Require_Action((pStagedFirmwareVersion != NULL), exit, status = kUARPStatusInvalidArgument); + pAccessory->stagedFirmwareVersion = *pStagedFirmwareVersion; + + pAccessory->lastAction = kUARPLastActionApplyFirmwareUpdate; + pAccessory->lastActionStatus = 0x08675309; + + options.maxTxPayloadLength = kFMNASampleMaxTxMsgPayloadSize; + options.maxRxPayloadLength = kFMNASampleMaxRxMsgPayloadSize; + options.payloadWindowLength = kFMNASamplePayloadWindowSize; + + pAccessory->callbacks = *pCallbacks; + __UARP_Require_Action((pAccessory->callbacks.fSendMessage != NULL), exit, + status = kUARPStatusInvalidArgument); + + /* setup our callbacks */ + callbacks.fRequestBuffer = FMNASampleRequestBuffer; + callbacks.fReturnBuffer = FMNASampleReturnBuffer; + callbacks.fRequestTransmitMsgBuffer = FMNASampleRequestTransmitMsgBuffer; + callbacks.fReturnTransmitMsgBuffer = FMNASampleReturnTransmitMsgBuffer; + callbacks.fSendMessage = FMNASampleSendMessage; + callbacks.fDataTransferPause = FMNASampleDataTransferPause; + callbacks.fDataTransferResume = FMNASampleDataTransferResume; + callbacks.fSuperBinaryOffered = FMNASampleSuperBinaryOffered; + callbacks.fDynamicAssetOffered = FMNASampleDynamicAssetOffered; + callbacks.fAssetOrphaned = FMNASampleAssetOrphaned; + callbacks.fAssetRescinded = FMNASampleAssetRescinded; + callbacks.fAssetCorrupt = FMNASampleAssetCorrupt; + callbacks.fAssetReady = FMNASampleAssetReady; + callbacks.fAssetMetaDataTLV = FMNASampleAssetMetaDataTLV; + callbacks.fAssetMetaDataComplete = FMNASampleAssetMetaDataComplete; + callbacks.fPayloadReady = FMNASamplePayloadReady; + callbacks.fPayloadMetaDataTLV = FMNASamplePayloadMetaDataTLV; + callbacks.fPayloadMetaDataComplete = FMNASamplePayloadMetaDataComplete; + callbacks.fPayloadData = FMNASamplePayloadData; + callbacks.fPayloadDataComplete = FMNASamplePayloadDataComplete; + callbacks.fApplyStagedAssets = FMNASampleApplyStagedAssets; + callbacks.fManufacturerName = FMNASampleQueryManufacturerName; + callbacks.fModelName = FMNASampleQueryModelName; + callbacks.fSerialNumber = FMNASampleQuerySerialNumber; + callbacks.fHardwareVersion = FMNASampleQueryHardwareVersion; + callbacks.fActiveFirmwareVersion = FMNASampleQueryActiveFirmwareVersion; + callbacks.fStagedFirmwareVersion = FMNASampleQueryStagedFirmwareVersion; + callbacks.fLastError = FMNASampleQueryLastError; + + status = uarpPlatformAccessoryInit(&pAccessory->_accessory, + &options, + &callbacks, + NULL, + NULL, + (void *)pAccessory); + __UARP_Check(status == kUARPStatusSuccess); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleControllerAdd(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController) +{ + uint32_t status; + + status = uarpPlatformControllerAdd(&(pAccessory->_accessory), &(pController->_controller), + (void *)pController); + __UARP_Require((status == kUARPStatusSuccess), exit); + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleControllerRemove(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController) +{ + uint32_t status; + + /* free and pending TX puffers */ + void *pBuf1 = NULL; + void *pBuf2 = NULL; + uint32_t flags; + CRITICAL_REGION_ENTER(); + pBuf1 = pController->pBuffer; + pController->pBuffer = NULL; + pBuf2 = pController->pPendingBuffer; + pController->pPendingBuffer = NULL; + pController->pendingLength = 0; + CRITICAL_REGION_EXIT(); + + if (pBuf1) + { + uarpFree(pBuf1); + } + if (pBuf2) + { + uarpFree(pBuf2); + } + + /* alert the lower layer */ + status = uarpPlatformControllerRemove(&(pAccessory->_accessory), &(pController->_controller)); + __UARP_Check(status == kUARPStatusSuccess); + + pAccessory->pSuperBinary.pController = NULL; + + /* done */ + status = kUARPStatusSuccess; + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleRecvMessage(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController, + uint8_t *pBuffer, uint32_t length) +{ + uint32_t status; + + status = uarpPlatformAccessoryRecvMessage(&(pAccessory->_accessory), &(pController->_controller), + pBuffer, length); + + return status; +} + + +/* MARK: CALLBACKS */ + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleRequestBuffer(void *pAccessoryDelegate, uint8_t **ppBuffer, + uint32_t bufferLength) +{ + uint32_t status; + + __UARP_Require_Action(ppBuffer, exit, status = kUARPStatusInvalidArgument); + + *ppBuffer = uarpZalloc(bufferLength); + __UARP_Require_Action(*ppBuffer, exit, status = kUARPStatusNoResources); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleReturnBuffer(void *pAccessoryDelegate, uint8_t *pBuffer) +{ + __UARP_Require(pBuffer, exit); + + uarpFree(pBuffer); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleRequestTransmitMsgBuffer(void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t **ppBuffer, uint32_t *pLength) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(ppBuffer, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pLength, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + /* alloc the memory and zero it out */ + *pLength = pAccessory->_accessory._options.maxTxPayloadLength + (uint32_t)sizeof( + union UARPMessages); + + *ppBuffer = uarpZalloc(*pLength); + __UARP_Require_Action(*ppBuffer, exit, status = kUARPStatusNoResources); + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleReturnTransmitMsgBuffer(void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer) +{ + __UARP_Require(pBuffer, exit); + + uarpFree(pBuffer); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleSendMessage(void *pAccessoryDelegate, void *pControllerDelegate, + uint8_t *pBuffer, uint32_t length) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + UNUSED struct FMNASampleController *pController; + uint8_t *pBuf = NULL; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pControllerDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pBuffer, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action((length > 0), exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + pController = (struct FMNASampleController *)pControllerDelegate; + +// CRITICAL_REGION_ENTER(); + if (pController->pBuffer == NULL) + { + // Set the buffer to return later + pController->pBuffer = pBuffer; + pBuf = pBuffer; + } + else + { + if (pController->pPendingBuffer != NULL) + { + uarpLogError(kUARPLoggingCategoryProduct, "Already have a pending UARP TX"); + } + pController->pPendingBuffer = pBuffer; + pController->pendingLength = length; + status = kUARPStatusSuccess; + } +// CRITICAL_REGION_EXIT(); + + if (pBuf) + { + status = pAccessory->callbacks.fSendMessage(pAccessoryDelegate, pControllerDelegate, pBuffer, + length); + } + else + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Queueing TX packet"); + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleSendMessageComplete(void *pAccessoryDelegate, void *pControllerDelegate) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + struct FMNASampleController *pController; + uint8_t *pBuf; + uint16_t length; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pControllerDelegate, exit, status = kUARPStatusInvalidArgument); + + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + pController = (struct FMNASampleController *)pControllerDelegate; + + __UARP_Require_Action((pController->pBuffer), exit, status = kUARPStatusInvalidArgument); + + /* TODO: This should only called by UARP Layer 3 when the accessory is 100% sure it is done with the buffer; + uarpPlatformAccessorySendMessageComplete() will free the buffer */ + pBuf = pController->pBuffer; + + uint32_t flags; + CRITICAL_REGION_ENTER(); + // See if there is a pending TX and send if there is. + pController->pBuffer = NULL; + if (pController->pPendingBuffer) + { + pController->pBuffer = pController->pPendingBuffer; + length = pController->pendingLength; + pController->pPendingBuffer = NULL; + } + CRITICAL_REGION_EXIT(); + + uarpPlatformAccessorySendMessageComplete(&(pAccessory->_accessory), &(pController->_controller), + pBuf); + + // there's another packet queued, so send it + if (pController->pBuffer) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Sending queued TX packet"); + pAccessory->callbacks.fSendMessage(pAccessoryDelegate, pControllerDelegate, pController->pBuffer, + length); + } + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleDataTransferPause(void *pAccessoryDelegate, void *pControllerDelegate) +{ + uint32_t status; + UNUSED struct FMNASampleAccessory *pAccessory; +#if !(FMNA_DISABLE_LOGS) + struct FMNASampleController *pController; +#else + UNUSED struct FMNASampleController *pController; +#endif + + /* alias delegates */ + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + pController = (struct FMNASampleController *)pControllerDelegate; + + uarpLogInfo(kUARPLoggingCategoryProduct, "Transfers PAUSED from Remote Controller %u", + pController->_controller._controller.remoteControllerID); + + /* done */ + status = kUARPStatusSuccess; + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleDataTransferResume(void *pAccessoryDelegate, void *pControllerDelegate) +{ + uint32_t status; + UNUSED struct FMNASampleAccessory *pAccessory; +#if !(FMNA_DISABLE_LOGS) + struct FMNASampleController *pController; +#else + UNUSED struct FMNASampleController *pController; +#endif + + /* alias delegates */ + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + pController = (struct FMNASampleController *)pControllerDelegate; + + uarpLogInfo(kUARPLoggingCategoryProduct, "Transfers RESUMED from Remote Controller %u", + pController->_controller._controller.remoteControllerID); + + /* done */ + status = kUARPStatusSuccess; + + return status; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleSuperBinaryOffered(void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpPlatformAsset *pAsset) +{ + UARPBool isAcceptable; + uint32_t status; + UARPVersionComparisonResult compareResult; + struct FMNASampleAccessory *pAccessory; + struct FMNASampleController *pController; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pControllerDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pAsset, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + pController = (struct FMNASampleController *)pControllerDelegate; + + uarpLogInfo(kUARPLoggingCategoryProduct, "Asset Offered <%08x> ", + pAsset->core.assetTag, + pAsset->core.assetVersion.major, pAsset->core.assetVersion.minor, + pAsset->core.assetVersion.release, pAsset->core.assetVersion.build); + + /* Ensure this is an acceptable offer */ + status = uarpPlatformAccessoryAssetIsAcceptable(&(pAccessory->_accessory), pAsset, &isAcceptable); + __UARP_Require((status == kUARPStatusSuccess), exit); + + /* If we are acceptable so far, determine our next step */ + if (isAcceptable == kUARPNo) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Asset is not acceptable"); + } + else if (uarpAssetIsSuperBinary(&(pAsset->core))) + { + if ((pAccessory->pSuperBinary.pAsset != NULL) && (pAccessory->pSuperBinary.pController != NULL)) + { + /* TODO: handle competing controllers */ + + isAcceptable = kUARPNo; + } + else if ((pAccessory->pSuperBinary.pAsset != NULL) && + (pAccessory->pSuperBinary.pController == NULL)) + { + compareResult = uarpAssetCoreCompare(&(pAccessory->pSuperBinary.pAsset->core), + &(pAsset->core)); + + if (compareResult == kUARPVersionComparisonResultIsEqual) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Merging offered SuperBinary and orphaned SuperBinary"); + + status = uarpPlatformAccessorySuperBinaryMerge(&(pAccessory->_accessory), + pAccessory->pSuperBinary.pAsset, + pAsset); + __UARP_Require((status == kUARPStatusSuccess), exit); + + /* slight trick, otherwise we would set the superbinary to the newly orphaned (was merged into existing) */ + pAsset = pAccessory->pSuperBinary.pAsset; + + /* TODO: handle the hasPayloadXXXX */ + } + else + { + uarpPlatformAccessoryAssetAbandon(&(pAccessory->_accessory), NULL, pAccessory->pSuperBinary.pAsset); + + pAccessory->pSuperBinary.pAsset = NULL; + } + } + } + + /* is this asset acceptable or no? handle appropriately */ + if (isAcceptable == kUARPYes) + { + if (pAccessory->pSuperBinary.pAsset == NULL) + { + pAccessory->hasPayload = kUARPNo; + } + + pAccessory->pSuperBinary.pAsset = pAsset; + pAccessory->pSuperBinary.pController = pController; + + pAsset->pDelegate = &(pAccessory->pSuperBinary); + + status = uarpPlatformAccessoryAssetAccept(&(pAccessory->_accessory), &(pController->_controller), + pAsset); + __UARP_Require((status == kUARPStatusSuccess), exit); + } + else + { + status = uarpPlatformAccessoryAssetDeny(&(pAccessory->_accessory), &(pController->_controller), + pAsset); + __UARP_Require((status == kUARPStatusSuccess), exit); + } + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleDynamicAssetOffered(void *pAccessoryDelegate, void *pControllerDelegate, + struct uarpPlatformAsset *pAsset) +{ + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetRescinded(void *pAccessoryDelegate, void *pControllerDelegate, + void *pAssetDelegate) +{ + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + uarpLogInfo(kUARPLoggingCategoryPlatform, "Asset %u Rescinded from Controller %d", + pAsset->pAsset->core.assetID, + pAsset->pController->_controller._controller.remoteControllerID); + + if (pAsset == &(pAccessory->pSuperBinary)) + { + pAccessory->pSuperBinary.pController = NULL; + } + + /* must unstage asset */ + memset(&pAccessory->stagedFirmwareVersion, 0, sizeof(pAccessory->stagedFirmwareVersion)); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetCorrupt(void *pAccessoryDelegate, void *pAssetDelegate) +{ + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + uarpLogInfo(kUARPLoggingCategoryPlatform, "Asset %u Corrupt from Controller %d", + pAsset->pAsset->core.assetID, + pAsset->pController->_controller._controller.remoteControllerID); + + if (pAsset == &(pAccessory->pSuperBinary)) + { + pAccessory->pSuperBinary.pController = NULL; + } + + /* must unstage asset */ + memset(&pAccessory->stagedFirmwareVersion, 0, sizeof(pAccessory->stagedFirmwareVersion)); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetOrphaned(void *pAccessoryDelegate, void *pAssetDelegate) +{ + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + if (pAsset == &(pAccessory->pSuperBinary)) + { + pAccessory->pSuperBinary.pController = NULL; + } + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetReady(void *pAccessoryDelegate, void *pAssetDelegate) +{ + uint32_t status; + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + status = uarpPlatformAccessoryAssetRequestMetaData(&(pAccessory->_accessory), pAsset->pAsset); + + if (status == kUARPStatusNoMetaData) + { + FMNASampleAssetMetaDataComplete(pAccessory, pAsset); + status = kUARPStatusSuccess; + } + __UARP_Require((status == kUARPStatusSuccess), exit); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetMetaDataTLV(void *pAccessoryDelegate, void *pAssetDelegate, + uint32_t tlvType, uint32_t tlvLength, uint8_t *pTlvValue) +{ + switch (tlvType) + { + default: + uarpLogInfo(kUARPLoggingCategoryProduct, "SuperBinary MetaData Option UNKNOWN %d, length %u", + tlvType, tlvLength); + break; + } + + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASampleAssetMetaDataComplete(void *pAccessoryDelegate, void *pAssetDelegate) +{ + uint32_t status; + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + status = uarpPlatformAssetSetPayloadIndex(&(pAccessory->_accessory), pAsset->pAsset, + kFMNASampleSuperBinaryPayloadIndexProto); + __UARP_Require((status == kUARPStatusSuccess), exit); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASamplePayloadReady(void *pAccessoryDelegate, void *pAssetDelegate) +{ + uint32_t status; + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + uarpLogInfo(kUARPLoggingCategoryProduct, "Payload Ready - Index %d Tag <%c%c%c%c>", + pAsset->pAsset->selectedPayloadIndex, + pAsset->pAsset->payload.payload4cc[0], + pAsset->pAsset->payload.payload4cc[1], + pAsset->pAsset->payload.payload4cc[2], + pAsset->pAsset->payload.payload4cc[3]); + + status = uarpPlatformAccessoryPayloadRequestMetaData(&(pAccessory->_accessory), pAsset->pAsset); + + if (status == kUARPStatusNoMetaData) + { + FMNASamplePayloadMetaDataComplete(pAccessory, pAsset); + status = kUARPStatusSuccess; + } + __UARP_Require((status == kUARPStatusSuccess), exit); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASamplePayloadMetaDataTLV(void *pAccessoryDelegate, void *pAssetDelegate, + uint32_t tlvType, uint32_t tlvLength, uint8_t *pTlvValue) +{ + uint32_t status; + UNUSED struct FMNASampleAsset *pAsset; + UNUSED struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + switch (tlvType) + { + default: + + status = kUARPStatusInvalidTLV; + + break; + } + __UARP_Require_Quiet((status == kUARPStatusInvalidTLV), exit); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASamplePayloadMetaDataComplete(void *pAccessoryDelegate, void *pAssetDelegate) +{ + uint32_t status; + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + status = uarpPlatformAccessoryPayloadRequestData(&(pAccessory->_accessory), pAsset->pAsset); + __UARP_Require((status == kUARPStatusSuccess), exit); + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +void FMNASamplePayloadData(void *pAccessoryDelegate, void *pAssetDelegate, + uint8_t *pBuffer, uint32_t lengthBuffer, uint32_t offset, + uint8_t *pAssetState, uint32_t lengthAssetState) +{ + uint8_t tagUnknown[kUARPSuperBinaryPayloadTagLength]; + static uint8_t tagSMPL[kUARPSuperBinaryPayloadTagLength] = { 'S', 'M', 'P', 'L' }; + struct FMNASampleAsset *pAsset; + UNUSED struct FMNASampleAccessory *pAccessory; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + if (pAsset->pAsset->payload.plHdr.payloadTag == uarpPayloadTagPack(tagSMPL)) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "SMPL RX %u bytes from offset %u", lengthBuffer, offset); + + } + else + { + uarpPayloadTagUnpack(pAsset->pAsset->payload.plHdr.payloadTag, tagUnknown); + + uarpLogInfo(kUARPLoggingCategoryProduct, "Unknown <%c%c%c%c> RX %u bytes from offset %u", + tagUnknown[0], tagUnknown[1], tagUnknown[2], tagUnknown[3], lengthBuffer, offset); + } + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ +void FMNASamplePayloadDataComplete(void *pAccessoryDelegate, void *pAssetDelegate) +{ + uint32_t status; + struct FMNASampleAsset *pAsset; + struct FMNASampleAccessory *pAccessory; + uint8_t cur_payload_index; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require(pAccessoryDelegate, exit); + + pAsset = (struct FMNASampleAsset *)pAssetDelegate; + __UARP_Require(pAssetDelegate, exit); + + pAccessory->hasPayload = kUARPYes; + + pAccessory->stagedFirmwareVersion = pAccessory->pSuperBinary.pAsset->core.assetVersion; + + cur_payload_index = pAsset->pAsset->selectedPayloadIndex; + + /* valid fw check */ + if (dfu_service_handle_valid_fw()) + { + if (cur_payload_index < total_payload_index) + { + /* Request the next image's payload header */ + cur_payload_index++; + status = uarpPlatformAssetSetPayloadIndex(&(pAccessory->_accessory), pAsset->pAsset, + cur_payload_index); + } + else + { + status = uarpPlatformAccessoryAssetFullyStaged(&(pAccessory->_accessory), pAsset->pAsset); + } + __UARP_Require((status == kUARPStatusSuccess), exit); + } + else + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Staged Assets corrupt"); + uarpAccessoryAssetCorrupt(&(pAccessory->_accessory._accessory), + pAsset->pAsset->pController->_controller.pDelegate, + pAsset->pAsset->core.assetID); + FMNASampleAssetCorrupt(pAccessoryDelegate, pAssetDelegate); + } + +__UARP_Verify_exit + return; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleApplyStagedAssets(void *pAccessoryDelegate, void *pControllerDelegate, + uint16_t *pFlags) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + struct FMNASampleController *pController; + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + __UARP_Require_Action(pAccessory, exit, status = kUARPStatusInvalidArgument); + + pController = (struct FMNASampleController *)pControllerDelegate; + __UARP_Require_Action(pController, exit, status = kUARPStatusInvalidArgument); + + if (pAccessory->pSuperBinary.pAsset == NULL) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Apply Staged Assets: Nothing staged"); + + *pFlags = kUARPApplyStagedAssetsFlagsNothingStaged; + } + else if ((pAccessory->stagedFirmwareVersion.major == 0) && + (pAccessory->stagedFirmwareVersion.minor == 0) && + (pAccessory->stagedFirmwareVersion.release == 0) && + (pAccessory->stagedFirmwareVersion.build == 0)) + { + uarpLogInfo(kUARPLoggingCategoryProduct, "Apply Staged Assets: Staging SuperBinary"); + + *pFlags = kUARPApplyStagedAssetsFlagsMidUpload; + } + else + { + uarpLogInfo(kUARPLoggingCategoryProduct, + "Apply Staged Assets: Updating Active FW Version to Staged FW Version"); + + pAccessory->activeFirmwareVersion = pAccessory->stagedFirmwareVersion; + + memset(&pAccessory->stagedFirmwareVersion, 0, sizeof(pAccessory->stagedFirmwareVersion)); + + /* Clean up superbinary */ + uarpPlatformAccessoryAssetRelease(&(pAccessory->_accessory), NULL, pAccessory->pSuperBinary.pAsset); + + pAccessory->pSuperBinary.pAsset = NULL; + pAccessory->pSuperBinary.pController = NULL; + + pAccessory->hasPayload = kUARPNo; + + /* set flags */ + *pFlags = kUARPApplyStagedAssetsFlagsSuccess; + + uarpPlatformCleanupAssets(&(pAccessory->_accessory)); + } + + /* done */ + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryManufacturerName(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength) +{ + uint32_t status; + uint32_t lengthNeeded; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pOptionString, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + lengthNeeded = (uint32_t)strlen(pAccessory->manufacturerName); + __UARP_Require_Action((*pLength >= lengthNeeded), exit, status = kUARPStatusInvalidLength); + + *pLength = lengthNeeded; + + memcpy(pOptionString, pAccessory->manufacturerName, *pLength); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryModelName(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength) +{ + uint32_t status; + uint32_t lengthNeeded; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pOptionString, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + lengthNeeded = (uint32_t)strlen(pAccessory->modelName); + __UARP_Require_Action((*pLength >= lengthNeeded), exit, status = kUARPStatusInvalidLength); + + *pLength = lengthNeeded; + + memcpy(pOptionString, pAccessory->modelName, *pLength); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQuerySerialNumber(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength) +{ + uint32_t status; + uint32_t lengthNeeded; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pOptionString, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + lengthNeeded = (uint32_t)strlen(pAccessory->serialNumber); + __UARP_Require_Action((*pLength >= lengthNeeded), exit, status = kUARPStatusInvalidLength); + + *pLength = lengthNeeded; + + memcpy(pOptionString, pAccessory->serialNumber, *pLength); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryHardwareVersion(void *pAccessoryDelegate, uint8_t *pOptionString, + uint32_t *pLength) +{ + uint32_t status; + uint32_t lengthNeeded; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pOptionString, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + lengthNeeded = (uint32_t)strlen(pAccessory->hardwareVersion); + __UARP_Require_Action((*pLength >= lengthNeeded), exit, status = kUARPStatusInvalidLength); + + *pLength = lengthNeeded; + + memcpy(pOptionString, pAccessory->hardwareVersion, *pLength); + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryActiveFirmwareVersion(void *pAccessoryDelegate, uint32_t assetTag, + struct UARPVersion *pVersion) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pVersion, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + if (assetTag == 0) + { + *pVersion = pAccessory->activeFirmwareVersion; + status = kUARPStatusSuccess; + } + else + { + memset(pVersion, 0, sizeof(struct UARPVersion)); + status = kUARPStatusInvalidAssetTag; + } + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryStagedFirmwareVersion(void *pAccessoryDelegate, uint32_t assetTag, + struct UARPVersion *pVersion) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pVersion, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + if (assetTag == 0) + { + *pVersion = pAccessory->stagedFirmwareVersion; + status = kUARPStatusSuccess; + } + else + { + memset(pVersion, 0, sizeof(struct UARPVersion)); + status = kUARPStatusInvalidAssetTag; + } + + +__UARP_Verify_exit + return status; +} + +/* -------------------------------------------------------------------------------- */ + +uint32_t FMNASampleQueryLastError(void *pAccessoryDelegate, struct UARPLastErrorAction *pLast) +{ + uint32_t status; + struct FMNASampleAccessory *pAccessory; + + __UARP_Require_Action(pAccessoryDelegate, exit, status = kUARPStatusInvalidArgument); + __UARP_Require_Action(pLast, exit, status = kUARPStatusInvalidArgument); + + pAccessory = (struct FMNASampleAccessory *)pAccessoryDelegate; + + pLast->lastAction = pAccessory->lastAction; + pLast->lastError = pAccessory->lastActionStatus; + + status = kUARPStatusSuccess; + +__UARP_Verify_exit + return status; +} diff --git a/src/app/findmy/fmna_adk/FMNASampleUARP.h b/src/app/findmy/fmna_adk/FMNASampleUARP.h new file mode 100644 index 0000000..3a8df86 --- /dev/null +++ b/src/app/findmy/fmna_adk/FMNASampleUARP.h @@ -0,0 +1,142 @@ +/* + * Disclaimer: IMPORTANT: This Apple software is supplied to you, by Apple Inc. ("Apple"), in your + * capacity as a current, and in good standing, Licensee in the MFi Licensing Program. Use of this + * Apple software is governed by and subject to the terms and conditions of your MFi License, + * including, but not limited to, the restrictions specified in the provision entitled "Public + * Software", and is further subject to your agreement to the following additional terms, and your + * agreement that the use, installation, modification or redistribution of this Apple software + * constitutes acceptance of these additional terms. If you do not agree with these additional terms, + * you may not use, install, modify or redistribute this Apple software. + * + * Subject to all of these terms and in consideration of your agreement to abide by them, Apple grants + * you, for as long as you are a current and in good-standing MFi Licensee, a personal, non-exclusive + * license, under Apple's copyrights in this Apple software (the "Apple Software"), to use, + * reproduce, and modify the Apple Software in source form, and to use, reproduce, modify, and + * redistribute the Apple Software, with or without modifications, in binary form, in each of the + * foregoing cases to the extent necessary to develop and/or manufacture "Proposed Products" and + * "Licensed Products" in accordance with the terms of your MFi License. While you may not + * redistribute the Apple Software in source form, should you redistribute the Apple Software in binary + * form, you must retain this notice and the following text and disclaimers in all such redistributions + * of the Apple Software. Neither the name, trademarks, service marks, or logos of Apple Inc. may be + * used to endorse or promote products derived from the Apple Software without specific prior written + * permission from Apple. Except as expressly stated in this notice, no other rights or licenses, + * express or implied, are granted by Apple herein, including but not limited to any patent rights that + * may be infringed by your derivative works or by other works in which the Apple Software may be + * incorporated. Apple may terminate this license to the Apple Software by removing it from the list + * of Licensed Technology in the MFi License, or otherwise in accordance with the terms of such MFi License. + * + * Unless you explicitly state otherwise, if you provide any ideas, suggestions, recommendations, bug + * fixes or enhancements to Apple in connection with this software ("Feedback"), you hereby grant to + * Apple a non-exclusive, fully paid-up, perpetual, irrevocable, worldwide license to make, use, + * reproduce, incorporate, modify, display, perform, sell, make or have made derivative works of, + * distribute (directly or indirectly) and sublicense, such Feedback in connection with Apple products + * and services. Providing this Feedback is voluntary, but if you do provide Feedback to Apple, you + * acknowledge and agree that Apple may exercise the license granted above without the payment of + * royalties or further consideration to Participant. + * The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, EXPRESS OR + * IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR + * IN COMBINATION WITH YOUR PRODUCTS. + * + * IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION + * AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + */ + +#ifndef FMNASampleUARP_h +#define FMNASampleUARP_h + +#include "CoreUARPPlatform.h" +#include "CoreUARPUtils.h" +#include "CoreUARPAccessory.h" +#include "CoreUARPProtocolDefines.h" +#include "CoreUARPPlatformAccessory.h" + +#define kFMNASampleInfoLength 128 +#define kFMNASampleMaxTxMsgPayloadSize 247 +#define kFMNASampleMaxRxMsgPayloadSize 247 +#define kFMNASamplePayloadWindowSize 512 + +#define kFMNASampleSuperBinaryPayloadIndexProto 0 +#define kFMNASampleSuperBinaryPayloadIndexEVT 1 +#define kFMNASampleSuperBinaryPayloadIndexDVT 2 +#define kFMNASampleSuperBinaryPayloadIndexPVT 3 + +struct FMNASampleAsset +{ + struct uarpPlatformAsset *pAsset; + + struct FMNASampleController *pController; +}; + +struct FMNASampleCallbacks +{ + fcnUarpAccessorySendMessage fSendMessage; +}; + +struct FMNASampleAccessory +{ + struct uarpPlatformAccessory _accessory; + + char manufacturerName[kFMNASampleInfoLength]; + char modelName[kFMNASampleInfoLength]; + char serialNumber[kFMNASampleInfoLength]; + char hardwareVersion[kFMNASampleInfoLength]; + + struct UARPVersion activeFirmwareVersion; + struct UARPVersion stagedFirmwareVersion; + + struct FMNASampleCallbacks callbacks; + + uint32_t lastAction; + uint32_t lastActionStatus; + + struct FMNASampleAsset pSuperBinary; + UARPBool hasPayload; +}; + +struct FMNASampleController +{ + struct uarpPlatformController _controller; + + void *pDelegate; + + uint8_t *pBuffer; + + // very simple queue + // Pending buffer since UARP could have up to 2 tx packets at the same time + uint8_t *pPendingBuffer; + uint16_t pendingLength; +}; + +extern uint8_t total_payload_index; + +uint32_t FMNASampleInit(struct FMNASampleAccessory *pAccessory, + const char *manufacturerName, + const char *modelName, + const char *serialNumber, + const char *hardwareVersion, + struct UARPVersion *pActiveFirmwareVersion, + struct UARPVersion *pStagedFirmwareVersion, + struct FMNASampleCallbacks *pCallbacks); + +uint32_t FMNASampleControllerAdd(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController); + +uint32_t FMNASampleControllerRemove(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController); + +uint32_t FMNASampleRecvMessage(struct FMNASampleAccessory *pAccessory, + struct FMNASampleController *pController, + uint8_t *pBuffer, uint32_t length); + +uint32_t FMNASampleSendMessageComplete(void *pAccessoryDelegate, + void *pControllerDelegate); + + +#endif /* FMNASampleUARP_h */ diff --git a/src/app/findmy/fmna_adk/fmna_adv.c b/src/app/findmy/fmna_adk/fmna_adv.c new file mode 100644 index 0000000..2e7258e --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_adv.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_util.h" +#include "fmna_constants.h" +#include "fmna_adv.h" +#include "fmna_state_machine.h" +#include "fmna_gatt.h" +#include "fmna_platform_includes.h" + +#define ADV_TYPE_FIND_MY 0x12 + +#define FMNA_ADV_STATUS_DEVICE_TYPE_FIND_MY 0x2 + +// bit position, e.g. bit 0 is position 0 +#define FMNA_ADV_STATUS_FLAG_DEVICE_TYPE_BITS_START_POS 4 +#define FMNA_ADV_STATUS_FLAG_DEVICE_TYPE_BITS_LENGTH 2 +#define FMNA_ADV_STATUS_FLAG_BATTERY_BITS_START_POS 6 +#define FMNA_ADV_STATUS_FLAG_BATTERY_BITS_LENGTH 2 +#define FMNA_ADV_STATUS_FLAG_MAINTENANCED_BIT_POS 2 + +// Separated fast advertising is used for UT finding, e.g. aggressive adv. +#define FMNA_SEPARATED_ADV_FAST_INTERVAL 0x30 /**< Fast advertising interval 30ms (in units of 0.625 ms.) */ +#define FMNA_SEPARATED_ADV_FAST_DURATION 12000 /**< The advertising duration of fast advertising 2 minutes (in units of 10 milliseconds.) */ +#define FMNA_SEPARATED_ADV_SLOW_INTERVAL 0xC80 /**< Slow advertising interval 2 seconds (in units of 0.625 ms.) */ +#define FMNA_SEPARATED_ADV_SLOW_DURATION 0 /**< The advertising duration of slow advertising forever (in units of 10 milliseconds.) */ + +static fmna_separated_adv_packet_t m_fmna_separated_adv_packet = {0}; + +const uint16_t fmna_separated_adv_fast_intv = FMNA_SEPARATED_ADV_FAST_INTERVAL; +const uint32_t fmna_separated_adv_fast_duration = FMNA_SEPARATED_ADV_FAST_DURATION; +const uint16_t fmna_separated_adv_slow_intv = FMNA_SEPARATED_ADV_SLOW_INTERVAL; +const uint32_t fmna_separated_adv_slow_duration = FMNA_SEPARATED_ADV_SLOW_DURATION; + +// Nearby fast advertising is used for leash break. +#define FMNA_NEARBY_ADV_FAST_INTERVAL 0x30 /**< Fast advertising interval 30ms (in units of 0.625 ms.) */ +#define FMNA_NEARBY_ADV_FAST_DURATION 300 /**< The advertising duration of fast advertising 3s (in units of 10 milliseconds.) */ +#define FMNA_NEARBY_ADV_SLOW_INTERVAL 0xC80 /**< Slow advertising interval 2 seconds (in units of 0.625 ms.) */ +#define FMNA_NEARBY_ADV_SLOW_DURATION 0 /**< The advertising duration of slow advertising forever (in units of 10 milliseconds.) */ + +static fmna_nearby_adv_packet_t m_fmna_nearby_adv_packet = {0}; + +const uint16_t fmna_nearby_adv_fast_intv = FMNA_NEARBY_ADV_FAST_INTERVAL; +const uint32_t fmna_nearby_adv_fast_duration = FMNA_NEARBY_ADV_FAST_DURATION; +const uint16_t fmna_nearby_adv_intv = FMNA_NEARBY_ADV_SLOW_INTERVAL; +const uint32_t fmna_nearby_adv_duration = FMNA_NEARBY_ADV_SLOW_DURATION; + +#define FMNA_PAIRING_ADV_FAST_INTERVAL 0x30 /**< Fast advertising interval 30ms (in units of 0.625 ms.) */ +#define FMNA_PAIRING_ADV_FAST_DURATION 60000 /**< The advertising duration of fast advertising 10min (in units of 10 milliseconds.) */ +#define FMNA_PAIRING_ADV_SLOW_INTERVAL 0x30 /**< Slow advertising interval 30ms (in units of 0.625 ms.) */ +#define FMNA_PAIRING_ADV_SLOW_DURATION 0 /**< The advertising duration of slow advertising forever (in units of 10 milliseconds.) */ + +static fmna_pairing_payload_t m_fmna_pairing_adv_payload = {0}; + +const uint16_t fmna_pairing_adv_fast_intv = FMNA_PAIRING_ADV_FAST_INTERVAL; +const uint32_t fmna_pairing_adv_fast_duration = FMNA_PAIRING_ADV_FAST_DURATION; +const uint16_t fmna_pairing_adv_slow_intv = FMNA_PAIRING_ADV_SLOW_INTERVAL; +const uint32_t fmna_pairing_adv_slow_duration = FMNA_PAIRING_ADV_SLOW_DURATION; + +void fmna_adv_reset_bd_addr(void) +{ + uint8_t default_bt_addr[FMNA_BLE_MAC_ADDR_BLEN]; + + fmna_adv_platform_get_default_bt_addr(default_bt_addr); + + // set address type bits for random static (0b11) + default_bt_addr[0] |= (uint8_t)FMNA_ADV_ADDR_TYPE_MASK; + + fmna_adv_platform_set_random_static_bt_addr(default_bt_addr); +} + +/// Overwrite the Bluetooth MAC address with the first 6 bytes of the public key.. +/// @details Top 2 bits of MSB should be set to 0b11 for Random Static GAP address type. +/// @param[in] current_pubkey Current key to set BT MAC address to. +/// @return Original top 2 bits of MSB to include in Find My ADV, so iOS can restore key. +static uint8_t overwrite_bd_addr(uint8_t current_pubkey[FMNA_PUBKEY_BLEN]) +{ + uint8_t new_bt_mac[FMNA_BLE_MAC_ADDR_BLEN]; + + memcpy(new_bt_mac, current_pubkey, FMNA_BLE_MAC_ADDR_BLEN); + // Set address type bits of public key bd_addr for random static, 0b11. + new_bt_mac[0] |= (uint8_t)FMNA_ADV_ADDR_TYPE_MASK; + + fmna_adv_platform_set_random_static_bt_addr(new_bt_mac); + + // Return original address type bits of public key bd_addr --> most significant bits + return ((current_pubkey[0] & FMNA_ADV_ADDR_TYPE_MASK) >> FMNA_ADV_OPT_ADDR_TYPE_SHIFT); +} + +#if HARDCODED_PAIRING_ENABLED +/// HARDCODED PAIRING FUNCTION: Separates hardcoded keys. +/// @param[in] keys Keys to separate and rotate through. +void organize_pub_keys(uint8_t *keys) +{ + current_key_index = 0; + for (uint8_t i = 0; i < NUM_OF_KEYS; i++) + { + memcpy(keys_to_rotate[i], &(keys[i * FMNA_PUBKEY_BLEN]), FMNA_PUBKEY_BLEN); + } +} +#endif + +static uint8_t get_fmna_status_flags_batt_bitfield(void) +{ + uint8_t bat_level = fmna_battery_platform_get_battery_level(); + + return ((uint8_t)(BF_VAL(bat_level, + FMNA_ADV_STATUS_FLAG_BATTERY_BITS_LENGTH, + FMNA_ADV_STATUS_FLAG_BATTERY_BITS_START_POS))); +} + +static uint8_t get_fmna_status_flags_device_type_bitfield(void) +{ + return ((uint8_t)(BF_VAL(FMNA_ADV_STATUS_DEVICE_TYPE_FIND_MY, + FMNA_ADV_STATUS_FLAG_DEVICE_TYPE_BITS_LENGTH, + FMNA_ADV_STATUS_FLAG_DEVICE_TYPE_BITS_START_POS))); +} + +/// Fills Pairing payload according to ADV spec. +static void fmna_pairing_adv_service_data_init(void) +{ + uint8_t product_data[PRODUCT_DATA_BLEN] = PRODUCT_DATA_VAL; + memcpy(m_fmna_pairing_adv_payload.product_data, + product_data, + PRODUCT_DATA_BLEN); + + uint8_t accessory_category[ACC_CATEGORY_MAX_LEN] = ACCESSORY_CATEGORY; + memcpy(m_fmna_pairing_adv_payload.acc_category, + accessory_category, + ACC_CATEGORY_MAX_LEN); + + m_fmna_pairing_adv_payload.battery_state = fmna_battery_platform_get_battery_level(); +} + +/// Fills Nearby payload according to ADV spec. +/// @param[in] current_pubkey Current FMNA primary key to use as BT MAC address. +static void fmna_nearby_adv_manuf_data_init(uint8_t current_pubkey[FMNA_PUBKEY_BLEN]) +{ + uint8_t pubkey_orig_addr_type_bits = overwrite_bd_addr(current_pubkey); + FMNA_LOG_INFO("fmna_nearby_adv_manuf_data_init"); + FMNA_LOG_HEXDUMP_DEBUG(current_pubkey, FMNA_PUBKEY_BLEN); + m_fmna_nearby_adv_packet.fmna_nearby_payload.opt = 0; + m_fmna_nearby_adv_packet.fmna_nearby_payload.opt |= pubkey_orig_addr_type_bits; + + m_fmna_nearby_adv_packet.type = ADV_TYPE_FIND_MY; + m_fmna_nearby_adv_packet.length = sizeof(struct fmna_nearby_payload_s); + + m_fmna_nearby_adv_packet.fmna_nearby_payload.status = 0; + m_fmna_nearby_adv_packet.fmna_nearby_payload.status |= get_fmna_status_flags_batt_bitfield(); + m_fmna_nearby_adv_packet.fmna_nearby_payload.status |= get_fmna_status_flags_device_type_bitfield(); + + if (fmna_state_machine_has_been_maintenanced()) + { + SET_BIT(m_fmna_nearby_adv_packet.fmna_nearby_payload.status, + FMNA_ADV_STATUS_FLAG_MAINTENANCED_BIT_POS); + } +} + +/// Fills Separated payload according to ADV spec. +/// @param[in] separated_pubkey Current FMNA primary separated key to use as BT MAC address. +/// @param[in] hint Current primary key hint for LTK reconciliation. +static void fmna_separated_adv_manuf_data_init(uint8_t separated_pubkey[FMNA_PUBKEY_BLEN], + uint8_t hint) +{ + uint8_t pubkey_orig_addr_type_bits = overwrite_bd_addr(separated_pubkey); + FMNA_LOG_INFO("fmna_separated_adv_manuf_data_init"); + FMNA_LOG_HEXDUMP_DEBUG(separated_pubkey, FMNA_PUBKEY_BLEN); + m_fmna_separated_adv_packet.fmna_separated_payload.extra = 0; + m_fmna_separated_adv_packet.fmna_separated_payload.extra |= pubkey_orig_addr_type_bits; + m_fmna_separated_adv_packet.fmna_separated_payload.hint = hint; + + m_fmna_separated_adv_packet.type = ADV_TYPE_FIND_MY; + m_fmna_separated_adv_packet.length = sizeof(struct fmna_separated_payload_s); + + m_fmna_separated_adv_packet.fmna_separated_payload.status = 0; + m_fmna_separated_adv_packet.fmna_separated_payload.status |= get_fmna_status_flags_batt_bitfield(); + m_fmna_separated_adv_packet.fmna_separated_payload.status |= + get_fmna_status_flags_device_type_bitfield(); + + // Copy 22 bytes from the public key provided to the manufacturer payload buffer + memcpy(m_fmna_separated_adv_packet.fmna_separated_payload.pubkey2, + separated_pubkey + FMNA_BLE_MAC_ADDR_BLEN, + FMNA_SEPARATED_ADV_PAYLOAD_PUBKEY_BLEN); +} + +void fmna_adv_init_pairing(void) +{ + fmna_adv_platform_stop_adv(); + + fmna_pairing_adv_service_data_init(); + + fmna_adv_platform_init_pairing((uint8_t *)&m_fmna_pairing_adv_payload, + sizeof(m_fmna_pairing_adv_payload)); +} + +void fmna_adv_init_separated(uint8_t separated_pubkey[FMNA_PUBKEY_BLEN], uint8_t hint) +{ + fmna_adv_platform_stop_adv(); + + // Initialize separated manufacturing data with the separated public key and hint + fmna_separated_adv_manuf_data_init(separated_pubkey, hint); + + fmna_adv_platform_init_separated((uint8_t *)&m_fmna_separated_adv_packet, + sizeof(m_fmna_separated_adv_packet)); +} + +void fmna_adv_init_nearby(uint8_t pubkey[FMNA_PUBKEY_BLEN]) +{ + fmna_adv_platform_stop_adv(); + + // Initialize Nearby manufacturing data with the public key + fmna_nearby_adv_manuf_data_init(pubkey); + + fmna_adv_platform_init_nearby((uint8_t *)&m_fmna_nearby_adv_packet, + sizeof(m_fmna_nearby_adv_packet)); +} diff --git a/src/app/findmy/fmna_adk/fmna_adv.h b/src/app/findmy/fmna_adk/fmna_adv.h new file mode 100644 index 0000000..df83493 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_adv.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_adv_h +#define fmna_adv_h + +#include "fmna_constants.h" +#include "fmna_adv_platform.h" + +typedef struct +{ + uint8_t type; + uint8_t length; + struct fmna_separated_payload_s + { + uint8_t status; + uint8_t pubkey2[FMNA_SEPARATED_ADV_PAYLOAD_PUBKEY_BLEN]; + uint8_t extra; + uint8_t hint; + } __attribute__((packed)) fmna_separated_payload; +} __attribute__((packed)) fmna_separated_adv_packet_t; // BLE manufacturer data + +typedef struct +{ + uint8_t type; + uint8_t length; + struct fmna_nearby_payload_s + { + uint8_t status; + uint8_t opt; + } __attribute__((packed)) fmna_nearby_payload; +} __attribute__((packed)) fmna_nearby_adv_packet_t; // BLE manufacturer data + +#define RESERVED_BLEN 4 + +typedef struct fmna_pairing_payload_s +{ + uint8_t product_data[PRODUCT_DATA_BLEN]; + uint8_t acc_category[ACC_CATEGORY_MAX_LEN]; + uint8_t reserved[RESERVED_BLEN]; + uint8_t battery_state; +} __attribute__((packed)) fmna_pairing_payload_t; + +extern const uint16_t fmna_separated_adv_fast_intv; +extern const uint32_t fmna_separated_adv_fast_duration; +extern const uint16_t fmna_separated_adv_slow_intv; +extern const uint32_t fmna_separated_adv_slow_duration; +extern const uint16_t fmna_nearby_adv_fast_intv; +extern const uint32_t fmna_nearby_adv_fast_duration; +extern const uint16_t fmna_nearby_adv_intv; +extern const uint32_t fmna_nearby_adv_duration; +extern const uint16_t fmna_pairing_adv_fast_intv; +extern const uint32_t fmna_pairing_adv_fast_duration; +extern const uint16_t fmna_pairing_adv_slow_intv; +extern const uint32_t fmna_pairing_adv_slow_duration; + +#define FMNA_ADV_OPT_ADDR_TYPE_SHIFT 6 +#define FMNA_ADV_ADDR_TYPE_MASK (0x03 << FMNA_ADV_OPT_ADDR_TYPE_SHIFT) + +#define fmna_adv_start_fast_adv fmna_adv_platform_start_fast_adv +#define fmna_adv_start_slow_adv fmna_adv_platform_start_slow_adv +#define fmna_adv_stop_adv fmna_adv_platform_stop_adv +#define fmna_adv_get_unpaired_bt_addr fmna_adv_platform_get_default_bt_addr + +/// Reset BT address to be default out-of-box address. +/// +/// @details Read the default address and set the appropriate BLE GAP 0b11 bits for Random Static address setting. +void fmna_adv_reset_bd_addr(void); + +/// Setup Pairing advertisement. +void fmna_adv_init_pairing(void); + +/// Setup Separated advertising with public key and hint. +/// +/// @param[in] separated_pubkey Current primary separated key, e.g. latched key. +/// @param[in] hint Byte 5 of current primary key. +void fmna_adv_init_separated(uint8_t separated_pubkey[FMNA_PUBKEY_BLEN], uint8_t hint); + +/// Setup Separated advertising with public key. +/// +/// @param[in] pubkey Current primary key. +void fmna_adv_init_nearby(uint8_t pubkey[FMNA_PUBKEY_BLEN]); + +#if HARDCODED_PAIRING_ENABLED +/// HARDCODED PAIRING FUNCTION: Separates hardcoded keys. +/// @param[in] keys Keys to separate and rotate through. +void organize_pub_keys(uint8_t *keys); +#endif + +#endif /* fmna_adv_h */ diff --git a/src/app/findmy/fmna_adk/fmna_config_control_point.c b/src/app/findmy/fmna_adk/fmna_config_control_point.c new file mode 100644 index 0000000..7c610fb --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_config_control_point.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" +#include "fmna_config_control_point.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_connection.h" +#include "fmna_adv.h" + +typedef struct +{ + uint16_t opcode; + FMNA_Response_Status_t status; +} __attribute__((packed)) command_response_data_t; + +//MARK: RX Packet Definitions + +typedef struct +{ + FMNA_Service_Opcode_t persistent_connection_status_opcode; + bool status; +} __attribute__((packed)) persistent_connection_status_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t set_nearby_timeout_opcode; + uint16_t timeout_seconds; +} __attribute__((packed)) set_nearby_timeout_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t configure_separated_state_opcode; + uint32_t next_key_roll_ms; + uint32_t secondary_key_evaluation_index; +} __attribute__((packed)) configure_separated_state_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t set_max_connections_opcode; + uint8_t max_connections; +} __attribute__((packed)) set_max_connections_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t set_utc_opcode; + uint64_t current_time; +} __attribute__((packed)) set_utc_packet_t; + +/// RX Length Check managers for default and variable length cases. +static fmna_service_length_check_manager_t rx_length_check_managers[] = \ +{ + /* RX Opcode Data Length */ + { FMNA_SERVICE_OPCODE_SOUND_START, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_OPCODE_SOUND_STOP, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_OPCODE_PERSISTENT_CONNECTION_STATUS, sizeof(persistent_connection_status_packet_t) }, + { FMNA_SERVICE_OPCODE_SET_NEARBY_TIMEOUT, sizeof(set_nearby_timeout_packet_t) }, + { FMNA_SERVICE_OPCODE_UNPAIR, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_OPCODE_CONFIGURE_SEPARATED_STATE, sizeof(configure_separated_state_packet_t) }, + { FMNA_SERVICE_OPCODE_LATCH_SEPARATED_KEY, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_OPCODE_SET_MAX_CONNECTIONS, sizeof(set_max_connections_packet_t) }, + { FMNA_SERVICE_OPCODE_SET_UTC, sizeof(set_utc_packet_t) }, + { FMNA_SERVICE_OPCODE_GET_MULTI_STATUS, sizeof(generic_control_point_packet_t) }, +}; + +static FMNA_Response_Status_t rx_error_check(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + uint8_t const *data, uint16_t length) +{ + // Reject config CP messages if we're not FMNA paired. + if (!fmna_connection_is_fmna_paired()) + { + FMNA_LOG_ERROR("conn_handle 0x%x not FMNA paired, reject message.", conn_handle); + return RESPONSE_STATUS_INVALID_STATE; + } + + if (!fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + // If this connection is not encrypted, do not allow config CP messages. + FMNA_LOG_ERROR("conn_handle 0x%x not encrypted, reject.", conn_handle); + return RESPONSE_STATUS_INVALID_STATE; + } + + return fmna_gatt_verify_control_point_opcode_and_length(opcode, length, rx_length_check_managers, + FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(rx_length_check_managers)); +} + +void fmna_config_control_point_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length) +{ + FMNA_Service_Opcode_t opcode = *(FMNA_Service_Opcode_t *)data; + + FMNA_Response_Status_t response_status = rx_error_check(conn_handle, opcode, data, length); + if (response_status != RESPONSE_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("Rx error 0x%x for opcode 0x%x, conn_handle 0x%x", response_status, opcode, + conn_handle); + if (response_status == RESPONSE_STATUS_INVALID_COMMAND) + { + opcode = FMNA_SERVICE_OPCODE_NONE; + } + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + return; + } + + // Initialize response status, since we will send command response for expected commands at the end of the switch statement. + // Commands that have their own responses will be handled within their case and will NOT send command response. + response_status = RESPONSE_STATUS_NO_COMMAND_RESPONSE; + + FMNA_LOG_INFO("Configuration rx: opcode = 0x%x, conn_handle 0x%x", opcode, conn_handle); + + switch (opcode) + { + case FMNA_SERVICE_OPCODE_SOUND_START: + { + FMNA_LOG_INFO("RX Sound Start"); + if (fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_PLAYING_SOUND)) + { + FMNA_LOG_ERROR("Sound session already in progress"); + response_status = RESPONSE_STATUS_INVALID_STATE; + } + else + { + // Update the multi status in case another play sound request comes before we execute play sound state machine handler. + fmna_connection_update_connection_info(conn_handle, FMNA_MULTI_STATUS_PLAYING_SOUND, true); + response_status = RESPONSE_STATUS_SUCCESS; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_START); + } + } break; + + case FMNA_SERVICE_OPCODE_SOUND_STOP: + { + FMNA_LOG_INFO("RX Sound Stop"); + if (!fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_PLAYING_SOUND)) + { + FMNA_LOG_WARNING("No sound session in progress"); + response_status = RESPONSE_STATUS_INVALID_STATE; + } + else + { + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_STOP); + } + } break; + + case FMNA_SERVICE_OPCODE_PERSISTENT_CONNECTION_STATUS: + { + persistent_connection_status_packet_t *packet = (persistent_connection_status_packet_t *)data; + + FMNA_LOG_INFO("RX Persistent Connection Status %d", packet->status); + + if (packet->status == false) + { + // Disable persistent connections. + fmna_connection_update_connection_info(conn_handle, FMNA_MULTI_STATUS_PERSISTENT_CONNECTION, false); + } + //only set persistent connection if no other links are persistent + else if (fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, + FMNA_MULTI_STATUS_PERSISTENT_CONNECTION) == false) + { + fmna_connection_update_connection_info(conn_handle, FMNA_MULTI_STATUS_PERSISTENT_CONNECTION, true); + + //start slow advertising + if (fmna_state_machine_is_persistent_connection_disconnection() && + (fmna_connection_get_num_connections() < fmna_connection_get_max_connections())) + { + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + fmna_adv_start_slow_adv(); + } + fmna_state_machine_set_persistent_connection_disconnection(false); + } + + response_status = RESPONSE_STATUS_SUCCESS; + } break; + + case FMNA_SERVICE_OPCODE_SET_NEARBY_TIMEOUT: + { + set_nearby_timeout_packet_t *packet = (set_nearby_timeout_packet_t *)data; + FMNA_LOG_INFO("RX Set Nearby Timeout, seconds: %d", packet->timeout_seconds); + + if (packet->timeout_seconds > NEARBY_TIMEOUT_MAX_SECONDS) + { + response_status = RESPONSE_STATUS_INVALID_PARAM; + } + else + { + fmna_state_machine_set_nearby_timeout_seconds(packet->timeout_seconds); + response_status = RESPONSE_STATUS_SUCCESS; + } + } break; + + case FMNA_SERVICE_OPCODE_LATCH_SEPARATED_KEY: + FMNA_LOG_INFO("RX Latch_Separated_Key"); + fmna_state_machine_latch_current_separated_key(conn_handle); + + break; + + case FMNA_SERVICE_OPCODE_SET_MAX_CONNECTIONS: + { + set_max_connections_packet_t *packet = (set_max_connections_packet_t *)data; +#if SUPPORT_CUSTOMIZED_APP + if (cust_feature_is_enabled() && packet->max_connections >= MAX_SUPPORTED_CONNECTIONS) + { + APP_PRINT_INFO0("cust adv is enabled, fmna max_connection set to 1"); + packet->max_connections = 1; + } +#endif + FMNA_LOG_INFO("RX Set_Max_Connections to %d", packet->max_connections); + + fmna_connection_set_max_connections(packet->max_connections, conn_handle); + } break; + + case FMNA_SERVICE_OPCODE_UNPAIR: + FMNA_LOG_INFO("RX Unpair"); + + if ((fmna_connection_get_max_connections() > 1) + || (fmna_connection_get_num_connections() != 1)) + { + // Unpair not allowed unless iOS sets max connections to 1 + // and only one central is connected to us. + response_status = RESPONSE_STATUS_INVALID_STATE; + } + else + { + fmna_connection_set_unpair_pending(true); + os_timer_start(&unpair_pending_timer); + response_status = RESPONSE_STATUS_SUCCESS; + } + break; + + case FMNA_SERVICE_OPCODE_CONFIGURE_SEPARATED_STATE: + { + FMNA_LOG_INFO("RX Configure Separated State"); + configure_separated_state_packet_t *packet = (configure_separated_state_packet_t *)data; + + if (((packet->secondary_key_evaluation_index + SEPARATED_STATE_CONFIG_NEGATIVE_BOUNDARY) < + m_fmna_current_primary_key.index) + || (packet->secondary_key_evaluation_index > (m_fmna_current_primary_key.index + + PRIMARY_KEYS_PER_SECONDARY_KEY))) + { + FMNA_LOG_ERROR("invalid Separated Mode Config Index: %#x", packet->secondary_key_evaluation_index); + response_status = RESPONSE_STATUS_INVALID_PARAM; + break; + } + + if (packet->next_key_roll_ms > m_fmna_key_rotation_timeout_ms) + { + FMNA_LOG_ERROR("invalid Separated Mode Config next keyroll ms: %d", packet->next_key_roll_ms); + response_status = RESPONSE_STATUS_INVALID_PARAM; + break; + } + + fmna_state_machine_set_next_secondary_key_rotation_index(conn_handle, + packet->secondary_key_evaluation_index); + fmna_state_machine_set_next_keyroll_ms(packet->next_key_roll_ms); + } break; + + case FMNA_SERVICE_OPCODE_SET_UTC: + FMNA_LOG_INFO("Set_UTC command received"); + //TODO: Set UTC here + response_status = RESPONSE_STATUS_SUCCESS; + break; + + case FMNA_SERVICE_OPCODE_GET_MULTI_STATUS: + FMNA_LOG_INFO("RX Get Multi Status"); + fmna_connection_send_multi_status(conn_handle); + break; + + default: + // We should never get here! rx_error_check should check for unknown command and respond with failed command response. + FMNA_LOG_ERROR("Invalid opcode for configuration control point received"); + } + + if (RESPONSE_STATUS_NO_COMMAND_RESPONSE != response_status) + { + // Send command response if this command needs one. + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + } +} + +bool fmna_config_control_point_is_tx_allowed(uint16_t conn_handle, FMNA_Service_Opcode_t opcode) +{ + bool is_tx_allowed = true; + + if (!fmna_connection_is_fmna_paired() || + !fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + FMNA_LOG_ERROR("Reject TX opcode 0x%x, conn_handle 0x%x. FMNA paired? %d, Encrypted? %d", + opcode, + conn_handle, + fmna_connection_is_fmna_paired(), + fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)); + is_tx_allowed = false; + } + + return is_tx_allowed; +} diff --git a/src/app/findmy/fmna_adk/fmna_config_control_point.h b/src/app/findmy/fmna_adk/fmna_config_control_point.h new file mode 100644 index 0000000..0efc73f --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_config_control_point.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_config_control_point_h +#define fmna_config_control_point_h + +#include "fmna_gatt.h" + +/// Function for handling the different Configuration opcodes. +/// @param data Buffer of data of configuration opcode and possible operands +void fmna_config_control_point_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length); +bool fmna_config_control_point_is_tx_allowed(uint16_t conn_handle, FMNA_Service_Opcode_t opcode); + +#endif /* fmna_config_control_point_h */ diff --git a/src/app/findmy/fmna_adk/fmna_connection.c b/src/app/findmy/fmna_adk/fmna_connection.c new file mode 100644 index 0000000..7c1314a --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_connection.c @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" + +#include "fmna_util.h" +#include "fmna_constants.h" +#include "fmna_connection.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_adv.h" +#include "fmna_pairing_control_point.h" +#include "fmna_peer_manager.h" +#include "fmna_crypto.h" +#if SUPPORT_NFC +#include "fmna_nfc.h" +#endif + +// Flag to determine whether we need to wait for disconnections to send +// set max connections response. +static bool m_fmna_delayed_max_conn = false; + +static bool m_is_fmna_paired = false; + +fmna_active_conn_info_t m_fmna_active_connections[MAX_SUPPORTED_CONNECTIONS]; + +// Default 1 connection only +static uint8_t m_max_connections = 1; + +// Unpair pending flag to keep track of unpair commit state. +static bool m_unpair_pending = false; + +static uint8_t m_active_ltk[GAP_SEC_KEY_LEN]; + +//MARK: Private Functions + +/// Initializes fmna_active_conn_info_t struct for this connection. +/// @details Ensures valid connection handle and this connection does not already exist. Disconnect for invalid connection. +/// @param[in] conn_intv Negotiated connection interval. +static void init_connection_info(uint16_t conn_handle, uint16_t conn_intv) +{ + // ensure connection handle is within number of allowed links + bool is_valid_conn_handle = conn_handle < MAX_SUPPORTED_CONNECTIONS; + + if (!is_valid_conn_handle + // ensure this connection handle is not already allocated + || (m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID)) + { + FMNA_LOG_ERROR("Invalid connection, disconnect conn_handle 0x%x", conn_handle); + fmna_ret_code_t ret_code = fmna_connection_platform_disconnect(conn_handle); + FMNA_ERROR_CHECK(ret_code); + return; + } + + // clear all the multi status bits + memset(&(m_fmna_active_connections[conn_handle].multi_status), 0, sizeof(uint32_t)); + + m_fmna_active_connections[conn_handle].conn_handle = conn_handle; + m_fmna_active_connections[conn_handle].conn_intv = conn_intv; +} + +/// Clears fmna_active_conn_info_t struct for this connection, on a disconnection. +/// @details Link is already disconnected at this point. This function is cleanup. +static void clear_connection_info(uint16_t conn_handle) +{ + // Ensure connection handle is within number of allowed links + if (conn_handle >= MAX_SUPPORTED_CONNECTIONS) + { + FMNA_LOG_ERROR("Invalid disconnection, conn_handle 0x%x", conn_handle); + return; + } + + m_fmna_active_connections[conn_handle].conn_handle = CONN_HANDLE_INVALID; +} + +/// Checks whether this connection has a particular multi status bit enabled. +/// @param[in] status Multi status bit to check. +/// @return True is this connection handle is a valid connection and has this multi status bit enabled. False otherwise. +static bool is_multi_status_bit_enabled(uint16_t conn_handle, FMNA_Multi_Status_t status) +{ + if (!fmna_connection_is_valid_connection(conn_handle)) + { + return false; + } + + return ((m_fmna_active_connections[conn_handle].multi_status & (1 << status)) != 0); +} + +/// Get multi status of all active connections. +static uint32_t fmna_connection_get_multi_status_all(void) +{ + uint32_t multi_status = 0; + + // Bitwise OR all the multi-statuses from all active connections. + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID) + { + multi_status |= m_fmna_active_connections[conn_handle].multi_status; + } + } + + return multi_status; +} + +/// Return whether multiple owners are currently connected. +/// +/// @details Go through all active connections, except the connection querying multi status, +/// and check encryption status. +/// +/// @param current_conn_handle Handle of connection querying multi status. +/// +/// @return True If another connection, other than this connection, is encrypted. False, otherwise. +/// +static bool is_multiple_owners_connected(uint16_t current_conn_handle) +{ + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (conn_handle != current_conn_handle + && m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID) + { + if (fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + return true; + } + } + } + + return false; +} + +//MARK: Public Functions + +void fmna_connection_init(void) +{ + // Set all connection info to 0xFF so that, initially, all connection handles are invalid. + for (uint8_t i = 0; i < MAX_SUPPORTED_CONNECTIONS; i++) + { + m_fmna_active_connections[i].conn_handle = CONN_HANDLE_INVALID; + } +} + +bool fmna_connection_is_valid_connection(uint16_t conn_handle) +{ + // Ensure connection handle is within number of allowed links. + if (conn_handle >= MAX_SUPPORTED_CONNECTIONS + // Ensure this is an active connection. + || m_fmna_active_connections[conn_handle].conn_handle == CONN_HANDLE_INVALID) + { + return false; + } + return true; +} + +bool fmna_connection_is_status_bit_enabled(uint16_t conn_handle, FMNA_Multi_Status_t status) +{ + if (CONN_HANDLE_ALL != conn_handle) + { + return is_multi_status_bit_enabled(conn_handle, status); + } + + // Check all connections to see if multi status bit is enabled + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (is_multi_status_bit_enabled(conn_handle, status)) + { + return true; + } + } + return false; +} + +uint16_t fmna_connection_get_conn_handle_with_multi_status_enabled(FMNA_Multi_Status_t status) +{ + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (is_multi_status_bit_enabled(conn_handle, status)) + { + return conn_handle; + } + } + + // No connection with that status bit enabled - return invalid + return CONN_HANDLE_INVALID; +} + +void fmna_connection_disconnect_all(void) +{ + fmna_ret_code_t ret_code; + + for (uint16_t conn_handle = 0; conn_handle < m_max_connections; conn_handle++) + { + ret_code = fmna_connection_platform_disconnect(conn_handle); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("fmna_connection_platform_disconnect err 0x%x", ret_code); + } + } +} + +void fmna_connection_disconnect_this(void) +{ + fmna_ret_code_t ret_code = fmna_connection_platform_disconnect( + fmna_gatt_get_most_recent_conn_handle()); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("fmna_connection_platform_disconnect err 0x%x", ret_code); + } +} + +static uint32_t m_multi_status; +void fmna_connection_send_multi_status(uint16_t conn_handle) +{ + m_multi_status = fmna_connection_get_multi_status_all(); + + // Check if any other connection other than this connection is encrypted. + if (is_multiple_owners_connected(conn_handle)) + { + // Set the bit + m_multi_status |= (1 << FMNA_MULTI_STATUS_IS_MULTIPLE_OWNERS_CONNECTED); + } + + fmna_gatt_send_indication(conn_handle, FMNA_SERVICE_OPCODE_GET_MULTI_STATUS_RESPONSE, + &m_multi_status, sizeof(m_multi_status)); +} + +void fmna_connection_update_connection_info(uint16_t conn_handle, FMNA_Multi_Status_t status, + bool enable) +{ + if (!fmna_connection_is_valid_connection(conn_handle)) + { + FMNA_LOG_ERROR("Unable to update connection info for invalid conn_handle 0x%x", conn_handle); + return; + } + + if (enable) + { + // Set the bit + m_fmna_active_connections[conn_handle].multi_status |= (1 << status); + } + else + { + // Clear the bit + m_fmna_active_connections[conn_handle].multi_status &= ~(1 << status); + } +} + +void fmna_connection_update_connection_info_all(FMNA_Multi_Status_t status, bool enable) +{ + for (uint8_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID) + { + fmna_connection_update_connection_info(conn_handle, status, enable); + } + } +} + +uint8_t fmna_connection_get_num_connections(void) +{ + uint8_t num_connections = 0; + for (uint8_t i = 0; i < MAX_SUPPORTED_CONNECTIONS; i++) + { + if (m_fmna_active_connections[i].conn_handle != CONN_HANDLE_INVALID) + { + num_connections++; + } + } + return num_connections; +} + +void fmna_connection_set_max_connections(uint8_t max_connections, uint16_t conn_handle) +{ + fmna_ret_code_t ret_code; + + // Check if provided max connections number is valid. + if (max_connections == 0) + { + FMNA_LOG_ERROR("Cannot set max connections to 0."); + return; + } + else if (max_connections > MAX_SUPPORTED_CONNECTIONS) + { + FMNA_LOG_ERROR("Maintaining %d simultaneous connections is not supported. Defaulting to max supported: %d connections.", + max_connections, + MAX_SUPPORTED_CONNECTIONS); + max_connections = MAX_SUPPORTED_CONNECTIONS; + } + + m_max_connections = max_connections; + + // Stop advertisement in preparation. + fmna_adv_stop_adv(); + + if (fmna_connection_get_num_connections() < m_max_connections) + { + // Room for more connections; (re)start advertiing Nearby. + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + fmna_adv_start_slow_adv(); + } + + // Forced to accept only 1 connection. Disconnect all others (who didn't send this command). + if (max_connections == 1) + { + for (uint16_t handle = 0; handle < MAX_SUPPORTED_CONNECTIONS; ++handle) + { + // For every valid, active connection that is not THIS connection... + if (handle != conn_handle && m_fmna_active_connections[handle].conn_handle != CONN_HANDLE_INVALID) + { + // Disconnect. Set m_fmna_delayed_max_conn to respond to iOS max connections command + // on disconnect confirm for all relevant connections. + m_fmna_delayed_max_conn = true; + ret_code = fmna_connection_platform_disconnect(handle); + FMNA_ERROR_CHECK(ret_code); + } + } + } + + if (!m_fmna_delayed_max_conn) + { + // No other connections to disconnect, respond immediately. + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, conn_handle, + FMNA_SERVICE_OPCODE_SET_MAX_CONNECTIONS, RESPONSE_STATUS_SUCCESS); + } +} + +void fmna_connection_connected_handler(uint16_t conn_handle, uint16_t conn_interval) +{ + FMNA_LOG_INFO("Connected, conn_handle 0x%x", conn_handle); + + // Initialize connection info for this new connection. + init_connection_info(conn_handle, conn_interval); + + // Send the event into the state machine. + fmna_evt_handler(FMNA_SM_EVENT_CONNECTED, &conn_handle); +} + +void fmna_connection_conn_param_update_handler(uint16_t conn_handle, uint16_t conn_interval) +{ + FMNA_LOG_INFO("Connection parameters updated, conn_handle 0x%x", conn_handle); + + // Update the connection interval negotiated. + m_fmna_active_connections[conn_handle].conn_intv = conn_interval; +} + +void fmna_connection_disconnected_handler(uint16_t conn_handle) +{ + FMNA_LOG_INFO("Disconnected, conn_handle 0x%x", conn_handle); + + // Check if this is a persistent connection disconnection by confirming if this bit is set in multi status. + bool is_persistent_connection_disconnection = fmna_connection_is_status_bit_enabled(conn_handle, + FMNA_MULTI_STATUS_PERSISTENT_CONNECTION); + + // Clear this connection info. + clear_connection_info(conn_handle); + + fmna_evt_handler(FMNA_SM_EVENT_DISCONNECTED, &conn_handle); + + if (fmna_connection_is_fmna_paired() && fmna_connection_get_num_connections() > 0) + { + // Restart Nearby advertising if there is still room for more connections. + if (fmna_connection_get_num_connections() < m_max_connections) + { + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + if (is_persistent_connection_disconnection) + { + fmna_adv_start_fast_adv(); + } + else + { + fmna_adv_start_slow_adv(); + } + } + } + else if (is_persistent_connection_disconnection) + { + fmna_state_machine_set_persistent_connection_disconnection(true); + } + + if (m_fmna_delayed_max_conn && fmna_connection_get_num_connections() <= 1) + { + // All necessary disconnections to enforce ower max connections are complete, + // clear the flag and send the response now. + m_fmna_delayed_max_conn = false; + + // Check which connection is still up, e.g. the connection that enforced lower max connections count, and send response. + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, + fmna_connection_get_conn_handle_with_multi_status_enabled(FMNA_MULTI_STATUS_ENCRYPTED), + FMNA_SERVICE_OPCODE_SET_MAX_CONNECTIONS, + RESPONSE_STATUS_SUCCESS); + } +} + +extern bool le_set_local_ltk(T_LE_KEY_ENTRY *p_entry, uint8_t key_length, uint8_t *p_ltk); +/// Set the LTK to swap existing LTK with for connection. +void fmna_connection_set_active_ltk(uint8_t new_ltk[GAP_SEC_KEY_LEN]) +{ + memcpy(m_active_ltk, new_ltk, GAP_SEC_KEY_LEN); + T_LE_KEY_ENTRY *p_key = le_find_key_entry_by_idx(app_global_data.app_bond_idx[FINDMY_BOND]); + if (le_set_local_ltk(p_key, GAP_SEC_KEY_LEN, m_active_ltk)) + { + FMNA_LOG_INFO("LTK replace success"); + } + else + { + FMNA_LOG_ERROR("LTK replace failed"); + } +} + +uint8_t *fmna_connection_get_active_ltk(void) +{ + return m_active_ltk; +} + +#include "ftl.h" +void fmna_connection_set_is_fmna_paired(bool is_paired) +{ + m_is_fmna_paired = is_paired; + uint32_t for_save = (uint32_t)is_paired; + ftl_save(&for_save, FTL_SAVE_PAIR_STATE_ADDR, FTL_SAVE_PAIR_STATE_SIZE); +} + +void fmna_connection_pair_info_restore(void) +{ + uint32_t for_load = false; + if (ftl_load(&for_load, FTL_SAVE_PAIR_STATE_ADDR, FTL_SAVE_PAIR_STATE_SIZE)) + { + m_is_fmna_paired = false; + } + else + { + if (for_load) + { + m_is_fmna_paired = true; + } + else + { + m_is_fmna_paired = false; + } + } + APP_PRINT_INFO1("fmna_connection_pair_info_restore %d", m_is_fmna_paired); +} + +bool fmna_connection_is_fmna_paired(void) +{ + return m_is_fmna_paired; +} + +void fmna_connection_fmna_unpair(bool force_disconnect) +{ + FMNA_LOG_INFO("FMNA unpair"); + + fmna_ret_code_t ret_code; + os_timer_stop(&unpair_pending_timer); + + // Delete the bonds + fmna_pm_delete_bonds(); + + // reset address + fmna_adv_reset_bd_addr(); + + // stop key rotation timers + fmna_state_machine_stop_key_rotation_timers(); +#ifdef DEBUG + m_fmna_key_rotation_timeout_ms = MIN_TO_MSEC(15); +#endif + + fmna_state_machine_set_persistent_connection_disconnection(false); + m_max_connections = 1; + + // Force disconnect if specified and connection is active. + if (force_disconnect) + { + for (uint8_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; ++conn_handle) + { + if (m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID) + { + ret_code = fmna_connection_platform_disconnect(conn_handle); + FMNA_ERROR_CHECK(ret_code); + } + } + } + + fmna_crypto_unpair(); + + fmna_connection_set_is_fmna_paired(false); + + // Other modules' unpair cleanup + fmna_state_machine_clear_keys(); +#if SUPPORT_NFC + fmna_nfc_load_unpaired_url(); +#endif + fmna_pairing_control_point_unpair(); + + fmna_gatt_reset_queues(); + + fmna_connection_platform_fmna_unpair(); +} + +uint8_t fmna_connection_get_max_connections(void) +{ + return m_max_connections; +} + +void fmna_connection_set_unpair_pending(bool enable) +{ + m_unpair_pending = enable; +} + +bool fmna_connection_get_unpair_pending(void) +{ + return m_unpair_pending; +} diff --git a/src/app/findmy/fmna_adk/fmna_connection.h b/src/app/findmy/fmna_adk/fmna_connection.h new file mode 100644 index 0000000..efc80b0 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_connection.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_connection_h +#define fmna_connection_h + +#include "fmna_connection_platform.h" + +// Multi status bits +typedef enum +{ + FMNA_MULTI_STATUS_PERSISTENT_CONNECTION = 0, + FMNA_MULTI_STATUS_PLAYING_SOUND = 2, + FMNA_MULTI_STATUS_UPDATING_FIRMWARE = 3, + FMNA_MULTI_STATUS_ENCRYPTED = 5, + FMNA_MULTI_STATUS_IS_MULTIPLE_OWNERS_CONNECTED = 6, +} FMNA_Multi_Status_t; + +typedef struct +{ + uint32_t multi_status; // Bitmask of multi status bits + uint16_t conn_handle; + uint16_t conn_intv; // Connection interval in units of 1.25ms. +} __attribute__((aligned(SYS_POINTER_BSIZE))) fmna_active_conn_info_t; + +// Connection info for all connections. +extern fmna_active_conn_info_t m_fmna_active_connections[MAX_SUPPORTED_CONNECTIONS]; + +/// Initializes fmna_connection module and relevant structs. +void fmna_connection_init(void); + +/// Set max allowed simultaneous connections, from iOS. +/// @details Sets max connections, if valid, and potentially starts advertising Nearby again. +/// If max connections is set to 1, we disconnect all OTHER links currently +/// connected, and max connections response will be delayed until disconnects +/// are complete. Otherwise, max connections response is sent synchronously, +/// +/// @param[in] max_connections Maximum allowed connections, depending on how many +/// applicable devices user has on iCloud account. +/// +/// @param[in] conn_handle Connection handle of connection setting max connections. +void fmna_connection_set_max_connections(uint8_t max_connections, uint16_t conn_handle); + +/// Disconnects every link connected to us. +void fmna_connection_disconnect_all(void); + +/// Disconnects current connection, e.g. most recently connected device. +void fmna_connection_disconnect_this(void); + +/// Sets or clears multi status bit for valid connection. +/// @param[in] conn_handle Connection handle for connection to update info of. +/// @param[in] status Multi status bit to update. +/// @param[in] enable Boolean flag: enable or disable a multi status bit. +void fmna_connection_update_connection_info(uint16_t conn_handle, FMNA_Multi_Status_t status, + bool enable); + +void fmna_connection_update_connection_info_all(FMNA_Multi_Status_t status, bool enable); + +/// Get number of currently active connections. +/// @return Number of currently active connections, 0 if none. +uint8_t fmna_connection_get_num_connections(void); + +void fmna_connection_send_multi_status(uint16_t conn_handle); + +/// Checks if connection has a valid handle. +/// @return True if this connection handle is for a valid connection, False otherwise. +bool fmna_connection_is_valid_connection(uint16_t conn_handle); + +/// Checks whether a particular connection, or any connection, has a particular multi status bit enabled. +/// @param[in] status Multi status bit to check. +/// @param[in] conn_handle Connection handle for the connection to check, or CONN_HANDLE_ALL. +/// @return True is this connection, or any connection (if applicable) handle is a valid connection and has this multi status bit enabled, False otherwise. +bool fmna_connection_is_status_bit_enabled(uint16_t conn_handle, FMNA_Multi_Status_t status); + + +uint32_t fmna_connection_get_non_owner_timeout(void); + +/// Find connection with particular multi status bit enabled. +/// @param[in] status Multi status bit to check. +/// @return Connection handle of connection with multi status bit enabled, +/// or CONN_HANDLE_INVALID if no connection has this multi status bit enabled. +uint16_t fmna_connection_get_conn_handle_with_multi_status_enabled(FMNA_Multi_Status_t status); + +void fmna_connection_pair_info_restore(void); +void fmna_connection_set_is_fmna_paired(bool is_paired); + +// Function to determine on the app level, if app is paired +// Function checks the global variable of app's pairing status, which is only set after successfully pairing complete +bool fmna_connection_is_fmna_paired(void); + +void fmna_connection_connected_handler(uint16_t conn_handle, uint16_t conn_interval); +void fmna_connection_conn_param_update_handler(uint16_t conn_handle, uint16_t conn_interval); +void fmna_connection_disconnected_handler(uint16_t conn_handle); + +/// Set the LTK to swap existing LTK with for connection. +void fmna_connection_set_active_ltk(uint8_t new_ltk[GAP_SEC_KEY_LEN]); +uint8_t *fmna_connection_get_active_ltk(void); + +uint8_t fmna_connection_get_max_connections(void); +void fmna_connection_set_unpair_pending(bool enable); +bool fmna_connection_get_unpair_pending(void); +void fmna_connection_fmna_unpair(bool force_disconnect); + +#endif /* fmna_connection_h */ diff --git a/src/app/findmy/fmna_adk/fmna_constants.h b/src/app/findmy/fmna_adk/fmna_constants.h new file mode 100644 index 0000000..869f7a4 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_constants.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_constants_h +#define fmna_constants_h + +#include "fmna_constants_platform.h" + +#define USE_CRYPTO + +#ifdef USE_CRYPTO +#define HARDCODED_PAIRING_ENABLED 0 +#else // USE_CRYPTO +#define HARDCODED_PAIRING_ENABLED 1 +#endif // USE_CRYPTO + +#define FMNA_COMPANY_IDENTIFIER 0x004C /**< Company identifier for Apple. as per www.bluetooth.org. */ +#define DEVICE_NAME "Find My Accessory" + +#define SYS_POINTER_BSIZE (sizeof(void *)) + +#define FMNA_PUBKEY_BLEN 28 /**< Length (in bytes) of the public key. */ +#define FMNA_SEPARATED_ADV_PAYLOAD_PUBKEY_BLEN (FMNA_PUBKEY_BLEN - BLE_GAP_ADDR_LEN) /**< Length (in bytes) of the Separated payload public key (bytes 6-27). */ +#define FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX 5 +#define PRIMARY_KEYS_PER_SECONDARY_KEY 96 +#define SEPARATED_STATE_CONFIG_NEGATIVE_BOUNDARY 4 +#define FMNA_BLE_MAC_ADDR_BLEN 6 /** 6 bytes per BT spec. */ +#define NEARBY_TIMEOUT_MAX_SECONDS 3600 + +#define NUM_OF_KEYS 8 +#define PAIRING_MAX_LEN 1394 +#define CONFIG_MAX_LEN 64 +#define NONOWN_MAX_LEN 7 +#define PAIRED_OWNER_MAX_LEN 144 +#define GATT_HEADER_LEN 3 /**< GATT header length. */ +#define GATT_PAYLOAD_LEN(mtu) ((mtu) - GATT_HEADER_LEN) /**< Length of the ATT payload for a given ATT MTU. */ + +//MARK: Apple Information Service lengths +#define PROD_DATA_MAX_LEN 8 +#define MANU_NAME_MAX_LEN 64 +#define MODEL_NAME_MAX_LEN 64 +#define RESERVED_MAX_LEN 3 +#define ACC_CATEGORY_MAX_LEN 8 +#define ACC_CAP_MAX_LEN 4 +#define FW_VERS_MAX_LEN 4 +#define FINDMY_VERS_MAX_LEN 4 +#define BATT_TYPE_MAX_LEN 1 +#define BATT_LVL_MAX_LEN 1 + +// Operand Lengths as per spec - R2 update from 8/5/20 + + +#define INITIATE_PAIRING_DATA_LENGTH (SESSION_NONCE_BLEN + E1_BLEN) + +#define OPCODE_OP_LENGTH 4 +#define STATUS_LENGTH 4 + +//MARK: Crypto Key Lengths +#define SESSION_NONCE_BLEN 32 +#define SERVER_SHARED_SECRET_BLEN 32 +#define SOFTWARE_AUTH_TOKEN_BLEN 1024 +#define SOFTWARE_AUTH_UUID_BLEN 16 +#define SERIAL_NUMBER_RAW_BLEN 16 +#define SK_BLEN 32 +#define P_BLEN 57 +#define C1_BLEN 32 +#define E1_BLEN 113 +#define C3_BLEN 60 +#define E2_BLEN 1326 +#define E3_BLEN 1040 +#define E4_BLEN 1286 +#define C2_BLEN 89 +#define SEEDS_BLEN 32 +#define ICLOUD_IDENTIFIER_BLEN 60 +#define S2_BLEN 100 +#define H1_BLEN 32 +#define SERIAL_NUMBER_PAYLOAD_HMAC_BLEN 32 +#define SERIAL_NUMBER_PAYLOAD_OP_BLEN 4 +#define ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN 141 + +#define APPLE_SERVER_ENCRYPTION_KEY_BLEN 65 +#define APPLE_SERVER_SIG_VERIFICATION_KEY_BLEN 65 + +#define PRODUCT_DATA_BLEN 8 +#define FINDMY_UUID_SERVICE 0xFD44 +#define FINDMY_CHAR_BASE_UUID {0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x00, 0x00, 0x86, 0x4F} +#define FINDMY_UUID_PAIRING_CHAR 0x0001 +#define FINDMY_UUID_CONFIG_CHAR 0x0002 +#define FINDMY_UUID_NONOWN_CHAR 0x0003 +#define FINDMY_UUID_PAIRED_OWNER_CHAR 0x0004 +#define FINDMY_UUID_DEBUG_CHAR 0x0005 + +#define UARP_UUID_SERVICE 0xFD43 +#define UARP_CHAR_BASE_UUID {0xDE, 0xB0, 0x01, 0x7F, 0x4A, 0x6A, 0xF1, 0xA4, 0x25, 0x42, 0x9B, 0x6D, 0x00, 0x00, 0x11, 0x94} +#define UARP_UUID_DATA_CHAR 0x0001 + + +#define AIS_SERVICE_BASE_UUID {0x8B, 0x47, 0x38, 0xDC, 0xB9, 0x11, 0xA9, 0xA1, 0xB1, 0x43, 0x51, 0x3C, 0x02, 0x01, 0x29, 0x87} +#define AIS_CHAR_BASE_UUID {0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x00, 0x00, 0xA5, 0X6A} + +// Realtek test product plan +#define PRODUCT_DATA_VAL {0x80, 0x24, 0xd0, 0x45, 0x5b, 0x9b, 0xd3, 0x13} +#define ACCESSORY_CATEGORY {1} //Location Tracker + +// Hardcoded values, eventually read these on boot from provisioned keys; +#define FMNA_SERVER_ENCRYPT_KEY "BJzFrd3QKbdTXTDm5dFtt6jSGxtItVsZ1bEQ6VvzFUXndM9Rjeu+PHFoM+RD8RRHblpLBU42dQcFbjmVzGuWkJY=" +#define FMNA_SIGN_VERIFY_KEY "BDNMWnP9Yd82Qz+8aZI245jklBLzwP3E5doLQRh3lRcIcSCIjpeSN3a6SNxRfA+oe5xiqf7paw84QD9mnh5nVWA=" +#endif /* fmna_constants_h */ diff --git a/src/app/findmy/fmna_adk/fmna_crypto.c b/src/app/findmy/fmna_adk/fmna_crypto.c new file mode 100644 index 0000000..859a8f2 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_crypto.c @@ -0,0 +1,788 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_constants.h" +#include "fmna_platform_includes.h" +#include "fmna_crypto.h" +#include "fmna_state_machine.h" +#include "fmna_connection.h" +#include "fmna_version.h" +#if SUPPORT_NFC +#include "fmna_nfc.h" +#endif +#if !HARDCODED_PAIRING_ENABLED +#include "fm-crypto.h" + +#ifdef GENERATE_RANDOM_SERIAL_NUMBER +//TODO: remove this - random UUID +#endif +#include "mbedtls/base64.h" + +fmna_send_pairing_data_t *p_fmna_send_pairing_data; +fmna_initiate_pairing_data_t *p_fmna_initiate_pairing_data; +fmna_finalize_pairing_data_t *p_fmna_finalize_pairing_data; +fmna_send_pairing_status_t *p_fmna_send_pairing_status; + +uint8_t *p_fmna_encrypted_serial_number_payload; + +bool serial_number_read_state = false; +static uint8_t m_serial_number[SERIAL_NUMBER_RAW_BLEN]; +#ifdef GENERATE_RANDOM_SERIAL_NUMBER +static uint8_t m_serial_number_random_map[SERIAL_NUMBER_RAW_BLEN]; +#endif + +typedef struct +{ + uint8_t serial_number[SERIAL_NUMBER_RAW_BLEN]; + uint64_t counter; + char op[SERIAL_NUMBER_PAYLOAD_OP_BLEN]; +} __attribute__((packed)) serial_number_hmac_payload_t; + +static serial_number_hmac_payload_t m_serial_number_hmac_payload; + +typedef struct +{ + uint8_t serial_number[SERIAL_NUMBER_RAW_BLEN]; + uint64_t counter; + uint8_t hmac[SERIAL_NUMBER_PAYLOAD_HMAC_BLEN]; + char op[SERIAL_NUMBER_PAYLOAD_OP_BLEN]; +} __attribute__((packed)) serial_number_payload_t; + +static serial_number_payload_t m_serial_number_payload; + +static struct fm_crypto_ckg_context m_fm_crypto_ckg_ctx; + +static uint8_t m_seedk1[SK_BLEN]; +static uint8_t m_p[P_BLEN]; +static uint8_t m_server_shared_secret[SERVER_SHARED_SECRET_BLEN]; +static uint64_t serial_number_query_count; + +// Hardcoded values, eventually read these on boot from provisioned keys; +static uint8_t m_q_e[APPLE_SERVER_ENCRYPTION_KEY_BLEN]; +static uint8_t m_q_a[APPLE_SERVER_SIG_VERIFICATION_KEY_BLEN]; + +static const uint8_t server_key[88] = FMNA_SERVER_ENCRYPT_KEY; +static const uint8_t sig_key[88] = FMNA_SIGN_VERIFY_KEY; + +static mfi_info_t m_mfi_struct; + +typedef struct +{ + uint8_t session_nonce[SESSION_NONCE_BLEN]; + uint8_t software_auth_token[SOFTWARE_AUTH_TOKEN_BLEN]; + uint8_t software_auth_uuid[SOFTWARE_AUTH_UUID_BLEN]; + uint8_t serial_number[SERIAL_NUMBER_RAW_BLEN]; + uint8_t product_data[PROD_DATA_MAX_LEN]; + uint32_t fw_version; + uint8_t e1[E1_BLEN]; + uint8_t seedk1[SK_BLEN]; +} __attribute__((packed)) e2_generation_encryption_msg_t; + +typedef struct +{ + uint8_t software_auth_uuid[SOFTWARE_AUTH_UUID_BLEN]; + uint8_t serial_number[SERIAL_NUMBER_RAW_BLEN]; + uint8_t session_nonce[SESSION_NONCE_BLEN]; + uint8_t e1[E1_BLEN]; + uint8_t latest_sw_token[SOFTWARE_AUTH_TOKEN_BLEN]; + uint32_t status; +} __attribute__((packed)) e4_generation_encryption_msg_t; + +typedef struct +{ + uint8_t software_auth_uuid[SOFTWARE_AUTH_UUID_BLEN]; + uint8_t session_nonce[SESSION_NONCE_BLEN]; + uint8_t seeds[SEEDS_BLEN]; + uint8_t h1[H1_BLEN]; + uint8_t e1[E1_BLEN]; + uint8_t e3[E3_BLEN]; +} __attribute__((packed)) s2_verification_msg_t; + +// Union to hold buffers for various encryption, verification messages. +typedef union +{ + e2_generation_encryption_msg_t e2_generation_encryption_msg; + e4_generation_encryption_msg_t e4_generation_encryption_msg; + s2_verification_msg_t s2_verification_msg; +} key_verif_encr_msg_t; + +e2_generation_encryption_msg_t decrypted_e2_generation_encryption_msg; + +static key_verif_encr_msg_t m_key_verif_encr_msg; + +static uint8_t m_current_primary_sk[SK_BLEN]; +static uint8_t m_current_secondary_sk[SK_BLEN]; + +#define FM_CRYPTO_STATUS_SUCCESS 0 + +static void populate_e2_generation_encryption_msg(void) +{ + // Populate the fields for m_key_verif_encr_msg.e2_generation_encryption_msg. + + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.session_nonce, + p_fmna_initiate_pairing_data->session_nonce, + SESSION_NONCE_BLEN); + + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.software_auth_uuid, + m_mfi_struct.m_software_auth_uuid, + SOFTWARE_AUTH_UUID_BLEN); + + flash_read_locked(SOFTWARE_AUTH_TOKEN_ADDR, + SOFTWARE_AUTH_TOKEN_BLEN, + m_key_verif_encr_msg.e2_generation_encryption_msg.software_auth_token); + + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.serial_number, + m_serial_number, + SERIAL_NUMBER_RAW_BLEN); + + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.e1, + p_fmna_initiate_pairing_data->e1, + E1_BLEN); + + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.seedk1, + m_seedk1, + SK_BLEN); + + m_key_verif_encr_msg.e2_generation_encryption_msg.fw_version = fmna_version_get_fw_version(); + + uint8_t product_data[PRODUCT_DATA_BLEN] = PRODUCT_DATA_VAL; + memcpy(m_key_verif_encr_msg.e2_generation_encryption_msg.product_data, + product_data, + PRODUCT_DATA_BLEN); +} + +static void populate_e4_generation_encryption_msg(void) +{ + // Populate the fields for m_key_verif_encr_msg.e4_generation_encryption_msg. + + memcpy(m_key_verif_encr_msg.e4_generation_encryption_msg.session_nonce, + p_fmna_initiate_pairing_data->session_nonce, + SESSION_NONCE_BLEN); + + memcpy(m_key_verif_encr_msg.e4_generation_encryption_msg.software_auth_uuid, + m_mfi_struct.m_software_auth_uuid, + SOFTWARE_AUTH_UUID_BLEN); + + memcpy(m_key_verif_encr_msg.e4_generation_encryption_msg.serial_number, + m_serial_number, + SERIAL_NUMBER_RAW_BLEN); + + memcpy(m_key_verif_encr_msg.e4_generation_encryption_msg.e1, + p_fmna_initiate_pairing_data->e1, + E1_BLEN); + + memcpy(m_key_verif_encr_msg.e4_generation_encryption_msg.latest_sw_token, + m_mfi_struct.p_software_auth_token, + SOFTWARE_AUTH_TOKEN_BLEN); + + m_key_verif_encr_msg.e4_generation_encryption_msg.status = 0; +} + +static void populate_s2_verification_msg(void) +{ + // Populate the fields for m_key_verif_encr_msg.s2_verification_msg. + memcpy(m_key_verif_encr_msg.s2_verification_msg.session_nonce, + p_fmna_initiate_pairing_data->session_nonce, + SESSION_NONCE_BLEN); + + memcpy(m_key_verif_encr_msg.s2_verification_msg.software_auth_uuid, + m_mfi_struct.m_software_auth_uuid, + SOFTWARE_AUTH_UUID_BLEN); + + memcpy(m_key_verif_encr_msg.s2_verification_msg.seeds, + p_fmna_finalize_pairing_data->seeds, + SEEDS_BLEN); + + ftl_save(p_fmna_finalize_pairing_data->icloud_id, FTL_SAVE_ICLOUD_ID_ADDR, + FTL_SAVE_ICLOUD_ID_SIZE); + + uint32_t ret = fm_crypto_sha256(C2_BLEN, p_fmna_finalize_pairing_data->c2, + m_key_verif_encr_msg.s2_verification_msg.h1); + FMNA_ERROR_CHECK(ret); + + memcpy(m_key_verif_encr_msg.s2_verification_msg.e1, + p_fmna_initiate_pairing_data->e1, + E1_BLEN); + + memcpy(m_key_verif_encr_msg.s2_verification_msg.e3, + p_fmna_finalize_pairing_data->e3, + E3_BLEN); +} + +static fmna_ret_code_t roll_sk(uint8_t current_sk[SK_BLEN]) +{ + uint8_t new_sk[SK_BLEN]; + int ret_code = fm_crypto_roll_sk(current_sk, new_sk); + if (ret_code != FM_CRYPTO_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("roll_sk err %d", ret_code); + return FMNA_ERROR_INTERNAL; + } + memcpy(current_sk, new_sk, SK_BLEN); + + return FMNA_SUCCESS; +} +#endif // HARDCODED_PAIRING_ENABLED + +#ifdef GENERATE_RANDOM_SERIAL_NUMBER +/** @brief Function for getting vector of random numbers. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval Number of bytes actually placed in p_buff. + */ +static uint8_t random_vector_generate(uint8_t *p_buff, uint8_t size) +{ + uint32_t err_code; + uint8_t available; + + nrf_drv_rng_bytes_available(&available); + uint8_t length = MIN(size, available); + + err_code = nrf_drv_rng_rand(p_buff, length); + FMNA_ERROR_CHECK(err_code); + + return length; +} + +static void generate_random_serial_number(void) +{ + static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"; + + random_vector_generate((uint8_t *)&m_serial_number_random_map, SERIAL_NUMBER_RAW_BLEN); + + for (uint8_t i = 0; i < SERIAL_NUMBER_RAW_BLEN; i++) + { + m_serial_number[i] = charset[m_serial_number_random_map[i] % sizeof(charset)]; + } + + FMNA_LOG_INFO("Serial Number:"); + FMNA_LOG_HEXDUMP_INFO(m_serial_number, 16); +} +#endif + +uint8_t *fmna_crypto_get_serial_number_raw(void) +{ + return m_serial_number; +} + +static void fmna_crypto_key_restore(void) +{ + uint32_t ret = FMNA_SUCCESS; + uint16_t error_line = 0; + + //Restore P , SKN and SKS + ret = ftl_load(m_p, FTL_SAVE_M_P_ADDR, FTL_SAVE_M_P_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + + ret = ftl_load(m_current_primary_sk, FTL_SAVE_SKN_ADDR, FTL_SAVE_SKN_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + + ret = ftl_load(m_current_secondary_sk, FTL_SAVE_SKS_ADDR, FTL_SAVE_SKS_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + + //Restore shared secret + ret = ftl_load(m_server_shared_secret, FTL_SAVE_SHARED_SECRET_ADDR, FTL_SAVE_SHARED_SECRET_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + + //Restore primary key + ret = ftl_load(&m_fmna_temp_primary_key, FTL_SAVE_PRI_KEY_ADDR, FTL_SAVE_PRI_KEY_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + memcpy(&m_fmna_current_primary_key, &m_fmna_temp_primary_key, sizeof(fmna_primary_key_t)); + APP_PRINT_INFO1("Restore Curr Primary Key (index = 0x%x):", m_fmna_current_primary_key.index); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_primary_key.public_key, FMNA_PUBKEY_BLEN); + APP_PRINT_INFO0("Restore Curr LTK:"); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_primary_key.ltk, GAP_SEC_KEY_LEN); + + //Restore secondary key and latched separated primary key + ret = ftl_load(&m_fmna_current_secondary_key, FTL_SAVE_SEC_KEY_ADDR, FTL_SAVE_SEC_KEY_SIZE); + FMNA_ERROR_CHECK_GOTO(ret, error); + APP_PRINT_INFO1("Restore Curr Secondary Key (index = 0x%x):", m_fmna_current_secondary_key.index); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_secondary_key.public_key, FMNA_PUBKEY_BLEN); + + //If the data is saved, restore the secondary primary key + fmna_primary_key_t temp_buf; + ret = ftl_load(&temp_buf, FTL_SAVE_SEC_PRI_KEY_ADDR, + FTL_SAVE_SEC_PRI_KEY_SIZE); + if (ret == 0) + { + memcpy(&m_fmna_current_separated_primary_key, &temp_buf, FTL_SAVE_SEC_PRI_KEY_SIZE); + APP_PRINT_INFO1("Restore Curr Secondary Primary Key (index = 0x%x):", + m_fmna_current_separated_primary_key.index); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_separated_primary_key.public_key, FMNA_PUBKEY_BLEN); + } + + //Restore key rotation infomation + ret = ftl_load(&m_fmna_secondary_keys_info.next_secondary_key_rotation_index, + (FTL_SAVE_NEXT_PW_ROT_INDEX_ADDR), (FTL_SAVE_NEXT_PW_ROT_INDEX_SIZE)); + if (ret == 0) + { + APP_PRINT_INFO1("Restore secondary key info index = %#x", + m_fmna_secondary_keys_info.next_secondary_key_rotation_index); + } + + //Restore serial number query count + ret = ftl_load(&serial_number_query_count, FTL_SAVE_SN_COUNTER_ADDR, FTL_SAVE_SN_COUNTER_SIZE); + if (ret != 0) // no counter saved + { + serial_number_query_count = 0; + } + APP_PRINT_INFO1("Restore serial_number_query_count index = %d", serial_number_query_count); + return; + +error: + APP_PRINT_ERROR3("FMNA error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + FMNA_PLATFORM_ABORT(error_line); +} + +void fmna_crypto_init(void) +{ +#if !HARDCODED_PAIRING_ENABLED + FMNA_LOG_INFO("fmna_crypto_init"); + + size_t len; + + mbedtls_base64_decode(m_q_e, APPLE_SERVER_ENCRYPTION_KEY_BLEN, &len, server_key, 88); + mbedtls_base64_decode(m_q_a, APPLE_SERVER_SIG_VERIFICATION_KEY_BLEN, &len, sig_key, 88); + + //Read software auth token, UUID, serial number etc. from accessory factory registers/ flash/ FTL. + FMNA_LOG_INFO("token and UUID address:%#x", SOFTWARE_AUTH_UUID_ADDR); + + uint8_t token_preview[16]; + flash_read_locked(SOFTWARE_AUTH_TOKEN_ADDR, 16, token_preview); + FMNA_LOG_INFO("m_software_auth_token preview: %b", TRACE_BINARY(16, token_preview)); + + flash_read_locked(SOFTWARE_AUTH_UUID_ADDR, SOFTWARE_AUTH_UUID_BLEN, + (uint8_t *)m_mfi_struct.m_software_auth_uuid); + FMNA_LOG_INFO("m_software_auth_uuid: %b", TRACE_BINARY(16, m_mfi_struct.m_software_auth_uuid)); + + if (fmna_connection_is_fmna_paired()) + { + fmna_crypto_key_restore(); + } + else + { + // Initialize new CKG context on unpair in preparation for new pairing. + int ret = fm_crypto_ckg_init(&m_fm_crypto_ckg_ctx); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_ckg_init err %d", ret); + } + } + +#endif // HARDCODED_PAIRING_ENABLED + +#ifdef GENERATE_RANDOM_SERIAL_NUMBER + generate_random_serial_number(); +#else + fmna_connection_platform_get_serial_number(m_serial_number, SERIAL_NUMBER_RAW_BLEN); +#endif +} + +fmna_ret_code_t fmna_crypto_generate_send_pairing_data_params(void) +{ +#if !HARDCODED_PAIRING_ENABLED + + // Generate C1, SeedK1, and E2. + int ret = fm_crypto_ckg_gen_c1(&m_fm_crypto_ckg_ctx, p_fmna_send_pairing_data->c1); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_ckg_gen_c1 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + ret = fm_crypto_generate_seedk1(m_seedk1); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_generate_seedk1 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + //Generate E2, see Section 6.2.3 for details. + + populate_e2_generation_encryption_msg(); + FMNA_LOG_INFO("E2 generation encryption msg size %d", + sizeof(m_key_verif_encr_msg.e2_generation_encryption_msg)); + uint32_t e2_blen = E2_BLEN; + ret = fm_crypto_encrypt_to_server((const uint8_t *)m_q_e, + sizeof(m_key_verif_encr_msg.e2_generation_encryption_msg), + (const uint8_t *)&m_key_verif_encr_msg.e2_generation_encryption_msg, + &e2_blen, + p_fmna_send_pairing_data->e2); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_encrypt_to_server e2 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + FMNA_LOG_INFO("E2, len %u", e2_blen); +#endif //HARCODED_PAIRING_ENABLED + + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_crypto_finalize_pairing(void) +{ +#if !HARDCODED_PAIRING_ENABLED + // Validate S2, decrypt E3, generate C3, generate E4, and send response. + + int ret = fm_crypto_derive_server_shared_secret(p_fmna_finalize_pairing_data->seeds, m_seedk1, + m_server_shared_secret); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_derive_server_shared_secret err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + populate_s2_verification_msg(); + FMNA_LOG_INFO("S2 verification msg len %d", sizeof(m_key_verif_encr_msg.s2_verification_msg)); + ret = fm_crypto_verify_s2(m_q_a, + S2_BLEN, + p_fmna_finalize_pairing_data->s2, + sizeof(m_key_verif_encr_msg.s2_verification_msg), + (const uint8_t *)(&m_key_verif_encr_msg.s2_verification_msg)); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_verify_s2 err %d", ret); + + //TODO: Do not bypass failure check for signature. + //return FMNA_ERROR_INTERNAL; + } + + + uint32_t e3_decrypt_plaintext_blen = SOFTWARE_AUTH_TOKEN_BLEN; + m_mfi_struct.p_software_auth_token = fmna_malloc(MFI_RAW_TOKEN, SOFTWARE_AUTH_TOKEN_BLEN); + if (m_mfi_struct.p_software_auth_token == NULL) + { + APP_PRINT_ERROR0("p_software_auth_token zalloc failed!"); + return FMNA_ERROR_INTERNAL; + } + + ret = fm_crypto_decrypt_e3((const uint8_t *)m_server_shared_secret, + E3_BLEN, + (const uint8_t *)p_fmna_finalize_pairing_data->e3, + &e3_decrypt_plaintext_blen, + (uint8_t *)m_mfi_struct.p_software_auth_token); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_decrypt_e3 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + FMNA_LOG_INFO("E3 decrypted token len %d", e3_decrypt_plaintext_blen); + fmna_log_mfi_token(); + + ret = fm_crypto_ckg_gen_c3(&m_fm_crypto_ckg_ctx, + p_fmna_finalize_pairing_data->c2, + p_fmna_send_pairing_status->c3); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_ckg_gen_c3 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + // Generate E4, see Section 6.2.6 for details. + populate_e4_generation_encryption_msg(); + FMNA_LOG_INFO("E4 generation encryption msg size %d", + sizeof(m_key_verif_encr_msg.e4_generation_encryption_msg)); + fmna_free(INITIATE_PAIRING_DATA); + + uint32_t e4_blen = E4_BLEN; + ret = fm_crypto_encrypt_to_server((const uint8_t *)m_q_e, + sizeof(m_key_verif_encr_msg.e4_generation_encryption_msg), + (const uint8_t *)&m_key_verif_encr_msg.e4_generation_encryption_msg, + &e4_blen, + p_fmna_send_pairing_status->e4); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_encrypt_to_server e4 err %d", ret); + return FMNA_ERROR_INTERNAL; + } + FMNA_LOG_INFO("E4, len %u", e4_blen); + + //new MFi token should be stored before pairing complete is sent + //Attempt to save MFi Token + fmna_connection_update_mfi_token_storage(&m_mfi_struct); + + fmna_free(MFI_RAW_TOKEN); + +#endif // HARDCODED_PAIRING_ENABLED + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_crypto_pairing_complete(void) +{ +#if !HARDCODED_PAIRING_ENABLED + int ret = fm_crypto_ckg_finish(&m_fm_crypto_ckg_ctx, + m_p, + m_current_primary_sk, + m_current_secondary_sk); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_ckg_finish err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + FMNA_LOG_INFO("P:"); + FMNA_LOG_HEXDUMP_INFO(m_p, P_BLEN); + ftl_save(m_p, FTL_SAVE_M_P_ADDR, FTL_SAVE_M_P_SIZE); + + FMNA_LOG_INFO("Primary SKN:"); + FMNA_LOG_HEXDUMP_INFO(m_current_primary_sk, SK_BLEN); + ftl_save(m_current_primary_sk, FTL_SAVE_SKN_ADDR, FTL_SAVE_SKN_SIZE); + + FMNA_LOG_INFO("Secondary SKS:"); + FMNA_LOG_HEXDUMP_INFO(m_current_secondary_sk, SK_BLEN); + ftl_save(m_current_secondary_sk, FTL_SAVE_SKS_ADDR, FTL_SAVE_SKN_SIZE); + + FMNA_LOG_INFO("Shared Secret:"); + FMNA_LOG_HEXDUMP_INFO(m_server_shared_secret, SERVER_SHARED_SECRET_BLEN); + ftl_save(m_server_shared_secret, FTL_SAVE_SHARED_SECRET_ADDR, FTL_SAVE_SHARED_SECRET_SIZE); + + fm_crypto_ckg_free(&m_fm_crypto_ckg_ctx); + +#endif //HARDCODED_PAIRING_ENABLED + + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_crypto_roll_primary_sk(void) +{ +#if !HARDCODED_PAIRING_ENABLED + return roll_sk(m_current_primary_sk); +#else + return FMNA_SUCCESS; +#endif +} + +fmna_ret_code_t fmna_crypto_roll_secondary_sk(void) +{ +#if !HARDCODED_PAIRING_ENABLED + return roll_sk(m_current_secondary_sk); +#else + return FMNA_SUCCESS; +#endif +} + +fmna_ret_code_t fmna_crypto_roll_primary_key(void) +{ +#if !HARDCODED_PAIRING_ENABLED + + // SK(i) -> SK(i+1) + fmna_ret_code_t fmna_ret_code = fmna_crypto_roll_primary_sk(); + if (fmna_ret_code != FMNA_SUCCESS) + { + return fmna_ret_code; + } + + // SK(i+1) -> Primary_Key(i+1) + int ret = fm_crypto_derive_primary_or_secondary_x(m_current_primary_sk, m_p, + m_fmna_temp_primary_key.public_key); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_derive_primary_or_secondary_x err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + // Increment Primary Key index + m_fmna_temp_primary_key.index++; + + // SK(i+1) -> LTK(i+1) + ret = fm_crypto_derive_ltk(m_current_primary_sk, m_fmna_temp_primary_key.ltk); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("m_current_primary_sk err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + return FMNA_SUCCESS; + +#else // HARDCODED_PAIRING_ENABLED + + return FMNA_SUCCESS; +#endif // HARDCODED_PAIRING_ENABLED +} + +fmna_ret_code_t fmna_primary_key_update(void) +{ + is_key_rotated = false; + fmna_ret_code_t ret = FMNA_SUCCESS; + memcpy(&m_fmna_current_primary_key, &m_fmna_temp_primary_key, sizeof(fmna_primary_key_t)); + fmna_connection_set_active_ltk(m_fmna_current_primary_key.ltk); + + if (ftl_save(&m_fmna_current_primary_key, FTL_SAVE_PRI_KEY_ADDR, FTL_SAVE_PRI_KEY_SIZE)) + { + APP_PRINT_ERROR0("FTL save m_fmna_current_primary_key failed!"); + ret = FMNA_ERROR_INTERNAL; + } + FMNA_LOG_INFO("Curr Primary Key (index = 0x%x):", m_fmna_current_primary_key.index); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_primary_key.public_key, FMNA_PUBKEY_BLEN); + + if (ftl_save(&m_current_primary_sk, FTL_SAVE_SKN_ADDR, FTL_SAVE_SKN_SIZE)) + { + APP_PRINT_ERROR0("FTL save m_current_primary_sk failed!"); + ret = FMNA_ERROR_INTERNAL; + } + FMNA_LOG_INFO("Curr LTK:"); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_primary_key.ltk, GAP_SEC_KEY_LEN); + + return ret; +} + +fmna_ret_code_t fmna_crypto_roll_secondary_key(void) +{ +#if !HARDCODED_PAIRING_ENABLED + // SK(i) -> SK(i+1) + fmna_ret_code_t fmna_ret_code = fmna_crypto_roll_secondary_sk(); + if (fmna_ret_code != FMNA_SUCCESS) + { + return fmna_ret_code; + } + + // SK(i+1) -> Secondary_Key(i+1) + int ret = fm_crypto_derive_primary_or_secondary_x(m_current_secondary_sk, m_p, + m_fmna_current_secondary_key.public_key); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fmna_crypto_roll_secondary_key err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + // Increment Secondary Key index + m_fmna_current_secondary_key.index++; + + FMNA_LOG_INFO("Curr Secondary Key (index = 0x%x):", m_fmna_current_secondary_key.index); + FMNA_LOG_HEXDUMP_INFO(m_fmna_current_secondary_key.public_key, FMNA_PUBKEY_BLEN); + ftl_save(&m_fmna_current_secondary_key, FTL_SAVE_SEC_KEY_ADDR, FTL_SAVE_SEC_KEY_SIZE); + ftl_save(&m_current_secondary_sk, FTL_SAVE_SKS_ADDR, FTL_SAVE_SKN_SIZE); + return FMNA_SUCCESS; + +#else //HARDCODED_PAIRING_ENABLED + + return FMNA_SUCCESS; +#endif // HARDCODED_PAIRING_ENABLED +} + +void serial_number_read_state_init(void) +{ + fmna_ret_code_t ret_code = fmna_crypto_generate_serial_number_response( + FMNA_SERIAL_NUMBER_QUERY_TYPE_BT); + FMNA_ERROR_CHECK(ret_code); + + if (ret_code == FMNA_SUCCESS) + { + serial_number_read_state = true; + os_timer_start(&sn_lookup_timer); + APP_PRINT_INFO0("serial number encrypt success"); + } +} + +fmna_ret_code_t fmna_crypto_generate_serial_number_response(FMNA_Serial_Number_Query_Type_t type) +{ +#if !HARDCODED_PAIRING_ENABLED + int ret; + // Clear the encrypted serial number initially in case of error. + p_fmna_encrypted_serial_number_payload = fmna_malloc(ENCRYPTED_SN, + ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN); + if (p_fmna_encrypted_serial_number_payload == NULL) + { + APP_PRINT_ERROR0("p_fmna_encrypted_serial_number_payload zalloc failed!"); + return FMNA_ERROR_INTERNAL; + } + + // Clear the encrypted serial number initially in case of error. + memset(p_fmna_encrypted_serial_number_payload, 0, ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN); + + serial_number_query_count++; + ftl_save(&serial_number_query_count, FTL_SAVE_SN_COUNTER_ADDR, FTL_SAVE_SN_COUNTER_SIZE); + + memcpy(m_serial_number_hmac_payload.serial_number, m_serial_number, SERIAL_NUMBER_RAW_BLEN); + memcpy(m_serial_number_payload.serial_number, m_serial_number, SERIAL_NUMBER_RAW_BLEN); + + m_serial_number_hmac_payload.counter = serial_number_query_count; + m_serial_number_payload.counter = serial_number_query_count; + + switch (type) + { + case FMNA_SERIAL_NUMBER_QUERY_TYPE_TAP: + strcpy(m_serial_number_hmac_payload.op, "tap"); + strcpy(m_serial_number_payload.op, "tap"); + break; + case FMNA_SERIAL_NUMBER_QUERY_TYPE_BT: + strcpy(m_serial_number_hmac_payload.op, "bt"); + strcpy(m_serial_number_payload.op, "bt"); + break; + default: + FMNA_LOG_ERROR("Invalid Serial Number Query Type"); + return FMNA_ERROR_INTERNAL; + } + + ret = fm_crypto_authenticate_with_ksn(m_server_shared_secret, + sizeof(m_serial_number_hmac_payload), + (const uint8_t *)&m_serial_number_hmac_payload, + m_serial_number_payload.hmac); + if (ret != FM_CRYPTO_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("fm_crypto_authenticate_with_ksn err %d", ret); + return FMNA_ERROR_INTERNAL; + } + + uint32_t encrypted_serial_number_payload_blen = ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN; + ret = fm_crypto_encrypt_to_server(m_q_e, + sizeof(m_serial_number_payload), + (const uint8_t *)&m_serial_number_payload, + &encrypted_serial_number_payload_blen, + p_fmna_encrypted_serial_number_payload); + if (ret != FM_CRYPTO_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("encrypted_serial_number_payload_blen err %d", ret); + + // Clear the encrypted serial number in case of fm_crypto_encrypt_to_server error. + fmna_free(ENCRYPTED_SN); + return FMNA_ERROR_INTERNAL; + } +#endif //HARDCODED_PAIRING_ENABLED + return FMNA_SUCCESS; +} + +void fmna_crypto_unpair(void) +{ +#if !HARDCODED_PAIRING_ENABLED + FMNA_LOG_INFO("fmna_crypto_unpair"); + if (fmna_connection_is_fmna_paired()) + { + // Initialize new CKG context on unpair in preparation for new pairing. + APP_PRINT_INFO0("Initialize new CKG context on unpair in preparation for new pairing"); + int ret = fm_crypto_ckg_init(&m_fm_crypto_ckg_ctx); + if (FM_CRYPTO_STATUS_SUCCESS != ret) + { + FMNA_LOG_ERROR("fm_crypto_ckg_init err %d", ret); + } + } +#endif // HARDCODED_PAIRING_ENABLED +} + +void fmna_log_mfi_token_help(void) +{ +#if !HARDCODED_PAIRING_ENABLED + fmna_connection_platform_log_token_help(m_mfi_struct.p_software_auth_token, + SOFTWARE_AUTH_TOKEN_BLEN, m_mfi_struct.m_software_auth_uuid, SOFTWARE_AUTH_UUID_BLEN); +#endif // HARDCODED_PAIRING_ENABLED +} + +void fmna_log_mfi_token(void) +{ +#if !HARDCODED_PAIRING_ENABLED + fmna_connection_platform_log_token(m_mfi_struct.p_software_auth_token, SOFTWARE_AUTH_TOKEN_BLEN); +#endif // HARDCODED_PAIRING_ENABLED +} + +void fmna_log_serial_number(void) +{ + FMNA_LOG_INFO("Serial Number: %s", TRACE_STRING(m_serial_number)); +} diff --git a/src/app/findmy/fmna_adk/fmna_crypto.h b/src/app/findmy/fmna_adk/fmna_crypto.h new file mode 100644 index 0000000..f82e4cb --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_crypto.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_crypto_h +#define fmna_crypto_h + +#include "fmna_constants.h" +#include "stdbool.h" + +#define SOFTWARE_AUTH_UUID_ADDR APPLE_AUTH_TOKEN_SAVE_ADDRESS +#define SOFTWARE_AUTH_TOKEN_ADDR SOFTWARE_AUTH_UUID_ADDR + SOFTWARE_AUTH_UUID_BLEN + +extern bool serial_number_read_state; + +typedef enum +{ + FMNA_SERIAL_NUMBER_QUERY_TYPE_TAP, + FMNA_SERIAL_NUMBER_QUERY_TYPE_BT, +} FMNA_Serial_Number_Query_Type_t; + +typedef struct +{ + uint8_t c1[C1_BLEN]; + uint8_t e2[E2_BLEN]; +} __attribute__((packed)) fmna_send_pairing_data_t; + +extern fmna_send_pairing_data_t *p_fmna_send_pairing_data; + +typedef struct +{ + uint8_t session_nonce[SESSION_NONCE_BLEN]; + uint8_t e1[E1_BLEN]; +} __attribute__((packed)) fmna_initiate_pairing_data_t; + +extern fmna_initiate_pairing_data_t *p_fmna_initiate_pairing_data; + +typedef struct +{ + uint8_t c2[C2_BLEN]; + uint8_t e3[E3_BLEN]; + uint8_t seeds[SEEDS_BLEN]; + uint8_t icloud_id[ICLOUD_IDENTIFIER_BLEN]; + uint8_t s2[S2_BLEN]; +} __attribute__((packed)) fmna_finalize_pairing_data_t; + +extern fmna_finalize_pairing_data_t *p_fmna_finalize_pairing_data; + +typedef struct +{ + uint8_t c3[C3_BLEN]; + uint32_t status; + uint8_t e4[E4_BLEN]; +} __attribute__((packed)) fmna_send_pairing_status_t; + +extern fmna_send_pairing_status_t *p_fmna_send_pairing_status; + +typedef struct +{ + uint8_t m_software_auth_uuid[SOFTWARE_AUTH_UUID_BLEN]; + uint8_t *p_software_auth_token; +} __attribute__((aligned(SYS_POINTER_BSIZE), packed)) mfi_info_t; + +extern uint8_t *p_fmna_encrypted_serial_number_payload; + +void fmna_crypto_init(void); + +fmna_ret_code_t fmna_crypto_generate_send_pairing_data_params(void); +fmna_ret_code_t fmna_crypto_finalize_pairing(void); +fmna_ret_code_t fmna_crypto_pairing_complete(void); + +fmna_ret_code_t fmna_crypto_roll_primary_key(void); +fmna_ret_code_t fmna_crypto_roll_secondary_key(void); +fmna_ret_code_t fmna_crypto_roll_primary_sk(void); +fmna_ret_code_t fmna_crypto_roll_secondary_sk(void); +fmna_ret_code_t fmna_primary_key_update(void); + +void serial_number_read_state_init(void); +fmna_ret_code_t fmna_crypto_generate_serial_number_response(FMNA_Serial_Number_Query_Type_t type); +uint8_t *fmna_crypto_get_serial_number_raw(void); + +void fmna_crypto_unpair(void); + +void fmna_log_mfi_token_help(void); +void fmna_log_mfi_token(void); +void fmna_log_serial_number(void); + +#endif /* fmna_crypto_h */ diff --git a/src/app/findmy/fmna_adk/fmna_debug_control_point.c b/src/app/findmy/fmna_adk/fmna_debug_control_point.c new file mode 100644 index 0000000..1883bb6 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_debug_control_point.c @@ -0,0 +1,133 @@ + + +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + + +#include "fmna_platform_includes.h" +#include "fmna_debug_control_point.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_motion_detection.h" + +#ifdef DEBUG + +//MARK: RX Packet Definitions +const char m_log_chunk[] = "No saved chunk logs"; + +typedef struct +{ + FMNA_Service_Opcode_t set_key_rotation_timeout_opcode; + uint32_t timeout_ms; +} __attribute__((packed)) set_key_rotation_timeout_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t ut_motion_timers_config_opcode; + uint32_t separated_ut_timeout_seconds; + uint32_t separated_ut_backoff_timeout_seconds; +} __attribute__((packed)) ut_motion_timers_config_packet_t; + +/// RX Length Check managers for default and variable length cases. +static fmna_service_length_check_manager_t rx_length_check_managers[] = \ +{ + /* RX Opcode Data Length */ + { FMNA_SERVICE_DEBUG_OPCODE_SET_KEY_ROTATION_TIMEOUT, sizeof(set_key_rotation_timeout_packet_t) }, + { FMNA_SERVICE_DEBUG_OPCODE_RESET, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_DEBUG_OPCODE_RETRIEVE_LOGS, sizeof(generic_control_point_packet_t) }, + { FMNA_SERVICE_DEBUG_UT_MOTION_TIMERS_CONFIG, sizeof(ut_motion_timers_config_packet_t) }, +}; + +static FMNA_Response_Status_t rx_error_check(FMNA_Service_Opcode_t opcode, uint8_t const *data, + uint16_t length) +{ + return fmna_gatt_verify_control_point_opcode_and_length(opcode, length, rx_length_check_managers, + FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(rx_length_check_managers)); +} + +void fmna_debug_control_point_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length) +{ + FMNA_Service_Opcode_t opcode = *(FMNA_Service_Opcode_t *)data; + + FMNA_Response_Status_t response_status = rx_error_check(opcode, data, length); + + if (response_status != RESPONSE_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("Rx error 0x%x for opcode 0x%x, conn_handle 0x%x", response_status, opcode, + conn_handle); + if (response_status == RESPONSE_STATUS_INVALID_COMMAND) + { + opcode = FMNA_SERVICE_OPCODE_NONE; + } + fmna_gatt_send_command_response(FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + return; + } + + response_status = RESPONSE_STATUS_NO_COMMAND_RESPONSE; + + FMNA_LOG_INFO("Debug CP rx: opcode = 0x%x, conn_handle 0x%x", opcode, conn_handle); + + switch (opcode) + { + case FMNA_SERVICE_DEBUG_OPCODE_SET_KEY_ROTATION_TIMEOUT: + fmna_state_machine_set_key_rotation_timeout_ms(((set_key_rotation_timeout_packet_t *) + data)->timeout_ms); + response_status = RESPONSE_STATUS_SUCCESS; + break; + + case FMNA_SERVICE_DEBUG_OPCODE_RESET: + fmna_gatt_send_command_response(FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + RESPONSE_STATUS_SUCCESS); + // "Reset" into Separated, beaconing secondary key. + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_DEBUG_RESET_INTO_SEPARATED); +// response_status = RESPONSE_STATUS_SUCCESS; + break; + + case FMNA_SERVICE_DEBUG_OPCODE_RETRIEVE_LOGS: + FMNA_LOG_INFO("RX Retrieve Logs"); + + //TODO: Send all logs in multiple chunks, if applicable. + + // Send empty chunk of size GATT_MAX_MTU_SIZE --> this will get broken up into two messages. + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_DEBUG_OPCODE_LOG_RESPONSE, + (void *)m_log_chunk, + sizeof(m_log_chunk)); + break; + + case FMNA_SERVICE_DEBUG_UT_MOTION_TIMERS_CONFIG: + { + ut_motion_timers_config_packet_t *packet = (ut_motion_timers_config_packet_t *)data; + FMNA_LOG_INFO("Separated UT timeout: %d s -- Separated UT backoff timeout: %d s", + packet->separated_ut_timeout_seconds, + packet->separated_ut_backoff_timeout_seconds); + + fmna_state_machine_set_separated_ut_timeout_seconds(packet->separated_ut_timeout_seconds); + fmna_motion_detection_set_separated_ut_backoff_timeout_seconds( + packet->separated_ut_backoff_timeout_seconds); + + response_status = RESPONSE_STATUS_SUCCESS; + } break; + + default: + // We should never get here! rx_error_check should check for unknown command and respond with failed command response. + FMNA_LOG_ERROR("Invalid opcode for debug control point received"); + } + + if (RESPONSE_STATUS_NO_COMMAND_RESPONSE != response_status) + { + // Send command response if this command needs one. + fmna_gatt_send_command_response(FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + } +} + +#endif // DEBUG + diff --git a/src/app/findmy/fmna_adk/fmna_debug_control_point.h b/src/app/findmy/fmna_adk/fmna_debug_control_point.h new file mode 100644 index 0000000..0d6f039 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_debug_control_point.h @@ -0,0 +1,27 @@ + + +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#ifndef fmna_debug_control_point_h +#define fmna_debug_control_point_h + +#include "fmna_gatt.h" + +#ifdef DEBUG + +/// Function for handling the different Debug opcodes. +/// @param data Buffer of data of debug opcode and possible operands +void fmna_debug_control_point_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length); + +#endif // DEBUG + +#endif /* fmna_debug_control_point_h */ + + diff --git a/src/app/findmy/fmna_adk/fmna_gatt.c b/src/app/findmy/fmna_adk/fmna_gatt.c new file mode 100644 index 0000000..34d9afd --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_gatt.c @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" +#include "fmna_config_control_point.h" +#include "fmna_connection.h" +#include "fmna_pairing_control_point.h" +#include "fmna_nonowner_control_point.h" +#include "fmna_state_machine.h" +#include "fmna_paired_owner_control_point.h" +#ifdef USE_UARP +#include "fmna_uarp_control_point.h" +#endif +#ifdef DEBUG +#include "fmna_debug_control_point.h" +#endif // DEBUG + +#define FMNA_OPCODE_LENGTH 2 +#define START_PACKET_DATA_LENGTH (GATT_MAX_MTU_SIZE - FRAGMENTATION_HEADER_LENGTH - FMNA_OPCODE_LENGTH) +#define CONTINUE_PACKET_DATA_LENGTH (GATT_MAX_MTU_SIZE - FRAGMENTATION_HEADER_LENGTH) + +uint16_t m_gatt_mtu = GATT_MAX_MTU_SIZE - GATT_HEADER_LEN; + +typedef struct +{ + uint8_t header; + union + { + struct + { + FMNA_Service_Opcode_t opcode; + uint8_t data[START_PACKET_DATA_LENGTH]; + } __attribute__((packed)) single_packet_data; + uint8_t continuation_packet_data[CONTINUE_PACKET_DATA_LENGTH]; + } __attribute__((packed)) data; +} __attribute__((packed)) tx_buffer_t; + +tx_buffer_t tx_buffer; + +#if HARDCODED_PAIRING_ENABLED +uint8_t keys_to_rotate[NUM_OF_KEYS][FMNA_PUBKEY_BLEN] = {0}; +uint32_t current_key_index = 0; +#endif + +fmna_service_extended_packet_t fmna_service_current_extended_packet_tx = {}; + +/// Ensure this GATT message has valid payload after fragmented flag header byte. +static fmna_ret_code_t fmna_gatt_verify_rx_length(uint16_t length) +{ + if (length >= (FRAGMENTED_FLAG_LENGTH + sizeof(FMNA_Service_Opcode_t))) + { + return FMNA_SUCCESS; + } + else + { + return FMNA_ERROR_INVALID_LENGTH; + } +} + +FMNA_Response_Status_t fmna_gatt_verify_control_point_opcode_and_length( + FMNA_Service_Opcode_t opcode, uint16_t length, fmna_service_length_check_manager_t *managers, + uint8_t num_managers) +{ + for (uint8_t i = 0; i < num_managers; i++) + { + if (managers[i].opcode == opcode) + { + if (managers[i].length == length) + { + return RESPONSE_STATUS_SUCCESS; + } + else + { + FMNA_LOG_ERROR("Invalid Length %d for RX Opcode 0x%x", length, opcode); + return RESPONSE_STATUS_INVALID_LENGTH; + } + } + } + FMNA_LOG_ERROR("Invalid Command: Rx Opcode 0x%x", opcode); + return RESPONSE_STATUS_INVALID_COMMAND; +} + +fmna_ret_code_t fmna_gatt_config_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + FMNA_LOG_INFO("Configuration Command issued, UUID: 0x%x", uuid); + + ret_code = fmna_gatt_verify_rx_length(length); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Incomplete packet - len = %d", length); + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, conn_handle, + FMNA_SERVICE_OPCODE_NONE, RESPONSE_STATUS_INVALID_COMMAND); + return FMNA_ERROR_INVALID_DATA; + } + + // Check fragmentation + if (data[FRAGMENTED_FLAG_INDEX] != FRAGMENTED_FLAG_FINAL) + { + FMNA_LOG_ERROR("Configuration command lengths do not exceed mtu"); + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, conn_handle, + *(FMNA_Service_Opcode_t *)&data[FRAGMENTED_FLAG_LENGTH], RESPONSE_STATUS_INVALID_LENGTH); + return FMNA_ERROR_INVALID_LENGTH; + } + + fmna_config_control_point_rx_handler(conn_handle, &data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_gatt_nonown_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + FMNA_LOG_INFO("Non-owner Command issued, UUID: 0x%x", uuid); + + //Check length + ret_code = fmna_gatt_verify_rx_length(length); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Incomplete packet - len = %d", length); + fmna_gatt_send_command_response(FMNA_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, + FMNA_SERVICE_OPCODE_NONE, RESPONSE_STATUS_INVALID_COMMAND); + return FMNA_ERROR_INVALID_DATA; + } + + // Check fragmentation + if (data[FRAGMENTED_FLAG_INDEX] != FRAGMENTED_FLAG_FINAL) + { + FMNA_LOG_ERROR("Non-owner command lengths do not exceed mtu"); + fmna_gatt_send_command_response(FMNA_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, + *(FMNA_Service_Opcode_t *)&data[FRAGMENTED_FLAG_LENGTH], RESPONSE_STATUS_INVALID_LENGTH); + return FMNA_ERROR_INVALID_LENGTH; + } + + fmna_nonowner_rx_handler(conn_handle, &data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + + return FMNA_SUCCESS; +} + +#ifdef USE_UARP +fmna_ret_code_t fmna_gatt_uarp_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + FMNA_LOG_INFO("UARP Write issued, UUID: 0x%x", uuid); + + return fmna_uarp_authorized_rx_handler(conn_handle, data, length); +} +#endif + +fmna_ret_code_t fmna_gatt_paired_owner_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + FMNA_LOG_INFO("Paired Owner Command issued, UUID: 0x%x", uuid); + + //Check length + ret_code = fmna_gatt_verify_rx_length(length); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Incomplete packet - len = %d", length); + + fmna_gatt_send_command_response(FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, + FMNA_SERVICE_OPCODE_NONE, RESPONSE_STATUS_INVALID_COMMAND); + return FMNA_ERROR_INVALID_LENGTH; + } + + // Check fragmentation + if (data[FRAGMENTED_FLAG_INDEX] != FRAGMENTED_FLAG_FINAL) + { + FMNA_LOG_ERROR("Paired owner command lengths do not exceed mtu"); + + fmna_gatt_send_command_response(FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, + *(FMNA_Service_Opcode_t *)&data[FRAGMENTED_FLAG_LENGTH], RESPONSE_STATUS_INVALID_LENGTH); + return FMNA_ERROR_INVALID_DATA; + } + + fmna_paired_owner_rx_handler(conn_handle, &data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + + return FMNA_SUCCESS; +} + +#ifdef DEBUG +fmna_ret_code_t fmna_gatt_debug_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + FMNA_LOG_INFO("Debug Command issued, UUID: 0x%x", uuid); + + //Check length + ret_code = fmna_gatt_verify_rx_length(length); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Incomplete packet - len = %d", length); + fmna_gatt_send_command_response(FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE, conn_handle, + FMNA_SERVICE_OPCODE_NONE, RESPONSE_STATUS_INVALID_STATE); + return FMNA_ERROR_INVALID_LENGTH; + } + + // Check fragmentation + if (data[FRAGMENTED_FLAG_INDEX] != FRAGMENTED_FLAG_FINAL) + { + FMNA_LOG_ERROR("Debug command lengths do not exceed mtu"); + fmna_gatt_send_command_response(FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE, conn_handle, + *(FMNA_Service_Opcode_t *)&data[FRAGMENTED_FLAG_LENGTH], RESPONSE_STATUS_INVALID_LENGTH); + return FMNA_ERROR_INVALID_DATA; + } + + fmna_debug_control_point_rx_handler(conn_handle, &data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + + return FMNA_SUCCESS; +} +#endif //DEBUG + +fmna_ret_code_t fmna_gatt_pairing_char_authorized_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + FMNA_LOG_INFO("Write request of Pairing Characteristic"); + + if (fmna_connection_is_fmna_paired() == true) + { + FMNA_LOG_ERROR("Already paired - refusing write request"); + return FMNA_ERROR_INVALID_STATE; + } + + ret_code = fmna_pairing_control_point_append_to_rx_buffer(&data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + if (ret_code != FMNA_SUCCESS) + { + return ret_code; + } + + if (data[FRAGMENTED_FLAG_INDEX] == FRAGMENTED_FLAG_FINAL) + { + ret_code = fmna_gatt_verify_rx_length(length); + if (ret_code != FMNA_SUCCESS) + { + fmna_pairing_control_point_unpair(); + return ret_code; + } + fmna_pairing_control_point_handle_rx(); + } + + return ret_code; +} + +static bool fmna_gatt_is_tx_allowed(uint16_t conn_handle, FMNA_Service_Opcode_t opcode) +{ + bool tx_allowed = true; + + switch (opcode & FMNA_SERVICE_OPCODE_BASE_MASK) + { + case FMNA_SERVICE_OPCODE_CONFIG_CONTROL_POINT_BASE: + tx_allowed = fmna_config_control_point_is_tx_allowed(conn_handle, opcode); + break; + + default: + break; + } + + return tx_allowed; +} + +static void fmna_gatt_dispatch_send_packet_extension_indication_handler(void *p_event_data, + uint16_t event_size) +{ + fmna_gatt_send_indication_internal(fmna_gatt_get_most_recent_conn_handle(), + FMNA_SERVICE_OPCODE_PACKET_EXTENSION, fmna_service_current_extended_packet_tx.data, + fmna_service_current_extended_packet_tx.length); +} + +void fmna_gatt_dispatch_send_packet_extension_indication(void) +{ + app_sched_event_put(NULL, NULL, fmna_gatt_dispatch_send_packet_extension_indication_handler); +} + + +void fmna_gatt_send_indication(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, void *data, + uint16_t length) +{ + uint8_t queue_msg; + if (fmna_connection_get_num_connections() == 0) + { + return; + } + + FMNA_LOG_INFO("tx conn_handle 0x%x: opcode = 0x%x, length = %d", conn_handle, opcode, length); + + queue_msg = fmna_gatt_platform_send_indication_busy(conn_handle, opcode, data, length); + + if (queue_msg == 0) + { + fmna_gatt_send_indication_internal(conn_handle, opcode, data, length); + } +} + + +void fmna_gatt_send_indication_internal(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + void *data, uint16_t length) +{ + uint8_t headers_length; + uint16_t packet_length; + bool did_send_indication = false; + uint16_t total_length = 0; + + fmna_ret_code_t ret_code; + + FMNA_LOG_INFO("fmna_gatt_send_indication_internal"); + headers_length = sizeof(tx_buffer.header); + if (opcode != FMNA_SERVICE_OPCODE_PACKET_EXTENSION && + opcode != FMNA_SERVICE_OPCODE_INTERNAL_UARP) // If the indication being sent is the first fragment, include the opcode in the "header" + { + headers_length += sizeof(opcode); + } + + memset(&tx_buffer, 0, sizeof(tx_buffer)); + total_length = headers_length + length; + // Fill header + if (total_length > m_gatt_mtu) + { + CLR_BIT(tx_buffer.header, FRAGMENTATION_BIT); + packet_length = m_gatt_mtu; + } + else + { + SET_BIT(tx_buffer.header, + FRAGMENTATION_BIT); // Setting the fragmentation bit means last fragment of indication to be sent + packet_length = total_length; + } + + // Fill data + if (opcode != FMNA_SERVICE_OPCODE_PACKET_EXTENSION && opcode != FMNA_SERVICE_OPCODE_INTERNAL_UARP) + { + tx_buffer.data.single_packet_data.opcode = opcode; + if ((total_length) > m_gatt_mtu) + { + memcpy(tx_buffer.data.single_packet_data.data, data, m_gatt_mtu - headers_length); + } + else + { + memcpy(tx_buffer.data.single_packet_data.data, data, length); + } + } + else + { + if ((total_length) > m_gatt_mtu) + { + memcpy(tx_buffer.data.continuation_packet_data, data, m_gatt_mtu - headers_length); + } + else + { + memcpy(tx_buffer.data.continuation_packet_data, data, length); + } + } + + if (fmna_gatt_is_tx_allowed(conn_handle, opcode)) + { + // Send indication to the specific central. + ret_code = fmna_gatt_platform_send_indication(conn_handle, &opcode, (uint8_t *)&tx_buffer, + packet_length); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("Send indication fail. opcode 0x%x, conn_handle 0x%x, err 0x%x", opcode, conn_handle, + ret_code); + } + else + { + did_send_indication = true; + } + } + + if (did_send_indication) + { + // Check if there is still indication left to be sent + if (total_length > m_gatt_mtu) + { + uint8_t *p_data; + p_data = data; + fmna_service_current_extended_packet_tx.opcode = opcode; + fmna_service_current_extended_packet_tx.data = p_data + (m_gatt_mtu - headers_length); + fmna_service_current_extended_packet_tx.length = length - (m_gatt_mtu - headers_length); + } + else + { + memset(&fmna_service_current_extended_packet_tx, 0, + sizeof(fmna_service_current_extended_packet_tx)); + } + } + else + { + memset(&fmna_service_current_extended_packet_tx, 0, + sizeof(fmna_service_current_extended_packet_tx)); + FMNA_LOG_INFO("No indication sent, try next indication"); + fmna_gatt_dispatch_send_next_packet(); + } +} + +control_point_command_response_data_t m_command_response_data[MAX_CONTROL_POINT_RSP]; +uint8_t m_command_response_index = 0; + +void fmna_gatt_send_command_response(FMNA_Service_Opcode_t command_response_opcode, + uint16_t conn_handle, FMNA_Service_Opcode_t command_opcode, FMNA_Response_Status_t status) +{ + uint8_t index = fmna_gatt_platform_get_next_command_response_index(); + m_command_response_data[index].opcode = command_opcode; + m_command_response_data[index].status = status; + fmna_gatt_send_indication(conn_handle, command_response_opcode, &(m_command_response_data[index]), + sizeof(control_point_command_response_data_t)); +} + +void fmna_gatt_init(void) +{ + fmna_gatt_platform_init(); +} + +void fmna_gatt_services_init(void) +{ + fmna_gatt_platform_services_init(); +} + +uint16_t fmna_gatt_get_most_recent_conn_handle(void) +{ + return fmna_gatt_platform_get_most_recent_conn_handle(); +} + +void fmna_gatt_reset_queues(void) +{ + fmna_gatt_platform_reset_indication_queue(); +} + +static void fmna_gatt_dispatch_send_next_packet_handler(void *p_event_data, uint16_t event_size) +{ + fmna_gatt_platform_send_next_indication(); +} + +void fmna_gatt_dispatch_send_next_packet(void) +{ + app_sched_event_put(NULL, NULL, fmna_gatt_dispatch_send_next_packet_handler); +} + diff --git a/src/app/findmy/fmna_adk/fmna_gatt.h b/src/app/findmy/fmna_adk/fmna_gatt.h new file mode 100644 index 0000000..76e67bf --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_gatt.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_gatt_h +#define fmna_gatt_h + +#include "fmna_constants.h" +#include +#include + +extern uint16_t m_gatt_mtu; + +#define FRAGMENTED_FLAG_INDEX 0 +#define FRAGMENTED_FLAG_LENGTH 1 +#define FRAGMENTATION_BIT 0 + +#define FRAGMENTATION_HEADER_LENGTH 1 + +#define FMNA_AIS_UUID_SERVICE 0x0102; + +#define ACC_CAPABILITY_PLAY_SOUND_BIT_POS 0 +#define ACC_CAPABILITY_UT_MOTION_DETECT_BIT_POS 1 +#define ACC_CAPABILITY_SRNM_LOOKUP_NFC_BIT_POS 2 +#define ACC_CAPABILITY_SRNM_LOOKUP_BLE_BIT_POS 3 +#define ACC_CAPABILITY_FW_UPDATE_SERVICE_BIT_POS 4 + +// Fragmentation flags available +typedef enum +{ + FRAGMENTED_FLAG_START_OR_CONTINUE = 0x0, + FRAGMENTED_FLAG_FINAL, +} fragmented_flag_t; + + +// UUIDs of the characteristics in AIS +typedef enum +{ + FMNA_AIS_UUID_PRODUCT_DATA = 0x0001, + FMNA_AIS_UUID_MANU_NAME, + FMNA_AIS_UUID_MODEL_NAME, + FMNA_AIS_UUID_RESERVED, + FMNA_AIS_UUID_ACC_CATEGORY, + FMNA_AIS_UUID_ACC_CAPABILITIES, + FMNA_AIS_UUID_FW_VERS, + FMNA_AIS_UUID_FINDMY_VERS, + FMNA_AIS_UUID_BATT_TYPE, + FMNA_AIS_UUID_BATT_LVL, +} FMNA_AIS_Char_UUID_t; + +// PAIRING control point Commands +typedef enum +{ + FMNA_SERVICE_OPCODE_NONE = 0x0000, + + // Pairing + FMNA_SERVICE_OPCODE_PAIRING_CONTROL_POINT_BASE = 0x0100, + FMNA_SERVICE_OPCODE_INITIATE_PAIRING = 0x0100, + FMNA_SERVICE_OPCODE_SEND_PAIRING_DATA = 0x0101, + FMNA_SERVICE_OPCODE_FINALIZE_PAIRING = 0x0102, + FMNA_SERVICE_OPCODE_SEND_PAIRING_STATUS = 0x0103, + FMNA_SERVICE_OPCODE_PAIRING_COMPLETE = 0x0104, + + // Config + FMNA_SERVICE_OPCODE_CONFIG_CONTROL_POINT_BASE = 0x0200, + FMNA_SERVICE_OPCODE_SOUND_START = 0x0200, + FMNA_SERVICE_OPCODE_SOUND_STOP = 0x0201, + FMNA_SERVICE_OPCODE_PERSISTENT_CONNECTION_STATUS = 0x0202, + FMNA_SERVICE_OPCODE_SET_NEARBY_TIMEOUT = 0x0203, + FMNA_SERVICE_OPCODE_UNPAIR = 0x0204, + FMNA_SERVICE_OPCODE_CONFIGURE_SEPARATED_STATE = 0x0205, + FMNA_SERVICE_OPCODE_LATCH_SEPARATED_KEY = 0x0206, + FMNA_SERVICE_OPCODE_SET_MAX_CONNECTIONS = 0x0207, + FMNA_SERVICE_OPCODE_SET_UTC = 0x0208, + FMNA_SERVICE_OPCODE_GET_MULTI_STATUS = 0x0209, + FMNA_SERVICE_OPCODE_KEYROLL_INDICATION = 0x020A, + FMNA_SERVICE_OPCODE_COMMAND_RESPONSE = 0x020B, + FMNA_SERVICE_OPCODE_GET_MULTI_STATUS_RESPONSE = 0x020C, + FMNA_SERVICE_OPCODE_SOUND_COMPLETED = 0x020D, + FMNA_SERVICE_OPCODE_LATCH_SEPARATED_KEY_RESPONSE = 0x020E, + + // Non-owner + FMNA_SERVICE_OPCODE_NON_OWNER_CONTROL_POINT_BASE = 0x0300, + FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_START = 0x0300, + FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_STOP = 0x0301, + FMNA_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE = 0x0302, + FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_COMPLETED = 0x0303, + FMNA_SERVICE_NON_OWNER_OPCODE_START_AGGRESSIVE_ADV = 0x0304, + + // Paired Owner information + FMNA_SERVICE_OPCODE_PAIRED_OWNER_CONTROL_POINT_BASE = 0x0400, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY = 0x0400, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER = 0x0401, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY_RESPONSE = 0x0402, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER_RESPONSE = 0x0403, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER = 0x0404, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER_RESPONSE = 0x0405, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE = 0x0406, + +#ifdef DEBUG + FMNA_SERVICE_OPCODE_DEBUG_CONTROL_POINT_BASE = 0x0500, + FMNA_SERVICE_DEBUG_OPCODE_SET_KEY_ROTATION_TIMEOUT = 0x0500, + FMNA_SERVICE_DEBUG_OPCODE_RETRIEVE_LOGS = 0x0501, + FMNA_SERVICE_DEBUG_OPCODE_LOG_RESPONSE = 0x0502, + FMNA_SERVICE_DEBUG_OPCODE_COMMAND_RESPONSE = 0x0503, + FMNA_SERVICE_DEBUG_OPCODE_RESET = 0x0504, + FMNA_SERVICE_DEBUG_UT_MOTION_TIMERS_CONFIG = 0x0505, +#endif //DEBUG + + // Reserved - can change if needed + FMNA_SERVICE_OPCODE_PACKET_EXTENSION = 0x01FF, + + // Internal opcode for sending UARP + FMNA_SERVICE_OPCODE_INTERNAL_UARP_BASE = 0x0600, + FMNA_SERVICE_OPCODE_INTERNAL_UARP = 0x06FF, +} FMNA_Service_Opcode_t; + +#define FMNA_SERVICE_OPCODE_BASE_MASK 0xFF00 + +// Response Status to Command Reponse possibilities +typedef enum +{ + RESPONSE_STATUS_SUCCESS = 0x0000, + RESPONSE_STATUS_INVALID_STATE = 0x0001, + RESPONSE_STATUS_INVALID_CONFIGURATION = 0x0002, + RESPONSE_STATUS_INVALID_LENGTH = 0x0003, + RESPONSE_STATUS_INVALID_PARAM = 0x0004, + RESPONSE_STATUS_NO_COMMAND_RESPONSE = 0xFFFE, + RESPONSE_STATUS_INVALID_COMMAND = 0xFFFF, +} FMNA_Response_Status_t; + +typedef struct +{ + FMNA_Service_Opcode_t opcode; + uint16_t length; +} fmna_service_length_check_manager_t; + +#define FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(managers) (sizeof(managers)/sizeof(managers[0])) + +// Struct for containing the data for a packet longer than the MTU +typedef struct +{ + FMNA_Service_Opcode_t opcode; + uint8_t *data; + uint16_t length; +} fmna_service_extended_packet_t; + +extern fmna_service_extended_packet_t fmna_service_current_extended_packet_tx; + +#if HARDCODED_PAIRING_ENABLED +extern uint32_t current_key_index; +extern uint8_t keys_to_rotate[NUM_OF_KEYS][FMNA_PUBKEY_BLEN]; +#endif + +typedef struct +{ + FMNA_Service_Opcode_t opcode; +} __attribute__((packed)) generic_control_point_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t opcode; + FMNA_Response_Status_t status; +} __attribute__((packed)) control_point_command_response_data_t; + +#define MAX_CONTROL_POINT_RSP 10 +extern uint8_t m_command_response_index; + +/// Generic function to send indications (via GATT) to a specific central. +/// +/// @param[in] conn_handle Handle of connection to send indication to. +/// @param[in] opcode If this is the first fragment of the indication to be sent, the opcode should correspond to the command to be sent. +/// See FMNA_Service_Opcode_t for more details. +/// @param[in] data Data buffer for data associated w/ the specific opcode. +/// @param[in] length Length in bytes of associated data. +/// +/// @note Function will append the opcode, if needed. Do NOT include the opcode in the data buffer. +void fmna_gatt_send_indication(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, void *data, + uint16_t length); +// Function for the platform file +void fmna_gatt_send_indication_internal(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + void *data, uint16_t length); + +void fmna_gatt_send_command_response(FMNA_Service_Opcode_t command_response_opcode, + uint16_t conn_handle, FMNA_Service_Opcode_t command_opcode, FMNA_Response_Status_t status); + +void fmna_gatt_dispatch_send_packet_extension_indication(void); + +FMNA_Response_Status_t fmna_gatt_verify_control_point_opcode_and_length( + FMNA_Service_Opcode_t opcode, uint16_t length, fmna_service_length_check_manager_t *managers, + uint8_t num_managers); + +void fmna_gatt_init(void); +void fmna_gatt_services_init(void); + +void fmna_gatt_reset_queues(void); +void fmna_gatt_dispatch_send_next_packet(void); + +/// Get conn handle of the most recently connected device, useful for pairing. +uint16_t fmna_gatt_get_most_recent_conn_handle(void); + +fmna_ret_code_t fmna_gatt_config_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +fmna_ret_code_t fmna_gatt_pairing_char_authorized_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +fmna_ret_code_t fmna_gatt_nonown_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +fmna_ret_code_t fmna_gatt_paired_owner_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +fmna_ret_code_t fmna_gatt_debug_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +fmna_ret_code_t fmna_gatt_uarp_char_write_handler(uint16_t conn_handle, uint16_t uuid, + uint16_t length, uint8_t const *data); +#endif /* fmna_gatt_h */ diff --git a/src/app/findmy/fmna_adk/fmna_motion_detection.c b/src/app/findmy/fmna_adk/fmna_motion_detection.c new file mode 100644 index 0000000..17dbe9a --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_motion_detection.c @@ -0,0 +1,241 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#include "fmna_platform_includes.h" +#include "fmna_util.h" +#include "fmna_motion_detection.h" +#include "fmna_state_machine.h" +#include "fmna_constants.h" + +#define SEPARATED_UT_MOTION_SAMPLING_RATE1_MS SEC_TO_MSEC(10) // Passive poll rate +#define SEPARATED_UT_MOTION_SAMPLING_RATE2_MS 500 // Active poll rate +#define SEPARATED_UT_MOTION_ACTIVE_POLL_DURATION_MS SEC_TO_MSEC(20) +#define SEPARATED_UT_MOTION_BACKOFF_MS HOURS_TO_MSEC(6) +#define SEPARATED_UT_MOTION_MAX_SOUND_COUNT 10 + +static bool m_motion_active_polling_enabled = false; +static bool m_motion_active_polling_ended = false; +static uint16_t m_motion_check_poll_rate_ms = SEPARATED_UT_MOTION_SAMPLING_RATE1_MS; +static uint8_t m_motion_sound_count = 0; + +APP_TIMER_DEF(m_motion_poll_timer_id); +static void motion_poll_timer_timeout_handler(void *p_context); + +APP_TIMER_DEF(m_motion_active_poll_duration_timer_id); +static void motion_active_poll_duration_timer_timeout_handler(void *p_context); + +static uint32_t m_motion_backoff_timeout_ms = SEPARATED_UT_MOTION_BACKOFF_MS; +APP_TIMER_DEF(m_motion_backoff_timer_id); +static void motion_backoff_timeout_handler(void *p_context); + +void fmna_motion_detection_init(void) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + + ret_code = app_timer_create(&m_motion_poll_timer_id, APP_TIMER_MODE_REPEATED, + motion_poll_timer_timeout_handler); + FMNA_ERROR_CHECK(ret_code); + ret_code = app_timer_create(&m_motion_active_poll_duration_timer_id, APP_TIMER_MODE_SINGLE_SHOT, + motion_active_poll_duration_timer_timeout_handler); + FMNA_ERROR_CHECK(ret_code); + ret_code = app_timer_create(&m_motion_backoff_timer_id, APP_TIMER_MODE_SINGLE_SHOT, + motion_backoff_timeout_handler); + FMNA_ERROR_CHECK(ret_code); + + //TODO: Any platform-specific motion detection initializations. +} + +static void stop_all_timers(void) +{ + fmna_ret_code_t ret_code = app_timer_stop(m_motion_poll_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("error %d stopping m_motion_poll_timer_id", ret_code); + } + + // Stop the active poll duration timer, if applicable + ret_code = app_timer_stop(m_motion_active_poll_duration_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("error %d stopping m_motion_active_poll_duration_timer_id", ret_code); + } + + // Stop the accel backoff timer, if applicable + ret_code = app_timer_stop(m_motion_backoff_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("error %d stopping m_motion_backoff_timer_id", ret_code); + } +} + +static void motion_active_poll_duration_timeout_sched_handler(void *p_event_data, + uint16_t event_size) +{ + // Haven't detected movement for active polling duration. Turn off motion detection + // and start the backoff timer so that we only reinitialize after X hours. + + FMNA_LOG_INFO("motion_active_poll_duration_timeout_sched_handler"); + fmna_motion_detection_platform_deinit(); + + fmna_ret_code_t ret_code = app_timer_stop(m_motion_poll_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("e,%x", "error %d stopping m_motion_poll_timer_id", ret_code); + } + m_motion_active_polling_enabled = false; + m_motion_active_polling_ended = true; + + ret_code = app_timer_start(m_motion_backoff_timer_id, + APP_TIMER_TICKS(m_motion_backoff_timeout_ms), + NULL); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("f,%x", "error %d starting m_motion_backoff_timer_id", ret_code); + } +} + +void fmna_motion_detection_start_active_polling(void) +{ + fmna_ret_code_t ret_code; + + // initialize to active poll rate + m_motion_check_poll_rate_ms = SEPARATED_UT_MOTION_SAMPLING_RATE2_MS; + + // Check if active poll duration completed during motion detection play sound. + if (!m_motion_active_polling_ended) + { + if (m_motion_sound_count >= SEPARATED_UT_MOTION_MAX_SOUND_COUNT) + { + // Max motion detect sounds played, we should preemptively not restart poll timer and go into backoff mode.. + FMNA_LOG_INFO("Max motion detection sounds played. Stopping polling, going to backoff."); + + // Stop the polling timer. + ret_code = app_timer_stop(m_motion_active_poll_duration_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("m_motion_active_poll_duration_timer_id stop err"); + } + + // Schedule the handler to cleanup and go into motion detection backoff. + app_sched_event_put(NULL, NULL, motion_active_poll_duration_timeout_sched_handler); + } + else + { + // We are still active polling... (re)start polling. + ret_code = app_timer_start(m_motion_poll_timer_id, APP_TIMER_TICKS(m_motion_check_poll_rate_ms), + NULL); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("m_motion_poll_timer_id start err"); + } + + if (!m_motion_active_polling_enabled) + { + // Start active polling for the first time. + FMNA_LOG_INFO("Starting active poll duration timer"); + // If we are currently active polling, don't restart the timer. + ret_code = app_timer_start(m_motion_active_poll_duration_timer_id, + APP_TIMER_TICKS(SEPARATED_UT_MOTION_ACTIVE_POLL_DURATION_MS), NULL); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("m_motion_active_poll_duration_timer_id start err %d", ret_code); + } + m_motion_active_polling_enabled = true; + } + } + } +} + +void motion_detected_handler(void) +{ + // Check if we detect motion, e.g. orientation change. + if (fmna_motion_detection_platform_is_motion_detected()) + { + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_MOTION_DETECTED); + m_motion_sound_count++; + } +} + +void motion_poll_timer_timeout_handler(void *p_context) +{ + FMNA_LOG_INFO("motion_poll_timer_timeout_handler"); + + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_MT; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[cust_button_int_handler] Send int_gpio_msg failed!"); + return; + } +} + +void motion_backoff_timeout_handler(void *p_context) +{ + FMNA_LOG_INFO("motion_backoff_timeout_handler"); + + // Backoff period is over, and we are still in Separated. Re-init motion detection. + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_UT_START; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[separated_ut_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +void motion_active_poll_duration_timer_timeout_handler(void *p_context) +{ + FMNA_LOG_INFO("motion_active_poll_duration_timer_timeout_handler"); + + // Schedule poll timer stop and blackout timer start. + app_sched_event_put(NULL, NULL, motion_active_poll_duration_timeout_sched_handler); +} + +void fmna_motion_detection_stop(void) +{ + FMNA_LOG_INFO("fmna_motion_detection_stop"); + + stop_all_timers(); + + // Power off motion detection, cleanup. + fmna_motion_detection_platform_deinit(); +} + +void fmna_motion_detection_start(void) +{ + FMNA_LOG_INFO("fmna_motion_detection_start"); + + // Initialize the poll rate + m_motion_check_poll_rate_ms = SEPARATED_UT_MOTION_SAMPLING_RATE1_MS; + + // Reset state + m_motion_active_polling_ended = false; + m_motion_active_polling_enabled = false; + m_motion_sound_count = 0; + + //TODO: Any platform-specific motion detection initializations. + fmna_motion_detection_platform_init(); + + // Start passive polling to detect motion + fmna_ret_code_t ret_code = app_timer_start(m_motion_poll_timer_id, + APP_TIMER_TICKS(m_motion_check_poll_rate_ms), NULL); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("error 0x%x starting m_motion_poll_timer_id", ret_code); + } +} + +#ifdef DEBUG +void fmna_motion_detection_set_separated_ut_backoff_timeout_seconds(uint32_t + separated_ut_backoff_timeout_seconds) +{ + m_motion_backoff_timeout_ms = SEC_TO_MSEC(separated_ut_backoff_timeout_seconds); +} +#endif //DEBUG diff --git a/src/app/findmy/fmna_adk/fmna_motion_detection.h b/src/app/findmy/fmna_adk/fmna_motion_detection.h new file mode 100644 index 0000000..89a3e2a --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_motion_detection.h @@ -0,0 +1,25 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#ifndef fmna_motion_detection_h +#define fmna_motion_detection_h + +#include "board.h" + +void fmna_motion_detection_init(void); +void fmna_motion_detection_stop(void); +void fmna_motion_detection_start(void); +void fmna_motion_detection_start_active_polling(void); +void motion_detected_handler(void); + +#ifdef DEBUG +void fmna_motion_detection_set_separated_ut_backoff_timeout_seconds(uint32_t + separated_ut_backoff_timeout_seconds); +#endif //DEBUG + +#endif /* fmna_motion_detection_h */ diff --git a/src/app/findmy/fmna_adk/fmna_nfc.c b/src/app/findmy/fmna_adk/fmna_nfc.c new file mode 100644 index 0000000..f9b954d --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_nfc.c @@ -0,0 +1,274 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#include "fmna_nfc.h" +#include "fmna_constants.h" +#include "fmna_connection.h" +#include "fmna_crypto.h" +#include "fmna_adv.h" +#include "fmna_nfc_platform.h" +#include "fmna_version.h" +#include "url_ndef.h" +#include "fmna_malloc_platform.h" +#include "trace.h" + +#if SUPPORT_NFC + +static const char *m_nfc_url_key_strings[] = +{ + "URL_KEY_BATT_STATUS", + "URL_KEY_SERIAL_NUMBER_RAW", + "URL_KEY_SERIAL_NUMBER_ENCRYPTED", + "URL_KEY_OP", + "URL_KEY_BT_MAC_ADDR", +}; + +typedef struct +{ + char bd_addr_str[FMNA_BLE_MAC_ADDR_BLEN * 2 + 1]; + char srnm_raw[SERIAL_NUMBER_RAW_BLEN + 1]; +} __attribute__((packed)) nfc_tap_url_unpaired_values_t; + +typedef struct +{ + char srnm_encrypted[ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN * 2 + 1]; + char op[SERIAL_NUMBER_PAYLOAD_OP_BLEN]; +} __attribute__((packed)) nfc_tap_url_paired_values_t; + +typedef struct +{ + uint16_t pid; + uint8_t batt_status; + uint32_t fw_version; + union + { + nfc_tap_url_unpaired_values_t nfc_tap_url_unpaired_values; + nfc_tap_url_paired_values_t nfc_tap_url_paired_values; + } nfc_tap_url_paired_state_values; +} __attribute__((packed)) nfc_tap_url_embedded_values_t; + +static nfc_tap_url_embedded_values_t m_nfc_tap_url_embedded_values = +{ + .pid = FMNA_PID, +}; + +#define NFC_TAP_URL_MAX_BSIZE (NFC_TAP_URL_BASE_BSIZE + sizeof(nfc_tap_url_embedded_values_t) + 50) + +static const char *m_base_url = "found.apple.com/accessory?pid=%04x&b=%02x&fv=%08x"; +#define NFC_TAP_URL_BASE_BSIZE 51 + +static const char *m_unpaired_url_suffix = "&bt=%s&sr=%s"; +static const char *m_paired_url_suffix = "&e=%s&op=%s"; + +static uint8_t m_nfc_tap_url[NFC_TAP_URL_MAX_BSIZE]; +static size_t m_nfc_url_length; + +static void hex_arr_to_ascii_str(char *dst_ascii_string, uint8_t *src_hex_arr, uint8_t data_length) +{ + for (uint8_t i = 0; i < data_length; i++) + { + dst_ascii_string[i] = (char)(src_hex_arr[i]); + } + dst_ascii_string[data_length] = '\0'; +} + +static void arr_to_hex_str(char *dst_hex_string, uint8_t *src_arr, uint8_t src_arr_length) +{ + char *dst_hex_string_start = dst_hex_string; + for (uint8_t i = 0; i < src_arr_length; i++) + { + dst_hex_string += sprintf(dst_hex_string, "%02x", src_arr[i]); + } + *dst_hex_string = '\0'; + dst_hex_string = dst_hex_string_start; + + FMNA_LOG_HEXDUMP_DEBUG(dst_hex_string, src_arr_length * 2); +} + +/// Program the NFC URL with appropriate values. +static fmna_ret_code_t update_url(void) +{ + // Clear the URL initially. + memset(m_nfc_tap_url, 0, NFC_TAP_URL_MAX_BSIZE); + + int ret = snprintf((char *)m_nfc_tap_url, + NFC_TAP_URL_MAX_BSIZE, + m_base_url, + m_nfc_tap_url_embedded_values.pid, + m_nfc_tap_url_embedded_values.batt_status, + m_nfc_tap_url_embedded_values.fw_version); + if (!(ret > 0 && ret < NFC_TAP_URL_MAX_BSIZE)) + { + FMNA_LOG_ERROR("update_url snprintf base url err %d", ret); + return FMNA_ERROR_INVALID_DATA; + } + + uint8_t base_url_len = strlen((char *)m_nfc_tap_url); + + // Check if we are paired or not to use which URL. + if (fmna_connection_is_fmna_paired()) + { + ret = snprintf((char *)m_nfc_tap_url + base_url_len, + NFC_TAP_URL_MAX_BSIZE - base_url_len, + m_paired_url_suffix, + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_paired_values.srnm_encrypted, + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_paired_values.op); + } + else + { + ret = snprintf((char *)m_nfc_tap_url + base_url_len, + NFC_TAP_URL_MAX_BSIZE - base_url_len, + m_unpaired_url_suffix, + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_unpaired_values.bd_addr_str, + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_unpaired_values.srnm_raw); + } + + if (!(ret > 0 && ret < (NFC_TAP_URL_MAX_BSIZE - base_url_len))) + { + FMNA_LOG_ERROR("update_url snprintf paired state url err %d", ret); + return FMNA_ERROR_INVALID_DATA; + } + + m_nfc_url_length = strlen((char *)m_nfc_tap_url); + FMNA_LOG_INFO("NFC URL: %s", TRACE_STRING((char *)m_nfc_tap_url)); + FMNA_LOG_INFO("NFC URL LENGTH: %d", m_nfc_url_length); + + // Reactivate NFC emulation + NDEF_URIInit(m_nfc_tap_url, m_nfc_url_length); + + fmna_ret_code_t ret_code = fmna_nfc_write_ndef(); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("fmna_nfc_write_ndef err 0x%x", ret_code); + } + + return ret_code; +} + +void fmna_nfc_set_url_key(FMNA_NFC_URL_Key_t nfc_url_key, void *nfc_url_key_data) +{ + FMNA_LOG_INFO("Set %s", TRACE_STRING(m_nfc_url_key_strings[nfc_url_key])); + + fmna_ret_code_t ret_code; + + switch (nfc_url_key) + { + case URL_KEY_BATT_STATUS: + m_nfc_tap_url_embedded_values.batt_status = *(uint8_t *)nfc_url_key_data; + break; + + case URL_KEY_BT_MAC_ADDR: + // Copy the pairing BD ADDR. + arr_to_hex_str( + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_unpaired_values.bd_addr_str, + (uint8_t *)nfc_url_key_data, + FMNA_BLE_MAC_ADDR_BLEN); + break; + + case URL_KEY_SERIAL_NUMBER_RAW: + // Copy the SRNM. + hex_arr_to_ascii_str( + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_unpaired_values.srnm_raw, + (uint8_t *)nfc_url_key_data, + SERIAL_NUMBER_RAW_BLEN); + break; + + case URL_KEY_SERIAL_NUMBER_ENCRYPTED: + arr_to_hex_str( + m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_paired_values.srnm_encrypted, + (uint8_t *)nfc_url_key_data, + ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN); + break; + + default: + FMNA_LOG_INFO("Unrecognized NFC Key: %d", nfc_url_key); + break; + } + + ret_code = update_url(); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("update_url err 0x%x", ret_code); + } +} + +/// Generate next encrypted serial number and program the NFC URL. +static void update_nfc_encrypted_serial_number(void) +{ + // (re)Generate the encrypted serial number. + fmna_ret_code_t ret_code = fmna_crypto_generate_serial_number_response( + FMNA_SERIAL_NUMBER_QUERY_TYPE_TAP); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("fmna_crypto_generate_serial_number_response err 0x%x", ret_code); + } + + // Set the encrypted serial number URL key for failure or success. In failure case, + // the encrypted serial number will be cleared out. + fmna_nfc_set_url_key(URL_KEY_SERIAL_NUMBER_ENCRYPTED, p_fmna_encrypted_serial_number_payload); + + fmna_free(ENCRYPTED_SN); +} + +void fmna_nfc_load_paired_url(void) +{ + // Should be paired here. Assert if not. + FMNA_ERROR_CHECK_BOOL(fmna_connection_is_fmna_paired()); + + strncpy(m_nfc_tap_url_embedded_values.nfc_tap_url_paired_state_values.nfc_tap_url_paired_values.op, + "tap", SERIAL_NUMBER_PAYLOAD_OP_BLEN); + + // Generate the first encrypted serial number. + update_nfc_encrypted_serial_number(); +} + +void fmna_nfc_load_unpaired_url(void) +{ + // Should be unpaired here. + FMNA_ERROR_CHECK_BOOL(!fmna_connection_is_fmna_paired()); + + // Set the raw serial number, bluetooth address. + + uint8_t unpaired_bt_addr[FMNA_BLE_MAC_ADDR_BLEN]; + fmna_adv_get_unpaired_bt_addr(unpaired_bt_addr); + + // set address type bits for random static (0b11) + unpaired_bt_addr[0] |= (uint8_t)FMNA_ADV_ADDR_TYPE_MASK; + + fmna_nfc_set_url_key(URL_KEY_BT_MAC_ADDR, unpaired_bt_addr); + fmna_nfc_set_url_key(URL_KEY_SERIAL_NUMBER_RAW, fmna_crypto_get_serial_number_raw()); +} + +void fmna_nfc_init(void) +{ + FMNA_LOG_INFO("NFC Init"); + + fmna_ret_code_t ret_code; + + // Initialize base URL keys. + m_nfc_tap_url_embedded_values.fw_version = fmna_version_get_fw_version(); + + ret_code = fmna_nfc_platform_init(); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("fmna_nfc_platform_init err 0x%x", ret_code); + } +// ret_code = update_url(); +// if (FMNA_SUCCESS != ret_code) +// { +// FMNA_LOG_ERROR("update_url err 0x%x", ret_code); +// } +} + +void fmna_nfc_field_off(void) +{ + // Generate the next encrypted serial number val. + update_nfc_encrypted_serial_number(); +} + +#endif diff --git a/src/app/findmy/fmna_adk/fmna_nfc.h b/src/app/findmy/fmna_adk/fmna_nfc.h new file mode 100644 index 0000000..ce40bed --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_nfc.h @@ -0,0 +1,47 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#ifndef fmna_nfc_h +#define fmna_nfc_h + +typedef enum +{ + URL_KEY_BATT_STATUS, + URL_KEY_SERIAL_NUMBER_RAW, + URL_KEY_SERIAL_NUMBER_ENCRYPTED, + URL_KEY_OP, + URL_KEY_BT_MAC_ADDR, +} FMNA_NFC_URL_Key_t; + +/// Initialize NFC module. +/// +/// @details Load initial URL values and initialize NFC platform-dependent module. +void fmna_nfc_init(void); + +/// Update NFC URL key w/ value. +/// +/// @details Set the appropriate key in the URL and reload the URL. +/// Try to reinitialize/ re-init the NFC tag after reloading the URL. +/// +/// @param[in] nfc_url_key URL key (@ref FMNA_NFC_URL_Key_t) to set. +/// @param[in] nfc_url_key_data Data for URL key. +void fmna_nfc_set_url_key(FMNA_NFC_URL_Key_t nfc_url_key, void *nfc_url_key_data); + +/// Load NFC URL keys for paired state, e.g. encrypted serial number, "tap" op string. +void fmna_nfc_load_paired_url(void); + +/// Load NFC URL keys for unpaired state, e.g. BT MAC address, raw serial number. +void fmna_nfc_load_unpaired_url(void); + +/// NFC field lost notification. +/// +/// @details Regenerate encrypted serial number for NFC URL. +/// Should be called by fmna_nfc_platform. +void fmna_nfc_field_off(void); + +#endif /* fmna_nfc_h */ diff --git a/src/app/findmy/fmna_adk/fmna_nonowner_control_point.c b/src/app/findmy/fmna_adk/fmna_nonowner_control_point.c new file mode 100644 index 0000000..6955b34 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_nonowner_control_point.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" +#include "fmna_nonowner_control_point.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_connection.h" + +typedef struct +{ + uint16_t opcode; + FMNA_Response_Status_t status; +} __attribute__((packed)) non_owner_command_response_data_t; + + +//MARK: RX Packet Definitions + +typedef struct +{ + FMNA_Service_Opcode_t sound_start_opcode; +} __attribute__((packed)) nonowner_sound_start_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t sound_stop_opcode; +} __attribute__((packed)) nonowner_sound_stop_packet_t; + +/// RX Length Check managers for default and variable length cases. +static fmna_service_length_check_manager_t rx_length_check_managers[] = \ +{ + /* RX Opcode Data Length */ + { FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_START, sizeof(nonowner_sound_start_packet_t) }, + { FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_STOP, sizeof(nonowner_sound_stop_packet_t) }, + { FMNA_SERVICE_NON_OWNER_OPCODE_START_AGGRESSIVE_ADV, sizeof(generic_control_point_packet_t) }, +}; + +bool m_aggressive_ut_adv_enabled = false; + +static FMNA_Response_Status_t rx_error_check(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + uint8_t const *data, uint16_t length) +{ + if (fmna_state_machine_is_nearby() || + fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + FMNA_LOG_ERROR("non-owner command cannot be issued"); + return RESPONSE_STATUS_INVALID_COMMAND; + } + + return fmna_gatt_verify_control_point_opcode_and_length(opcode, length, rx_length_check_managers, + FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(rx_length_check_managers)); +} + +void fmna_nonowner_rx_handler(uint16_t conn_handle, uint8_t const *data, uint16_t length) +{ + FMNA_Service_Opcode_t opcode = *(FMNA_Service_Opcode_t *)data; + + FMNA_Response_Status_t response_status = rx_error_check(conn_handle, opcode, data, length); + if (response_status != RESPONSE_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("Rx error 0x%x for opcode 0x%x, conn_handle 0x%x", response_status, opcode, + conn_handle); + if (response_status == RESPONSE_STATUS_INVALID_COMMAND) + { + opcode = FMNA_SERVICE_OPCODE_NONE; + } + fmna_gatt_send_command_response(FMNA_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + return; + } + + response_status = RESPONSE_STATUS_NO_COMMAND_RESPONSE; + + FMNA_LOG_INFO("Non-owner rx: opcode = 0x%x, conn_handle 0x%x", opcode, conn_handle); + + switch (opcode) + { + case FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_START: + FMNA_LOG_INFO("RX Non-owner Sound Start"); + if (fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_PLAYING_SOUND)) + { + FMNA_LOG_ERROR("Sound session already in progress"); + response_status = RESPONSE_STATUS_INVALID_STATE; + } + else + { + fmna_connection_update_connection_info(conn_handle, FMNA_MULTI_STATUS_PLAYING_SOUND, true); + response_status = RESPONSE_STATUS_SUCCESS; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_START); + } + break; + + case FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_STOP: + FMNA_LOG_INFO("RX Non-owner Sound Stop"); + if (!fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_PLAYING_SOUND)) + { + FMNA_LOG_INFO("No sound session in progress"); + response_status = RESPONSE_STATUS_INVALID_STATE; + } + else + { + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_STOP); + } + break; + + case FMNA_SERVICE_NON_OWNER_OPCODE_START_AGGRESSIVE_ADV: + FMNA_LOG_INFO("RX UT aggressive adv"); + + // Set flag to Start advertising Separated mode aggressively on disconnect. + m_aggressive_ut_adv_enabled = true; + + response_status = RESPONSE_STATUS_SUCCESS; + break; + + default: + // We should never get here! rx_error_check should check for unknown command and respond with failed command response. + FMNA_LOG_ERROR("Invalid opcode for non-owner control point received"); + } + + if (RESPONSE_STATUS_NO_COMMAND_RESPONSE != response_status) + { + // Send command response for this command. + fmna_gatt_send_command_response(FMNA_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, opcode, + response_status); + } + +} diff --git a/src/app/findmy/fmna_adk/fmna_nonowner_control_point.h b/src/app/findmy/fmna_adk/fmna_nonowner_control_point.h new file mode 100644 index 0000000..8899b4f --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_nonowner_control_point.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_nonowner_control_point_h +#define fmna_nonowner_control_point_h + +#include "fmna_gatt.h" + +extern bool m_aggressive_ut_adv_enabled; + +/// Function for handling the different Non-owner opcodes. +/// @param data Buffer of data of non-owner opcode and possible operands +void fmna_nonowner_rx_handler(uint16_t conn_handle, uint8_t const *data, uint16_t length); + +#endif /* fmna_nonowner_control_point_h */ diff --git a/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.c b/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.c new file mode 100644 index 0000000..eb01bf5 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" +#include "fmna_paired_owner_control_point.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_crypto.h" +#include "fmna_connection.h" + +//MARK: RX Packet Definitions + +typedef struct +{ + FMNA_Service_Opcode_t get_current_primary_key_opcode; +} __attribute__((packed)) paired_owner_get_current_primary_key_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t get_icloud_identifier_opcode; +} __attribute__((packed)) paired_owner_get_icloud_identifier_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t get_serial_number_opcode; +} __attribute__((packed)) paired_owner_get_serial_number_packet_t; + +/// RX Length Check managers for default and variable length cases. +static fmna_service_length_check_manager_t rx_length_check_managers[] = \ +{ + /* RX Opcode Data Length */ + { FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY, sizeof(paired_owner_get_current_primary_key_packet_t) }, + { FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER, sizeof(paired_owner_get_icloud_identifier_packet_t) }, + { FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER, sizeof(paired_owner_get_serial_number_packet_t) }, +}; + +static FMNA_Response_Status_t rx_error_check(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + uint8_t const *data, uint16_t length) +{ + return fmna_gatt_verify_control_point_opcode_and_length(opcode, length, rx_length_check_managers, + FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(rx_length_check_managers)); +} + +void fmna_paired_owner_rx_handler(uint16_t conn_handle, uint8_t const *data, uint16_t length) +{ + FMNA_Service_Opcode_t opcode = *(FMNA_Service_Opcode_t *)data; + + FMNA_Response_Status_t response_status = rx_error_check(conn_handle, opcode, data, length); + if (response_status != RESPONSE_STATUS_SUCCESS) + { + FMNA_LOG_ERROR("Rx error 0x%x for opcode 0x%x, conn_handle 0x%x", response_status, opcode, + conn_handle); + if (response_status == RESPONSE_STATUS_INVALID_COMMAND) + { + opcode = FMNA_SERVICE_OPCODE_NONE; + } + fmna_gatt_send_command_response(FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE, conn_handle, + opcode, response_status); + return; + } + + FMNA_LOG_INFO("Paired owner rx: opcode = 0x%x", opcode); + switch (opcode) + { + case FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY: + FMNA_LOG_INFO("Paired Owner get current primary key command received"); + if (fmna_connection_is_fmna_paired()) + { + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY_RESPONSE, + m_fmna_current_primary_key.public_key, FMNA_PUBKEY_BLEN); + } + else + { + uint8_t Primary_key_pairing_invalid[FMNA_PUBKEY_BLEN] = {0}; + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_CURRENT_PRIMARY_KEY_RESPONSE, + (void *)Primary_key_pairing_invalid, FMNA_PUBKEY_BLEN); + } + break; + + case FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER: + FMNA_LOG_INFO("Paired Owner get iCloud identifier command received"); + if (fmna_connection_is_fmna_paired()) + { + uint8_t icloud_id[ICLOUD_IDENTIFIER_BLEN] = {0}; + uint32_t ret = ftl_load(icloud_id, FTL_SAVE_ICLOUD_ID_ADDR, FTL_SAVE_ICLOUD_ID_SIZE); + FMNA_ERROR_CHECK(ret); + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER_RESPONSE, + icloud_id, ICLOUD_IDENTIFIER_BLEN); + } + else + { + uint8_t Icloud_id_pairing_invalid[ICLOUD_IDENTIFIER_BLEN] = {0}; + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_ICLOUD_IDENTIFIER_RESPONSE, (void *)Icloud_id_pairing_invalid, + ICLOUD_IDENTIFIER_BLEN); + } + break; + + case FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER: + FMNA_LOG_INFO("Paired Owner get serial number command received"); + + if (!fmna_connection_is_fmna_paired()) + { + fmna_gatt_send_command_response(FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE, + conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER, + RESPONSE_STATUS_INVALID_STATE); + } + else + { + // Valid state to read serial number. + if (serial_number_read_state == true) + { + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER_RESPONSE, + p_fmna_encrypted_serial_number_payload, + ENCRYPTED_SERIAL_NUMBER_PAYLOAD_BLEN); + } + else + { + fmna_gatt_send_command_response(FMNA_SERVICE_PAIRED_OWNER_OPCODE_COMMAND_RESPONSE, + conn_handle, + FMNA_SERVICE_PAIRED_OWNER_OPCODE_GET_SERIAL_NUMBER, + RESPONSE_STATUS_INVALID_COMMAND); + } + } + + break; + + default: + FMNA_LOG_INFO("Invalid opcode for paired owner control point received"); + } + +} diff --git a/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.h b/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.h new file mode 100644 index 0000000..64c730f --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_paired_owner_control_point.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_paired_owner_control_point_h +#define fmna_paired_owner_control_point_h + +#include "fmna_gatt.h" + +/// Function for handling the different Paired Owner opcodes. +/// @param data Buffer of data of Paired Owner opcode and possible operands +void fmna_paired_owner_rx_handler(uint16_t conn_handle, uint8_t const *data, uint16_t length); + +#endif /* fmna_paired_owner_control_point_h */ + + diff --git a/src/app/findmy/fmna_adk/fmna_pairing_control_point.c b/src/app/findmy/fmna_adk/fmna_pairing_control_point.c new file mode 100644 index 0000000..caab72a --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_pairing_control_point.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_constants.h" +#include "fmna_platform_includes.h" +#include "fmna_pairing_control_point.h" + +#include "fmna_crypto.h" +#include "fmna_gatt.h" +#include "fmna_connection.h" +#include "fmna_state_machine.h" +#if HARDCODED_PAIRING_ENABLED +#include "fmna_adv.h" +#endif + +//MARK: RX Packet Definitions + +typedef struct +{ + FMNA_Service_Opcode_t initiate_pairing_opcode; + fmna_initiate_pairing_data_t initiate_pairing_data; +} __attribute__((packed)) initiate_pairing_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t finalize_pairing_opcode; + fmna_finalize_pairing_data_t finalize_pairing_data; +} __attribute__((packed)) finalize_pairing_packet_t; + +typedef struct +{ + FMNA_Service_Opcode_t pairing_complete_opcode; +} __attribute__((packed)) pairing_complete_packet_t; + +// General buffer to hold the incoming Pairing characteristic Write data +typedef struct +{ + uint16_t len; + uint8_t data[PAIRING_MAX_LEN]; +} pairing_rx_buffer_t; + +static pairing_rx_buffer_t pairing_rx_buffer = {}; + +/// RX Length Check managers for default and variable length cases. +static fmna_service_length_check_manager_t rx_length_check_managers[] = \ +{ + /* RX Opcode Data Length */ + { FMNA_SERVICE_OPCODE_INITIATE_PAIRING, sizeof(initiate_pairing_packet_t) }, + { FMNA_SERVICE_OPCODE_FINALIZE_PAIRING, sizeof(finalize_pairing_packet_t) }, + { FMNA_SERVICE_OPCODE_PAIRING_COMPLETE, sizeof(pairing_complete_packet_t) }, +}; + +static FMNA_Response_Status_t rx_error_check(FMNA_Service_Opcode_t opcode, uint8_t *data, + uint16_t length) +{ + FMNA_Response_Status_t response_status = fmna_gatt_verify_control_point_opcode_and_length(opcode, + length, rx_length_check_managers, + FMNA_SERVICE_LENGTH_CHECK_MANAGERS_SIZE(rx_length_check_managers)); + + if ((opcode == FMNA_SERVICE_OPCODE_FINALIZE_PAIRING) + && (response_status == RESPONSE_STATUS_INVALID_LENGTH)) + { + // Bypass finalize pairing length check for now. + //TODO: Add min max check for finalize pairing. + response_status = RESPONSE_STATUS_SUCCESS; + } + + return response_status; +} + +void fmna_pairing_control_point_unpair(void) +{ + //add other cleanup + memset(&pairing_rx_buffer, 0, sizeof(pairing_rx_buffer)); + return; +} + +fmna_ret_code_t fmna_pairing_control_point_append_to_rx_buffer(uint8_t const *data, + uint16_t length) +{ + if ((pairing_rx_buffer.len + length) > PAIRING_MAX_LEN) + { + APP_PRINT_ERROR0("Buffer too long"); + fmna_connection_fmna_unpair(true); + } + + memcpy(&(pairing_rx_buffer.data[pairing_rx_buffer.len]), data, length); + + pairing_rx_buffer.len += length; + + return FMNA_SUCCESS; +} + +void fmna_pairing_control_point_handle_rx(void) +{ + FMNA_Service_Opcode_t opcode = *(FMNA_Service_Opcode_t *)pairing_rx_buffer.data; + + FMNA_Response_Status_t response_status = rx_error_check(opcode, (uint8_t *)&pairing_rx_buffer, + pairing_rx_buffer.len); + if (response_status != RESPONSE_STATUS_SUCCESS) + { + APP_PRINT_ERROR2("Rx error %d for opcode 0x%x", response_status, opcode); + fmna_connection_fmna_unpair(true); + return; + } + + APP_PRINT_INFO1("Rx: Opcode = 0x%x", opcode); + switch (opcode) + { + case FMNA_SERVICE_OPCODE_INITIATE_PAIRING: +// memcpy(&m_fmna_initiate_pairing_data, pairing_rx_buffer.data + sizeof(FMNA_Service_Opcode_t), sizeof(m_fmna_initiate_pairing_data)); + p_fmna_initiate_pairing_data = fmna_malloc(INITIATE_PAIRING_DATA, + sizeof(fmna_initiate_pairing_data_t)); + memcpy(p_fmna_initiate_pairing_data, + &(((initiate_pairing_packet_t *)pairing_rx_buffer.data)->initiate_pairing_data), + sizeof(fmna_initiate_pairing_data_t)); +// os_mem_free(p_rx_buff); + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_FMNA_PAIRING_INITIATE); + break; + + case FMNA_SERVICE_OPCODE_FINALIZE_PAIRING: + fmna_free(SEND_PAIRING_DATA); + p_fmna_finalize_pairing_data = fmna_malloc(FINALIZE_PAIRING_DATA, + sizeof(fmna_finalize_pairing_data_t)); + memcpy(p_fmna_finalize_pairing_data, + &(((finalize_pairing_packet_t *)pairing_rx_buffer.data)->finalize_pairing_data), + sizeof(fmna_finalize_pairing_data_t)); +// fmna_free(pairing_rx_buffer.data); +#if HARDCODED_PAIRING_ENABLED + organize_pub_keys(((finalize_pairing_packet_t *)&pairing_rx_buffer)->finalize_pairing_data.e3); +#endif + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_FMNA_PAIRING_FINALIZE); + break; + + case FMNA_SERVICE_OPCODE_PAIRING_COMPLETE: + fmna_free(SEND_PAIRING_STATUS); + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_FMNA_PAIRING_COMPLETE); + break; + + default: + break; + } + + memset(&pairing_rx_buffer, 0, sizeof(pairing_rx_buffer)); +} diff --git a/src/app/findmy/fmna_adk/fmna_pairing_control_point.h b/src/app/findmy/fmna_adk/fmna_pairing_control_point.h new file mode 100644 index 0000000..96ad698 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_pairing_control_point.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_pairing_control_point_h +#define fmna_pairing_control_point_h + +void fmna_pairing_control_point_unpair(void); +fmna_ret_code_t fmna_pairing_control_point_append_to_rx_buffer(uint8_t const *data, + uint16_t length); +void fmna_pairing_control_point_handle_rx(void); + +#endif /* fmna_pairing_control_point_h */ diff --git a/src/app/findmy/fmna_adk/fmna_state_machine.c b/src/app/findmy/fmna_adk/fmna_state_machine.c new file mode 100644 index 0000000..e7d21f5 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_state_machine.c @@ -0,0 +1,1680 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" + +#include "fmna_util.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_adv.h" +#include "fmna_connection.h" +#include "fmna_crypto.h" +#include "fmna_peer_manager.h" +#include "fmna_motion_detection.h" +#include "fmna_nonowner_control_point.h" +#if SUPPORT_NFC +#include "fmna_nfc.h" +#endif + +typedef uint32_t (*fmna_evt_fptr_t)(FMNA_SM_Event_t fmna_evt, void *p_context); + +typedef struct +{ + FMNA_SM_Event_t fmna_evt; // FIND MY Event + FMNA_SM_State_t fmna_state_success; // New state (Success) + FMNA_SM_State_t fmna_state_fail; // New state (Failure) + fmna_evt_fptr_t handler; // Event Handler +} fmna_evt_handler_t; + +typedef struct +{ + fmna_evt_handler_t const *p_array_handlers; + uint8_t count; +} fmna_array_evt_handler_t; + +typedef enum +{ + IS_NEARBY_UNINIT, + IS_NEARBY_FALSE, + IS_NEARBY_TRUE, +} is_nearby_t; + +fmna_primary_key_t m_fmna_temp_primary_key = {0}; +fmna_primary_key_t m_fmna_current_primary_key = {0}; // primary key +fmna_primary_key_t m_fmna_current_separated_primary_key = {0}; // latched separated key +fmna_secondary_key_t m_fmna_current_secondary_key = {0}; //secondary key + +uint32_t m_current_separated_primary_key_index; + +// Log decode strings +const char *fmna_sm_state_strings[] = +{ + "FMNA_SM_BOOT", + "FMNA_SM_PAIR", + "FMNA_SM_SEPARATED", + "FMNA_SM_NEARBY", + "FMNA_SM_CONNECTING", + "FMNA_SM_FMNA_PAIR", + "FMNA_SM_FMNA_PAIR_COMPLETE", + "FMNA_SM_CONNECTED", + "FMNA_SM_DISCONNECTING", + "FMNA_SM_NOCHANGE", +}; + +// Log decode strings +const char *fmna_sm_event_strings[] = +{ + "FMNA_SM_EVENT_BOOT", + "FMNA_SM_EVENT_NEARBY_SEPARATED_TIMEOUT", + "FMNA_SM_EVENT_KEY_ROTATE", + "FMNA_SM_EVENT_BONDED", + "FMNA_SM_EVENT_UNBONDED", + "FMNA_SM_EVENT_CONNECTED", + "FMNA_SM_EVENT_DISCONNECTED", + "FMNA_SM_EVENT_NEARBY", + "FMNA_SM_EVENT_SEPARATED", + "FMNA_SM_EVENT_PAIR", + "FMNA_SM_EVENT_SOUND_START", + "FMNA_SM_EVENT_SOUND_STOP", + "FMNA_SM_EVENT_SOUND_COMPLETE", + "FMNA_SM_EVENT_LOST_UT_SPEAKER_START", + "FMNA_SM_EVENT_FMNA_PAIRING_INITIATE", + "FMNA_SM_EVENT_FMNA_PAIRING_FINALIZE", + "FMNA_SM_EVENT_FMNA_PAIRING_COMPLETE", + "FMNA_SM_EVENT_FMNA_PAIRING_MFITOKEN", + "FMNA_SM_EVENT_MOTION_DETECTED", +#ifdef DEBUG + "FMNA_SM_EVENT_DEBUG_RESET_INTO_SEPARATED", +#endif // DEBUG +}; + +#define FMNA_EVT_LIST_LENGTH(fmna_evt_handler) (sizeof(fmna_evt_handler)/sizeof(fmna_evt_handler[0])) + +// MARK: Static Functions +// Naming follows: fmna__evt__handler +static uint32_t fmna_boot_evt_boot_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_pair_evt_bonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_pair_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_pair_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_pair_evt_pair_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_separated_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_separated_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_separated_evt_unbonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_separated_evt_motion_detected_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +static uint32_t fmna_separated_evt_sound_start_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_separated_evt_sound_complete_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +static uint32_t fmna_nearby_evt_timeout_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_nearby_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_nearby_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +static uint32_t fmna_connected_evt_unbonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_connected_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_connected_evt_timeout_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_connected_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_connected_evt_sound_stop_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_fmna_pair_evt_fmna_pairing_finalize_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +#if !HARDCODED_PAIRING_ENABLED +static uint32_t fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +#endif // HARDCODED_PAIRING_ENABLED +static uint32_t fmna_fmna_pair_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler(FMNA_SM_Event_t fmna_evt, + void *p_context); +static uint32_t fmna_disconnecting_evt_nearby_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_disconnecting_evt_separated_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_disconnecting_evt_pair_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_generic_evt_bonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_generic_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_generic_evt_sound_start_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +static uint32_t fmna_generic_evt_sound_complete_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +#ifdef DEBUG +static uint32_t fmna_connected_evt_debug_reset_handler(FMNA_SM_Event_t fmna_evt, void *p_context); +#endif // DEBUG + +static void fmna_nearby_separated_timeout_handler(void *p_context); +static void fmna_key_rotation_handler(void *p_context); +static void fmna_one_time_key_rotation_handler(void *p_context); +static void fmna_non_owner_0_connection_timeout_handler(void *p_context); +static void fmna_non_owner_1_connection_timeout_handler(void *p_context); +static void fmna_pair_connection_timeout_handler(void *p_context); +static void fmna_persistent_connection_disconnection_timeout_handler(void *p_context); +static void separated_ut_timeout_handler(void *p_context); +static void fmna_update_secondary_index(uint32_t current_index); + +static void stop_pair_connection_timer(void); + +// MARK: - Static Variables + +volatile FMNA_SM_State_t m_fmna_state; + +// Persistent connection flag to determine disconnection advertising behavior. +static bool is_persistent_connection_disconnection = false; +static bool m_motion_detected_sound = false; +static is_nearby_t m_is_nearby = IS_NEARBY_UNINIT; +// Flag tracking maintenanced status of accessory. +static bool has_been_maintenanced = false; +// Nearby handler +static bool nearby_separated_timeout_timer_is_on_work = false; +static uint16_t nearby_disconnecting_conn_handle = 0xFFFF; + +static uint32_t m_fmna_nearby_separated_timeout = MIN_TO_MSEC(15); +APP_TIMER_DEF( + m_fmna_nearby_separated_timeout_timer_id); /**< Nearby to Separated state timeout timer id. */ + +uint32_t m_fmna_key_rotation_timeout_ms = MIN_TO_MSEC(15); +APP_TIMER_DEF(m_fmna_key_rotation_timer_id); /**< Rotation timer id. */ +APP_TIMER_DEF(m_fmna_one_time_key_rotation_timer_id); /**< One time rotation timer id. */ + +static const uint32_t m_fmna_non_owner_connection_timeout = SEC_TO_MSEC(10); // 10 second +APP_TIMER_DEF( + m_fmna_non_owner_0_connection_timeout_timer_id); /**< Non-owner 0 connection timeout timer id. */ +APP_TIMER_DEF( + m_fmna_non_owner_1_connection_timeout_timer_id); /**< Non-owner 1 connection timeout timer id. */ + +static const uint32_t m_fmna_pair_connection_timeout = SEC_TO_MSEC(10); +APP_TIMER_DEF( + m_fmna_pair_connection_timeout_timer_id); /**< pair connection timeout timer id. */ + +static uint32_t m_separated_ut_timeout_ms = DAYS_TO_MSEC( + 3); // Default smoke alarm timeout @ 3 days. +APP_TIMER_DEF( + m_separated_ut_timeout_timer_id); /**< Wild smoke alarm timeout timer id. */ + +APP_TIMER_DEF(m_fmna_persistent_connection_disconnection_timer_id); /**< Rotation timer id. */ + +fmna_secondary_keys_info_t m_fmna_secondary_keys_info = {0}; + +// MARK: - Event Handler List +static const fmna_evt_handler_t fmna_sm_boot_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_BOOT, FMNA_SM_SEPARATED, FMNA_SM_PAIR, fmna_boot_evt_boot_handler }, +}; + + +static const fmna_evt_handler_t fmna_sm_pair_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_BONDED, FMNA_SM_CONNECTING, FMNA_SM_CONNECTED, fmna_pair_evt_bonded_handler }, + { FMNA_SM_EVENT_CONNECTED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_pair_evt_connected_handler }, + { FMNA_SM_EVENT_DISCONNECTED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_pair_evt_disconnected_handler }, + { FMNA_SM_EVENT_PAIR, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_pair_evt_pair_handler }, + { FMNA_SM_EVENT_FMNA_PAIRING_INITIATE, FMNA_SM_FMNA_PAIR, FMNA_SM_NOCHANGE, fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler }, +}; + +static const fmna_evt_handler_t fmna_sm_separated_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_KEY_ROTATE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_separated_evt_key_rotate_handler }, + { FMNA_SM_EVENT_CONNECTED, FMNA_SM_CONNECTED, FMNA_SM_NOCHANGE, fmna_separated_evt_connected_handler }, + { FMNA_SM_EVENT_UNBONDED, FMNA_SM_PAIR, FMNA_SM_PAIR, fmna_separated_evt_unbonded_handler }, + { FMNA_SM_EVENT_SOUND_COMPLETE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_separated_evt_sound_complete_handler }, + { FMNA_SM_EVENT_MOTION_DETECTED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_separated_evt_motion_detected_handler }, + { FMNA_SM_EVENT_SOUND_START, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_separated_evt_sound_start_handler }, +}; + +static const fmna_evt_handler_t fmna_sm_nearby_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_NEARBY_SEPARATED_TIMEOUT, FMNA_SM_SEPARATED, FMNA_SM_SEPARATED, fmna_nearby_evt_timeout_handler }, + { FMNA_SM_EVENT_KEY_ROTATE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_nearby_evt_key_rotate_handler }, + { FMNA_SM_EVENT_CONNECTED, FMNA_SM_CONNECTED, FMNA_SM_NOCHANGE, fmna_nearby_evt_connected_handler }, + { FMNA_SM_EVENT_SOUND_COMPLETE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_generic_evt_sound_complete_handler }, +}; + +static const fmna_evt_handler_t fmna_sm_connecting_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_DISCONNECTED, FMNA_SM_DISCONNECTING, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_disconnected_handler }, + { FMNA_SM_EVENT_FMNA_PAIRING_INITIATE, FMNA_SM_FMNA_PAIR, FMNA_SM_NOCHANGE, fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler }, +}; + +static const fmna_evt_handler_t fmna_sm_fmna_pair_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + +#if HARDCODED_PAIRING_ENABLED + { FMNA_SM_EVENT_FMNA_PAIRING_FINALIZE, FMNA_SM_FMNA_PAIR_COMPLETE, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_fmna_pairing_finalize_handler }, +#else + { FMNA_SM_EVENT_FMNA_PAIRING_FINALIZE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_fmna_pairing_finalize_handler }, + { FMNA_SM_EVENT_FMNA_PAIRING_MFITOKEN, FMNA_SM_FMNA_PAIR_COMPLETE, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler }, +#endif //HARDCODED_PAIRING_ENABLED + { FMNA_SM_EVENT_DISCONNECTED, FMNA_SM_DISCONNECTING, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_disconnected_handler}, + +}; + +static const fmna_evt_handler_t fmna_sm_fmna_pair_complete_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_FMNA_PAIRING_COMPLETE, FMNA_SM_CONNECTED, FMNA_SM_NOCHANGE, fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler }, + { FMNA_SM_EVENT_DISCONNECTED, FMNA_SM_DISCONNECTING, FMNA_SM_NOCHANGE, fmna_fmna_pair_evt_disconnected_handler}, + +}; + +static const fmna_evt_handler_t fmna_sm_connected_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_BONDED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_generic_evt_bonded_handler }, + { FMNA_SM_EVENT_UNBONDED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_connected_evt_unbonded_handler }, + { FMNA_SM_EVENT_CONNECTED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_nearby_evt_connected_handler }, + { FMNA_SM_EVENT_DISCONNECTED, FMNA_SM_DISCONNECTING, FMNA_SM_NOCHANGE, fmna_connected_evt_disconnected_handler }, + { FMNA_SM_EVENT_KEY_ROTATE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_connected_evt_key_rotate_handler }, + { FMNA_SM_EVENT_NEARBY_SEPARATED_TIMEOUT, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_connected_evt_timeout_handler }, + { FMNA_SM_EVENT_SOUND_START, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_generic_evt_sound_start_handler }, + { FMNA_SM_EVENT_SOUND_STOP, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_connected_evt_sound_stop_handler }, + { FMNA_SM_EVENT_SOUND_COMPLETE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_generic_evt_sound_complete_handler }, +#ifdef DEBUG + { FMNA_SM_EVENT_DEBUG_RESET_INTO_SEPARATED, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_connected_evt_debug_reset_handler }, +#endif // DEBUG +}; + +static const fmna_evt_handler_t fmna_sm_disconnecting_evt_handlers[] = \ +{ + /* FIND_MY Event AppStateSuccess AppStateFailure Handler */ + + { FMNA_SM_EVENT_NEARBY, FMNA_SM_NEARBY, FMNA_SM_NEARBY, fmna_disconnecting_evt_nearby_handler }, + { FMNA_SM_EVENT_SEPARATED, FMNA_SM_SEPARATED, FMNA_SM_SEPARATED, fmna_disconnecting_evt_separated_handler }, + { FMNA_SM_EVENT_PAIR, FMNA_SM_PAIR, FMNA_SM_PAIR, fmna_disconnecting_evt_pair_handler }, + { FMNA_SM_EVENT_SOUND_COMPLETE, FMNA_SM_NOCHANGE, FMNA_SM_NOCHANGE, fmna_generic_evt_sound_complete_handler }, + +}; + +static const fmna_array_evt_handler_t fmna_sm_handlers[] = \ +{ + {fmna_sm_boot_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_boot_evt_handlers)}, + {fmna_sm_pair_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_pair_evt_handlers)}, + {fmna_sm_separated_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_separated_evt_handlers)}, + {fmna_sm_nearby_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_nearby_evt_handlers)}, + {fmna_sm_connecting_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_connecting_evt_handlers)}, + {fmna_sm_fmna_pair_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_fmna_pair_evt_handlers)}, + {fmna_sm_fmna_pair_complete_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_fmna_pair_complete_evt_handlers)}, + {fmna_sm_connected_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_connected_evt_handlers)}, + {fmna_sm_disconnecting_evt_handlers, FMNA_EVT_LIST_LENGTH(fmna_sm_disconnecting_evt_handlers)}, +}; + +#define FMNA_EVT_LIST_LEN(evt_handlers) (sizeof(evt_handlers)/sizeof(evt_handlers[0])) + +static void set_is_nearby(is_nearby_t new_is_nearby) +{ + fmna_ret_code_t ret_code; + + switch (new_is_nearby) + { + case IS_NEARBY_TRUE: + if (m_is_nearby != IS_NEARBY_TRUE) + { + // Turn off motion detection if we're going into Nearby. + fmna_motion_detection_stop(); + + // If we're transitioning to Nearby, turn the Separated UT motion detection timer off. + ret_code = app_timer_stop(m_separated_ut_timeout_timer_id); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Failed to stop m_separated_ut_timeout_timer_id timer, err 0x%x", ret_code); + } + } + break; + case IS_NEARBY_FALSE: + if (m_is_nearby != IS_NEARBY_FALSE) + { + // If we are transitioning out of Nearby, start the Separated UT motion detection timer. + ret_code = app_timer_start(m_separated_ut_timeout_timer_id, + APP_TIMER_TICKS(m_separated_ut_timeout_ms), + NULL); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("Failed to start m_separated_ut_timeout_timer_id timer, err 0x%x", ret_code); + } + } + break; + + case IS_NEARBY_UNINIT: + // This should never happen. + FMNA_ERROR_CHECK(FMNA_ERROR_INVALID_STATE); + default: + break; + } + + m_is_nearby = new_is_nearby; +} + +bool fmna_state_machine_is_nearby(void) +{ + return (m_is_nearby == IS_NEARBY_TRUE); +} + +void start_pair_adv(void) +{ + fmna_adv_init_pairing(); + fmna_adv_start_fast_adv(); +} + +void fmna_state_machine_set_nearby_timeout_seconds(uint16_t nearby_timeout_seconds) +{ + m_fmna_nearby_separated_timeout = SEC_TO_MSEC(nearby_timeout_seconds); + APP_PRINT_INFO1("m_fmna_nearby_separated_timeout ms: %dms", m_fmna_nearby_separated_timeout); +} + +void fmna_state_machine_set_next_keyroll_ms(uint32_t next_keyroll_ms) +{ + uint32_t next_keyroll_ticks = MSEC_TO_TIMER_TICKS(next_keyroll_ms); + + if (MSEC_TO_TIMER_TICKS(next_keyroll_ms) < APP_TIMER_MIN_TIMEOUT_TICKS) + { + next_keyroll_ticks = APP_TIMER_MIN_TIMEOUT_TICKS; + } + + fmna_state_machine_stop_key_rotation_timers(); + + fmna_ret_code_t ret_code = app_timer_start(m_fmna_one_time_key_rotation_timer_id, + next_keyroll_ticks, NULL); + FMNA_ERROR_CHECK(ret_code); +} + +static uint32_t next_secondary_key_rotation_index; + +void dispatch_set_next_secondary_key_rotation_index_handler(void *p_event_data, + uint16_t event_size) +{ + APP_PRINT_INFO2("next recovery key rotation index = %#x, current index = %#x", + next_secondary_key_rotation_index, m_fmna_current_primary_key.index); + uint32_t current_index = m_fmna_current_primary_key.index; + if (next_secondary_key_rotation_index > current_index) + { + m_fmna_secondary_keys_info.next_secondary_key_rotation_index = next_secondary_key_rotation_index; + ftl_save(&next_secondary_key_rotation_index, FTL_SAVE_NEXT_PW_ROT_INDEX_ADDR, + FTL_SAVE_NEXT_PW_ROT_INDEX_SIZE); + } + else + { + //latch current separated key *and* re-align the next recovery key rotation index + APP_PRINT_INFO1("latch current separated key and re-align the next recovery key rotation index to %#x", + next_secondary_key_rotation_index + PRIMARY_KEYS_PER_SECONDARY_KEY); + memcpy(&m_fmna_current_separated_primary_key, &m_fmna_current_primary_key, + sizeof(fmna_primary_key_t)); + ftl_save(&m_fmna_current_separated_primary_key, FTL_SAVE_SEC_PRI_KEY_ADDR, + FTL_SAVE_SEC_PRI_KEY_SIZE); + m_current_separated_primary_key_index = current_index; + m_fmna_secondary_keys_info.next_secondary_key_rotation_index = next_secondary_key_rotation_index + + PRIMARY_KEYS_PER_SECONDARY_KEY; + } + + fmna_update_secondary_index(current_index); + + fmna_gatt_send_command_response(FMNA_SERVICE_OPCODE_COMMAND_RESPONSE, *(uint16_t *)p_event_data, + FMNA_SERVICE_OPCODE_CONFIGURE_SEPARATED_STATE, RESPONSE_STATUS_SUCCESS); +} + + +void fmna_state_machine_set_next_secondary_key_rotation_index(uint16_t conn_handle, uint32_t index) +{ + //set next secondary rotate at 4 a.m. + next_secondary_key_rotation_index = index; + app_sched_event_put(&conn_handle, sizeof(conn_handle), + dispatch_set_next_secondary_key_rotation_index_handler); +} + +// latch current separated key without re-aligning future separated keys +void fmna_state_machine_latch_current_separated_key(uint16_t conn_handle) +{ + uint32_t current_index = m_fmna_current_primary_key.index; + + APP_PRINT_INFO1("latch current separated key index = %#x", current_index); + m_current_separated_primary_key_index = current_index; + memcpy(&m_fmna_current_separated_primary_key, &m_fmna_current_primary_key, + sizeof(fmna_primary_key_t)); + ftl_save(&m_fmna_current_separated_primary_key, FTL_SAVE_SEC_PRI_KEY_ADDR, + FTL_SAVE_SEC_PRI_KEY_SIZE); + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_OPCODE_LATCH_SEPARATED_KEY_RESPONSE, + &m_current_separated_primary_key_index, + sizeof(m_current_separated_primary_key_index)); +} + +void fmna_update_secondary_index(uint32_t current_index) +{ + uint32_t secondary_index = current_index / PRIMARY_KEYS_PER_SECONDARY_KEY + 1; // j = i/96 +1 + + if (m_fmna_current_secondary_key.index < secondary_index) + { + fmna_ret_code_t ret_code = fmna_crypto_roll_secondary_key(); + FMNA_ERROR_CHECK(ret_code); + + if (m_fmna_current_secondary_key.index != secondary_index) + { + APP_PRINT_ERROR2("cur secondary key index = %#x not equal to target %#x", + m_fmna_current_secondary_key.index, secondary_index); + } + } + else if (m_fmna_current_secondary_key.index > secondary_index) + { + APP_PRINT_ERROR2("cur secondary key index = %#x greater than target %#x", + m_fmna_current_secondary_key.index, secondary_index); + } +} + +static uint32_t cached_next_secondary_key_rotation_index; + +static void dispatch_update_next_secondary_key_rotation_index(void *p_event_data, + uint16_t event_size) +{ + if (cached_next_secondary_key_rotation_index == + m_fmna_secondary_keys_info.next_secondary_key_rotation_index) + { + m_fmna_secondary_keys_info.next_secondary_key_rotation_index += PRIMARY_KEYS_PER_SECONDARY_KEY; + } +} + +void fmna_rotate_key(void) +{ + cached_next_secondary_key_rotation_index = + m_fmna_secondary_keys_info.next_secondary_key_rotation_index; + + fmna_rotate_key_internal(); + + fmna_ret_code_t ret_code = fmna_primary_key_update(); + FMNA_ERROR_CHECK(ret_code); + +#if HARDCODED_PAIRING_ENABLED + current_key_index++; + memcpy((m_fmna_current_primary_key.public_key), &(keys_to_rotate[current_key_index % NUM_OF_KEYS]), + FMNA_PUBKEY_BLEN); +#endif //HARDCODED_PAIRING_ENABLED + + if (m_fmna_current_primary_key.index == cached_next_secondary_key_rotation_index) + { + APP_PRINT_INFO1("rotate secondary key index = %#x", cached_next_secondary_key_rotation_index); + //if in separated state, clear separated primary key, change to secondary key + if (m_fmna_state == FMNA_SM_SEPARATED) + { + m_current_separated_primary_key_index = 0; + memset(&m_fmna_current_separated_primary_key, 0, sizeof(fmna_primary_key_t)); + ftl_save(&m_fmna_current_separated_primary_key, FTL_SAVE_SEC_PRI_KEY_ADDR, + FTL_SAVE_SEC_PRI_KEY_SIZE); + } + + fmna_update_secondary_index(m_fmna_current_primary_key.index); + + app_sched_event_put(NULL, NULL, dispatch_update_next_secondary_key_rotation_index); + } +} + +static void fmna_state_machine_timers_init(void) +{ + fmna_ret_code_t ret_code; + uint16_t error_line = 0; + + ret_code = app_timer_create(&m_fmna_nearby_separated_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_nearby_separated_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_key_rotation_timer_id, + APP_TIMER_MODE_REPEATED, + fmna_key_rotation_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_one_time_key_rotation_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_one_time_key_rotation_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_non_owner_0_connection_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_non_owner_0_connection_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_non_owner_1_connection_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_non_owner_1_connection_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_pair_connection_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_pair_connection_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_separated_ut_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + separated_ut_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_create(&m_fmna_persistent_connection_disconnection_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_persistent_connection_disconnection_timeout_handler); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + return; + +error: + APP_PRINT_ERROR3("FMNA error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret_code); + FMNA_PLATFORM_ABORT(error_line); +} + +static void fmna_state_machine_boot(void) +{ + m_fmna_state = FMNA_SM_BOOT; + fmna_evt_handler(FMNA_SM_EVENT_BOOT, NULL); +} + +void fmna_state_machine_init(void) +{ + fmna_state_machine_timers_init(); + fmna_state_machine_boot(); +} + +static void dispatch_fmna_sm_event_handler(void *p_event_data, uint16_t event_size) +{ + fmna_evt_handler(*(FMNA_SM_Event_t *)(p_event_data), NULL); +} + +void fmna_state_machine_dispatch_event(FMNA_SM_Event_t fmna_evt) +{ + app_sched_event_put(&fmna_evt, sizeof(fmna_evt), dispatch_fmna_sm_event_handler); +} + +/// Boots into to Pairing or Separated based on paired status. +uint32_t fmna_boot_evt_boot_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_ret_code_t ret_code = FMNA_ERROR_INTERNAL; + + fmna_crypto_init(); + fmna_log_serial_number(); +// fmna_log_mfi_token_help(); + + // Check if we are paired or not. If we are NOT paired, force unpair (for sanity cleanup) + // and go into the pairing state, start advertising. + if (fmna_connection_is_fmna_paired() == false) + { + APP_PRINT_INFO0("Device is not FMNA Paired, waiting for going into pairing state."); + + // Unpair just in case, ensure that we are really unpaired before booting into Pairing state. + fmna_pm_delete_bonds(); + +#if SUPPORT_NFC + fmna_nfc_load_unpaired_url(); +#endif + return FMNA_SM_STATUS_NOT_BONDED; + } + + app_global_data.fmna_enable = true; + + // If app is paired, proceed + ret_code = app_timer_start(m_fmna_key_rotation_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_key_rotation_timeout_ms), NULL); + FMNA_ERROR_CHECK(ret_code); + + is_key_rotated = false; + + //TODO: Read/get/generate current primary key & current secondary key. + + // since this is a boot we need to see if the recovery index has moved on + fmna_update_secondary_index(m_fmna_current_primary_key.index); + + fmna_connection_set_active_ltk(m_fmna_current_primary_key.ltk); +#if SUPPORT_NFC + fmna_nfc_load_paired_url(); +#endif + + // Begin separated advertisement + if (memcmp_val(m_fmna_current_separated_primary_key.public_key, 0, FMNA_PUBKEY_BLEN)) + { + fmna_adv_init_separated(m_fmna_current_secondary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + else + { + fmna_adv_init_separated(m_fmna_current_separated_primary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + + fmna_adv_start_slow_adv(); + + set_is_nearby(IS_NEARBY_FALSE); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_pair_evt_pair_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + APP_PRINT_INFO0("start pairing adv for 10min"); + + fmna_adv_reset_bd_addr(); + start_pair_adv(); + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_pair_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + stop_pair_connection_timer(); + + start_pair_adv(); + + return FMNA_SM_STATUS_NOT_BONDED; +} + +/// Pairing to Connected event handler. +uint32_t fmna_pair_evt_bonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + return FMNA_SM_STATUS_SUCCESS; +} + +/// Starts pairing connection timer. +uint32_t fmna_pair_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_ret_code_t ret_code = app_timer_start(m_fmna_pair_connection_timeout_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_pair_connection_timeout), + NULL); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("app_timer_start m_fmna_pair_connection_timeout_timer_id err %d", ret_code); + + // Force disconnect if this timer fails to start. + fmna_connection_disconnect_this(); + return FMNA_SM_STATUS_FAIL; + } + + return FMNA_SM_STATUS_SUCCESS; +} + +/// Starts non owner connection timeout. Fires and disconnects if link is not encrypted in time. +uint32_t fmna_separated_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + uint16_t conn_handle; + void *p_non_owner_timer = NULL; + + memcpy(&conn_handle, p_context, sizeof(uint16_t)); + APP_PRINT_INFO1("fmna_separated_evt_connected_handler conn_handle=%d", conn_handle); + if (conn_handle == 0) + { + p_non_owner_timer = m_fmna_non_owner_0_connection_timeout_timer_id; + } + else if (conn_handle == 1) + { + p_non_owner_timer = m_fmna_non_owner_1_connection_timeout_timer_id; + } + fmna_ret_code_t ret_code = app_timer_start(p_non_owner_timer, + MSEC_TO_TIMER_TICKS(m_fmna_non_owner_connection_timeout), + NULL); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("app_timer_start m_fmna_non_owner_connection_timeout_timer_id err %d", ret_code); + + // Force disconnect if this timer fails to start. + fmna_connection_disconnect_this(); + return FMNA_SM_STATUS_FAIL; + } + + return FMNA_SM_STATUS_SUCCESS; +} + +/// Re-initializes Separated advertisement with the next keys. +uint32_t fmna_separated_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // Check what key we should be beaconing in the Separated state with. + if (memcmp_val(m_fmna_current_separated_primary_key.public_key, 0, FMNA_PUBKEY_BLEN)) + { + //no latched separated key, beacon secondary key + fmna_adv_init_separated(m_fmna_current_secondary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + else + { + fmna_adv_init_separated(m_fmna_current_separated_primary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + fmna_adv_start_slow_adv(); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_separated_evt_unbonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + start_pair_adv(); + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_separated_evt_motion_detected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // Motion detected in Separated state; play sound. + + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_START); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_separated_evt_sound_start_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + m_motion_detected_sound = true; + + fmna_sound_platform_start(SOUND_EVENT_FMNA, MSEC_TO_TIMER_TICKS(400), PWM_FREQ); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_separated_evt_sound_complete_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + if (m_motion_detected_sound) + { + // Sound complete from motion detected play sound in Separated state. + m_motion_detected_sound = false; + + // Detected motion, so (re)start active polling. + fmna_motion_detection_start_active_polling(); + + return FMNA_SM_STATUS_SUCCESS; + } + else + { + // Regular play sound, connection initiated. + return fmna_generic_evt_sound_complete_handler(fmna_evt, p_context); + } +} + + +/// Starts non owner connection timer. Fires and disconnects if link is not encrypted in time. +uint32_t fmna_nearby_evt_connected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + uint16_t conn_handle; + void *p_non_owner_timer = NULL; + + memcpy(&conn_handle, p_context, sizeof(uint16_t)); + APP_PRINT_INFO1("fmna_nearby_evt_connected_handler conn_handle=%d", conn_handle); + if (conn_handle == 0) + { + p_non_owner_timer = m_fmna_non_owner_0_connection_timeout_timer_id; + } + else if (conn_handle == 1) + { + p_non_owner_timer = m_fmna_non_owner_1_connection_timeout_timer_id; + } + fmna_ret_code_t ret_code = app_timer_start(p_non_owner_timer, + MSEC_TO_TIMER_TICKS(m_fmna_non_owner_connection_timeout), + NULL); + if (ret_code != FMNA_SUCCESS) + { + FMNA_LOG_ERROR("app_timer_start m_fmna_non_owner_connection_timeout_timer_id err %d", ret_code); + + // Force disconnect if this timer fails to start. + fmna_connection_disconnect_this(); + return FMNA_SM_STATUS_FAIL; + } + + return FMNA_SM_STATUS_SUCCESS; +} + +/// Re-initializes Nearby advertisement with new key. +uint32_t fmna_nearby_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + fmna_adv_start_slow_adv(); + return FMNA_SM_STATUS_SUCCESS; +} + +/// Reinitializes advertismenets and switches to Separated advertising, with relevant keys. +uint32_t fmna_nearby_evt_timeout_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // Begin separated advertisement + if (memcmp_val(m_fmna_current_separated_primary_key.public_key, 0, FMNA_PUBKEY_BLEN)) + { + fmna_adv_init_separated(m_fmna_current_secondary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + else + { + fmna_adv_init_separated(m_fmna_current_separated_primary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + + fmna_adv_start_slow_adv(); + + set_is_nearby(IS_NEARBY_FALSE); + + return FMNA_SM_STATUS_SUCCESS; +} + +/// Notify iOS of keyroll, and re-initialize Nearby ADV with new key, if applicable. +uint32_t fmna_connected_evt_key_rotate_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ +#if HARDCODED_PAIRING_ENABLED + // Broadcast this message to all valid centrals. + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (CONN_HANDLE_INVALID != m_fmna_active_connections[conn_handle].conn_handle) + { + // Send indication to the specific central. + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_OPCODE_KEYROLL_INDICATION, + ¤t_key_index, + sizeof(current_key_index)); + } + } +#else + // Broadcast this message to all valid centrals. + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (CONN_HANDLE_INVALID != m_fmna_active_connections[conn_handle].conn_handle) + { + // Send indication to the specific central. + fmna_gatt_send_indication(conn_handle, + FMNA_SERVICE_OPCODE_KEYROLL_INDICATION, + &(m_fmna_current_primary_key.index), + sizeof(m_fmna_current_primary_key.index)); + } + } +#endif + // rotate adv for multiple connections + if (fmna_connection_get_num_connections() + && fmna_connection_get_num_connections() < fmna_connection_get_max_connections()) + { + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + fmna_adv_start_slow_adv(); + } + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_connected_evt_unbonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_connected_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + uint16_t conn_handle; + void *p_non_owner_timer = NULL; + + memcpy(&conn_handle, p_context, sizeof(uint16_t)); + APP_PRINT_INFO1("fmna_connected_evt_disconnected_handler conn_handle=%d", conn_handle); + if (conn_handle == 0) + { + p_non_owner_timer = m_fmna_non_owner_0_connection_timeout_timer_id; + } + else if (conn_handle == 1) + { + p_non_owner_timer = m_fmna_non_owner_1_connection_timeout_timer_id; + } + + fmna_ret_code_t ret_code = app_timer_stop(p_non_owner_timer); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("app_timer_stop fmna_connected_evt_disconnected_handler err %d", ret_code); + } + + // If another Owner is still connected, we want to clean up the disconnecting device + // but still stay in the Connected state. + if (fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_ENCRYPTED)) + { + return FMNA_SM_STATUS_FAIL; + } + + return fmna_generic_evt_disconnected_handler(fmna_evt, p_context); +} + +uint32_t fmna_connected_evt_timeout_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // link might not be encrypted yet and Nearby to Separated timeout fired + // the next time we disconnect, we should disconnect into Separated. + + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; ++conn_handle) + { + if (m_fmna_active_connections[conn_handle].conn_handle != CONN_HANDLE_INVALID) + { + if (fmna_state_machine_is_nearby() | fmna_connection_is_status_bit_enabled(conn_handle, + FMNA_MULTI_STATUS_ENCRYPTED)) + { + set_is_nearby(IS_NEARBY_TRUE); + } + else + { + set_is_nearby(IS_NEARBY_FALSE); + } + } + } + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_generic_evt_sound_start_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_sound_platform_start(SOUND_EVENT_FMNA, MSEC_TO_TIMER_TICKS(SEC_TO_MSEC(10)), PWM_FREQ); + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_generic_evt_sound_complete_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + uint16_t sound_conn_handle = fmna_connection_get_conn_handle_with_multi_status_enabled( + FMNA_MULTI_STATUS_PLAYING_SOUND); + + if (sound_conn_handle == CONN_HANDLE_INVALID) + { + APP_PRINT_WARN0("Sound initiator no longer connected"); + return FMNA_SM_STATUS_SUCCESS; + } + + if (fmna_connection_is_status_bit_enabled(sound_conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + fmna_gatt_send_indication(sound_conn_handle, FMNA_SERVICE_OPCODE_SOUND_COMPLETED, NULL, 0); + } + else + { + fmna_gatt_send_indication(sound_conn_handle, FMNA_SERVICE_NON_OWNER_OPCODE_SOUND_COMPLETED, NULL, + 0); + } + + fmna_connection_update_connection_info_all(FMNA_MULTI_STATUS_PLAYING_SOUND, false); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_connected_evt_sound_stop_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + return FMNA_SM_STATUS_SUCCESS; +} + +#ifdef DEBUG +#include "os_sched.h" +uint32_t fmna_connected_evt_debug_reset_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + APP_PRINT_INFO0("fmna_connected_evt_debug_reset_handler"); + + // Disconnect into Separated mode and start beaconing secondary key. + + set_is_nearby(IS_NEARBY_FALSE); + + // Clear the latched separated key so that we start advertising secondary on disconnect + memset(m_fmna_current_separated_primary_key.public_key, 0, FMNA_PUBKEY_BLEN); + ftl_save(&m_fmna_current_separated_primary_key, FTL_SAVE_SEC_PRI_KEY_ADDR, + FTL_SAVE_SEC_PRI_KEY_SIZE); + + // Disconnect to go into Separated. + os_delay(1000); + fmna_connection_disconnect_all(); + + return FMNA_SM_STATUS_SUCCESS; +} +#endif // DEBUG + +uint32_t fmna_unpaired_connecting_evt_fmna_pairing_initiate_handler(FMNA_SM_Event_t fmna_evt, + void *p_context) +{ + stop_pair_connection_timer(); + + fmna_ret_code_t ret_code = FMNA_SUCCESS; + uint32_t sm_ret = FMNA_SM_STATUS_SUCCESS; + + p_fmna_send_pairing_data = fmna_malloc(SEND_PAIRING_DATA, sizeof(fmna_send_pairing_data_t)); + if (p_fmna_send_pairing_data == NULL) + { + APP_PRINT_ERROR0("p_fmna_send_pairing_data zalloc failed!"); + return FMNA_SM_STATUS_CRYPTO_FAIL; + } + +#if HARDCODED_PAIRING_ENABLED + memset(p_fmna_send_pairing_data, 0xFF, sizeof(fmna_send_pairing_data_t)); +#else + ret_code = fmna_crypto_generate_send_pairing_data_params(); +#endif //HARDCODED_PAIRING_ENABLED + + if (FMNA_SUCCESS != ret_code) + { + // Failure to generate send_pairing_data params, disconnect and end this pairing attempt. + fmna_connection_disconnect_this(); + sm_ret = FMNA_SM_STATUS_CRYPTO_FAIL; + } + else + { + // Successfully generated send_pairing_data params, send response to central, and go into App Pairing state. + fmna_gatt_send_indication(fmna_gatt_get_most_recent_conn_handle(), + FMNA_SERVICE_OPCODE_SEND_PAIRING_DATA, + p_fmna_send_pairing_data, + sizeof(fmna_send_pairing_data_t)); + } + + return sm_ret; +} + +//MARK: Find My Pair State Event Handlers +uint32_t fmna_fmna_pair_evt_fmna_pairing_finalize_handler(FMNA_SM_Event_t fmna_evt, + void *p_context) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + uint32_t sm_ret = FMNA_SM_STATUS_SUCCESS; + + p_fmna_send_pairing_status = fmna_malloc(SEND_PAIRING_STATUS, sizeof(fmna_send_pairing_status_t)); + if (p_fmna_send_pairing_status == NULL) + { + APP_PRINT_ERROR0("p_fmna_send_pairing_status zalloc failed!"); + return FMNA_SM_STATUS_CRYPTO_FAIL; + } + +#if HARDCODED_PAIRING_ENABLED + memset(p_fmna_send_pairing_status, 0xFF, sizeof(fmna_send_pairing_status_t)); +#else + ret_code = fmna_crypto_finalize_pairing(); +#endif + + if (FMNA_SUCCESS != ret_code) + { + // Failure to finalize pairing, disconnect and end this pairing attempt. + fmna_connection_disconnect_this(); + sm_ret = FMNA_SM_STATUS_CRYPTO_FAIL; + } +#if HARDCODED_PAIRING_ENABLED + else + { + // Successfully finalized pairing, send response to central, and go into Connected state. + fmna_gatt_send_indication(fmna_gatt_get_most_recent_conn_handle(), + FMNA_SERVICE_OPCODE_SEND_PAIRING_STATUS, + p_fmna_send_pairing_status, + sizeof(fmna_send_pairing_status_t)); + } + return sm_ret; +} +#else //HARDCODED_PAIRING_ENABLED + + fmna_free(FINALIZE_PAIRING_DATA); + + // For POR pairing wait to confirm the MFI token is in flash before sending the indication. + return sm_ret; +} + +uint32_t fmna_fmna_pair_evt_fmna_pairing_mfitoken_handler(FMNA_SM_Event_t fmna_evt, + void *p_context) +{ + uint32_t sm_ret = FMNA_SM_STATUS_SUCCESS; + bool token_stored = fmna_connection_mfi_token_stored(); + + if (token_stored == false) + { + // Failure to finalize pairing - store the MFi token, disconnect and end this pairing attempt. + fmna_connection_disconnect_this(); + sm_ret = FMNA_SM_STATUS_CRYPTO_FAIL; + } + else + { + // Successfully finalized pairing, send response to central, and go into Connected state. + fmna_gatt_send_indication(fmna_gatt_get_most_recent_conn_handle(), + FMNA_SERVICE_OPCODE_SEND_PAIRING_STATUS, + p_fmna_send_pairing_status, + sizeof(fmna_send_pairing_status_t)); + } + + return sm_ret; +} +#endif // HARDCODED_PAIRING_ENABLED + +/// Handler for Owner connecting and encrypting the link successfully. +/// @details Disable Nearby->Separated timer, and non-owner connection timer. +/// In multi-scenario, if there is still an unencrypted connection, restart the +/// non-owner connection timeout for that connection. +uint32_t fmna_generic_evt_bonded_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_ret_code_t ret_code; + + uint8_t periph_link_cnt = fmna_connection_get_num_connections(); + set_is_nearby(IS_NEARBY_TRUE); + + // Set the maintenanced flag to be true since we just connected to an owner. + has_been_maintenanced = true; + + // only stop the Nearby -> Separated timeout timer if the owner connects from Nearby and encrypts the link + ret_code = app_timer_stop(m_fmna_nearby_separated_timeout_timer_id); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("app_timer_stop m_fmna_nearby_separated_timeout_timer_id err %d", ret_code); + } + nearby_separated_timeout_timer_is_on_work = false; + + // turn off the non-owner timeout disconnect timer + uint16_t conn_handle; + void *p_non_owner_timer = NULL; + + memcpy(&conn_handle, p_context, sizeof(uint16_t)); + APP_PRINT_INFO1("fmna_generic_evt_bonded_handler conn_handle=%d", conn_handle); + if (conn_handle == 0) + { + p_non_owner_timer = m_fmna_non_owner_0_connection_timeout_timer_id; + } + else if (conn_handle == 1) + { + p_non_owner_timer = m_fmna_non_owner_1_connection_timeout_timer_id; + } + + ret_code = app_timer_stop(p_non_owner_timer); + if (FMNA_SUCCESS != ret_code) + { + FMNA_LOG_ERROR("app_timer_stop m_fmna_non_owner_connection_timeout_timer_id err %d", ret_code); + } + + if (periph_link_cnt < fmna_connection_get_max_connections()) + { + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + if (is_persistent_connection_disconnection) + { + fmna_adv_start_fast_adv(); + } + else + { + fmna_adv_start_slow_adv(); + } + } + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_fmna_pair_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // Pairing variables/buffer cleanup + fmna_all_pairing_buf_free(); + + return fmna_generic_evt_disconnected_handler(fmna_evt, p_context); +} + +uint32_t fmna_fmna_pair_complete_evt_fmna_pairing_complete_handler(FMNA_SM_Event_t fmna_evt, + void *p_context) +{ + uint16_t error_line = 0; + + fmna_connection_set_is_fmna_paired(true); + +#if SUPPORT_CUSTOMIZED_APP + cust_adv_update_device_name(true); +#endif + + fmna_crypto_pairing_complete(); + + set_is_nearby(IS_NEARBY_TRUE); + + // SK_Primary_N -> SK_Primary_0 + fmna_ret_code_t ret_code = fmna_crypto_roll_primary_sk(); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + // SK_Secondary_N -> SK_Secondary_0 + ret_code = fmna_crypto_roll_secondary_sk(); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + // Roll to P_Primary_1 + ret_code = fmna_crypto_roll_primary_key(); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + // update primary key + ret_code = fmna_primary_key_update(); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + // Roll to P_Secondary_1 + ret_code = fmna_crypto_roll_secondary_key(); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + + ret_code = app_timer_start(m_fmna_key_rotation_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_key_rotation_timeout_ms), NULL); + FMNA_ERROR_CHECK_GOTO(ret_code, error); + +#if SUPPORT_NFC + fmna_nfc_load_paired_url(); +#endif + return FMNA_SM_STATUS_SUCCESS; + +error: + APP_PRINT_ERROR3("FMNA error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret_code); + FMNA_PLATFORM_ABORT(error_line); + return FMNA_SM_STATUS_CRYPTO_FAIL; +} + +//MARK: Disconnecting State Event Handlers +uint32_t fmna_disconnecting_evt_nearby_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + fmna_ret_code_t ret_code; + + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + + if (is_persistent_connection_disconnection) + { + fmna_adv_start_fast_adv(); + } + else + { + fmna_adv_start_slow_adv(); + } + + fmna_gatt_reset_queues(); + + if (nearby_separated_timeout_timer_is_on_work) + { + // when non-owner device is disconnecting, no need to restart nearby separated timeout timer + uint16_t conn_handle = nearby_disconnecting_conn_handle; + if (!fmna_connection_is_status_bit_enabled(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED)) + { + APP_PRINT_INFO1("non-owner_device conn_handle=%d disconnecting to nearby state", conn_handle); + return FMNA_SM_STATUS_SUCCESS; + } + } + + ret_code = app_timer_start(m_fmna_nearby_separated_timeout_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_nearby_separated_timeout), NULL); + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR1("app_timer_start m_fmna_nearby_separated_timeout_timer_id err %d", ret_code); + } + nearby_separated_timeout_timer_is_on_work = true; + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_disconnecting_evt_separated_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + // begin Separated advertisement + if (memcmp_val(m_fmna_current_separated_primary_key.public_key, 0, FMNA_PUBKEY_BLEN)) + { + fmna_adv_init_separated(m_fmna_current_secondary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + else + { + fmna_adv_init_separated(m_fmna_current_separated_primary_key.public_key, + m_fmna_current_primary_key.public_key[FMNA_SEPARATED_ADV_PUBKEY_HINT_INDEX]); + } + + if (m_aggressive_ut_adv_enabled) + { + m_aggressive_ut_adv_enabled = false; + fmna_adv_start_fast_adv(); + } + else + { + fmna_adv_start_slow_adv(); + } + + fmna_gatt_reset_queues(); + + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_disconnecting_evt_pair_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + start_pair_adv(); + return FMNA_SM_STATUS_SUCCESS; +} + +uint32_t fmna_generic_evt_disconnected_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + bool is_paired = fmna_connection_is_fmna_paired(); + + // check to see if this disconnection is to complete an unpair + if (fmna_connection_get_unpair_pending() == true) + { + fmna_connection_set_unpair_pending(false); + // set is paired flag to false so that we unpair on this disconnect + is_paired = false; + } + + // connected to owner + if (is_paired && fmna_state_machine_is_nearby()) + { + uint16_t conn_handle; + memcpy(&conn_handle, p_context, sizeof(uint16_t)); + nearby_disconnecting_conn_handle = conn_handle; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_NEARBY); + } + // connected to anyone else + else if (is_paired && !fmna_state_machine_is_nearby()) + { + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SEPARATED); + } + // unpaired from owner + else + { + // Make sure we are BT unpaired as well. + if (fmna_pm_peer_count() > 0) + { + fmna_connection_fmna_unpair(false); + } + } + + return FMNA_SM_STATUS_SUCCESS; +} + +/// Function for handling Find My state machine events. +/// @param fmna_evt FIND_MY App event. +/// @param p_context Unused. +void fmna_evt_handler(FMNA_SM_Event_t fmna_evt, void *p_context) +{ + uint32_t ret_code = 0; + APP_PRINT_INFO2("fmna_evt_handler | Current State %s Event %s", + TRACE_STRING(fmna_sm_state_strings[m_fmna_state]), + TRACE_STRING(fmna_sm_event_strings[fmna_evt])); + + uint16_t list_len = fmna_sm_handlers[m_fmna_state].count; + + bool evtHandled = false; + + for (uint16_t i = 0; i < list_len; i++) + { + + if (fmna_sm_handlers[m_fmna_state].p_array_handlers[i].handler && + (fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_evt == fmna_evt)) + { + evtHandled = true; + ret_code = fmna_sm_handlers[m_fmna_state].p_array_handlers[i].handler(fmna_evt, p_context); + // update state (success) + if ((ret_code == FMNA_SM_STATUS_SUCCESS) && + (fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_success != FMNA_SM_NOCHANGE)) + { + APP_PRINT_INFO2("fmna_evt_handler successful transition old %s new %s", + TRACE_STRING(fmna_sm_state_strings[m_fmna_state]), + TRACE_STRING( + fmna_sm_state_strings[fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_success])); + m_fmna_state = fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_success; + } + else if ((ret_code != FMNA_SM_STATUS_SUCCESS) && + (fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_fail != FMNA_SM_NOCHANGE)) + { + APP_PRINT_WARN2("fmna_evt_handler fail transition old %s new %s", + TRACE_STRING(fmna_sm_state_strings[m_fmna_state]), + TRACE_STRING( + fmna_sm_state_strings[fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_fail])); + m_fmna_state = fmna_sm_handlers[m_fmna_state].p_array_handlers[i].fmna_state_fail; + } + + break; + } + } + + if (evtHandled == false) + { + APP_PRINT_ERROR2("Event Handler %s was not executed because it is not in the state: %s", + TRACE_STRING(fmna_sm_event_strings[fmna_evt]), TRACE_STRING(fmna_sm_state_strings[m_fmna_state])); + } +} + +void fmna_state_machine_stop_key_rotation_timers(void) +{ + fmna_ret_code_t ret_code = app_timer_stop(m_fmna_key_rotation_timer_id); + FMNA_ERROR_CHECK(ret_code); + + ret_code = app_timer_stop(m_fmna_one_time_key_rotation_timer_id); + FMNA_ERROR_CHECK(ret_code); +} + +/// Function for handling the timeout to transition to SEPARATED. +/// @param p_context Pointer used for passing information app_start_timer() was called. +static void fmna_nearby_separated_timeout_handler(void *p_context) +{ + nearby_separated_timeout_timer_is_on_work = false; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_NEARBY_SEPARATED_TIMEOUT); +} + +/// Function for handling the timeout to rotate keys. +/// @param p_context Pointer used for passing information app_start_timer() was called. +static void fmna_key_rotation_handler(void *p_context) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_KEYROLL; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_key_rotation_handler] Send int_gpio_msg failed!"); + return; + } +} + +static void fmna_one_time_key_rotation_handler(void *p_context) +{ + APP_PRINT_INFO0("STARTING KEY ROTATION"); + fmna_ret_code_t ret_code = app_timer_start(m_fmna_key_rotation_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_key_rotation_timeout_ms), NULL); + FMNA_ERROR_CHECK(ret_code); + + fmna_key_rotation_handler(NULL); +} + +/// Function for handling the non-owner connection timeout. +/// @param p_context Pointer used for passing information app_start_timer() was called. +void fmna_non_owner_0_connection_timeout_handler(void *p_context) +{ + APP_PRINT_INFO0("non-owner connection timeout"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_DISCONNECT; + int_gpio_msg.u.param = 0; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_non_owner_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +/// Function for handling the non-owner connection timeout. +/// @param p_context Pointer used for passing information app_start_timer() was called. +void fmna_non_owner_1_connection_timeout_handler(void *p_context) +{ + APP_PRINT_INFO0("non-owner connection timeout"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_DISCONNECT; + int_gpio_msg.u.param = 1; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_non_owner_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +/// Disconnect link if pairing not initiated and this timer fired. +/// @param p_context Pointer used for passing information app_start_timer() was called. +void fmna_pair_connection_timeout_handler(void *p_context) +{ + APP_PRINT_INFO0("Pairing Connection Timeout"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_DISCONNECT; + int_gpio_msg.u.param = fmna_gatt_platform_get_most_recent_conn_handle(); + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_pair_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +void stop_pair_connection_timer(void) +{ + APP_PRINT_INFO0("Stopping pairing timeout timer"); + // Stop pair timeout timer + fmna_ret_code_t ret_code = app_timer_stop(m_fmna_pair_connection_timeout_timer_id); + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR1("app_timer_stop m_fmna_pair_connection_timeout_timer_id err %d", ret_code); + } +} + +void separated_ut_timeout_handler(void *p_context) +{ + APP_PRINT_INFO0("separated_ut_timeout_handler"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_UT_START; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[separated_ut_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +bool fmna_state_machine_has_been_maintenanced(void) +{ + return has_been_maintenanced; +} + +void fmna_state_machine_set_persistent_connection_disconnection(bool + persistent_connection_disconnection) +{ + fmna_ret_code_t ret_code; + if (persistent_connection_disconnection) + { + ret_code = app_timer_start(m_fmna_persistent_connection_disconnection_timer_id, + MSEC_TO_TIMER_TICKS(fmna_nearby_adv_fast_duration) * 10, NULL); + FMNA_ERROR_CHECK(ret_code); + } + else + { + ret_code = app_timer_stop(m_fmna_persistent_connection_disconnection_timer_id); + FMNA_ERROR_CHECK(ret_code); + } + is_persistent_connection_disconnection = persistent_connection_disconnection; +} + +bool fmna_state_machine_is_persistent_connection_disconnection(void) +{ + return is_persistent_connection_disconnection; +} + +void fmna_persistent_connection_disconnection_timeout_handler(void *p_context) +{ + if (fmna_connection_is_fmna_paired() == false) + { + return; + } + + FMNA_LOG_INFO("Persistent Connection Disconnection Timeout"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_RECONNECT_TIMEOUT; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_persistent_connection_disconnection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +uint32_t get_next_secondary_key_rotation_index(void) +{ + return m_fmna_secondary_keys_info.next_secondary_key_rotation_index; +} + +uint32_t fmna_state_machine_get_non_owner_connection_timeout(void) +{ + return m_fmna_non_owner_connection_timeout; +} + +#ifdef DEBUG +void fmna_state_machine_set_key_rotation_timeout_ms(uint32_t key_rotation_timeout_ms) +{ + APP_PRINT_INFO1("Setting key rotation timeout to %dms", key_rotation_timeout_ms); + + // Set key rotation timeout and restart the timer. + m_fmna_key_rotation_timeout_ms = key_rotation_timeout_ms; + + fmna_state_machine_stop_key_rotation_timers(); + fmna_ret_code_t ret_code = app_timer_start(m_fmna_one_time_key_rotation_timer_id, + MSEC_TO_TIMER_TICKS(m_fmna_key_rotation_timeout_ms), + NULL); + FMNA_ERROR_CHECK(ret_code); +} + +void fmna_state_machine_set_separated_ut_timeout_seconds(uint32_t separated_ut_timeout_seconds) +{ + m_separated_ut_timeout_ms = SEC_TO_MSEC(separated_ut_timeout_seconds); +} +#endif +void fmna_state_machine_clear_keys(void) +{ + fmna_rotate_key_internal(); + is_key_rotated = true; + memset(&m_fmna_temp_primary_key, 0, sizeof(m_fmna_temp_primary_key)); + memset(&m_fmna_current_primary_key, 0, sizeof(m_fmna_current_primary_key)); + memset(&m_fmna_current_separated_primary_key, 0, sizeof(m_fmna_current_separated_primary_key)); + memset(&m_fmna_current_secondary_key, 0, sizeof(m_fmna_current_secondary_key)); + m_current_separated_primary_key_index = 0; +} + +void fmna_state_machine_handle_msg(T_IO_MSG msg) +{ + uint16_t msg_sub_type = msg.subtype; + APP_PRINT_INFO1("[fmna_state_machine_handle_msg]type = %d!", msg_sub_type); + + switch (msg_sub_type) + { + case IO_MSG_FMNA_KEYROLL: + { + APP_PRINT_INFO0("[fmna_state_machine_handle_msg]ROTATING KEYS"); + fmna_rotate_key(); + + // if we are conencted and encrypted we are maintenanced + if (fmna_connection_is_status_bit_enabled(CONN_HANDLE_ALL, FMNA_MULTI_STATUS_ENCRYPTED)) + { + has_been_maintenanced = true; + } + else + { + has_been_maintenanced = false; + } +#if (SUPPORT_BAT_DETECT_FEATURE && !GFPS_FEATURE_SUPPORT) + bat_update_battery_info(); +#endif + fmna_evt_handler(FMNA_SM_EVENT_KEY_ROTATE, NULL); + } + break; + + case IO_MSG_FMNA_DISCONNECT: + { + uint8_t conn_id = msg.u.param; + APP_PRINT_INFO1("[fmna_state_machine_handle_msg]disconnect conn_id %d", conn_id); + fmna_ret_code_t ret_code = fmna_connection_platform_disconnect(conn_id); + FMNA_ERROR_CHECK(ret_code); + } + break; + + case IO_MSG_FMNA_RECONNECT_TIMEOUT: + { + APP_PRINT_INFO0("[fmna_state_machine_handle_msg]fast reconnect adv change to slow"); + is_persistent_connection_disconnection = false; + if (fmna_connection_get_num_connections() < fmna_connection_get_max_connections()) + { + fmna_adv_init_nearby(m_fmna_current_primary_key.public_key); + fmna_adv_start_slow_adv(); + } + } + break; + + case IO_MSG_FMNA_UT_START: + { + // Enough time has passed that we need to enable motion detection and play sound on movement. + fmna_motion_detection_start(); + } + break; + + case IO_MSG_FMNA_MT: + { + motion_detected_handler(); + } + break; +#if (!ONE_SHOT_ADV_EN) + case IO_MSG_FMNA_GAP: + { + rtk_gap_handle_msg(); + } + break; +#endif + default: + APP_PRINT_WARN0("[fmna_state_machine_handle_msg]Invalid message type"); + break; + } +} diff --git a/src/app/findmy/fmna_adk/fmna_state_machine.h b/src/app/findmy/fmna_adk/fmna_state_machine.h new file mode 100644 index 0000000..6173fcf --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_state_machine.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_state_machine_h +#define fmna_state_machine_h + +#include "fmna_constants.h" +#include +#include "app_msg.h" + +typedef enum +{ + FMNA_SM_BOOT = 0, + FMNA_SM_PAIR, + FMNA_SM_SEPARATED, + FMNA_SM_NEARBY, + FMNA_SM_CONNECTING, + FMNA_SM_FMNA_PAIR, + FMNA_SM_FMNA_PAIR_COMPLETE, + FMNA_SM_CONNECTED, + FMNA_SM_DISCONNECTING, + FMNA_SM_NOCHANGE, +} FMNA_SM_State_t; + +typedef enum +{ + FMNA_SM_EVENT_BOOT = 0, + FMNA_SM_EVENT_NEARBY_SEPARATED_TIMEOUT, + FMNA_SM_EVENT_KEY_ROTATE, + FMNA_SM_EVENT_BONDED, + FMNA_SM_EVENT_UNBONDED, + FMNA_SM_EVENT_CONNECTED, + FMNA_SM_EVENT_DISCONNECTED, + FMNA_SM_EVENT_NEARBY, + FMNA_SM_EVENT_SEPARATED, + FMNA_SM_EVENT_PAIR, + FMNA_SM_EVENT_SOUND_START, + FMNA_SM_EVENT_SOUND_STOP, + FMNA_SM_EVENT_SOUND_COMPLETE, + FMNA_SM_EVENT_LOST_UT_SPEAKER_START, + FMNA_SM_EVENT_FMNA_PAIRING_INITIATE, + FMNA_SM_EVENT_FMNA_PAIRING_FINALIZE, + FMNA_SM_EVENT_FMNA_PAIRING_COMPLETE, + FMNA_SM_EVENT_FMNA_PAIRING_MFITOKEN, + FMNA_SM_EVENT_MOTION_DETECTED, +#ifdef DEBUG + FMNA_SM_EVENT_DEBUG_RESET_INTO_SEPARATED, +#endif // DEBUG +} FMNA_SM_Event_t; + +typedef struct +{ + uint32_t next_secondary_key_rotation_index; +} __attribute__((aligned(SYS_POINTER_BSIZE), packed)) fmna_secondary_keys_info_t; + +extern fmna_secondary_keys_info_t m_fmna_secondary_keys_info; + +typedef struct +{ + uint32_t index; + uint8_t public_key[FMNA_PUBKEY_BLEN]; + uint8_t ltk[GAP_SEC_KEY_LEN]; +} fmna_primary_key_t; + +typedef struct +{ + uint32_t index; + uint8_t public_key[FMNA_PUBKEY_BLEN]; +} fmna_secondary_key_t; + +extern fmna_primary_key_t m_fmna_temp_primary_key; +extern fmna_primary_key_t m_fmna_current_primary_key; +extern fmna_primary_key_t m_fmna_current_separated_primary_key; +extern fmna_secondary_key_t m_fmna_current_secondary_key; + +extern uint32_t m_fmna_key_rotation_timeout_ms; +extern volatile FMNA_SM_State_t m_fmna_state; + +/// Customized Find My State Machine error codes +#define FMNA_SM_ERROR_BASE_NUM (0x02000000) + +typedef enum +{ + FMNA_SM_STATUS_SUCCESS = FMNA_SM_ERROR_BASE_NUM, + FMNA_SM_STATUS_FAIL, + FMNA_SM_STATUS_INVALID_STATE, + FMNA_SM_STATUS_NOT_BONDED, + FMNA_SM_STATUS_CRYPTO_FAIL +} FMNA_Sm_Status_t; + +void start_pair_adv(void); + +/// Initializes the state machine. +/// @details Initializes all state machine timers, and sends a BOOT event into the state machine. +/// Accessory drops into either the Pairing state or Separated state. +void fmna_state_machine_init(void); + +/// Send event to the state machine. +/// +/// @param[in] fmna_evt Event to send to the state machine, see FMNA_SM_Event_t. +/// @param[in] p_context Data associated with this state machine event. +void fmna_evt_handler(FMNA_SM_Event_t fmna_evt, void *p_context); + +/// Dispatch state machine event to be handled in the main work loop. +/// +/// @details Intended for events that do not have additional associated info, e.g. trigger events. +/// +/// @param[in] fmna_evt Event to send to the state machine, see FMNA_SM_Event_t. +void fmna_state_machine_dispatch_event(FMNA_SM_Event_t fmna_evt); + +void fmna_state_machine_set_nearby_timeout_seconds(uint16_t nearby_timeout_seconds); +void fmna_state_machine_set_next_keyroll_ms(uint32_t next_keyroll_ms); +void fmna_state_machine_set_next_secondary_key_rotation_index(uint16_t conn_handle, uint32_t index); + +/// Latch the current primary key as the primary separated key. +/// +/// @details Latches the key and sends LATCH_SEPARATED_KEY_RESPONSE. +/// +/// @param[in] conn_handle Handle of connection issuiing the message. +void fmna_state_machine_latch_current_separated_key(uint16_t conn_handle); + +void fmna_state_machine_stop_key_rotation_timers(void); + +bool fmna_state_machine_has_been_maintenanced(void); + +void fmna_state_machine_set_persistent_connection_disconnection(bool + persistent_connection_disconnection); +bool fmna_state_machine_is_persistent_connection_disconnection(void); + +bool fmna_state_machine_is_nearby(void); + +uint32_t fmna_state_machine_get_non_owner_connection_timeout(void); + +void fmna_state_machine_clear_keys(void); + +#ifdef DEBUG +void fmna_state_machine_set_key_rotation_timeout_ms(uint32_t key_rotation_timeout_ms); +void fmna_state_machine_set_separated_ut_timeout_seconds(uint32_t separated_ut_timeout_seconds); +#endif + +void fmna_state_machine_handle_msg(T_IO_MSG msg); + +#endif /* fmna_state_machine_h */ diff --git a/src/app/findmy/fmna_adk/fmna_uarp_control_point.c b/src/app/findmy/fmna_adk/fmna_uarp_control_point.c new file mode 100644 index 0000000..6bd7395 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_uarp_control_point.c @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#include "fmna_platform_includes.h" +#include "fmna_gatt.h" +#include "fmna_state_machine.h" +#include "fmna_connection.h" +#include "fmna_crypto.h" +#include "fmna_version.h" +#include "fmna_uarp_control_point.h" +#include "FMNASampleUARP.h" + +#define UARP_MAX_LEN kFMNASamplePayloadWindowSize + +//MARK: RX Packet Definitions + +// General buffer to hold the incoming Pairing characteristic Write data +typedef struct +{ + uint16_t len; + uint8_t data[UARP_MAX_LEN]; +} uarp_buffer_t; + +static uarp_buffer_t uarp_rx_buffer = {}; + +// Only allow one controller +static uint16_t uarp_conn_handle = CONN_HANDLE_INVALID; + +static struct FMNASampleAccessory uarpAccessory = {}; +static struct FMNASampleController uarpController = {}; +static struct UARPVersion activeFW = {}; +static struct UARPVersion stagedFW = {}; +static struct FMNASampleCallbacks uarpCBs = {}; + +// Hold info for sending messages + +char dummySerial[SERIAL_NUMBER_RAW_BLEN + 1]; + +static void fmna_uarp_dispatch_send_packet_complete_handler(void *p_event_data, + uint16_t event_size) +{ + uint32_t ret_code = FMNASampleSendMessageComplete(&uarpAccessory, + &uarpController); + FMNA_ERROR_CHECK(ret_code); +} + +void fmna_uarp_packet_sent(void) +{ + app_sched_event_put(NULL, NULL, fmna_uarp_dispatch_send_packet_complete_handler); +} + +static void fmna_uarp_dispatch_rx_handler(void *p_event_data, uint16_t event_size) +{ + // Call into UARP handler + uint32_t ret_val; + ret_val = FMNASampleRecvMessage(&uarpAccessory, + &uarpController, + uarp_rx_buffer.data, + uarp_rx_buffer.len); + APP_PRINT_INFO2("UARP msg received length %x status %x", uarp_rx_buffer.len, ret_val); + memset(&uarp_rx_buffer, 0, sizeof(uarp_rx_buffer)); +} + +void fmna_uarp_control_point_handle_rx(void) +{ + app_sched_event_put(NULL, NULL, fmna_uarp_dispatch_rx_handler); +} + + +uint32_t fmna_uarp_send_msg(void *pAccessoryDelegate, void *pControllerDelegate, uint8_t *pBuffer, + uint32_t length) +{ + APP_PRINT_INFO1("fmna_uarp_send_msg 0x%x", pBuffer); + fmna_gatt_send_indication(uarp_conn_handle, FMNA_SERVICE_OPCODE_INTERNAL_UARP, pBuffer, length); + return kUARPStatusSuccess; +} + +fmna_ret_code_t fmna_uarp_controller_reset(void) +{ + APP_PRINT_INFO0("fmna_uarp_controller_reset"); + if (uarp_conn_handle != CONN_HANDLE_INVALID) + { + fmna_uarp_disconnect(uarp_conn_handle); + } + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_uarp_connect(uint16_t conn_handle) +{ + APP_PRINT_INFO0("fmna_uarp_connect"); + if (uarp_conn_handle == CONN_HANDLE_INVALID) + { + uarp_conn_handle = conn_handle; + memset(&uarp_rx_buffer, 0, sizeof(uarp_rx_buffer)); + FMNASampleControllerAdd(&uarpAccessory, &uarpController); + } + else + { + APP_PRINT_INFO2("UARP controller already established current handle %x, new conn %x", + uarp_conn_handle, conn_handle); + } + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_uarp_disconnect(uint16_t conn_handle) +{ + if (conn_handle == uarp_conn_handle) + { + APP_PRINT_INFO1("Removing controller for handle %d", conn_handle); + uarp_conn_handle = CONN_HANDLE_INVALID; + memset(&uarp_rx_buffer, 0, sizeof(uarp_rx_buffer)); + + if (uarpAccessory.pSuperBinary.pAsset) + { + /* Clean up superbinary */ + uarpAccessory.pSuperBinary.pAsset->internalFlags |= 0x80; //kUARPAssetMarkForCleanup + FMNASampleControllerRemove(&uarpAccessory, &uarpController); + uarpAccessory.pSuperBinary.pAsset = NULL; + uarpAccessory.hasPayload = kUARPNo; + memset(&(uarpAccessory.stagedFirmwareVersion), 0, sizeof(uarpAccessory.stagedFirmwareVersion)); + } + else + { + FMNASampleControllerRemove(&uarpAccessory, &uarpController); + } + + dfu_buf_free(); + } + else + { + APP_PRINT_INFO2("Not Removing controller, different handle uarp_handle %x conn_handle %d", + uarp_conn_handle, conn_handle); + } + return FMNA_SUCCESS; +} + +void fmna_uarp_control_point_init(void) +{ + APP_PRINT_INFO0("fmna uarp control point init"); + uint32_t ret_code = 0; + // The FW version code needs to verfied + activeFW.build = 0; + activeFW.major = FW_VERSION_MAJOR_NUMBER; + activeFW.minor = FW_VERSION_MINOR_NUMBER; + activeFW.release = FW_VERSION_REVISION_NUMBER; + uarpCBs.fSendMessage = fmna_uarp_send_msg; + + memcpy(dummySerial, fmna_crypto_get_serial_number_raw(), SERIAL_NUMBER_RAW_BLEN); + dummySerial[SERIAL_NUMBER_RAW_BLEN] = 0; + ret_code = FMNASampleInit(&uarpAccessory, + FMNA_MANUFACTURER_NAME, + FMNA_MODEL_NAME, + (const char *)dummySerial, + FMNA_HARDWARE_VERSION, + &activeFW, + &stagedFW, + &uarpCBs); + FMNA_ERROR_CHECK(ret_code); +} + +fmna_ret_code_t fmna_uarp_control_point_append_to_rx_buffer(uint8_t const *data, uint16_t length) +{ + APP_PRINT_INFO0("fmna_uarp_control_point_append_to_rx_buffer"); + if ((uarp_rx_buffer.len + length) > UARP_MAX_LEN) + { + APP_PRINT_INFO0("Too much UARP data in packet"); + memset(&uarp_rx_buffer, 0, sizeof(uarp_rx_buffer)); + return FMNA_ERROR_INVALID_LENGTH; + } + + memcpy(&(uarp_rx_buffer.data[uarp_rx_buffer.len]), data, length); + uarp_rx_buffer.len += length; + + return FMNA_SUCCESS; +} + +fmna_ret_code_t fmna_uarp_authorized_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length) +{ + fmna_ret_code_t ret_code = FMNA_SUCCESS; + APP_PRINT_INFO1("Write request of UARP Characteristic flags %x", data[FRAGMENTED_FLAG_INDEX]); + + if (fmna_connection_is_fmna_paired() != true) + { + APP_PRINT_ERROR0("Not paired - refusing write request"); + return FMNA_ERROR_INVALID_STATE; + } + + if (uarp_conn_handle != conn_handle) + { + // drop the packet not the correct connection handle + APP_PRINT_ERROR0("Not current Controller - Dropping"); + return FMNA_ERROR_INVALID_STATE; + } + + ret_code = fmna_uarp_control_point_append_to_rx_buffer(&data[FRAGMENTED_FLAG_LENGTH], + length - FRAGMENTED_FLAG_LENGTH); + if (ret_code != FMNA_SUCCESS) + { + // TODO send an error? + APP_PRINT_ERROR1("fmna_uarp_control_point_append_to_rx_buffer error %x", ret_code); + return ret_code; + } + + if (data[FRAGMENTED_FLAG_INDEX] & FRAGMENTED_FLAG_FINAL) + { + // packet reassembled so give to UARP + // Delay allowing gatt writes until the packet is processes so the rx buffer is not overwritten + fmna_uarp_control_point_handle_rx(); + } + else + { + APP_PRINT_ERROR0("fmna_uarp_control_point_append_to_rx_buffer fragment not final"); + } + + return ret_code; +} diff --git a/src/app/findmy/fmna_adk/fmna_uarp_control_point.h b/src/app/findmy/fmna_adk/fmna_uarp_control_point.h new file mode 100644 index 0000000..88aab0b --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_uarp_control_point.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_uarp_control_point_h +#define fmna_uarp_control_point_h + +#include "fmna_gatt.h" + +/// Function for handling the different UARP messages. +/// @param data Buffer of UARP data +fmna_ret_code_t fmna_uarp_authorized_rx_handler(uint16_t conn_handle, uint8_t const *data, + uint16_t length); + +/// Function for indicating an encrypted link has connected +/// @param conn_handle the connection handle for the encrypted connection +fmna_ret_code_t fmna_uarp_connect(uint16_t conn_handle); + +/// Function for indicating a link has disconnected +/// @param conn_handle the connection handle for the disconnected link +fmna_ret_code_t fmna_uarp_disconnect(uint16_t conn_handle); + +fmna_ret_code_t fmna_uarp_controller_reset(void); + +void fmna_uarp_packet_sent(void); + +void fmna_uarp_control_point_init(void); + +#endif /* fmna_uarp_control_point_h */ diff --git a/src/app/findmy/fmna_adk/fmna_util.h b/src/app/findmy/fmna_adk/fmna_util.h new file mode 100644 index 0000000..ad690d9 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_util.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_util_h +#define fmna_util_h + +#include +#include +#include + +/// Macro for converting seconds to milliseconds. +/// @param SECONDS Number of seconds to convert. +#define SEC_TO_MSEC(SECONDS) (SECONDS * 1000) + +/// Macro for converting minutes to milliseconds. +/// @param MINUTES Number of minutes to convert. +#define MIN_TO_MSEC(MINUTES) (MINUTES * SEC_TO_MSEC(60)) + +/// Macro for converting HOURS to milliseconds. +/// @param HOURS Number of hours to convert. +#define HOURS_TO_MSEC(HOURS) (HOURS * MIN_TO_MSEC(60)) + +/// Macro for converting days to milliseconds. +/// @param DAYS Number of days to convert. +#define DAYS_TO_MSEC(DAYS) (DAYS * HOURS_TO_MSEC(24)) + +/**@brief Set a bit in the uint32 word. + * + * @param[in] W Word whose bit is being set. + * @param[in] B Bit number in the word to be set. + */ +#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B))) + + +/**@brief Clears a bit in the uint32 word. + * + * @param[in] W Word whose bit is to be cleared. + * @param[in] B Bit number in the word to be cleared. + */ +#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B)))) + +/** + * @brief Define Bit-field mask + * + * Macro that defined the mask with selected number of bits set, starting from + * provided bit number. + * + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + */ +#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) ) + +/** + * @brief Get bit-field + * + * Macro that extracts selected bit-field from provided value + * + * @param[in] val Value from which selected bit-field would be extracted + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + * + * @return Value of the selected bits + */ +#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) ) + +/** + * @brief Create bit-field value + * + * Value is masked and shifted to match given bit-field + * + * @param[in] val Value to set on bit-field + * @param[in] bcnt Number of bits for bit-field + * @param[in] boff Offset of bit-field + * + * @return Value positioned of given bit-field. + */ +#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) ) + +/// Utility function to reverse an array given start and end indices. +static inline void reverse_array(uint8_t *array, uint8_t start_idx, uint8_t end_idx) +{ + while (start_idx < end_idx) + { + uint8_t temp = array[start_idx]; + array[start_idx] = array[end_idx]; + array[end_idx] = temp; + start_idx += 1; + end_idx -= 1; + } +} + +/// Utility function to check if every element in an array is a specified value. +/// @param array Array of values to check. +/// @param val Value to compare array elements to. +/// @param len Length of the array. +static inline bool memcmp_val(void *array, unsigned char val, size_t len) +{ + unsigned char *p_array = array; + + // Compare each element in array to val. + for (; len > 0; len--, p_array++) + { + if (*p_array != val) + { + return false; + } + } + return true; +} + +#endif /* fmna_util_h */ diff --git a/src/app/findmy/fmna_adk/fmna_version.c b/src/app/findmy/fmna_adk/fmna_version.c new file mode 100644 index 0000000..8d33497 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_version.c @@ -0,0 +1,37 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#include "fmna_platform_includes.h" +#include "fmna_constants.h" +#include "fmna_util.h" +#include "fmna_version.h" + +// FW version bit offsets as described in spec. +#define FW_VERSION_MAJOR_NUMBER_OFFSET 16 +#define FW_VERSION_MINOR_NUMBER_OFFSET 8 + +static uint32_t m_fw_version = 0; + +void fmna_version_init(void) +{ + // Build the FW version value. + + m_fw_version |= FW_VERSION_REVISION_NUMBER; + m_fw_version |= BF_VAL(FW_VERSION_MAJOR_NUMBER, 16, FW_VERSION_MAJOR_NUMBER_OFFSET); + m_fw_version |= BF_VAL(FW_VERSION_MINOR_NUMBER, 8, FW_VERSION_MINOR_NUMBER_OFFSET); + + APP_PRINT_INFO1("FW Version: 0x%08x", m_fw_version); +} + +uint32_t fmna_version_get_fw_version(void) +{ + APP_PRINT_INFO3("get fw version: v%d.%d.%d", FW_VERSION_MAJOR_NUMBER, FW_VERSION_MINOR_NUMBER, + FW_VERSION_REVISION_NUMBER); + return m_fw_version; +} + diff --git a/src/app/findmy/fmna_adk/fmna_version.h b/src/app/findmy/fmna_adk/fmna_version.h new file mode 100644 index 0000000..58f4036 --- /dev/null +++ b/src/app/findmy/fmna_adk/fmna_version.h @@ -0,0 +1,19 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#ifndef fmna_version_h +#define fmna_version_h + +#define FW_VERSION_MAJOR_NUMBER 1 +#define FW_VERSION_MINOR_NUMBER 1 +#define FW_VERSION_REVISION_NUMBER 1 + +void fmna_version_init(void); +uint32_t fmna_version_get_fw_version(void); + +#endif /* fmna_version_h */ diff --git a/src/app/findmy/fmna_peripheral/FM11NT082C.c b/src/app/findmy/fmna_peripheral/FM11NT082C.c new file mode 100644 index 0000000..6b92b19 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/FM11NT082C.c @@ -0,0 +1,220 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file FM11NT082C.c +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-17 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "FM11NT082C.h" +#include "rtl876x_i2c.h" +#include "trace.h" +#include "string.h" +#include "os_sched.h" + +/*============================================================================* +* Local functions +*============================================================================*/ +/** + * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. + * @note The number of byte can't exceed the EEPROM page size. + * @param pBuffer : pointer to the buffer containing the data to be written to + * the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : variable holding number of bytes to + * written to the EEPROM. + * @return bool +*/ +static bool sEE_WritePage(uint8_t *pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite) +{ + if (NumByteToWrite <= 0 || NumByteToWrite > sEE_PAGESIZE) + { + APP_PRINT_ERROR1("FM11 I2C write EEPROM size %d error!", NumByteToWrite); + return false; + } + + uint8_t tx_buf[sEE_PAGESIZE + 2] = {0}; + tx_buf[0] = (uint8_t)((WriteAddr & 0xFF00) >> 8); + tx_buf[1] = (uint8_t)(WriteAddr & 0x00FF); + memcpy(&tx_buf[2], pBuffer, NumByteToWrite); + + I2C_Status ret = I2C_MasterWrite(I2C0, tx_buf, sizeof(tx_buf)); + if (ret != I2C_Success) + { + APP_PRINT_ERROR3("FM11 I2C write EEPROM failed! addr:%#x data:%b err:%d", + WriteAddr, TRACE_BINARY(NumByteToWrite, pBuffer), ret); + return false; + } + + os_delay(10); //write across pages must delay 10ms + return true; +} + +/*============================================================================* +* Global functions +*============================================================================*/ +/** + * @brief Write buffer of data to the I2C EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : number of bytes to write to the EEPROM. + * @param pBuffer : pointer to the buffer containing the data to be written + * to the EEPROM. + * @return bool +*/ +bool FM11_WriteE2(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) +{ + uint16_t StartAddr = WriteAddr; + + /* Check WriteAddr is sEE_PAGESIZE aligned */ + uint8_t RemainByte = WriteAddr % sEE_PAGESIZE; + uint8_t ByteOfFront = (RemainByte) ? sEE_PAGESIZE - RemainByte : 0; + uint8_t NumOfPage = (NumByteToWrite - ByteOfFront) / sEE_PAGESIZE; + uint8_t ByteOfEnd = (NumByteToWrite - ByteOfFront) % sEE_PAGESIZE; + APP_PRINT_INFO4("FM11 write EEPROM: addr %#x front %dB page number %d, end %dB", + StartAddr, ByteOfFront, NumOfPage, ByteOfEnd); + + if (ByteOfFront) + { + if (!sEE_WritePage(pBuffer, WriteAddr, ByteOfFront)) + { + return false; + } + WriteAddr += ByteOfFront; + pBuffer += ByteOfFront; + } + + while (NumOfPage--) + { + if (!sEE_WritePage(pBuffer, WriteAddr, sEE_PAGESIZE)) + { + return false; + } + WriteAddr += sEE_PAGESIZE; + pBuffer += sEE_PAGESIZE; + } + + if (ByteOfEnd) + { + if (!sEE_WritePage(pBuffer, WriteAddr, ByteOfEnd)) + { + return false; + } + WriteAddr += ByteOfEnd; + pBuffer += ByteOfEnd; + } + + if ((WriteAddr - StartAddr) != NumByteToWrite) + { + APP_PRINT_ERROR2("Address misalignment! Start Addr:%#x Cur Addr:%#x", StartAddr, WriteAddr); + return false; + } + return true; +} + +/** + * @brief Read buffer of data to the I2C EEPROM. + * @param pBuffer : pointer to the buffer containing the data to be read + * to the EEPROM. + * @param ReadAddr : EEPROM's internal address to read to. + * @param NumByteToWrite : number of bytes to write to the EEPROM. + * @return bool +*/ +bool FM11_ReadE2(uint8_t *pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead) +{ + if (NumByteToRead <= 0) + { + APP_PRINT_ERROR1("FM11 I2C read EEPROM size %d error!", NumByteToRead); + return false; + } + + uint8_t addr[2]; + addr[0] = (uint8_t)((ReadAddr & 0xFF00) >> 8); + addr[1] = (uint8_t)(ReadAddr & 0x00FF); + + memset(pBuffer, 0, NumByteToRead); + I2C_Status ret = I2C_RepeatRead(I2C0, addr, 2, pBuffer, NumByteToRead); + if (ret != I2C_Success) + { + APP_PRINT_ERROR3("FM11 I2C read failed! addr:%#x data:%b err:%d", + ReadAddr, TRACE_BINARY(NumByteToRead, pBuffer), ret); + return false; + } + return true; +} + +/** + * @brief I2C Write FM11 Register + * @param addr: register address + * @param data: data to be writen + * @return void +*/ +void FM11_WriteReg(uint16_t addr, uint8_t data) +{ + uint8_t tx_buf[3] = {0}; + tx_buf[0] = (uint8_t)((addr & 0xFF00) >> 8); + tx_buf[1] = (uint8_t)(addr & 0x00FF); + tx_buf[2] = data; + + I2C_Status ret = I2C_MasterWrite(I2C0, tx_buf, sizeof(tx_buf)); + if (ret != I2C_Success) + { + APP_PRINT_ERROR3("FM11 I2C write failed! reg:%#x data:%#x err:%d", addr, data, ret); + } + os_delay(10); +} + +/** + * @brief I2C Read FM11 Register + * @param addr: register address + * @return data: data to be read +*/ +uint8_t FM11_ReadReg(uint16_t addr) +{ + uint8_t data = 0; + FM11_ReadE2(&data, addr, 1); + return data; +} + +/** + * @brief i2c read FM11 manufacturer id + * @param void + * @return FM11 manufacturer id +*/ +uint8_t FM11_Get_ManuID(void) +{ + uint8_t manu_id = FM11_ReadReg(FM441_Serial_number_EEaddress); + + APP_PRINT_INFO1("FM11 manufacturer ID = %#x", manu_id); + return manu_id; +} + +bool FM11_Init(void) +{ + if (FM11_Get_ManuID() != FM11_MANU_ID) + { + APP_PRINT_ERROR0("FM11 deinit failed, manu id mismatch"); + return false; + } + +// FM11_WriteReg(FM11_RESET_SILENCE, 0x55); //Soft Reset + uint8_t user_cfg[4] = {0x00, 0x86, 0xA1, 0xD8}; //disable Vout_mode + FM11_WriteE2(user_cfg, FM441_Protocol_Control_EEaddress, 4); + + FM11_ReadE2(user_cfg, FM441_Protocol_Control_EEaddress, 4); + APP_PRINT_INFO1("FM11 USER CFG REG = %b", TRACE_BINARY(4, user_cfg)); + if (user_cfg[3] & 0x01) + { + APP_PRINT_ERROR1("FM11 USER CFG REG check failed! flag = %#x", user_cfg[3]); + return false; + } + + return true; +} + diff --git a/src/app/findmy/fmna_peripheral/FM11NT082C.h b/src/app/findmy/fmna_peripheral/FM11NT082C.h new file mode 100644 index 0000000..5643859 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/FM11NT082C.h @@ -0,0 +1,76 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file FM11NT082C.h +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-17 +* @version v1.0 +********************************************************************************************************* +*/ + +#ifndef __FM11NT082C_H +#define __FM11NT082C_H + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Macros + *============================================================================*/ +#define FM11_CLK 400000 //uint:Hz +#define FM11_ADDR 0x57 +#define FM11_MANU_ID 0x1D +#define sEE_PAGESIZE 16 + +/* FM11NT082C register address map */ +#define FM11_USER_CFG0 0xFFE0 +#define FM11_USER_CFG1 0xFFE1 +#define FM11_USER_CFG2 0xFFE2 +#define FM11_RESET_SILENCE 0xFFE6 +#define FM11_STATUS 0xFFE7 +#define FM11_VOUT_EN_CFG 0xFFE9 +#define FM11_VOUT_RES_CFG 0xFFEA + +/* FM11NT082C register EEPROM address */ +#define FM11_USER_CFG0_EE 0x0390 +#define FM11_USER_CFG1_EE 0x0391 +#define FM11_USER_CFG2_EE 0x0392 +#define FM11_STATUS_EE 0x0393 +#define FM11_VOUT_RES_CFG_EE 0x03B2 + +#define FM441_Serial_number_EEaddress 0x0000 +#define FM441_CC_EEaddress 0x000C +#define FM441_NDEF_Header_EEaddress 0x0010 +#define FM441_AUTH0_EEaddress 0x03CF +#define FM441_AUTH_Key_EEaddress 0x03A0 + +#define FM441_CRC8_EEaddress 0x03BB +#define FM441_ATQA_EEaddress 0x03BC +#define FM441_SAK_Control_EEaddress 0x03BF +#define FM441_Protocol_Control_EEaddress 0x0390 + +/*============================================================================* +* Global functions +*============================================================================*/ +bool FM11_WriteE2(uint8_t *pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite); +bool FM11_ReadE2(uint8_t *pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead); +void FM11_WriteReg(uint16_t addr, uint8_t data); +uint8_t FM11_ReadReg(uint16_t addr); +uint8_t FM11_Get_ManuID(void); +bool FM11_Init(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/fmna_peripheral/da213b.c b/src/app/findmy/fmna_peripheral/da213b.c new file mode 100644 index 0000000..8809666 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/da213b.c @@ -0,0 +1,191 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file da213b.h +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-01 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "da213b.h" +#include "rtl876x_i2c.h" +#include "trace.h" +#include "os_sched.h" +#include "fmna_sound_platform.h" + +#if USE_DA213B_SENSOR +/*============================================================================* +* Local functions +*============================================================================*/ +/** + * @brief i2c write one byte + * @param reg: register address + * @param data: data to be writen + * @return void +*/ +static void da213b_write_one_byte(uint8_t reg, uint8_t data) +{ + I2C_SetSlaveAddress(I2C0, DA213B_ADDR); + + uint8_t tx_buf[2] = {0}; + tx_buf[0] = reg; + tx_buf[1] = data; + + /* Wait communication end as a master . If SET, I2C0 have not finish transmission */ + while (I2C_GetFlagState(I2C0, I2C_FLAG_MST_ACTIVITY) == 1); + + I2C_Status ret = I2C_MasterWrite(I2C0, tx_buf, sizeof(tx_buf)); + if (ret != I2C_Success) + { + APP_PRINT_ERROR3("I2C write failed! reg:%#x data:%#x err:%d", reg, data, ret); + } +} + +/** + * @brief i2c read one byte + * @param reg: register address + * @param data: data to be read + * @return void +*/ +static void da213b_read_one_byte(uint8_t reg, uint8_t *data) +{ + I2C_SetSlaveAddress(I2C0, DA213B_ADDR); + + /* Wait communication end as a master . If SET, I2C0 have not finish transmission */ + while (I2C_GetFlagState(I2C0, I2C_FLAG_MST_ACTIVITY) == 1); + + I2C_Status ret = I2C_RepeatRead(I2C0, ®, 1, data, 1); + if (ret != I2C_Success) + { + APP_PRINT_ERROR3("I2C read failed! reg:%#x data:%#x err:%d", reg, *data, ret); + } +} + +/** + * @brief i2c read da213b chip id + * @param void + * @return da213b chip id +*/ +static uint8_t da213b_get_chipid(void) +{ + uint8_t da213b_chip_id = 0; + da213b_read_one_byte(DA213B_CHIPID, &da213b_chip_id); + + APP_PRINT_INFO1("DA213B CHIP ID = %#x", da213b_chip_id); + return da213b_chip_id; +} + +/** + * @brief Initialize the da213b active detect mode + * @param void + * @return void +*/ +static void da213b_active_detect_init(void) +{ + da213b_write_one_byte(DA213B_ACTIVE_DUR, ACTIVE_DUR); + da213b_write_one_byte(DA213B_ACTIVE_THS, ACTIVE_TH); + da213b_write_one_byte(DA213B_INT_LATCH, 0x0F); //int latched + da213b_write_one_byte(DA213B_INT_CONFIG, 0x80); //reset all latched int + da213b_write_one_byte(DA213B_INT_SET1, 0x07); //enable the active interrupt for the x/y/z axis +} + +/*============================================================================* +* Global functions +*============================================================================*/ +/** + * @brief check da213b motion flag + * @param void + * @return true: motion detected false: motion undetected +*/ +bool da213b_check_motion_flag(void) +{ + uint8_t motion_flag; + if (da213b_get_chipid() != DA213B_ID) + { + APP_PRINT_ERROR0("da213b check failed, chip id mismatch"); + return false; + } +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + if (sound_en) + { + APP_PRINT_INFO0("stop sound for motion detection"); + da213b_write_one_byte(DA213B_INT_CONFIG, 0x80); //reset all latched int + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + os_delay(30); + da213b_read_one_byte(DA213B_MOTION_FLAG, &motion_flag); + } + else +#endif + { + os_delay(30); + da213b_read_one_byte(DA213B_MOTION_FLAG, &motion_flag); + } + + if (motion_flag & BIT2) + { + uint8_t active_status; + da213b_read_one_byte(DA213B_ACTIVE_STATUS, &active_status); + da213b_write_one_byte(DA213B_INT_CONFIG, 0x80); //reset all latched int + APP_PRINT_INFO1("motion detected! active status = %#x", active_status & 0x0f); + da213b_write_one_byte(DA213B_INT_LATCH, 0x0C); //after firstly MT, int latched 25ms + return true; + } + return false; +} + +/** + * @brief Initialize the da213b register + * @param void + * @return true: succeed false: failed +*/ +bool da213b_init(void) +{ + if (da213b_get_chipid() != DA213B_ID) + { + APP_PRINT_ERROR0("da213b init failed, chip id mismatch"); + return false; + } + + da213b_write_one_byte(DA213B_CONFIG, 0x24); //soft reset + os_delay(50); + + da213b_write_one_byte(DA213B_RANGE, 0x00); //full scale = 2g + da213b_write_one_byte(DA213B_ODR_AXIS, 0x09); //ODR = 500hz + da213b_write_one_byte(DA213B_MODE_BW, 0x05); //normal mode, 100Hz Bandwidth, autosleep enable + + da213b_active_detect_init(); + return true; +} + +/** + * @brief Deinitialize the da213b register + * @param void + * @return true: succeed false: failed +*/ +bool da213b_deinit(void) +{ +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + if (sound_en) + { + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + } +#endif + if (da213b_get_chipid() != DA213B_ID) + { + APP_PRINT_ERROR0("da213b deinit failed, chip id mismatch"); + return false; + } + + da213b_write_one_byte(DA213B_MODE_BW, 0x9E); //switch to suspend mode + os_delay(50); + da213b_write_one_byte(DA213B_CONFIG, 0x24); //soft reset + + return true; +} +#endif diff --git a/src/app/findmy/fmna_peripheral/da213b.h b/src/app/findmy/fmna_peripheral/da213b.h new file mode 100644 index 0000000..cd6d8c7 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/da213b.h @@ -0,0 +1,70 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file da213b.h +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-01 +* @version v1.0 +********************************************************************************************************* +*/ + +#ifndef __DA213B_H +#define __DA213B_H + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Macros + *============================================================================*/ +#define DA213B_CLK 400000 //uint:Hz +#define DA213B_ADDR 0x27 +#define DA213B_ID 0x13 + +/* da213b register address map */ +#define DA213B_CONFIG 0X00 +#define DA213B_CHIPID 0X01 +#define DA213B_OUT_X_L 0x02 +#define DA213B_OUT_X_H 0x03 +#define DA213B_OUT_Y_L 0x04 +#define DA213B_OUT_Y_H 0x05 +#define DA213B_OUT_Z_L 0x06 +#define DA213B_OUT_Z_H 0x07 +#define DA213B_MOTION_FLAG 0X09 +#define DA213B_NEWDATA_FLAG 0X0A +#define DA213B_ACTIVE_STATUS 0X0B +#define DA213B_RANGE 0X0F +#define DA213B_ODR_AXIS 0X10 +#define DA213B_MODE_BW 0X11 +#define DA213B_SWAP_POLARITY 0X12 +#define DA213B_INT_SET1 0X16 +#define DA213B_INT_SET2 0X17 +#define DA213B_INT_MAP1 0X19 +#define DA213B_INT_MAP2 0X1A +#define DA213B_INT_CONFIG 0X20 +#define DA213B_INT_LATCH 0X21 +#define DA213B_ACTIVE_DUR 0X27 +#define DA213B_ACTIVE_THS 0X28 + +/*============================================================================* +* Global functions +*============================================================================*/ +bool da213b_check_motion_flag(void); +bool da213b_init(void); +bool da213b_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/fmna_peripheral/key_handle.c b/src/app/findmy/fmna_peripheral/key_handle.c new file mode 100644 index 0000000..764ae12 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/key_handle.c @@ -0,0 +1,389 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file key_handle.c +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-01 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "rtl876x_gpio.h" +#include "rtl876x_pinmux.h" +#include "rtl876x_nvic.h" +#include "rtl876x_rcc.h" +#include "board.h" +#include "key_handle.h" +#include "app_msg.h" +#include "app_task.h" +#include "trace.h" +#include "os_timer.h" +#include "fmna_connection.h" +#include "os_sched.h" +#include "fmna_platform_includes.h" + +/*============================================================================* + * Macros + *============================================================================*/ +#define GPIO_KEY_DEBOUNCE_TIMEOUT 10 /* when the timeout < 20ms, the cpu doesn't enter DLPS */ +#define BUTTON_PERIODIC_TIMEOUT 100 + +/*============================================================================* + * Local Variables + *============================================================================*/ +static T_BUTTON trigger_button = {GPIO_KEY_LEVEL_0, IDLE, 0}; +#if SUPPORT_CUSTOMIZED_APP +static T_BUTTON cust_button = {GPIO_KEY_LEVEL_0, IDLE, 0}; +#endif +static void *button_periodic_timer; + +/* 长按检测标志位,避免重复触发 */ +#define FLAG_3S_TRIGGERED 0x01 +#define FLAG_5S_TRIGGERED 0x02 +#define FLAG_10S_TRIGGERED 0x04 +static uint8_t time_flags = 0; + +/*============================================================================* + * Global Variables + *============================================================================*/ +void *gpio_key_debounce_timer; + +/*============================================================================* +* Local Functions +*============================================================================*/ +static void gpio_nvic_init(void) +{ + NVIC_InitTypeDef NVIC_init_struct; + NVIC_init_struct.NVIC_IRQChannel = TRIG_BUTTON_IRQ; + NVIC_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_init_struct.NVIC_IRQChannelPriority = 3; + NVIC_Init(&NVIC_init_struct); + +#if SUPPORT_CUSTOMIZED_APP + NVIC_init_struct.NVIC_IRQChannel = CUST_ADV_PIN_IRQ; + NVIC_Init(&NVIC_init_struct); +#endif +} + +static void button_periodic_timer_cb(void *p_timer) +{ +#if SUPPORT_CUSTOMIZED_APP + if (cust_button.state == PRESSED) + { + cust_button.pressed_time += BUTTON_PERIODIC_TIMEOUT; + } +#endif + if (trigger_button.state == PRESSED) + { + trigger_button.pressed_time += BUTTON_PERIODIC_TIMEOUT; + + // 3秒检测 + if ((trigger_button.pressed_time >= 3300) && !(time_flags & FLAG_3S_TRIGGERED)) + { + APP_PRINT_INFO0("--------------------------------------------------------------------------->THIS IS 3S"); + fmna_sound_platform_start(SOUND_EVENT_FMNA, 500, PWM_HIGH_FREQ); + os_delay(100); + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + time_flags |= FLAG_3S_TRIGGERED; + } + // 5秒检测 + else if ((trigger_button.pressed_time >= 4800) && !(time_flags & FLAG_5S_TRIGGERED)) + { + APP_PRINT_INFO0("--------------------------------------------------------------------------->THIS IS 5S"); + for(int i = 0; i<=1; i++){ + fmna_sound_platform_start(SOUND_EVENT_FMNA, 500, PWM_HIGH_FREQ); + os_delay(100); + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + os_delay(100); + } + time_flags |= FLAG_5S_TRIGGERED; + } + // 10秒检测 + else if ((trigger_button.pressed_time >= 9800) && !(time_flags & FLAG_10S_TRIGGERED)) + { + APP_PRINT_INFO0("--------------------------------------------------------------------------->THIS IS 10S"); + for(int i = 0; i<=3; i++){ + fmna_sound_platform_start(SOUND_EVENT_FMNA, 500, PWM_HIGH_FREQ); + os_delay(100); + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + os_delay(100); + } + fmna_sound_platform_start(SOUND_EVENT_FMNA, 2000, PWM_HIGH_FREQ); + os_delay(1000); + fmna_sound_platform_stop(SOUND_EVENT_FMNA); + os_delay(100); + fmna_factory_reset(); + time_flags |= FLAG_10S_TRIGGERED; + } + } +} + +#if SUPPORT_CUSTOMIZED_APP +static void cust_button_int_handler(uint8_t keystatus) +{ + if (cust_button.trig_level == GPIO_KEY_LEVEL_0) + { + GPIO->INTPOLARITY |= GPIO_CUST_ADV_PIN; + cust_button.trig_level = GPIO_KEY_LEVEL_1; + APP_PRINT_INFO0("[cust_button_int_handler]cust button is pressed"); + + cust_button.pressed_time = 0; + cust_button.state = PRESSED; + os_timer_start(&button_periodic_timer); + } + else + { + GPIO->INTPOLARITY &= ~GPIO_CUST_ADV_PIN; + cust_button.trig_level = GPIO_KEY_LEVEL_0; + APP_PRINT_INFO1("[cust_button_int_handler]cust button is released, pressed %d ms", + cust_button.pressed_time); + + cust_button.state = IDLE; + os_timer_stop(&button_periodic_timer); + + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_GPIO; + if (cust_button.pressed_time >= 10000) + { + int_gpio_msg.subtype = IO_MSG_GPIO_CUST_LONG_PRESS_10S; + } + else if (cust_button.pressed_time >= 2000) + { + int_gpio_msg.subtype = IO_MSG_GPIO_CUST_LONG_PRESS_2S; + } + else + { + int_gpio_msg.subtype = IO_MSG_GPIO_CUST_SHORT_PRESS; + } + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[cust_button_int_handler]Send int_gpio_msg failed!"); + //Add user code here! + return; + } + } +} +#endif + +static void trig_button_int_handler(uint8_t keystatus) +{ + if (trigger_button.trig_level == GPIO_KEY_LEVEL_0) + { + GPIO->INTPOLARITY |= GPIO_TRIG_PIN; + + trigger_button.trig_level = GPIO_KEY_LEVEL_1; + APP_PRINT_INFO0("[trig_button_int_handler]gpio trigger button is pressed"); + + trigger_button.pressed_time = 0; + trigger_button.state = PRESSED; + // 重置时间标志位,准备新的长按检测 + time_flags = 0; + + os_timer_start(&button_periodic_timer); + + } + else + { + GPIO->INTPOLARITY &= ~GPIO_TRIG_PIN; + trigger_button.trig_level = GPIO_KEY_LEVEL_0; + + APP_PRINT_INFO1("[trig_button_int_handler]trig button is released, pressed %d ms", + trigger_button.pressed_time); + + trigger_button.state = IDLE; + os_timer_stop(&button_periodic_timer); + // 重置时间标志位 + time_flags = 0; + + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_GPIO; + if (trigger_button.pressed_time >= 10000) + { + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_LONG_PRESS_10S; + } + else if (trigger_button.pressed_time >= 5000) + { + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_LONG_PRESS_5S; + } + else if(trigger_button.pressed_time >= 2600){ + + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_LONG_PRESS_3S; + + }else if (trigger_button.pressed_time >= 2000) + { + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_LONG_PRESS_2S; + }else if(trigger_button.pressed_time >= 800){ + + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_LONG_PRESS_1S; + } + else + { + int_gpio_msg.subtype = IO_MSG_GPIO_TRIG_SHORT_PRESS; + } + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[trig_button_int_handler]Send int_gpio_msg failed!"); + return; + } + } +} + +static void gpio_key_debounce_timeout_cb(void *p_timer) +{ + uint8_t input_data = GPIO_ReadInputDataBit(GPIO_TRIG_PIN); + if (trigger_button.trig_level == input_data) + { + APP_PRINT_INFO2("[gpio_key_debounce_timeout_cb] trig pin cur level:%d, trig level:%d", input_data, + trigger_button.trig_level); + trig_button_int_handler(input_data); + } + +#if SUPPORT_CUSTOMIZED_APP + input_data = GPIO_ReadInputDataBit(GPIO_CUST_ADV_PIN); + if (cust_button.trig_level == input_data) + { + APP_PRINT_INFO2("[gpio_key_debounce_timeout_cb] cust pin cur level:%d, trig level:%d", input_data, + cust_button.trig_level); + cust_button_int_handler(input_data); + } +#endif +} + +/*============================================================================* +* Global Functions +*============================================================================*/ +void gpio_board_init(void) +{ + Pinmux_Config(TRIGGER_BUTTON, DWGPIO); + Pad_Config(TRIGGER_BUTTON, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + +#if SUPPORT_CUSTOMIZED_APP + Pinmux_Config(CUST_ADV_PIN, DWGPIO); + Pad_Config(CUST_ADV_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); +#endif +} + +void gpio_driver_init(void) +{ + RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + GPIO_InitTypeDef GPIO_init_struct; + GPIO_StructInit(&GPIO_init_struct); + + GPIO_init_struct.GPIO_Pin = GPIO_TRIG_PIN; + GPIO_init_struct.GPIO_Mode = GPIO_Mode_IN; + GPIO_init_struct.GPIO_ITCmd = ENABLE; + GPIO_init_struct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + GPIO_init_struct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + GPIO_init_struct.GPIO_DebounceTime = 5; + GPIO_init_struct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + GPIO_Init(&GPIO_init_struct); + + GPIO_ClearINTPendingBit(GPIO_TRIG_PIN); + GPIO_MaskINTConfig(GPIO_TRIG_PIN, DISABLE); + GPIO_INTConfig(GPIO_TRIG_PIN, ENABLE); + +#if SUPPORT_CUSTOMIZED_APP + GPIO_init_struct.GPIO_Pin = GPIO_CUST_ADV_PIN; + GPIO_init_struct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + GPIO_Init(&GPIO_init_struct); + + GPIO_ClearINTPendingBit(GPIO_CUST_ADV_PIN); + GPIO_MaskINTConfig(GPIO_CUST_ADV_PIN, DISABLE); + GPIO_INTConfig(GPIO_CUST_ADV_PIN, ENABLE); +#endif + + gpio_nvic_init(); + /* init sw debounce timer */ + os_timer_create(&gpio_key_debounce_timer, "gpio key debounce timer", + 1, GPIO_KEY_DEBOUNCE_TIMEOUT, false, gpio_key_debounce_timeout_cb); + /* init periodic timer */ + os_timer_create(&button_periodic_timer, "button_periodic_timer", + 1, BUTTON_PERIODIC_TIMEOUT, true, button_periodic_timer_cb); +} + +void trig_button_handler(void) +{ + GPIO_MaskINTConfig(GPIO_TRIG_PIN, ENABLE); + GPIO_ClearINTPendingBit(GPIO_TRIG_PIN); + + uint8_t input_data = GPIO_ReadInputDataBit(GPIO_TRIG_PIN); + APP_PRINT_INFO2("[trig_button_handler] cur level:%d, trig level:%d", input_data, + trigger_button.trig_level); + if (trigger_button.trig_level == input_data) + { + trig_button_int_handler(input_data); + } + + GPIO_ClearINTPendingBit(GPIO_TRIG_PIN); + GPIO_MaskINTConfig(GPIO_TRIG_PIN, DISABLE); +} + +#if SUPPORT_CUSTOMIZED_APP +void cust_adv_pin_handler(void) +{ + GPIO_MaskINTConfig(GPIO_CUST_ADV_PIN, ENABLE); + GPIO_ClearINTPendingBit(GPIO_CUST_ADV_PIN); + + uint8_t input_data = GPIO_ReadInputDataBit(GPIO_CUST_ADV_PIN); + APP_PRINT_INFO2("[cust_adv_pin_handler] cur level:%d, trig level:%d", input_data, + cust_button.trig_level); + if (cust_button.trig_level == input_data) + { + cust_button_int_handler(input_data); + } + + GPIO_ClearINTPendingBit(GPIO_CUST_ADV_PIN); + GPIO_MaskINTConfig(GPIO_CUST_ADV_PIN, DISABLE); +} +#endif + +/****************************************************************** + * @brief gpio key enter DLPS config + */ +void gpio_key_enter_dlps_config(void) +{ + if (trigger_button.trig_level == GPIO_KEY_LEVEL_0) + { + System_WakeUpPinEnable(TRIGGER_BUTTON, PAD_WAKEUP_POL_LOW, PAD_WK_DEBOUNCE_DISABLE, 0); + } + else + { + System_WakeUpPinEnable(TRIGGER_BUTTON, PAD_WAKEUP_POL_HIGH, PAD_WK_DEBOUNCE_DISABLE, 0); + } + + Pad_Config(TRIGGER_BUTTON, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + +#if SUPPORT_CUSTOMIZED_APP + if (cust_button.trig_level == GPIO_KEY_LEVEL_0) + { + System_WakeUpPinEnable(CUST_ADV_PIN, PAD_WAKEUP_POL_LOW, PAD_WK_DEBOUNCE_DISABLE, 0); + } + else + { + System_WakeUpPinEnable(CUST_ADV_PIN, PAD_WAKEUP_POL_HIGH, PAD_WK_DEBOUNCE_DISABLE, 0); + } + Pad_Config(CUST_ADV_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); +#endif +} + +/****************************************************************** + * @brief gpio key exit DLPS config + */ +void gpio_key_exit_dlps_config(void) +{ + Pad_Config(TRIGGER_BUTTON, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + +#if SUPPORT_CUSTOMIZED_APP + Pad_Config(CUST_ADV_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); +#endif +} + diff --git a/src/app/findmy/fmna_peripheral/key_handle.h b/src/app/findmy/fmna_peripheral/key_handle.h new file mode 100644 index 0000000..27934c0 --- /dev/null +++ b/src/app/findmy/fmna_peripheral/key_handle.h @@ -0,0 +1,67 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file key_handle.h +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-01 +* @version v1.0 +********************************************************************************************************* +*/ +#ifndef _key_handle_h_ +#define _key_handle_h_ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "board.h" +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + IDLE, + PRESSED, +} T_BUTTON_STATE; + +typedef enum +{ + GPIO_KEY_LEVEL_0, + GPIO_KEY_LEVEL_1, +} T_TRIGGER_LEVEL; + +typedef struct +{ + T_TRIGGER_LEVEL trig_level; + T_BUTTON_STATE state; + uint32_t pressed_time; +} T_BUTTON; + +/*============================================================================* + * Global Variables + *============================================================================*/ +extern void *gpio_key_debounce_timer; + +/*============================================================================* + * Global Functions + *============================================================================*/ +void gpio_board_init(void); +void gpio_driver_init(void); +void trig_button_handler(void); +void gpio_key_enter_dlps_config(void); +void gpio_key_exit_dlps_config(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/fmna_peripheral/url_ndef.c b/src/app/findmy/fmna_peripheral/url_ndef.c new file mode 100644 index 0000000..385d7cb --- /dev/null +++ b/src/app/findmy/fmna_peripheral/url_ndef.c @@ -0,0 +1,422 @@ + +/* Includes ------------------------------------------------------------------*/ +#include "url_ndef.h" +#include "trace.h" + +uint8_t NDEF_Buffer[400]; +uint16_t NDEF_length; + +/** @defgroup libURI_Private_Functions + * @{ + */ +/** + * @brief This function read the URI information and store data in a structure. + * @param pRecordStruct : Pointer on the record structure. + * @param pURI : pointer on the structure to fill. + */ +void NDEF_Parse_WellKnowType(sRecordInfo_t *pRecordStruct, sURI_Info *pURI) +{ + uint32_t PayloadSize; + uint8_t Offset; + uint8_t *pPayload; + + pPayload = (uint8_t *)(pRecordStruct->PayloadBufferAdd); + + switch (*pPayload) + { + case URI_ID_0x01: + memcpy(pURI->protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING)); + Offset = strlen(URI_ID_0x01_STRING); + break; + + case URI_ID_0x02: + memcpy(pURI->protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING)); + Offset = strlen(URI_ID_0x02_STRING); + break; + + case URI_ID_0x03: + memcpy(pURI->protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING)); + Offset = strlen(URI_ID_0x03_STRING); + break; + + case URI_ID_0x04: + memcpy(pURI->protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING)); + Offset = strlen(URI_ID_0x04_STRING); + break; + + case URI_ID_0x05: + memcpy(pURI->protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING)); + Offset = strlen(URI_ID_0x05_STRING); + break; + + case URI_ID_0x06: + memcpy(pURI->protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING)); + Offset = strlen(URI_ID_0x06_STRING); + break; + + case URI_ID_0x07: + memcpy(pURI->protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING)); + Offset = strlen(URI_ID_0x07_STRING); + break; + + case URI_ID_0x08: + memcpy(pURI->protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING)); + Offset = strlen(URI_ID_0x08_STRING); + break; + + case URI_ID_0x09: + memcpy(pURI->protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING)); + Offset = strlen(URI_ID_0x09_STRING); + break; + + case URI_ID_0x0A: + memcpy(pURI->protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING)); + Offset = strlen(URI_ID_0x0A_STRING); + break; + + case URI_ID_0x0B: + memcpy(pURI->protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING)); + Offset = strlen(URI_ID_0x0B_STRING); + break; + + case URI_ID_0x0C: + memcpy(pURI->protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING)); + Offset = strlen(URI_ID_0x0C_STRING); + break; + + case URI_ID_0x0D: + memcpy(pURI->protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING)); + Offset = strlen(URI_ID_0x0D_STRING); + break; + + case URI_ID_0x0E: + memcpy(pURI->protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING)); + Offset = strlen(URI_ID_0x0E_STRING); + break; + + case URI_ID_0x0F: + memcpy(pURI->protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING)); + Offset = strlen(URI_ID_0x0F_STRING); + break; + + case URI_ID_0x10: + memcpy(pURI->protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING)); + Offset = strlen(URI_ID_0x10_STRING); + break; + + case URI_ID_0x11: + memcpy(pURI->protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING)); + Offset = strlen(URI_ID_0x11_STRING); + break; + + case URI_ID_0x12: + memcpy(pURI->protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING)); + Offset = strlen(URI_ID_0x12_STRING); + break; + + case URI_ID_0x13: + memcpy(pURI->protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING)); + Offset = strlen(URI_ID_0x13_STRING); + break; + + case URI_ID_0x14: + memcpy(pURI->protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING)); + Offset = strlen(URI_ID_0x14_STRING); + break; + + case URI_ID_0x15: + memcpy(pURI->protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING)); + Offset = strlen(URI_ID_0x15_STRING); + break; + + case URI_ID_0x16: + memcpy(pURI->protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING)); + Offset = strlen(URI_ID_0x16_STRING); + break; + + case URI_ID_0x17: + memcpy(pURI->protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING)); + Offset = strlen(URI_ID_0x17_STRING); + break; + + case URI_ID_0x18: + memcpy(pURI->protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING)); + Offset = strlen(URI_ID_0x18_STRING); + break; + + case URI_ID_0x19: + memcpy(pURI->protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING)); + Offset = strlen(URI_ID_0x19_STRING); + break; + + case URI_ID_0x1A: + memcpy(pURI->protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING)); + Offset = strlen(URI_ID_0x1A_STRING); + break; + + case URI_ID_0x1B: + memcpy(pURI->protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING)); + Offset = strlen(URI_ID_0x1B_STRING); + break; + + case URI_ID_0x1C: + memcpy(pURI->protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING)); + Offset = strlen(URI_ID_0x1C_STRING); + break; + + case URI_ID_0x1D: + memcpy(pURI->protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING)); + Offset = strlen(URI_ID_0x1D_STRING); + break; + + case URI_ID_0x1E: + memcpy(pURI->protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING)); + Offset = strlen(URI_ID_0x1E_STRING); + break; + + case URI_ID_0x1F: + memcpy(pURI->protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING)); + Offset = strlen(URI_ID_0x1F_STRING); + break; + + case URI_ID_0x20: + memcpy(pURI->protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING)); + Offset = strlen(URI_ID_0x20_STRING); + break; + + case URI_ID_0x21: + memcpy(pURI->protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING)); + Offset = strlen(URI_ID_0x21_STRING); + break; + + case URI_ID_0x22: + memcpy(pURI->protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING)); + Offset = strlen(URI_ID_0x22_STRING); + break; + + case URI_ID_0x23: + memcpy(pURI->protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING)); + Offset = strlen(URI_ID_0x23_STRING); + break; + + default: + Offset = 0; + /* Should not happened */ + break; + } + /* add end of string character */ + pURI->protocol[Offset] = '\0'; + + pPayload++; /* go after well know byte */ + + PayloadSize = pRecordStruct->PayloadLength; + + PayloadSize = PayloadSize - 1; /* remove well know byte */ + + memcpy(pURI->URI_Message, pPayload, PayloadSize); + /* add end of string character */ + pURI->URI_Message[PayloadSize] = '\0'; + +} + + + +/** + * @brief This function prepare the NDEF message with the URI data given in the structure. + * @param pURI : pointer on structure that contain the URI information. + * @param pNDEFMessage : pointer on the NDEF message. + * @param size : to store the size of the NDEF message generated. + */ +void NDEF_PrepareURIMessage(sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size) +{ + uint32_t uriSize, totalSize, Offset = 0; + uint32_t infoSize = 0; + char type; + + /* An URI can be included in a smart poster to add text to give instruction to user for instance */ + + /* URI (smart poster) Record Header */ + /************************************/ + /* 7 | 6 | 5 | 4 | 3 | 2 1 0 */ + /*----------------------------------*/ + /* MB ME CF SR IL TNF */ /* <---- CF=0, IL=0 and SR=1 TNF=1 NFC Forum Well-known type*/ + /*----------------------------------*/ + /* TYPE LENGTH */ + /*----------------------------------*/ + /* PAYLOAD LENGTH 3 */ /* <---- Used only if SR=0 */ + /*----------------------------------*/ + /* PAYLOAD LENGTH 2 */ /* <---- Used only if SR=0 */ + /*----------------------------------*/ + /* PAYLOAD LENGTH 1 */ /* <---- Used only if SR=0 */ + /*----------------------------------*/ + /* PAYLOAD LENGTH 0 */ + /*----------------------------------*/ + /* ID LENGTH */ /* <---- Not Used */ + /*----------------------------------*/ + /* TYPE */ + /*----------------------------------*/ + /* ID */ /* <---- Not Used */ + /************************************/ + + /* We need to know the URI type in order to define if an abreviation is available */ + type = getUriType(pURI->protocol); + + /* URI : 1+URI for abreviate protocol*/ + if (type != URI_ID_0x00) + { + uriSize = 1 + strlen(pURI->URI_Message); + } + else /*: 1+protocol+URI else*/ + { + uriSize = 1 + strlen(pURI->protocol) + strlen(pURI->URI_Message); + } + + /* Check if a Smart poster is needed */ + if (pURI->Information[0] != '\0') + { + /* Info : 1+2+info */ + infoSize = 1 + ISO_ENGLISH_CODE_STRING_LENGTH + strlen(pURI->Information); + /* Total */ + totalSize = 4 + uriSize + 4 + infoSize; + if (uriSize > 255) { totalSize += 3; } /* Normal URI size */ + if (infoSize > 255) { totalSize += 3; } /* Normal Info size */ + + /* SmartPoster header */ + if (totalSize > 255) + { + pNDEFMessage[Offset++] = 0xC1; + pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH; + pNDEFMessage[Offset++] = (totalSize & 0xFF000000) >> 24; + pNDEFMessage[Offset++] = (totalSize & 0x00FF0000) >> 16; + pNDEFMessage[Offset++] = (totalSize & 0x0000FF00) >> 8; + pNDEFMessage[Offset++] = totalSize & 0x000000FF; + } + else + { + pNDEFMessage[Offset++] = 0xD1; + pNDEFMessage[Offset++] = SMART_POSTER_TYPE_STRING_LENGTH; + pNDEFMessage[Offset++] = (uint8_t)totalSize; + } + memcpy(&pNDEFMessage[Offset], SMART_POSTER_TYPE_STRING, SMART_POSTER_TYPE_STRING_LENGTH); + Offset += SMART_POSTER_TYPE_STRING_LENGTH; + } + + /* URI header */ + pNDEFMessage[Offset] = 0x81; + if (uriSize < 256) { pNDEFMessage[Offset] |= SR_Mask; } // Set the SR bit + if (pURI->Information[0] == '\0') { pNDEFMessage[Offset] |= ME_Mask; } // Set the ME bit + Offset++; + + pNDEFMessage[Offset++] = URI_TYPE_STRING_LENGTH; + if (uriSize > 255) + { + pNDEFMessage[Offset++] = (uriSize & 0xFF000000) >> 24; + pNDEFMessage[Offset++] = (uriSize & 0x00FF0000) >> 16; + pNDEFMessage[Offset++] = (uriSize & 0x0000FF00) >> 8; + pNDEFMessage[Offset++] = uriSize & 0x000000FF; + } + else + { + pNDEFMessage[Offset++] = (uint8_t)uriSize; + } + memcpy(&pNDEFMessage[Offset], URI_TYPE_STRING, URI_TYPE_STRING_LENGTH); + Offset += URI_TYPE_STRING_LENGTH; + + pNDEFMessage[Offset++] = type; + if (type == URI_ID_0x00) // No abreviation + { + memcpy(&pNDEFMessage[Offset], pURI->protocol, strlen(pURI->protocol)); + Offset += strlen(pURI->protocol); + } + + memcpy(&pNDEFMessage[Offset], pURI->URI_Message, strlen(pURI->URI_Message)); + Offset += strlen(pURI->URI_Message); + + /* Information header */ + if (pURI->Information[0] != '\0') + { + if (infoSize > 255) + { + pNDEFMessage[Offset++] = 0x41; + pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH; + pNDEFMessage[Offset++] = (infoSize & 0xFF000000) >> 24; + pNDEFMessage[Offset++] = (infoSize & 0x00FF0000) >> 16; + pNDEFMessage[Offset++] = (infoSize & 0x0000FF00) >> 8; + pNDEFMessage[Offset++] = infoSize & 0x000000FF; + } + else + { + pNDEFMessage[Offset++] = 0x51; + pNDEFMessage[Offset++] = TEXT_TYPE_STRING_LENGTH; + pNDEFMessage[Offset++] = (uint8_t)infoSize; + } + + memcpy(&pNDEFMessage[Offset], TEXT_TYPE_STRING, TEXT_TYPE_STRING_LENGTH); + Offset += TEXT_TYPE_STRING_LENGTH; + pNDEFMessage[Offset++] = ISO_ENGLISH_CODE_STRING_LENGTH; /* UTF-8 with x byte language code */ + memcpy(&pNDEFMessage[Offset], ISO_ENGLISH_CODE_STRING, ISO_ENGLISH_CODE_STRING_LENGTH); + Offset += ISO_ENGLISH_CODE_STRING_LENGTH; + + /* Information payload */ + memcpy(&pNDEFMessage[Offset], pURI->Information, strlen(pURI->Information)); + Offset += strlen(pURI->Information); + } + + *size = Offset; + +} + + +char getUriType(char *protocol) +{ + if (!memcmp(protocol, URI_ID_0x01_STRING, strlen(URI_ID_0x01_STRING))) { return URI_ID_0x01; } + else if (!memcmp(protocol, URI_ID_0x02_STRING, strlen(URI_ID_0x02_STRING))) { return URI_ID_0x02; } + else if (!memcmp(protocol, URI_ID_0x03_STRING, strlen(URI_ID_0x03_STRING))) { return URI_ID_0x03; } + else if (!memcmp(protocol, URI_ID_0x04_STRING, strlen(URI_ID_0x04_STRING))) { return URI_ID_0x04; } + else if (!memcmp(protocol, URI_ID_0x05_STRING, strlen(URI_ID_0x05_STRING))) { return URI_ID_0x05; } + else if (!memcmp(protocol, URI_ID_0x06_STRING, strlen(URI_ID_0x06_STRING))) { return URI_ID_0x06; } + else if (!memcmp(protocol, URI_ID_0x07_STRING, strlen(URI_ID_0x07_STRING))) { return URI_ID_0x07; } + else if (!memcmp(protocol, URI_ID_0x08_STRING, strlen(URI_ID_0x08_STRING))) { return URI_ID_0x08; } + else if (!memcmp(protocol, URI_ID_0x09_STRING, strlen(URI_ID_0x09_STRING))) { return URI_ID_0x09; } + else if (!memcmp(protocol, URI_ID_0x0A_STRING, strlen(URI_ID_0x0A_STRING))) { return URI_ID_0x0A; } + else if (!memcmp(protocol, URI_ID_0x0B_STRING, strlen(URI_ID_0x0B_STRING))) { return URI_ID_0x0B; } + else if (!memcmp(protocol, URI_ID_0x0C_STRING, strlen(URI_ID_0x0C_STRING))) { return URI_ID_0x0C; } + else if (!memcmp(protocol, URI_ID_0x0D_STRING, strlen(URI_ID_0x0D_STRING))) { return URI_ID_0x0D; } + else if (!memcmp(protocol, URI_ID_0x0E_STRING, strlen(URI_ID_0x0E_STRING))) { return URI_ID_0x0E; } + else if (!memcmp(protocol, URI_ID_0x0F_STRING, strlen(URI_ID_0x0F_STRING))) { return URI_ID_0x0F; } + else if (!memcmp(protocol, URI_ID_0x10_STRING, strlen(URI_ID_0x10_STRING))) { return URI_ID_0x10; } + else if (!memcmp(protocol, URI_ID_0x11_STRING, strlen(URI_ID_0x11_STRING))) { return URI_ID_0x11; } + else if (!memcmp(protocol, URI_ID_0x12_STRING, strlen(URI_ID_0x12_STRING))) { return URI_ID_0x12; } + else if (!memcmp(protocol, URI_ID_0x13_STRING, strlen(URI_ID_0x13_STRING))) { return URI_ID_0x13; } + else if (!memcmp(protocol, URI_ID_0x14_STRING, strlen(URI_ID_0x14_STRING))) { return URI_ID_0x14; } + else if (!memcmp(protocol, URI_ID_0x15_STRING, strlen(URI_ID_0x15_STRING))) { return URI_ID_0x15; } + else if (!memcmp(protocol, URI_ID_0x16_STRING, strlen(URI_ID_0x16_STRING))) { return URI_ID_0x16; } + else if (!memcmp(protocol, URI_ID_0x17_STRING, strlen(URI_ID_0x17_STRING))) { return URI_ID_0x17; } + else if (!memcmp(protocol, URI_ID_0x18_STRING, strlen(URI_ID_0x18_STRING))) { return URI_ID_0x18; } + else if (!memcmp(protocol, URI_ID_0x19_STRING, strlen(URI_ID_0x19_STRING))) { return URI_ID_0x19; } + else if (!memcmp(protocol, URI_ID_0x1A_STRING, strlen(URI_ID_0x1A_STRING))) { return URI_ID_0x1A; } + else if (!memcmp(protocol, URI_ID_0x1B_STRING, strlen(URI_ID_0x1B_STRING))) { return URI_ID_0x1B; } + else if (!memcmp(protocol, URI_ID_0x1C_STRING, strlen(URI_ID_0x1C_STRING))) { return URI_ID_0x1C; } + else if (!memcmp(protocol, URI_ID_0x1D_STRING, strlen(URI_ID_0x1D_STRING))) { return URI_ID_0x1D; } + else if (!memcmp(protocol, URI_ID_0x1E_STRING, strlen(URI_ID_0x1E_STRING))) { return URI_ID_0x1E; } + else if (!memcmp(protocol, URI_ID_0x1F_STRING, strlen(URI_ID_0x1F_STRING))) { return URI_ID_0x1F; } + else if (!memcmp(protocol, URI_ID_0x20_STRING, strlen(URI_ID_0x20_STRING))) { return URI_ID_0x20; } + else if (!memcmp(protocol, URI_ID_0x21_STRING, strlen(URI_ID_0x21_STRING))) { return URI_ID_0x21; } + else if (!memcmp(protocol, URI_ID_0x22_STRING, strlen(URI_ID_0x22_STRING))) { return URI_ID_0x22; } + else if (!memcmp(protocol, URI_ID_0x23_STRING, strlen(URI_ID_0x23_STRING))) { return URI_ID_0x23; } + else { return URI_ID_0x00; } // No abreviation for this protocol +} + +void NDEF_URIInit(uint8_t *uri, uint32_t uri_len) +{ + sURI_Info fmna_uri = {URI_ID_0x04_STRING, "", ""}; + memcpy(fmna_uri.URI_Message, uri, uri_len); + APP_PRINT_INFO2("NDEF URI: %s%s", TRACE_STRING(fmna_uri.protocol), + TRACE_STRING(fmna_uri.URI_Message)); + + NDEF_PrepareURIMessage(&fmna_uri, &NDEF_Buffer[2], &NDEF_length); + NDEF_Buffer[0] = 0x03; + memcpy(&NDEF_Buffer[1], &NDEF_length, 1); + APP_PRINT_INFO2("NDEF Record Length: %d, Header: %b", NDEF_length, TRACE_BINARY(10, NDEF_Buffer)); +} + diff --git a/src/app/findmy/fmna_peripheral/url_ndef.h b/src/app/findmy/fmna_peripheral/url_ndef.h new file mode 100644 index 0000000..704f03e --- /dev/null +++ b/src/app/findmy/fmna_peripheral/url_ndef.h @@ -0,0 +1,227 @@ +#ifndef _url_ndef_h_ +#define _url_ndef_h_ + +#include "stdint.h" +#include + + +#define MAX_NDEF_MEM ((uint32_t)0xC00) +#define NFC_DEVICE_MAX_NDEFMEMORY ((uint32_t)MAX_NDEF_MEM) + + +#define NDEF_OK RESULTOK + +#define NDEF_ERROR_MEMORY_TAG 2 +#define NDEF_ERROR_MEMORY_INTERNAL 3 +#define NDEF_ERROR_LOCKED 4 +#define NDEF_ERROR_NOT_FORMATED 5 + + +// #define NDEF_RECORD_MAX_SIZE (512) + +#define NDEF_SIZE_OFFSET 0 +#define FIRST_RECORD_OFFSET 0 + +#define RECORD_FLAG_FIELD 1 +#define TYPE_LENGTH_FIELD 1 +#define ID_LENGTH_FIELD 1 +#define MB_Mask ((uint8_t)(0x80)) +#define ME_Mask ((uint8_t)(0x40)) +#define CF_Mask ((uint8_t)(0x20)) +#define SR_Mask ((uint8_t)(0x10)) +#define IL_Mask ((uint8_t)(0x08)) +#define TNF_Mask ((uint8_t)(0x07)) + +#define TNF_Empty 0x00 +#define TNF_WellKnown 0x01 +#define TNF_MediaType 0x02 +#define TNF_AbsoluteURI 0x03 +#define TNF_NFCForumExternal 0x04 +#define TNF_Unknown 0x05 +#define TNF_Unchanged 0x06 +#define TNF_Reserved 0x07 + +#define SP_MAX_RECORD 4 + +#define AAR_TYPE_STRING "android.com:pkg" +#define AAR_TYPE_STRING_LENGTH 15 + +#define M24SR_DISCOVERY_APP_STRING "st.com:m24sr_discovery_democtrl" +#define M24SR_DISCOVERY_APP_STRING_LENGTH 31 + +#define VCARD_TYPE_STRING "text/vcard" +#define VCARD_TYPE_STRING_LENGTH 10 + +#define XVCARD_TYPE_STRING "text/x-vCard" +#define XVCARD_TYPE_STRING_LENGTH 12 + +#define XVCARD2_TYPE_STRING "text/x-vcard" +#define XVCARD2_TYPE_STRING_LENGTH 12 + +#define SMART_POSTER_TYPE_STRING "Sp" +#define SMART_POSTER_TYPE_STRING_LENGTH 2 + +#define URI_TYPE_STRING "U" +#define URI_TYPE_STRING_LENGTH 1 + +#define SMS_TYPE_STRING "sms:" +#define SMS_TYPE_STRING_LENGTH 4 + +#define GEO_TYPE_STRING "geo:" +#define GEO_TYPE_STRING_LENGTH 4 + +#define URI_LATITUDE_END "," +#define URI_LATITUDE_END_LENGTH 1 + +#define EMAIL_TYPE_STRING "mailto:" +#define EMAIL_TYPE_STRING_LENGTH 7 + +#define URI_FIRST_DATA_END "?" +#define URI_FIRST_DATA_END_LENGTH 1 + +#define SUBJECT_BEGIN_STRING "subject=" +#define SUBJECT_BEGIN_STRING_LENGTH 8 + +#define MESSAGE_BEGIN_STRING "body=" +#define MESSAGE_BEGIN_STRING_LENGTH 5 + +#define URI_SECOND_DATA_END "&" +#define URI_SECOND_DATA_END_LENGTH 1 + +#define TEXT_TYPE_STRING "T" +#define TEXT_TYPE_STRING_LENGTH 1 + +#define ISO_ENGLISH_CODE_STRING "en" +#define ISO_ENGLISH_CODE_STRING_LENGTH 2 + + +#define URI_ID_0x00 0x00 +#define URI_ID_0x01 0x01 +#define URI_ID_0x02 0x02 +#define URI_ID_0x03 0x03 +#define URI_ID_0x04 0x04 +#define URI_ID_0x05 0x05 +#define URI_ID_0x06 0x06 +#define URI_ID_0x07 0x07 +#define URI_ID_0x08 0x08 +#define URI_ID_0x09 0x09 +#define URI_ID_0x0A 0x0A +#define URI_ID_0x0B 0x0B +#define URI_ID_0x0C 0x0C +#define URI_ID_0x0D 0x0D +#define URI_ID_0x0E 0x0E +#define URI_ID_0x0F 0x0F +#define URI_ID_0x10 0x10 +#define URI_ID_0x11 0x11 +#define URI_ID_0x12 0x12 +#define URI_ID_0x13 0x13 +#define URI_ID_0x14 0x14 +#define URI_ID_0x15 0x15 +#define URI_ID_0x16 0x16 +#define URI_ID_0x17 0x17 +#define URI_ID_0x18 0x18 +#define URI_ID_0x19 0x19 +#define URI_ID_0x1A 0x1A +#define URI_ID_0x1B 0x1B +#define URI_ID_0x1C 0x1C +#define URI_ID_0x1D 0x1D +#define URI_ID_0x1E 0x1E +#define URI_ID_0x1F 0x1F +#define URI_ID_0x20 0x20 +#define URI_ID_0x21 0x21 +#define URI_ID_0x22 0x22 +#define URI_ID_0x23 0x23 +#define URI_RFU 0x24 + +#define URI_ID_0x01_STRING "http://www.\0" +#define URI_ID_0x02_STRING "https://www.\0" +#define URI_ID_0x03_STRING "http://\0" +#define URI_ID_0x04_STRING "https://\0" +#define URI_ID_0x05_STRING "tel:\0" +#define URI_ID_0x06_STRING "mailto:\0" +#define URI_ID_0x07_STRING "ftp://anonymous:anonymous@\0" +#define URI_ID_0x08_STRING "ftp://ftp.\0" +#define URI_ID_0x09_STRING "ftps://\0" +#define URI_ID_0x0A_STRING "sftp://\0" +#define URI_ID_0x0B_STRING "smb://\0" +#define URI_ID_0x0C_STRING "nfs://\0" +#define URI_ID_0x0D_STRING "ftp://\0" +#define URI_ID_0x0E_STRING "dav://\0" +#define URI_ID_0x0F_STRING "news:\0" +#define URI_ID_0x10_STRING "telnet://\0" +#define URI_ID_0x11_STRING "imap:\0" +#define URI_ID_0x12_STRING "rtsp://\0" +#define URI_ID_0x13_STRING "urn:\0" +#define URI_ID_0x14_STRING "pop:\0" +#define URI_ID_0x15_STRING "sip:\0" +#define URI_ID_0x16_STRING "sips:\0" +#define URI_ID_0x17_STRING "tftp:\0" +#define URI_ID_0x18_STRING "btspp://\0" +#define URI_ID_0x19_STRING "btl2cap://\0" +#define URI_ID_0x1A_STRING "btgoep://\0" +#define URI_ID_0x1B_STRING "tcpobex://\0" +#define URI_ID_0x1C_STRING "irdaobex://\0" +#define URI_ID_0x1D_STRING "file://\0" +#define URI_ID_0x1E_STRING "urn:epc:id:\0" +#define URI_ID_0x1F_STRING "urn:epc:tag\0" +#define URI_ID_0x20_STRING "urn:epc:pat:\0" +#define URI_ID_0x21_STRING "urn:epc:raw:\0" +#define URI_ID_0x22_STRING "urn:epc:\0" +#define URI_ID_0x23_STRING "urn:nfc:\0" + + +// exported variables +extern uint8_t NDEF_Buffer[400]; +extern uint16_t NDEF_length; + +typedef enum +{ + UNKNOWN_TYPE = 0, + VCARD_TYPE, + WELL_KNOWN_ABRIDGED_URI_TYPE, + URI_SMS_TYPE, + URI_GEO_TYPE, + URI_EMAIL_TYPE, + SMARTPOSTER_TYPE, + URL_TYPE, + TEXT_TYPE, + HANDOVER_TYPE, + /* list of "external type" known by this demo, other external type will be addressed as UNKNWON_TYPE */ + M24SR_DISCOVERY_APP_TYPE, + BT_TYPE, + BLE_TYPE, + URI_WIFITOKEN_TYPE +} NDEF_TypeDef; + +typedef struct sRecordInfo sRecordInfo_t; + +struct sRecordInfo +{ + uint8_t RecordFlags; + uint8_t TypeLength; + uint32_t PayloadLength; + uint8_t IDLength; + uint8_t Type[0xFF]; + uint8_t ID[0xFF]; + uint16_t PayloadOffset; + uint8_t *PayloadBufferAdd; /* add where payload content has been stored */ + NDEF_TypeDef NDEF_Type; /* to store identification ID for application */ + sRecordInfo_t + *SPRecordStructAdd[SP_MAX_RECORD]; /*in case of smart poster array to store add of other sRecordInfo struct */ + uint8_t NbOfRecordInSPPayload; +}; + +typedef struct +{ + char protocol[80]; + char URI_Message[400]; + char Information[400]; +} sURI_Info; + + +void NDEF_Parse_WellKnowType(sRecordInfo_t *pRecordStruct, sURI_Info *pURI); +void NDEF_PrepareURIMessage(sURI_Info *pURI, uint8_t *pNDEFMessage, uint16_t *size); +char getUriType(char *protocol); +void NDEF_URIInit(uint8_t *uri, uint32_t uri_len); + +#endif diff --git a/src/app/findmy/fmna_platform/fmna_adv_platform.c b/src/app/findmy/fmna_platform/fmna_adv_platform.c new file mode 100644 index 0000000..9761995 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_adv_platform.c @@ -0,0 +1,290 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_adv_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "string.h" +#include "trace.h" +#include "gap.h" +#include "gap_adv.h" +#include "gap_bond_le.h" +#include "gap_config.h" +#include "fmna_gatt_platform.h" +#include "fmna_constants_platform.h" +#include "fmna_constants.h" +#include "fmna_util.h" +#include "fmna_adv.h" +#include "fmna_gap_platform.h" +#include "fmna_adv_platform.h" + +/*============================================================================* + * Macros + *============================================================================*/ +#define SERVICE_DATA_OFFSET (4) +#define MANU_DATA_OFFSET (4) + +/*============================================================================* + * Local Variables + *============================================================================*/ +static uint32_t fmna_fast_adv_duration = 0; +static uint16_t fmna_fast_adv_interval = 0; +static uint32_t fmna_slow_adv_duration = 0; +static uint16_t fmna_slow_adv_interval = 0; + +static T_ADV_DATA fmna_adv; + +/** @brief GAP - Advertisement data (max size = 31 bytes, best kept short to conserve power) */ +static uint8_t pairing_adv_data[29] = +{ + /* Flags */ + 0x18, /* length */ + GAP_ADTYPE_SERVICE_DATA, /* type="Flags" */ + LO_WORD(FINDMY_UUID_SERVICE), + HI_WORD(FINDMY_UUID_SERVICE), +}; + +static uint8_t nearby_adv_data[31] = +{ + 0x03, + GAP_ADTYPE_MANUFACTURER_SPECIFIC, + (uint8_t)FMNA_COMPANY_IDENTIFIER, + (uint8_t)(FMNA_COMPANY_IDENTIFIER >> 8), +}; + +static uint8_t separate_adv_data[31] = +{ + 0x03, + GAP_ADTYPE_MANUFACTURER_SPECIFIC, + (uint8_t)FMNA_COMPANY_IDENTIFIER, + (uint8_t)(FMNA_COMPANY_IDENTIFIER >> 8), +}; + +/*============================================================================* + * Local Functions + *============================================================================*/ +static void fmna_adv_init(void) +{ + fmna_adv.p_scan_rsp_data = NULL; + fmna_adv.scan_rsp_data_len = 0; + fmna_adv.adv_type = GAP_ADTYPE_ADV_IND; +} + +/** + * @brief Initialize peripheral and gap bond manager related parameters + * @return void + */ +static void fmna_le_gap_init(void) +{ + /* Device name and device appearance */ + uint8_t device_name[] = "SDD Finder-2*"; + uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN; + uint8_t slave_init_mtu_req = false; + + /* Advertising parameters */ + uint8_t adv_direct_type = GAP_LOCAL_ADDR_LE_PUBLIC; + uint8_t adv_direct_addr[8] = {0}; + uint8_t adv_chann_map = GAP_ADVCHAN_ALL; + uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY; + + /* GAP Bond Manager parameters */ + uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE; + uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG; + uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT; + uint8_t auth_use_fix_passkey = false; + uint32_t auth_fix_passkey = 0; + uint8_t gap_param_key_manager = 2; + uint8_t auth_sec_req_enable = false; + uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG; + uint8_t irk_auto = true; + + /* Set device name and device appearance */ + le_set_gap_param(GAP_PARAM_DEVICE_NAME, sizeof(device_name), device_name); + le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance); + le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req), + &slave_init_mtu_req); + + /* Set advertising parameters */ + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, 6, adv_direct_addr); + le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map); + le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy); + + /* Setup the GAP Bond Manager */ + gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode); + gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags); + gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey), + &auth_use_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enable), &auth_sec_req_enable); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags), + &auth_sec_req_flags); + le_bond_set_param(GAP_PARAM_BOND_KEY_MANAGER, sizeof(gap_param_key_manager), + &gap_param_key_manager); + le_bond_set_param(GAP_PARAM_BOND_GEN_LOCAL_IRK_AUTO, sizeof(uint8_t), &irk_auto); + + /* register gap message callback */ + le_register_app_cb(app_gap_callback); + + gap_config_le_key_storage_flag(0xFF & (~LE_KEY_STORE_CCCD_DATA_BIT)); +} + +/*============================================================================* + * Global Functions + *============================================================================*/ +void fmna_adv_platform_get_default_bt_addr(uint8_t default_bt_addr[FMNA_BLE_MAC_ADDR_BLEN]) +{ + uint16_t error_line = 0; + T_GAP_CAUSE ret = le_gen_rand_addr(GAP_RAND_ADDR_STATIC, default_bt_addr); + __GAP_RET_CHECK(ret, fail); + + reverse_array(default_bt_addr, 0, FMNA_BLE_MAC_ADDR_BLEN - 1); //LSB + return; +fail: + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); +} + +void fmna_adv_platform_set_random_static_bt_addr(uint8_t new_bt_mac[FMNA_BLE_MAC_ADDR_BLEN]) +{ + reverse_array(new_bt_mac, 0, FMNA_BLE_MAC_ADDR_BLEN - 1); + APP_PRINT_INFO1("fmna_adv_platform_set_random_static_bt_addr: %s", TRACE_BDADDR(new_bt_mac)); +#if ONE_SHOT_ADV_EN + one_shot_bt_addr_set(new_bt_mac, GAP_LOCAL_ADDR_LE_RANDOM, ADV_DATA_FINDMY); +#else + uint16_t error_line = 0; + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + + uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM; + ret = le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + __GAP_RET_CHECK(ret, fail); + ret = le_set_rand_addr(new_bt_mac); + __GAP_RET_CHECK(ret, fail); + return; +fail: + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); +#endif +} + +void fmna_adv_platform_start_fast_adv(void) +{ +#if SUPPORT_BAT_DETECT_FEATURE + if (app_global_data.low_power_mode) + { + APP_PRINT_INFO0("[fmna_adv_platform_start_fast_adv]failure, low power mode"); + return; + } +#endif + fmna_adv.adv_interval = fmna_fast_adv_interval; + fmble_gap_adv_data_set(fmna_adv, ADV_DATA_FINDMY); + fmble_gap_adv_start(ADV_DATA_FINDMY); + if (fmna_fast_adv_duration > 0) + { + os_timer_restart(&adv_timer, fmna_fast_adv_duration * 10); + } +} + +void fmna_adv_platform_start_slow_adv(void) +{ +#if SUPPORT_BAT_DETECT_FEATURE + if (app_global_data.low_power_mode) + { + APP_PRINT_INFO0("[fmna_adv_platform_start_slow_adv]failure, low power mode"); + return; + } +#endif + fmna_adv.adv_interval = fmna_slow_adv_interval; + fmble_gap_adv_data_set(fmna_adv, ADV_DATA_FINDMY); + fmble_gap_adv_start(ADV_DATA_FINDMY); + if (fmna_slow_adv_duration > 0) + { + os_timer_restart(&adv_timer, fmna_slow_adv_duration * 10); + } +} + +void fmna_adv_platform_stop_adv(void) +{ + fmble_gap_adv_stop(ADV_DATA_FINDMY); + uint32_t adv_timer_state = 0xFFFFFFFF; + os_timer_state_get(&adv_timer, &adv_timer_state); + if (adv_timer_state) + { + os_timer_stop(&adv_timer); + } +} + +void fmna_adv_platform_init_pairing(uint8_t *pairing_adv_service_data, + size_t pairing_adv_service_data_size) +{ + fmna_fast_adv_duration = fmna_pairing_adv_fast_duration; + fmna_fast_adv_interval = fmna_pairing_adv_fast_intv; + fmna_slow_adv_duration = fmna_pairing_adv_slow_duration; + fmna_slow_adv_interval = fmna_pairing_adv_slow_intv; + memcpy(pairing_adv_data + SERVICE_DATA_OFFSET, pairing_adv_service_data, + pairing_adv_service_data_size); + fmna_adv.p_adv_data = pairing_adv_data; + fmna_adv.adv_data_len = 25; + APP_PRINT_INFO1("Pairing ADV: %b", TRACE_BINARY(pairing_adv_service_data_size, pairing_adv_data)); +} + +void fmna_adv_platform_init_nearby(uint8_t *nearby_adv_manuf_data, + size_t nearby_adv_manuf_data_size) +{ + fmna_fast_adv_duration = fmna_nearby_adv_fast_duration; + fmna_fast_adv_interval = fmna_nearby_adv_fast_intv; + fmna_slow_adv_duration = fmna_nearby_adv_duration; + fmna_slow_adv_interval = fmna_nearby_adv_intv; + memcpy(nearby_adv_data + MANU_DATA_OFFSET, nearby_adv_manuf_data, nearby_adv_manuf_data_size); + nearby_adv_data[0] = 3 + nearby_adv_manuf_data_size; + fmna_adv.p_adv_data = nearby_adv_data; + fmna_adv.adv_data_len = nearby_adv_manuf_data_size + 4; + APP_PRINT_INFO1("Nearby ADV: %b", TRACE_BINARY(3 + nearby_adv_manuf_data_size + 1, + nearby_adv_data)); +} + + +void fmna_adv_platform_init_separated(uint8_t *separated_adv_manuf_data, + size_t separated_adv_manuf_data_size) +{ + fmna_fast_adv_duration = fmna_separated_adv_fast_duration; + fmna_fast_adv_interval = fmna_separated_adv_fast_intv; + fmna_slow_adv_duration = fmna_separated_adv_slow_duration; + fmna_slow_adv_interval = fmna_separated_adv_slow_intv; + memcpy(separate_adv_data + MANU_DATA_OFFSET, separated_adv_manuf_data, + separated_adv_manuf_data_size); + separate_adv_data[0] = 3 + separated_adv_manuf_data_size; + fmna_adv.p_adv_data = separate_adv_data; + fmna_adv.adv_data_len = separated_adv_manuf_data_size + 4; + APP_PRINT_INFO1("Separated ADV: %b", TRACE_BINARY(3 + separated_adv_manuf_data_size + 1, + separate_adv_data)); +} + +void fmna_ble_platform_init(void) +{ + /* Initialize GAP and set the number of BLE links */ + le_gap_init(APP_MAX_LINKS); + gap_lib_init(); +#if (!ONE_SHOT_ADV_EN) + /* Initialize GAP synchronization interface */ + rtk_gap_task_init(); +#else + /* Initialize one shot advertising */ + one_shot_adv_init(); +#endif + /* Initialize GAP parameters */ + fmna_le_gap_init(); + /* Initialize extended advertising parameters and data */ + fmna_adv_init(); +} + diff --git a/src/app/findmy/fmna_platform/fmna_adv_platform.h b/src/app/findmy/fmna_platform/fmna_adv_platform.h new file mode 100644 index 0000000..20e3298 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_adv_platform.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.’s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_adv_platform_h +#define fmna_adv_platform_h + +#include "fmna_constants.h" +#include "fmna_platform_includes.h" + +#define FMNA_ADV_TX_POWER_DBM 4 /** 4dBm - maximum tx power. */ + +void fmna_adv_platform_get_default_bt_addr(uint8_t default_bt_addr[FMNA_BLE_MAC_ADDR_BLEN]); + +/// Sets Random Static BT MAC address. +/// @param[in] new_bt_mac 6-byte MAC address to set, in MSB first, e.g. +/// new_bt_mac[0] is MSB of MAC address. +void fmna_adv_platform_set_random_static_bt_addr(uint8_t new_bt_mac[FMNA_BLE_MAC_ADDR_BLEN]); + +void fmna_adv_platform_start_fast_adv(void); + +void fmna_adv_platform_start_slow_adv(void); + +/// Stop BLE advertising. +void fmna_adv_platform_stop_adv(void); + +/// Setup Pairing advertisement. +void fmna_adv_platform_init_pairing(uint8_t *pairing_adv_service_data, + size_t pairing_adv_service_data_size); + +/// Setup Separated advertising, +void fmna_adv_platform_init_nearby(uint8_t *nearby_adv_manuf_data, + size_t nearby_adv_manuf_data_size); + +/// Setup Separated advertising. +/// @param[in] separated_adv_manuf_data Separated ADV manufacturer data. +void fmna_adv_platform_init_separated(uint8_t *separated_adv_manuf_data, + size_t separated_adv_manuf_data_size); + +void fmna_ble_platform_init(void); + +#endif /* fmna_adv_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_battery_platform.c b/src/app/findmy/fmna_platform/fmna_battery_platform.c new file mode 100644 index 0000000..8cf1343 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_battery_platform.c @@ -0,0 +1,394 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_battery_platform.c +* @brief battery detection function +* @details +* @author scarlett_liang +* @date 2024-04-26 +* @version v1.1 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "findmy_app.h" +#include "fmna_battery_platform.h" +#include "fmna_adv_platform.h" +#include "fmna_timer_platform.h" +#include "rtl876x_adc.h" +#include "rtl876x_rcc.h" +#if SUPPORT_BAT_LPC_FEATURE +#include "rtl876x_lpc.h" +#include "rtl876x_wdg.h" +#include "rtl876x_nvic.h" +#include "vector_table.h" +#include "app_section.h" +#endif +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE +#include "rtl876x_pinmux.h" +#endif +#if SUPPORT_NFC +#include "fmna_nfc.h" +#endif +#if GFPS_FEATURE_SUPPORT +#include "dult.h" +#endif + +/*============================================================================* + * Local Variables + *============================================================================*/ +static fmna_bat_state_level_t cur_bat_level; +#if SUPPORT_BAT_DETECT_FEATURE +static bool is_adc_efuse_existed; + +/*============================================================================* + * Local functions + *============================================================================*/ +#if SUPPORT_BAT_LPC_FEATURE +static void bat_driver_lpc_init(void); +static void bat_driver_lpc_enter_dlps_config(void); +static void bat_driver_lpc_exit_dlps_config(void); +static void bat_lpc_handler(void) DATA_RAM_FUNCTION; + +/****************************************************************** + * @brief Initialize LPC driver. + * @param none + * @return none + */ +void bat_driver_lpc_init(void) +{ + if (app_global_data.low_power_mode) + { + APP_PRINT_INFO0("[bat_driver_lpc_init] In low power mode. Don't init LPC"); + return; + } + + APP_PRINT_INFO0("[bat_driver_lpc_init] init LPC"); + + LPC_InitTypeDef LPC_InitStruct; + LPC_StructInit(&LPC_InitStruct); + LPC_InitStruct.LPC_Channel = LPC_CHANNEL_VBAT ; + LPC_InitStruct.LPC_Edge = LPC_Vin_Below_Vth ; + LPC_InitStruct.LPC_Threshold = BAT_LPC_COMP_VALUE; + LPC_Init(&LPC_InitStruct); + LPC_Cmd(ENABLE); + RamVectorTableUpdate(LPCOMP_VECTORn, bat_lpc_handler); + + LPC_ResetCounter(); + LPC_SetCompValue(1); + LPC_CounterCmd(ENABLE); + LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT); + LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + + LPC_INTCmd(ENABLE); + + /* Config LPC interrupt */ + NVIC_InitTypeDef NVIC_InitStruct; + NVIC_InitStruct.NVIC_IRQChannel = LPCOMP_IRQn; + NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStruct); +} + +/****************************************************************** + * @brief LPC driver enter dlps config. + * @param none + * @return none + */ +void bat_driver_lpc_enter_dlps_config(void) +{ + LPC_Cmd(DISABLE); + + LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT); + LPC_INTConfig(LPC_INT_LPCOMP_CNT, DISABLE); + + LPC_INTCmd(DISABLE); +} + +/****************************************************************** + * @brief LPC driver exit dlps config. + * @param none + * @return none + */ +void bat_driver_lpc_exit_dlps_config(void) +{ + LPC_Cmd(ENABLE); + + LPC_ResetCounter(); + LPC_SetCompValue(1); + LPC_CounterCmd(ENABLE); + LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT); + LPC_INTConfig(LPC_INT_LPCOMP_CNT, ENABLE); + + LPC_INTCmd(ENABLE); +} + +/****************************************************************** + * @brief lpc interrupt handler function. + * @param none + * @return none + * @retval void + */ +void bat_lpc_handler(void) +{ + DBG_DIRECT("[bat_lpc_handler] LPC lower power triggered!"); + + /* LPC counter comparator interrupt */ + if (LPC_GetFlagStatus(LPC_FLAG_LPCOMP_CNT) == SET) + { + LPC_INTConfig(LPC_INT_LPCOMP_CNT, DISABLE); + LPC_INTCmd(DISABLE); + DBG_DIRECT("[bat_lpc_handler] LPC lower power CNT triggered!"); + LPC_ResetCounter(); + + LPC_ClearINTPendingBit(LPC_INT_LPCOMP_CNT); + WDG_SystemReset(RESET_ALL_EXCEPT_AON, RESET_REASON_LPC_TRIGGER); + } +} +#endif + +/****************************************************************** + * @brief calculate battery level + * @param uint16_t - ADC voltage whose unit is mv. + * @return fmna_bat_state_level_t battery_level + * @retval void + */ +static fmna_bat_state_level_t bat_calculate_bat_level(uint16_t bat_value) +{ + fmna_bat_state_level_t bat_level; + + /*calculate bat level according to bat value*/ + if (bat_value >= 3100) /* >3.1V, 100% */ + { + bat_level = BAT_STATE_FULL; + } + else if (bat_value >= BAT_ENTER_OTA_MODE_THRESHOLD) /* 3.1~2.5V, 100%~30% */ + { + bat_level = BAT_STATE_MEDIUM; + } + else if (bat_value >= BAT_ENTER_LOW_POWER_THRESHOLD) /* 2.5~2.0V, 30%~0% */ + { + bat_level = BAT_STATE_LOW; + } + else /* <2.0V, 0% */ + { + bat_level = BAT_STATE_CRITICALLY_LOW; + } + + return bat_level; +} + +/****************************************************************** + * @brief calculation battery calibration voltage. + * @param data - data read from ADC. + * @return uint16_t - ADC voltage whose unit is mv. + */ +static uint16_t bat_calibrate_voltage(uint16_t data) +{ + float adc_voltage = 0; + ADC_ErrorStatus error_status = NO_ERROR; + if (true == is_adc_efuse_existed) + { +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + adc_voltage = ADC_GetVoltage(BYPASS_SINGLE_MODE, (int32_t)data, &error_status); +#else + adc_voltage = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)data, &error_status); +#endif + if (error_status < 0) + { + APP_PRINT_WARN1("ADC parameter or efuse data error %d!", error_status); + adc_voltage = (float)(((98500 * data) / 100000) - ((374 * data * data) / 100000000) - 62.121); + } + } + else + { + adc_voltage = (float)(((98500 * data) / 100000) - ((374 * data * data) / 100000000) - 62.121); + } + +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + adc_voltage *= VOLTAGE_DIVIDER; +#endif + return (uint16_t)adc_voltage; +} + +/*============================================================================* +* Global functions +*============================================================================*/ +/****************************************************************** + * @brief Initialize battery module data + * @param none + * @return none + */ +void bat_init_data(void) +{ + APP_PRINT_INFO0("[bat_init_data] init data"); + is_adc_efuse_existed = ADC_CalibrationInit(); + if (false == is_adc_efuse_existed) + { + APP_PRINT_WARN0("[bat_init_data] Read ADC efuse data error!"); + } +} + +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE +/****************************************************************** + * @brief Initialize battery board. + * @param none + * @return none + */ +void bat_init_board(void) +{ + Pad_Config(ADC_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW); + Pinmux_Config(ADC_PIN, IDLE_MODE); +} +#endif + +/****************************************************************** + * @brief battery module enter DLPS config + * @param none + * @return none + * @retval void + */ +void bat_enter_dlps_config(void) +{ +#if SUPPORT_BAT_LPC_FEATURE + bat_driver_lpc_enter_dlps_config(); +#endif +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + Pad_Config(ADC_PIN, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW); +#endif +} + +/****************************************************************** + * @brief battery module exit DLPS config + * @param none + * @return none + * @retval void + */ +void bat_exit_dlps_config(void) +{ +#if SUPPORT_BAT_LPC_FEATURE + bat_driver_lpc_exit_dlps_config(); +#endif +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + bat_init_board(); +#endif +} + +/****************************************************************** + * @brief Initialize battery driver. + * @param none + * @return none + */ +void bat_init_driver(void) +{ + ADC_DeInit(ADC); + RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, ENABLE); + + ADC_InitTypeDef adcInitStruct; + ADC_StructInit(&adcInitStruct); + + for (uint8_t index = 0; index < BAT_ADC_SAMPLE_CNT; index++) + { +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + adcInitStruct.ADC_SchIndex[index] = EXT_SINGLE_ENDED(ADC_CHANNEL); +#else + adcInitStruct.ADC_SchIndex[index] = INTERNAL_VBAT_MODE; +#endif + } + adcInitStruct.ADC_Bitmap = (1 << BAT_ADC_SAMPLE_CNT) - 1; + adcInitStruct.ADC_SampleTime = 255; + + ADC_Init(ADC, &adcInitStruct); + +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + /* High bypass resistance mode config, please notice that the input voltage of + adc channel using high bypass mode should not be over 0.9V */ + ADC_BypassCmd(ADC_CHANNEL, ENABLE); +#endif +#if GFPS_FEATURE_SUPPORT + os_timer_start(&bat_detect_timer); +#endif +} + +/****************************************************************** + * @brief update battery level. + * @param none + * @return none + */ +void bat_update_battery_info(void) +{ + uint32_t sum = 0; + uint16_t adc_arr[BAT_ADC_SAMPLE_CNT]; + uint16_t min = 0xffff; + uint16_t max = 0; + + ADC_INTConfig(ADC, ADC_INT_ONE_SHOT_DONE, ENABLE); + ADC_Cmd(ADC, ADC_ONE_SHOT_MODE, ENABLE); + + uint32_t delay = 0; + /* 5000 timeout: 1ms at 40M Clock */ + while ((ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) != SET) + && ((delay++ < 5000))); + ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE); + + /* get average value after remove minimal and maximal values */ + for (uint8_t index = 0; index < BAT_ADC_SAMPLE_CNT; index ++) + { + adc_arr[index] = ADC_ReadRawData(ADC, index); + sum += adc_arr[index]; + if (min > adc_arr[index]) + { + min = adc_arr[index]; + } + if (max < adc_arr[index]) + { + max = adc_arr[index]; + } + } + sum = (sum - min - max) / (BAT_ADC_SAMPLE_CNT - 2); + APP_PRINT_INFO1("[bat_update_battery_info] raw bat_adc_sample_average_value = %d", sum); + + /* calculate battery voltage value */ + uint16_t bat_value = bat_calibrate_voltage(sum); + + /* calculate battery level */ + fmna_bat_state_level_t bat_level = bat_calculate_bat_level(bat_value); + + if (cur_bat_level != bat_level) + { +#if SUPPORT_NFC // Set the NFC URL battery status key. + fmna_nfc_set_url_key(URL_KEY_BATT_STATUS, &bat_level); +#endif +#if GFPS_FEATURE_SUPPORT + dult_set_battery_level(bat_level); +#endif + /* update battery mode */ + if (bat_level == BAT_STATE_CRITICALLY_LOW) + { + app_global_data.low_power_mode = true; + fmna_adv_platform_stop_adv(); + APP_PRINT_WARN0("[bat_update_battery_info] enter low power mode"); + } + else + { + app_global_data.low_power_mode = false; +#if SUPPORT_BAT_LPC_FEATURE + bat_driver_lpc_init(); +#endif + APP_PRINT_WARN0("[bat_update_battery_info] enter normal power mode"); + } + } + cur_bat_level = bat_level; + + APP_PRINT_INFO2("[bat_update_battery_info] bat_value is %d, cur_bat_level is %d", + bat_value, cur_bat_level); +} +#endif + +fmna_bat_state_level_t fmna_battery_platform_get_battery_level(void) +{ + return cur_bat_level; +} + diff --git a/src/app/findmy/fmna_platform/fmna_battery_platform.h b/src/app/findmy/fmna_platform/fmna_battery_platform.h new file mode 100644 index 0000000..92e4584 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_battery_platform.h @@ -0,0 +1,53 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_battery_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2024-04-26 +* @version v1.1 +********************************************************************************************************* +*/ +#ifndef fmna_battery_platform_h +#define fmna_battery_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include + +/*============================================================================* +* Macro Definitions +*============================================================================*/ +#define BAT_ADC_SAMPLE_CNT 4 /* battery adc samples counts, ragne 3-16 */ + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + BAT_STATE_FULL = 0, + BAT_STATE_MEDIUM, + BAT_STATE_LOW, + BAT_STATE_CRITICALLY_LOW, +} fmna_bat_state_level_t; + +/*============================================================================* + * Interface Functions + *============================================================================*/ +#if SUPPORT_BAT_DETECT_FEATURE +void bat_init_data(void); +void bat_init_driver(void); +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE +void bat_init_board(void); +#endif +void bat_enter_dlps_config(void); +void bat_exit_dlps_config(void); +void bat_update_battery_info(void); +#endif + +fmna_bat_state_level_t fmna_battery_platform_get_battery_level(void); + +#endif /* fmna_battery_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_connection_platform.c b/src/app/findmy/fmna_platform/fmna_connection_platform.c new file mode 100644 index 0000000..4d7cd29 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_connection_platform.c @@ -0,0 +1,318 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_connection_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_connection_platform.h" +#include "fmna_platform_includes.h" +#include "fmna_constants.h" +#include "fmna_connection.h" +#include "fmna_gatt_platform.h" +#include "fmna_state_machine.h" +#include "fmna_peer_manager.h" +#include +#include +#include "system_rtl876x.h" +#if GFPS_FEATURE_SUPPORT +#include "app_gfps.h" +#endif + +/*============================================================================* + * Global Functions + *============================================================================*/ +fmna_ret_code_t fmna_connection_platform_disconnect(uint16_t conn_handle) +{ + return le_disconnect((uint8_t)conn_handle); +} + +bool fmna_handle_ble_evt(T_FMNA_BLE_EVT_TYPE evt_type, uint8_t conn_id) +{ + bool ret = false; + switch (evt_type) + { + case FMNA_CONNECTED: + { + APP_PRINT_INFO1("[fmna_handle_ble_evt]FMNA_CONNECTED conn_id=%d", conn_id); + uint16_t conn_interval; + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + fmna_connection_connected_handler(conn_id, conn_interval); + on_connect(conn_id); + ret = true; + } + break; + + case FMNA_DISCONNECTED: + { + if (fmna_connection_is_valid_connection(conn_id)) + { + APP_PRINT_INFO1("[fmna_handle_ble_evt]FMNA_DISCONNECTED conn_id=%d", conn_id); +#if SUPPORT_DYNAMIC_SERVICE + if (fmna_connection_get_num_connections() == 1) + { + fmna_gatt_dynamic_service_change(NON_OWNER_SERVICE); + } + else +#endif + { + fmna_connection_disconnected_handler(conn_id); + } + + on_disconnect(conn_id); + fmna_connection_update_connection_info(conn_id, FMNA_MULTI_STATUS_ENCRYPTED, false); + ret = true; + } + } + break; + + case FMNA_CONN_PARAM_UPDATE: + { + if (fmna_connection_is_valid_connection(conn_id)) + { + APP_PRINT_INFO1("[fmna_handle_ble_evt]FMNA_CONN_PARAM_UPDATE conn_id=%d", conn_id); + uint16_t conn_interval; + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + fmna_connection_conn_param_update_handler(conn_id, conn_interval); + ret = true; + } + } + break; + + case FMNA_AUTHEN_SUCCESS: + { + if (fmna_connection_is_valid_connection(conn_id)) + { + APP_PRINT_INFO1("[fmna_handle_ble_evt]FMNA_AUTHEN_SUCCESS conn_id=%d", conn_id); +#if SUPPORT_DYNAMIC_SERVICE + if (fmna_connection_is_fmna_paired()) + { + fmna_gatt_dynamic_service_change(OWNER_SERVICE); + } +#endif + fmna_pm_conn_sec_handle(conn_id); + ret = true; + } + } + break; + + default: + APP_PRINT_ERROR1("[fmna_handle_ble_evt] unknown evt_type=%d", evt_type); + break; + } + return ret; +} + +void fmna_connection_platform_fmna_unpair(void) +{ + app_global_data.fmna_enable = false; +#if SUPPORT_CUSTOMIZED_APP + cust_adv_update_device_name(false); +#endif +#if GFPS_FEATURE_SUPPORT + uint8_t remain_srv_num = 1; + server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_TABLE, &remain_srv_num); + app_gfps_gatt_init(); + server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_STACK, &remain_srv_num); +#endif +} + +void fmna_connection_platform_log_token_help(void *auth_token, uint16_t token_size, void *auth_uuid, + uint16_t uuid_size) +{ + APP_PRINT_INFO2("MFi token: UUID %b, %d", TRACE_BINARY(uuid_size, auth_uuid), uuid_size); + APP_PRINT_INFO1("MFi token len: %d", token_size); +} + +#define MFI_TOKEN_MAX_LOG_CHUNK 64 +void fmna_connection_platform_log_token(void *auth_token, uint16_t token_size) +{ + uint16_t token_remaining = token_size; + uint8_t *p_temp = auth_token; + uint16_t to_print; + + APP_PRINT_INFO0("MFi Token:"); + while (token_remaining) + { + if (token_remaining > MFI_TOKEN_MAX_LOG_CHUNK) + { + to_print = MFI_TOKEN_MAX_LOG_CHUNK; + } + else + { + to_print = token_remaining; + } + APP_PRINT_INFO1("%b", TRACE_BINARY(to_print, p_temp)); + token_remaining -= to_print; + p_temp += to_print; + } +} + +char num_to_char(uint8_t nibble) +{ + if (nibble < 10) + { + return (('0' + nibble)); + } + + return (('a' + nibble - 10)); +} + +#define SN_DOWNLOAD_ADDR APPLE_AUTH_SN_SAVE_ADDRESS + +//TODO: confirm spec, any SN can be accepted? +uint8_t fmna_connection_platform_get_serial_number(uint8_t *pSN, uint8_t length) +{ + /*uint8_t temp[8]; + uint16_t remaining = length; + int i = 0; + + uint8_t chip_id = get_ic_type(); + uint8_t bd_addr[6]; + memcpy(bd_addr, app_global_data.mac_address, 6); + + // xor device id and bd addr to identify the device + *((uint32_t *)temp) = chip_id; + *((uint32_t *)temp) ^= *((uint32_t *)bd_addr); + + *((uint32_t *)(temp + 4)) = chip_id; + *((uint16_t *)(temp + 4)) ^= *((uint16_t *)(bd_addr + 4)); + + // Convert to a character string + for (; i < 8 && remaining; ++i) + { + pSN[2 * i] = num_to_char((temp[i] & 0x0f)); + remaining--; + if (remaining) + { + pSN[2 * i + 1] = num_to_char(((temp[i] >> 4) & 0x0f)); + remaining--; + } + } + + // Pad remaining with 'f' + if (remaining) + { + pSN[i] = 'f'; + remaining--; + i++; + }*/ + + uint64_t all_sn = 0; + uint8_t actual_length = (length > 16) ? 16 : length; // 限制最多16个字节 + + // 从闪存读取序列号 + flash_read_locked(SN_DOWNLOAD_ADDR, length, pSN); + + // 打印读取的数据 + for(int i = 0; i < actual_length; i++) { + APP_PRINT_INFO1("--> 0x%02x", pSN[i]); + } + + // 将数据组装到all_sn中(最多8个字节,因为uint64_t是64位) + // 如果pSN超过8个字节,我们只取前8个字节 + uint8_t copy_length = (actual_length > 8) ? 8 : actual_length; + for(int i = 0; i < copy_length; i++) { + // 将每个字节放入all_sn的对应位置(大端序) + all_sn = (all_sn << 8) | pSN[i]; + } + + APP_PRINT_INFO1("--> 0x%02x", all_sn); + + return all_sn; + +} + +// TODO remove / replace this with POR storage +// Using fstorage as temp storage for Token + +// There is a window after erase and before write completes +// that there is no Token stored. A reset in this window could + +#define CHECK_FLASH_RET(ret, _label_) if (!ret) goto _label_; + +static bool m_new_token_stored = false; + +void fmna_connection_update_mfi_token_storage(mfi_info_t *p_data) +{ + bool ret = false; + uint16_t auth_total_len = SOFTWARE_AUTH_TOKEN_BLEN + SOFTWARE_AUTH_UUID_BLEN; + uint8_t *p_temp_auth_buffer = NULL; + uint8_t *old_token = NULL; + + // Allocate memory for temporary buffers + p_temp_auth_buffer = os_mem_zalloc(RAM_TYPE_DATA_ON, USER_DATA1_SIZE); + if (p_temp_auth_buffer == NULL) + { + APP_PRINT_ERROR1("malloc heap failed! line %d", __LINE__); + goto cleanup; + } + + old_token = os_mem_zalloc(RAM_TYPE_DATA_ON, auth_total_len); + if (old_token == NULL) + { + APP_PRINT_ERROR1("malloc heap failed! line %d", __LINE__); + goto cleanup; + } + + // Backup old token in flash + APP_PRINT_INFO0("token backup"); + ret = flash_read_locked(APPLE_AUTH_TOKEN_SAVE_ADDRESS, auth_total_len, old_token); + CHECK_FLASH_RET(ret, cleanup); + + memcpy(p_temp_auth_buffer + APPLE_AUTH_TOKEN_BACKUP_OFFSET, old_token, auth_total_len); + + // Update token + APP_PRINT_INFO0("token update"); + memcpy(p_temp_auth_buffer, p_data->m_software_auth_uuid, SOFTWARE_AUTH_UUID_BLEN); + memcpy(p_temp_auth_buffer + SOFTWARE_AUTH_UUID_BLEN, p_data->p_software_auth_token, + SOFTWARE_AUTH_TOKEN_BLEN); + + // Erase, write and verify the new token to flash + ret = flash_erase_locked(FLASH_ERASE_SECTOR, APPLE_AUTH_TOKEN_SAVE_ADDRESS); + CHECK_FLASH_RET(ret, cleanup); + + ret = flash_write_locked(APPLE_AUTH_TOKEN_SAVE_ADDRESS, USER_DATA1_SIZE, p_temp_auth_buffer); + CHECK_FLASH_RET(ret, cleanup); + + if (memcmp((const void *)APPLE_AUTH_TOKEN_SAVE_ADDRESS, (const void *)p_temp_auth_buffer, + USER_DATA1_SIZE)) + { + APP_PRINT_ERROR0("[ERROR]token region not matched"); + goto cleanup; + } + + // Successful execution + m_new_token_stored = true; + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_FMNA_PAIRING_MFITOKEN); + +cleanup: + // Error handling and resource cleanup + if (!ret) + { + APP_PRINT_ERROR0("[fmna_connection_update_mfi_token_storage] failed!"); + m_new_token_stored = false; + } + if (p_temp_auth_buffer) + { + os_mem_free(p_temp_auth_buffer); + } + if (old_token) + { + os_mem_free(old_token); + } + return; +} + +bool fmna_connection_mfi_token_stored(void) +{ + return m_new_token_stored; +} diff --git a/src/app/findmy/fmna_platform/fmna_connection_platform.h b/src/app/findmy/fmna_platform/fmna_connection_platform.h new file mode 100644 index 0000000..6083393 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_connection_platform.h @@ -0,0 +1,72 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_connection_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +#ifndef fmna_connection_platform_h +#define fmna_connection_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_crypto.h" + +/*============================================================================* +* Macro Definitions +*============================================================================*/ +#define FIRST_CONN_PARAMS_UPDATE_DELAY MSEC_TO_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to the first time sd_ble_gap_conn_param_update is called (5 seconds). */ +#define NEXT_CONN_PARAMS_UPDATE_DELAY MSEC_TO_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ +#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ + +/* Connection Interval Parameters Requirements: + * 1. conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * 2. The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +#define DEFAULT_MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(15, UNIT_1_25_MS) /**< Determines minimum connection interval in milliseconds. */ +#define NON_OWNER_MIN_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(200, UNIT_1_25_MS) /**< Determines minimum connection interval in milliseconds. */ +#define MAX_CONNECTION_INTERVAL (uint16_t) MSEC_TO_UNITS(2000, UNIT_1_25_MS) /**< Determines maximum connection interval in milliseconds. */ +#define SLAVE_LATENCY 0 /**< Determines slave latency in terms of connection events. */ +#define SUPERVISION_TIMEOUT (uint16_t) MSEC_TO_UNITS(5000, UNIT_10_MS) /**< Determines supervision time-out in units of 10 milliseconds. */ + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + FMNA_CONNECTED = 0, + FMNA_DISCONNECTED, + FMNA_CONN_PARAM_UPDATE, + FMNA_AUTHEN_SUCCESS, +} T_FMNA_BLE_EVT_TYPE; + +/*============================================================================* + * Interface Functions + *============================================================================*/ +/// Disconnect the link. +/// @details Disconnects the link with BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION disconnect reason. +/// @param[in] conn_handle Connection handle for connection to disconnect. +fmna_ret_code_t fmna_connection_platform_disconnect(uint16_t conn_handle); + +bool fmna_handle_ble_evt(T_FMNA_BLE_EVT_TYPE evt_type, uint8_t conn_id); + +void fmna_connection_platform_log_token_help(void *auth_token, uint16_t token_size, void *auth_uuid, + uint16_t uuid_size); +void fmna_connection_platform_log_token(void *auth_token, uint16_t token_size); + +uint8_t fmna_connection_platform_get_serial_number(uint8_t *pSN, uint8_t length); + +void fmna_connection_update_mfi_token_storage(mfi_info_t *p_data); + +bool fmna_connection_mfi_token_stored(void); + +void fmna_connection_platform_fmna_unpair(void); + +#endif /* fmna_connection_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_constants_platform.h b/src/app/findmy/fmna_platform/fmna_constants_platform.h new file mode 100644 index 0000000..26c1ea8 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_constants_platform.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.'s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_constants_platform_h +#define fmna_constants_platform_h + +#include "board.h" +#include "otp.h" +#include "platform_utils.h" + +#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B))) +#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B)))) +#define IS_SET(W, B) (((W) >> (B)) & 1) + +/** @brief Default minimum advertising interval when device is discoverable (units of 625us, 160=100ms) */ +#define DEFAULT_ADVERTISING_INTERVAL_MIN 320 +/** @brief Default maximum advertising interval */ +#define DEFAULT_ADVERTISING_INTERVAL_MAX 320 + +#define FMNA_MANUFACTURER_NAME "SWISSDIGITAL DESIGN" +#define FMNA_MODEL_NAME "SDD Finder 2" +#define FMNA_PID 0xCAFE +#define FMNA_HARDWARE_VERSION "1" +#define BATTERY_TYPE 0 // 0 = Powered, 1 = Non-rechargeable battery, 2 = Rechargeable battery + +#define ARG_COUNT(...) INTERNAL_ARG_COUNT_PRIVATE(0, ##__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define INTERNAL_ARG_COUNT_PRIVATE( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N + +#if !(FMNA_DISABLE_LOGS) + +#define FMNA_LOG_ERROR(fmt,...) DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_ERROR, "!!!"fmt, ARG_COUNT(__VA_ARGS__),__VA_ARGS__) +#define FMNA_LOG_WARNING(fmt,...) DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_WARN, "!!*"fmt, ARG_COUNT(__VA_ARGS__),__VA_ARGS__) +#define FMNA_LOG_INFO(fmt,...) DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_INFO, "!**"fmt, ARG_COUNT(__VA_ARGS__),__VA_ARGS__) +#define FMNA_LOG_DEBUG(fmt,...) DBG_BUFFER(TYPE_BEE3, SUBTYPE_FORMAT, MODULE_APP, LEVEL_TRACE, fmt, ARG_COUNT(__VA_ARGS__),__VA_ARGS__) + +#define FMNA_LOG_HEXDUMP_INFO(p_data, len) APP_PRINT_INFO1("%b", TRACE_BINARY(len, p_data)) +#define FMNA_LOG_HEXDUMP_DEBUG(p_data, len) APP_PRINT_INFO1("%b", TRACE_BINARY(len, p_data)) + +#else + +#define FMNA_LOG_ERROR(fmt,...) +#define FMNA_LOG_WARNING(fmt,...) +#define FMNA_LOG_INFO(fmt,...) +#define FMNA_LOG_DEBUG(fmt,...) + +#define FMNA_LOG_HEXDUMP_INFO(p_data, len) +#define FMNA_LOG_HEXDUMP_DEBUG(p_data, len) + +#endif + +#define MAX_SUPPORTED_CONNECTIONS 2 +#define GATT_MAX_MTU_SIZE 247 +#define BLE_GAP_ADDR_LEN (6) + +#define CONN_HANDLE_INVALID 0xFF +#define CONN_HANDLE_ALL 0xEF +#define GAP_SEC_KEY_LEN 16 + +#define fmna_ret_code_t uint32_t + +#define FMNA_SUCCESS 0 ///< Successful command +#define FMNA_ERROR_INTERNAL 1 ///< Internal Error +#define FMNA_ERROR_INVALID_STATE 2 ///< Invalid state, operation disallowed in this state +#define FMNA_ERROR_INVALID_LENGTH 3 ///< Invalid Length +#define FMNA_ERROR_INVALID_DATA 4 ///< Invalid Data +#define FMNA_ERROR_NULL 5 ///< Null Pointer + +/**@brief Macro for debugging error if supplied error code any other than FMNA_SUCCESS. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#define FMNA_ERROR_CHECK(ERR_CODE) \ + do \ + { \ + if (ERR_CODE != FMNA_SUCCESS) \ + { \ + APP_PRINT_ERROR3("[ERROR] %s:%d ERR_CODE: %d", TRACE_STRING(__FUNCTION__), __LINE__, ERR_CODE); \ + } \ + } while (0) + +/**@brief Macro for debugging error function if supplied boolean value is false. + * + * @param[in] BOOLEAN_VALUE Boolean value to be evaluated. + */ +#define FMNA_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \ + do \ + { \ + if (!BOOLEAN_VALUE) \ + { \ + APP_PRINT_ERROR3("[ERROR] %s:%d", TRACE_STRING(__FUNCTION__), __LINE__); \ + } \ + } while (0) + +/**@brief Macro for calling critical error handler function if supplied error code any other than FMNA_SUCCESS. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#define FMNA_ERROR_CHECK_GOTO(ERR_CODE, exceptionLabel) \ + do \ + { \ + if (ERR_CODE != FMNA_SUCCESS) \ + { \ + error_line = __LINE__; \ + goto exceptionLabel; \ + } \ + } while (0) + +/** + * Called when a fatal error occurred. + */ +extern void vAssertHandler(const char *pFuncName, uint32_t funcLine); +#define FMNA_PLATFORM_ABORT(error_line) \ + do \ + { \ + if (OTP->enableASSERT) \ + { \ + platform_delay_ms(100); \ + vAssertHandler(__FUNCTION__, error_line); \ + } \ + } while (0) + + +#define APP_TIMER_MIN_TIMEOUT_TICKS 10 +#define MSEC_TO_TIMER_TICKS(ms) (uint32_t)(ms) + +#define APPLE_AUTH_TOKEN_SAVE_ADDRESS (USER_DATA1_ADDR) +#define APPLE_AUTH_TOKEN_BACKUP_OFFSET (0x0800) + +#define APPLE_AUTH_SN_SAVE_ADDRESS (USER_DATA2_ADDR) + +/* FTL 4 byte alignment */ +#define ALIGN_SIZE(len) (len + 3)&(~3) + +#define FTL_SAVE_PAIR_STATE_ADDR 0 +#define FTL_SAVE_PAIR_STATE_SIZE (4) +#define FTL_SAVE_M_P_ADDR (FTL_SAVE_PAIR_STATE_ADDR + FTL_SAVE_PAIR_STATE_SIZE) +#define FTL_SAVE_M_P_SIZE ALIGN_SIZE(P_BLEN) +#define FTL_SAVE_PRI_KEY_ADDR (FTL_SAVE_M_P_ADDR + FTL_SAVE_M_P_SIZE) +#define FTL_SAVE_PRI_KEY_SIZE ALIGN_SIZE(sizeof(fmna_primary_key_t)) +#define FTL_SAVE_SEC_KEY_ADDR (FTL_SAVE_PRI_KEY_ADDR + FTL_SAVE_PRI_KEY_SIZE) +#define FTL_SAVE_SEC_KEY_SIZE ALIGN_SIZE(sizeof(fmna_secondary_key_t)) +#define FTL_SAVE_NEXT_PW_ROT_INDEX_ADDR (FTL_SAVE_SEC_KEY_ADDR + FTL_SAVE_SEC_KEY_SIZE) +#define FTL_SAVE_NEXT_PW_ROT_INDEX_SIZE (4) +#define FTL_SAVE_SKN_ADDR (FTL_SAVE_NEXT_PW_ROT_INDEX_ADDR + FTL_SAVE_NEXT_PW_ROT_INDEX_SIZE) +#define FTL_SAVE_SKN_SIZE ALIGN_SIZE(SK_BLEN) +#define FTL_SAVE_SKS_ADDR (FTL_SAVE_SKN_ADDR + FTL_SAVE_SKN_SIZE) +#define FTL_SAVE_SKS_SIZE ALIGN_SIZE(SK_BLEN) +#define FTL_SAVE_ICLOUD_ID_ADDR (FTL_SAVE_SKS_ADDR + FTL_SAVE_SKS_SIZE) +#define FTL_SAVE_ICLOUD_ID_SIZE ALIGN_SIZE(ICLOUD_IDENTIFIER_BLEN) +#define FTL_SAVE_BOND_IDX_ADDR (FTL_SAVE_ICLOUD_ID_ADDR + FTL_SAVE_ICLOUD_ID_SIZE) +#define FTL_SAVE_BOND_IDX_SIZE (4) +#define FTL_SAVE_SHARED_SECRET_ADDR (FTL_SAVE_BOND_IDX_ADDR + FTL_SAVE_BOND_IDX_SIZE) +#define FTL_SAVE_SHARED_SECRET_SIZE ALIGN_SIZE(SERVER_SHARED_SECRET_BLEN) +#define FTL_SAVE_SEC_PRI_KEY_ADDR (FTL_SAVE_SHARED_SECRET_ADDR + FTL_SAVE_SHARED_SECRET_SIZE) +#define FTL_SAVE_SEC_PRI_KEY_SIZE ALIGN_SIZE(sizeof(fmna_primary_key_t)) +#define FTL_SAVE_SN_COUNTER_ADDR (FTL_SAVE_SEC_PRI_KEY_ADDR + FTL_SAVE_SEC_PRI_KEY_SIZE) +#define FTL_SAVE_SN_COUNTER_SIZE (8) + +#define FTL_SAVE_APP_PASSWORD_ADDR (FTL_SAVE_SN_COUNTER_ADDR+FTL_SAVE_SN_COUNTER_SIZE) +#define FTL_SAVE_APP_PASSWORD_SIZE (8) + +#define FTL_SAVE_APP_SINGLE_ID_ADDR (FTL_SAVE_APP_PASSWORD_ADDR+FTL_SAVE_APP_PASSWORD_SIZE) +#define FTL_SAVE_APP_SINGLE_ID_SIZE (8) + +#endif /* fmna_constants_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_dfu_platform.c b/src/app/findmy/fmna_platform/fmna_dfu_platform.c new file mode 100644 index 0000000..140e54f --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_dfu_platform.c @@ -0,0 +1,308 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_dfu_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_dfu_platform.h" +#include "fmna_platform_includes.h" +#include "dfu_flash.h" +#include "CoreUARPProtocolDefines.h" +#include "os_mem.h" + +/*============================================================================* + * Local Variables + *============================================================================*/ +static uint16_t uarp_buf_used_size; +static uint32_t dfu_resend_offset; +static uint8_t temp_image_num = 0; +static T_TEMP_IMAGE_INFO temp_image_info[IMAGE_MAX - SecureBoot]; +static T_DFU_PARA g_dfu_para; +static uint8_t *p_uarp_buf; +static uint8_t resend_cnt; + +/*============================================================================* + * Local Functions + *============================================================================*/ +static bool dfu_check_image_header(uint8_t *pbuffer) +{ + uint8_t *p_header = pbuffer; + + g_dfu_para.ctrl_header.ic_type = (*p_header); + p_header += 1; + g_dfu_para.ctrl_header.secure_version = (*p_header); + p_header += 1; + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.ctrl_flag.value, p_header); + p_header += 2; + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p_header); + p_header += 2; + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.crc16, p_header); + p_header += 2; + LE_ARRAY_TO_UINT32(g_dfu_para.ctrl_header.payload_len, p_header); + DFU_PRINT_INFO6("[dfu_check_image_header]ic_type=0x%x, secure_version=0x%x, ctrl_flag.value=0x%x, image_id=0x%x, crc16=0x%x, payload_len=%d", + g_dfu_para.ctrl_header.ic_type, + g_dfu_para.ctrl_header.secure_version, + g_dfu_para.ctrl_header.ctrl_flag.value, + g_dfu_para.ctrl_header.image_id, + g_dfu_para.ctrl_header.crc16, + g_dfu_para.ctrl_header.payload_len + ); + + /*check if start dfu fileds are vaild*/ + if (g_dfu_para.ctrl_header.ic_type == DEFINED_IC_TYPE) + { + if (((g_dfu_para.ctrl_header.image_id >= OTA) && (g_dfu_para.ctrl_header.image_id < IMAGE_MAX)) + || (g_dfu_para.ctrl_header.image_id == IMAGE_USER_DATA)) + { + /*disable bank switch, need record temp image info*/ + if (!is_ota_support_bank_switch()) + { + temp_image_info[temp_image_num].image_id = (T_IMG_ID)g_dfu_para.ctrl_header.image_id; + temp_image_info[temp_image_num].image_size = g_dfu_para.ctrl_header.payload_len + IMG_HEADER_SIZE; + if (temp_image_num == 0) + { + temp_image_info[temp_image_num].image_offset = 0; + } + else + { + temp_image_info[temp_image_num].image_offset = temp_image_info[temp_image_num - 1].image_offset + + temp_image_info[temp_image_num - 1].image_size; + } + g_dfu_para.image_total_length = temp_image_info[temp_image_num].image_size; + } + + DFU_PRINT_INFO4("[dfu_check_image_header]cur image[%d]: image_id=0x%x, image_size=0x%x, image_offset=0x%x", + temp_image_num, temp_image_info[temp_image_num].image_id, + temp_image_info[temp_image_num].image_size, temp_image_info[temp_image_num].image_offset); + return true; + + } + else + { + DFU_PRINT_ERROR1("[dfu_check_image_header]image id=0x%x Error!", g_dfu_para.ctrl_header.image_id); + return false; + } + } + else + { + DFU_PRINT_ERROR1("[dfu_check_image_header]ic type=0x%x Error!", g_dfu_para.ctrl_header.ic_type); + return false; + } +} + +static bool dfu_data_init(void) +{ + uarp_buf_used_size = 0; + dfu_resend_offset = 0; + resend_cnt = 0; + memset(&g_dfu_para, 0, sizeof(T_DFU_PARA)); + p_uarp_buf = os_mem_zalloc(RAM_TYPE_DATA_ON, DFU_TEMP_BUFFER_SIZE); + if (p_uarp_buf == NULL) + { + DFU_PRINT_ERROR0("[dfu_data_init]uarp_buf malloc fail!"); + return false; + } + else + { + DFU_PRINT_INFO1("[dfu_data_init]uarp_buff zalloc success size: %d", DFU_TEMP_BUFFER_SIZE); + return true; + } +} + +/*============================================================================* + * Global Functions + *============================================================================*/ +void dfu_buf_free(void) +{ + if (p_uarp_buf) + { + os_mem_free(p_uarp_buf); + p_uarp_buf = NULL; + DFU_PRINT_INFO0("[dfu_buf_free]"); + } +} + +uint32_t dfu_handle_uarp_payload(uint8_t *pbuffer, uint32_t length, uint32_t offset) +{ + bool is_new_image = false; + bool check_header_result = false; + + if (offset == 0) + { + DFU_PRINT_INFO0("[dfu_handle_uarp_payload]abandon the first 512 Bytes"); + if (dfu_data_init()) + { + return kUARPStatusSuccess; + } + else + { + return kUARPStatusInvalidPayload; + } + } + else if (offset == IMAGE_ABANDON_SIZE) + { + check_header_result = dfu_check_image_header(pbuffer); + if (!check_header_result) + { + dfu_buf_free(); + return kUARPStatusInvalidPayload; + } + } + else if (offset >= g_dfu_para.image_total_length + IMAGE_ABANDON_SIZE) + { + DFU_PRINT_INFO0("[dfu_handle_uarp_payload]abandon the extra ending"); + return kUARPStatusSuccess; + + } + else if (offset + length > g_dfu_para.image_total_length + IMAGE_ABANDON_SIZE) + { + length = g_dfu_para.image_total_length + IMAGE_ABANDON_SIZE - offset; + } + + if (p_uarp_buf && ((DFU_TEMP_BUFFER_SIZE - uarp_buf_used_size) >= length)) + { + memcpy(p_uarp_buf + uarp_buf_used_size, pbuffer, length); + } + uarp_buf_used_size += length; + + /* every DFU_TEMP_BUFFER_SIZE or the last packet will update flash */ + if (uarp_buf_used_size == DFU_TEMP_BUFFER_SIZE || + g_dfu_para.cur_offset + uarp_buf_used_size == g_dfu_para.image_total_length) + { + /* the first packet include header, set is_new_image is true */ + if (g_dfu_para.cur_offset == 0) + { + is_new_image = true; + } + + uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id, + g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset, + uarp_buf_used_size, (uint32_t *)p_uarp_buf, is_new_image); + + if (result == DFU_UPDATE_SUCCESS) + { + g_dfu_para.cur_offset += uarp_buf_used_size; + if ((g_dfu_para.cur_offset - dfu_resend_offset) >= FMC_SEC_SECTION_LEN) + { + dfu_resend_offset += FMC_SEC_SECTION_LEN; + } + uarp_buf_used_size = 0; + DFU_PRINT_INFO2("[dfu_handle_uarp_payload] dfu_update Success! cur_offset=%d, dfu_resend_offset=%d", + g_dfu_para.cur_offset, dfu_resend_offset); + return kUARPStatusSuccess; + } + else + { + resend_cnt++; + DFU_PRINT_ERROR2("[dfu_handle_uarp_payload]dfu update fail result=%d, cnt=%d", result, resend_cnt); + if (resend_cnt > MAX_RESEND_CNT) + { + return kUARPStatusInvalidPayload; + } + + result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, dfu_resend_offset); + if (result) + { + //Todo: erase fail + } + if ((g_dfu_para.cur_offset - dfu_resend_offset) > FMC_SEC_SECTION_LEN) //need erase two sector + { + DFU_PRINT_INFO0("[dfu_handle_uarp_payload]Need erase two sectors"); + result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, + dfu_resend_offset + FMC_SEC_SECTION_LEN); + if (result) + { + //Todo: erase fail + } + } + uarp_buf_used_size = 0; + g_dfu_para.cur_offset = dfu_resend_offset; + DFU_PRINT_INFO1("[dfu_handle_uarp_payload]erase ok! cur_offset=%d", g_dfu_para.cur_offset); + return kUARPStatusRequestResendPayload; + } + } + return kUARPStatusSuccess; +} + +uint32_t get_resend_offset(void) +{ + return (g_dfu_para.cur_offset + IMAGE_ABANDON_SIZE); +} + +bool dfu_service_handle_valid_fw(void) +{ + bool check_result = false; + bool is_enable_bank_switch = is_ota_support_bank_switch(); + + if (is_enable_bank_switch) + { + check_result = dfu_check_checksum(g_dfu_para.ctrl_header.image_id, 0); + } + else + { + check_result = dfu_check_checksum(temp_image_info[temp_image_num].image_id, + temp_image_info[temp_image_num].image_offset); + } + DFU_PRINT_INFO1("dfu_service_handle_valid_fw: check_result=%d (1: Success, 0: Fail)", check_result); + + if (check_result) + { + if (!is_enable_bank_switch) + { + temp_image_num ++; + DFU_PRINT_INFO1("dfu_service_handle_valid_fw: temp_image_num=%d ", temp_image_num); + } + } + + dfu_buf_free(); + return check_result; +} + +void dfu_service_handle_active_image(void) +{ + if (!is_ota_support_bank_switch()) + { + uint32_t base_addr = 0; + T_IMG_CTRL_HEADER_FORMAT *p_header = NULL; + if (IMAGE_USER_DATA == g_dfu_para.ctrl_header.image_id) + { + /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */ + base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE; + } + else + { + /* check OTA temp or running bank to see if received image is OK.*/ + base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id); + } + + for (uint8_t i = 0; i < temp_image_num; i++) + { + p_header = (T_IMG_CTRL_HEADER_FORMAT *)(base_addr + temp_image_info[i].image_offset); + dfu_set_image_ready(p_header); + } + } + + if (!is_ota_support_bank_switch()) + { + /*note: must unlock flash bp for ota copy before reset when not support bank switch*/ + unlock_flash_bp_all(); + } + + T_IO_MSG dfu_valid_fw_msg; + dfu_valid_fw_msg.type = IO_MSG_TYPE_DFU_VALID_FW; + if (app_send_msg_to_apptask(&dfu_valid_fw_msg) == false) + { + DBG_DIRECT("DFU send Valid FW msg fail!"); + } +} + + diff --git a/src/app/findmy/fmna_platform/fmna_dfu_platform.h b/src/app/findmy/fmna_platform/fmna_dfu_platform.h new file mode 100644 index 0000000..5a2a51d --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_dfu_platform.h @@ -0,0 +1,58 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_dfu_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +#ifndef fmna_dfu_platform_h +#define fmna_dfu_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "patch_header_check.h" + +/*============================================================================* +* Macro Definitions +*============================================================================*/ +#define IMAGE_ABANDON_SIZE 512 +#define MAX_RESEND_CNT 5 + +/*============================================================================* + * Types + *============================================================================*/ +typedef struct +{ + T_IMG_ID image_id; + uint32_t image_size; + uint32_t image_offset; +} T_TEMP_IMAGE_INFO; + +typedef struct +{ + T_IMG_CTRL_HEADER_FORMAT ctrl_header; + uint32_t image_total_length; + uint32_t origin_image_version; + uint32_t cur_offset; + uint8_t mtu_size; + bool dfu_conn_para_update_in_progress; + uint16_t dfu_conn_interval; + uint16_t dfu_conn_lantency; +} T_DFU_PARA; + +/*============================================================================* + * Global Functions + *============================================================================*/ +uint32_t dfu_handle_uarp_payload(uint8_t *pbuffer, uint32_t length, uint32_t offset); +uint32_t get_resend_offset(void); +bool dfu_service_handle_valid_fw(void); +void dfu_service_handle_active_image(void); +void dfu_buf_free(void); + +#endif /* fmna_dfu_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_gap_platform.c b/src/app/findmy/fmna_platform/fmna_gap_platform.c new file mode 100644 index 0000000..450bdde --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_gap_platform.c @@ -0,0 +1,664 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_gap_platform.c +* @brief findmy ble gap api +* @details Gap data types and functions. +* @author +* @date 2022-8-22 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include + +#include "fmna_gap_platform.h" +#include "os_timer.h" +#include "os_mem.h" +#include "os_queue.h" +#include "trace.h" +#include "app_msg.h" +#include "app_task.h" +#include "findmy_app.h" + +#include "sdd_service.h" + +#if ONE_SHOT_ADV_EN +#include "stdlib.h" +#include "string.h" +#endif + +/*============================================================================* + * Variables + *============================================================================*/ +#if (!ONE_SHOT_ADV_EN) +static rtk_gap_task_t *pcur_task; +static T_OS_QUEUE rtk_gap_task_list; +static void *rtk_gap_timer; +static uint8_t task_try_cnt; +#else //ONE_SHOT_ADV_EN +T_ONE_SHOT_DATA one_shot_adv_data; +static void *findmy_adv_timer; +#if SUPPORT_CUSTOMIZED_APP +static void *customized_adv_timer; +#endif +#if GFPS_FEATURE_SUPPORT +static void *gfps_adv_timer; +static void *finder_adv_timer; +#endif +#endif + +/*============================================================================* + * Functions Declaration + *============================================================================*/ +#if (!ONE_SHOT_ADV_EN) +static void rtk_gap_task_run(rtk_gap_task_t *ptask); +static void rtk_gap_task_try(rtk_gap_task_t *ptask); +static void rtk_gap_cur_task_done(void); +static void rtk_gap_timeout_handle(void *pargs); +#else +static void findmy_adv_timer_callback(void *p_timer); +#if SUPPORT_CUSTOMIZED_APP +static void customized_adv_timer_callback(void *p_timer); +#endif +static void plt_rand(uint8_t *prand, uint16_t len); +#endif + +/******************************************************************************/ + +// ڱ¶ʱ +static void *custom_new_adv_timer; + +/******************************************************************************/ + +/*============================================================================* + * Local functions + *============================================================================*/ +#if (!ONE_SHOT_ADV_EN) +static void rtk_gap_cur_task_done(void) +{ +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[rtk_gap_cur_task_done]task done: 0x%x", pcur_task); +#endif + /* stop timer first and clear tasy_try_cnt*/ + os_timer_stop(&rtk_gap_timer); + task_try_cnt = 0; + + /* free current task */ + if (NULL != pcur_task) + { + os_mem_free(pcur_task); + pcur_task = NULL; + } + /* run next task */ + rtk_gap_task_t *ptask = os_queue_out(&rtk_gap_task_list); +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[rtk_gap_cur_task_done]pop task: 0x%x", ptask); +#endif + if (NULL != ptask) + { + rtk_gap_task_run(ptask); + } +} + +static void rtk_gap_timeout_handle(void *pargs) +{ + /* current task run timeout, maybe error happened or message missed */ + APP_PRINT_INFO0("[rtk_gap_timeout_handle]operate timeout!"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_FMNA; + int_gpio_msg.subtype = IO_MSG_FMNA_GAP; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[rtk_gap_timeout_handle] Send msg failed!"); + //Add user code here! + return; + } +} + +static void rtk_gap_task_run(rtk_gap_task_t *ptask) +{ +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[rtk_gap_task_run]run task: 0x%x", ptask); +#endif + pcur_task = ptask; + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + uint16_t error_line = 0; + + switch (ptask->task_type) + { + case RTK_GAP_TASK_TYPE_ADV_START: + { + if (GAP_ADV_STATE_IDLE != app_global_data.gap_dev_state.gap_adv_state) + { + APP_PRINT_WARN0("adv not in IDLE state"); + rtk_gap_cur_task_done(); + return; + } + APP_PRINT_INFO0("sync start adv"); + ret = le_adv_start(); + __GAP_RET_CHECK(ret, error); + } + break; + case RTK_GAP_TASK_TYPE_ADV_STOP: + { + if (GAP_ADV_STATE_ADVERTISING != app_global_data.gap_dev_state.gap_adv_state) + { + APP_PRINT_WARN0("adv not in ADVERTISING state"); + rtk_gap_cur_task_done(); + return; + } + APP_PRINT_INFO0("sync stop adv"); + ret = le_adv_stop(); + __GAP_RET_CHECK(ret, error); + } + break; + case RTK_GAP_TASK_TYPE_UPDATE_ADV_PARAM: + { + APP_PRINT_INFO0("sync update adv param"); + ret = le_adv_update_param(); + __GAP_RET_CHECK(ret, error); + } + break; + default: + APP_PRINT_ERROR1("[rtk_gap_task_run]invalid task_type=%d", ptask->task_type); + break; + } + + if (!os_timer_restart(&rtk_gap_timer, RTK_GAP_OPERATE_TIMEOUT)) + { + APP_PRINT_ERROR0("rtk_gap_timer restart fail"); + } + return; +error: + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + rtk_gap_cur_task_done(); +} + +static void rtk_gap_task_try(rtk_gap_task_t *ptask) +{ + if (NULL == pcur_task) + { + rtk_gap_task_run(ptask); + } + else + { +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[rtk_gap_task_try]pending task: 0x%x", pcur_task); +#endif + task_try_cnt++; + os_queue_in(&rtk_gap_task_list, ptask); + + if (task_try_cnt == RTK_GAP_MAX_TASK_TRY_CNT) + { + rtk_gap_cur_task_done(); + APP_PRINT_INFO1("[rtk_gap_task_try]reaches the max try cnt:%d", RTK_GAP_MAX_TASK_TRY_CNT); + } + } +} +#else +static void findmy_adv_timer_callback(void *p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV; + int_gpio_msg.subtype = ADV_DATA_FINDMY; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[findmy_adv_timer_callback] Send int_gpio_msg failed!"); + return; + } +} + +#if SUPPORT_CUSTOMIZED_APP +static void customized_adv_timer_callback(void *p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV; + int_gpio_msg.subtype = ADV_DATA_CUSTOMIZED; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[customized_adv_timer_callback] Send int_gpio_msg failed!"); + return; + } +} +#endif + +// Ӷʱص +static void custom_new_adv_timer_callback(void *p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV; + int_gpio_msg.subtype = ADV_DATA_CUSTOM_NEW; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[custom_new_adv_timer_callback] Send int_gpio_msg failed!"); + return; + } +} + +#if GFPS_FEATURE_SUPPORT +static void gfps_adv_timer_callback(void *p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV; + int_gpio_msg.subtype = ADV_DATA_GFPS; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[gfps_adv_timer_callback] Send int_gpio_msg failed!"); + return; + } +} + +static void finder_adv_timer_callback(void *p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV; + int_gpio_msg.subtype = ADV_DATA_FINDER; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[gfps_adv_timer_callback] Send int_gpio_msg failed!"); + return; + } +} +#endif + +static void plt_rand(uint8_t *prand, uint16_t len) +{ + while (len > 0) + { + if (((uint32_t)prand & 0x3) == 0 && len >= 4) + { + *(uint32_t *)prand = rand(); + prand += 4; + len -= 4; + } + else + { + *prand++ = rand(); + len -= 1; + } + } +} +#endif + +/*============================================================================* +* Global functions +*============================================================================*/ +#if (!ONE_SHOT_ADV_EN) +void rtk_gap_task_init(void) +{ + if (false == os_timer_create(&rtk_gap_timer, "rtk_gap_timer", 1, \ + RTK_GAP_OPERATE_TIMEOUT, false, rtk_gap_timeout_handle)) + { + APP_PRINT_INFO0("[rtk_gap_task_init] init rtk_gap_timer failed"); + } + + os_queue_init(&rtk_gap_task_list); +} + +void rtk_gap_handle_msg(void) +{ + rtk_gap_cur_task_done(); +} + +void fmble_gap_dev_state_change(T_GAP_DEV_STATE state) +{ + if (pcur_task == NULL) + { + return; + } + + if (RTK_GAP_TASK_TYPE_ADV_START == pcur_task->task_type) + { + if (GAP_ADV_STATE_ADVERTISING == state.gap_adv_state) + { + /* start adv success */ + APP_PRINT_INFO0("sync start adv success"); + rtk_gap_cur_task_done(); + } + } + if (RTK_GAP_TASK_TYPE_ADV_STOP == pcur_task->task_type) + { + if (GAP_ADV_STATE_IDLE == state.gap_adv_state) + { + /* stop adv success */ + APP_PRINT_INFO0("sync stop adv success"); + rtk_gap_cur_task_done(); + } + } +} + +void fmble_gap_adv_cb(void) +{ + if (pcur_task->task_type == RTK_GAP_TASK_TYPE_UPDATE_ADV_PARAM) + { + /* update adv param success */ + APP_PRINT_INFO0("sync update adv param success"); + rtk_gap_cur_task_done(); + } +} + +#else + +uint8_t gap_sched_adv_random_delay(void) +{ + uint8_t rand_delay = 0; + plt_rand(&rand_delay, 1); + rand_delay %= 10; + return rand_delay; +} + +void one_shot_bt_addr_set(uint8_t bt_mac[GAP_BD_ADDR_LEN], \ + T_GAP_LOCAL_ADDR_TYPE bt_addr_type, \ + T_ADV_DATA_TYPE adv_data_type) +{ + one_shot_adv_data.adv_data[adv_data_type].just_change = true; + memcpy(one_shot_adv_data.adv_data[adv_data_type].bd_addr, bt_mac, GAP_BD_ADDR_LEN); + one_shot_adv_data.adv_data[adv_data_type].bd_addr_type = bt_addr_type; +} + +void one_shot_adv_init(void) +{ + memset(&one_shot_adv_data, 0, sizeof(one_shot_adv_data)); + one_shot_adv_data.waiting_adv_param_update = true; + one_shot_adv_data.waiting_vendor_one_shot = true; + + /* findmy_adv_timer is used to set the findmy advertising interval */ + if (false == os_timer_create(&findmy_adv_timer, "findmy_adv_timer", 1, \ + 200, true, findmy_adv_timer_callback)) + { + APP_PRINT_INFO0("[one_shot_timer_init] init findmy_adv_timer failed"); + } + +#if SUPPORT_CUSTOMIZED_APP + /* customized_adv_timer is used to set the customized advertising interval */ + if (false == os_timer_create(&customized_adv_timer, "customized_adv_timer", 1, \ + 200, true, customized_adv_timer_callback)) + { + APP_PRINT_INFO0("[one_shot_timer_init] init customized_adv_timer failed"); + } +#endif + + // ·㲥ʱʼ + if (false == os_timer_create(&custom_new_adv_timer, "custom_new_adv_timer", 1, \ + 200, true, custom_new_adv_timer_callback)) + { + APP_PRINT_INFO0("[one_shot_timer_init] init custom_new_adv_timer failed"); + } + +#if GFPS_FEATURE_SUPPORT + /* gfps_adv_timer is used to set the GFPS advertising interval */ + if (false == os_timer_create(&gfps_adv_timer, "gfps_adv_timer", 1, \ + 200, true, gfps_adv_timer_callback)) + { + APP_PRINT_INFO0("[one_shot_timer_init] init gfps_adv_timer failed"); + } + /* finder_adv_timer is used to set the GFPS finder advertising interval */ + if (false == os_timer_create(&finder_adv_timer, "finder_adv_timer", 1, \ + 200, true, finder_adv_timer_callback)) + { + APP_PRINT_INFO0("[one_shot_timer_init] init finder_adv_timer failed"); + } +#endif +} + +void one_shot_handle_pending_adv(void) +{ + if (!one_shot_adv_data.pending_adv) + { + return; + } + APP_PRINT_INFO1("[one_shot_handle_pending_adv]type = %d", one_shot_adv_data.pending_adv_type); + one_shot_adv_set_param(one_shot_adv_data.pending_adv_type); + if (one_shot_adv_data.cur_adv_type == one_shot_adv_data.pending_adv_type) + { + one_shot_adv_data.pending_adv = false; + } +} + +void one_shot_adv_set_addr(void) +{ + le_set_rand_addr(one_shot_adv_data.adv_data[one_shot_adv_data.cur_adv_type].bd_addr); +} + +void one_shot_adv_set_param(T_ADV_DATA_TYPE msg_sub_type) +{ + uint16_t error_line = 0; + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + T_ADV_DATA_TYPE chg_type = msg_sub_type; + + if (!one_shot_adv_data.waiting_adv_param_update || !one_shot_adv_data.waiting_vendor_one_shot) + { + APP_PRINT_INFO2("adv para updated %d ,one shot vendor %d", + one_shot_adv_data.waiting_adv_param_update, one_shot_adv_data.waiting_vendor_one_shot); + one_shot_adv_data.pending_adv = true; + one_shot_adv_data.pending_adv_type = chg_type; + APP_PRINT_INFO1("[one_shot_adv_set_param]type = %d pending", one_shot_adv_data.pending_adv_type); + return; + } + + if (one_shot_adv_data.cur_adv_type != chg_type || \ + one_shot_adv_data.adv_data[chg_type].just_change) + { + one_shot_adv_data.adv_data[chg_type].just_change = false; + + T_GAP_LOCAL_ADDR_TYPE local_bd_type = one_shot_adv_data.adv_data[chg_type].bd_addr_type; + ret = le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + __GAP_RET_CHECK(ret, fail); + if (local_bd_type == GAP_LOCAL_ADDR_LE_RANDOM) + { + one_shot_adv_data.waiting_adv_addr_update = false; + } + + ret = le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, \ + sizeof(one_shot_adv_data.adv_data[chg_type].adv_type), \ + &one_shot_adv_data.adv_data[chg_type].adv_type); + __GAP_RET_CHECK(ret, fail); + + ret = le_adv_set_param(GAP_PARAM_ADV_DATA, \ + one_shot_adv_data.adv_data[chg_type].adv_data_len, \ + (void *)one_shot_adv_data.adv_data[chg_type].p_adv_data); + __GAP_RET_CHECK(ret, fail); + + ret = le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, \ + one_shot_adv_data.adv_data[chg_type].scan_rsp_data_len, \ + (void *)one_shot_adv_data.adv_data[chg_type].p_scan_rsp_data); + __GAP_RET_CHECK(ret, fail); + + ret = le_adv_update_param(); + __GAP_RET_CHECK(ret, fail); + + one_shot_adv_data.cur_adv_type = chg_type; + one_shot_adv_data.waiting_adv_param_update = false; + APP_PRINT_INFO1("[one_shot_adv_set_param]type = %d change succeed", chg_type); + + + + } + else + { + le_vendor_one_shot_adv(gap_sched_adv_random_delay(), 0, 0); + one_shot_adv_data.waiting_vendor_one_shot = false; + } + return; +fail: + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + return; +} + +#endif + +T_GAP_CAUSE fmble_gap_adv_start(T_ADV_DATA_TYPE adv_data_type) +{ + T_GAP_CAUSE err = GAP_CAUSE_SUCCESS; +#if (!ONE_SHOT_ADV_EN) + rtk_gap_task_t *ptask = os_mem_alloc(RAM_TYPE_DATA_ON, sizeof(rtk_gap_task_t)); + if (NULL != ptask) + { +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[fmble_gap_adv_start]push task: %#x", ptask); +#endif + ptask->task_type = RTK_GAP_TASK_TYPE_ADV_START; + rtk_gap_task_try(ptask); + } + else + { + APP_PRINT_ERROR0("[fmble_gap_adv_start]failed: out of memory!"); + err = GAP_CAUSE_NO_RESOURCE; + } +#else + uint16_t adv_timer_interval = one_shot_adv_data.adv_data[adv_data_type].adv_interval * 0.625; + APP_PRINT_INFO2("[fmble_gap_adv_start]adv_type: %d, interval: %dms", adv_data_type, + adv_timer_interval); + + if (adv_data_type == ADV_DATA_FINDMY) + { + os_timer_restart(&findmy_adv_timer, adv_timer_interval); + } +#if SUPPORT_CUSTOMIZED_APP + if (adv_data_type == ADV_DATA_CUSTOMIZED) + { + os_timer_restart(&customized_adv_timer, adv_timer_interval); + } +#endif + + // ·㲥ʹ + if (adv_data_type == ADV_DATA_CUSTOM_NEW) + { + os_timer_restart(&custom_new_adv_timer, adv_timer_interval); + } + +#if GFPS_FEATURE_SUPPORT + if (adv_data_type == ADV_DATA_GFPS) + { + os_timer_restart(&gfps_adv_timer, adv_timer_interval); + } + if (adv_data_type == ADV_DATA_FINDER) + { + os_timer_restart(&finder_adv_timer, adv_timer_interval); + } +#endif +#endif + return err; +} + +T_GAP_CAUSE fmble_gap_adv_data_set(T_ADV_DATA adv_param, T_ADV_DATA_TYPE adv_data_type) +{ + T_GAP_CAUSE err = GAP_CAUSE_SUCCESS; +#if (!ONE_SHOT_ADV_EN) + uint16_t adv_int = adv_param.adv_interval; + le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_param.adv_type), &adv_param.adv_type); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int), &adv_int); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int), &adv_int); + + if (adv_param.p_adv_data != NULL) + { + if (adv_param.adv_data_len <= GAP_MAX_ADV_LEN && adv_param.adv_data_len > 0) + { + le_adv_set_param(GAP_PARAM_ADV_DATA, adv_param.adv_data_len, (void *)adv_param.p_adv_data); + } + } + + if (adv_param.p_scan_rsp_data != NULL) + { + if (adv_param.scan_rsp_data_len <= GAP_MAX_ADV_LEN && adv_param.scan_rsp_data_len > 0) + { + le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, adv_param.scan_rsp_data_len, + (void *)adv_param.p_scan_rsp_data); + } + } + + rtk_gap_task_t *ptask = os_mem_alloc(RAM_TYPE_DATA_ON, sizeof(rtk_gap_task_t)); + if (NULL != ptask) + { +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[fmble_gap_adv_data_set]push task: %#x", ptask); +#endif + ptask->task_type = RTK_GAP_TASK_TYPE_UPDATE_ADV_PARAM; + rtk_gap_task_try(ptask); + } + else + { + APP_PRINT_ERROR0("[fmble_gap_adv_data_set]failed: out of memory!"); + err = GAP_CAUSE_NO_RESOURCE; + } +#else + one_shot_adv_data.adv_data[adv_data_type].adv_interval = adv_param.adv_interval; + one_shot_adv_data.adv_data[adv_data_type].adv_type = adv_param.adv_type; + if ((NULL != adv_param.p_adv_data) && (adv_param.adv_data_len > 0)) + { + APP_PRINT_INFO1("[fmble_gap_adv_data_set]adv_type: %d adv data set", adv_data_type); + one_shot_adv_data.adv_data[adv_data_type].p_adv_data = (uint8_t *)adv_param.p_adv_data; + one_shot_adv_data.adv_data[adv_data_type].adv_data_len = adv_param.adv_data_len; + one_shot_adv_data.adv_data[adv_data_type].just_change = true; + } + if ((NULL != adv_param.p_scan_rsp_data) && (adv_param.scan_rsp_data_len > 0)) + { + APP_PRINT_INFO1("[fmble_gap_adv_data_set]adv_type: %d scan rsp set", adv_data_type); + one_shot_adv_data.adv_data[adv_data_type].p_scan_rsp_data = (uint8_t *)adv_param.p_scan_rsp_data; + one_shot_adv_data.adv_data[adv_data_type].scan_rsp_data_len = adv_param.scan_rsp_data_len; + one_shot_adv_data.adv_data[adv_data_type].just_change = true; + } +#endif + return err; +} + +T_GAP_CAUSE fmble_gap_adv_stop(T_ADV_DATA_TYPE adv_data_type) +{ + T_GAP_CAUSE err = GAP_CAUSE_SUCCESS; +#if (!ONE_SHOT_ADV_EN) + rtk_gap_task_t *ptask = os_mem_alloc(RAM_TYPE_DATA_ON, sizeof(rtk_gap_task_t)); + if (NULL != ptask) + { +#if RTK_GAP_DEBUG + APP_PRINT_INFO1("[fmble_gap_adv_stop]push task: %#x", ptask); +#endif + ptask->task_type = RTK_GAP_TASK_TYPE_ADV_STOP; + rtk_gap_task_try(ptask); + } + else + { + APP_PRINT_ERROR0("[fmble_gap_adv_stop]failed: out of memory!"); + err = GAP_CAUSE_NO_RESOURCE; + } +#else + APP_PRINT_INFO1("[fmble_gap_adv_stop]adv_type: %d", adv_data_type); + if (adv_data_type == ADV_DATA_FINDMY) + { + os_timer_stop(&findmy_adv_timer); + } +#if SUPPORT_CUSTOMIZED_APP + if (adv_data_type == ADV_DATA_CUSTOMIZED) + { + os_timer_stop(&customized_adv_timer); + } +#endif + + // ·㲥͵Ĵ + if (adv_data_type == ADV_DATA_CUSTOM_NEW) + { + os_timer_stop(&custom_new_adv_timer); + } + +#if GFPS_FEATURE_SUPPORT + if (adv_data_type == ADV_DATA_GFPS) + { + os_timer_stop(&gfps_adv_timer); + } + if (adv_data_type == ADV_DATA_FINDER) + { + os_timer_stop(&finder_adv_timer); + } +#endif +#endif + return err; +} + diff --git a/src/app/findmy/fmna_platform/fmna_gap_platform.h b/src/app/findmy/fmna_platform/fmna_gap_platform.h new file mode 100644 index 0000000..c143ce0 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_gap_platform.h @@ -0,0 +1,130 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_gap_platform.c +* @brief findmy ble gap api +* @details Gap data types and functions. +* @author scarlett_liang +* @date 2024-7-22 +* @version v2.0 +* ********************************************************************************************************* +*/ +#ifndef fmna_gap_platform_h +#define fmna_gap_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdint.h" +#include "gap_le_types.h" +#include "gap.h" +#include "gap_msg.h" +#include "board.h" +#include "fmna_timer_platform.h" + +/*============================================================================* +* Macro Definitions +*============================================================================*/ +#define RTK_GAP_OPERATE_TIMEOUT 200 +#define RTK_GAP_MAX_TASK_TRY_CNT 6 + +#define RTK_GAP_MAX_ADV_DATA_LEN 31 + +#define __GAP_RET_CHECK(assertion, exceptionLabel) \ + do \ + { \ + if ( assertion ) \ + { \ + error_line = __LINE__; \ + goto exceptionLabel; \ + } \ + } while ( 0 ) + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + RTK_GAP_TASK_TYPE_ADV_START = 0, + RTK_GAP_TASK_TYPE_ADV_STOP, + RTK_GAP_TASK_TYPE_UPDATE_ADV_PARAM, +} T_GAP_TASK_TYPE; + +typedef struct +{ + struct rtk_gap_task_t *p_next; + T_GAP_TASK_TYPE task_type; +} rtk_gap_task_t; + +typedef enum +{ + ADV_DATA_FINDMY = 0, +#if SUPPORT_CUSTOMIZED_APP + ADV_DATA_CUSTOMIZED, +#endif +#if GFPS_FEATURE_SUPPORT + ADV_DATA_GFPS, + ADV_DATA_FINDER, +#endif + + /*********/ + + ADV_DATA_CUSTOM_NEW, + + /*********/ + ADV_DATA_TYPE_MAX, +} T_ADV_DATA_TYPE; + +typedef struct +{ +#if ONE_SHOT_ADV_EN + bool just_change; + uint8_t bd_addr[GAP_BD_ADDR_LEN]; + T_GAP_LOCAL_ADDR_TYPE bd_addr_type; +#endif + uint8_t *p_adv_data; + uint8_t adv_data_len; + uint8_t *p_scan_rsp_data; + uint8_t scan_rsp_data_len; + uint16_t adv_interval; //Value range: 0x0020 - 0x4000 (20ms - 10240ms 0.625ms/step) + T_GAP_ADTYPE adv_type; +} T_ADV_DATA; + +#if ONE_SHOT_ADV_EN +typedef struct +{ + bool waiting_adv_param_update; + bool waiting_vendor_one_shot; + bool waiting_adv_addr_update; + bool pending_adv; + T_ADV_DATA_TYPE pending_adv_type; + T_ADV_DATA adv_data[ADV_DATA_TYPE_MAX]; + T_ADV_DATA_TYPE cur_adv_type; +} T_ONE_SHOT_DATA; +#endif + +/*============================================================================* + * Interface Functions + *============================================================================*/ +T_GAP_CAUSE fmble_gap_adv_start(T_ADV_DATA_TYPE adv_data_type); +T_GAP_CAUSE fmble_gap_adv_stop(T_ADV_DATA_TYPE adv_data_type); +T_GAP_CAUSE fmble_gap_adv_data_set(T_ADV_DATA adv_param, T_ADV_DATA_TYPE adv_data_type); +#if (!ONE_SHOT_ADV_EN) +void rtk_gap_task_init(void); +void rtk_gap_handle_msg(void); +void fmble_gap_dev_state_change(T_GAP_DEV_STATE state); +void fmble_gap_adv_cb(void); +#else +extern T_ONE_SHOT_DATA one_shot_adv_data; +void one_shot_adv_init(void); +void one_shot_adv_set_param(T_ADV_DATA_TYPE msg_sub_type); +void one_shot_handle_pending_adv(void); +void one_shot_adv_set_addr(void); +void one_shot_bt_addr_set(uint8_t bt_mac[GAP_BD_ADDR_LEN], \ + T_GAP_LOCAL_ADDR_TYPE bt_addr_type, \ + T_ADV_DATA_TYPE adv_data_type); + +#endif + +#endif /* findmy_ble_internal_h */ diff --git a/src/app/findmy/fmna_platform/fmna_gatt_platform.c b/src/app/findmy/fmna_platform/fmna_gatt_platform.c new file mode 100644 index 0000000..6a87fc1 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_gatt_platform.c @@ -0,0 +1,909 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_gatt_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_gatt_platform.h" +#include "fmna_platform_includes.h" +#include "fmna_constants.h" +#include "fmna_gatt.h" +#include "fmna_connection.h" +#include "fmna_util.h" +#include "findmy_app.h" +#include "app_task.h" +#include "os_msg.h" +#include "os_mem.h" +#include "os_sync.h" +#include "os_sched.h" +#include "bt_direct_msg.h" +#include "gap_conn_le.h" +#include "fmna_version.h" + +#ifdef USE_UARP +#include "fmna_uarp_control_point.h" +#endif +#if GFPS_FEATURE_SUPPORT +#include "app_gfps.h" +#endif +#if CUST_HID_SERVICE +#include "hids_kb.h" +#endif +#include "ias.h" +#include "sdd_service.h" +#include "dis.h" + +#include "ftl.h" +#include "fmna_constants_platform.h" +#include "fmna_state_machine.h" + +extern T_CUSTOM_DATA custom_data; +#define PASSWORD_LENGTH 7 +/*============================================================================* + * Local Variables + *============================================================================*/ +static uint8_t recent_conn_handle = BLE_CONN_HANDLE_INVALID; +static bool ind_complete_flag = true; +static T_GATT_DATA fmna_gatt_data; +#if SUPPORT_DYNAMIC_SERVICE +static void *service_chg_timer; +#endif + +//һλı洢ûõ +uint8_t password[PASSWORD_LENGTH] = {0}; + +//жǷͬ +bool password_correct = false; + +//һsdd_commander洢commanderеݵsdd_commander +uint8_t sdd_commander = 0; + +/*============================================================================* + * Global Functions + *============================================================================*/ +T_GATT_DATA fmna_gatt_platform_get_gatt_data(void) +{ + return fmna_gatt_data; +} + +/*============================================================================* + * Local Functions + *============================================================================*/ +#if SUPPORT_DYNAMIC_SERVICE +static void fmna_back_to_state_machine(void) +{ + for (uint16_t conn_handle = 0; conn_handle < MAX_SUPPORTED_CONNECTIONS; conn_handle++) + { + if (fmna_connection_is_valid_connection(conn_handle)) + { + fmna_connection_disconnected_handler(conn_handle); + break; + } + } +#if SUPPORT_CUSTOMIZED_APP + cust_resume_pending_ble_oprations(); +#endif +} + +/****************************************************************** + * @fn fmna_gatt_service_change_internal + * @brief The processing function that needs to clear the service table when the service mode changes + */ +static void fmna_gatt_service_change_internal(void) +{ + APP_PRINT_INFO1("[fmna_gatt_service_change_internal]chg_step:%d", fmna_gatt_data.chg_step); + switch (fmna_gatt_data.chg_step) + { +#if SUPPORT_CUSTOMIZED_APP + case SET_CUST_IDLE: + { + if (!cust_ble_set_to_idle()) + { + fmna_gatt_data.chg_step = SERVICE_CLEAR; + fmna_gatt_service_change_internal(); + } + } + break; +#endif + case SERVICE_CLEAR: + { + bool ret = server_clear_service(); + APP_PRINT_INFO1("server_clear_service ret=%d", ret); + } + break; + case ADD_SERVICE: + { + uint8_t remain_srv_num = 1; + bool ret = server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_TABLE, &remain_srv_num); + APP_PRINT_INFO1("server_set_service_reg_mode to TABLE ret=%d", ret); + //If there are other services, you need to add them here +#if CUST_HID_SERVICE + fmna_gatt_data.hid_kb_srv_id = hids_add_service(app_profile_callback); +#endif + fmna_gatt_data.ais_srv_id = accessory_info_add_service(app_profile_callback); + fmna_gatt_data.fns_srv_id = findmy_network_add_service(app_profile_callback); + fmna_gatt_data.tps_srv_id = tps_add_service(app_profile_callback); + if (fmna_gatt_data.cur_mode == NON_OWNER_SERVICE) + { + fmna_gatt_data.fwus_srv_id = 0xFF; + ret = server_set_service_reg_mode(SERVICE_REG_MODE_ADD_TO_STACK, &remain_srv_num); + APP_PRINT_INFO1("server_set_service_reg_mode to STACK ret=%d", ret); + } + } + break; + case FMNA_SRV_CHG_COMPLETE: + { + APP_PRINT_INFO1("Service mode change to %d", fmna_gatt_data.cur_mode); + os_timer_stop(&service_chg_timer); + fmna_gatt_data.chg_step = INVALID_STATE; + fmna_back_to_state_machine(); + } + break; + default: + APP_PRINT_WARN1("Unknown Service chg_step:%d", fmna_gatt_data.chg_step); + break; + } +} + +static void service_change_timer_callback(void) +{ + APP_PRINT_ERROR1("Service mode %d change failed!", fmna_gatt_data.cur_mode); + fmna_gatt_data.chg_step = INVALID_STATE; + fmna_back_to_state_machine(); +} + +#if SUPPORT_CUSTOMIZED_APP +void cust_connection_disconnect_gatt_handler(void) +{ + if (fmna_gatt_data.chg_step == SET_CUST_IDLE) + { + fmna_gatt_data.chg_step = SERVICE_CLEAR; + fmna_gatt_service_change_internal(); + } +} +#endif +#endif + +static void fmna_gatt_platform_set_indication_complete_flag(bool flag) +{ + ind_complete_flag = flag; +} + +static bool fmna_gatt_platform_get_indication_complete_flag(void) +{ + return ind_complete_flag; +} + +/****************************************************************** + * @fn app_general_srv_cb + * @brief General service callbacks are handled in this function. + * @param p_data - pointer to callback data + * @return cb_result + * @retval T_APP_RESULT + */ +static T_APP_RESULT app_general_srv_cb(T_SERVER_APP_CB_DATA *p_data) +{ + T_APP_RESULT cb_result = APP_RESULT_SUCCESS; + + T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_param->eventId) + { + case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event. + APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d", + p_param->event_data.service_reg_result); + break; +#if SUPPORT_DYNAMIC_SERVICE + case PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE: + APP_PRINT_INFO2("PROFILE_EVT_SRV_CLEAR_AFTER_INIT_COMPLETE, cause 0x%x, svc_changed_char_cccd_handle 0x%x", + p_param->event_data.clear_service_after_init_result.cause, + p_param->event_data.clear_service_after_init_result.svc_changed_char_cccd_handle); + fmna_gatt_data.fwus_srv_id = 0xFF; +#if CUST_HID_SERVICE + fmna_gatt_data.hid_kb_srv_id = 0xFF; +#endif + fmna_gatt_data.ais_srv_id = 0xFF; + fmna_gatt_data.fns_srv_id = 0xFF; + fmna_gatt_data.tps_srv_id = 0xFF; +#if GFPS_FEATURE_SUPPORT + gfps_db.gfps_srv_id = 0xFF; + gfps_db.dult_srv_id = 0xFF; +#endif + le_clear_cccd_data(0, NULL); + fmna_gatt_data.chg_step++; + fmna_gatt_service_change_internal(); + break; + + case PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE: + APP_PRINT_INFO0("PROFILE_EVT_SRV_REG_AFTER_INIT_COMPLETE"); + if (fmna_gatt_data.chg_step == ADD_SERVICE) + { + fmna_gatt_data.chg_step++; + fmna_gatt_service_change_internal(); + } + break; +#endif + case PROFILE_EVT_SEND_DATA_COMPLETE: + APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d", + p_param->event_data.send_data_result.conn_id, + p_param->event_data.send_data_result.cause, + p_param->event_data.send_data_result.service_id, + p_param->event_data.send_data_result.attrib_idx, + p_param->event_data.send_data_result.credits); + if (p_param->event_data.send_data_result.cause == GAP_SUCCESS) + { + APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success"); + if (fmna_connection_is_valid_connection(p_param->event_data.send_data_result.conn_id)) + { + if (memcmp_val(&fmna_service_current_extended_packet_tx, 0, + sizeof(fmna_service_current_extended_packet_tx))) + { + fmna_gatt_platform_set_indication_complete_flag(true); +#ifdef USE_UARP + if (p_param->event_data.send_data_result.service_id == fmna_gatt_data.fwus_srv_id) + { + APP_PRINT_INFO0("UARP Packet has finished being sent."); + fmna_uarp_packet_sent(); + } + else +#endif + { + APP_PRINT_INFO0("Indication has finished being sent."); + } + fmna_gatt_dispatch_send_next_packet(); + } + else + { + APP_PRINT_INFO0("sending packet extension indication"); + fmna_gatt_dispatch_send_packet_extension_indication(); + } + } + } + else + { + APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed"); + } + break; + + default: + break; + } + + return cb_result; +} + +/****************************************************************** + * @fn fmna_fns_srv_cb + * @brief Find my network service callbacks are handled in this function. + * @param p_data - pointer to callback data + * @return cb_result + * @retval T_APP_RESULT + */ +static T_APP_RESULT fmna_fns_srv_cb(SRV_CALLBACK_DATA *p_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + fmna_ret_code_t ret_code = FMNA_SUCCESS; + + SRV_CALLBACK_DATA *p_srv_data = p_data; + uint8_t conn_id = p_srv_data->conn_id; + + if (p_srv_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + if (fmna_connection_is_valid_connection(conn_id)) + { + switch (p_srv_data->msg_data.write.opcode) + { + case FMNA_FNS_PAIRING_CP_INDEX: + ret_code = fmna_gatt_pairing_char_authorized_write_handler(conn_id, FINDMY_UUID_PAIRING_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; + case FMNA_FNS_CONFIG_CP_INDEX: + ret_code = fmna_gatt_config_char_write_handler(conn_id, FINDMY_UUID_CONFIG_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; + case FMNA_FNS_NON_OWNER_CP_INDEX: + ret_code = fmna_gatt_nonown_char_write_handler(conn_id, FINDMY_UUID_NONOWN_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; + case FMNA_FNS_PAIRED_OWNER_CP_INDEX: + ret_code = fmna_gatt_paired_owner_char_write_handler(conn_id, FINDMY_UUID_PAIRED_OWNER_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; +#ifdef DEBUG + case FMNA_FNS_DEBUG_CP_INDEX: + ret_code = fmna_gatt_debug_char_write_handler(conn_id, FINDMY_UUID_DEBUG_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; +#endif //DEBUG + default: + APP_PRINT_ERROR2("[fns_attr_write_cb] Error: no such attrib_index 0x%x, length %d", + p_srv_data->msg_data.write.opcode, p_srv_data->msg_data.write.len); + break; + } + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR2("[fns_attr_write_cb] FMNA Error: attrib_index 0x%x, error code 0x%x", + p_srv_data->msg_data.write.opcode, ret_code); + } + } + } + return result; +} + +/****************************************************************** + * @fn fmna_fwus_srv_cb + * @brief Firmware update service callbacks are handled in this function. + * @param p_data - pointer to callback data + * @return cb_result + * @retval T_APP_RESULT + */ +#ifdef USE_UARP +static T_APP_RESULT fmna_fwus_srv_cb(SRV_CALLBACK_DATA *p_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + fmna_ret_code_t ret_code = FMNA_SUCCESS; + + SRV_CALLBACK_DATA *p_srv_data = p_data; + uint8_t conn_id = p_srv_data->conn_id; + + if (fmna_connection_is_valid_connection(conn_id)) + { + if (p_srv_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + switch (p_srv_data->msg_data.write.opcode) + { + case FMNA_FWUS_DATA_CTRL_INDEX: + ret_code = fmna_gatt_uarp_char_write_handler(conn_id, UARP_UUID_DATA_CHAR, + p_srv_data->msg_data.write.len, + p_srv_data->msg_data.write.p_value); + break; + default: + APP_PRINT_ERROR2("[fwus_attr_write_cb] Error: no such attrib_index 0x%x, length %d", + p_srv_data->msg_data.write.opcode, p_srv_data->msg_data.write.len); + break; + } + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR2("[fwus_attr_write_cb] FMNA Error: attrib_index 0x%x, error code 0x%x", + p_srv_data->msg_data.write.opcode, ret_code); + } + } + else if (p_srv_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION) + { + switch (p_srv_data->msg_data.nofity_indicate_update.notification_indification_index) + { + case FMNA_FWUS_DATA_CTRL_CCCD_INDEX: + if (p_srv_data->msg_data.nofity_indicate_update.cccbits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + APP_PRINT_INFO0("[fwus_attr_cccd_cb] FW update data ctrl indication enable"); + } + else + { + APP_PRINT_INFO0("[fwus_attr_cccd_cb] FW update data ctrl indication disable"); + } + break; + default: + break; + } + } + } + return result; +} +#endif + +static void app_bt_direct_callback(uint8_t cb_type, void *p_cb_data) +{ + T_BT_DIRECT_CB_DATA *p_data = (T_BT_DIRECT_CB_DATA *)p_cb_data; + if (cb_type == BT_DIRECT_MSG_GATT_SERVER_SERVICE_GET_ALLOW_INFO) + { + T_BT_DIRECT_GATT_SERVER_SERVICE_GET_ALLOW_INFO *p_allow_info_data = + (T_BT_DIRECT_GATT_SERVER_SERVICE_GET_ALLOW_INFO *) + p_data->p_bt_direct_gatt_server_service_get_allow_info; + uint8_t conn_id; + bool ret = le_get_conn_id_by_handle(p_allow_info_data->conn_handle, &conn_id); + APP_PRINT_INFO5("app_bt_direct_callback: conn_handle=%d, conn_id=%d, service_id=%d, attr_idx=%d, attr_handle=%d", + p_allow_info_data->conn_handle, conn_id, + p_allow_info_data->service_id, p_allow_info_data->attribute_idx, + p_allow_info_data->attribute_handle); +#if CUST_HID_SERVICE + if (p_allow_info_data->service_id == fmna_gatt_data.hid_kb_srv_id) + { + if (fmna_connection_is_valid_connection(conn_id)) + { + *(p_allow_info_data->p_use_flag) = true; + *(p_allow_info_data->p_allow) = false; + APP_PRINT_INFO0("findmy link not allow hid service"); + } + } +#endif + } +} + +/*============================================================================* + * Global Functions + *============================================================================*/ +void fmna_gatt_platform_services_init(void) +{ + APP_PRINT_INFO1("[fmna_gatt_platform_services_init] GATT services number=%d", GATT_SRV_NUM); + server_init(GATT_SRV_NUM+2); +#ifdef USE_UARP +#if SUPPORT_DYNAMIC_SERVICE + fmna_gatt_data.cur_mode = NON_OWNER_SERVICE; + fmna_gatt_data.fwus_srv_id = 0xFF; +#else + fmna_gatt_data.fwus_srv_id = firmware_update_add_service(app_profile_callback); +#endif +#endif +#if CUST_HID_SERVICE + fmna_gatt_data.hid_kb_srv_id = hids_add_service(app_profile_callback); +#endif + fmna_gatt_data.ais_srv_id = accessory_info_add_service(app_profile_callback); + fmna_gatt_data.fns_srv_id = findmy_network_add_service(app_profile_callback); + fmna_gatt_data.tps_srv_id = tps_add_service(app_profile_callback); + fmna_gatt_data.ias_srv_id = ias_add_service(app_profile_callback); + fmna_gatt_data.sdd_srv_id = sdd_add_service(app_profile_callback); + fmna_gatt_data.dis_srv_id = dis_add_service(app_profile_callback); + server_register_app_cb(app_profile_callback); + gap_register_direct_cb(app_bt_direct_callback); +} + +#if SUPPORT_DYNAMIC_SERVICE +void fmna_gatt_dynamic_service_change(T_SERVICE_MODE chg_mode) +{ + if (chg_mode == fmna_gatt_data.cur_mode) + { + APP_PRINT_INFO0("Service mode don't need to be changed"); + if (chg_mode == NON_OWNER_SERVICE) + { + fmna_back_to_state_machine(); + } + return; + } + + if (NULL == service_chg_timer) + { + os_timer_create(&service_chg_timer, "service_chg_timer", 1, \ + 5000, false, service_change_timer_callback); + } + + // fwus service remained to be added + if (chg_mode == OWNER_SERVICE && fmna_gatt_data.cur_mode == NON_OWNER_SERVICE) + { + fmna_gatt_data.fwus_srv_id = firmware_update_add_service(app_profile_callback); + fmna_gatt_data.cur_mode = chg_mode; + APP_PRINT_INFO1("Service mode change to %d", chg_mode); + } + else + { + os_timer_start(&service_chg_timer); +#if SUPPORT_CUSTOMIZED_APP + fmna_gatt_data.chg_step = SET_CUST_IDLE; +#else + fmna_gatt_data.chg_step = SERVICE_CLEAR; +#endif + fmna_gatt_data.cur_mode = chg_mode; + fmna_gatt_service_change_internal(); + } +} + +T_SERVICE_MODE fmna_gatt_get_service_mode(void) +{ + return fmna_gatt_data.cur_mode; +} + +#endif + +void fmna_gatt_platform_init(void) +{ + fmna_gatt_platform_services_init(); + +} + +uint16_t fmna_gatt_platform_get_most_recent_conn_handle(void) +{ + return recent_conn_handle; +} + +fmna_ret_code_t fmna_gatt_platform_send_indication(uint16_t conn_handle, + FMNA_Service_Opcode_t *p_opcode, + uint8_t *data, uint16_t length) +{ + T_SERVER_ID srv_id = 0xFF; + uint16_t attr_idx = 0xFFFF; + bool return_val; + // If indication needs to be fragmented TODO, check + if (*p_opcode == FMNA_SERVICE_OPCODE_PACKET_EXTENSION) + { + *p_opcode = fmna_service_current_extended_packet_tx.opcode; + } + + switch (*p_opcode & FMNA_SERVICE_OPCODE_BASE_MASK) + { + case FMNA_SERVICE_OPCODE_PAIRING_CONTROL_POINT_BASE: + srv_id = fmna_gatt_data.fns_srv_id; + attr_idx = FMNA_FNS_PAIRING_CP_INDEX; + break; + + case FMNA_SERVICE_OPCODE_CONFIG_CONTROL_POINT_BASE: + srv_id = fmna_gatt_data.fns_srv_id; + attr_idx = FMNA_FNS_CONFIG_CP_INDEX; + break; + + case FMNA_SERVICE_OPCODE_NON_OWNER_CONTROL_POINT_BASE: + srv_id = fmna_gatt_data.fns_srv_id; + attr_idx = FMNA_FNS_NON_OWNER_CP_INDEX; + break; + + case FMNA_SERVICE_OPCODE_PAIRED_OWNER_CONTROL_POINT_BASE: + srv_id = fmna_gatt_data.fns_srv_id; + attr_idx = FMNA_FNS_PAIRED_OWNER_CP_INDEX; + break; + +#ifdef DEBUG + case FMNA_SERVICE_OPCODE_DEBUG_CONTROL_POINT_BASE: + srv_id = fmna_gatt_data.fns_srv_id; + attr_idx = FMNA_FNS_DEBUG_CP_INDEX; + break; +#endif // DEBUG + +#ifdef USE_UARP + case FMNA_SERVICE_OPCODE_INTERNAL_UARP_BASE: + srv_id = fmna_gatt_data.fwus_srv_id; + attr_idx = FMNA_FWUS_DATA_CTRL_INDEX; + break; +#endif + + default: + APP_PRINT_INFO1("Unknown opcode: 0x%x", *p_opcode); + break; + } + + fmna_gatt_platform_set_indication_complete_flag(false); + return_val = server_send_data(conn_handle, srv_id, attr_idx, data, length, + GATT_PDU_TYPE_INDICATION); + return !return_val; +} + +uint8_t fmna_gatt_platform_send_indication_busy(uint16_t conn_handle, FMNA_Service_Opcode_t opcode, + void *data, uint16_t length) +{ + uint8_t queue_msg = 1; + uint8_t gap_link_credits = 0; + le_get_gap_param(GAP_PARAM_LE_REMAIN_CREDITS, &gap_link_credits); + + if (gap_link_credits > 0 && fmna_gatt_platform_get_indication_complete_flag()) + { + queue_msg = 0; + } + else + { + APP_PRINT_INFO0("fmna_gatt_platform_send_indication_busy send to msg"); + + /* BT indication queue message */ + T_BT_INDICATION indication_msg; + indication_msg.length = length; + indication_msg.conn_handle = conn_handle; + indication_msg.opcode = opcode; + indication_msg.buf = os_mem_alloc(RAM_TYPE_DATA_ON, length); + memcpy(indication_msg.buf, data, length); + + if (os_msg_send(bt_indication_queue, &indication_msg, 0) == false) + { + APP_PRINT_ERROR0("send to bt_indication_queue fail"); + } + } + + return queue_msg; +} + +void fmna_gatt_platform_reset_indication_queue(void) +{ + /* clear bt indication queue message*/ + T_BT_INDICATION msg; + while (os_msg_recv(bt_indication_queue, &msg, 0)) + { + APP_PRINT_INFO1("indication abondon, opcode %#x", msg.opcode); + } + fmna_gatt_platform_set_indication_complete_flag(true); +} + +uint8_t fmna_gatt_platform_get_next_command_response_index(void) +{ + uint8_t index; + uint32_t s = os_lock(); + index = m_command_response_index; + m_command_response_index++; + if (m_command_response_index <= MAX_CONTROL_POINT_RSP) + { + m_command_response_index = 0; + } + os_unlock(s); + return index; +} + +void fmna_gatt_platform_send_next_indication(void) +{ + T_BT_INDICATION msg; + if (os_msg_recv(bt_indication_queue, &msg, 0) == true) + { + fmna_gatt_send_indication(msg.conn_handle, msg.opcode, msg.buf, msg.length); + APP_PRINT_INFO0("bt_indication_queue recv, send next packet"); + os_mem_free(msg.buf); + } +} + +/****************************************************************** + * @fn app_profile_callback + * @brief All the BT Profile service callback events are handled in this function + * @note Then the event handling function shall be called according to the + * service_id + * @param service_id Profile service ID + * @param p_data Pointer to callback data + * @return T_APP_RESULT, which indicates the function call is successful or not + * @retval APP_RESULT_SUCCESS Function run successfully + * @retval others Function run failed, and return number indicates the reason + */ +T_APP_RESULT app_profile_callback(T_SERVER_ID service_id, void *p_data) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + app_general_srv_cb((T_SERVER_APP_CB_DATA *)p_data); + } + else if (service_id == fmna_gatt_data.ais_srv_id) + { + //Do Nothing + } + else if (service_id == fmna_gatt_data.fns_srv_id) + { + app_result = fmna_fns_srv_cb((SRV_CALLBACK_DATA *)p_data); + } +#ifdef USE_UARP + else if (service_id == fmna_gatt_data.fwus_srv_id) + { + app_result = fmna_fwus_srv_cb((SRV_CALLBACK_DATA *)p_data); + } +#endif + else if (service_id == fmna_gatt_data.tps_srv_id) + { + //Do Nothing + } + else if (service_id == fmna_gatt_data.sdd_srv_id) + { + T_SDD_CALLBACK_DATA *p_sdd_cb_data = (T_SDD_CALLBACK_DATA *)p_data; + switch (p_sdd_cb_data->msg_type) + { + case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION: + { + switch (p_sdd_cb_data->msg_data.notification_indification_index) + { + case SDD_NOTIFY_BATTERY_LEVEL_ENABLE: + { + APP_PRINT_INFO0("SDD_NOTIFY_BATTERY_LEVEL_ENABLE"); + } + break; + + case SDD_NOTIFY_BATTERY_LEVEL_DISABLE: + { + APP_PRINT_INFO0("SDD_NOTIFY_BATTERY_LEVEL_DISABLE"); + } + break; + default: + break; + } + } + break; + + case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE: + { + if (p_sdd_cb_data->msg_data.read_value_index == SDD_READ_BATTERY_LEVEL) + { + //uint8_t battery_level = 90; + extern uint8_t sdd_rssi_level ; + le_read_rssi(custom_data.cust_conn_id ); + APP_PRINT_INFO1("case SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE:SDD_READ_BATTERY_LEVEL: rssi_level %d", sdd_rssi_level); + + + } + } + break; + case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE: + { + APP_PRINT_INFO1("commander = %d ",p_sdd_cb_data->write_data[0]); + APP_PRINT_INFO6("password = %d %d %d %d %d %d ",p_sdd_cb_data->write_data[1],p_sdd_cb_data->write_data[2], + p_sdd_cb_data->write_data[3],p_sdd_cb_data->write_data[4],p_sdd_cb_data->write_data[5],p_sdd_cb_data->write_data[6]); + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,p_sdd_cb_data->write_data[6]); + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,0x02); + + // жpasswordеǷһΪ0Ϊ0p_sdd_cb_data->write_data[0]нյpassword + for(int i = 0;i<=6;i++){ + + password[i] = p_sdd_cb_data->write_data[i]; + + } + + ftl_save(password,FTL_SAVE_APP_PASSWORD_ADDR,FTL_SAVE_APP_PASSWORD_SIZE); + + for(int i = 0; i<=6;i++){ + + if(password[i] == p_sdd_cb_data->write_data[i]){ + + password_correct = true; + + }else { + password_correct = false; + } + + } + //password_correctΪfalseϿ + if(password_correct == false){ + cust_connection_disconnect_this(); + }else{ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,0x02); + + fmna_bat_state_level_t battey_level = fmna_battery_platform_get_battery_level(); + + uint8_t energy = battey_level; + + if(energy == 0){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,14); + + }else if(energy == 1){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,13); + + }else if(energy == 2){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,12); + + }else if(energy == 3){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,11); + + }else if(energy == 4){ + + sdd_battery_level_value_notify(custom_data.cust_conn_id ,fmna_gatt_data.sdd_srv_id,10); + + }else{ + + APP_PRINT_INFO0("---------------------------------------------------------------------------->missing msg"); + + } + + APP_PRINT_INFO1("----------------------------------------------------------------------------->ENERGY = %d",energy); + + } + + } + + + break; + + default: + break; + } + } + else if (service_id == fmna_gatt_data.ias_srv_id) + { + + T_SDD_CALLBACK_DATA *p_sdd_cb_data = (T_SDD_CALLBACK_DATA *)p_data; + + T_IAS_CALLBACK_DATA *p_ias_cb_data = (T_IAS_CALLBACK_DATA *)p_data; + APP_PRINT_ERROR0("IAS CallBack."); + if (p_ias_cb_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE) + { + uint8_t g_sdd_immediate_alert_level; + g_sdd_immediate_alert_level = p_ias_cb_data->msg_data.write_alert_level; + APP_PRINT_ERROR1("p_ias_cb_data->msg_data.write_alert_level=%d.",g_sdd_immediate_alert_level); + if (g_sdd_immediate_alert_level == 1) + { + + play_beep_mode(300,BEEP_MODE_FIVE); + + } + else if (g_sdd_immediate_alert_level == 2) + { + + play_beep_mode(300,BEEP_MODE_FIVE); + + } + else if(g_sdd_immediate_alert_level == 3) + { + + + } + else if (g_sdd_immediate_alert_level == 4) + { +// + } + else if (g_sdd_immediate_alert_level == 5) + { + APP_PRINT_INFO0 ("-------------------------------------->unbundle"); + } + else if (g_sdd_immediate_alert_level == 0) { + // ָ: 0x00 + APP_PRINT_INFO0("The unbinding instruction 0x00 has been obtained."); + + // ֤Ƿȷ + bool is_password_match = true; + T_SDD_CALLBACK_DATA *p_sdd_cb_data = (T_SDD_CALLBACK_DATA *)p_data; + + for(int i = 0; i < PASSWORD_LENGTH; i++) + { + if(p_sdd_cb_data->write_data[i+1] != password[i]) + { + is_password_match = false; + break; + } + } + + if(is_password_match && password_correct) + { + // ȷִн + APP_PRINT_INFO0("֤ɹִн"); + fmna_connection_fmna_unpair(true); + sdd_battery_level_value_notify(custom_data.cust_conn_id, fmna_gatt_data.sdd_srv_id, 0x04); // ɹ֪ͨ + } + } + else + { +// + } + } + } + return app_result; +} + + + +/// Function for handling the Connect event. +/// @param conn_id Event received from the BLE stack. +void on_connect(uint8_t conn_id) +{ + // The config handle servers as the most recently connected device. + // This allows for easier commnuication with the device during: + // Pairing lock + // UT Play sound + // connected / not encrypted devices + recent_conn_handle = conn_id; +#ifdef USE_UARP + if (fmna_connection_is_fmna_paired()) + { + fmna_uarp_connect(conn_id); + } +#endif +} + +/// Function for handling the Disconnect event. +/// @param conn_id Event received from the BLE stack. +void on_disconnect(uint8_t conn_id) +{ +#ifdef USE_UARP + if (fmna_connection_is_fmna_paired()) + { + fmna_uarp_disconnect(conn_id); + } +#endif + if (recent_conn_handle == conn_id) + { + recent_conn_handle = BLE_CONN_HANDLE_INVALID; + } +} + +/******************* (C) COPYRIGHT 2022 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/app/findmy/fmna_platform/fmna_gatt_platform.h b/src/app/findmy/fmna_platform/fmna_gatt_platform.h new file mode 100644 index 0000000..c9c8dac --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_gatt_platform.h @@ -0,0 +1,136 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_gatt_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +#ifndef fmna_gatt_platform_h +#define fmna_gatt_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_gatt.h" +#include "fmna_timer_platform.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Macros + *============================================================================*/ +#define BLE_CONN_HANDLE_INVALID 0xFF + +/*============================================================================* + * Types + *============================================================================*/ +#if SUPPORT_DYNAMIC_SERVICE +typedef enum +{ + OWNER_SERVICE = 0, + NON_OWNER_SERVICE, +} T_SERVICE_MODE; + +typedef enum +{ + INVALID_STATE, +#if SUPPORT_CUSTOMIZED_APP + SET_CUST_IDLE, +#endif + SERVICE_CLEAR, + ADD_SERVICE, + FMNA_SRV_CHG_COMPLETE, +} T_CHG_STEP; +#endif + +typedef struct +{ + T_SERVER_ID ais_srv_id; /**< Accessory information service id */ + T_SERVER_ID fns_srv_id; /**< FindMy network service id */ + T_SERVER_ID tps_srv_id; /**< Tx power service id */ +#ifdef USE_UARP + T_SERVER_ID fwus_srv_id; /**< Firmware update service id */ +#endif +#if CUST_HID_SERVICE + T_SERVER_ID hid_kb_srv_id; +#endif +#if SUPPORT_DYNAMIC_SERVICE + T_SERVICE_MODE cur_mode; + T_CHG_STEP chg_step; +#endif + T_SERVER_ID ias_srv_id; + T_SERVER_ID sdd_srv_id; + T_SERVER_ID dis_srv_id; + +} T_GATT_DATA; + +#ifndef SRV_CB +#define SRV_CB +typedef struct +{ + uint8_t opcode; + T_WRITE_TYPE write_type; + uint16_t len; + uint8_t *p_value; +} SRV_WRITE_MSG; + +typedef struct +{ + uint8_t notification_indification_index; + uint8_t cccbits; +} SRV_NOTIFY_MSG; + +typedef union +{ + SRV_NOTIFY_MSG nofity_indicate_update; + uint8_t read_value_index; + SRV_WRITE_MSG write; +} SRV_UPSTREAM_MSG_DATA; + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + SRV_UPSTREAM_MSG_DATA msg_data; +} SRV_CALLBACK_DATA; +#endif + +/*============================================================================* +* Global functions +*============================================================================*/ +void fmna_gatt_platform_init(void); +void fmna_gatt_platform_services_init(void); +#if SUPPORT_DYNAMIC_SERVICE +void fmna_gatt_dynamic_service_change(T_SERVICE_MODE chg_mode); +T_SERVICE_MODE fmna_gatt_get_service_mode(void); +#endif +#if SUPPORT_CUSTOMIZED_APP +void cust_connection_disconnect_gatt_handler(void); +#endif +uint16_t fmna_gatt_platform_get_most_recent_conn_handle(void); +fmna_ret_code_t fmna_gatt_platform_send_indication(uint16_t conn_handle, + FMNA_Service_Opcode_t *opcode, + uint8_t *data, uint16_t length); +uint8_t fmna_gatt_platform_send_indication_busy(uint16_t conn_handle, + FMNA_Service_Opcode_t opcode, + void *data, uint16_t length); +void fmna_gatt_platform_reset_indication_queue(void); +uint8_t fmna_gatt_platform_get_next_command_response_index(void); +void fmna_gatt_platform_send_next_indication(void); +T_GATT_DATA fmna_gatt_platform_get_gatt_data(void); +void on_connect(uint8_t conn_id); +void on_disconnect(uint8_t conn_id); + +#ifdef __cplusplus +} +#endif + +#endif /* fmna_gatt_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_malloc_platform.c b/src/app/findmy/fmna_platform/fmna_malloc_platform.c new file mode 100644 index 0000000..b4a71b9 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_malloc_platform.c @@ -0,0 +1,91 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_malloc_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_malloc_platform.h" +#include "os_mem.h" +#include "stdlib.h" +#include "trace.h" + +/*============================================================================* + * Local Variables + *============================================================================*/ +static T_MALLOC malloc_buf[BUF_TYPE_MAX_SIZE]; + +/*============================================================================* +* Global functions +*============================================================================*/ +void *fmna_malloc(T_BUF_TYPE type, uint16_t len) +{ + if (type >= BUF_TYPE_MAX_SIZE) + { + APP_PRINT_WARN1("buffer type %d wrong", type); + return NULL; + } + + if (malloc_buf[type].p_buf != NULL) + { + APP_PRINT_WARN2("buffer type %d has already allocated, len=%d!", type, malloc_buf[type].buf_len); + return NULL; + } + + malloc_buf[type].p_buf = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + if (malloc_buf[type].p_buf == NULL) + { + APP_PRINT_ERROR0("fmna malloc failed!"); + return NULL; + } + + malloc_buf[type].buf_len = len; + APP_PRINT_INFO3("fmna malloc type:%d -- %p len:%d", type, malloc_buf[type].p_buf, len); + + return malloc_buf[type].p_buf; +} + +void fmna_free(T_BUF_TYPE type) +{ + if (type >= BUF_TYPE_MAX_SIZE) + { + APP_PRINT_WARN1("buffer type %d wrong", type); + return; + } + + if (malloc_buf[type].p_buf == NULL) + { + APP_PRINT_WARN1("buffer type %d has already freed", type); + return; + } + + APP_PRINT_INFO2("fmna free type:%d -- %p", type, malloc_buf[type].p_buf); + os_mem_free(malloc_buf[type].p_buf); + malloc_buf[type].p_buf = NULL; + malloc_buf[type].buf_len = 0; + return; +} + +void fmna_all_pairing_buf_free(void) +{ + for (uint8_t i = SEND_PAIRING_DATA; i < PAIRING_RX_BUFFER + 1; i++) + { + if (malloc_buf[i].p_buf != NULL) + { + APP_PRINT_INFO2("fmna free type:%d -- %p", i, malloc_buf[i].p_buf); + os_mem_free(malloc_buf[i].p_buf); + malloc_buf[i].p_buf = NULL; + malloc_buf[i].buf_len = 0; + } + } + APP_PRINT_INFO0("fmna all pairng buffer freed on heap"); +} + diff --git a/src/app/findmy/fmna_platform/fmna_malloc_platform.h b/src/app/findmy/fmna_platform/fmna_malloc_platform.h new file mode 100644 index 0000000..8506195 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_malloc_platform.h @@ -0,0 +1,59 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_malloc_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ + +#ifndef FMNA_MALLOC_PLATFORM_H +#define FMNA_MALLOC_PLATFORM_H + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdbool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + SEND_PAIRING_DATA = 0, + INITIATE_PAIRING_DATA, + FINALIZE_PAIRING_DATA, + SEND_PAIRING_STATUS, + MFI_RAW_TOKEN, + PAIRING_RX_BUFFER, + ENCRYPTED_SN, + BUF_TYPE_MAX_SIZE //Maximum value marker +} T_BUF_TYPE; + +typedef struct +{ + uint16_t buf_len; + void *p_buf; +} T_MALLOC; + +/*============================================================================* +* Global functions +*============================================================================*/ +void *fmna_malloc(T_BUF_TYPE type, uint16_t len); +void fmna_free(T_BUF_TYPE type); +void fmna_all_pairing_buf_free(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/app/findmy/fmna_platform/fmna_motion_detection_platform.c b/src/app/findmy/fmna_platform/fmna_motion_detection_platform.c new file mode 100644 index 0000000..5d9d396 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_motion_detection_platform.c @@ -0,0 +1,150 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_motion_detection_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_motion_detection_platform.h" +#include "fmna_constants_platform.h" +#include "rtl876x_pinmux.h" +#include "rtl876x_rcc.h" +#include "rtl876x_i2c.h" +#include "trace.h" +#if USE_DA213B_SENSOR +#include "da213b.h" +#endif + +/*============================================================================* + * Global variables + *============================================================================*/ +bool is_motion_detection_start; + +/*============================================================================* + * Local functions + *============================================================================*/ +#if USE_DA213B_SENSOR +/** + * @brief Initialize DA213B I2C communication. + * @param No parameter. + * @return void + */ +static void da213b_i2c_driver_init(void) +{ + /* Initialize I2C peripheral */ + RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE); + I2C_Cmd(I2C0, DISABLE); + + I2C_InitTypeDef I2C_InitStruct; + I2C_StructInit(&I2C_InitStruct); + + I2C_InitStruct.I2C_ClockSpeed = DA213B_CLK; + I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master; + I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT; + I2C_InitStruct.I2C_SlaveAddress = DA213B_ADDR; + I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + + I2C_Init(I2C0, &I2C_InitStruct); + I2C_Cmd(I2C0, ENABLE); +} + +/** + * @brief Deinitialize I2C Master peripheral. + * @param No parameter. + * @return void + */ +static void da213b_i2c_driver_deinit(void) +{ + I2C_Cmd(I2C0, DISABLE); +} + +/*============================================================================* +* Global functions +*============================================================================*/ +/** + * @brief Initialization of pinmux settings and pad settings. + * @param No parameter. + * @return void +*/ +void board_i2c_master_init(void) +{ + Pad_Config(I2C_DA213B_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, + PAD_OUT_HIGH); + Pad_Config(I2C_DA213B_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, + PAD_OUT_HIGH); + + Pinmux_Config(I2C_DA213B_SCL_PIN, I2C0_CLK); + Pinmux_Config(I2C_DA213B_SDA_PIN, I2C0_DAT); +} + +/** + * @brief Deinitialization of pinmux settings and pad settings. + * @param No parameter. + * @return void +*/ +void board_i2c_master_deinit(void) +{ + Pad_Config(I2C_DA213B_SCL_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + Pad_Config(I2C_DA213B_SDA_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); +} +#endif + +void fmna_motion_detection_platform_init(void) +{ + APP_PRINT_INFO0("fmna_motion_detection_platform_init"); + is_motion_detection_start = true; +#if USE_DA213B_SENSOR + /* Configure pad and pinmux firstly! */ + board_i2c_master_init(); + + /* Initialize i2c peripheral */ + da213b_i2c_driver_init(); + + /* Initialize DA213B peripheral */ + if (!da213b_init()) + { + APP_PRINT_ERROR0("DA213B init failed!"); + } +#endif +} + +void fmna_motion_detection_platform_deinit(void) +{ + if (!is_motion_detection_start) + { + return; + } + APP_PRINT_INFO0("fmna_motion_detection_platform_deinit"); + is_motion_detection_start = false; + +#if USE_DA213B_SENSOR + if (!da213b_deinit()) + { + APP_PRINT_ERROR0("DA213B deinit failed!"); + } + + da213b_i2c_driver_deinit(); + board_i2c_master_deinit(); +#endif +} + +bool fmna_motion_detection_platform_is_motion_detected(void) +{ + bool mt_flag = false; + +#if USE_DA213B_SENSOR + mt_flag = da213b_check_motion_flag(); +#endif + return mt_flag; +} + diff --git a/src/app/findmy/fmna_platform/fmna_motion_detection_platform.h b/src/app/findmy/fmna_platform/fmna_motion_detection_platform.h new file mode 100644 index 0000000..3d35fbe --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_motion_detection_platform.h @@ -0,0 +1,24 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_motion_detection_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +#ifndef fmna_motion_detection_platform_h +#define fmna_motion_detection_platform_h + +#include "stdbool.h" + +void board_i2c_master_init(void); +void board_i2c_master_deinit(void); +void fmna_motion_detection_platform_init(void); +void fmna_motion_detection_platform_deinit(void); +bool fmna_motion_detection_platform_is_motion_detected(void); + +#endif /* fmna_motion_detection_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_nfc_platform.c b/src/app/findmy/fmna_platform/fmna_nfc_platform.c new file mode 100644 index 0000000..8e02224 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_nfc_platform.c @@ -0,0 +1,176 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_nfc_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2022-11-17 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_nfc_platform.h" +#include "fmna_constants.h" +#include "rtl876x_rcc.h" +#include "rtl876x_gpio.h" +#include "rtl876x_pinmux.h" +#include "rtl876x_nvic.h" +#include "rtl876x_i2c.h" +#include "os_sched.h" +#include "FM11NT082C.h" +#include "url_ndef.h" + +#if SUPPORT_NFC +/*============================================================================* + * Macros + *============================================================================*/ +#define NFC_CS_ON Pad_Config(FM11_CSN_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW) +#define NFC_CS_OFF Pad_Config(FM11_CSN_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH) + +/*============================================================================* +* Global Functions +*============================================================================*/ +void nfc_board_init(void) +{ + /* FM11 IRQN board config */ + Pinmux_Config(FM11_IRQN_PIN, DWGPIO); //TODO: CHECK FM11 IRQ CONFIG + Pad_Config(FM11_IRQN_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + + /* FM11 I2C board config */ + Pad_Config(I2C_FM11_SCL_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, + PAD_OUT_HIGH); + Pad_Config(I2C_FM11_SDA_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_ENABLE, + PAD_OUT_HIGH); + + Pinmux_Config(I2C_FM11_SCL_PIN, I2C0_CLK); + Pinmux_Config(I2C_FM11_SDA_PIN, I2C0_DAT); +} + +void nfc_board_deinit(void) +{ + NFC_CS_OFF; + + Pad_Config(FM11_IRQN_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + + Pad_Config(I2C_FM11_SCL_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); + Pad_Config(I2C_FM11_SDA_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_HIGH); +} + +void nfc_gpio_driver_init(void) +{ + RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE); + GPIO_InitTypeDef GPIO_init_struct; + GPIO_StructInit(&GPIO_init_struct); + + GPIO_init_struct.GPIO_Pin = GPIO_FM11_IRQN_PIN; + GPIO_init_struct.GPIO_Mode = GPIO_Mode_IN; + GPIO_init_struct.GPIO_ITCmd = ENABLE; + GPIO_init_struct.GPIO_ITTrigger = GPIO_INT_Trigger_EDGE; + GPIO_init_struct.GPIO_ITDebounce = GPIO_INT_DEBOUNCE_ENABLE; + GPIO_init_struct.GPIO_DebounceTime = 1; + GPIO_init_struct.GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + + GPIO_Init(&GPIO_init_struct); + + NVIC_InitTypeDef NVIC_init_struct; + NVIC_init_struct.NVIC_IRQChannel = GPIO_FM11_IRQ; + NVIC_init_struct.NVIC_IRQChannelCmd = ENABLE; + NVIC_init_struct.NVIC_IRQChannelPriority = 3; + NVIC_Init(&NVIC_init_struct); + + GPIO_ClearINTPendingBit(GPIO_FM11_IRQN_PIN); + GPIO_MaskINTConfig(GPIO_FM11_IRQN_PIN, DISABLE); + GPIO_INTConfig(GPIO_FM11_IRQN_PIN, ENABLE); +} + +/** + * @brief Initialize FM11NT082C I2C communication. + * @param No parameter. + * @return void + */ +void nfc_i2c_driver_init(void) +{ + /* Initialize I2C peripheral */ + RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, ENABLE); + I2C_Cmd(I2C0, DISABLE); + + I2C_InitTypeDef I2C_InitStruct; + I2C_StructInit(&I2C_InitStruct); + + I2C_InitStruct.I2C_ClockSpeed = FM11_CLK; + I2C_InitStruct.I2C_DeviveMode = I2C_DeviveMode_Master; + I2C_InitStruct.I2C_AddressMode = I2C_AddressMode_7BIT; + I2C_InitStruct.I2C_SlaveAddress = FM11_ADDR; + I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; + + I2C_Init(I2C0, &I2C_InitStruct); + I2C_Cmd(I2C0, ENABLE); +} + +void nfc_i2c_driver_deinit(void) +{ + I2C_Cmd(I2C0, DISABLE); +} + +fmna_ret_code_t fmna_nfc_platform_init(void) +{ + fmna_ret_code_t ret; + //TODO: Initialize NFC peripheral, and activate. + nfc_i2c_driver_init(); + + /* FM11 CS ON, must delay more than 250us */ + NFC_CS_ON; + os_delay(10); + + if (FM11_Init()) + { + APP_PRINT_INFO0("[fmna_nfc_platform_init] FM11 init succeed"); + ret = FMNA_SUCCESS; + } + else + { + APP_PRINT_INFO0("[fmna_nfc_platform_init] FM11 init failed"); + ret = FMNA_ERROR_INTERNAL; + } + + NFC_CS_OFF; + nfc_i2c_driver_deinit(); + + return ret; +} + +fmna_ret_code_t fmna_nfc_write_ndef(void) +{ + fmna_ret_code_t ret; + nfc_i2c_driver_init(); + + /* FM11 CS ON, must delay more than 250us */ + NFC_CS_ON; + os_delay(1); + + if (FM11_WriteE2(NDEF_Buffer, FM441_NDEF_Header_EEaddress, NDEF_length + 2)) + { + APP_PRINT_INFO0("[fmna_nfc_write_ndef] FM11 Write EEPROM succeed"); + ret = FMNA_SUCCESS; + } + else + { + APP_PRINT_ERROR0("[fmna_nfc_write_ndef] FM11 Write EEPROM failed"); + ret = FMNA_ERROR_INTERNAL; + } + + NFC_CS_OFF; + nfc_i2c_driver_deinit(); + + return ret; +} + +#endif diff --git a/src/app/findmy/fmna_platform/fmna_nfc_platform.h b/src/app/findmy/fmna_platform/fmna_nfc_platform.h new file mode 100644 index 0000000..551ff79 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_nfc_platform.h @@ -0,0 +1,34 @@ +/* +* Copyright (C) 2020 Apple Inc. All Rights Reserved. +* +* Find My Network ADK is licensed under Apple Inc.'s MFi Sample Code License Agreement, +* which is contained in the License.txt file distributed with the Find My Network ADK, +* and only to those who accept that license. +*/ + +#ifndef fmna_nfc_platform_h +#define fmna_nfc_platform_h + +#include "fmna_constants.h" +#include "fmna_platform_includes.h" +#include "board.h" + +#if SUPPORT_NFC +#define FM11_CSN_PIN P4_1 +#define FM11_IRQN_PIN P1_0 +#define I2C_FM11_SCL_PIN P2_4 +#define I2C_FM11_SDA_PIN P2_5 + +#define GPIO_FM11_IRQN_PIN GPIO_GetPin(FM11_IRQN_PIN) +#define GPIO_FM11_IRQ GPIO8_IRQn +#define fm11_irqn_handler GPIO8_Handler +#endif + +void nfc_board_init(void); +void nfc_board_deinit(void); + +/// Initialize platform NFC peripheral. +fmna_ret_code_t fmna_nfc_platform_init(void); +fmna_ret_code_t fmna_nfc_write_ndef(void); + +#endif /* fmna_nfc_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_peer_manager.c b/src/app/findmy/fmna_platform/fmna_peer_manager.c new file mode 100644 index 0000000..ceebaab --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_peer_manager.c @@ -0,0 +1,50 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_peer_manager.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_platform_includes.h" +#include "fmna_peer_manager.h" +#include "fmna_state_machine.h" +#include "fmna_connection.h" + +/*============================================================================* + * Global Functions + *============================================================================*/ +uint8_t fmna_pm_peer_count(void) +{ + uint8_t bond_num = le_get_bond_dev_num(); + APP_PRINT_INFO1("[fmna_pm_peer_count]bond_num = %d", bond_num); + return bond_num; +} + +void fmna_pm_delete_bonds(void) +{ + if (app_global_data.app_bond_idx[FINDMY_BOND] != 0xFF) + { + APP_PRINT_INFO0("Erase findmy bond!"); + le_bond_delete_by_idx(app_global_data.app_bond_idx[FINDMY_BOND]); + } +} + +void fmna_pm_conn_sec_handle(uint16_t conn_handle) +{ + APP_PRINT_INFO1("PM Conn secured: conn_handle: 0x%x.", conn_handle); + + // mark as encrypted in the connection record + fmna_connection_update_connection_info(conn_handle, FMNA_MULTI_STATUS_ENCRYPTED, true); + + // BT pairing completed successfully/ link was encrypted. Send BONDED event to state machine. + fmna_evt_handler(FMNA_SM_EVENT_BONDED, &conn_handle); +} + diff --git a/src/app/findmy/fmna_platform/fmna_peer_manager.h b/src/app/findmy/fmna_platform/fmna_peer_manager.h new file mode 100644 index 0000000..5cdaef2 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_peer_manager.h @@ -0,0 +1,31 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_peer_manager.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +#ifndef fmna_peer_manager_h +#define fmna_peer_manager_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_constants.h" + +/*============================================================================* + * Interface Functions + *============================================================================*/ +// Check how many devices we are paired to. +uint8_t fmna_pm_peer_count(void); + +/// Delete all BT pairing records. +void fmna_pm_delete_bonds(void); + +void fmna_pm_conn_sec_handle(uint16_t conn_handle); +#endif /* fmna_peer_manager_h */ diff --git a/src/app/findmy/fmna_platform/fmna_platform_includes.h b/src/app/findmy/fmna_platform/fmna_platform_includes.h new file mode 100644 index 0000000..ad8d4f2 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_platform_includes.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Apple Inc. All Rights Reserved. + * + * Find My Network ADK is licensed under Apple Inc.'s MFi Sample Code License Agreement, + * which is contained in the License.txt file distributed with the Find My Network ADK, + * and only to those who accept that license. + */ + +#ifndef fmna_platform_includes_h +#define fmna_platform_includes_h + +#include "stdbool.h" +#include "stdio.h" +#include "string.h" +#include "board.h" +#include "trace.h" +#include "ftl.h" +#include "os_msg.h" +#include "os_mem.h" +#include "os_timer.h" +#include "flash_map.h" +#include "system_rtl876x.h" +#include "gap_bond_le.h" +#include "app_msg.h" +#include "app_task.h" +#include "findmy_app.h" +#include "key_crypto.h" +#include "tps.h" +#include "accessory_info_service.h" +#include "findmy_network_service.h" +#include "firmware_update_service.h" +#include "fmna_gap_platform.h" +#include "fmna_adv_platform.h" +#include "fmna_dfu_platform.h" +#include "fmna_gatt_platform.h" +#include "fmna_sound_platform.h" +#include "fmna_timer_platform.h" +#include "fmna_malloc_platform.h" +#include "fmna_battery_platform.h" +#include "fmna_constants_platform.h" +#include "fmna_connection_platform.h" +#include "fmna_motion_detection_platform.h" + +#endif /* fmna_platform_includes_h */ diff --git a/src/app/findmy/fmna_platform/fmna_sound_platform.c b/src/app/findmy/fmna_platform/fmna_sound_platform.c new file mode 100644 index 0000000..442e9be --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_sound_platform.c @@ -0,0 +1,562 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_sound_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_util.h" +#include "fmna_sound_platform.h" +#include "fmna_timer_platform.h" +#include "fmna_state_machine.h" +#include "rtl876x_pinmux.h" +#include "rtl876x_rcc.h" +#include "rtl876x_tim.h" +#include "trace.h" +#include "os_sched.h" +#if GFPS_FEATURE_SUPPORT +#include "app_gfps_finder.h" +#include "app_dult.h" +#endif + +/*============================================================================* + * Macros + *============================================================================*/ +#if SOUND_LED_EN +#define led_on Pad_Config(SOUND_LED_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH) +#define led_off Pad_Config(SOUND_LED_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW) + +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER +/** Define TIM num and pinmux of PWM output. + * Timer2 to Timer5 all have PWM output function. + * But only Timer2 support PWM complementary output function, other timers do not support it. + */ +#define PWM_TIMER_NUM TIM2 +#define PWM_OUT_PIN_PINMUX TIM_PWM2 //timer_pwm2 + +/* Config PWM_PERIOD and PWM_DUTY_CYCLE */ +#define PWM_PERIOD(freq) (1000000/(freq)) //uint:us +#define PWM_DUTY_CYCLE 50 //uint:percent +#define PWM_HIGH_COUNT(freq) ((PWM_PERIOD(freq))*(PWM_DUTY_CYCLE*40)/100-1) //PWM CLOCK = 40M +#define PWM_LOW_COUNT(freq) ((PWM_PERIOD(freq))*(100-PWM_DUTY_CYCLE)*40/100-1) + +#define BEEP_INTERVAL_MS 100 // 100ms + +#endif + +/*============================================================================* + * Functions Declaration + *============================================================================*/ +static void fmna_sound_timeout_handler(void *p_context); + +static void beep_sequence_handler(void *p_context); //д + +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER +static void buzzer_init(bool enable, uint16_t pwm_freq); +bool sound_en; +#endif + +/*============================================================================* + * Local Variables + *============================================================================*/ +APP_TIMER_DEF(m_fmna_sound_timeout_timer_id); /** Sound timeout timer id*/ + +APP_TIMER_DEF(m_beep_sequence_timer_id); /**жʱ */ + +//static Sound_Event_t cur_event = SOUND_EVENT_NONE; + +/*****************************************************************************/ +/*============================================================================* + * Ľṹ + *============================================================================*/ +typedef struct +{ + Sound_Event_t event; + uint32_t duration_ms; + uint16_t pwm_freq; + bool is_playing; + uint32_t start_time; +} Sound_Context_t; + +// Ľṹ +typedef struct +{ + Beep_Mode_t mode; + uint32_t beep_duration; + uint16_t pwm_freq; + uint8_t current_beep_count; + uint8_t total_beep_count; + bool is_active; +} Beep_Sequence_Context_t; + +static Sound_Context_t sound_context = { + .event = SOUND_EVENT_NONE, + .duration_ms = 0, + .pwm_freq = 0, + .is_playing = false, + .start_time = 0 +}; + +static Beep_Sequence_Context_t beep_sequence_context = { + .mode = BEEP_MODE_SINGLE, + .beep_duration = 0, + .pwm_freq = 0, + .current_beep_count = 0, + .total_beep_count = 0, + .is_active = false +}; + +/*****************************************************************************/ + +/*============================================================================* + * Local functions + *============================================================================*/ +/******************************************************************************/ + +/** + * @brief ִеη + */ +static void execute_single_beep(uint32_t duration, uint16_t pwm_freq) +{ +#if SOUND_LED_EN + led_on; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(true, pwm_freq); +#endif + + // õηijʱʱ + fmna_ret_code_t ret = app_timer_start(m_fmna_sound_timeout_timer_id, duration, NULL); + if (ret != FMNA_SUCCESS) + { + APP_PRINT_ERROR0("Failed to start single beep timer"); +#if SOUND_LED_EN + led_off; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + } +} + + +/** + * @brief д + */ +static void beep_sequence_handler(void *p_context) +{ + if (!beep_sequence_context.is_active) + { + return; + } + + // ִеǰ + execute_single_beep(beep_sequence_context.beep_duration, beep_sequence_context.pwm_freq); + + os_delay(100); + + // ͣ +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + + beep_sequence_context.current_beep_count++; + + APP_PRINT_INFO2("Beep sequence: %d/%d", + beep_sequence_context.current_beep_count, + beep_sequence_context.total_beep_count); + + // Ƿз + if (beep_sequence_context.current_beep_count >= beep_sequence_context.total_beep_count) + { + beep_sequence_context.is_active = false; + APP_PRINT_INFO0("Beep sequence completed"); + } + else + { + // һηĶʱ + fmna_ret_code_t ret = app_timer_start(m_beep_sequence_timer_id, + BEEP_INTERVAL_MS, NULL); + if (ret != FMNA_SUCCESS) + { + APP_PRINT_ERROR0("Failed to start next beep timer"); + beep_sequence_context.is_active = false; + } + } +} + + +/******************************************************************************/ + +static void fmna_sound_timeout_handler(void *p_context) +{ + +#if SOUND_LED_EN + led_off; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + + // Ƿеһ֣Ҫ¼ص + if (beep_sequence_context.is_active) + { + // beep_sequence_handler + return; + } + APP_PRINT_INFO1("fmna_sound_timeout_handler cur_event=%d", sound_context.event); + // 浱ǰ¼Ȼ + Sound_Event_t completed_event = sound_context.event; + + // ״̬ + sound_context.is_playing = false; + sound_context.event = SOUND_EVENT_NONE; + sound_context.duration_ms = 0; + sound_context.pwm_freq = 0; + sound_context.start_time = 0; + + // ʹñcompleted_eventcur_event + switch (completed_event) + { + case SOUND_EVENT_FMNA: + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_COMPLETE); + break; +#if GFPS_FEATURE_SUPPORT + case SOUND_EVENT_GFPS_FINDER: + app_gfps_finder_set_ring_type(GFPS_RING_STOP, GFPS_FINDER_RING_TIMEOUT_STOP); + break; + case SOUND_EVENT_DULT: + app_dult_sound_callback(APP_DULT_SOUND_COMPLETE); + break; +#endif + default: + APP_PRINT_ERROR1("sound event error: unknown event type %d!!!", completed_event); + break; + } +} + +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER +static void driver_pwm_init(void) +{ + RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + + TIM_TimeBaseInitTypeDef TIM_InitStruct; + TIM_StructInit(&TIM_InitStruct); + TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + TIM_InitStruct.TIM_PWM_En = PWM_ENABLE; + TIM_InitStruct.TIM_PWM_High_Count = PWM_HIGH_COUNT(PWM_FREQ); + TIM_InitStruct.TIM_PWM_Low_Count = PWM_LOW_COUNT(PWM_FREQ); + TIM_InitStruct.PWM_Stop_State_P = PWM_STOP_AT_HIGH; + TIM_InitStruct.PWM_Stop_State_N = PWM_STOP_AT_LOW; + TIM_InitStruct.PWMDeadZone_En = DEADZONE_DISABLE; //disable to use pwn p/n output + TIM_TimeBaseInit(PWM_TIMER_NUM, &TIM_InitStruct); +} + +static void buzzer_init(bool enable, uint16_t pwm_freq) +{ + if (enable && pwm_freq > 0) + { +#if USE_PAM8904_BUZZER + Pad_Config(PAM8904_EN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH); +#endif + Pad_Config(PWM_OUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH); + Pinmux_Config(PWM_OUT_PIN, PWM_OUT_PIN_PINMUX); + TIM_PWMChangeFreqAndDuty(PWM_TIMER_NUM, PWM_HIGH_COUNT(pwm_freq), PWM_LOW_COUNT(pwm_freq)); + TIM_Cmd(PWM_TIMER_NUM, ENABLE); + sound_en = true; + } + else + { + TIM_Cmd(PWM_TIMER_NUM, DISABLE); +#if USE_PAM8904_BUZZER + Pad_Config(PAM8904_EN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); +#endif + Pad_Config(PWM_OUT_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); + sound_en = false; + } +} +#endif + +/*============================================================================* +* Global functions +*============================================================================*/ + +/*****************************************************************************/ +/*============================================================================* +* ״̬ѯӿʵ +*============================================================================*/ +bool fmna_sound_is_playing(void) +{ + return sound_context.is_playing || beep_sequence_context.is_active; +} + +Sound_Event_t fmna_sound_get_current_event(void) +{ + return sound_context.event; +} + +uint32_t fmna_sound_get_remaining_time(void) +{ + if (!sound_context.is_playing || sound_context.duration_ms == 0) + return 0; + + uint32_t current_time = os_sys_time_get(); // ȡǰϵͳʱ䣨룩 + uint32_t elapsed_time = current_time - sound_context.start_time; + + if (elapsed_time >= sound_context.duration_ms) + return 0; + + return sound_context.duration_ms - elapsed_time; +} + +/*****************************************************************************/ + +void fmna_sound_platform_init(void) +{ + + // ʼ + sound_context.event = SOUND_EVENT_NONE; + sound_context.duration_ms = 0; + sound_context.pwm_freq = 0; + sound_context.is_playing = false; + sound_context.start_time = 0; + + // ʼ + beep_sequence_context.mode = BEEP_MODE_SINGLE; + beep_sequence_context.beep_duration = 0; + beep_sequence_context.pwm_freq = 0; + beep_sequence_context.current_beep_count = 0; + beep_sequence_context.total_beep_count = 0; + beep_sequence_context.is_active = false; + + fmna_ret_code_t ret_code = app_timer_create(&m_fmna_sound_timeout_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + fmna_sound_timeout_handler); + FMNA_ERROR_CHECK(ret_code); + + // жʱ + ret_code = app_timer_create(&m_beep_sequence_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + beep_sequence_handler); + FMNA_ERROR_CHECK(ret_code); + +#if USE_ACTIVE_BUZZER + driver_pwm_init(); + Pad_Config(PWM_OUT_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); +#elif USE_PAM8904_BUZZER + driver_pwm_init(); + Pad_Config(PAM8904_EN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); + Pad_Config(PWM_OUT_PIN, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_HIGH); +#endif +} + +void fmna_sound_platform_start(Sound_Event_t event, uint32_t duration_ms, uint16_t pwm_freq) +{ + /*if (cur_event != SOUND_EVENT_NONE) + { + APP_PRINT_ERROR1("fmna_sound_platform_start another event %d is executing", cur_event); + return; + } + cur_event = event;*/ + + // ǷѾڲ + if (sound_context.is_playing) + { + APP_PRINT_INFO2("Sound event %d is busy, new event %d will be ignored", + sound_context.event, event); + return; + } + + // + sound_context.event = event; + sound_context.duration_ms = duration_ms; + sound_context.pwm_freq = pwm_freq; + sound_context.is_playing = true; + sound_context.start_time = os_sys_time_get(); // ¼ʼʱ + APP_PRINT_INFO0("Sound starting..."); + +#if GFPS_FEATURE_SUPPORT + if (event == SOUND_EVENT_DULT) + { + app_dult_sound_callback(APP_DULT_SOUND_SUCCESS); + } +#endif + +#if SOUND_LED_EN + led_on; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(true, pwm_freq); +#endif + fmna_ret_code_t ret_code = app_timer_start(m_fmna_sound_timeout_timer_id, + duration_ms, + NULL); + + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR0("Failed to start sound timeout timer"); + + // ʱʧܣֹͣ +#if SOUND_LED_EN + led_off; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + sound_context.is_playing = false; + sound_context.event = SOUND_EVENT_NONE; + } + else + { + APP_PRINT_INFO2("Sound started: event=%d, duration=%dms", event, duration_ms); + } + + FMNA_ERROR_CHECK(ret_code); +} + +void fmna_sound_platform_stop(Sound_Event_t event) +{ + + if (!sound_context.is_playing) + { + APP_PRINT_INFO0("No sound is playing, stop operation ignored"); + return; + } + + // ¼Ƿƥ + if (sound_context.event != event) + { + APP_PRINT_WARN2("Stop event %d doesn't match current event %d", + event, sound_context.event); + return; + } + + + // ֹͣ + if (beep_sequence_context.is_active) + { + app_timer_stop(m_beep_sequence_timer_id); + beep_sequence_context.is_active = false; + APP_PRINT_INFO0("Beep sequence stopped"); + } + + + fmna_ret_code_t ret_code = app_timer_stop(m_fmna_sound_timeout_timer_id); + if (ret_code != FMNA_SUCCESS) + { + APP_PRINT_ERROR0("Failed to stop sound timer"); + } + FMNA_ERROR_CHECK(ret_code); + +#if SOUND_LED_EN + led_off; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + + // 浱ǰ¼ڻص +// Sound_Event_t stopped_event = sound_context.event; + + // ״̬ + sound_context.is_playing = false; + sound_context.event = SOUND_EVENT_NONE; + sound_context.duration_ms = 0; + sound_context.pwm_freq = 0; + sound_context.start_time = 0; + + // ֹͣͨ + if (sound_context.is_playing && sound_context.event == event) + { + app_timer_stop(m_fmna_sound_timeout_timer_id); + +#if SOUND_LED_EN + led_off; +#elif USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + buzzer_init(false, 0); +#endif + + Sound_Event_t stopped_event = sound_context.event; + sound_context.is_playing = false; + sound_context.event = SOUND_EVENT_NONE; + + switch (stopped_event) + { + case SOUND_EVENT_FMNA: + fmna_state_machine_dispatch_event(FMNA_SM_EVENT_SOUND_COMPLETE); + break; +#if GFPS_FEATURE_SUPPORT + case SOUND_EVENT_GFPS_FINDER: + break; + case SOUND_EVENT_DULT: + app_dult_sound_callback(APP_DULT_SOUND_COMPLETE); + break; +#endif + default: + break; + } + } +// cur_event = SOUND_EVENT_NONE; + APP_PRINT_INFO0("Sound successfully stopped"); +} + +/** + * @brief ģʽ + * @param duration ηʱ + * @param mode ģʽ + */ +void play_beep_mode(uint32_t duration, Beep_Mode_t mode) +{ + if (fmna_sound_is_playing()) + { + APP_PRINT_INFO0("Sound is busy, beep mode request will be ignored"); + return; + } + + // ÷в + beep_sequence_context.mode = mode; + beep_sequence_context.beep_duration = duration; + beep_sequence_context.pwm_freq = PWM_HIGH_FREQ; + beep_sequence_context.current_beep_count = 0; + beep_sequence_context.is_active = true; + + // ģʽܷ + switch (mode) + { + case BEEP_MODE_SINGLE: + beep_sequence_context.total_beep_count = 1; + break; + case BEEP_MODE_DOUBLE: + beep_sequence_context.total_beep_count = 2; + break; + case BEEP_MODE_TRIPLE: + beep_sequence_context.total_beep_count = 3; + break; + case BEEP_MODE_FOURS: + beep_sequence_context.total_beep_count = 4; + break; + case BEEP_MODE_FIVE: + beep_sequence_context.total_beep_count = 5; + break; + case BEEP_MODE_HANDERD: + beep_sequence_context.total_beep_count = 100; + break; + default: + beep_sequence_context.total_beep_count = 1; + break; + } + + APP_PRINT_INFO2("Starting beep mode: mode=%d, duration=%dms", mode, duration); + + // ʼһη + beep_sequence_handler(NULL); + +} + +void beep_stop(void){ + + buzzer_init(false, 0); + +} diff --git a/src/app/findmy/fmna_platform/fmna_sound_platform.h b/src/app/findmy/fmna_platform/fmna_sound_platform.h new file mode 100644 index 0000000..7750be7 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_sound_platform.h @@ -0,0 +1,74 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_sound_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +#ifndef fmna_sound_platform_h +#define fmna_sound_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "board.h" +#include "stdbool.h" + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + SOUND_EVENT_NONE, + SOUND_EVENT_FMNA, +#if GFPS_FEATURE_SUPPORT + SOUND_EVENT_GFPS_FINDER, + SOUND_EVENT_DULT, +#endif +} Sound_Event_t; + + +typedef enum +{ + BEEP_MODE_SINGLE, + BEEP_MODE_DOUBLE, + BEEP_MODE_TRIPLE, + BEEP_MODE_FOURS, + BEEP_MODE_FIVE, + BEEP_MODE_HANDERD +} Beep_Mode_t; + +/*============================================================================* + * Interface Functions + *============================================================================*/ +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER +extern bool sound_en; +#endif + + +/*****************************************************************************/ +/*============================================================================* + * + *============================================================================*/ +bool fmna_sound_is_playing(void); +Sound_Event_t fmna_sound_get_current_event(void); +uint32_t fmna_sound_get_remaining_time(void); + +/*****************************************************************************/ + +void fmna_sound_platform_init(void); +void fmna_sound_platform_start(Sound_Event_t event, uint32_t duration_ms, uint16_t pwm_freq); +void fmna_sound_platform_stop(Sound_Event_t event); + + +void play_beep_mode(uint32_t duration, Beep_Mode_t mode); + +void beep_stop(void); + + +#endif /* fmna_sound_platform_h */ diff --git a/src/app/findmy/fmna_platform/fmna_timer_platform.c b/src/app/findmy/fmna_platform/fmna_timer_platform.c new file mode 100644 index 0000000..0add3c7 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_timer_platform.c @@ -0,0 +1,255 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_timer_platform.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#include "fmna_timer_platform.h" +#include "fmna_malloc_platform.h" +#include "fmna_adv_platform.h" +#include "fmna_crypto.h" +#include "otp_config.h" +#include "app_section.h" +#include "app_task.h" +#include "trace.h" +#include "fmna_connection.h" +#if GFPS_FEATURE_SUPPORT +#include "app_dult.h" +#endif + +/*============================================================================* + * Global Variables + *============================================================================*/ +TimerHandle_t adv_timer; +TimerHandle_t sn_lookup_timer; +#if (AON_WDG_ENABLE == 1) +TimerHandle_t aon_watch_dog_wake_up_dlps_timer; +#define AON_WDG_TIMER_WAKEUP_DLPS_PERIOD ((AON_WDG_TIME_OUT_PERIOD_SECOND - 2) * 1000) +#endif +#if (SUPPORT_BAT_DETECT_FEATURE && GFPS_FEATURE_SUPPORT) +TimerHandle_t bat_detect_timer; +#endif +TimerHandle_t unpair_pending_timer; +TimerHandle_t double_click_detect_timer; + +//ʱ +TimerHandle_t disconnection_click_timer; + +/* ζ̰ʱж */ +extern void double_click_detect_timer_cb(TimerHandle_t p_timer); + +// +extern void password_verification_timeout(TimerHandle_t p_timer); + +/*============================================================================* + * Local Functions + *============================================================================*/ +#if (AON_WDG_ENABLE == 1) +static void aon_watch_dog_wake_up_dlps_callback(TimerHandle_t p_timer) DATA_RAM_FUNCTION; +#endif + +/** + * @brief advertising timer callback + * + * adv_timer_callback is used to stop advertising after timeout + * + * @param p_timer - timer handler + * @return none + * @retval void + */ +void adv_timer_callback(TimerHandle_t p_timer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADV_TIMEOUT; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[sn_trig_callback] Send IO_MSG_FMNA_ADV_TIMEOUT failed!"); + return; + } +} + +/** + * @brief serial number lookup timer callback + * + * sn_lookup_callback is used to disable serial number read state after timeout + * + * @param p_timer - timer handler + * @return none + * @retval void + */ +static void sn_lookup_callback(TimerHandle_t p_timer) +{ + APP_PRINT_INFO0("[sn_lookup_callback] serial number read state timeout"); +#if GFPS_FEATURE_SUPPORT + if (app_global_data.gfps_enable) + { + app_dult_set_identification_mode(false); + } + else +#endif + { + serial_number_read_state = false; + fmna_free(ENCRYPTED_SN); + } +} + +static void unpair_pending_callback(TimerHandle_t p_timer) +{ + if (fmna_connection_get_unpair_pending()) + { + fmna_factory_reset(); + } +} + +#if (AON_WDG_ENABLE == 1) +static void aon_watch_dog_wake_up_dlps_callback(TimerHandle_t pxTimer) +{ + //send message to app task in which reset the aon watch dog timer + T_IO_MSG bee_io_msg = {0}; + bee_io_msg.type = IO_MSG_TYPE_RESET_AON_WDG_TIMER; + if (false == app_send_msg_to_apptask(&bee_io_msg)) + { + APP_PRINT_ERROR0("[WDG] send IO_MSG_TYPE_RESET_AON_WDG_TIMER message failed!"); + } +} +#endif + +#if (SUPPORT_BAT_DETECT_FEATURE && GFPS_FEATURE_SUPPORT) +static void bat_detect_callback(TimerHandle_t pxTimer) +{ + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_ADC; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[bat_detect_callback] Send IO_MSG_TYPE_ADC failed!"); + return; + } +} +#endif + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief Initialize software timer. + * @param No parameter. + * @return void +*/ +void sw_timer_init(void) +{ + /* adv_timer is used to stop advertising after timeout */ + if (false == os_timer_create(&adv_timer, "adv_timer", 1, \ + ADV_TIMEOUT, false, adv_timer_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init adv_timer failed"); + } + + /* sn_lookup_timer is used to disable serial number read state after timeout */ + if (false == os_timer_create(&sn_lookup_timer, "sn_lookup_timer", 1, \ + SN_LOOKUP_TIMEOUT, false, sn_lookup_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init sn_lookup_timer failed"); + } + + /* unpair_timer is used to factory data reset */ + if (false == os_timer_create(&unpair_pending_timer, "unpair_pending_timer", 1, \ + UNPAIR_PENDING_TIMEOUT, false, unpair_pending_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init factory_reset_timer failed"); + } + + /* double_click_detect_timer is used to detect single click after 300ms */ + + if (false == os_timer_create(&double_click_detect_timer, "double_click_detect_timer", 1, \ + BTN_SEARCH_TIME, false, double_click_detect_timer_cb)) + { + APP_PRINT_INFO0("[sw_timer_init] init double_click_detect_timer failed"); + } + + /* double_click_detect_timer is used to detect single click after 300ms */ + + if (false == os_timer_create(&disconnection_click_timer, "disconnection_click_timer", 1, \ + ADV_TIMEOUT, false, password_verification_timeout)) + { + APP_PRINT_INFO0("[sw_timer_init] init double_click_detect_timer failed"); + } + +#if (AON_WDG_ENABLE == 1) + if (false == os_timer_create(&aon_watch_dog_wake_up_dlps_timer, "aon_watch_dog_wake_up_dlps_timer", + 1, \ + AON_WDG_TIMER_WAKEUP_DLPS_PERIOD, true, aon_watch_dog_wake_up_dlps_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init aon_watch_dog_wake_up_dlps_timer failed"); + } + else + { + os_timer_start(&aon_watch_dog_wake_up_dlps_timer); + APP_PRINT_INFO0("Start aon_watch_dog_wake_up_dlps_timer!"); + } +#endif + +#if (SUPPORT_BAT_DETECT_FEATURE && GFPS_FEATURE_SUPPORT) + /* bat_detect_timer is used to detect battery periodically */ + if (false == os_timer_create(&bat_detect_timer, "bat_detect_timer", 1, \ + BAT_DETECT_PERIOD, true, bat_detect_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init bat_detect_timer failed"); + } +#endif +} + + +fmna_ret_code_t app_timer_create(void **p_timer_id, app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler) +{ + if (p_timer_id == NULL || timeout_handler == NULL) + { + return FMNA_ERROR_NULL; + } + + if (false == os_timer_create(p_timer_id, NULL, 1, 1000, mode, timeout_handler)) + { + return FMNA_ERROR_INTERNAL; + } + + return FMNA_SUCCESS; +} + +fmna_ret_code_t app_timer_start(void *p_timer, uint32_t timeout_ms, void *p_context) +{ + if (timeout_ms == 0) + { + return FMNA_ERROR_INVALID_STATE; + } + + if (false == os_timer_restart(&p_timer, timeout_ms)) + { + return FMNA_ERROR_INTERNAL; + } + + return FMNA_SUCCESS; +} + +fmna_ret_code_t app_timer_stop(void *p_timer) +{ + uint32_t timer_state = 0; + os_timer_state_get(&p_timer, &timer_state); + if (timer_state) + { + if (false == os_timer_stop(&p_timer)) + { + return FMNA_ERROR_INTERNAL; + } + } + return FMNA_SUCCESS; +} + diff --git a/src/app/findmy/fmna_platform/fmna_timer_platform.h b/src/app/findmy/fmna_platform/fmna_timer_platform.h new file mode 100644 index 0000000..f787209 --- /dev/null +++ b/src/app/findmy/fmna_platform/fmna_timer_platform.h @@ -0,0 +1,94 @@ +/** +********************************************************************************************************* +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file fmna_timer_platform.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-25 +* @version v1.0 +********************************************************************************************************* +*/ +#ifndef fmna_timer_platform_h +#define fmna_timer_platform_h + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "board.h" +#include "os_timer.h" +#include "fmna_constants_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*============================================================================* + * Macros + *============================================================================*/ +/** + * @brief Create a timer identifier and statically allocate memory for the timer. + * + * @param timer_id Name of the timer identifier variable that will be used to control the timer. + */ +#define APP_TIMER_DEF(timer_id) _APP_TIMER_DEF(timer_id) + +#define _APP_TIMER_DEF(timer_id) \ + static TimerHandle_t (timer_id) + +#define APP_TIMER_TICKS(MS) (MS) + +#define BTN_SEARCH_TIME 400 /* 4ms */ +#define ADV_TIMEOUT 3000 /* 3s */ +#define SN_LOOKUP_TIMEOUT 5*60*1000 /* 5min */ +#define UNPAIR_PENDING_TIMEOUT 5000 /* 5s */ +#if (SUPPORT_BAT_DETECT_FEATURE == 1) +#define BAT_DETECT_PERIOD 10*60*1000 /* 10min */ +#define BATTERY_SEND BAT_DETECT_PERIOD*6*72 +#endif + +/*============================================================================* + * Types + *============================================================================*/ +typedef void *TimerHandle_t; + +/**@brief Timer modes. */ +typedef enum +{ + APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */ + APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */ +} app_timer_mode_t; + +/**@brief Application time-out handler type. */ +typedef void (*app_timer_timeout_handler_t)(void *p_context); + +/*============================================================================* +* Export Global Variables +*============================================================================*/ +extern TimerHandle_t adv_timer; +extern TimerHandle_t sn_lookup_timer; +extern TimerHandle_t unpair_pending_timer; +extern TimerHandle_t double_click_detect_timer; +#if (SUPPORT_BAT_DETECT_FEATURE && GFPS_FEATURE_SUPPORT) +extern TimerHandle_t bat_detect_timer; +#endif + +/*============================================================================* + * Global Functions + *============================================================================*/ +void sw_timer_init(void); + +fmna_ret_code_t app_timer_create(void **p_timer_id, \ + app_timer_mode_t mode, \ + app_timer_timeout_handler_t timeout_handler); + +fmna_ret_code_t app_timer_start(void *p_timer, uint32_t timeout_ms, void *p_context); + +fmna_ret_code_t app_timer_stop(void *p_timer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/app/findmy/fmna_profile/accessory_info_service.c b/src/app/findmy/fmna_profile/accessory_info_service.c new file mode 100644 index 0000000..374bb20 --- /dev/null +++ b/src/app/findmy/fmna_profile/accessory_info_service.c @@ -0,0 +1,390 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define FMNA_AIS_PRODUCT_DATA_INDEX 2 +#define FMNA_AIS_MANU_NAME_INDEX 4 +#define FMNA_AIS_MODEL_NAME_INDEX 6 +#define FMNA_AIS_ACCESSORY_CATEGORY_INDEX 8 +#define FMNA_AIS_ACCESSORY_CAPABILITY_INDEX 10 +#define FMNA_AIS_FIRMWARE_VERSION_INDEX 12 +#define FMNA_AIS_FINDMY_VERSION_INDEX 14 +#define FMNA_AIS_BATTERY_TYPE_INDEX 16 +#define FMNA_AIS_BATTERY_LEVEL_INDEX 18 + +T_SERVER_ID ais_id; + +const uint8_t GATT_UUID_ACC_INFO_SERVICE[16] = AIS_SERVICE_BASE_UUID; +const uint8_t product_data[PRODUCT_DATA_BLEN] = PRODUCT_DATA_VAL; +const uint8_t manu_name[MANU_NAME_MAX_LEN] = FMNA_MANUFACTURER_NAME; +const uint8_t model_name[MODEL_NAME_MAX_LEN] = FMNA_MODEL_NAME; +const uint8_t accessory_category[ACC_CATEGORY_MAX_LEN] = ACCESSORY_CATEGORY; +uint32_t acc_capability; +uint32_t fw_vers; +const uint32_t findmy_vers = 0x00010000; // FMN version 1.0.0 +const uint8_t bat_type = BATTERY_TYPE; +uint8_t bat_level; + +const T_ATTRIB_APPL ais_attr_tbl[] = +{ + /*--------------------------AIS Service ---------------------------*/ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)GATT_UUID_ACC_INFO_SERVICE, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1, Product data*/ //------------------------Product data 1 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 2*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_PROD_DATA + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 3, Manufacturer Name*/ //------------------------Manufacturer Name 2 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 4*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_MANU_NAME + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 5, Model Name*/ //------------------------Model Name 3 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 6*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_MODEL_NAME + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + +// /* <>, .. 7, Reserved*/ //------------------------Reserved 4 +// { +// ATTRIB_FLAG_VALUE_INCL, /* wFlags */ +// { /* bTypeValue */ +// LO_WORD(GATT_UUID_CHARACTERISTIC), +// HI_WORD(GATT_UUID_CHARACTERISTIC), +// GATT_CHAR_PROP_READ, /* characteristic properties */ +// /* characteristic UUID not needed here, is UUID of next attrib. */ +// }, +// 1, /* bValueLen */ +// NULL, +// GATT_PERM_READ /* wPermissions */ +// }, +// /* AIS characteristic value 8*/ +// { +// ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ +// { /* type_value */ +// GATT_UUID128_RESERVED +// }, +// 0, /* bValueLen */ +// (void *)NULL, +// GATT_PERM_READ /* wPermissions */ +// }, + + /* <>, .. 9, Accessory Category*/ //------------------------Accessory Category 5 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x0A*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_ACC_CATEGORY + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x0b, Accessory Capabilities*/ //------------------------Accessory Capabilities 6 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x0c*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_ACC_CAP + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x0d, Firmware Version*/ //------------------------Firmware Version 7 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x0e*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_FW_VERS + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x0f, FindMy Version*/ //------------------------FindMy Version 8 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x10 */ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_FINDMY_VERS + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x11, Battery Type*/ //------------------------Battery Type 9 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x12*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_BATT_TYPE + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x13, Battery Level*/ //------------------------Battery Level 10 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* AIS characteristic value 0x14*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_BATT_LVL + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + } + +}; + +T_APP_RESULT ais_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + APP_PRINT_ERROR1("ais_attr_read_cb, Attr found, index %d", attrib_index); + switch (attrib_index) + { + case FMNA_AIS_PRODUCT_DATA_INDEX: + { + *pp_value = (uint8_t *)product_data; + *p_length = PRODUCT_DATA_BLEN; + } + break; + case FMNA_AIS_MANU_NAME_INDEX: + { + *pp_value = (uint8_t *)manu_name; + *p_length = sizeof(FMNA_MANUFACTURER_NAME); + } + break; + case FMNA_AIS_MODEL_NAME_INDEX: + { + *pp_value = (uint8_t *)model_name; + *p_length = sizeof(FMNA_MODEL_NAME); + } + break; + case FMNA_AIS_ACCESSORY_CATEGORY_INDEX: + { + *pp_value = (uint8_t *)accessory_category; + *p_length = ACC_CATEGORY_MAX_LEN; + } + break; + case FMNA_AIS_ACCESSORY_CAPABILITY_INDEX: + { + // Accessory capabilities bitmask as defined in Find My Network specification. + // SDK supports play sound, Firmware update service, motion detection and serial number lookup by BLE & NFC. + // The capabilities must be the same as that of the Product Plan registered on MFI. + SET_BIT(acc_capability, ACC_CAPABILITY_PLAY_SOUND_BIT_POS); + SET_BIT(acc_capability, ACC_CAPABILITY_SRNM_LOOKUP_BLE_BIT_POS); + SET_BIT(acc_capability, ACC_CAPABILITY_FW_UPDATE_SERVICE_BIT_POS); +// SET_BIT(acc_capability, ACC_CAPABILITY_SRNM_LOOKUP_NFC_BIT_POS); + SET_BIT(acc_capability, ACC_CAPABILITY_UT_MOTION_DETECT_BIT_POS); + *pp_value = (uint8_t *)(&acc_capability); + *p_length = ACC_CAP_MAX_LEN; + } + break; + case FMNA_AIS_FIRMWARE_VERSION_INDEX: + { + fw_vers = fmna_version_get_fw_version(); + *pp_value = (uint8_t *)(&fw_vers); + *p_length = FW_VERS_MAX_LEN; + } + break; + case FMNA_AIS_FINDMY_VERSION_INDEX: + { + *pp_value = (uint8_t *)(&findmy_vers); + *p_length = FINDMY_VERS_MAX_LEN; + } + break; + case FMNA_AIS_BATTERY_TYPE_INDEX: + { + *pp_value = (uint8_t *)(&bat_type); + *p_length = BATT_TYPE_MAX_LEN; + } + break; + case FMNA_AIS_BATTERY_LEVEL_INDEX: + { + bat_level = fmna_battery_platform_get_battery_level(); + *pp_value = (uint8_t *)(&bat_level); + *p_length = BATT_LVL_MAX_LEN; + } + break; + default: + APP_PRINT_ERROR1("ais_attr_read_cb, Attr not found, index %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + } + + return cause; +} + +const T_FUN_GATT_SERVICE_CBS ais_ble_cbs = +{ + ais_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + NULL // CCCD update callback function pointer +}; + +T_SERVER_ID accessory_info_add_service(void *p_func) +{ + if (false == server_add_service(&ais_id, + (uint8_t *)ais_attr_tbl, + sizeof(ais_attr_tbl), + ais_ble_cbs)) + { + APP_PRINT_ERROR0("accessory_info_add_service: fail"); + ais_id = 0xff; + return ais_id; + } + + return ais_id; +} diff --git a/src/app/findmy/fmna_profile/accessory_info_service.h b/src/app/findmy/fmna_profile/accessory_info_service.h new file mode 100644 index 0000000..4ff2fc0 --- /dev/null +++ b/src/app/findmy/fmna_profile/accessory_info_service.h @@ -0,0 +1,18 @@ +#ifndef ais_h +#define ais_h + +#include +T_SERVER_ID accessory_info_add_service(void *p_func); + +#define GATT_UUID128_PROD_DATA 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x01, 0x00, 0xA5, 0x6A +#define GATT_UUID128_MANU_NAME 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x02, 0x00, 0xA5, 0x6A +#define GATT_UUID128_MODEL_NAME 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x03, 0x00, 0xA5, 0x6A +#define GATT_UUID128_RESERVED 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x04, 0x00, 0xA5, 0x6A +#define GATT_UUID128_ACC_CATEGORY 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x05, 0x00, 0xA5, 0x6A +#define GATT_UUID128_ACC_CAP 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x06, 0x00, 0xA5, 0x6A +#define GATT_UUID128_FW_VERS 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x07, 0x00, 0xA5, 0x6A +#define GATT_UUID128_FINDMY_VERS 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x08, 0x00, 0xA5, 0x6A +#define GATT_UUID128_BATT_TYPE 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x09, 0x00, 0xA5, 0x6A +#define GATT_UUID128_BATT_LVL 0x0B, 0xBB, 0x6F, 0x41, 0x3A, 0x00, 0xB4, 0xA7, 0x57, 0x4D, 0x52, 0x63, 0x0A, 0x00, 0xA5, 0x6A + +#endif diff --git a/src/app/findmy/fmna_profile/findmy_network_service.c b/src/app/findmy/fmna_profile/findmy_network_service.c new file mode 100644 index 0000000..840f3a6 --- /dev/null +++ b/src/app/findmy/fmna_profile/findmy_network_service.c @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include + +T_SERVER_ID fns_id; +static P_FUN_SERVER_GENERAL_CB pfn_fns_data_cb = NULL; + +const T_ATTRIB_APPL fns_attr_tbl[] = +{ + /*--------------------------FMN Service ---------------------------*/ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + LO_WORD(FINDMY_UUID_SERVICE), /* service UUID */ + HI_WORD(FINDMY_UUID_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1, Pairing Control Point*/ //------------------------Pairing Control Point 1 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FMN characteristic value 2*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_PAIR_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <>, .. 3, Configuration Control Point*/ //------------------------Configuration Control Point 2 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FMN characteristic value 4*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_CONF_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <>, .. 5, Non Owner Control Point*/ //------------------------Non Owner Control Point 3 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FMN characteristic value 6*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_NON_OWNER_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <>, .. 7, Paired owner Information Control Point*/ //------------------------Paired owner Information Control Point 4 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FMN characteristic value 8*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_PAIRED_OWNER_INFO_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#ifdef DEBUG + /* <>, .. 9, Debug Control Point*/ //------------------------Debug Control Point 5 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FMN characteristic value 0x0a*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_DEBUG_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + /* client characteristic configuration Index 0x0b */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif //DEBUG +}; + +void fns_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t length, uint8_t *p_value) +{ + APP_PRINT_INFO4("fns_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d", + conn_id, service_id, attrib_index, length); +} + +T_APP_RESULT fns_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("fns_attr_write_cb write_type = 0x%x", write_type); + *p_write_ind_post_proc = fns_write_post_callback; + if (p_value == NULL) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + if (pfn_fns_data_cb == NULL) + { + APP_PRINT_ERROR0("[FNS] service data handler missing."); + } + else + { + SRV_CALLBACK_DATA fns_cb_data; + fns_cb_data.conn_id = conn_id; + fns_cb_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + fns_cb_data.msg_data.write.len = length; + fns_cb_data.msg_data.write.opcode = attrib_index; + fns_cb_data.msg_data.write.write_type = write_type; + fns_cb_data.msg_data.write.p_value = p_value; + cause = pfn_fns_data_cb(fns_id, &fns_cb_data); + } + } + return cause; +} + +void fns_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, + uint16_t cccbits) +{ + APP_PRINT_INFO2("[fns_cccd_update_cb] index = %d, cccbits 0x%x", index, cccbits); +} + +const T_FUN_GATT_SERVICE_CBS fns_ble_cbs = +{ + NULL, // Read callback function pointer + fns_attr_write_cb, // Write callback function pointer + fns_cccd_update_cb // CCCD update callback function pointer +}; + +T_SERVER_ID findmy_network_add_service(void *p_func) +{ + if (false == server_add_service(&fns_id, + (uint8_t *)fns_attr_tbl, + sizeof(fns_attr_tbl), + fns_ble_cbs)) + { + APP_PRINT_ERROR0("findmy_network_add_service: fail"); + fns_id = 0xff; + return fns_id; + } + + pfn_fns_data_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return fns_id; +} diff --git a/src/app/findmy/fmna_profile/findmy_network_service.h b/src/app/findmy/fmna_profile/findmy_network_service.h new file mode 100644 index 0000000..52fd9b8 --- /dev/null +++ b/src/app/findmy/fmna_profile/findmy_network_service.h @@ -0,0 +1,29 @@ +#ifndef fns_h +#define fns_h + +#include +#include "fmna_constants_platform.h" +T_SERVER_ID findmy_network_add_service(void *p_func); + +#define GATT_UUID128_PAIR_CTRL_POINT 0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x01, 0x00, 0x86, 0x4F +#define GATT_UUID128_CONF_CTRL_POINT 0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x02, 0x00, 0x86, 0x4F +#define GATT_UUID128_NON_OWNER_CTRL_POINT 0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x03, 0x00, 0x86, 0x4F +#define GATT_UUID128_PAIRED_OWNER_INFO_CTRL_POINT 0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x04, 0x00, 0x86, 0x4F + +#define FMNA_FNS_PAIRING_CP_INDEX 2 +#define FMNA_FNS_CONFIG_CP_INDEX 5 +#define FMNA_FNS_NON_OWNER_CP_INDEX 8 +#define FMNA_FNS_PAIRED_OWNER_CP_INDEX 11 + +#define FMNA_FNS_PAIRING_CP_CCCD_INDEX FMNA_FNS_PAIRING_CP_INDEX + 1 +#define FMNA_FNS_CONFIG_CP_CCCD_INDEX FMNA_FNS_CONFIG_CP_INDEX + 1 +#define FMNA_FNS_NON_OWNER_CP_CCCD_INDEX FMNA_FNS_NON_OWNER_CP_INDEX + 1 +#define FMNA_FNS_PAIRED_OWNER_CP_CCCD_INDEX FMNA_FNS_PAIRED_OWNER_CP_INDEX + 1 + +#ifdef DEBUG +#define GATT_UUID128_DEBUG_CTRL_POINT 0x7A, 0x42, 0x04, 0x03, 0x73, 0x2F, 0xD4, 0xBE, 0xEF, 0x49, 0x3B, 0x94, 0x05, 0x00, 0x86, 0x4F +#define FMNA_FNS_DEBUG_CP_INDEX 14 +#define FMNA_DEBUG_CP_CCCD_INDEX FMNA_FNS_DEBUG_CP_INDEX + 1 +#endif //DEBUG + +#endif diff --git a/src/app/findmy/fmna_profile/firmware_update_service.c b/src/app/findmy/fmna_profile/firmware_update_service.c new file mode 100644 index 0000000..6e94ac2 --- /dev/null +++ b/src/app/findmy/fmna_profile/firmware_update_service.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include + +T_SERVER_ID fwus_id; +static P_FUN_SERVER_GENERAL_CB pfn_fwus_data_cb = NULL; + +const T_ATTRIB_APPL fwus_attr_tbl[] = +{ + /*--------------------------FMN Service ---------------------------*/ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + LO_WORD(UARP_UUID_SERVICE), /* service UUID */ + HI_WORD(UARP_UUID_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1, Data Control Point*/ //------------------------Data Control Point 1 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* FWUS characteristic value 2*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_DATA_CTRL_POINT + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +}; + +void fwus_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t length, uint8_t *p_value) +{ + APP_PRINT_INFO4("fwus_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d", + conn_id, service_id, attrib_index, length); +} + +T_APP_RESULT fwus_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("fwus_attr_write_cb write_type = 0x%x", write_type); + *p_write_ind_post_proc = fwus_write_post_callback; + if (p_value == NULL) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + if (pfn_fwus_data_cb == NULL) + { + APP_PRINT_ERROR0("[FWUS] service data handler missing."); + } + else + { + SRV_CALLBACK_DATA fwus_cb_data; + fwus_cb_data.conn_id = conn_id; + fwus_cb_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + fwus_cb_data.msg_data.write.len = length; + fwus_cb_data.msg_data.write.opcode = attrib_index; + fwus_cb_data.msg_data.write.write_type = write_type; + fwus_cb_data.msg_data.write.p_value = p_value; + cause = pfn_fwus_data_cb(fwus_id, &fwus_cb_data); + } + } + return cause; +} + +void fwus_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, + uint16_t cccbits) +{ + APP_PRINT_INFO2("fwus_cccd_update_cb: index = %d, cccbits 0x%x", index, cccbits); + + if (pfn_fwus_data_cb == NULL) + { + APP_PRINT_ERROR0("[FWUS] service data handler missing."); + } + else + { + SRV_CALLBACK_DATA fwus_cb_data; + fwus_cb_data.conn_id = conn_id; + fwus_cb_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + fwus_cb_data.msg_data.nofity_indicate_update.notification_indification_index = index; + fwus_cb_data.msg_data.nofity_indicate_update.cccbits = cccbits; + pfn_fwus_data_cb(fwus_id, &fwus_cb_data); + } +} + +const T_FUN_GATT_SERVICE_CBS fwus_ble_cbs = +{ + NULL, // Read callback function pointer + fwus_attr_write_cb, // Write callback function pointer + fwus_cccd_update_cb // CCCD update callback function pointer +}; + +T_SERVER_ID firmware_update_add_service(void *p_func) +{ + if (false == server_add_service(&fwus_id, + (uint8_t *)fwus_attr_tbl, + sizeof(fwus_attr_tbl), + fwus_ble_cbs)) + { + APP_PRINT_ERROR0("firmware_update_add_service: fail"); + fwus_id = 0xff; + return fwus_id; + } + + pfn_fwus_data_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return fwus_id; +} diff --git a/src/app/findmy/fmna_profile/firmware_update_service.h b/src/app/findmy/fmna_profile/firmware_update_service.h new file mode 100644 index 0000000..0fbd6a5 --- /dev/null +++ b/src/app/findmy/fmna_profile/firmware_update_service.h @@ -0,0 +1,14 @@ +#ifndef fwus_h +#define fwus_h + +#include +#include "fmna_constants_platform.h" + +#define GATT_UUID128_DATA_CTRL_POINT 0xDE, 0xB0, 0x01, 0x7F, 0x4A, 0x6A, 0xF1, 0xA4, 0x25, 0x42, 0x9B, 0x6D, 0x01, 0x00, 0x11, 0x94 + +#define FMNA_FWUS_DATA_CTRL_INDEX 2 +#define FMNA_FWUS_DATA_CTRL_CCCD_INDEX FMNA_FWUS_DATA_CTRL_INDEX + 1 + +T_SERVER_ID firmware_update_add_service(void *p_func); + +#endif diff --git a/src/app/findmy/fmna_profile/hids_kb.c b/src/app/findmy/fmna_profile/hids_kb.c new file mode 100644 index 0000000..6d5d14f --- /dev/null +++ b/src/app/findmy/fmna_profile/hids_kb.c @@ -0,0 +1,851 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_kb.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "hids_kb.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + +/* Report ID for General Keyboard, change: 0x03 to 0x01 */ +#define HOGP_KB_REPORT_ID 0x03 +#define HOGP_MM_REPORT_ID 0x04 +#define MULTIMEDIA_KEYBOARD +T_HID_INFO hid_info = {0, 0, 0x0100}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + +const uint8_t hids_report_descriptor[] = +{ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_KB_REPORT_ID, /* REPORT_ID (3) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x08, /* REPORT_COUNT (8) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x91, 0x01, /* OUTPUT (Cnst,Var,Abs) */ + 0x95, 0x06, /* REPORT_COUNT (6) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xa4, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */ + 0x29, 0xa4, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ +#ifdef MULTIMEDIA_KEYBOARD + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_MM_REPORT_ID, /* REPORT_ID (4) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x18, /* REPORT_COUNT (24) */ + 0x09, 0xb5, /* USAGE (Scan Next Track) */ + 0x09, 0xb6, /* USAGE (Scan Previous Track) */ + 0x09, 0xb7, /* USAGE (Stop) */ + 0x09, 0xcd, /* USAGE (Play/Pause) */ + 0x09, 0xe2, /* USAGE (Mute) */ + 0x09, 0xe5, /* USAGE (Bass Boost) */ + 0x09, 0xe7, /* USAGE (Loudness) */ + 0x09, 0xe9, /* USAGE (Volume Increment) */ + 0x09, 0xea, /* USAGE (Volume Decrement) */ + 0x0a, 0x52, 0x01, /* USAGE (Bass Increment) */ + 0x0a, 0x53, 0x01, /* USAGE (Bass Decrement) */ + 0x0a, 0x54, 0x01, /* USAGE (Treble Increment) */ + 0x0a, 0x55, 0x01, /* USAGE (Treble Decrement) */ + 0x0a, 0x83, 0x01, /* USAGE (AL Consumer Control Configuration) */ + 0x0a, 0x8a, 0x01, /* USAGE (AL Email Reader) */ + 0x0a, 0x92, 0x01, /* USAGE (AL Calculator) */ + 0x0a, 0x94, 0x01, /* USAGE (AL Local Machine Browser) */ + 0x0a, 0x21, 0x02, /* USAGE (AC Search) */ + 0x0a, 0x23, 0x02, /* USAGE (AC Home) */ + 0x0a, 0x24, 0x02, /* USAGE (AC Back) */ + 0x0a, 0x25, 0x02, /* USAGE (AC Forward) */ + 0x0a, 0x26, 0x02, /* USAGE (AC Stop) */ + 0x0a, 0x27, 0x02, /* USAGE (AC Refresh) */ + 0x0a, 0x2a, 0x02, /* USAGE (AC Bookmarks) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0xc0 /* END_COLLECTION */ +#endif +}; + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE | ATTRIB_FLAG_SERVICE_ALLOW_APP), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 10*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 11*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 12*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_KB_REPORT_ID, + HID_FEATURE_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 13*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* permissions */ + }, + + /* <>, .. 16*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard input characteristic value .. 17*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* client characteristic configuration .. 18*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ + }, + + /* <>, .. 19*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard output characteristic value .. 20*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* <>, .. 21*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 22*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 23*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 24*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + +#ifdef MULTIMEDIA_KEYBOARD + /* <>, .. 25*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value ,multimedia keyboard Input 26*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 3, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration 27*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor 28*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_MM_REPORT_ID, /* client char. config. bit field */ + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + } +#endif + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_KB_IN_REPORT: + break; + + case HID_BOOT_KB_OUT_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.output = *p_value; + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/app/findmy/fmna_profile/sdd_service.c b/src/app/findmy/fmna_profile/sdd_service.c new file mode 100644 index 0000000..be35787 --- /dev/null +++ b/src/app/findmy/fmna_profile/sdd_service.c @@ -0,0 +1,344 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file sdd_service.c +* @brief +* @details +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "sdd_service.h" +//#include "bas_config.h" + +/*============================================================================* + * Macros + *============================================================================*/ +#define GATT_UUID_SDD 0xFFE0 +#define GATT_UUID_CHAR_SDD_LEVEL 0xFFE1 + +#define GATT_SVC_SDD_LEVEL_INDEX 2 /**< @brief Index for sdd level chars's value */ +#define GATT_SVC_SDD_CHAR_CCCD_INDEX 3 /**< @brief CCCD Index forsdd level chars's value */ + +/*============================================================================* + * Local Variables + *============================================================================*/ + +uint8_t sdd_rssi_level = 20; +//static uint8_t sdd_notify_level = 0; +static bool sdd_read_level_pending = false; +/**< Function pointer used to send event to application from pxp profile. */ +/**< Initiated in PXP_AddService. */ +static P_FUN_SERVER_GENERAL_CB pfn_sdd_cb = NULL; + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL sdd_attr_tbl[] = +{ + /*----------------- sdd ervice -------------------*/ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_SDD), /* service UUID */ + HI_WORD(GATT_UUID_SDD) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* p_value_context */ + GATT_PERM_READ /* permissions */ + }, + + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + + (GATT_CHAR_PROP_READ |GATT_CHAR_PROP_WRITE_NO_RSP| /* characteristic properties */ + GATT_CHAR_PROP_NOTIFY) + + + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Battery Level value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SDD_LEVEL), + HI_WORD(GATT_UUID_CHAR_SDD_LEVEL) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ|GATT_PERM_WRITE /* permissions */ + } + + , + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ + } + +}; + + +const static uint16_t sdd_attr_tbl_size = sizeof(sdd_attr_tbl); + +/*============================================================================* + * Local Functions + *============================================================================*/ + +bool sdd_set_parameter(T_SDD_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR1("sdd_set_parameter: unknown param_type 0x%02x", param_type); + } + break; + + case SDD_PARAM_BATTERY_LEVEL: + { + if (length != sizeof(uint8_t)) + { + ret = false; + } + else + { + //sdd_battery_level = p_value[0]; + } + } + break; + } + + return ret; +} + + +bool sdd_battery_level_value_notify(uint8_t conn_id, uint8_t service_id, uint8_t sdd_notify_level) +{ + return server_send_data(conn_id, service_id, GATT_SVC_SDD_LEVEL_INDEX, &sdd_notify_level, + sizeof(sdd_notify_level), GATT_PDU_TYPE_ANY); +} + +bool sdd_send_array_value(uint8_t conn_id, T_SERVER_ID service_id, uint8_t array[], uint16_t array_len) +{ + return server_send_data(conn_id, service_id, GATT_SVC_SDD_LEVEL_INDEX, array, + array_len, GATT_PDU_TYPE_ANY); +} + +bool sdd_battery_level_value_read_confirm(uint8_t conn_id, uint8_t service_id, + uint8_t sdd_rssi_level) +{ + if (sdd_read_level_pending == true) + { + sdd_read_level_pending = false; + return server_attr_read_confirm(conn_id, service_id, GATT_SVC_SDD_LEVEL_INDEX, + &sdd_rssi_level, sizeof(sdd_rssi_level), APP_RESULT_SUCCESS); + } + else + { + return false; + } +} + +/** + * @brief read characteristic data from service. + * + * @param conn_id Connection ID. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Offset of characteritic to be read. + * @param p_length Length of getting characteristic data. + * @param pp_value Pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT sdd_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + + PROFILE_PRINT_INFO2("sdd_attr_read_cb: attrib_index %d offset %d", attrib_index, offset); + + switch (attrib_index) + { + default: + { + PROFILE_PRINT_ERROR0("sdd_attr_read_cb: unknown attrib_index"); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + + case GATT_SVC_SDD_LEVEL_INDEX: + { + T_SDD_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + callback_data.msg_data.read_value_index = SDD_READ_BATTERY_LEVEL; + cause = pfn_sdd_cb(service_id, (void *)&callback_data); + if (cause == APP_RESULT_PENDING) + { + sdd_read_level_pending = true; + } + + *pp_value = &sdd_rssi_level; + *p_length = sizeof(sdd_rssi_level); + } + break; + } + return (cause); +} + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id Connection ID. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None +*/ +void sdd_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_SDD_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool handle = true; + PROFILE_PRINT_INFO2("sdd_cccd_update_cb: index %d ccc_bits 0x%04x", index, ccc_bits); + + switch (index) + { + case GATT_SVC_SDD_CHAR_CCCD_INDEX : + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = SDD_NOTIFY_BATTERY_LEVEL_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = SDD_NOTIFY_BATTERY_LEVEL_DISABLE; + } + break; + } + default: + { + handle = false; + break; + } + + } + + if (pfn_sdd_cb && (handle == true)) + { + pfn_sdd_cb(service_id, (void *)&callback_data); + } + + return; +} + +T_APP_RESULT sdd_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_SDD_CALLBACK_DATA callback_data; + PROFILE_PRINT_ERROR0("enter sdd_attr_write_cb!"); + if (!p_value) + { + PROFILE_PRINT_ERROR2("sdd_attr_write_cb: p_value %p length= 0x%x", p_value, length); + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_SDD_LEVEL_INDEX: + if (length != 7) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + if(p_value[0]==0||p_value[0]==1) + { + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + memcpy(callback_data.write_data, p_value, 7); + + } + else + { + cause = APP_RESULT_INVALID_PDU; + } + } + break; + } + if (pfn_sdd_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_sdd_cb(service_id, (void *)&callback_data); + } + + return cause; +} + + + +const T_FUN_GATT_SERVICE_CBS sdd_cbs = +{ + sdd_attr_read_cb, // Read callback function pointer + sdd_attr_write_cb, // Write callback function pointer + sdd_cccd_update_cb // CCCD update callback function pointer +}; + + +T_SERVER_ID sdd_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)sdd_attr_tbl, + sdd_attr_tbl_size, + sdd_cbs)) + { + PROFILE_PRINT_ERROR1("sdd_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_sdd_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/app/findmy/fmna_profile/sdd_service.h b/src/app/findmy/fmna_profile/sdd_service.h new file mode 100644 index 0000000..16d7302 --- /dev/null +++ b/src/app/findmy/fmna_profile/sdd_service.h @@ -0,0 +1,76 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file sdd_service.h + * @brief Head file for using battery service. + * @details + * @author + * @date + * @version + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _SDD_H_ +#define _SDD_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "profile_server.h" + + +#define SDD_READ_BATTERY_LEVEL 1 +#define SDD_NOTIFY_BATTERY_LEVEL_ENABLE 1 +#define SDD_NOTIFY_BATTERY_LEVEL_DISABLE 2 + + +typedef enum +{ + SDD_PARAM_BATTERY_LEVEL = 0x01, +} T_SDD_PARAM_TYPE; + + +typedef union +{ + uint8_t notification_indification_index; + uint8_t read_value_index; +} T_SDD_UPSTREAM_MSG_DATA; + + +typedef struct +{ + uint8_t conn_id; + T_SERVICE_CALLBACK_TYPE msg_type; + T_SDD_UPSTREAM_MSG_DATA msg_data; + uint8_t write_data[7]; +} T_SDD_CALLBACK_DATA; + + +T_SERVER_ID sdd_add_service(void *p_func); + + +bool sdd_set_parameter(T_SDD_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value); + + + +bool sdd_battery_level_value_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t sdd_notify_level); + +//ͨ +bool sdd_send_array_value(uint8_t conn_id, T_SERVER_ID service_id, uint8_t array[],uint16_t array_len); + + +bool sdd_battery_level_value_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t sdd_rssi_level); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SDD_H_ */ diff --git a/src/app/findmy/gfps/app_dult.c b/src/app/findmy/gfps/app_dult.c new file mode 100644 index 0000000..39c464c --- /dev/null +++ b/src/app/findmy/gfps/app_dult.c @@ -0,0 +1,153 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_dult.c +* @brief +* @details +* @author scarlett_liang +* @date 2024-04-28 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#if GFPS_FEATURE_SUPPORT +#include +#include "board.h" +#include "trace.h" +#include "dult.h" +#include "app_gfps.h" +#include "app_dult.h" +#include "app_gfps_finder.h" +#include "gfps_int.h" +#include "gfps_find_my_device.h" +#include "fmna_version.h" +#include "fmna_constants.h" +#include "fmna_sound_platform.h" +#include "fmna_battery_platform.h" + +// DULT Network ID +#define GOOGLE_IDENTIFIER 0x02 +/*============================================================================* +* Local Variables +*============================================================================*/ +const char gfps_company_name[] = GFPS_COMPANY_NAME; +const char gfps_device_name[] = GFPS_DEVICE_NAME; +static bool identification_mode; + +/*============================================================================* +* Global functions +*============================================================================*/ +void app_dult_cb(T_SERVER_ID service_id, void *p_data) +{ + DULT_Callback_Event_t *dult_event = (DULT_Callback_Event_t *)p_data; + switch (*dult_event) + { + case DULT_CALLBACK_EVENT_SOUND_START: + fmna_sound_platform_start(SOUND_EVENT_DULT, 12000, PWM_MEDIUM_FREQ); + break; + + case DULT_CALLBACK_EVENT_SOUND_STOP: + fmna_sound_platform_stop(SOUND_EVENT_DULT); + break; + + case DULT_CALLBACK_EVENT_GET_IDENTIFIER: + { + uint8_t dult_conn_id = app_gfps_get_conn_id(); + if (app_dult_get_identification_mode()) + { + uint8_t recovery_key[8]; + uint8_t ephemeral_identifier[32]; + app_gfps_get_ei(ephemeral_identifier); + gfps_finder_get_recovery_key(recovery_key); + uint8_t p_output[32]; + gfps_hmac_sha256(ephemeral_identifier, 10, p_output, recovery_key, 8); + uint8_t identifier_payload[18]; + memcpy(identifier_payload, ephemeral_identifier, 10); + memcpy(identifier_payload + 10, p_output, 8); + dult_gatt_send_indication(dult_conn_id, gfps_db.dult_srv_id, + DULT_SERVICE_NON_OWNER_OPCODE_GET_IDENTIFIER_RESPONSE, \ + identifier_payload, sizeof(identifier_payload)); + } + else + { + DULT_Response_Status_t response_status = DULT_RESPONSE_STATUS_INVALID_COMMAND; + dult_gatt_send_indication(dult_conn_id, gfps_db.dult_srv_id, + DULT_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE, \ + &response_status, sizeof(DULT_Response_Status_t)); + } + } + break; + } +} + +void app_dult_set_identification_mode(bool flag) +{ + APP_PRINT_INFO1("app_dult_set_identification_mode %d", flag); + identification_mode = flag; +} + +bool app_dult_get_identification_mode(void) +{ + return identification_mode; +} + +/** + * @brief app_dult_sound_callback + * @param APP_DULT_SOUND_STATE + * @return none + */ +void app_dult_sound_callback(APP_DULT_SOUND_STATE sound_state) +{ + APP_PRINT_INFO1("app_dult_sound_callback sound_state=%d", sound_state); + uint8_t dult_conn_id = app_gfps_get_conn_id(); + DULT_Response_Status_t status = DULT_RESPONSE_STATUS_INVALID_STATE; + switch (sound_state) + { + case APP_DULT_SOUND_SUCCESS: + // Send command response for this command. + status = DULT_RESPONSE_STATUS_SUCCESS; + dult_gatt_send_cmd_rsp(dult_conn_id, gfps_db.dult_srv_id, DULT_SERVICE_NON_OWNER_OPCODE_SOUND_START, + \ + &status, sizeof(DULT_Response_Status_t)); + break; + case APP_DULT_SOUND_INVALID: + // Send command response for this command. + status = DULT_RESPONSE_STATUS_INVALID_STATE; + dult_gatt_send_cmd_rsp(dult_conn_id, gfps_db.dult_srv_id, DULT_SERVICE_NON_OWNER_OPCODE_SOUND_STOP, + \ + &status, sizeof(DULT_Response_Status_t)); + break; + case APP_DULT_SOUND_COMPLETE: + dult_gatt_send_indication(dult_conn_id, gfps_db.dult_srv_id, + DULT_SERVICE_NON_OWNER_OPCODE_SOUND_COMPLETED, + \ + NULL, 0); + break; + default: + break; + } +} + +void app_gfps_finder_dult_init(void) +{ + dult_info_t dult_info; + memset(&dult_info, 0, sizeof(dult_info_t)); + //Get_Product_Data should return the model ID provided by the console, zero padded to fit the 8-byte requirement. + uint8_t gfps_model_id[GFPS_MODEL_ID_LEN] = GFPS_MODEL_ID; + memcpy(&dult_info.product_data[5], gfps_model_id, GFPS_MODEL_ID_LEN); + //Get_Manufacturer_Name and Get_Model_Name should match the values provided in the console. + dult_info.p_manufacturer_name = (char *)gfps_company_name; + dult_info.p_model_name = (char *)gfps_device_name; + dult_info.accessory_category = (uint64_t)ACCESSORY_CATEGORY; + dult_info.accessory_capabilities = DULT_SUPPORT_PLAY_SOUND | DULT_SUPPORT_MOTION_DETECTOR_UT | + DULT_SUPPORT_LOOPKUP_BLE; + dult_info.network_id = GOOGLE_IDENTIFIER; + dult_info.firmware_version = fmna_version_get_fw_version(); + dult_info.battery_type = BATTERY_TYPE; + dult_info.battery_level = fmna_battery_platform_get_battery_level(); + dult_init(dult_info); +} +#endif diff --git a/src/app/findmy/gfps/app_dult.h b/src/app/findmy/gfps/app_dult.h new file mode 100644 index 0000000..dc7ffa0 --- /dev/null +++ b/src/app/findmy/gfps/app_dult.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _APP_DULT_H_ +#define _APP_DULT_H_ + +#include "stdbool.h" +#include "profile_server.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef enum +{ + APP_DULT_SOUND_SUCCESS = 0, + APP_DULT_SOUND_INVALID = 1, + APP_DULT_SOUND_COMPLETE = 2, +} APP_DULT_SOUND_STATE; + +/** + * @brief DULT service callback handler + * + * @param service_id Service ID of the DULT service + * @param p_data Pointer to the callback data + * @return void + */ +void app_dult_cb(T_SERVER_ID service_id, void *p_data); + +/** + * @brief DULT sound state callback handler + * + * @param sound_state Sound state notification to DULT service + * @return void + */ +void app_dult_sound_callback(APP_DULT_SOUND_STATE sound_state); + +/** + * @brief Initialize GFPS finder with DULT service + * + * @return void + */ +void app_gfps_finder_dult_init(void); + +/** + * @brief Set DULT identification mode + * + * @param flag true to enable identification mode, false to disable + * @return void + */ +void app_dult_set_identification_mode(bool flag); + +/** + * @brief Get current DULT identification mode status + * + * @return bool true if identification mode is enabled, false otherwise + */ +bool app_dult_get_identification_mode(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/app/findmy/gfps/app_gfps.c b/src/app/findmy/gfps/app_gfps.c new file mode 100644 index 0000000..553c1e8 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps.c @@ -0,0 +1,591 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_gfps.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-27 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#if GFPS_FEATURE_SUPPORT +#include +#include "trace.h" +#include "app_msg.h" +#include "app_task.h" +#include "gap_bond_le.h" +#include "gap_adv.h" +#include "gap_conn_le.h" +#include "gfps.h" +#include "app_gfps.h" +#include "app_gfps_account_key.h" +#include "base64.h" +#include "gfps_find_my_device.h" +#include "app_gfps_finder.h" +#include "fmna_gap_platform.h" +#include "fmna_timer_platform.h" +#include "os_timer.h" +#include "findmy_app.h" +#include "dult.h" +#include "app_dult.h" + +/*============================================================================* + * Variables + *============================================================================*/ +T_GFPS_DB gfps_db; +uint8_t gfps_adv_len; +uint8_t gfps_adv_data[GAP_MAX_ADV_LEN]; + +static T_ADV_DATA gfps_adv; +void *locator_tag_unpair_timer; + +/*============================================================================* + * Local functions + *============================================================================*/ +static void app_gfps_adv_init(void) +{ + gfps_adv.p_scan_rsp_data = NULL; + gfps_adv.scan_rsp_data_len = 0; + gfps_adv.adv_type = GAP_ADTYPE_ADV_IND; + gfps_db.first_bd_sddr_set = false; +} + +static bool app_gfps_adv_start(T_GFPS_ADV_MODE mode) +{ + T_GAP_CAUSE ret = GAP_CAUSE_SUCCESS; + uint16_t error_line = 0; + + if (mode == DISCOVERABLE_MODE_WITH_MODEL_ID) + { + ret = le_adv_set_tx_power(GAP_ADV_TX_POW_SET_1M, 0xD8); // -20dBm + __GAP_RET_CHECK(ret, fail); + gfps_adv.adv_interval = GFPS_DISCOV_ADV_INTERVAL; + gfps_set_tx_power(true, GFPS_ADV_TX_POWER); + } + else + { + ret = le_adv_set_tx_power(GAP_ADV_TX_POW_SET_1M, 0x08); // 4dBm + __GAP_RET_CHECK(ret, fail); + gfps_adv.adv_interval = GFPS_NON_DISCOV_ADV_INTERVAL; + gfps_set_tx_power(true, 4); + } + + //GFPS locator tag not support subsequent pairing + if (!gfps_gen_adv_data(mode, gfps_adv_data, &gfps_adv_len, false)) + { + APP_PRINT_ERROR0("app_gfps_adv_start: gfps_gen_adv_data failed"); + } + gfps_adv.p_adv_data = gfps_adv_data; + gfps_adv.adv_data_len = gfps_adv_len; + + if (!gfps_db.first_bd_sddr_set && !app_gfps_finder_provisoned()) + { + gfps_db.first_bd_sddr_set = true; + uint8_t bt_addr[6] = {0}; + /*When not discoverable, the Provider shall advertise Fast Pair Account Key Data with RPA*/ + le_gen_rand_addr(GAP_RAND_ADDR_STATIC, bt_addr); + T_GAP_LOCAL_ADDR_TYPE local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM; +#if ONE_SHOT_ADV_EN + one_shot_bt_addr_set(bt_addr, local_bd_type, ADV_DATA_GFPS); +#else + le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + le_set_rand_addr(bt_addr); +#endif + APP_PRINT_INFO2("app_gfps_adv_start: mode:%d addr: %s", mode, TRACE_BDADDR(bt_addr)); + } + else if (app_gfps_finder_provisoned()) + { +#if ONE_SHOT_ADV_EN + one_shot_bt_addr_set(gfps_db.local_bd_addr, GAP_LOCAL_ADDR_LE_RANDOM, ADV_DATA_GFPS); +#else + le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + le_set_rand_addr(gfps_db.local_bd_addr); +#endif + APP_PRINT_INFO2("app_gfps_adv_start with finder mode:%d adv addr: %s", mode, + TRACE_BDADDR(gfps_db.local_bd_addr)); + } + else + { + APP_PRINT_INFO1("app_gfps_adv_start mode:%d", mode); + } + + ret = fmble_gap_adv_data_set(gfps_adv, ADV_DATA_GFPS); + __GAP_RET_CHECK(ret, fail); + + ret = fmble_gap_adv_start(ADV_DATA_GFPS); + __GAP_RET_CHECK(ret, fail); + + return true; +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + ret); + } + return false; +} + +static void app_gfps_adv_timer_stop(void) +{ + uint32_t timer_state; + os_timer_state_get(&adv_timer, &timer_state); + if (timer_state) + { + // Timer is active, do something. + os_timer_stop(&adv_timer); + APP_PRINT_INFO0("app_gfps_adv_timer_stop"); + } + else + { + //Timer is not active, do something else. + APP_PRINT_INFO0("app_gfps_adv_timer_stop: timer is not active"); + } +} + +/*Fast pair service callback*/ +static T_APP_RESULT app_gfps_gatt_cb(T_SERVER_ID service_id, void *p_data) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_GFPS_CALLBACK_DATA *p_callback = (T_GFPS_CALLBACK_DATA *)p_data; + + if (gfps_db.current_conn_id == 0xFF) + { + APP_PRINT_INFO1("app_gfps_gatt_cb: connected by other adv, conn_id %d", p_callback->conn_id); + gfps_db.current_conn_id = p_callback->conn_id; + } + + switch (p_callback->msg_type) + { + case GFPS_CALLBACK_TYPE_NOTIFICATION_ENABLE: + { + APP_PRINT_INFO1("app_gfps_gatt_cb: GFPS_CALLBACK_TYPE_NOTIFICATION_ENABLE, T_GFPS_NOTIFICATION_TYPE %d", + p_callback->msg_data.notify_type); + } + break; + + case GFPS_CALLBACK_TYPE_KBP_WRITE_REQ: + { + if (p_callback->msg_data.kbp.result == GFPS_WRITE_RESULT_SUCCESS) + { + APP_PRINT_INFO7("GFPS_CALLBACK_TYPE_KBP_WRITE_REQ: provider_init_bond %d, notify_existing_name %d, " + "retroactively_account_key %d, pk_field_exist %d, account_key_idx %d, provider_addr %s, seek_br_edr_addr %s", + p_callback->msg_data.kbp.provider_init_bond, + p_callback->msg_data.kbp.notify_existing_name, + p_callback->msg_data.kbp.retroactively_account_key, + p_callback->msg_data.kbp.pk_field_exist, + p_callback->msg_data.kbp.account_key_idx, + TRACE_BDADDR(p_callback->msg_data.kbp.provider_addr), + TRACE_BDADDR(p_callback->msg_data.kbp.seek_br_edr_addr) + ); + } + else + { + APP_PRINT_ERROR1("GFPS_CALLBACK_TYPE_KBP_WRITE_REQ: failed, result %d", + p_callback->msg_data.kbp.result); + } + } + break; + + case GFPS_CALLBACK_TYPE_ACTION_REQ: + { + if (p_callback->msg_data.action_req.result == GFPS_WRITE_RESULT_SUCCESS) + { + APP_PRINT_INFO5("GFPS_CALLBACK_TYPE_ACTION_REQ: pk_field_exist %d, account_key_idx %d, " + "device_action %d, additional_data %d, provider_addr %s", + p_callback->msg_data.action_req.pk_field_exist, + p_callback->msg_data.action_req.account_key_idx, + p_callback->msg_data.action_req.device_action, + p_callback->msg_data.action_req.additional_data, + TRACE_BDADDR(p_callback->msg_data.action_req.provider_addr) + ); + } + else + { + APP_PRINT_ERROR1("GFPS_CALLBACK_TYPE_ACTION_REQ: failed, result %d", + p_callback->msg_data.action_req.result); + } + } + break; + + case GFPS_CALLBACK_TYPE_PASSKEY: + { + APP_PRINT_INFO2("GFPS_CALLBACK_TYPE_PASSKEY: conn_id %d, gfps_raw_passkey %d", + p_callback->conn_id, p_callback->msg_data.passkey); + } + break; + + case GFPS_CALLBACK_TYPE_ACCOUNT_KEY: + { + /*for initial pairing or retroactive write account key receive account key from seeker*/ + if (!app_gfps_account_key_store(p_callback->msg_data.account_key, gfps_db.remote_bd_addr)) + { + app_result = APP_RESULT_REJECT; + } + os_timer_start(&locator_tag_unpair_timer); + } + break; + +#if GFPS_ADDTIONAL_DATA_SUPPORT + case GFPS_CALLBACK_TYPE_ADDITIONAL_DATA: + { + //locator tag not support personalized name + app_result = APP_RESULT_SUCCESS; + } + break; +#endif + + default: + break; + } + + return app_result; +} + +static void locator_tag_unpair_timer_callback(void *p_timer) +{ + APP_PRINT_INFO0("locator_tag_unpair_timer_callback"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_GFPS; + int_gpio_msg.subtype = IO_MSG_GFPS_LOCATOR_TAG_UNPAIR; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_non_owner_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +/*============================================================================* +* Global functions +*============================================================================*/ +/*google Fast pair initialize*/ +void app_gfps_init(void) +{ + uint32_t len; + uint8_t gfps_model_id[GFPS_MODEL_ID_LEN] = GFPS_MODEL_ID; + uint8_t gfps_enc_private_key[GFPS_ENC_PRIVATE_KEY_LEN] = GFPS_ENC_PRIVATE_KEY; + uint8_t gfps_private_key[GFPS_PRIVATE_KEY_LEN]; + + if (app_gfps_account_key_init(GFPS_ACCOUNT_KEY_NUM) == false) + { + goto error; + } + + mbedtls_base64_decode(gfps_private_key, GFPS_PRIVATE_KEY_LEN, + &len, gfps_enc_private_key, GFPS_ENC_PRIVATE_KEY_LEN); + if (gfps_init((uint8_t *)&gfps_model_id, gfps_private_key) == false) + { + goto error; + } + APP_PRINT_INFO2("[app_gfps_init] model id=%b, private key=%b", + TRACE_BINARY(3, (uint8_t *)&gfps_model_id), + TRACE_BINARY(GFPS_PRIVATE_KEY_LEN, gfps_private_key)); + + gfps_set_battery_info(NULL); //no battery notification + gfps_db.current_conn_id = 0xFF; + + gfps_db.gfps_srv_id = 0xFF; + gfps_db.dult_srv_id = 0xFF; + app_gfps_gatt_init(); + + gfps_le_device_init(true, GFPS_LE_DEVICE_MODE_LE_MODE_WITHOUT_CSIP); + app_gfps_adv_init(); + gfps_set_identity_address(app_global_data.mac_address, NULL, false); + + gfps_set_finder_enable(true); + app_gfps_finder_init(); + + /* factory_reset_timer is used to factory data reset */ + if (false == os_timer_create(&locator_tag_unpair_timer, "locator_tag_unpair_timer", 1, \ + 5 * 60000, false, locator_tag_unpair_timer_callback)) + { + APP_PRINT_INFO0("[sw_timer_init] init locator_tag_unpair_timer failed"); + } + + return; +error: + APP_PRINT_ERROR0("app_gfps_init: failed"); +} + +/** + * @brief google Fast pair service initialization + * + * @param void + * @return void + */ +void app_gfps_gatt_init(void) +{ + if (gfps_db.gfps_srv_id == 0xFF) + { + gfps_db.gfps_srv_id = gfps_add_service(app_gfps_gatt_cb); + } + if (gfps_db.dult_srv_id == 0xFF) + { + gfps_db.dult_srv_id = dult_add_service(app_dult_cb); + } +} + +/** + * @brief start gfps adv according to expected gfps action + * + * @param gfps_next_action @ref T_GFPS_ACTION + * @return true success + * @return false fail + */ +bool app_gfps_next_action(T_GFPS_ACTION gfps_next_action) +{ + APP_PRINT_INFO2("app_gfps_next_action: gfps_curr_action %d, gfps_next_action %d", + gfps_db.gfps_curr_action, gfps_next_action); + + app_gfps_adv_stop(); + + switch (gfps_next_action) + { + case GFPS_ACTION_IDLE: + { + if (gfps_db.current_conn_id != 0xFF) + { + le_disconnect(gfps_db.current_conn_id); + } + } + break; + + case GFPS_ACTION_ADV_DISCOVERABLE_MODE: + { + app_gfps_adv_start(DISCOVERABLE_MODE_WITH_MODEL_ID); + } + break; + + case GFPS_ACTION_ADV_NON_DISCOVERABLE_MODE: + { + app_gfps_adv_start(NOT_DISCOVERABLE_MODE); + } + break; + + default: + break; + } + + gfps_db.gfps_curr_action = gfps_next_action; + return true; +} + +/** + * @brief gfps ble event callback + * + * @param cb_data + * @return true success + * @return false: in disconnect event, the conn_id don't match gfps_conn_id + */ +bool app_gfps_ble_evt_callback(T_GFPS_CB cb_data) +{ + switch (cb_data.cb_type) + { + case GFPS_CB_CONNECTION: + { + app_gfps_adv_timer_stop(); + gfps_db.current_conn_id = cb_data.conn_id; + uint8_t remote_bd[6]; + T_GAP_REMOTE_ADDR_TYPE remote_bd_type; + le_get_conn_addr(cb_data.conn_id, remote_bd, (uint8_t *)&remote_bd_type); + memcpy(gfps_db.remote_bd_addr, remote_bd, 6); + APP_PRINT_INFO2("GFPS_CB_CONNECTION: conn_id %d remote_bd %s", cb_data.conn_id, + TRACE_BDADDR(remote_bd)); + } + break; + + case GFPS_CB_DISCONNECTION: + { + if (gfps_db.current_conn_id != cb_data.conn_id) + { + APP_PRINT_INFO2("app_gfps_le_disconnect_cb: current connid %d not gfps conn_id %d", + cb_data.conn_id, gfps_db.current_conn_id); + return false; + } + APP_PRINT_INFO1("GFPS_CB_DISCONNECTION: conn_id %d", cb_data.conn_id); + gfps_db.current_conn_id = 0xFF; + + if (app_gfps_finder_get_factory_flag()) + { + app_gfps_finder_set_factory_flag(false); + app_gfps_device_handle_factory_reset(); + } + + /*gfps finder maybe connected by gfps ble link to do provising or provisioned actions, + so when gfps ble link disconencted, we shall reset gfps finder link here*/ + app_gfps_finder_reset_conn(); + + gfps_reset_aeskey_and_pairing_status(); + if (app_gfps_finder_get_beacon_state() == GFPS_FINDER_BEACON_STATE_OFF) + { + T_ACCOUNT_KEY *p_key_info = app_gfps_account_key_get_table(); + if (app_gfps_finder_provisoned() || p_key_info->num != 0) + { + app_gfps_next_action(GFPS_ACTION_ADV_NON_DISCOVERABLE_MODE); + } + } + } + break; + + default: + break; + } + + return true; +} + +/** + * @brief app_gfps_get_conn_id + * get gfps ble link connection id + * @return uint8_t + */ +uint8_t app_gfps_get_conn_id(void) +{ + return gfps_db.current_conn_id; +} + +void app_gfps_handle_ble_user_confirm(uint8_t conn_id, uint32_t passkey) +{ + /*For locator tag, Provider should reject normal Bluetooth pairing attempts. + It should only accept FastPair pairing.*/ + le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_REJECT); + return; +} + +void app_gfps_msg_handler(uint16_t msg_sub_type) +{ + APP_PRINT_INFO1("[app_gfps_msg_handler]type = %d!", msg_sub_type); + + switch (msg_sub_type) + { + case IO_MSG_GFPS_ID_ROTAION: + app_gfps_update_random_window_handler(); + break; + + case IO_MSG_GFPS_UPDATE_RPA: + app_gfps_update_rpa_handler(); + break; + + case IO_MSG_GFPS_LOCATOR_TAG_UNPAIR: + { + /* If the Provider was paired, but FHN wasn't provisioned within 5 minutes + (or if an OTA update was applied while the device is paired but not FHN-provisioned), + the Provider should revert to its factory configuration and clear the stored account keys. */ + app_global_data.gfps_enable = false; + app_gfps_account_key_clear(); + app_gfps_next_action(GFPS_ACTION_IDLE); + } + break; + + default: + APP_PRINT_WARN0("[app_gfps_msg_handler]Invalid message type"); + break; + } +} + +/** + * @brief GFPS power on handler + * + * @return void + */ +void app_handle_gfps_power_on(void) +{ + if (app_gfps_finder_provisoned()) + { + APP_PRINT_INFO0("app_handle_gfps_power_on after a power loss"); + app_global_data.gfps_enable = true; + app_gfps_finder_enter_beacon_state(GFPS_FINDER_BEACON_STATE_ON); + /* After a power loss, the device should advertise non-discoverable Fast Pair frames until the next invocation of read beacon parameters. + This lets the Seeker detect the device and synchronize the clock even if a significant clock drift occurred. */ + app_gfps_next_action(GFPS_ACTION_ADV_NON_DISCOVERABLE_MODE); + } +} + +/** + * @brief GFPS device factory reset handler + * + * @return void + */ +void app_gfps_device_handle_factory_reset(void) +{ + APP_PRINT_TRACE0("app_gfps_device_handle_factory_reset"); + app_global_data.gfps_enable = false; + + app_gfps_account_key_clear(); + + app_gfps_finder_handle_factory_reset(); +} + +/** + * @brief GFPS advertising stop handler + * + * @return void + */ +void app_gfps_adv_stop(void) +{ + APP_PRINT_INFO0("app_gfps_adv_stop"); + fmble_gap_adv_stop(ADV_DATA_GFPS); +} + +#include "mbedtls/ecdh.h" +#include "mbedtls/ecp.h" +#include "mbedtls/platform_util.h" +T_APP_RESULT app_gfps_gen_ecdh_key(uint8_t *public_key, uint8_t *private_key, uint8_t *aes_key) +{ + mbedtls_ecdh_context ctx_client; + mbedtls_ecdh_context ctx_server; + + mbedtls_ecdh_init(&ctx_client); + mbedtls_ecdh_init(&ctx_server); + + int ret = mbedtls_ecp_group_load(&ctx_client.grp, MBEDTLS_ECP_DP_SECP256R1); + if (ret != 0) + { + goto cleanup; + } + + ret = mbedtls_mpi_read_binary(&ctx_client.d, private_key, 32); + if (ret != 0) + { + goto cleanup; + } + + ret = mbedtls_ecp_point_read_binary(&ctx_client.grp, &ctx_client.Qp, public_key, 65); + if (ret != 0) + { + goto cleanup; + } + + ret = mbedtls_ecdh_compute_shared( + &ctx_client.grp, + &ctx_client.z, /* Shared secret will be written here */ + &ctx_client.Qp, /* Server's public key */ + &ctx_client.d, /* Client's private key */ + mbedtls_platform_frng, /* RNG function */ + NULL + ); + if (ret != 0) + { + goto cleanup; + } + + ret = mbedtls_mpi_write_binary(&ctx_client.z, aes_key, 32); + if (ret != 0) + { + goto cleanup; + } + APP_PRINT_INFO1("app_gfps_gen_ecdh_key aes_key=%b", TRACE_BINARY(32, aes_key)); + + return APP_RESULT_SUCCESS; +cleanup: + APP_PRINT_ERROR1("app_gfps_gen_ecdh_key error=%#x", ret); + mbedtls_ecdh_free(&ctx_client); + mbedtls_ecdh_free(&ctx_server); + return APP_RESULT_APP_ERR; +} + +#endif diff --git a/src/app/findmy/gfps/app_gfps.h b/src/app/findmy/gfps/app_gfps.h new file mode 100644 index 0000000..8449de2 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps.h @@ -0,0 +1,184 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_gfps.h +* @brief +* @details +* @author scarlett_liang +* @date 2023-06-27 +* @version v1.0 +* ********************************************************************************************************* +*/ +#ifndef _APP_GFPS_H_ +#define _APP_GFPS_H_ + +#if GFPS_FEATURE_SUPPORT +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "gfps.h" +#include "os_queue.h" +#include "gap_msg.h" +#include "gap_adv.h" +#include "gap_ext_adv.h" + +/*============================================================================* +* Macro Definitions +*============================================================================*/ +#define GFPS_MODEL_ID {0x46, 0xBE, 0x82}//{0xEC, 0xF4, 0xAC}//{0xA7, 0x4E, 0x3F} +#define GFPS_COMPANY_NAME "Realtek Semiconductor Corporation" +#define GFPS_DEVICE_NAME "Realtek Tag" +/*Model ID 0x46BE82 corresponds to the locator tag. + If it is not the locator tag, GFPS bond information management needs to be added. */ +#define GFPS_MODEL_ID_LEN 3 +#define GFPS_ENC_PRIVATE_KEY "7Ael/3hZqAmEbldqeNkGuwnc79w1hT/mowNalOJGovU="//"8r4Fp3iTkcD54eTZcEKz5w2qSTBFSIZob+HORko8yS0="//"rOjaBjAfip77poaZ0GUxeiGXxbxU81Zq5EoM6yz5kqw=" +#define GFPS_ENC_PRIVATE_KEY_LEN 44 +#define GFPS_PRIVATE_KEY_LEN 32 +#define GFPS_ACCOUNT_KEY_NUM 1 //locator tag only store a single account key +#define GFPS_MAX_LINK_NUM 1 +#define GFPS_DISCOV_ADV_INTERVAL 128 //80ms. In units of 0.625ms +#define GFPS_NON_DISCOV_ADV_INTERVAL 400 //250ms. In units of 0.625ms +#define GFPS_ADV_TX_POWER -20 + +#define FTL_SAVE_ACCOUNT_KEY_ADDR 500 +#define GFPS_FINDER_EIK_FLASH_OFFSET 620 +#define GFPS_FINDER_EIK_LEN sizeof(T_GFPS_EIK) +#define GFPS_FINDER_CLOCK_FLASH_OFFSET (GFPS_FINDER_EIK_FLASH_OFFSET + GFPS_FINDER_EIK_LEN) +#define GFPS_FINDER_CLOCK_LEN 0x04 + +/*============================================================================* + * Types + *============================================================================*/ +typedef enum +{ + GFPS_ACTION_IDLE, + GFPS_ACTION_ADV_DISCOVERABLE_MODE, + GFPS_ACTION_ADV_NON_DISCOVERABLE_MODE, +} T_GFPS_ACTION; + +typedef struct +{ + bool first_bd_sddr_set; + T_GFPS_ACTION gfps_curr_action; + + T_SERVER_ID gfps_srv_id; + T_SERVER_ID dult_srv_id; + uint8_t current_conn_id; + uint8_t remote_bd_addr[6]; + uint8_t local_bd_addr[6]; + T_GFPS_BATTERY_INFO gfps_battery_info; +} T_GFPS_DB; + +typedef enum +{ + GFPS_CB_CONNECTION, + GFPS_CB_DISCONNECTION, +} T_GFPS_BLE_EVT_CB_TYPE; + +typedef struct +{ + T_GFPS_BLE_EVT_CB_TYPE cb_type; + uint8_t conn_id; +} T_GFPS_CB; + +/*============================================================================* + * Global Variables + *============================================================================*/ +extern T_GFPS_DB gfps_db; +extern uint8_t gfps_adv_len; +extern uint8_t gfps_adv_data[GAP_MAX_ADV_LEN]; +extern void *locator_tag_unpair_timer; + +/*============================================================================* + * Interface Functions + *============================================================================*/ +/** + * @brief google Fast pair initialization + * + * @param void + * @return void + */ +void app_gfps_init(void); + +/** + * @brief google Fast pair service initialization + * + * @param void + * @return void + */ +void app_gfps_gatt_init(void); + +/** + * @brief start gfps adv according to expected gfps action + * + * @param gfps_next_action @ref T_GFPS_ACTION + * @return true success + * @return false fail + */ +bool app_gfps_next_action(T_GFPS_ACTION gfps_next_action); + +/** + * @brief handle user confirmation for le pairing. + * + * @param conn_id BLE connection id + * @param passkey + * @return void + */ +void app_gfps_handle_ble_user_confirm(uint8_t conn_id, uint32_t passkey); + +/** + * @brief gfps ble event callback + * + * @param cb_data + * @return true success + * @return false: in disconnect event, the conn_id don't match gfps_conn_id + */ +bool app_gfps_ble_evt_callback(T_GFPS_CB cb_data); + +/** + * @brief app_gfps_get_conn_id + * get gfps ble link connection id + * @return uint8_t + */ +uint8_t app_gfps_get_conn_id(void); + +/** + * @brief gfps message handler + * + * @param msg_sub_type + * @return void + */ +void app_gfps_msg_handler(uint16_t msg_sub_type); + +/** + * @brief GFPS advertising stop handler + * + * @return void + */ +void app_gfps_adv_stop(void); + +/** + * @brief GFPS device factory reset handler + * + * @return void + */ +void app_gfps_device_handle_factory_reset(void); + +/** + * @brief GFPS power on handler + * + * @return void + */ +void app_handle_gfps_power_on(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +#endif diff --git a/src/app/findmy/gfps/app_gfps_account_key.c b/src/app/findmy/gfps/app_gfps_account_key.c new file mode 100644 index 0000000..808e2a3 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_account_key.c @@ -0,0 +1,162 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_gfps_account_key.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-07-20 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#if GFPS_FEATURE_SUPPORT +#include "trace.h" +#include "ftl.h" +#include "stdlib.h" +#include "string.h" +#include "app_msg.h" +#include "app_task.h" +#include "gfps.h" +#include "app_gfps.h" +#include "app_gfps_account_key.h" + +/*============================================================================* + * Variables + *============================================================================*/ +static T_ACCOUNT_KEY *account_key = NULL; +static uint8_t gfps_account_key_num; //sum of account key +static uint8_t gfps_account_key_table_size; + +/*============================================================================* +* Global functions +*============================================================================*/ +/*Fast pair initialize*/ +bool app_gfps_account_key_init(uint8_t key_num) +{ + gfps_account_key_num = key_num; + gfps_account_key_table_size = 4 + gfps_account_key_num * (GFPS_ACCOUNT_KEY_LENGTH + + GFPS_BD_ADDR_LENGTH); + account_key = calloc(1, gfps_account_key_table_size); + if (account_key) + { + uint32_t read_result = ftl_load(account_key, FTL_SAVE_ACCOUNT_KEY_ADDR, + gfps_account_key_table_size); + if (read_result) + { + memset(account_key, 0, gfps_account_key_table_size); + APP_PRINT_INFO2("app_gfps_account_key_init: max key_num %d, table size %d", + key_num, gfps_account_key_table_size); + + ftl_save(account_key, FTL_SAVE_ACCOUNT_KEY_ADDR, gfps_account_key_table_size); + } + else + { + for (uint8_t i = 0; i < account_key->num; i++) + { + APP_PRINT_INFO4("app_gfps_account_key_init: idx %d, key %b, bd_addr %s, del %d", i, + TRACE_BINARY(16, account_key->account_info[i].key), + TRACE_BDADDR(account_key->account_info[i].addr), account_key->del); + } + } + } + else + { + APP_PRINT_ERROR0("app_gfps_account_key_init: alloc account key memory fail"); + return false; + } + + gfps_account_key_init(account_key, gfps_account_key_num); + return true; +} + +T_ACCOUNT_KEY *app_gfps_account_key_get_table(void) +{ + return account_key; +} + +/*Account key store */ +bool app_gfps_account_key_store(uint8_t key[16], uint8_t *bd_addr) +{ + for (uint8_t i = 0; i < account_key->num; i++) + { + if (memcmp(bd_addr, account_key->account_info[i].addr, 6) == 0) + { + if (memcmp(key, account_key->account_info[i].key, 16) == 0) + { + /*bd_addr and key has already in account key table*/ + APP_PRINT_INFO1("app_gfps_account_key_store: key exist i=%d", i); + return false; + } + else + { + /*bd_addr has already stored in flash, just update key + if finder support, shall not update owner key*/ + APP_PRINT_INFO1("app_gfps_account_key_store: key update i=%d", i); + memcpy(account_key->account_info[i].key, key, 16); + goto save; + } + } + } + // add new account key + if (account_key->num < gfps_account_key_num) + { + memcpy(account_key->account_info[account_key->num].key, key, 16); + memcpy(account_key->account_info[account_key->num].addr, bd_addr, 6); + account_key->num++; + } + else //should never go here, check factory reset process + { + APP_PRINT_ERROR0("app_gfps_account_key_store ERROR"); + } +save: + app_gfps_account_key_table_print(); + uint32_t ret = ftl_save(account_key, FTL_SAVE_ACCOUNT_KEY_ADDR, gfps_account_key_table_size); + if (ret) + { + APP_PRINT_ERROR1("app_gfps_account_key_store FTL save error:%d", ret); + } + return true; +} + +/*Clear Account key store */ +void app_gfps_account_key_clear(void) +{ + APP_PRINT_WARN0("app_gfps_account_key_clear"); + memset(account_key, 0, sizeof(T_ACCOUNT_KEY)); + ftl_save(account_key, FTL_SAVE_ACCOUNT_KEY_ADDR, gfps_account_key_table_size); +} + +/** + * @brief print all account key info + */ +void app_gfps_account_key_table_print(void) +{ + for (uint8_t i = 0; i < account_key->num; i++) + { + APP_PRINT_INFO3("app_gfps_account_key_table_print: idx %d, key %b, bd_addr %s", i, + TRACE_BINARY(16, account_key->account_info[i].key), + TRACE_BDADDR(account_key->account_info[i].addr)); + } + APP_PRINT_INFO1("app_gfps_account_key_table_print total num %d", account_key->num); +} + +bool app_gfps_account_key_update_owner_key(uint8_t key[16], T_ACCOUNT_KEY *p_table) +{ + memcpy(p_table->account_info[0].key, key, 16); + if (p_table->num == 0) + { + p_table->num++; + } + return true; +} + +void app_gfps_account_key_save_ownerkey_valid(void) +{ + APP_PRINT_INFO1("app_gfps_account_key_save_ownerkey_valid: valid %d", account_key->owner_key_valid); + ftl_save(account_key, FTL_SAVE_ACCOUNT_KEY_ADDR, gfps_account_key_table_size); +} +#endif diff --git a/src/app/findmy/gfps/app_gfps_account_key.h b/src/app/findmy/gfps/app_gfps_account_key.h new file mode 100644 index 0000000..d1734aa --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_account_key.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _APP_GFPS_ACCOUNT_KEY_H_ +#define _APP_GFPS_ACCOUNT_KEY_H_ + +#include +#include +#include "gfps.h" + +#if GFPS_FEATURE_SUPPORT +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Macros + *============================================================================*/ +#define GFPS_ACCOUNT_KEY_MAX 5 + +/*============================================================================* + * Functions + *============================================================================*/ +bool app_gfps_account_key_init(uint8_t key_num); +void app_gfps_account_key_clear(void); +bool app_gfps_account_key_store(uint8_t key[16], uint8_t *bd_addr); + +/** + * @brief print all account key info + */ +void app_gfps_account_key_table_print(void); + +void app_gfps_account_key_save_ownerkey_valid(void); + +T_ACCOUNT_KEY *app_gfps_account_key_get_table(void); + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/app/findmy/gfps/app_gfps_finder.c b/src/app/findmy/gfps/app_gfps_finder.c new file mode 100644 index 0000000..f23f468 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_finder.c @@ -0,0 +1,787 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_gfps_finder.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-07-27 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#if GFPS_FEATURE_SUPPORT +#include "ftl.h" +#include "trace.h" +#include "string.h" +#include "stdlib.h" +#include "os_timer.h" +#include "gap_conn_le.h" +#include "gfps_find_my_device.h" +#include "app_gfps.h" +#include "app_gfps_account_key.h" +#include "app_gfps_finder.h" +#include "app_gfps_finder_adv.h" +#include "sha256.h" +#include "platform_utils.h" +#include "platform_secp160r1.h" +#include "fmna_sound_platform.h" +#include "fmna_battery_platform.h" +#include "findmy_app.h" +#include "app_task.h" +#include "app_msg.h" +#include "app_dult.h" +#include "gfps_int.h" +#include "dult.h" + +/*============================================================================* +* definitions +*============================================================================*/ +typedef enum +{ + GFPS_FINDER_UPDATE_ADV_EI, + GFPS_FINDER_UPDATE_RANDOM_WINDOW, + GFPS_FINDER_UTP_ENABLE_UPDATE_RPA, + GFPS_FINDER_TOTAL +} T_GFPS_FINDER_TIMER; + +typedef struct +{ + T_GFPS_FINDER *p_finder; + T_GFPS_FINDER_BEACON_STATE finder_state; + bool gfps_finder_read_param; + uint32_t gfps_finder_timeout_ms; + uint8_t gfps_finder_service_id; + uint8_t gfps_finder_ring_volume_level; + uint8_t gfps_finder_ring_type; + uint16_t gfps_finder_ring_timeout; +} T_APP_GFPS_FINDER; + +/*============================================================================* +* Variables +*============================================================================*/ +static T_APP_GFPS_FINDER *p_app_gfps_finder = NULL; +static void *update_adv_ei_timer; +static void *update_random_window_timer; +static void *update_rpa_timer; + +/*============================================================================* +* Global functions +*============================================================================*/ +void app_gfps_finder_set_default_value(void) +{ + p_app_gfps_finder->p_finder = NULL; + p_app_gfps_finder->finder_state = GFPS_FINDER_BEACON_STATE_OFF; + p_app_gfps_finder->gfps_finder_read_param = false; + p_app_gfps_finder->gfps_finder_timeout_ms = 1024000;//1024s + p_app_gfps_finder->gfps_finder_service_id = 0xFF; +} + +void app_gfps_finder_generate_hash_flag(uint8_t *r, uint8_t len, uint8_t *hash) +{ + fmna_bat_state_level_t bat_level = fmna_battery_platform_get_battery_level(); + + if (bat_level == BAT_STATE_LOW) + { + p_app_gfps_finder->p_finder->hash_flag.battery_level = GFPS_FINDER_BATTERY_LOW; + } + else if (bat_level == BAT_STATE_CRITICALLY_LOW) + { + p_app_gfps_finder->p_finder->hash_flag.battery_level = GFPS_FINDER_BATTERY_CRITICALLY_LOW; + } + else + { + p_app_gfps_finder->p_finder->hash_flag.battery_level = GFPS_FINDER_BATTERY_NORMAL; + } + + APP_PRINT_INFO2("app_gfps_finder_generate_hash_flag battery_level = %d, utp_mode = %d", + p_app_gfps_finder->p_finder->hash_flag.battery_level, + p_app_gfps_finder->p_finder->hash_flag.utp_mode); + + uint8_t input = 0; + uint8_t output[32] = {0}; + + SHA256(r + 1, len, output); + memcpy(&input, &p_app_gfps_finder->p_finder->hash_flag, 1); + + /*To produce the final value of this byte, it should be xor-ed with the least significant byte of + SHA256(r). + the least significant byte is output[0] or output[31] ????????????*/ + *hash = input ^ output[31]; +} + +/** + * @brief app_gfps_finder_generate_adv_ei_and_hash + * + * @param p_adv_ei[out] 20 bytes EI + * @param p_eik[in] 32 bytes EIK + * @param counter_value[in] counter_value = (clock_value / 1024) * 1024 + */ +void app_gfps_finder_generate_adv_ei_and_hash(uint8_t *p_adv_ei, uint8_t *p_eik, + uint32_t counter_value, uint8_t *hash) +{ + /*beacon_data[0] - beacon_data[10] Padding, Value = 0xFF*/ + uint8_t padding_len = 11; + uint8_t K = 10; //Rotation period exponent is fixed and set to 10, corresponding to 1024 seconds. + uint8_t *p = p_app_gfps_finder->p_finder->beacon_data; + uint8_t r1[32] = {0};// r' in google spec + uint8_t r[21] = {0}; + uint8_t r_temp[21] = {0}; + uint8_t r_len = 21; + uint8_t adv_ei[20] = {0}; + + memset(p, 0xFF, padding_len); + p += padding_len; + + BE_UINT8_TO_STREAM(p, K); + BE_UINT32_TO_STREAM(p, counter_value); + + /*beacon_data[16] - beacon_data[26] Padding, Value = 0x00*/ + memset(p, 0x00, padding_len); + p += padding_len; + + BE_UINT8_TO_STREAM(p, K); + BE_UINT32_TO_STREAM(p, counter_value); + + gfps_finder_encrypted_beacon_data(p_eik, p_app_gfps_finder->p_finder->beacon_data, r1); + + /*r1 equal to r' in google spec, r = r' mod n*/ + platform_uecc_compute_public_key(r1, adv_ei, r_temp, SECP160R1); + gfps_swap_endian(r, r_temp, r_len); + + memcpy(p_adv_ei, adv_ei, 20); + APP_PRINT_TRACE1("gfps_finder: adv_ei %b", TRACE_BINARY(20, adv_ei)); + + //r will be get from platform_uecc_compute_public_key() + app_gfps_finder_generate_hash_flag(r, 20, hash); +} + +/** + * @brief start timer and set timeout value to 1000ms. + * every 1024 seconds update adv EI and update RPA in deactive UTP mode. + * + * Rotation should happen every 1024 seconds on average. It is required that the + * precise point at which the beacon starts advertising the new identifier is randomized within the + * window. + */ +void app_gfps_finder_start_update_adv_ei_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_start_update_adv_ei_timer"); + os_timer_start(&update_adv_ei_timer); +} + +/** + * @brief stop update adv ei timer + * + */ +void app_gfps_finder_stop_update_adv_ei_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_stop_update_adv_ei_timer"); + os_timer_stop(&update_adv_ei_timer); +} + +/** + * @brief start timer and set timeout value to platform_random(204). + * Add random window, and when timeout provider should update adv EI. + * + * The recommended size of the randomization window is 20% of the interval, i.e. 204 seconds. + * So when the device needs to compute the next time point to rotate EID/MAC, + * it's going to be floor((last_rotation_time_seconds + 1024) / 1024) * 1024 + random(0, 204). + * Rotation should happen every 1024 seconds on average. It is required that the + * precise point at which the beacon starts advertising the new identifier is randomized within the + * window. + */ +void app_gfps_finder_start_update_random_window_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_start_update_random_window_timer"); + os_timer_restart(&update_random_window_timer, platform_random(204) * 1000); +} + +/** + * @brief stop update random window timer + * + */ +void app_gfps_finder_stop_update_random_window_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_stop_update_random_window_timer"); + os_timer_stop(&update_random_window_timer); +} + +/** + * @brief Once UTP mode was activated, the beacon should reduce MAC private address + * rotation frequency to once per 24h. + * start timer and set timeout value to 24h. + * when timeout update RPA. + */ +void app_gfps_finder_upt_enable_start_update_rpa_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_upt_enable_start_update_rpa_timer"); + os_timer_start(&update_rpa_timer); +} + +/** + * @brief stop update rpa timer + * + */ +void app_gfps_finder_upt_enable_stop_rpa_timer() +{ + APP_PRINT_TRACE0("app_gfps_finder_upt_enable_stop_rpa_timer"); + os_timer_stop(&update_rpa_timer); +} + +void app_gfps_update_adv_ei_timer_cb(void *p_timer) +{ + p_app_gfps_finder->p_finder->clock_value += 1024; + ftl_save(&p_app_gfps_finder->p_finder->clock_value, GFPS_FINDER_CLOCK_FLASH_OFFSET, 4); + + app_gfps_finder_start_update_random_window_timer(); + + APP_PRINT_INFO1("app_gfps_update_adv_ei_timer_cb: current_clock_value %#x", + p_app_gfps_finder->p_finder->clock_value); +} + +void app_gfps_update_random_window_handler(void) +{ + uint32_t new_counter = (p_app_gfps_finder->p_finder->clock_value / 1024) * 1024; + APP_PRINT_TRACE1("app_gfps_update_random_window_handler: new_counter=%d", new_counter); + + gfps_finder_adv_stop(); + + uint8_t hash; + app_gfps_finder_generate_adv_ei_and_hash(p_app_gfps_finder->p_finder->adv_ei, + p_app_gfps_finder->p_finder->eik.key, new_counter, &hash); + gfps_finder_adv_update_adv_ei_hash(p_app_gfps_finder->p_finder->adv_ei, hash); + //Fast Pair advertisement, FMDN advertisement and the corresponding BLE address(es) should rotate at the same time. + if (app_gfps_finder_get_utp_mode() == false) + { + gfps_finder_adv_update_rpa(); + } + gfps_finder_adv_start();//no duration +} + +static void app_gfps_update_random_window_timer_cb(void *p_timer) +{ + APP_PRINT_TRACE0("app_gfps_update_random_window_timer_cb"); + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_GFPS; + int_gpio_msg.subtype = IO_MSG_GFPS_ID_ROTAION; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_non_owner_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } +} + +void app_gfps_update_rpa_handler(void) +{ + APP_PRINT_TRACE0("app_gfps_update_rpa_handler"); + if (p_app_gfps_finder->p_finder->hash_flag.utp_mode == 1) + { + APP_PRINT_TRACE0("GFPS_FINDER_UTP_ENABLE_UPDATE_RPA"); + gfps_finder_adv_stop(); + gfps_finder_adv_update_rpa(); + gfps_finder_adv_start(); + } +} + +static void app_gfps_update_rpa_timer_cb(void *p_timer) +{ + APP_PRINT_TRACE0("app_gfps_finder_timeout_cb"); + + T_IO_MSG int_gpio_msg; + int_gpio_msg.type = IO_MSG_TYPE_GFPS; + int_gpio_msg.subtype = IO_MSG_GFPS_UPDATE_RPA; + if (false == app_send_msg_to_apptask(&int_gpio_msg)) + { + APP_PRINT_ERROR0("[fmna_non_owner_connection_timeout_handler]Send int_gpio_msg failed!"); + return; + } + + app_gfps_finder_upt_enable_start_update_rpa_timer(); +} + +void app_gfps_timer_init(void) +{ + if (false == os_timer_create(&update_adv_ei_timer, "update_adv_ei_timer", 1, \ + p_app_gfps_finder->gfps_finder_timeout_ms, true, \ + app_gfps_update_adv_ei_timer_cb)) + { + APP_PRINT_INFO0("[app_gfps_timer_init] init update_adv_ei_timer failed"); + } + + if (false == os_timer_create(&update_random_window_timer, "update_random_window_timer", 1, \ + 1000, false, \ + app_gfps_update_random_window_timer_cb)) + { + APP_PRINT_INFO0("[app_gfps_timer_init] init update_random_window_timer failed"); + } + + if (false == os_timer_create(&update_rpa_timer, "update_rpa_timer", 1, \ + 0x05265C00, false, \ + app_gfps_update_rpa_timer_cb)) //24hours + { + APP_PRINT_INFO0("[app_gfps_timer_init] init update_rpa_timer failed"); + } +} + +/** + * @brief app_gfps_finder_handle_factory_reset + * If a factory reset is performed, + * beaconing should be disabled and the Ephemeral Identity Key + * as well as the owner Account Key used to provision it should be wiped out. + * + */ +void app_gfps_finder_handle_factory_reset(void) +{ + uint32_t ret_eik = 0; + uint32_t ret_clock = 0; + uint8_t ret_value = 0; + + memset(&p_app_gfps_finder->p_finder->eik, 0, sizeof(T_GFPS_EIK)); + ret_eik = ftl_save(&p_app_gfps_finder->p_finder->eik, GFPS_FINDER_EIK_FLASH_OFFSET, + sizeof(T_GFPS_EIK)); + + memset(&p_app_gfps_finder->p_finder->clock_value, 0, 4); + ret_clock = ftl_save(&p_app_gfps_finder->p_finder->clock_value, + GFPS_FINDER_CLOCK_FLASH_OFFSET, 4); + + if (ret_eik || ret_clock) + { + ret_value = 1; + } + + app_gfps_finder_enter_beacon_state(GFPS_FINDER_BEACON_STATE_OFF); + + p_app_gfps_finder->gfps_finder_read_param = false; + + APP_PRINT_TRACE1("app_gfps_finder_handle_factory_reset: ret %s", + ((ret_value == 0) ? TRACE_STRING("success") : TRACE_STRING("fail"))); +} + + +void app_gfps_finder_set_factory_flag(bool flag) +{ + p_app_gfps_finder->p_finder->factory_reset_pending = flag; +} + +bool app_gfps_finder_get_factory_flag(void) +{ + return p_app_gfps_finder->p_finder->factory_reset_pending; +} + +/** + * @brief app_gfps_finder_enter_beacon_state + * used to start or stop beacon adv(gfps_finder_adv) + * + * @param beacon_state @ref T_GFPS_FINDER_BEACON_STATE + */ +void app_gfps_finder_enter_beacon_state(T_GFPS_FINDER_BEACON_STATE beacon_state) +{ + APP_PRINT_INFO1("app_gfps_finder_enter_beacon_state %d", beacon_state); + + if (beacon_state == GFPS_FINDER_BEACON_STATE_ON && p_app_gfps_finder->p_finder->eik.valid) + { + uint8_t hash; + uint32_t counter = (p_app_gfps_finder->p_finder->clock_value / 1024) * 1024; + app_gfps_finder_generate_adv_ei_and_hash(p_app_gfps_finder->p_finder->adv_ei, + p_app_gfps_finder->p_finder->eik.key, counter, &hash); + gfps_finder_adv_update_adv_ei_hash(p_app_gfps_finder->p_finder->adv_ei, hash); + gfps_finder_adv_start(); + app_gfps_finder_start_update_adv_ei_timer(); + p_app_gfps_finder->finder_state = GFPS_FINDER_BEACON_STATE_ON; + } + else if (beacon_state == GFPS_FINDER_BEACON_STATE_OFF) + { + gfps_finder_adv_stop(); + app_gfps_finder_stop_update_adv_ei_timer(); + app_gfps_finder_stop_update_random_window_timer(); + app_gfps_finder_upt_enable_stop_rpa_timer(); + p_app_gfps_finder->finder_state = GFPS_FINDER_BEACON_STATE_OFF; + } +} + +/** + * @brief app_gfps_finder_get_beacon_state + * + * @return finder state @ref T_GFPS_FINDER_BEACON_STATE + */ +T_GFPS_FINDER_BEACON_STATE app_gfps_finder_get_beacon_state(void) +{ + return p_app_gfps_finder->finder_state; +} + +/** + * @brief app_gfps_finder_send_ring_rsp + * When ringing starts or terminates a notification is sent to seeker. + * @param ring_state @ref T_GFPS_FINDER_RING_STATE + * @return true + * @return false + */ +bool app_gfps_finder_send_ring_rsp(uint8_t ring_state) +{ + bool ret = false; + + if ((app_gfps_get_conn_id() == 0xFF) || + (p_app_gfps_finder->gfps_finder_service_id == 0xFF)) + { + APP_PRINT_ERROR0("app_gfps_finder_send_ring_rsp: invalid conn"); + return false; + } + + ret = gfps_finder_rsp_ring_request(app_gfps_get_conn_id(), + p_app_gfps_finder->gfps_finder_service_id, + ring_state, + p_app_gfps_finder->gfps_finder_ring_type, + p_app_gfps_finder->gfps_finder_ring_timeout); + return ret; +} + +/** + * @brief app_gfps_finder_reset_conn + * reset conn_id when ble link disconnected. + * this ble link maybe gfps ble link or gfps finder beacon ble link. + * if seeker modify EIK, The new Ephemeral Identity Key + * should take effect immediately after the BLE connection is terminated. + */ +void app_gfps_finder_reset_conn(void) +{ + APP_PRINT_INFO1("app_gfps_finder_reset_conn: temp_modified_eik.valid %d", + p_app_gfps_finder->p_finder->temp_modified_eik.valid); + + if (p_app_gfps_finder->p_finder->temp_modified_eik.valid == true) + { + memcpy(p_app_gfps_finder->p_finder->eik.key, p_app_gfps_finder->p_finder->temp_modified_eik.key, + 32); + p_app_gfps_finder->p_finder->temp_modified_eik.valid = false; + ftl_save(&p_app_gfps_finder->p_finder->eik, GFPS_FINDER_EIK_FLASH_OFFSET, + sizeof(T_GFPS_EIK)); + } + +// if (p_app_gfps_finder->gfps_finder_read_param) +// { +// p_app_gfps_finder->gfps_finder_read_param = false; + if (app_gfps_finder_provisoned()) + { + app_gfps_finder_enter_beacon_state(GFPS_FINDER_BEACON_STATE_ON); + } +// } +}; + +void app_gfps_finder_set_ring_param(void) +{ + p_app_gfps_finder->p_finder->ring_components_num = GFPS_FINDER_RING_SINGLE; + p_app_gfps_finder->p_finder->ring_volume_modify = GFPS_FINDER_RING_VOLUME_ENABLE; +} + +static uint16_t app_gfps_volume_lv_convert_to_freq(T_GFPS_FINDER_RING_VOLUME_LEVEL volume_level) +{ + uint16_t pwm_freq = 0; + switch (volume_level) + { + case GFPS_FINDER_RING_VOLUME_DEFAULT: + pwm_freq = PWM_DEFAULT_FREQ; + break; + + case GFPS_FINDER_RING_VOLUME_LOW: + pwm_freq = PWM_LOW_FREQ; + break; + + case GFPS_FINDER_RING_VOLUME_MEDIUM: + pwm_freq = PWM_MEDIUM_FREQ; + break; + + case GFPS_FINDER_RING_VOLUME_HIGH: + pwm_freq = PWM_HIGH_FREQ; + break; + + default: + APP_PRINT_ERROR1("GFPS_FINDER_EVT_RING: undefined ring_volume_level %d", volume_level); + break; + } + return pwm_freq; +} + +T_GFPS_FINDER_RING_VOLUME_LEVEL app_gfps_finder_get_ring_volume_level(void) +{ + return (T_GFPS_FINDER_RING_VOLUME_LEVEL)p_app_gfps_finder->gfps_finder_ring_volume_level; +} + +bool app_gfps_finder_set_ring_type(T_GFPS_RING_TYPE ring_type, + T_GFPS_FINDER_RING_STATE ring_new_state) +{ + if (p_app_gfps_finder->gfps_finder_ring_type == ring_type) + { + APP_PRINT_INFO0("GFPS ring type don't change"); + return false; + } + + p_app_gfps_finder->gfps_finder_ring_type = ring_type; + if (ring_type == GFPS_RING_STOP) + { + p_app_gfps_finder->gfps_finder_ring_timeout = 0; + if (ring_new_state != GFPS_FINDER_RING_GATT_STOP) + { + app_gfps_finder_send_ring_rsp(ring_new_state); + } + } + APP_PRINT_INFO2("app_gfps_finder_set_ring_type %d, timeout %ds", + ring_type, p_app_gfps_finder->gfps_finder_ring_timeout); + return true; +} + +/** + * @brief app_gfps_finder_cb + * receive event from gfps_lib then handle it. + * @param p_data + * @return T_GFPS_FINDER_CAUSE + */ +T_GFPS_FINDER_CAUSE app_gfps_finder_cb(T_GFPS_FINDER_CB_DATA *p_data) +{ + T_GFPS_FINDER_CAUSE cause = GFPS_FINDER_CAUSE_SUCCESS; + + T_GFPS_FINDER_CB_DATA data; + memcpy(&data, p_data, sizeof(T_GFPS_FINDER_CB_DATA)); + + uint8_t evt = data.evt; + uint8_t ret_err = 0; + APP_PRINT_INFO1("app_gfps_finder_cb: evt %d", evt); + + switch (evt) + { + case GFPS_FINDER_EVT_SET_EIK: + { + memcpy(&p_app_gfps_finder->p_finder->eik, &data.msg_data.eik, sizeof(T_GFPS_EIK)); + + uint32_t save_ret = ftl_save(&p_app_gfps_finder->p_finder->eik, + GFPS_FINDER_EIK_FLASH_OFFSET, + sizeof(T_GFPS_EIK)); + if (save_ret) + { + ret_err = 1; + goto err; + }; + os_timer_stop(&locator_tag_unpair_timer); + app_gfps_finder_enter_beacon_state(GFPS_FINDER_BEACON_STATE_ON); + } + break; + + case GFPS_FINDER_EVT_CLEAR_EIK: + { + memset(&p_app_gfps_finder->p_finder->eik, 0, sizeof(T_GFPS_EIK)); + uint32_t ret = ftl_save(&p_app_gfps_finder->p_finder->eik, GFPS_FINDER_EIK_FLASH_OFFSET, + sizeof(T_GFPS_EIK)); + if (ret) + { + ret_err = 2; + goto err; + } + + /*If the EIK is cleared from the device, the device should perform a factory + reset and clear the stored Account Keys as well.*/ + app_gfps_finder_set_factory_flag(true); + } + break; + + case GFPS_FINDER_EVT_KEY_RECOVERY: + { + //TODO: If the device is not in pairing mode, Provider should return a No User Consent error. + //cause = GFPS_FINDER_CAUSE_NO_USER_CONSENT; + } + break; + + case GFPS_FINDER_EVT_RING: + { + p_app_gfps_finder->gfps_finder_service_id = data.msg_data.ring.service_id; + p_app_gfps_finder->gfps_finder_ring_timeout = data.msg_data.ring.ring_time; + + uint8_t ring_type = data.msg_data.ring.ring_type; + T_GFPS_FINDER_RING_VOLUME_LEVEL ring_volume_level = (T_GFPS_FINDER_RING_VOLUME_LEVEL) + data.msg_data.ring.ring_volume_level; + uint16_t pwm_freq = PWM_DEFAULT_FREQ; + /*A byte indicating the new ringing state*/ + T_GFPS_FINDER_RING_STATE ring_state = GFPS_FINDER_RING_FAIL; + + if ((ring_volume_level != GFPS_FINDER_RING_VOLUME_DEFAULT) && + (p_app_gfps_finder->p_finder->ring_volume_modify == GFPS_FINDER_RING_VOLUME_ENABLE)) + { + p_app_gfps_finder->gfps_finder_ring_volume_level = ring_volume_level; + pwm_freq = app_gfps_volume_lv_convert_to_freq(ring_volume_level); + } + + /*the first byte may hold a special value of 0xFF to ring all components that can ring.*/ + if (ring_type == 0xFF || ring_type == GFPS_ALL_RING) + { + ring_state = GFPS_FINDER_RING_STARTED; + app_gfps_finder_set_ring_type(GFPS_ALL_RING, ring_state); + fmna_sound_platform_start(SOUND_EVENT_GFPS_FINDER, + p_app_gfps_finder->gfps_finder_ring_timeout * 1000, pwm_freq); + } + else if (ring_type == GFPS_RING_STOP) + { + ring_state = GFPS_FINDER_RING_GATT_STOP; + fmna_sound_platform_stop(SOUND_EVENT_GFPS_FINDER); + app_gfps_finder_set_ring_type(GFPS_RING_STOP, ring_state); + } + + gfps_finder_rsp_ring_request(app_gfps_get_conn_id(), + p_app_gfps_finder->gfps_finder_service_id, + ring_state, + p_app_gfps_finder->gfps_finder_ring_type, + p_app_gfps_finder->gfps_finder_ring_timeout); + } + break; + + case GFPS_FINDER_EVT_RING_STATE: + { + p_app_gfps_finder->gfps_finder_service_id = data.msg_data.ring.service_id; + + /*Two bytes indicating the remaining time for ringing in deciseconds*/ + gfps_finder_rsp_ring_state(app_gfps_get_conn_id(), + p_app_gfps_finder->gfps_finder_service_id, + p_app_gfps_finder->gfps_finder_ring_type, + p_app_gfps_finder->gfps_finder_ring_timeout); + } + break; + + case GFPS_FINDER_EVT_UTP_ACTIVE: + { + dult_set_state(DULT_SEPARATED); + gfps_finder_adv_update_frame_type(0x41); + app_gfps_finder_upt_enable_start_update_rpa_timer(); + } + break; + + case GFPS_FINDER_EVT_UTP_DEACTIVE: + { + dult_set_state(DULT_NEAR_OWNER); + gfps_finder_adv_update_frame_type(0x40); + app_gfps_finder_upt_enable_stop_rpa_timer(); + } + break; + + case GFPS_FINDER_EVT_SET_OWNERKEY_VALID: + { + app_gfps_account_key_save_ownerkey_valid(); + } + break; + + case GFPS_FINDER_EVT_READ_BEACON_PARAM: + { + p_app_gfps_finder->gfps_finder_read_param = true; + } + break; + + default: + { + + } + break; + } + return cause; + +err: + cause = GFPS_FINDER_CAUSE_INVALID_VALUE; + APP_PRINT_ERROR1("app_gfps_finder_cb: err %d", ret_err); + return cause; +} + +bool app_gfps_finder_provisoned(void) +{ + return p_app_gfps_finder->p_finder->eik.valid; +} + +void app_gfps_handle_button_press(void) +{ + if (p_app_gfps_finder->gfps_finder_ring_type == GFPS_ALL_RING) + { + APP_PRINT_INFO0("app_gfps_handle_button_press stop ring"); + fmna_sound_platform_stop(SOUND_EVENT_GFPS_FINDER); + app_gfps_finder_set_ring_type(GFPS_RING_STOP, GFPS_FINDER_RING_BUTTON_STOP); + } +} + +/** + * @brief get utp mode + * + * @return true active utp mode + * @return false deactive utp mode + */ +bool app_gfps_finder_get_utp_mode(void) +{ + return p_app_gfps_finder->p_finder->hash_flag.utp_mode; +} + +void app_gfps_finder_ftl_init(void) +{ + uint32_t eik_ret = ftl_load(&p_app_gfps_finder->p_finder->eik, + GFPS_FINDER_EIK_FLASH_OFFSET, sizeof(T_GFPS_EIK)); + uint32_t clock_ret = ftl_load(&p_app_gfps_finder->p_finder->clock_value, + GFPS_FINDER_CLOCK_FLASH_OFFSET, 4); + + if (eik_ret) + { + memset(&p_app_gfps_finder->p_finder->eik, 0, sizeof(T_GFPS_EIK)); + ftl_save(&p_app_gfps_finder->p_finder->eik, GFPS_FINDER_EIK_FLASH_OFFSET, + sizeof(T_GFPS_EIK)); + } + + if (clock_ret) + { + memset(&p_app_gfps_finder->p_finder->clock_value, 0, 4); + ftl_save(&p_app_gfps_finder->p_finder->clock_value, GFPS_FINDER_CLOCK_FLASH_OFFSET, 4); + } + + APP_PRINT_INFO3("app_gfps_finder_ftl_init: eik %b, valid %d, clock %d", + TRACE_BINARY(32, p_app_gfps_finder->p_finder->eik.key), p_app_gfps_finder->p_finder->eik.valid, + p_app_gfps_finder->p_finder->clock_value); +} + +static void app_gfps_finder_beacon_init(void) +{ + gfps_finder_adv_init(p_app_gfps_finder->p_finder->adv_ei, 0); +} + +void app_gfps_get_ei(uint8_t *p_ei) +{ + memcpy(p_ei, p_app_gfps_finder->p_finder->adv_ei, 32); +} + +bool app_gfps_finder_init(void) +{ + p_app_gfps_finder = calloc(1, sizeof(T_APP_GFPS_FINDER)); + + if (p_app_gfps_finder) + { + app_gfps_finder_set_default_value(); + p_app_gfps_finder->p_finder = calloc(1, sizeof(T_GFPS_FINDER)); + + if (p_app_gfps_finder->p_finder) + { +#if GFPS_FINDER_TEST_SUPPORT + bool app_gfps_finder_test(void); + app_gfps_finder_test(); +#endif + app_gfps_finder_ftl_init(); + app_gfps_finder_beacon_init(); + gfps_finder_init(p_app_gfps_finder->p_finder, app_gfps_finder_cb); + app_gfps_timer_init(); + app_gfps_finder_set_ring_param(); + app_gfps_finder_dult_init(); + if (!app_gfps_finder_provisoned()) + { + app_gfps_account_key_clear(); + } + return true; + } + else + { + APP_PRINT_ERROR0("app_gfps_finder_init: err"); + return false; + } + } + return false; +} +#endif diff --git a/src/app/findmy/gfps/app_gfps_finder.h b/src/app/findmy/gfps/app_gfps_finder.h new file mode 100644 index 0000000..1bef494 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_finder.h @@ -0,0 +1,115 @@ +#ifndef _APP_GFPS_FINDER_H_ +#define _APP_GFPS_FINDER_H_ + +#include "stdbool.h" +#include "stdlib.h" +#include "stdint.h" +#include "gfps.h" +#include "gfps_find_my_device.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief beacon state + * GFPS_FINDER_BEACON_STATE_OFF stop beacon adv and stop beacon timer + * GFPS_FINDER_BEACON_STATE_ON start beacon adv and start beacon timer + */ +typedef enum +{ + GFPS_FINDER_BEACON_STATE_OFF = 0x00, + GFPS_FINDER_BEACON_STATE_ON = 0x01, +} T_GFPS_FINDER_BEACON_STATE; + +typedef enum +{ + GFPS_RING_STOP = 0x00, + GFPS_RIGHT_RING = 0x01, + GFPS_LEFT_RING = 0x02, + GFPS_ALL_RING = 0x03, +} T_GFPS_RING_TYPE; + +/** + * @brief app_gfps_finder_init + * init gfps finder struct. + * @return true + * @return false + */ +bool app_gfps_finder_init(void); + +/** + * @brief app_gfps_finder_handle_factory_reset + * If a factory reset is performed, + * beaconing should be disabled and the Ephemeral Identity Key + * as well as the owner Account Key used to provision it (as described above) should be wiped out. + */ +void app_gfps_finder_handle_factory_reset(void); + +/** + * @brief app_gfps_finder_enter_beacon_state + * used to start or stop beacon adv(gfps_finder_adv) + * @param beacon_state @ref T_GFPS_FINDER_BEACON_STATE + */ +void app_gfps_finder_enter_beacon_state(T_GFPS_FINDER_BEACON_STATE beacon_state); + +/** + * @brief app_gfps_finder_get_beacon_state + * + * @return finder state @ref T_GFPS_FINDER_BEACON_STATE + */ +T_GFPS_FINDER_BEACON_STATE app_gfps_finder_get_beacon_state(void); + +/** + * @brief app_gfps_finder_send_ring_rsp + * When ringing starts or terminates a notification is sent to seeker. + * @param ring_state @ref T_GFPS_FINDER_RING_STATE + * @return true + * @return false + */ +bool app_gfps_finder_send_ring_rsp(uint8_t ring_state); + +/** + * @brief app_gfps_finder_reset_conn + * reset conn_id when ble link disconnect. + */ +void app_gfps_finder_reset_conn(void); + +void app_gfps_finder_set_factory_flag(bool flag); + +bool app_gfps_finder_get_factory_flag(void); + +T_GFPS_FINDER_RING_VOLUME_LEVEL app_gfps_finder_get_ring_volume_level(void); + +void app_gfps_finder_set_ring_param(void); + +bool app_gfps_finder_set_ring_type(T_GFPS_RING_TYPE ring_type, + T_GFPS_FINDER_RING_STATE ring_new_state); + +bool app_gfps_finder_provisoned(void); + +void app_gfps_update_random_window_handler(void); + +void app_gfps_update_rpa_handler(void); + +void app_gfps_handle_button_press(void); + +/** + * @brief get utp mode + * + * @return true active utp mode + * @return false deactive utp mode + */ +bool app_gfps_finder_get_utp_mode(void); + +/** + * @brief get ephemeral identifier data + * + * @return ephemeral identifier data + */ +void app_gfps_get_ei(uint8_t *p_ei); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/app/findmy/gfps/app_gfps_finder_adv.c b/src/app/findmy/gfps/app_gfps_finder_adv.c new file mode 100644 index 0000000..610712e --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_finder_adv.c @@ -0,0 +1,170 @@ +/** +********************************************************************************************************* +* Copyright(c) 2023, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file app_gfps_finder_adv.c +* @brief +* @details +* @author scarlett_liang +* @date 2023-07-30 +* @version v1.0 +* ********************************************************************************************************* +*/ +/*============================================================================* + * Header Files + *============================================================================*/ +#if GFPS_FEATURE_SUPPORT +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "app_gfps.h" +#include "app_gfps_finder.h" +#include "app_gfps_finder_adv.h" +#include "findmy_app.h" +#include "fmna_gap_platform.h" + +/*============================================================================* +* Local Variables +*============================================================================*/ +static T_ADV_DATA gfps_finder_adv; + +/** + * @brief GFPS finder beacon advertising data + Eddystone-E2EE frame supporting a 160-bit curve + * + */ +static uint8_t gfps_finder_advdata[29] = +{ + 0x02,//length = 0x02 + 0x01,//type = GAP_ADTYPE_FLAGS + 0x06,//data = GAP_ADTYPE_FLAGS_GENERAL|GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED + + 0x19,//length = 0x18 + GAP_ADTYPE_SERVICE_DATA, + 0xAA, 0xFE, //data: 16-bit Eddystone UUID = 0xFEAA + 0x40,//E2EE-EID Frame type + /*20-byte Ephemeral Identifier.*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*hashed flags*/ + 0x00 +}; + +static uint8_t gfps_finder_scanrspdata[13] = +{ + 12,//length = 0x02 + GAP_ADTYPE_LOCAL_NAME_COMPLETE, + 'G', 'F', 'P', 'S', '_', 'F', 'i', 'n', 'd', 'e', 'r', +}; + +/*============================================================================* +* Global functions +*============================================================================*/ +T_GAP_CAUSE gfps_finder_adv_update_rpa(void) +{ + T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS; + uint16_t error_line; + + uint8_t random_address[6] = {0}; + T_GAP_LOCAL_ADDR_TYPE local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM; + cause = le_gen_rand_addr(GAP_RAND_ADDR_STATIC, random_address); + __GAP_RET_CHECK(cause, fail); + +#if ONE_SHOT_ADV_EN + one_shot_bt_addr_set(random_address, local_bd_type, ADV_DATA_FINDER); +#else + cause = le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + __GAP_RET_CHECK(cause, fail); + cause = le_set_rand_addr(random_address); + __GAP_RET_CHECK(cause, fail); +#endif + memcpy(gfps_db.local_bd_addr, random_address, 6); + APP_PRINT_TRACE1("gfps_finder_adv_update_rpa: RPA %s", + TRACE_BDADDR(random_address)); + return cause; +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + cause); + } + return cause; +} + +void gfps_finder_adv_start(void) +{ + T_GAP_CAUSE cause = GAP_CAUSE_SUCCESS; + uint16_t error_line; + + cause = le_adv_set_tx_power(GAP_ADV_TX_POW_SET_1M, 0x08); // 4dBm + __GAP_RET_CHECK(cause, fail); + + /*if device not in active UTP mode, update RPA when start adv or update adv EI*/ + if (app_gfps_finder_get_utp_mode() == false) + { + cause = gfps_finder_adv_update_rpa(); + } + __GAP_RET_CHECK(cause, fail); + + cause = fmble_gap_adv_data_set(gfps_finder_adv, ADV_DATA_FINDER); + __GAP_RET_CHECK(cause, fail); + cause = fmble_gap_adv_start(ADV_DATA_FINDER); + __GAP_RET_CHECK(cause, fail); + APP_PRINT_TRACE0("gfps_finder_adv_start"); + return; +fail: + if (error_line) + { + APP_PRINT_ERROR3("GAP error func:%s, line:%d, err_code:%d", TRACE_STRING(__FUNCTION__), error_line, + cause); + } +} + +void gfps_finder_adv_stop(void) +{ + APP_PRINT_TRACE0("gfps_finder_adv_stop"); + fmble_gap_adv_stop(ADV_DATA_FINDER); +} + +/** + * @brief update frame type + * + * the frame type should be set to 0x41 when Unwanted Tracking Protection mode is on. + * the frame type should be set to 0x40 when Unwanted Tracking Protection mode is off. + * @param frame_type + */ +void gfps_finder_adv_update_frame_type(uint8_t frame_type) +{ + gfps_finder_advdata[7] = frame_type; +} + +/** + * @brief update adv EI and hash + * + * @param p_ei + * @param hash + */ +void gfps_finder_adv_update_adv_ei_hash(uint8_t *p_ei, uint8_t hash) +{ + if (p_ei) + { + memcpy(&gfps_finder_advdata[8], p_ei, 20); + } + gfps_finder_advdata[28] = hash; + APP_PRINT_TRACE2("gfps_finder_adv_update_adv_ei_hash: EI %b, hash %#x", TRACE_BINARY(20, p_ei), + hash); +} + +void gfps_finder_adv_init(uint8_t *p_adv_ei, uint8_t hash) +{ + memcpy(&gfps_finder_advdata[8], p_adv_ei, 20); + gfps_finder_advdata[28] = hash; + gfps_finder_adv.p_adv_data = gfps_finder_advdata; + gfps_finder_adv.adv_data_len = sizeof(gfps_finder_advdata); + gfps_finder_adv.p_scan_rsp_data = gfps_finder_scanrspdata; + gfps_finder_adv.scan_rsp_data_len = sizeof(gfps_finder_scanrspdata); + + gfps_finder_adv.adv_type = GAP_ADTYPE_ADV_IND; + gfps_finder_adv.adv_interval = 0xC80; //2s +} +#endif diff --git a/src/app/findmy/gfps/app_gfps_finder_adv.h b/src/app/findmy/gfps/app_gfps_finder_adv.h new file mode 100644 index 0000000..ac4dab9 --- /dev/null +++ b/src/app/findmy/gfps/app_gfps_finder_adv.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _APP_GFPS_FINDER_ADV_H_ +#define _APP_GFPS_FINDER_ADV_H_ + +#include "stdbool.h" +#include "stdlib.h" +#include "stdint.h" +#include "gfps.h" +#include "gap_ext_adv.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief gfps_finder_adv_start + * start gfps finder adv + */ +void gfps_finder_adv_start(void); + +/** + * @brief gfps_finder_adv_stop + * stop gfps finder adv + */ +void gfps_finder_adv_stop(void); + +/** + * @brief set frame type + * + * the frame type should be set to 0x41 when Unwanted Tracking Protection mode is on. + * the frame type should be set to 0x40 when Unwanted Tracking Protection mode is off. + * @param frame_type + */ +void gfps_finder_adv_update_frame_type(uint8_t frame_type); + +/** + * @brief gfps_finder_adv_update_adv_ei_hash + * update adv EI and hash + * @param p_ei 20 bytes indicating the current E2EE EID advertised by the beacon + * @param hash + */ +void gfps_finder_adv_update_adv_ei_hash(uint8_t *p_ei, uint8_t hash); + +/** + * @brief update resolvable private address + * + * @return T_GAP_CAUSE + */ +T_GAP_CAUSE gfps_finder_adv_update_rpa(void); + +/** + * @brief gfps_finder_adv_init + * init gfps finder adv + * @param p_adv_ei 20 bytes indicating the current E2EE EID advertised by the beacon. + */ +void gfps_finder_adv_init(uint8_t *p_adv_ei, uint8_t hash); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/app/findmy/gfps/gfps_lib/dult.h b/src/app/findmy/gfps/gfps_lib/dult.h new file mode 100644 index 0000000..fb27185 --- /dev/null +++ b/src/app/findmy/gfps/gfps_lib/dult.h @@ -0,0 +1,114 @@ +#ifndef dult_h +#define dult_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DULT_SRV_UUID 0xFCB2 + +// DULT non-owner service opcodes +#define DULT_OPCODE_LENGTH 2 + +// DULT accessory capabilities +#define DULT_SUPPORT_PLAY_SOUND BIT(0) +#define DULT_SUPPORT_MOTION_DETECTOR_UT BIT(1) +#define DULT_SUPPORT_LOOKUP_NFC BIT(2) +#define DULT_SUPPORT_LOOPKUP_BLE BIT(3) + +typedef enum +{ + DULT_SERVICE_OPCODE_NONE = 0x0000, + + // Accessory information + DULT_SERVICE_OPCODE_GET_PRODUCT_DATA = 0x0003, + DULT_SERVICE_OPCODE_GET_PRODUCT_DATA_RESPONSE = 0x0803, + DULT_SERVICE_OPCODE_GET_MANUFACTURER_NAME = 0x0004, + DULT_SERVICE_OPCODE_GET_MANUFACTURER_NAME_RESPONSE = 0x0804, + DULT_SERVICE_OPCODE_GET_MODEL_NAME = 0x0005, + DULT_SERVICE_OPCODE_GET_MODEL_NAME_RESPONSE = 0x0805, + DULT_SERVICE_OPCODE_GET_ACCESSORY_CATEGORY = 0x0006, + DULT_SERVICE_OPCODE_GET_ACCESSORY_CATEGORY_RESPONSE = 0x0806, + DULT_SERVICE_OPCODE_GET_PROTOCOL_IMPLEMENTATION_VERSION = 0x0007, + DULT_SERVICE_OPCODE_GET_PROTOCOL_IMPLEMENTATION_VERSION_RESPONSE = 0x0807, + DULT_SERVICE_OPCODE_GET_ACCESSORY_CAPABILITIES = 0x0008, + DULT_SERVICE_OPCODE_GET_ACCESSORY_CAPABILITIES_RESPONSE = 0x0808, + DULT_SERVICE_OPCODE_GET_NETWORK_ID = 0x0009, + DULT_SERVICE_OPCODE_GET_NETWORK_ID_RESPONSE = 0x0809, + DULT_SERVICE_OPCODE_GET_FIRMWARE_VERSION = 0x000A, + DULT_SERVICE_OPCODE_GET_FIRMWARE_VERSION_RESPONSE = 0x080A, + DULT_SERVICE_OPCODE_GET_BATTERY_TYPE = 0x000B, + DULT_SERVICE_OPCODE_GET_BATTERY_TYPE_RESPONSE = 0x080B, + DULT_SERVICE_OPCODE_GET_BATTERY_LEVEL = 0x000C, + DULT_SERVICE_OPCODE_GET_BATTERY_LEVEL_RESPONSE = 0x080C, + + // Non-owner controls + DULT_SERVICE_OPCODE_NON_OWNER_CONTROL_POINT_BASE = 0x0300, + DULT_SERVICE_NON_OWNER_OPCODE_SOUND_START = 0x0300, + DULT_SERVICE_NON_OWNER_OPCODE_SOUND_STOP = 0x0301, + DULT_SERVICE_NON_OWNER_OPCODE_COMMAND_RESPONSE = 0x0302, + DULT_SERVICE_NON_OWNER_OPCODE_SOUND_COMPLETED = 0x0303, + DULT_SERVICE_NON_OWNER_OPCODE_GET_IDENTIFIER = 0x0404, + DULT_SERVICE_NON_OWNER_OPCODE_GET_IDENTIFIER_RESPONSE = 0x0405, +} DULT_Service_Opcode_t; + +// Response Status to Command Reponse possibilities +typedef enum +{ + DULT_RESPONSE_STATUS_SUCCESS = 0x0000, + DULT_RESPONSE_STATUS_INVALID_STATE = 0x0001, + DULT_RESPONSE_STATUS_INVALID_CONFIGURATION = 0x0002, + DULT_RESPONSE_STATUS_INVALID_LENGTH = 0x0003, + DULT_RESPONSE_STATUS_INVALID_PARAM = 0x0004, + DULT_RESPONSE_STATUS_NO_COMMAND_RESPONSE = 0xFFFE, + DULT_RESPONSE_STATUS_INVALID_COMMAND = 0xFFFF, +} DULT_Response_Status_t; + +typedef enum +{ + DULT_CALLBACK_EVENT_SOUND_START, + DULT_CALLBACK_EVENT_SOUND_STOP, + DULT_CALLBACK_EVENT_GET_IDENTIFIER, +} DULT_Callback_Event_t; + +typedef enum +{ + DULT_NEAR_OWNER, + DULT_SEPARATED, +} DULT_State_t; + +typedef struct +{ + DULT_Service_Opcode_t opcode; + uint8_t operand[40]; +} __attribute__((packed)) dult_tx_buffer_t; + +typedef struct +{ + uint8_t product_data[8]; + char *p_manufacturer_name; + char *p_model_name; + uint64_t accessory_category; + uint8_t network_id; + uint32_t accessory_capabilities; + uint32_t firmware_version; + uint8_t battery_type; + uint8_t battery_level; +} __attribute__((packed)) dult_info_t; + +T_SERVER_ID dult_add_service(void *p_func); +void dult_gatt_send_indication(uint16_t conn_handle, T_SERVER_ID service_id, \ + DULT_Service_Opcode_t opcode, void *data, uint16_t length); +void dult_gatt_send_cmd_rsp(uint16_t conn_handle, T_SERVER_ID service_id, \ + DULT_Service_Opcode_t opcode, void *data, uint16_t length); +void dult_set_battery_level(uint8_t battery_level); +void dult_set_state(DULT_State_t new_state); +void dult_init(dult_info_t dult_info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/app/findmy/gfps/gfps_lib/gfps.h b/src/app/findmy/gfps/gfps_lib/gfps.h new file mode 100644 index 0000000..58a6b40 --- /dev/null +++ b/src/app/findmy/gfps/gfps_lib/gfps.h @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ + +#ifndef _GFPS_H_ +#define _GFPS_H_ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** @defgroup GFPS GFPS + * @brief + * @{ + */ + +/** @defgroup APP_GFPS GFPS LIB + * @brief Google fast pair service lib + * @{ + */ + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GFPS_Exported_Macros Gfps Macros + * @{ + */ +#define GFPS_DATA_ID_PERSONALIZED_NAME 0x01 + +#define GFPS_ADDTIONAL_DATA_SUPPORT (!GFPS_LOCATOR_TAG && GFPS_FEATURE_SUPPORT) +#define GFPS_PERSONALIZED_NAME_SUPPORT (1 && GFPS_ADDTIONAL_DATA_SUPPORT) + +#define GFPS_PSM_MSG_STREAM 0x0080 + +#define GFPS_CHAR_KEY_BASE_PAIRING_INDEX 0x04 +#define GFPS_CHAR_KEY_BASE_PAIRING_CCCD_INDEX (GFPS_CHAR_KEY_BASE_PAIRING_INDEX + 1) +#define GFPS_CHAR_PASSKEY_INDEX 0x07 +#define GFPS_CHAR_PASSKEY_CCCD_INDEX (GFPS_CHAR_PASSKEY_INDEX + 1) +#define GFPS_CHAR_ACCOUNT_KEY_INDEX 0x0A +#define GFPS_CHAR_FIND_BEACON_ACTION_INDEX 0x0C +#define GFPS_CHAR_FIND_BEACON_ACTION_CCCD_INDEX (GFPS_CHAR_FIND_BEACON_ACTION_INDEX + 1) +#define GFPS_CHAR_ADDITIONAL_DATA_INDEX 0x0F +#define GFPS_CHAR_ADDITIONAL_DATA_CCCD_INDEX (GFPS_CHAR_ADDITIONAL_DATA_INDEX + 1) +#define GFPS_CHAR_PSM_INDEX 0x12 + +#if GFPS_FEATURE_SUPPORT +#define GFPS_PERSONALIZED_NAME_MAX_LEN (64) +#define GFPS_BATTERY_VALUE_UNKNOWN 0x7F +#define GFPS_ACCOUNT_KEY_LENGTH (16) +#define GFPS_BD_ADDR_LENGTH (8) + +//Distribution of keys +#define GFPS_LE_SMP_DIST_ENC_KEY 0x01/*distribute LTK*/ +#define GFPS_LE_SMP_DIST_ID_KEY 0x02/*distribute IRK*/ +#define GFPS_LE_SMP_DIST_SIGN_KEY 0x04/*distribute CSRK*/ +#define GFPS_LE_SMP_DIST_LINK_KEY 0x08/*distribute link key*/ + +/** End of GFPS_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GFPS_Exported_Types Gfps Types + * @{ + */ + +typedef enum +{ + GFPS_WRITE_RESULT_SUCCESS = 0, + GFPS_WRITE_RESULT_ERROR_DECRYPT_FAIL = 1, + GFPS_WRITE_RESULT_ERROR_NOT_IN_PAIR_MODE = 2, + GFPS_WRITE_RESULT_ERROR_MESSAGE_TYPE = 3, + GFPS_WRITE_RESULT_ERROR_PROVIDER_ADDRESS = 4, + GFPS_WRITE_RESULT_ERROR_ADDITIONAL_DATA_LEN = 5, + GFPS_WRITE_RESULT_ERROR_INVALID_PARAM = 6, + + GFPS_WRITE_RESULT_ERROR_UNKNOWN = 0xff, +} T_GFPS_KBP_WRITE_RESULT; + +typedef struct +{ + bool battery_enable; //!< Whether including the battery notification + bool battery_show_ui; //!< Whether showing UI: true(show UI indication) or false(hide UI indication) + bool battery_left_charging; //!< Whether in charging: true(charging) or false(not charging) + uint8_t battery_left_level; //!< Left bud battery level. Range: 0-100 (0x7F-unknown) + bool battery_right_charging; //!< Whether in charging: true(charging) or false(not charging) + uint8_t battery_right_level; //!< Right bud battery level. Range: 0-100 (0x7F-unknown) + bool battery_case_charging; //!< Whether in charging: true(charging) or false(not charging) + uint8_t battery_case_level; //!< Case battery level. Range: 0-100 (0x7F-unknown) + bool battery_remain_time_enable; + uint16_t battery_remain_time; +} T_GFPS_BATTERY_INFO; + +typedef struct +{ + T_GFPS_KBP_WRITE_RESULT result; + uint8_t pk_field_exist; + uint8_t account_key_idx; + + uint8_t provider_init_bond: 1; + uint8_t notify_existing_name: 1; + uint8_t retroactively_account_key: 1; + uint8_t seeker_ble_device_support: 1; + uint8_t seeker_ble_audio_support: 1; + uint8_t rfu: 3; + + uint8_t provider_addr[6]; + uint8_t seek_br_edr_addr[6]; + +} T_GFPS_KBP_WRITE_MSG_DATA; + +typedef struct +{ + T_GFPS_KBP_WRITE_RESULT result; + uint8_t pk_field_exist; + uint8_t account_key_idx; + + uint8_t device_action: 1; + uint8_t additional_data: 1; + //true:it will be followed by Additional Data characteristic (#AdditionalData), 0 otherwise + uint8_t rfu: 6; + + uint8_t message_group; + uint8_t message_code; + uint8_t additional_data_length; + uint8_t add_data[6];//array to store Additional data + uint8_t data_id; + + uint8_t provider_addr[6]; +} T_GFPS_ACTION_REQ_MSG_DATA; + +typedef enum +{ + GFPS_NOTIFICATION_ENABLE_KBP = 1, + GFPS_NOTIFICATION_DISABLE_KBP = 2, + GFPS_NOTIFICATION_ENABLE_PASSKEY = 3, + GFPS_NOTIFICATION_DISABLE_PASSKEY = 4, + GFPS_NOTIFICATION_ENABLE_ADDITIONAL_DATA = 5, + GFPS_NOTIFICATION_DISABLE_ADDITIONAL_DATA = 6 +} T_GFPS_NOTIFICATION_TYPE; + +typedef struct +{ + uint8_t data_id; + uint8_t data_len; + uint8_t *p_data; +} T_GFPS_ADDITIONAL_DATA; + +typedef union +{ + T_GFPS_NOTIFICATION_TYPE notify_type; + uint32_t passkey; + T_GFPS_KBP_WRITE_MSG_DATA kbp; + T_GFPS_ACTION_REQ_MSG_DATA action_req; + uint8_t account_key[16]; + T_GFPS_ADDITIONAL_DATA additional_data; +} T_GFPS_UPSTREAM_MSG_DATA; + +typedef enum +{ + GFPS_CALLBACK_TYPE_UNKNOWN = 0, + GFPS_CALLBACK_TYPE_NOTIFICATION_ENABLE = 1, + GFPS_CALLBACK_TYPE_KBP_WRITE_REQ = 2, + GFPS_CALLBACK_TYPE_ACTION_REQ = 3, + GFPS_CALLBACK_TYPE_PASSKEY = 4, + GFPS_CALLBACK_TYPE_ACCOUNT_KEY = 5, +#if GFPS_ADDTIONAL_DATA_SUPPORT + GFPS_CALLBACK_TYPE_ADDITIONAL_DATA = 6, +#endif +} T_GFPS_CALLBACK_TYPE; + +typedef struct +{ + uint8_t conn_id; + + T_GFPS_CALLBACK_TYPE msg_type; + T_GFPS_UPSTREAM_MSG_DATA msg_data; +} T_GFPS_CALLBACK_DATA; + +typedef enum +{ + DISCOVERABLE_MODE_WITH_MODEL_ID, + NOT_DISCOVERABLE_MODE, +} T_GFPS_ADV_MODE; + +/** + * @brief Maintain a mapping table to map Seeker's public address to account key + */ +typedef struct +{ + uint8_t key[GFPS_ACCOUNT_KEY_LENGTH];//account key + uint8_t addr[GFPS_BD_ADDR_LENGTH];//seeker's public address +} T_GFPS_ACCOUNT_INFO; + +/** + * @brief account key table + * uint8_t num; the number of key that has stored in account key table + * uint8_t del; Indicates the index of element that needs to be deleted when a new key needs to be added while the table is full. + * uint8_t gap[2];reserved + */ +typedef struct +{ + uint8_t num; + uint8_t del; + uint16_t owner_key_valid : 1; + uint16_t gap_reserved : 15; + T_GFPS_ACCOUNT_INFO account_info[1]; +} T_ACCOUNT_KEY; + +typedef enum +{ + GFPS_PAIRING_STATUS_IDLE = 0x00,//idle state + GFPS_PAIRING_STATUS_INITIAL = 0x01,//initial pairing is ongoing + GFPS_PAIRING_STATUS_SUBSEQUENT = 0x02,//subsequent pairing is ongoing +} T_GFPS_PAIRING_STATUS; + +/** + * @brief + * GFPS_LE_DEVICE_MODE_DUAL_MODE_WITHOUT_CSIP: indicate a dual_mode device without le audio, such as classic BT headphones... + * GFPS_LE_DEVICE_MODE_DUAL_MODE_WITH_CSIP: indicate a dual_mode device with le audio, such as headphones both support classic BT and le audio... + * GFPS_LE_DEVICE_MODE_LE_MODE_WITHOUT_CSIP: indicate a le device without le audio, such as mouse, keyboard... + * GFPS_LE_DEVICE_MODE_LE_MODE_WITH_CSIP: indicate a le device with le audio, such as le audio headphones... + * + */ +typedef enum +{ + GFPS_LE_DEVICE_MODE_DUAL_MODE_WITHOUT_CSIP = 0x00, + GFPS_LE_DEVICE_MODE_DUAL_MODE_WITH_CSIP = 0x01, + GFPS_LE_DEVICE_MODE_LE_MODE_WITHOUT_CSIP = 0x02, + GFPS_LE_DEVICE_MODE_LE_MODE_WITH_CSIP = 0x03, +} T_GFPS_LE_DEVICE_MODE; + +/** + * @brief + * GFPS_PSM_STATE_NOT_READY: + * FP will read PSM characteristic for several times until the state is 0x01 or hit the retry count. + * GFPS_PSM_STATE_READY: + * FP will create LE L2cap connection + * GFPS_PSM_STATE_NOT_AVAILABLE: + * means Not Available This Time. Then when FP read the state, it will immediately drop this request, + * and try to find other component to establish L2CAP connection. + */ +typedef enum +{ + GFPS_PSM_STATE_NOT_READY = 0x00, + GFPS_PSM_STATE_READY = 0x01, + GFPS_PSM_STATE_NOT_AVAILABLE = 0x02, + +} T_GFPS_PSM_STATE; + +/** End of GFPS_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GFPS_Exported_Functions Ble Adv Functions + * @{ + */ + +/** + * @brief gfps_account_key_init + * + * @param[in] p_account_key_table point to account key table which malloced by APP. + * @param[in] max_key_num The maximum of keys allowed to be stroed in accout key table. + */ +void gfps_account_key_init(T_ACCOUNT_KEY *p_account_key_table, uint8_t max_key_num); + +/** + * @brief Fast pair service initialize, this fuction shall be invoke before using fast pair. + * The mode id, anti spoofing public / private key aquire from mode registation. + * @param[in] model_id Mode ID. + * @param[in] anti_spoofing_private Anti spoofing private key. + * @retval true Initialize success. + * @retval false Initialize fail. + */ +bool gfps_init(uint8_t model_id[3], uint8_t anti_spoofing_private[32]); + +/** + * @brief Add fast pair service, this fuction shall be invoke before using fast pair. + * @param[in] p_func Callback when service attribute was read, write or cccd update.. + * @return Service id generated by the BLE stack. + * @retval 0xFF Operation failure. + */ +T_SERVER_ID gfps_add_service(void *p_func); + +/** + * @brief Set the TX power used in advertising data. + * NOTE: This function can be called before @ref gfps_gen_adv_data is invoked. + * + * @param[in] tx_power_exist + * @param[in] adv_tx_power Adverting TX power. + * @retval void + */ +void gfps_set_tx_power(bool tx_power_exist, int8_t adv_tx_power); + +/** + * @brief Set battery notification information in not discoverable advertising data. + * NOTE: This function can be called before @ref gfps_gen_adv_data is invoked. + * + * @param[in] p_battery_info Point to the battery notification + * @retval true Success. + * @retval false Fail. + */ +bool gfps_set_battery_info(T_GFPS_BATTERY_INFO *p_battery_info); + +/** + * @brief Generate session/message nonce + * @param[out] nonce. + * @retval void + */ +void gfps_gen_random_nonce(uint8_t *nonce); +/** + * @brief Generate fast pair advertising data, using to trigger android device find audio device. + * @param[in] mode Adverting mode @ref T_GFPS_ADV_MODE. + * @param[out] p_adv + * @param[out] p_adv_len + * @param[in] show_ui + * @retval true Get advertising data success. + * @retval false Get advertising data fail. + */ +bool gfps_gen_adv_data(T_GFPS_ADV_MODE mode, uint8_t *p_adv, uint8_t *p_adv_len, bool show_ui); + +/** + * @brief Send passkey to android device during pairing procedure. + * @param[in] conn_id BLE link connection id. + * @param[in] service_id Fast pair service id return by gfps_add_service function. + * @param[in] passkey Passkey display on provide device. + * @retval true Send passkey success. + * @retval false Start advertising fail. + */ +bool gfps_send_passkey(uint8_t conn_id, T_SERVER_ID service_id, uint32_t passkey); + +#if GFPS_PERSONALIZED_NAME_SUPPORT +/** + * @brief send personalized name when seeker set notify_existing_name flags to 1 + * @param[in] personalized_name the pointer of personalized name + * @param[in] personalized_name_len the length of personalized name + * @param[in] conn_id + * @param[in] service_id + * @retval true send personalized name success. + * @retval false send personalized name fail. + */ +bool gfps_send_personalized_name(uint8_t *personalized_name, uint8_t personalized_name_len, + uint8_t conn_id, uint8_t service_id); +#endif + +/** + * @brief do write request confirm for attr_index GFPS_CHAR_KEY_BASE_PAIRING_INDEX + * and call gfps_handle_char_kbp() again when ecdh_shared_secret_enhanced() run completed + * + * @return T_APP_RESULT + */ +T_APP_RESULT gfps_handle_pending_char_kbp(void); + +/** + * @brief get current subsequent pairing account key. + * This function only can be used when gfps ble link state is connected, +* if gfps ble link state is disconnected(for example:gfps_conn_id ==0xFF) + * this account key maybe a invalid value. + * @param[out] key current subsequent pairing account key. + * @return true success get current subsequent pairing account key. + * @return false not in subsequent pairing mode or have an invalid account key. + */ +bool gfps_get_subsequent_pairing_account_key(uint8_t *key); + +/** + * @brief shall discard aes key and pairing status if this LE link disconnects + */ +void gfps_reset_aeskey_and_pairing_status(void); +/** + * @brief set inuse account key index + * @param[in] inuse account key index + */ +void gfps_set_inuse_account_key_index(uint8_t index); +/** + * @brief set most recently inuse account key index + * @param[in] most recently inuse account key index + */ + +void gfps_set_most_recently_inuse_account_key_index(uint8_t index); +/** + * @brief Get inuse account key index + * @retval inuse account key index + */ +uint8_t gfps_get_inuse_account_key_index(void); +/** + * @brief Get inuse account key index + * @retval inuse account key index + */ +uint8_t gfps_get_recently_inuse_account_key_index(void); +/** + * @brief Get inuse account key index + * @retval successfully get account_key + */ +bool gfps_sass_get_account_key_by_index(uint8_t *key, uint8_t key_index); +/** + * @brief get the highest priority device in account key table. + * @param[out] p_idx if account key table is empty then *p_idx = 0xFF. + * @retval false get fail + * @retval true get success + */ +bool gfps_get_highest_priority_device(uint8_t *p_idx); + +/** + * @brief enable or disable finder in gfps_lib + * + * @param enable true:enable, false:disable + */ +void gfps_set_finder_enable(bool enable); + +/** + * @brief get owner key valid or not + * + * @return true owner key valid + * @return false owner key invalid + */ +bool gfps_get_owner_key_valid(void); + +/** + * @brief set owner key valid or not + * + * @param valid true:owner key valid false:owner key invalid + */ +void gfps_set_owner_key_valid(bool valid); + +/** + * @brief malloc memory for ecc + * + */ +void gfps_ecc_manager_malloc(void); + +/** + * @brief free memory for ecc + * + */ +void gfps_ecc_manager_free(void); + +/** + * @brief gfps le device init + * @param le_device_support 1:support, 0: not support + * @param le_device_mode @ref T_GFPS_LE_DEVICE_MODE + */ +void gfps_le_device_init(uint8_t le_device_support, uint8_t le_device_mode); + +/** + * @brief gfps_le_get_device_mode + * + * @return T_GFPS_LE_DEVICE_MODE + */ +T_GFPS_LE_DEVICE_MODE gfps_le_get_device_mode(void); + +/** + * @brief gfps_set_identity_address + * if b2b_connected is true, p_pri_addr and p_sec_addr shall not be NULL. + * if b2b_connected is false, p_pri_addr shall not be NULL, p_sec_addr can be NULL. + * @param p_pri_addr primary bud identity address. + * @param p_sec_addr secondary bud indentity address. + * @param b2b_connected if true b2b connected, if false b2b disconnected. + */ +void gfps_set_identity_address(uint8_t *p_pri_addr, uint8_t *p_sec_addr, bool b2b_connected); + +/** + * @brief get gfps pairing status + * + * when ble link disconnected, gfps pairing status will be set to GFPS_PAIRING_STATUS_IDLE + * @return T_GFPS_PAIRING_STATUS @ref T_GFPS_PAIRING_STATUS + */ +T_GFPS_PAIRING_STATUS gfps_get_pairing_status(void); + +/** + * @brief set gfps pairing status + * + * @param pairing_status @ref T_GFPS_PAIRING_STATUS + */ +void gfps_set_pairing_status(T_GFPS_PAIRING_STATUS pairing_status); + +/** @} */ /* End of group GFPS_Exported_Functions */ +/** End of APP_GFPS +* @} +*/ + +/** @} End of GFPS */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/app/findmy/gfps/gfps_lib/gfps.lib b/src/app/findmy/gfps/gfps_lib/gfps.lib new file mode 100644 index 0000000..63ec712 Binary files /dev/null and b/src/app/findmy/gfps/gfps_lib/gfps.lib differ diff --git a/src/app/findmy/gfps/gfps_lib/gfps_find_my_device.h b/src/app/findmy/gfps/gfps_lib/gfps_find_my_device.h new file mode 100644 index 0000000..fd15da5 --- /dev/null +++ b/src/app/findmy/gfps/gfps_lib/gfps_find_my_device.h @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ +#ifndef _GFPS_FIND_MY_DEVICE_H_ +#define _GFPS_FIND_MY_DEVICE_H_ + +#include "stdbool.h" +#include "stdlib.h" +#include "stdint.h" +#include "gfps.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*One byte indicating the protocols major version number. Currently it is 0x01.*/ +#define GFPS_FINDER_SPEC_VERSION 0x01 + +#define GFPS_FINDER_SECP160R1 0x00 +#define GFPS_FINDER_SECP256R1 0x01 + +/** + * @brief + * 00: battery level indication unsupported + * 01: normal battery level + * 10: low battery level + * 11: critically low battery level (battery replacement needed soon) + * + */ +#define GFPS_FINDER_BATTERY_UNSUPPORT 0x00 +#define GFPS_FINDER_BATTERY_NORMAL 0x01 +#define GFPS_FINDER_BATTERY_LOW 0x02 +#define GFPS_FINDER_BATTERY_CRITICALLY_LOW 0x03 +typedef struct +{ + uint8_t utp_mode: 1; + uint8_t battery_level: 2; + uint8_t rsv: 5; +} T_GFPS_FINDER_HASH_FLAG; + +/** + * @brief GFPS Finder GATT Error Codes + * GFPS_FINDER_CAUSE_SUCCESS success + * GFPS_FINDER_CAUSE_UNAUTHEN authen fail + * GFPS_FINDER_CAUSE_INVALID_VALUE value fail + * GFPS_FINDER_CAUSE_NO_USER_CONSENT not in pairing mode + */ +typedef enum +{ + GFPS_FINDER_CAUSE_SUCCESS = 0x0000, + GFPS_FINDER_CAUSE_UNAUTHEN = 0x0480, + GFPS_FINDER_CAUSE_INVALID_VALUE = 0x0481, + GFPS_FINDER_CAUSE_NO_USER_CONSENT = 0x0482, +} T_GFPS_FINDER_CAUSE; + +/** + * @brief GFPS Finder EIK struct + * valid true means this EIK is valid. + * key 32 bytes EIK + */ +typedef struct +{ + bool valid; + uint8_t rsv[3]; + uint8_t key[32]; +} T_GFPS_EIK; + +typedef enum +{ + GFPS_FINDER_EVT_SET_EIK = 0x00, + GFPS_FINDER_EVT_CLEAR_EIK = 0x01, + GFPS_FINDER_EVT_KEY_RECOVERY = 0x02, + GFPS_FINDER_EVT_RING = 0x03, + GFPS_FINDER_EVT_RING_STATE = 0x04, + GFPS_FINDER_EVT_UTP_ACTIVE = 0x05, + GFPS_FINDER_EVT_UTP_DEACTIVE = 0x06, + GFPS_FINDER_EVT_SET_OWNERKEY_VALID = 0x07, + GFPS_FINDER_EVT_READ_BEACON_PARAM = 0x08, +} T_GFPS_FINDER_CB_EVENT; + +/** + * @brief A byte indicating the number of components capable of ringing: + * 0x00: indicates that the device is incapable of ringing. + * 0x01: indicates that only a single component is capable of ringing. + * 0x02: indicates that two components, left and right buds, are capable of ringing individually. + * 0x03: indicates that three components, left and right buds and the case, are capable of ringing individually + */ +typedef enum +{ + GFPS_FINDER_RING_NOT_SUPPORT = 0x00, + GFPS_FINDER_RING_SINGLE = 0x01, + GFPS_FINDER_RING_RWS = 0x02, +} T_GFPS_FINDER_RING_CAP; + +typedef enum +{ + GFPS_FINDER_RING_VOLUME_DISABLE, + GFPS_FINDER_RING_VOLUME_ENABLE, +} T_GFPS_FINDER_RING_VOLUME_STATE; + +typedef enum +{ + GFPS_FINDER_RING_VOLUME_DEFAULT, + GFPS_FINDER_RING_VOLUME_LOW, + GFPS_FINDER_RING_VOLUME_MEDIUM, + GFPS_FINDER_RING_VOLUME_HIGH, +} T_GFPS_FINDER_RING_VOLUME_LEVEL; + +typedef struct +{ + uint8_t conn_id; + uint8_t service_id; + uint8_t ring_type; + uint16_t ring_time; + uint8_t ring_volume_level; +} T_GFPS_FINDER_RING; + +/** + * @brief A byte indicating the new ringing state: + * 0x00: started + * 0x01: failed to start or stop (all requested components are out of range) + * 0x02: stopped (timeout) + * 0x03: stopped (button press) + * 0x04: stopped (GATT request) + * + */ +typedef enum +{ + GFPS_FINDER_RING_STARTED = 0x00, + GFPS_FINDER_RING_FAIL = 0x01, + GFPS_FINDER_RING_TIMEOUT_STOP = 0x02, + GFPS_FINDER_RING_BUTTON_STOP = 0x03, + GFPS_FINDER_RING_GATT_STOP = 0x04, +} T_GFPS_FINDER_RING_STATE; + +typedef union +{ + T_GFPS_EIK eik; + T_GFPS_FINDER_RING ring; +} T_GFPS_FINDER_CB_MSG; + +typedef struct +{ + T_GFPS_FINDER_CB_EVENT evt; + T_GFPS_FINDER_CB_MSG msg_data; +} T_GFPS_FINDER_CB_DATA; + +typedef T_GFPS_FINDER_CAUSE(*P_FUN_GFPS_FINDER_CB)(T_GFPS_FINDER_CB_DATA *p_data); + +typedef struct +{ + T_GFPS_EIK eik; + uint32_t clock_value; + uint8_t random_nonce[8]; + uint8_t adv_ei[32];//secp160r1 ei is 20 bytes, secp256r1 ei is 32 bytes + uint8_t beacon_data[32]; + uint8_t ring_components_num; + uint8_t ring_volume_modify; + uint8_t secp_mode; + bool skip_ring_authen; + T_GFPS_FINDER_HASH_FLAG hash_flag; + T_GFPS_EIK temp_modified_eik; + bool factory_reset_pending; + bool random_nonce_valid; +} T_GFPS_FINDER; + +/** + * @brief gfps_finder_init + * + * @param p_finder @ref T_GFPS_FINDER + * @param p_fun_cb @ref P_FUN_GFPS_FINDER_CB + * @return true init success + * @return false init fail + */ +bool gfps_finder_init(T_GFPS_FINDER *p_finder, P_FUN_GFPS_FINDER_CB p_fun_cb); + +/** + * @brief gfps_finder_handle_beacon_action + * Fast Pair Service characteristic Beacon Actions. + * The operations required by this extension are performed as a write operation. + * @param conn_id + * @param service_id + * @param length + * @param p_value + * @return T_GFPS_FINDER_CAUSE + */ +T_GFPS_FINDER_CAUSE gfps_finder_handle_beacon_action(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t length, uint8_t *p_value); + +/** + * @brief gfps_finder_rsp_ring_request + * + * @param conn_id + * @param service_id + * @param ring_state @ref T_GFPS_FINDER_RING_STATE + * @param ring_type + * Bit 1 (0x01): ring right + * Bit 2 (0x02): ring left + * Bit 3 (0x04): ring case + * @param timeout + * Two bytes indicating the remaining time for ringing in deciseconds. + * Note that if the device has stopped ringing, 0x0000 should be returned + * @return true + * @return false + */ +bool gfps_finder_rsp_ring_request(uint8_t conn_id, uint8_t service_id, uint8_t ring_state, + uint8_t ring_type, uint16_t timeout); + +/** + * @brief gfps_finder_rsp_ring_state + * + * @param conn_id + * @param service_id + * @param ring_type + * Bit 1 (0x01): ring right + * Bit 2 (0x02): ring left + * Bit 3 (0x04): ring case + * @param timeout + * Two bytes indicating the remaining time for ringing in deciseconds. + * Note that if the device has stopped ringing, 0x0000 should be returned + * @return true + * @return false + */ +bool gfps_finder_rsp_ring_state(uint8_t conn_id, uint8_t service_id, + uint8_t ring_type, uint8_t timeout); + +/** + * @brief gfps_finder_encrypted_beacon_data + * A random r is generated by AES-ECB-256 encrypting the beacon data with the identity key + * @param p_eik + * @param p_input beacon_data + * @param p_output r + * @return true + * @return false + */ +bool gfps_finder_encrypted_beacon_data(uint8_t *p_eik, uint8_t *p_input, uint8_t *p_output); + +/** + * @brief defined as SHA256(Ephemeral Identity Key || 0x01), truncated to the first 8 bytes. || means string concatenation. + * + * @param[out] p_recovery_key point to the recovery key, the length of recovery key is GFPS_FINDER_RECOVERY_KEY_LENGTH + * @return true + * @return false + */ +bool gfps_finder_get_recovery_key(uint8_t *p_recovery_key); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/app/findmy/gfps/gfps_lib/gfps_int.h b/src/app/findmy/gfps/gfps_lib/gfps_int.h new file mode 100644 index 0000000..3d9ce66 --- /dev/null +++ b/src/app/findmy/gfps/gfps_lib/gfps_int.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018, Realsil Semiconductor Corporation. All rights reserved. + */ + + +#ifndef _GFPS_INT_ +#define _GFPS_INT_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "gfps.h" +#include "aes_api.h" +#define GFPS_BATTERY_RAMAIN_TIME_SUPPORT (GFPS_FEATURE_SUPPORT && 0) + +typedef struct +{ + uint8_t anti_spoofing_private[32]; + uint8_t aes_key[16]; + uint8_t public_addr[6]; + T_GFPS_ADV_MODE gfps_adv_mode;// ref @T_GFPS_ADV_MODE + int8_t adv_tx_power; + bool tx_power_exist; + + bool battery_level_exist; + uint8_t battery_len_type; + uint8_t battery_left; + uint8_t battery_right; + uint8_t battery_case; +#if GFPS_BATTERY_RAMAIN_TIME_SUPPORT + //battery remain time + bool battery_remain_time_exist; + uint8_t battery_remain_time_len_type; + uint16_t battery_remain_time; +#endif + //addtional data, data_id + uint8_t data_id; + uint8_t gfps_pairing_status;//ref @T_GFPS_PAIRING_STATUS + uint8_t inuse_account_key_idx; + uint8_t recently_inuse_account_key_idx; + + bool gfps_finder_support; + bool gfps_is_locator_tag; + + uint8_t le_device_support; + uint8_t le_device_mode; + uint8_t identity_addr_num; + uint8_t gfps_pri_addr[6]; + uint8_t gfps_sec_addr[6]; +} T_GFPS_MGR; + +extern T_GFPS_MGR *gfps; + +uint8_t gfps_gen_battery_info(uint8_t *p_info); + +bool gfps_encode_additional_packet(uint8_t *input_nonce, uint8_t *aes_key, + uint8_t *input_raw_data, uint8_t input_data_len, + uint8_t data_id, uint8_t *data_packet, uint8_t *packet_len); + +bool gfps_decode_additional_packet(uint16_t length, uint8_t *p_value, + uint8_t *p_descrypted_data, uint8_t *p_data_len); + +//gfps_crypto.c +uint8_t gfps_gen_account_key_filter(T_GFPS_ACCOUNT_INFO *account_info, uint8_t num, uint16_t salt, + uint8_t *p_battery_info, uint8_t battery_len, uint8_t *sass, uint8_t sass_len, + uint8_t *filter); + +void gfps_swap_endian(uint8_t *dst, uint8_t *src, uint32_t len); + +#if !GFPS_LOCATOR_TAG +T_APP_RESULT gfps_gen_ecdh_key(uint8_t *public_key, uint8_t *private_key, uint8_t *ecdh_key); + +/** + * @brief Generate AES key in discoverable mode and print via MSB. +*/ +//Test function: bool gfps_test_ecdh_key(void) +#else +extern T_APP_RESULT app_gfps_gen_ecdh_key(uint8_t *public_key, uint8_t *private_key, uint8_t *aes_key); +#endif + +T_APP_RESULT gfps_gen_aes_key(uint8_t *public_key, uint8_t *private_key, uint8_t *aes_key); + +void gfps_ase_ctr_concat(uint8_t *input_data, uint8_t *input_nonce, uint8_t *input_key, + uint8_t input_data_len, uint8_t *output_data); + +bool gfps_hmac_sha256(uint8_t *p_encrypted_data, uint8_t data_len, + uint8_t p_out[8], uint8_t *p_key, uint8_t key_len); + +void gfps_ctr_concat(uint8_t *input_data, uint8_t iv[16], uint8_t *input_key, + uint8_t input_data_len, uint8_t *output_data); + +/** + * @brief get all account key in account key table + * + * @param[out] key_num key number in account key table. + * @return T_GFPS_ACCOUNT_INFO* point to the account key table, this account key table is malloced by app. + */ +T_GFPS_ACCOUNT_INFO *gfps_get_account_key_info(uint8_t *key_num); + +bool gfps_sass_get_inuse_accountkey(uint8_t *in_use_accountkey, uint8_t *in_use_pattern); +/** + * @brief get account key table used for filter. + * Before computing the account key filter, + * the Provider shall modify the first byte of the account keys to include in use pattern. + * @ref T_SASS_ACCOUNT_KEY_IN_USE_PATTERNS + * + * @return T_GFPS_ACCOUNT_INFO* point to account key table used for filter. + */ +T_GFPS_ACCOUNT_INFO *gfps_sass_malloc_key_for_filter(void); + +/** + * @brief get the highest priority device in account key table. + * @param[out] p_idx if account key table is empty then *p_idx = 0xFF. + * @retval false get fail + * @retval true get success + */ +bool gfps_get_highest_priority_device(uint8_t *p_idx); + +//finder +bool gfps_finder_set_random_nonce(uint8_t *p_random_nonce); +bool gfps_finder_get_random_nonce(uint8_t *p_random_nonce); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/app/findmy/gfps/gfps_lib/platform_secp160r1.h b/src/app/findmy/gfps/gfps_lib/platform_secp160r1.h new file mode 100644 index 0000000..f94fdbf --- /dev/null +++ b/src/app/findmy/gfps/gfps_lib/platform_secp160r1.h @@ -0,0 +1,65 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file platform_uecc.h + * @brief micro_ecc Platform abstraction layer + * @author + * @date 2023-4-27 + * @version v1.0 + * ************************************************************************************* + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +#ifndef _PLATFORM_SECP160R1_H_ +#define _PLATFORM_SECP160R1_H_ + +/** @defgroup HAL_UECC_API uecc api + * @brief This file introduces the uecc APIs + * @{ + */ + +/** @defgroup HAL_uecc_Exported_Functions uecc Exported Functions + * @brief + * @{ + */ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum +{ + SECP160R1 = 0, + SECP256R1, + SECP256K1,/*to do*/ + UECC_ALGORITHE_NUM +} T_UECC_ALGORITHM_TYPE; + +/** + * @brief calculate pulic key on the base of aes_key + * \xrefitem Added_API_2_12_0_0 "Added Since 2.12.0.0" "Added API" + * @param aes_key: the point of input of private key to calculate + * @param public_key: the pulic key calculated based on aes key + * @param r : the result of pubic key mod k of curve parameter + * @param uecc_type : curve type selected to calculate public key + * @return void + */ +int platform_uecc_compute_public_key(uint8_t *aes_key, uint8_t *public_key, uint8_t *r, + T_UECC_ALGORITHM_TYPE uecc_type); + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ /* End of group HAL_Log_Control_Exported_Functions */ +/** @} */ /* End of group HAL_LOG_API */ +#endif /* _PLATFORM_UECC_H_ */ diff --git a/src/app/findmy/key_crypto.h b/src/app/findmy/key_crypto.h new file mode 100644 index 0000000..e0584d0 --- /dev/null +++ b/src/app/findmy/key_crypto.h @@ -0,0 +1,46 @@ +/** +***************************************************************************************** +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file fmna_task.h + * @brief Routines to create FMNA task and handle events & messages + * @author scarlett_liang + * @date 2022-10-24 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2022 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ +#ifndef _FMNA_TASK_H_ +#define _FMNA_TASK_H_ + +#include "stdbool.h" +#include "stdint.h" + +extern void *fmna_task_handle; +extern void *fmna_sem; +extern bool is_key_rotated; + +extern void driver_init(void); + +/** + * @brief Initialize FMNA task + * @return void + */ +void fmna_task_init(void); + +/** + * @brief Initialize TIM peripheral. + * @param No parameter. + * @return void +*/ +void hw_timer_driver_init(void); + +void crypto_exit_dlps_config(void); + +void crypto_enter_dlps_config(void); + +void fmna_rotate_key_internal(void); +#endif + diff --git a/src/app/findmy/main.c b/src/app/findmy/main.c new file mode 100644 index 0000000..ff5ec0f --- /dev/null +++ b/src/app/findmy/main.c @@ -0,0 +1,287 @@ +/** +***************************************************************************************** +* Copyright(c) 2022, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file main.c + * @brief Source file for findmy project, mainly used for initialize modules + * @author scarlett_liang + * @date 2022-09-01 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2022 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if DLPS_EN +#include +#include +#endif +#include "rtl876x_pinmux.h" +#include "key_handle.h" +#include "key_crypto.h" +#include "fmna_sound_platform.h" +#include "fmna_battery_platform.h" +#include "fmna_motion_detection_platform.h" +#include "fmna_version.h" +#include "fmna_timer_platform.h" +#include "fmna_crypto.h" +#include "fmna_motion_detection.h" +#include "fmna_connection.h" +#include "fmna_gatt_platform.h" +#include "fmna_adv_platform.h" +#include "fmna_gap_platform.h" +#include "findmy_app.h" + +#include "serial_number_send.h" + +#if SUPPORT_NFC +#include "fmna_nfc_platform.h" +#include "fmna_nfc.h" +#endif +#ifdef USE_UARP +#include "fmna_uarp_control_point.h" +#endif +#if GFPS_FEATURE_SUPPORT +#include "app_gfps.h" +#include "app_gfps_finder.h" +#endif + +/** @defgroup FINDMY_DEMO Main + * @brief Main file to initialize hardware and BT stack and start task scheduling + * @{ + */ +/*============================================================================* + * Functions + *============================================================================*/ + +/** + * @brief Contains the initialization of pinmux settings and pad settings + * @note All the pinmux settings and pad settings shall be initiated in this function, + * but if legacy driver is used, the initialization of pinmux setting and pad setting + * should be peformed with the IO initializing. + * @return void + */ +void board_init(void) +{ + gpio_board_init(); +#if SUPPORT_LITHIUM_BAT_DETECT_FEATURE + bat_init_board(); +#endif +#if USE_DA213B_SENSOR + board_i2c_master_init(); +#endif +#if SUPPORT_NFC + nfc_board_init(); +#endif +} + +/** + * @brief Contains the initialization of peripherals + * @note Both new architecture driver and legacy driver initialization method can be used + * @return void + */ +void driver_init(void) +{ + gpio_driver_init(); +#if SUPPORT_BAT_DETECT_FEATURE + bat_init_driver(); +#endif + hw_timer_driver_init(); +#if SUPPORT_NFC + fmna_nfc_init(); +#endif +} + +#if DLPS_EN +/** + * @brief Contains the power mode settings + * @return void + */ +void io_dlps_enter_cb(void) +{ +// DBG_DIRECT("ENTER DLPS"); + gpio_key_enter_dlps_config(); + +#if USE_DA213B_SENSOR + board_i2c_master_deinit(); +#endif + +#if SUPPORT_NFC + nfc_board_deinit(); +#endif + +#if SUPPORT_BAT_DETECT_FEATURE + bat_enter_dlps_config(); +#endif +} + +void io_dlps_exit_cb(void) +{ +// DBG_DIRECT("EXIT DLPS"); + crypto_exit_dlps_config(); + + gpio_key_exit_dlps_config(); + +#if SUPPORT_BAT_DETECT_FEATURE + bat_exit_dlps_config(); +#endif + +#if USE_DA213B_SENSOR + board_i2c_master_init(); +#endif + +#if SUPPORT_NFC + nfc_board_init(); +#endif +} + +bool app_dlps_check_cb(void) +{ + return ( + 1 +#if USE_PAM8904_BUZZER || USE_ACTIVE_BUZZER + && + (!sound_en) +#endif + ); +} +#endif + +void pwr_mgr_init(void) +{ +#if DLPS_EN + if (false == dlps_check_cb_reg(app_dlps_check_cb)) + { + APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!"); + } + DLPS_IORegUserDlpsEnterCb(io_dlps_enter_cb); + DLPS_IORegUserDlpsExitCb(io_dlps_exit_cb); + DLPS_IORegister(); + lps_mode_set(PLATFORM_DLPS_PFM); +#endif +} + +/** + * @brief Contains the initialization of all tasks + * @note There is only one task in BLE Peripheral APP, thus only one APP task is init here + * @return void + */ +void task_init(void) +{ + app_task_init(); + fmna_task_init(); +} + +/** + * @brief Entry of APP code + * @return int (To avoid compile warning) + */ +int main(void) +{ + extern uint32_t random_seed_value; + srand(random_seed_value); + +#if FEAUTRE_SUPPORT_FLASH_2_BIT_MODE + if (FLASH_SUCCESS == flash_try_high_speed(FLASH_MODE_2BIT)) + { + APP_PRINT_INFO0("Switch to 2-Bit flash mode"); + } +#endif + + app_global_data_init(); + app_global_data.reset_reason = reset_reason_get(); + APP_PRINT_INFO1("reset_reason = %#x", app_global_data.reset_reason); + + fmna_connection_pair_info_restore(); + board_init(); +#if SUPPORT_BAT_DETECT_FEATURE + bat_init_data(); +#endif +#if ONE_SHOT_ADV_EN + one_shot_adv_init(); +#endif + fmna_version_init(); + app_bond_info_restore(); + fmna_connection_init(); + fmna_ble_platform_init(); + fmna_gatt_platform_init(); + fmna_sound_platform_init(); + fmna_motion_detection_init(); + + custom_new_adv_init(); + + +#ifdef USE_UARP + fmna_uarp_control_point_init(); +#endif +#if GFPS_FEATURE_SUPPORT + app_gfps_init(); +#endif + pwr_mgr_init(); + sw_timer_init(); + task_init(); + os_sched_start(); + + return 0; +} + +/** + * @brief System interrupt handler function, for wakeup pin. + * @param No parameter. + * @return void +*/ +void System_Handler(void) +{ + APP_PRINT_INFO0("[System_Handler] system on interrupt"); + NVIC_DisableIRQ(System_IRQn); + + if (System_WakeUpInterruptValue(TRIGGER_BUTTON) == SET) + { + Pad_ClearWakeupINTPendingBit(TRIGGER_BUTTON); + os_timer_start(&gpio_key_debounce_timer); + } + +#if SUPPORT_CUSTOMIZED_APP + if (System_WakeUpInterruptValue(CUST_ADV_PIN) == SET) + { + Pad_ClearWakeupINTPendingBit(CUST_ADV_PIN); + os_timer_start(&gpio_key_debounce_timer); + } +#endif + NVIC_ClearPendingIRQ(System_IRQn); +} + +/** + * @brief Config bt stack related feature + * @return void + */ +#ifdef BT_STACK_CONFIG_ENABLE +#include "app_section.h" +#include "gap_config.h" +extern void gap_config_local_addr_storage(bool enable); + +APP_FLASH_TEXT_SECTION void bt_stack_config_init(void) +{ +#if SUPPORT_CUSTOMIZED_APP + gap_config_max_le_paired_device(BLE_BOND_NUM); +#endif + gap_config_local_addr_storage(true); +} +#endif +/** @} */ /* End of group FINDMY_DEMO_MAIN */ + diff --git a/src/app/findmy/reset_watch_dog_timer.c b/src/app/findmy/reset_watch_dog_timer.c new file mode 100644 index 0000000..78899f3 --- /dev/null +++ b/src/app/findmy/reset_watch_dog_timer.c @@ -0,0 +1,108 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file reset_watch_dog_timer.c +* @brief This is the entry of user code which the watch dog module resides in. +* @details +* @author +* @date 2020-03-10 +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "rtl876x_tim.h" +#include "rtl876x_rcc.h" +#include "rtl876x_nvic.h" +#include "app_msg.h" +#include "app_task.h" +#include "trace.h" +#include + +/*============================================================================* + * Macros + *============================================================================*/ +#define TIMER_NUM TIM3 +#define TIMER_IRQN Timer3_IRQn +#define WDG_Timer_Handler Timer3_Handler +#define TIMER_PERIOD (2*1000*1000*40-1) //2s for 40M clock + +/*============================================================================* + * Functions Declaration + *============================================================================*/ +static void watch_dog_timer_driver_init(void); + +void WDG_Timer_Handler(void) DATA_RAM_FUNCTION; + +/*============================================================================* + * Local Functions + *============================================================================*/ +/****************************************************************** + * @brief Initialize watch dog timer. + * @param none + * @return none + * @retval void + */ +void watch_dog_timer_driver_init(void) +{ + RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE); + + TIM_TimeBaseInitTypeDef TIM_InitStruct; + TIM_StructInit(&TIM_InitStruct); + + TIM_InitStruct.TIM_PWM_En = PWM_DISABLE; + TIM_InitStruct.TIM_Period = TIMER_PERIOD ; + TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine; + TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct); + + /* Enable TIMER IRQ */ + NVIC_InitTypeDef NVIC_InitStruct; + NVIC_InitStruct.NVIC_IRQChannel = TIMER_IRQN; + NVIC_InitStruct.NVIC_IRQChannelPriority = 3; + NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStruct); + + TIM_ClearINT(TIMER_NUM); + TIM_INTConfig(TIMER_NUM, ENABLE); + TIM_Cmd(TIMER_NUM, ENABLE); +} + +/*============================================================================* + * Global Functions + *============================================================================*/ +/****************************************************************** + * @brief enable watch dog timer. + * @param none + * @return none + * @retval void + */ +void reset_watch_dog_timer_enable(void) +{ + watch_dog_timer_driver_init(); +} + +/****************************************************************** + * @brief watch dog timer handle. + * @param none + * @return none + * @retval void + */ +void WDG_Timer_Handler(void) +{ + TIM_ClearINT(TIMER_NUM); + TIM_Cmd(TIMER_NUM, DISABLE); + //send message to app task in which reset the watch dog timer + T_IO_MSG bee_io_msg = {0}; + bee_io_msg.type = IO_MSG_TYPE_RESET_WDG_TIMER; + if (false == app_send_msg_to_apptask(&bee_io_msg)) + { + APP_PRINT_ERROR0("[WDG] send IO_MSG_TYPE_RESET_WDG_TIMER message failed!"); + } + + TIM_Cmd(TIMER_NUM, ENABLE); +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/app/findmy/serial_number_send.c b/src/app/findmy/serial_number_send.c new file mode 100644 index 0000000..e75bfbd --- /dev/null +++ b/src/app/findmy/serial_number_send.c @@ -0,0 +1,186 @@ +// ͷļ +#include "serial_number_send.h" +#include "findmy_app.h" +#include "gap_le_types.h" +#include "gap.h" +#include "gap_bond_le.h" +#include "gap_config.h" +#include "string.h" +#include "trace.h" +#include "gap_adv.h" +#include "fmna_gatt_platform.h" +#include "fmna_constants_platform.h" +#include "fmna_constants.h" +#include "fmna_util.h" +#include "fmna_adv.h" +#include "fmna_gap_platform.h" +#include "fmna_adv_platform.h" + +// кͷļ +#include "fmna_connection_platform.h" + +// кų +#define SERIAL_NUMBER_LENGTH 16 // ĵ2еʵ֣16ֽ + +// ̬洢к +static uint8_t device_serial_number[SERIAL_NUMBER_LENGTH]; +static bool serial_number_loaded = false; + +// 㲥 - ޸Ϊɸ¸ʽ +static uint8_t custom_new_adv_data[31] = +{ + 0x02, // ȣ2ֽ + GAP_ADTYPE_FLAGS, // ־ + GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // ־ֵ + + 0x0C, // ȣ12ֽ + GAP_ADTYPE_LOCAL_NAME_COMPLETE, // + 'S', 'e', 'r', 'i', 'a', 'l', '_', 'N', 'b', // 豸"Serial_Nb" +}; + +// ɨӦ - к +static uint8_t custom_new_scan_rsp_data[31] = +{ + 0x03, // ȣ3ֽ + GAP_ADTYPE_APPEARANCE, // + LO_WORD(GAP_GATT_APPEARANCE_UNKNOWN), // ֵֽ + HI_WORD(GAP_GATT_APPEARANCE_UNKNOWN), // ֵֽ + + 0x11, // ȣ17ֽ + GAP_ADTYPE_MANUFACTURER_SPECIFIC, // ض + 0x53, 0x44, // ID: 0x4453 (С) + // Ԥ16ֽڿռк (λ: 6-21) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// 㲥ṹ +T_ADV_DATA custom_new_adv; + +/** + * @brief Flashкŵ豸洢 + */ +void load_serial_number_from_flash(void) +{ + if (!serial_number_loaded) + { + // ĵ2еĺȡк + uint8_t ret = fmna_connection_platform_get_serial_number(device_serial_number, SERIAL_NUMBER_LENGTH); + + APP_PRINT_INFO1("Serial number loaded from flash, result=0x%02x", ret); + APP_PRINT_INFO1("Serial number data: %b", TRACE_BINARY(SERIAL_NUMBER_LENGTH, device_serial_number)); + + serial_number_loaded = true; + } +} + +/** + * @brief ¹㲥ек + */ +void update_serial_number_in_adv(void) +{ + // ȷкѼ + load_serial_number_from_flash(); + + // кŸƵɨӦݵض + // λ: custom_new_scan_rsp_data[6] ʼ16ֽ + memcpy(&custom_new_scan_rsp_data[6], device_serial_number, SERIAL_NUMBER_LENGTH); + + // ¹㲥 + fmble_gap_adv_data_set(custom_new_adv, ADV_DATA_CUSTOM_NEW); + + APP_PRINT_INFO0("Serial number updated in advertisement data"); +} + +/** + * @brief кŵ㲥ݣԭнӿڣ + * @param serial_number кָ + * @param len кų + */ +void set_serial_number_to_adv(uint8_t *serial_number, uint8_t len) +{ + uint8_t actual_len = (len > SERIAL_NUMBER_LENGTH) ? SERIAL_NUMBER_LENGTH : len; + + // Ƶ豸洢 + memcpy(device_serial_number, serial_number, actual_len); + + // Ȳ㣬0 + if (actual_len < SERIAL_NUMBER_LENGTH) + { + memset(&device_serial_number[actual_len], 0, SERIAL_NUMBER_LENGTH - actual_len); + } + + serial_number_loaded = true; + + // ¹㲥 + update_serial_number_in_adv(); +} + +/** + * @brief ȡǰк + * @param serial_number + * @param max_len 󳤶 + * @return ʵʸƵij + */ +uint8_t get_serial_number(uint8_t *serial_number, uint8_t max_len) +{ + load_serial_number_from_flash(); + + uint8_t copy_len = (max_len > SERIAL_NUMBER_LENGTH) ? SERIAL_NUMBER_LENGTH : max_len; + memcpy(serial_number, device_serial_number, copy_len); + + return copy_len; +} + +/** + * @brief ʼԶ㲥 + */ +void custom_new_adv_init(void) +{ + // ʼ㲥ṹ + custom_new_adv.p_adv_data = custom_new_adv_data; + custom_new_adv.adv_data_len = sizeof(custom_new_adv_data); + custom_new_adv.p_scan_rsp_data = custom_new_scan_rsp_data; + custom_new_adv.scan_rsp_data_len = sizeof(custom_new_scan_rsp_data); + custom_new_adv.adv_type = GAP_ADTYPE_ADV_IND; + custom_new_adv.adv_interval = 320; // 200ms (320 * 0.625ms) + + // ַ + uint8_t custom_new_bt_addr[GAP_BD_ADDR_LEN]; + le_gen_rand_addr(GAP_RAND_ADDR_RESOLVABLE, custom_new_bt_addr); + one_shot_bt_addr_set(custom_new_bt_addr, GAP_LOCAL_ADDR_LE_RANDOM, ADV_DATA_CUSTOM_NEW); + + // زк + update_serial_number_in_adv(); +} + +/** + * @brief Զ㲥 + */ +void custom_new_adv_start(void) +{ + // ȷкѸ + update_serial_number_in_adv(); + + T_GAP_CAUSE ret = fmble_gap_adv_start(ADV_DATA_CUSTOM_NEW); + if (ret != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR1("[custom_new_adv_start] failed, ret=%d", ret); + } + else + { + APP_PRINT_INFO0("Custom advertisement started with serial number"); + } +} + +/** + * @brief ֹͣԶ㲥 + */ +void custom_new_adv_stop(void) +{ + T_GAP_CAUSE ret = fmble_gap_adv_stop(ADV_DATA_CUSTOM_NEW); + if (ret != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR1("[custom_new_adv_stop] failed, ret=%d", ret); + } +} diff --git a/src/app/findmy/serial_number_send.h b/src/app/findmy/serial_number_send.h new file mode 100644 index 0000000..2ad4295 --- /dev/null +++ b/src/app/findmy/serial_number_send.h @@ -0,0 +1,15 @@ +#ifndef _SERIAL_NUMBER_SEND_H_ +#define _SERIAL_NUMBER_SEND_H_ + +#include +#include + +// 函数声明 +void custom_new_adv_init(void); +void custom_new_adv_start(void); +void custom_new_adv_stop(void); +void set_serial_number_to_adv(uint8_t *serial_number, uint8_t len); +uint8_t get_serial_number(uint8_t *serial_number, uint8_t max_len); +void update_serial_number_in_adv(void); + +#endif // SERIAL_NUMBER_SEND_H diff --git a/src/ble/privacy/privacy_mgnt.c b/src/ble/privacy/privacy_mgnt.c new file mode 100644 index 0000000..f8dc76b --- /dev/null +++ b/src/ble/privacy/privacy_mgnt.c @@ -0,0 +1,578 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file privacy_mgnt.c +* @brief privacy1.2 management file. +* @details Demonstration of how to implement privacy. +* @author +* @date 2016-02-18 +* @version v0.1 +********************************************************************************************************* +*/ +#include +#include +#include +#include +#include +#include + +typedef enum +{ + PRIVACY_RESOLVING_LIST_IDLE, + PRIVACY_RESOLVING_LIST_ADD_PENDING, + PRIVACY_RESOLVING_LIST_REMOVE_PENDING, +} T_PRIVACY_MODIFY_STATE; + +typedef enum +{ + PRIVACY_RESOLVING_ADDED_IDLE, + PRIVACY_RESOLVING_ADDED_PENDING, + PRIVACY_RESOLVING_ADDED, +} T_PRIVACY_ADDED_STATE; + +typedef struct +{ + bool is_used; + T_PRIVACY_ADDED_STATE is_added; + T_PRIVACY_MODIFY_STATE state; + bool device_mode; + T_GAP_IDENT_ADDR_TYPE remote_bd_type; + uint8_t addr[6]; +} T_LE_PRIVACY_ENTRY, *P_LE_PRIVACY_ENTRY; + +T_LE_PRIVACY_ENTRY *privacy_table; +bool privacy_clear_pending = false; +bool privacy_modify_resolv_list_pending = false; +uint8_t privacy_modify_resolv_list_idx = 0xff; +T_PRIVACY_STATE privacy_state = PRIVACY_STATE_INIT; +T_LE_PRIVACY_STATE privacy_resolution_status = LE_PRIVACY_RESOLUTION_DISABLED; +bool privacy_whitelist = false; +bool privacy_mode_manage = true; +static P_FUN_PRIVACY_STATE_CB privacy_app_cb = NULL; + +extern T_GAP_DEV_STATE gap_dev_state; + +void privacy_modify_resolving_list(T_GAP_RESOLV_LIST_OP op, T_GAP_IDENT_ADDR_TYPE addr_type, + uint8_t *addr, bool device_mode); + +T_APP_RESULT privacy_msg_callback(uint8_t msg_type, T_LE_PRIVACY_CB_DATA msg_data); + +void privacy_change_state(T_PRIVACY_STATE state) +{ + if (privacy_state != state) + { + + privacy_state = state; + if (privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.privacy_state = privacy_state; + privacy_app_cb(PRIVACY_STATE_MSGTYPE, cb_data); + } + } +} + +bool privacy_add_device(T_LE_KEY_ENTRY *p_entry) +{ + if (p_entry != NULL && p_entry->is_used) + { + bool device_mode = true; + T_LE_PRIVACY_INFO privacy_info; + if (le_get_privacy_info(p_entry, &privacy_info)) + { + if (privacy_info.is_discov && privacy_info.resolv_addr_only) + { + device_mode = false; + } + } + if ((p_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_PUBLIC) || + ((p_entry->remote_bd.remote_bd_type == GAP_REMOTE_ADDR_LE_RANDOM) && + ((p_entry->remote_bd.addr[5] & RANDOM_ADDR_MASK) == RANDOM_ADDR_MASK_STATIC)) + ) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_ADD, + (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, device_mode); + return true; + } + else + { + if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_ADD, + (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type, + p_entry->resolved_remote_bd.addr, device_mode); + return true; + } + else + { + APP_PRINT_ERROR1("[PRIVACY] privacy_add_device: failed, idx %d", p_entry->idx); + } + } + } + return false; +} + +void privacy_init(P_FUN_PRIVACY_STATE_CB privacy_callback, bool whitelist) +{ + uint8_t i; + uint16_t size; + T_LE_KEY_ENTRY *p_entry; + uint8_t bond_storage_num = le_get_max_le_paired_device_num(); + + APP_PRINT_INFO1("[PRIVACY] privacy_init: whitelist %d", whitelist); + size = bond_storage_num * sizeof(T_LE_PRIVACY_ENTRY); + privacy_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + privacy_app_cb = privacy_callback; + privacy_whitelist = whitelist; + le_privacy_register_cb(privacy_msg_callback); + + privacy_change_state(PRIVACY_STATE_IDLE); + + for (i = 0; i < bond_storage_num; i++) + { + p_entry = le_find_key_entry_by_idx(i); + privacy_add_device(p_entry); + } + return; +} + +T_PRIVACY_STATE privacy_handle_resolv_list_int(void) +{ + uint8_t i; + T_GAP_CAUSE cause; + T_PRIVACY_STATE state = PRIVACY_STATE_BUSY; + uint8_t bond_storage_num = le_get_max_le_paired_device_num(); + + if (privacy_modify_resolv_list_pending) + { + APP_PRINT_INFO0("[PRIVACY] wait rsp"); + return state; + } + if (privacy_clear_pending) + { + APP_PRINT_INFO0("[PRIVACY] clear"); + cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL); + if (cause == GAP_CAUSE_SUCCESS) + { + if (privacy_whitelist) + { + le_modify_white_list(GAP_WHITE_LIST_OP_CLEAR, NULL, GAP_REMOTE_ADDR_LE_PUBLIC); + } + privacy_modify_resolv_list_pending = true; + return state; + } + else + { + APP_PRINT_ERROR1("[PRIVACY] clear failed: cause %d", cause); + return state; + } + } + for (i = 0; i < bond_storage_num; i++) + { + if (privacy_table[i].is_used && privacy_table[i].state != PRIVACY_RESOLVING_LIST_IDLE) + { + if (privacy_table[i].state == PRIVACY_RESOLVING_LIST_ADD_PENDING) + { + + APP_PRINT_INFO3("[PRIVACY] Add: i %d, BD %s, type %d\n", i, + TRACE_BDADDR(privacy_table[i].addr), + privacy_table[i].remote_bd_type); + cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_ADD, + privacy_table[i].remote_bd_type, + privacy_table[i].addr); + if (cause == GAP_CAUSE_SUCCESS) + { + privacy_modify_resolv_list_pending = true; + privacy_modify_resolv_list_idx = i; + privacy_table[i].is_added = PRIVACY_RESOLVING_ADDED_PENDING; + if (privacy_whitelist) + { + le_modify_white_list(GAP_WHITE_LIST_OP_ADD, privacy_table[i].addr, + (T_GAP_REMOTE_ADDR_TYPE)privacy_table[i].remote_bd_type); + } + if (privacy_table[i].device_mode && privacy_mode_manage) + { + le_privacy_set_mode(privacy_table[i].remote_bd_type, privacy_table[i].addr, + GAP_PRIVACY_MODE_DEVICE); + } + return state; + } + else if (cause != GAP_CAUSE_INVALID_STATE) + { + APP_PRINT_ERROR2("[PRIVACY] Add failed: cause %d, remove i=%d from pend add\n", cause, i); + memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY)); + } + else + { + APP_PRINT_ERROR0("[PRIVACY] Add failed: invalid state"); + return state; + } + } + else + { + APP_PRINT_INFO3("[PRIVACY] Remove: i %d, BD %s, type %d", i, + TRACE_BDADDR(privacy_table[i].addr), + privacy_table[i].remote_bd_type); + cause = le_privacy_modify_resolv_list(GAP_RESOLV_LIST_OP_REMOVE, + privacy_table[i].remote_bd_type, + privacy_table[i].addr); + if (cause == GAP_CAUSE_SUCCESS) + { + privacy_modify_resolv_list_pending = true; + privacy_modify_resolv_list_idx = i; + if (privacy_whitelist) + { + le_modify_white_list(GAP_WHITE_LIST_OP_REMOVE, privacy_table[i].addr, + (T_GAP_REMOTE_ADDR_TYPE)privacy_table[i].remote_bd_type); + } + return state; + } + else if (cause != GAP_CAUSE_INVALID_STATE) + { + APP_PRINT_ERROR2("[PRIVACY] Remove failed: cause %d, remove i=%d from pend add\n", cause, i); + memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY)); + } + else + { + APP_PRINT_ERROR0("[PRIVACY] Remove failed: invalid state"); + return state; + } + } + } + } + APP_PRINT_INFO0("[PRIVACY] privacy_handle_resolv_list_int: idle"); + state = PRIVACY_STATE_IDLE; + return state; +} + +T_PRIVACY_STATE privacy_handle_resolv_list(void) +{ + T_GAP_DEV_STATE dev_state; + le_get_gap_param(GAP_PARAM_DEV_STATE, &dev_state); + if (privacy_resolution_status == LE_PRIVACY_RESOLUTION_DISABLED + || ((dev_state.gap_adv_state == GAP_ADV_STATE_IDLE) + && (dev_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE))) + { + T_PRIVACY_STATE state = privacy_handle_resolv_list_int(); + privacy_change_state(state); + } + return privacy_state; +} + +void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry, + bool handle_add) +{ + APP_PRINT_INFO1("[PRIVACY] privacy_handle_bond_modify_msg: type 0x%x", type); + + if (type == LE_BOND_CLEAR) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_CLEAR, GAP_IDENT_ADDR_PUBLIC, NULL, false); + } + else if (type == LE_BOND_DELETE) + { + if (p_entry->flags & LE_KEY_STORE_REMOTE_IRK_BIT) + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->resolved_remote_bd.remote_bd_type, + p_entry->resolved_remote_bd.addr, false); + } + else + { + privacy_modify_resolving_list(GAP_RESOLV_LIST_OP_REMOVE, + (T_GAP_IDENT_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, false); + } + } + else if (type == LE_BOND_ADD) + { + if (handle_add) + { + privacy_add_device(p_entry); + } + } + privacy_handle_resolv_list(); +} + +T_GAP_CAUSE privacy_set_addr_resolution(bool enable) +{ + return le_privacy_set_addr_resolution(enable); +} + +T_GAP_CAUSE privacy_read_peer_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address) +{ + uint8_t *peer_identity_address = peer_address; + uint8_t resolved_addr[6]; + T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type); + if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM) + { + if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type)) + { + peer_identity_address = resolved_addr; + } + } + return le_privacy_read_peer_resolv_addr(peer_identity_address_type, peer_identity_address); +} + +T_GAP_CAUSE privacy_read_local_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address) +{ + uint8_t *peer_identity_address = peer_address; + uint8_t resolved_addr[6]; + T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type); + if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM) + { + if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type)) + { + peer_identity_address = resolved_addr; + } + } + return le_privacy_read_local_resolv_addr(peer_identity_address_type, peer_identity_address); +} + +void privacy_manage_mode(bool is_manage) +{ + privacy_mode_manage = is_manage; +} + +T_GAP_CAUSE privacy_set_peer_mode(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address, bool device_mode) +{ + uint8_t *peer_identity_address = peer_address; + uint8_t resolved_addr[6]; + T_GAP_PRIVACY_MODE privacy_mode = GAP_PRIVACY_MODE_NETWORK; + T_GAP_IDENT_ADDR_TYPE peer_identity_address_type = le_privacy_convert_addr_type(peer_address_type); + if (peer_address_type == GAP_REMOTE_ADDR_LE_RANDOM) + { + if (le_resolve_random_address(peer_address, resolved_addr, &peer_identity_address_type)) + { + peer_identity_address = resolved_addr; + } + } + if (device_mode) + { + privacy_mode = GAP_PRIVACY_MODE_DEVICE; + } + return le_privacy_set_mode(peer_identity_address_type, peer_identity_address, privacy_mode); +} + +T_GAP_CAUSE privacy_set_gen_priv_addr_interval(uint16_t interval) +{ + T_GAP_DEV_STATE dev_state; + le_get_gap_param(GAP_PARAM_DEV_STATE, &dev_state); + le_privacy_set_param(GAP_PARAM_PRIVACY_TIMEOUT, sizeof(uint16_t), &interval); + if (dev_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + return le_privacy_set_resolv_priv_addr_timeout(); + } + return GAP_CAUSE_SUCCESS; +} + +void privacy_modify_resolving_list(T_GAP_RESOLV_LIST_OP op, T_GAP_IDENT_ADDR_TYPE addr_type, + uint8_t *addr, bool device_mode) +{ + uint8_t bond_storage_num = le_get_max_le_paired_device_num(); + APP_PRINT_INFO1("[PRIVACY] privacy_modify_resolving_list op = %d", op); + switch (op) + { + case GAP_RESOLV_LIST_OP_CLEAR: + privacy_clear_pending = true; + privacy_change_state(PRIVACY_STATE_BUSY); + break; + + case GAP_RESOLV_LIST_OP_ADD: + { + uint8_t i; + APP_PRINT_INFO2("[PRIVACY] privacy_add_device add: addr %s, addr type %d", TRACE_BDADDR(addr), + addr_type); + for (i = 0; i < bond_storage_num; i++) + { + if (privacy_table[i].is_used) + { + if ((privacy_table[i].remote_bd_type == addr_type) + && (memcmp(privacy_table[i].addr, addr, 6) == 0)) + { + APP_PRINT_ERROR0("[PRIVACY] privacy_add_device add: failed, exist"); + return; + } + } + } + for (i = 0; i < bond_storage_num; i++) + { + if (!privacy_table[i].is_used) + { + privacy_table[i].is_used = true; + privacy_table[i].remote_bd_type = addr_type; + memcpy(privacy_table[i].addr, addr, 6); + privacy_table[i].state = PRIVACY_RESOLVING_LIST_ADD_PENDING; + privacy_table[i].device_mode = device_mode; + privacy_change_state(PRIVACY_STATE_BUSY); + return; + } + } + APP_PRINT_ERROR0("[PRIVACY] privacy_add_device add: failed, no free entry"); + } + break; + + case GAP_RESOLV_LIST_OP_REMOVE: + { + uint8_t i; + APP_PRINT_INFO2("[PRIVACY] privacy_add_device remove: addr %s, addr type %d", TRACE_BDADDR(addr), + addr_type); + for (i = 0; i < bond_storage_num; i++) + { + if (privacy_table[i].is_used) + { + if ((privacy_table[i].remote_bd_type == addr_type) + && (memcmp(privacy_table[i].addr, addr, 6) == 0)) + { + if (privacy_table[i].is_added != PRIVACY_RESOLVING_ADDED_IDLE) + { + privacy_table[i].state = PRIVACY_RESOLVING_LIST_REMOVE_PENDING; + privacy_change_state(PRIVACY_STATE_BUSY); + } + else + { + memset(&privacy_table[i], 0, sizeof(T_LE_PRIVACY_ENTRY)); + APP_PRINT_INFO0("[PRIVACY] privacy_add_device remove: not added"); + } + break; + } + } + } + APP_PRINT_ERROR0("[PRIVACY] privacy_add_device remove: failed, no find"); + } + break; + + default: + break; + } +} + +void privacy_handle_le_privacy_resolution_status_info(T_LE_PRIVACY_RESOLUTION_STATUS_INFO + resolv_status) +{ + APP_PRINT_INFO1("[PRIVACY] privacy_handle_le_privacy_resolution_status_info: status 0x%x\n", + resolv_status.status); + privacy_resolution_status = resolv_status.status; + if (privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.resolution_state = (T_PRIVACY_ADDR_RESOLUTION_STATE)resolv_status.status; + privacy_app_cb(PRIVACY_RESOLUTION_STATUS_MSGTYPE, cb_data); + } +} + +void privacy_handle_le_privacy_modify_resolv_list_rsp(T_LE_PRIVACY_MODIFY_RESOLV_LIST_RSP *p_rsp) +{ + uint8_t bond_storage_num = le_get_max_le_paired_device_num(); + APP_PRINT_INFO2("[PRIVACY] privacy_handle_le_privacy_modify_resolv_list_rsp: operation 0x%x, casue 0x%x", + p_rsp->operation, p_rsp->cause); + privacy_modify_resolv_list_pending = false; + if (p_rsp->cause != GAP_SUCCESS) + { + if (p_rsp->cause == (HCI_ERR | HCI_ERR_UNKNOWN_CONN_ID) + || p_rsp->cause == (HCI_ERR | HCI_ERR_MEMORY_FULL) + || p_rsp->cause == (HCI_ERR | HCI_ERR_INVALID_PARAM)) + { + memset(&privacy_table[privacy_modify_resolv_list_idx], 0, sizeof(T_LE_PRIVACY_ENTRY)); + } + privacy_modify_resolv_list_idx = 0xff; + } + else + { + if (p_rsp->operation == GAP_RESOLV_LIST_OP_CLEAR) + { + privacy_clear_pending = false; + memset(privacy_table, 0, bond_storage_num * sizeof(T_LE_PRIVACY_ENTRY)); + } + else if (p_rsp->operation == GAP_RESOLV_LIST_OP_ADD) + { + if (privacy_modify_resolv_list_idx < bond_storage_num) + { + privacy_table[privacy_modify_resolv_list_idx].is_added = PRIVACY_RESOLVING_ADDED; + privacy_table[privacy_modify_resolv_list_idx].state = PRIVACY_RESOLVING_LIST_IDLE; + privacy_modify_resolv_list_idx = 0xff; + } + } + else + { + if (privacy_modify_resolv_list_idx < bond_storage_num) + { + memset(&privacy_table[privacy_modify_resolv_list_idx], 0, sizeof(T_LE_PRIVACY_ENTRY)); + privacy_modify_resolv_list_idx = 0xff; + } + } + privacy_handle_resolv_list(); + } +} + +T_APP_RESULT privacy_msg_callback(uint8_t msg_type, T_LE_PRIVACY_CB_DATA msg_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("[PRIVACY] privacy_msg_callback: msg_type %d", msg_type); + + switch (msg_type) + { + case GAP_MSG_LE_PRIVACY_RESOLUTION_STATUS_INFO: + privacy_handle_le_privacy_resolution_status_info(msg_data.le_privacy_resolution_status_info); + break; + + case GAP_MSG_LE_PRIVACY_MODIFY_RESOLV_LIST: + privacy_handle_le_privacy_modify_resolv_list_rsp(msg_data.p_le_privacy_modify_resolv_list_rsp); + break; + + case GAP_MSG_LE_PRIVACY_SET_MODE: + APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_SET_MODE: cause 0x%x", + msg_data.p_le_privacy_set_mode_rsp->cause); + if (privacy_mode_manage == false && privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.cause = msg_data.p_le_privacy_set_mode_rsp->cause; + privacy_app_cb(PRIVACY_SET_PEER_MODE_MSGTYPE, cb_data); + } + break; + + case GAP_MSG_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT: + APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_SET_RESOLV_PRIV_ADDR_TIMEOUT: cause 0x%x", + msg_data.p_le_privacy_set_resolv_priv_addr_timeout_rsp->cause); + if (privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.cause = msg_data.p_le_privacy_set_resolv_priv_addr_timeout_rsp->cause; + privacy_app_cb(PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE, cb_data); + } + break; + + case GAP_MSG_LE_PRIVACY_READ_PEER_RESOLV_ADDR: + APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_READ_PEER_RESOLV_ADDR: cause 0x%x", + msg_data.p_le_privacy_read_peer_resolv_addr_rsp->cause); + if (privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.p_privacy_read_resolv_addr_rsp = (T_PRIVACY_READ_RESOLV_ADDR_RSP *) + msg_data.p_le_privacy_read_peer_resolv_addr_rsp; + privacy_app_cb(PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE, cb_data); + } + break; + + case GAP_MSG_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR: + APP_PRINT_INFO1("[PRIVACY] GAP_MSG_LE_PRIVACY_READ_LOCAL_RESOLV_ADDR: cause 0x%x", + msg_data.p_le_privacy_read_local_resolv_addr_rsp->cause); + if (privacy_app_cb) + { + T_PRIVACY_CB_DATA cb_data; + cb_data.p_privacy_read_resolv_addr_rsp = (T_PRIVACY_READ_RESOLV_ADDR_RSP *) + msg_data.p_le_privacy_read_local_resolv_addr_rsp; + privacy_app_cb(PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE, cb_data); + } + break; + + default: + break; + } + return result; +} + diff --git a/src/ble/privacy/privacy_mgnt.h b/src/ble/privacy/privacy_mgnt.h new file mode 100644 index 0000000..b586a4b --- /dev/null +++ b/src/ble/privacy/privacy_mgnt.h @@ -0,0 +1,492 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file privacy_mgnt.h + * @brief privacy management module. + * @details privacy management module. + * @author jane + * @date 2018-06-19 + * @version v0.1 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _PRIVACY_MGNT_H_ +#define _PRIVACY_MGNT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include + +/** @defgroup BLE_PRIV_MODULE BLE Privacy Management Module + * @brief Application uses this module to handle privacy procedures. + * @{ + */ +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BLE_PRIV_MODULE_Exported_Types BLE Privacy Management Module Exported Types + * @{ + */ +/** @brief Privacy management module callback type*/ +typedef enum +{ + PRIVACY_STATE_MSGTYPE, //!< Privacy management module state. + PRIVACY_RESOLUTION_STATUS_MSGTYPE, //!< Response msg type for privacy_set_addr_resolution + PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE, //!< Response msg type for privacy_read_peer_resolv_addr + PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE,//!< Response msg type for privacy_read_local_resolv_addr + PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE,//!< Response msg type for privacy_set_gen_priv_addr_interval + PRIVACY_SET_PEER_MODE_MSGTYPE, +} T_PRIVACY_CB_TYPE; + +/** @brief Privacy management module state*/ +typedef enum +{ + PRIVACY_STATE_INIT, //!< Privacy management module is not initialization. + PRIVACY_STATE_IDLE, //!< Idle. No pending resolving list modification procedure. + PRIVACY_STATE_BUSY //!< Busy. Resolving list modification procedure is not completed. +} T_PRIVACY_STATE; + +/** @brief Define the privacy address resolution state */ +typedef enum +{ + PRIVACY_ADDR_RESOLUTION_DISABLED, + PRIVACY_ADDR_RESOLUTION_DISABLING, + PRIVACY_ADDR_RESOLUTION_ENABLING, + PRIVACY_ADDR_RESOLUTION_ENABLED +} T_PRIVACY_ADDR_RESOLUTION_STATE; + +/** @brief Callback data of PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE or PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE*/ +typedef struct +{ + uint16_t cause; + uint8_t resolv_addr[6]; +} T_PRIVACY_READ_RESOLV_ADDR_RSP; + +/** @brief Privacy management module callback data */ +typedef union +{ + uint16_t cause; //!< Callback data of PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE + T_PRIVACY_STATE privacy_state; //!< Callback data of PRIVACY_STATE_MSGTYPE + T_PRIVACY_ADDR_RESOLUTION_STATE + resolution_state; //!< Callback data of PRIVACY_RESOLUTION_STATUS_MSGTYPE + T_PRIVACY_READ_RESOLV_ADDR_RSP *p_privacy_read_resolv_addr_rsp; +} T_PRIVACY_CB_DATA; +/** End of BLE_PRIV_MODULE_Exported_Types + * @} + */ +/*============================================================================* + * Functions + *============================================================================*/ +/** + * @defgroup BLE_PRIV_MODULE_EXPORT_Functions BLE Privacy Management Module Exported Functions + * + * @{ + */ +/** + * @brief Callback for privacy management module to notify app + * @param[in] type callback msy type @ref T_PRIVACY_CB_TYPE. + * @param[in] cb_data callback data @ref T_PRIVACY_CB_DATA. + * @retval void + */ +typedef void(*P_FUN_PRIVACY_STATE_CB)(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data); + +/** + * @brief Initialize privacy management module. + * @param[in] p_fun Callback function provided by the APP to handle privacy messages sent from the privacy management module. + * @param[in] whitelist Whether manage the white list when modify the resolving list. + * @return none + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ...... + privacy_init(app_privacy_callback, true); + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_STATE_MSGTYPE: + app_privacy_state = cb_data.privacy_state; + break; + + case PRIVACY_RESOLUTION_STATUS_MSGTYPE: + app_privacy_resolution_state = cb_data.resolution_state; + break; + + default: + break; + } + } + * \endcode + */ +void privacy_init(P_FUN_PRIVACY_STATE_CB p_fun, bool whitelist); + +/** + * @brief Handle the pending resolving list modification procedure. + * + * Application shall call this funtion when the device state is in the idle state. + * + * @return The current privacy management module state. + * @retval T_PRIVACY_STATE module state + * + * Example usage + * \code{.c} + void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) + { + APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x", + new_state.gap_init_state, new_state.gap_adv_state, cause); + + if ((new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + && (new_state.gap_adv_state == GAP_ADV_STATE_IDLE) + && (new_state.gap_conn_state == GAP_CONN_DEV_STATE_IDLE)) + { + privacy_handle_resolv_list(); + } + + if (gap_dev_state.gap_init_state != new_state.gap_init_state) + { + if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + APP_PRINT_INFO0("GAP stack ready"); + app_adv_start(); + } + } + ...... + } + * \endcode + */ +T_PRIVACY_STATE privacy_handle_resolv_list(void); + +/** + * @brief Hande the GAP_MSG_LE_BOND_MODIFY_INFO message. + * + * Application shall call this funtion to handle the message GAP_MSG_LE_BOND_MODIFY_INFO. + * + * @param[in] type Bond modification type @ref T_LE_BOND_MODIFY_TYPE. + * @param[in] p_entry The key entry of the modified device. + * @param[in] handle_add Whether handle the type @ref LE_BOND_ADD. + * @return none + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + ...... + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry, true); + break; + + default: + APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type); + break; + } + return result; + } + * \endcode + */ +void privacy_handle_bond_modify_msg(T_LE_BOND_MODIFY_TYPE type, T_LE_KEY_ENTRY *p_entry, + bool handle_add); + +/** + * @brief Add the device to the resolving list. + * + * Application can call this funcation when the parameter handle_add of the privacy_handle_bond_modify_msg is false. + * + * @param[in] p_entry The key entry of the device. + * @return result + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + T_APP_RESULT app_gap_callback(uint8_t cb_type, void *p_cb_data) + { + ...... + switch (cb_type) + { + ...... + case GAP_MSG_LE_BOND_MODIFY_INFO: + APP_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + privacy_handle_bond_modify_msg(p_data->p_le_bond_modify_info->type, + p_data->p_le_bond_modify_info->p_entry, false); + break; + } + return result; + } + bool app_save_privacy_info(uint8_t conn_id) + { + if (app_link_table[conn_id].p_entry != NULL) + { + le_set_privacy_info(app_link_table[conn_id].p_entry, &app_link_table[conn_id].privacy_info); + privacy_add_device(app_link_table[conn_id].p_entry); + privacy_handle_resolv_list(); + } + return true; + } + * \endcode + */ +bool privacy_add_device(T_LE_KEY_ENTRY *p_entry); + +/** + * @brief Enable/disable le privacy address resolution mode. + * @param[in] enable Enable or disable address resolution. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void app_adv_start(void) + { + uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND; + uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY; + T_LE_KEY_ENTRY *p_entry; + p_entry = le_get_high_priority_bond(); + + if (p_entry == NULL) + { + app_work_mode = APP_PAIRABLE_MODE; + adv_filter_policy = GAP_ADV_FILTER_ANY; + if (app_privacy_resolution_state == PRIVACY_ADDR_RESOLUTION_ENABLED) + { + privacy_set_addr_resolution(false); + } + } + ...... + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_RESOLUTION_STATUS_MSGTYPE: + app_privacy_resolution_state = cb_data.resolution_state; + break; + + ...... + } + } + * \endcode + */ +T_GAP_CAUSE privacy_set_addr_resolution(bool enable); + +/** + * @brief Read peer resolvable random address. + * @param[in] peer_address_type Peer address type. + * @param[in] peer_address Peer address. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_readpra(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t idx = p_parse_value->dw_param[0]; + T_GAP_CAUSE cause; + T_LE_KEY_ENTRY *p_entry; + p_entry = le_find_key_entry_by_idx(idx); + if (p_entry) + { + cause = privacy_read_peer_resolv_addr((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr); + return (T_USER_CMD_PARSE_RESULT)cause; + } + else + { + return RESULT_ERR; + } + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE: + APP_PRINT_INFO2("PRIVACY_READ_PEER_RESOLV_ADDR_MSGTYPE: cause 0x%x, addr %b", + cb_data.p_privacy_read_resolv_addr_rsp->cause, + TRACE_BDADDR(cb_data.p_privacy_read_resolv_addr_rsp->resolv_addr)); + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE privacy_read_peer_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address); + +/** + * @brief Read local resolvable random address. + * @param[in] peer_address_type Peer address type. + * @param[in] peer_address Peer address. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_readlra(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t idx = p_parse_value->dw_param[0]; + T_GAP_CAUSE cause; + T_LE_KEY_ENTRY *p_entry; + p_entry = le_find_key_entry_by_idx(idx); + if (p_entry) + { + cause = privacy_read_local_resolv_addr((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr); + return (T_USER_CMD_PARSE_RESULT)cause; + } + else + { + return RESULT_ERR; + } + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE: + APP_PRINT_INFO2("PRIVACY_READ_LOCAL_RESOLV_ADDR_MSGTYPE: cause 0x%x, addr %b", + cb_data.p_privacy_read_resolv_addr_rsp->cause, + TRACE_BDADDR(cb_data.p_privacy_read_resolv_addr_rsp->resolv_addr)); + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE privacy_read_local_resolv_addr(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address); + +/** + * @brief Set privacy address generation interavl. + * @param[in] interval Privacy address generation interavl. + * Range:0x0001 - 0xA1B8(1s/step). Default value is 0x0384. + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t privacy_timeout = 0x384; + privacy_set_gen_priv_addr_interval(privacy_timeout); + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE: + APP_PRINT_INFO1("PRIVACY_GEN_PRIV_ADDR_INTERVAL_MSGTYPE: cause 0x%x", cb_data.cause); + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE privacy_set_gen_priv_addr_interval(uint16_t interval); + +/** + * @brief Configure privacy management module whether manage privacy mode when add device to the resolving list. + * @param[in] is_manage Whether manage privacy mode. + * @return None + */ +void privacy_manage_mode(bool is_manage); + +/** + * @brief Configure privacy mode. + * + * The default mode is network privacy mode. + * Application can call this funcation when the parameter is_manage of the privacy_manage_mode() is false. + * + * @param[in] peer_address_type Peer address type. + * @param[in] peer_address Peer address. + * @param[in] device_mode Configure the privacy mode. + * false - Network Privacy mode + * true - Device Privacy mode + * @return Operation result + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval Others Operation failure. + * + * Example usage + * \code{.c} + void app_le_gap_init(void) + { + ...... + privacy_manage_mode(false); + privacy_init(app_privacy_callback, true); + } + static T_USER_CMD_PARSE_RESULT cmd_setprivacy(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t idx = p_parse_value->dw_param[0]; + bool mode = p_parse_value->dw_param[1]; + T_LE_KEY_ENTRY *p_entry; + T_GAP_CAUSE cause; + p_entry = le_find_key_entry_by_idx(idx); + if (p_entry != NULL) + { + cause = privacy_set_peer_mode((T_GAP_REMOTE_ADDR_TYPE)p_entry->remote_bd.remote_bd_type, + p_entry->remote_bd.addr, + mode); + return (T_USER_CMD_PARSE_RESULT)cause; + } + else + { + return RESULT_CMD_ERR_PARAM; + } + } + void app_privacy_callback(T_PRIVACY_CB_TYPE type, T_PRIVACY_CB_DATA cb_data) + { + APP_PRINT_INFO1("app_privacy_callback: type %d", type); + switch (type) + { + case PRIVACY_SET_PEER_MODE_MSGTYPE: + APP_PRINT_INFO1("PRIVACY_SET_PEER_MODE_MSGTYPE: cause 0x%x", cb_data.cause); + break; + + default: + break; + } + } + * \endcode + */ +T_GAP_CAUSE privacy_set_peer_mode(T_GAP_REMOTE_ADDR_TYPE peer_address_type, + uint8_t *peer_address, bool device_mode); + + +/** @} */ /* End of group BLE_PRIV_MODULE_EXPORT_Functions */ +/** @} */ /* End of group BLE_PRIV_MODULE */ +#ifdef __cplusplus +} +#endif + +#endif /* _PRIVACY_MGNT_H_ */ diff --git a/src/ble/profile/bt_gatt_svc.c b/src/ble/profile/bt_gatt_svc.c new file mode 100644 index 0000000..4a6ce1c --- /dev/null +++ b/src/ble/profile/bt_gatt_svc.c @@ -0,0 +1,92 @@ +#include +#include "stdlib.h" +#include "bt_gatt_svc.h" +#include "trace.h" + + +T_CHAR_UUID gatt_svc_find_char_uuid_by_index(const T_ATTRIB_APPL *p_srv, uint16_t index, + uint16_t attr_num) +{ + T_CHAR_UUID char_uuid; + memset(&char_uuid, 0, sizeof(T_CHAR_UUID)); + if (p_srv == NULL) + { + PROFILE_PRINT_ERROR0("gatt_svc_find_char_uuid_by_index: failed, service table is NULL"); + return char_uuid; + } + + if (index >= attr_num) + { + PROFILE_PRINT_ERROR0("gatt_svc_find_char_uuid_by_index: failed, index error"); + return char_uuid; + } + + + char_uuid.uu.char_uuid16 = (p_srv[index].type_value[0]) | (p_srv[index].type_value[1] << 8); + char_uuid.uuid_size = UUID_16BIT_SIZE; + //If it is cccd, we should find charac uuid + if (char_uuid.uu.char_uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + index--; + while (index > 0) + { + char_uuid.uu.char_uuid16 = (p_srv[index].type_value[0]) | (p_srv[index].type_value[1] << 8); + if (char_uuid.uu.char_uuid16 == GATT_UUID_CHARACTERISTIC) + { + index++; + char_uuid.uu.char_uuid16 = (p_srv[index].type_value[0]) | (p_srv[index].type_value[1] << 8); + break; + } + index--; + } + } + + char_uuid.index = index; + return char_uuid; +} + + +/********************************************************************* +*** attr_num: the table total attr_num + +*** char_uuid: + char_uuid.index: the which num-th character to be found + +*** return char index in the table +**********************************************************************/ +uint16_t gatt_svc_find_char_index_by_uuid16(const T_ATTRIB_APPL *p_srv, uint16_t char_uuid16, + uint16_t attr_num) +{ + T_CHAR_UUID char_uuid; + uint16_t attrib_idx = 0; + char_uuid.index = 1; + char_uuid.uuid_size = UUID_16BIT_SIZE; + char_uuid.uu.char_uuid16 = char_uuid16; + + uint16_t idx = 0; + uint8_t char_num = 1; + + if (p_srv != NULL) + { + while (idx < attr_num) + { + if ((char_uuid.uuid_size == UUID_16BIT_SIZE && !(p_srv[idx].flags & ATTRIB_FLAG_UUID_128BIT))) + { + if (memcmp(&char_uuid.uu.char_uuid16, p_srv[idx].type_value, char_uuid.uuid_size) == 0) + { + if (char_uuid.index == char_num) + { + attrib_idx = idx; + return attrib_idx; + } + char_num++; + } + } + idx++; + } + } + + PROFILE_PRINT_ERROR0("gatt_svc_find_char_index_by_uuid16: failed"); + return attrib_idx; +} + diff --git a/src/ble/profile/bt_gatt_svc.h b/src/ble/profile/bt_gatt_svc.h new file mode 100644 index 0000000..7fe952d --- /dev/null +++ b/src/ble/profile/bt_gatt_svc.h @@ -0,0 +1,81 @@ +#ifndef _BT_GATT_SVC_H_ +#define _BT_GATT_SVC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "profile_server.h" +#include "gatt.h" + +/** @defgroup BT_GATT_SVC Bluetooth GATT Service + * @brief Bluetooth GATT Service + * @{ + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup BT_GATT_SERVICE_Exported_Types Bluetooth GATT Service Exported Types + * @{ + */ +/** + * @brief Bluetooth GATT service characteristic UUID + */ +typedef struct +{ + uint16_t index; + uint8_t uuid_size; + union + { + uint16_t char_uuid16; + uint8_t char_uuid128[16]; + } uu; +} T_CHAR_UUID; + +/** End of BT_GATT_SERVICE_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup BT_GATT_SERVICE_Exported_Functions Bluetooth GATT Service Exported Functions + * @{ + */ + +/** + * @brief Find service characteristic uuid by attribute index. + * @param[in] p_srv Pointer to service table: @ref T_ATTRIB_APPL. + * @param[in] index Attribute index of characteristic. + * @param[in] attr_num Total attribute number of service. + * @return The characteristic uuid. @ref T_CHAR_UUID. + */ +T_CHAR_UUID gatt_svc_find_char_uuid_by_index(const T_ATTRIB_APPL *p_srv, uint16_t index, + uint16_t attr_num); + +/** + * @brief Find service characteristic attribute index by uuid. + * @param[in] p_srv Pointer to service table. @ref T_ATTRIB_APPL. + * @param[in] char_uuid Service characteristic uuid. + * @param[in] attr_num Total attribute number of service. + * @param[in,out] index Attribute index of characteristic. + * @return The result of finding service characteristic attribute index. + * @retval true Success. + * @retval false Failed. + */ +uint16_t gatt_svc_find_char_index_by_uuid16(const T_ATTRIB_APPL *p_srv, uint16_t char_uuid16, + uint16_t attr_num); + +/** End of BT_GATT_SERVICE_Exported_Functions + * @} + */ +/** End of BT_GATT_SVC + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/src/ble/profile/client/ams_client.c b/src/ble/profile/client/ams_client.c new file mode 100644 index 0000000..52c391a --- /dev/null +++ b/src/ble/profile/client/ams_client.c @@ -0,0 +1,536 @@ +/** +***************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ams_client.c + * @brief + * @details + * @author + * @date + * @version v1.0 + *************************************************************************************** +*/ +#include +#include "ams_client.h" +#include "os_mem.h" +#include "trace.h" + +/** + * @brief AMS Link control block defination. + */ +typedef struct +{ + T_AMS_DISC_STATE disc_state; + bool remote_cmd_notify; + bool entity_upd_notify; + uint16_t hdl_cache[AMS_HDL_CACHE_LEN]; +} T_AMS_LINK, *P_AMS_LINK; + +//AMS service UUID 89D3502B-0F36-433A-8EF4-C502AD55F8DC +uint8_t AMS_SRV_UUID128[16] = {0xdc, 0xf8, 0x55, 0xad, 0x02, 0xc5, 0xf4, 0x8e, 0x3a, 0x43, 0x36, 0x0f, 0x2b, 0x50, 0xd3, 0x89}; +//Remote Command UUID 9B3C81D8-57B1-4A8A-B8DF-0E56F7CA51C2 (writeable, notifiable) +const uint8_t AMS_CHAR_REMOTE_CMD_UUID128[16] = {0xc2, 0x51, 0xca, 0xf7, 0x56, 0x0e, 0xdf, 0xb8, 0x8a, 0x4a, 0xb1, 0x57, 0xd8, 0x81, 0x3c, 0x9b}; +//Entity Update UUID 2F7CABCE-808D-411F-9A0C-BB92BA96C102 (writeable with response, notifiable) +const uint8_t AMS_CHAR_ENTITY_UPD_UUID128[16] = {0x02, 0xc1, 0x96, 0xba, 0x92, 0xbb, 0x0c, 0x9a, 0x1f, 0x41, 0x8d, 0x80, 0xce, 0xab, 0x7c, 0x2f}; +//Entity Attribute UUID C6B2F38C-23AB-46D8-A6AB-A3A870BBD5D7 (readable, writeable) +const uint8_t AMS_CHAR_ENTITY_ATTR_UUID128[16] = {0xd7, 0xd5, 0xbb, 0x70, 0xa8, 0xa3, 0xab, 0xa6, 0xd8, 0x46, 0xab, 0x23, 0x8c, 0xf3, 0xb2, 0xc6}; + +P_AMS_LINK ams_table; +static uint8_t ams_link_num; +T_CLIENT_ID ams_client_id = CLIENT_PROFILE_GENERAL_ID; +static P_FUN_GENERAL_APP_CB ams_client_cb = NULL; + +uint16_t ams_search_handle(uint8_t conn_id, T_AMS_HANDLE_TYPE handle_type) +{ + uint16_t handle = 0; + P_AMS_LINK link_info = ams_table; + + if (handle_type >= AMS_HDL_CACHE_LEN) + { + APP_PRINT_ERROR1("ams_search_handle: no handle_type %d", handle_type); + return AMS_HDL_CACHE_LEN; + } + + handle = link_info[conn_id].hdl_cache[handle_type]; + + APP_PRINT_INFO1("ams_search_handle: ams handle 0x%08x", handle); + + return handle; +} + + + +/** + * @brief start AMS service discovery procedure. + */ +bool ams_start_discovery(uint8_t conn_id) +{ + if (conn_id >= ams_link_num) + { + PROFILE_PRINT_ERROR2("ams_start_discovery: failed invalid conn_id %d, ams_link_num = %d", conn_id, + ams_link_num); + return false; + } + + //clear handle cache first + memset(ams_table[conn_id].hdl_cache, 0, 2 * AMS_HDL_CACHE_LEN); + ams_table[conn_id].disc_state = AMS_DISC_START; + APP_PRINT_INFO0("ams_start_discovery"); + if (client_by_uuid128_srv_discovery(conn_id, ams_client_id, AMS_SRV_UUID128) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief start AMS characteristic discovery procedure. + */ +bool ams_discovery_char(uint8_t conn_id) +{ + uint16_t start_handle = ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START]; + uint16_t end_handle = ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END]; + + APP_PRINT_INFO0("ams_start_char_discovery"); + if (client_all_char_discovery(conn_id, ams_client_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief AMS remote command subscribe. + */ +bool ams_subscribe_remote_cmd(uint8_t conn_id, bool subscribe) +{ + uint16_t handle; + if (conn_id >= ams_link_num) + { + PROFILE_PRINT_ERROR1("ams_subscribe_remote_cmd: failed invalid conn_id %d", conn_id); + return false; + } + handle = ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_CCCD]; + if (handle) + { + uint16_t cccd = subscribe ? 1 : 0; + APP_PRINT_INFO0("ams_subscribe_remote_cmd"); + if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(uint16_t), + (uint8_t *)&cccd) == GAP_CAUSE_SUCCESS) + { + ams_table[conn_id].remote_cmd_notify = 1; + return true; + } + } + return false; +} + +/** + * @brief AMS write remote command. + */ +bool ams_write_remote_cmd(uint8_t conn_id, T_AMS_REMOTE_CMD_ID cmd_id) +{ + uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_VALUE]; + if (handle) + { + APP_PRINT_INFO0("ams_write_remote_cmd"); + if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, + 1, (uint8_t *)&cmd_id) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + return false; +} + + +/** + * @brief AMS entity update subscribe. + */ +bool ams_subscribe_entity_upd(uint8_t conn_id, bool subscribe) +{ + uint16_t handle; + if (conn_id >= ams_link_num) + { + PROFILE_PRINT_ERROR1("ams_subscribe_entity_upd: failed invalid conn_id %d", conn_id); + return false; + } + handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_CCCD]; + if (handle) + { + uint16_t cccd = subscribe ? 1 : 0; + APP_PRINT_INFO0("ams_subscribe_entity_upd"); + if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(uint16_t), + (uint8_t *)&cccd) == GAP_CAUSE_SUCCESS) + { + ams_table[conn_id].entity_upd_notify = 1; + return true; + } + } + return false; +} + +/** + * @brief AMS write entity update command. + entity_attr_id, first byte is entity id, the other bytes are attribute id list. + */ +bool ams_write_entity_upd_cmd(uint8_t conn_id, uint8_t *p_value, uint8_t value_len) +{ + uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_VALUE]; + if (handle) + { + APP_PRINT_INFO0("ams_write_entity_upd_cmd"); + if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, + value_len, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + return false; +} + + +/** + * @brief AMS write entity attribute. + */ +bool ams_write_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr) +{ + uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE]; + if (handle) + { + APP_PRINT_INFO0("ams_write_entity_attr"); + if (client_attr_write(conn_id, ams_client_id, GATT_WRITE_TYPE_REQ, handle, sizeof(entity_attr), + (uint8_t *)&entity_attr) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + return false; +} + + +/** + * @brief AMS read entity attribute. + */ +bool ams_read_entity_attr(uint8_t conn_id, T_AMS_ENTITY_ATTR entity_attr) +{ + uint16_t handle = ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE]; + if (handle) + { + APP_PRINT_INFO0("ams_read_entity_attr"); + if (client_attr_read(conn_id, ams_client_id, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + return false; +} + + +/** + * @brief Called by profile client layer, when discover state of discovery procedure changed. + */ +static void ams_client_cb_discover_state(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_AMS_CB_DATA cb_data; + cb_data.cb_type = AMS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("ams_client_cb_discover_state: discovery state = %d", discovery_state); + if (ams_table[conn_id].disc_state == AMS_DISC_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + if ((ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START] != 0) || + (ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END] != 0)) + { + // start discover characteristic. + if (ams_discovery_char(conn_id) == false) + { + ams_table[conn_id].disc_state = AMS_DISC_FAILED; + cb_flag = true; + } + } + else // No AMS handle found. + { + ams_table[conn_id].disc_state = AMS_DISC_FAILED; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DONE: + ams_table[conn_id].disc_state = AMS_DISC_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + ams_table[conn_id].disc_state = AMS_DISC_FAILED; + cb_flag = true; + break; + + default: + APP_PRINT_ERROR0("ams_client_cb_discover_state: invalid discovery state!"); + break; + } + } + + // send discover state to app if need + if (cb_flag && ams_client_cb) + { + cb_data.cb_content.disc_state = ams_table[conn_id].disc_state; + (*ams_client_cb)(ams_client_id, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + */ +static void ams_client_cb_discover_result(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("ams_client_discover_result_cb: result type = %d", result_type); + if (ams_table[conn_id].disc_state == AMS_DISC_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + { + ams_table[conn_id].hdl_cache[AMS_HDL_SRV_START] = result_data.p_srv_disc_data->att_handle; + ams_table[conn_id].hdl_cache[AMS_HDL_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + } + break; + + case DISC_RESULT_CHAR_UUID128: + { + uint16_t handle; + handle = result_data.p_char_uuid128_disc_data->value_handle; + if (0 == memcmp(AMS_CHAR_REMOTE_CMD_UUID128, result_data.p_char_uuid128_disc_data->uuid128, 16)) + { + ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_VALUE] = handle; + ams_table[conn_id].hdl_cache[AMS_HDL_REMOTE_CMD_CCCD] = handle + 2; + } + else if (0 == memcmp(AMS_CHAR_ENTITY_UPD_UUID128, result_data.p_char_uuid128_disc_data->uuid128, + 16)) + { + ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_VALUE] = handle; + ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_UPD_CCCD] = handle + 2; + } + else if (0 == memcmp(AMS_CHAR_ENTITY_ATTR_UUID128, result_data.p_char_uuid128_disc_data->uuid128, + 16)) + { + ams_table[conn_id].hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE] = handle; + } + } + break; + + default: + APP_PRINT_ERROR0("ams_client_discover_result_cb: invalid discovery result type"); + break; + } + } + + return; +} + +static void ams_client_cb_read_result(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_AMS_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ams_table[conn_id].hdl_cache; + + cb_data.cb_type = AMS_CLIENT_CB_TYPE_READ_RESULT; + + APP_PRINT_INFO2("ams_client_cb_read_result: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_data.cause = cause; + + if (handle == hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE]) + { + cb_data.cb_content.read_data.type = AMS_READ_FROM_ENTITY_UPD; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_data.p_value = p_value; + cb_data.cb_content.read_data.value_size = value_size; + } + else + { + cb_data.cb_content.read_data.value_size = 0; + } + } + else + { + return; + } + /* Inform application the read result. */ + if (ams_client_cb) + { + (*ams_client_cb)(ams_client_id, conn_id, &cb_data); + } + + return; +} + +/** + * @brief Called by profile client layer, when write result arrived. + */ +static void ams_client_cb_write_result(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle, + uint16_t cause, uint8_t credits) +{ + T_AMS_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ams_table[conn_id].hdl_cache; + cb_data.cb_type = AMS_CLIENT_CB_TYPE_WRITE_RESULT; + + APP_PRINT_INFO2("ams_client_write_result_cb: handle=0x%x cause = 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_CCCD]) + { + if (ams_table[conn_id].remote_cmd_notify == 1) + { + cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE; + } + } + else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_CCCD]) + { + if (ams_table[conn_id].entity_upd_notify == 1) + { + cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE; + } + } + else if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_VALUE]) + { + cb_data.cb_content.write_result.type = AMS_WRITE_REMOTE_CMD_VALUE; + } + else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_VALUE]) + { + cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_UPD_VALUE; + } + else if (handle == hdl_cache[AMS_HDL_ENTITY_ATTR_VALUE]) + { + cb_data.cb_content.write_result.type = AMS_WRITE_ENTITY_ATTR_VALUE; + } + else + { + return; + } + + if (ams_client_cb) + { + (*ams_client_cb)(ams_client_id, conn_id, &cb_data); + } + + return; +} + +/** + * @brief Called by profile client layer, when notification or indication arrived. + */ +static T_APP_RESULT ams_client_cb_notify_ind(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_AMS_CB_DATA cb_data; + uint16_t *hdl_cache; + + hdl_cache = ams_table[conn_id].hdl_cache; + cb_data.cb_type = AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[AMS_HDL_REMOTE_CMD_VALUE]) + { + cb_data.cb_content.notify_data.type = AMS_NOTIFY_FROM_REMOTE_CMD; + cb_data.cb_content.notify_data.value_size = value_size; + cb_data.cb_content.notify_data.p_value = p_value; + } + else if (handle == hdl_cache[AMS_HDL_ENTITY_UPD_VALUE]) + { + cb_data.cb_content.notify_data.type = AMS_NOTIFY_FROM_ENTITY_UPD; + cb_data.cb_content.notify_data.value_size = value_size; + cb_data.cb_content.notify_data.p_value = p_value; + } + else + { + return APP_RESULT_SUCCESS; + } + + if (ams_client_cb) + { + app_result = (*ams_client_cb)(ams_client_id, conn_id, &cb_data); + } + + return app_result; +} + +/** + * @brief Called by profile client layer, when one LE link is disconnected. + */ +static void ams_client_cb_disc(uint8_t conn_id) +{ + APP_PRINT_INFO0("ams_client_disc_cb."); + memset(&ams_table[conn_id], 0, sizeof(T_AMS_LINK)); + if (ams_client_cb) + { + T_AMS_CB_DATA cb_data; + cb_data.cb_type = AMS_CLIENT_CB_TYPE_DISCONNECT_INFO; + (*ams_client_cb)(ams_client_id, conn_id, &cb_data); + } + return; +} +/** + * @brief AMS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS ams_cbs = +{ + ams_client_cb_discover_state, //!< Discovery State callback function pointer + ams_client_cb_discover_result, //!< Discovery result callback function pointer + ams_client_cb_read_result, //!< Read response callback function pointer + ams_client_cb_write_result, //!< Write result callback function pointer + ams_client_cb_notify_ind, //!< Notify Indicate callback function pointer + ams_client_cb_disc //!< Link disconnection callback function pointer +}; + +/** + * @brief Add ams client. + * + * @param[in] app_cb Callback to notify client read/write/notify/indicate events. + * @param[in] link_num Initialize link number + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + */ +T_CLIENT_ID ams_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > AMS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("ams_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&ams_client_id, &ams_cbs)) + { + ams_client_id = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("ams_add_client Fail !!!"); + return ams_client_id; + } + APP_PRINT_INFO1("ams_add_client: client ID = %d", ams_client_id); + + /* register callback for profile to inform application that some events happened. */ + ams_client_cb = app_cb; + ams_link_num = link_num; + size = ams_link_num * sizeof(T_AMS_LINK); + ams_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return ams_client_id; +} + diff --git a/src/ble/profile/client/ancs_client.c b/src/ble/profile/client/ancs_client.c new file mode 100644 index 0000000..1bb60a2 --- /dev/null +++ b/src/ble/profile/client/ancs_client.c @@ -0,0 +1,681 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ancs_client.c + * @brief + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +/** + * @brief ANCS Link control block definition. + */ +typedef struct +{ + T_ANCS_DISC_STATE disc_state; + bool write_notify_value; + uint16_t hdl_cache[HDL_ANCS_CACHE_LEN]; +} T_ANCS_LINK, *P_ANCS_LINK; + +/** @brief ANCS link table */ +static P_ANCS_LINK ancs_table; +static uint8_t ancs_link_num; + +/**< ANCS client ID. */ +static T_CLIENT_ID ancs_client_id = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from ANCS client layer. */ +static P_FUN_GENERAL_APP_CB ancs_client_cb = NULL; + +uint8_t ANCS_UUID128_SRV[16] = {0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79}; +const uint8_t ANCS_UUID128_CHAR_CONTROL_POINT[16] = {0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69}; +const uint8_t ANCS_UUID128_CHAR_NOTIFICATION_SOURCE[16] = {0xBD, 0x1D, 0xA2, 0x99, 0xE6, 0x25, 0x58, 0x8C, 0xD9, 0x42, 0x01, 0x63, 0x0D, 0x12, 0xBF, 0x9F}; +const uint8_t ANCS_UUID128_CHAR_DATA_SOURCE[16] = {0xFB, 0x7B, 0x7C, 0xCE, 0x6A, 0xB3, 0x44, 0xBE, 0xB5, 0x4B, 0xD6, 0x24, 0xE9, 0xC6, 0xEA, 0x22}; + + +uint16_t ancs_search_handle(uint8_t conn_id, T_ANCS_HANDLE_TYPE handle_type) +{ + uint16_t handle = 0; + P_ANCS_LINK link_info = ancs_table; + + if (handle_type >= HDL_ANCS_CACHE_LEN) + { + APP_PRINT_ERROR1("ancs_search_handle: no handle_type %d", handle_type); + return HDL_ANCS_CACHE_LEN; + } + + handle = link_info[conn_id].hdl_cache[handle_type]; + + APP_PRINT_INFO1("ancs_search_handle: ancs handle 0x%08x", handle); + + return handle; +} + + +/** + * @brief Used by application, to start the discovery procedure of ANCS. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_start_discovery(uint8_t conn_id) +{ + APP_PRINT_INFO0("ancs_start_discovery"); + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(ancs_table[conn_id].hdl_cache, 0, 2 * HDL_ANCS_CACHE_LEN); + ancs_table[conn_id].disc_state = DISC_ANCS_START; + if (client_by_uuid128_srv_discovery(conn_id, ancs_client_id, + ANCS_UUID128_SRV) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used internal, start the discovery of ANCS characteristics. + * NOTE--user can offer this interface for application if required. + * @param[in] conn_id: connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +static bool ancs_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("ancs_start_char_discovery"); + start_handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START]; + end_handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END]; + if (client_all_char_discovery(conn_id, ancs_client_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_ancshdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_ANCS_CACHE_LEN]; + bool ret = ancs_get_hdl_cache(conn_id, hdl_cache, + sizeof(uint16_t) * HDL_ANCS_CACHE_LEN); + + ...... + } + * \endcode + */ +bool ancs_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].disc_state != DISC_ANCS_DONE) + { + PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid state %d", ancs_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_ANCS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("ancs_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, ancs_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_ANCS_FLAG) + { + ancs_set_hdl_cache(conn_id, app_srvs_table.ancs_hdl_cache, sizeof(uint16_t) * HDL_ANCS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool ancs_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].disc_state != DISC_ANCS_IDLE) + { + PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid state %d", ancs_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_ANCS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("ancs_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(ancs_table[conn_id].hdl_cache, p_hdl_cache, len); + ancs_table[conn_id].disc_state = DISC_ANCS_DONE; + return true; +} + +/** + * @brief Used by application, to set the notifcation flag of notification source. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_set_notification_source_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_set_notification_source_notify: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD]) + { + uint16_t handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + ancs_table[conn_id].write_notify_value = notify; + return true; + } + } + return false; +} + +/** + * @brief Used by application, to set the notifcation flag of data source. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_set_data_source_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_set_data_source_notify: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD]) + { + uint16_t handle = ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + ancs_table[conn_id].write_notify_value = notify; + return true; + } + } + return false; +} + +/** + * @brief Used by application, to get the notifcation attribute. + * @param[in] conn_id connection ID. + * @param[in] notification_uid value to enable or disable notify. + * @param[in] p_attribute_ids Pointer to attribute ids. + * @param[in] attribute_ids_len Length of attribute ids. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_get_notification_attr(uint8_t conn_id, uint32_t notification_uid, + uint8_t *p_attribute_ids, uint8_t attribute_ids_len) +{ + bool result = false; + uint8_t command_id = CP_CMD_ID_GET_NOTIFICATION_ATTR; + uint16_t length = sizeof(command_id) + sizeof(notification_uid) + attribute_ids_len; + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_get_notification_attr: failed invalid conn_id %d", conn_id); + return false; + } + if (attribute_ids_len > 25) + { + return false; + } + if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT]) + { + uint8_t buffer[30]; + uint16_t offset = 0; + memcpy(buffer + offset, &command_id, sizeof(command_id)); + offset += sizeof(command_id); + memcpy(buffer + offset, ¬ification_uid, sizeof(notification_uid)); + offset += sizeof(notification_uid); + memcpy(buffer + offset, p_attribute_ids, attribute_ids_len); + if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, + ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT], + length, buffer) == GAP_CAUSE_SUCCESS) + { + result = true; + } + } + return result; +} + +/** + * @brief Used by application, to get the app attribute. + * @param[in] conn_id connection ID. + * @param[in] p_app_identifier value to enable or disable notify. + * @param[in] p_attribute_ids Pointer to attribute ids. + * @param[in] attribute_ids_len Length of attribute ids. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_get_app_attr(uint8_t conn_id, char *p_app_identifier, uint8_t *p_attribute_ids, + uint8_t attribute_ids_len) +{ + bool result = false; + uint8_t command_id = CP_CMD_ID_GET_APP_ATTR; + uint16_t length = sizeof(command_id) + strlen((const char *)p_app_identifier) + attribute_ids_len + + 1; + uint8_t *p_buffer = NULL; + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_get_app_attr: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT]) + { + uint16_t offset = 0; + p_buffer = os_mem_zalloc(RAM_TYPE_DATA_ON, length); + + if (!p_buffer) + { + PROFILE_PRINT_ERROR2("ancs_get_app_attr: allocation failed, conn_id %d, length %d", conn_id, + length); + return false; + } + + memcpy(p_buffer + offset, &command_id, sizeof(command_id)); + offset += sizeof(command_id); + memcpy(p_buffer + offset, p_app_identifier, strlen((const char *)p_app_identifier)); + offset += strlen((const char *)p_app_identifier); + p_buffer[offset] = 0; + offset += 1; + memcpy(p_buffer + offset, p_attribute_ids, attribute_ids_len); + if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, + ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT], + length, p_buffer) == GAP_CAUSE_SUCCESS) + { + result = true; + } + } + if (p_buffer != NULL) + { + os_mem_free(p_buffer); + } + + return result; +} + +/** + * @brief Used by application, to perfome the notication action. + * @param[in] conn_id Connection ID. + * @param[in] notification_uid Notification UUID. + * @param[in] action_id Action id. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ancs_perform_notification_action(uint8_t conn_id, uint32_t notification_uid, uint8_t action_id) +{ + bool result = false; + uint8_t command_id = CP_CMD_ID_PERFORM_NOTIFICATION_ACTION; + uint16_t length = sizeof(command_id) + sizeof(notification_uid) + sizeof(action_id); + if (conn_id >= ancs_link_num) + { + PROFILE_PRINT_ERROR1("ancs_perform_notification_action: failed invalid conn_id %d", conn_id); + return false; + } + if (ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT]) + { + uint8_t buffer[12]; + uint16_t offset = 0; + memcpy(buffer + offset, &command_id, sizeof(command_id)); + offset += sizeof(command_id); + memcpy(buffer + offset, ¬ification_uid, sizeof(notification_uid)); + offset += sizeof(notification_uid); + memcpy(buffer + offset, &action_id, sizeof(action_id)); + if (client_attr_write(conn_id, ancs_client_id, GATT_WRITE_TYPE_REQ, + ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT], + length, buffer) == GAP_CAUSE_SUCCESS) + { + result = true; + } + } + return result; +} + +/** + * @brief Called by profile client layer, when discover state of discovery procedure changed. + * @param[in] conn_id: connection ID. + * @param[in] discovery_state: current service discovery state. + * @retval None + */ +static void ancs_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_ANCS_CB_DATA cb_data; + cb_data.cb_type = ANCS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("ancs_client_discover_state_cb: discoveryState %d", discovery_state); + if (ancs_table[conn_id].disc_state == DISC_ANCS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START] != 0) + || (ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END] != 0)) + { + if (ancs_start_char_discovery(conn_id) == false) + { + ancs_table[conn_id].disc_state = DISC_ANCS_FAILED; + cb_flag = true; + } + } + /* No ANCS handle found. Discover procedure complete. */ + else + { + ancs_table[conn_id].disc_state = DISC_ANCS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + ancs_table[conn_id].disc_state = DISC_ANCS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + ancs_table[conn_id].disc_state = DISC_ANCS_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && ancs_client_cb) + { + cb_data.cb_content.disc_state = ancs_table[conn_id].disc_state; + (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param[in] conn_id: connection ID. + * @param[in] result_type: indicate which type of value discovered in service discovery procedure. + * @param[in] result_data: value discovered. + * @retval None + */ +static void ancs_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("gap_client_discover_result_cb: resultType %d", result_type); + if (ancs_table[conn_id].disc_state == DISC_ANCS_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + ancs_table[conn_id].hdl_cache[HDL_ANCS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + case DISC_RESULT_CHAR_UUID128: + { + uint16_t handle; + handle = result_data.p_char_uuid128_disc_data->value_handle; + if (0 == memcmp(ANCS_UUID128_CHAR_CONTROL_POINT, result_data.p_char_uuid128_disc_data->uuid128, 16)) + { + ancs_table[conn_id].hdl_cache[HDL_ANCS_CONTROL_POINT] = handle; + } + else if (0 == memcmp(ANCS_UUID128_CHAR_NOTIFICATION_SOURCE, + result_data.p_char_uuid128_disc_data->uuid128, 16)) + { + ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE] = handle; + ancs_table[conn_id].hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD] = handle + 1; + } + else if (0 == memcmp(ANCS_UUID128_CHAR_DATA_SOURCE, result_data.p_char_uuid128_disc_data->uuid128, + 16)) + { + ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE] = handle; + ancs_table[conn_id].hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD] = handle + 1; + } + } + break; + + default: + APP_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +/** + * @brief Called by profile client layer, when write result arrived. + * @param[in] conn_id: connection ID. + * @param[in] type: write type + * @param[in] handle: handle of the value in write request. + * @param[in] cause: the write result. + * @param[in] credits: write commands credit. + * @retval void + */ +static void ancs_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_ANCS_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ancs_table[conn_id].hdl_cache; + cb_data.cb_type = ANCS_CLIENT_CB_TYPE_WRITE_RESULT; + + APP_PRINT_INFO2("ancs_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE_CCCD]) + { + if (ancs_table[conn_id].write_notify_value == 0) + { + cb_data.cb_content.write_result.type = ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_DISABLE; + } + else + { + cb_data.cb_content.write_result.type = ANCS_WRITE_NOTIFICATION_SOURCE_NOTIFY_ENABLE; + } + } + else if (handle == hdl_cache[HDL_ANCS_DATA_SOURCE_CCCD]) + { + if (ancs_table[conn_id].write_notify_value == 0) + { + cb_data.cb_content.write_result.type = ANCS_WRITE_DATA_SOURCE_NOTIFY_DISABLE; + } + else + { + cb_data.cb_content.write_result.type = ANCS_WRITE_DATA_SOURCE_NOTIFY_ENABLE; + } + } + else if (handle == hdl_cache[HDL_ANCS_CONTROL_POINT]) + { + cb_data.cb_content.write_result.type = ANCS_WRITE_CONTROL_POINT; + } + else + { + return; + } + + if (ancs_client_cb) + { + (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data); + } + return; +} +/** + * @brief Called by profile client layer, when notification or indication arrived. + * @param[in] conn_id: connection ID. + * @param[in] notify: Whether the data is notification + * @param[in] handle: handle of the value in received data. + * @param[in] value_size: size of the value in received data. + * @param[in] p_value: pointer to the value in received data. + * @retval APP_RESULT_SUCCESS procedure OK. + * @retval other procedure exception. + */ +static T_APP_RESULT ancs_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_ANCS_CB_DATA cb_data; + uint16_t *hdl_cache; + + hdl_cache = ancs_table[conn_id].hdl_cache; + cb_data.cb_type = ANCS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_ANCS_DATA_SOURCE]) + { + cb_data.cb_content.notify_data.type = ANCS_FROM_DATA_SOURCE; + cb_data.cb_content.notify_data.value_size = value_size; + cb_data.cb_content.notify_data.p_value = p_value; + } + else if (handle == hdl_cache[HDL_ANCS_NOTIFICATION_SOURCE]) + { + cb_data.cb_content.notify_data.type = ANCS_FROM_NOTIFICATION_SOURCE; + cb_data.cb_content.notify_data.value_size = value_size; + cb_data.cb_content.notify_data.p_value = p_value; + } + else + { + return APP_RESULT_SUCCESS; + } + + if (ancs_client_cb) + { + app_result = (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data); + } + + return app_result; +} + +/** + * @brief Called by profile client layer, when one LE link is disconnected. + * @param[in] conn_id: connection ID. + * @retval void + */ +static void ancs_client_disc_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("gap_client_disc_cb."); + memset(&ancs_table[conn_id], 0, sizeof(T_ANCS_LINK)); + if (ancs_client_cb) + { + T_ANCS_CB_DATA cb_data; + cb_data.cb_type = ANCS_CLIENT_CB_TYPE_DISCONNECT_INFO; + (*ancs_client_cb)(ancs_client_id, conn_id, &cb_data); + } + return; +} +/** + * @brief ANCS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS ancs_cbs = +{ + ancs_client_discover_state_cb, //!< Discovery State callback function pointer + ancs_client_discover_result_cb, //!< Discovery result callback function pointer + NULL, //!< Read response callback function pointer + ancs_client_write_result_cb, //!< Write result callback function pointer + ancs_client_notify_ind_cb, //!< Notify Indicate callback function pointer + ancs_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add ancs client. + * + * @param[in] app_cb Callbackto notify client read/write/notify/indicate events. + * @param[in] link_num Initialize link number + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void ancs_init(uint8_t link_num) + { + ancs_client = ancs_add_client(ancs_client_cb, link_num); + } + * \endcode + */ +T_CLIENT_ID ancs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > ANCS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("ancs_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&ancs_client_id, &ancs_cbs)) + { + ancs_client_id = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("ancs_add_client Fail !!!"); + return ancs_client_id; + } + APP_PRINT_INFO1("ancs_add_client: client ID %d", ancs_client_id); + + /* register callback for profile to inform application that some events happened. */ + ancs_client_cb = app_cb; + ancs_link_num = link_num; + size = ancs_link_num * sizeof(T_ANCS_LINK); + ancs_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return ancs_client_id; +} + diff --git a/src/ble/profile/client/bas_client.c b/src/ble/profile/client/bas_client.c new file mode 100644 index 0000000..3f20ee0 --- /dev/null +++ b/src/ble/profile/client/bas_client.c @@ -0,0 +1,613 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bas_client.c + * @brief + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +#define GATT_UUID_BATTERY 0x180F +#define GATT_UUID_CHAR_BAS_LEVEL 0x2A19 +/** + * @brief BAS client Link control block defination. + */ +typedef struct +{ + T_BAS_DISC_STATE disc_state; + bool write_notify_value; + uint16_t properties; + uint16_t hdl_cache[HDL_BAS_CACHE_LEN]; +} T_BAS_LINK, *P_BAS_LINK; + +static P_BAS_LINK bas_table; +static uint8_t bas_link_num; + +/**< BAS client ID. */ +static T_CLIENT_ID bas_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from BAS client layer. */ +static P_FUN_GENERAL_APP_CB bas_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of battery service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = bas_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool bas_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("bas_start_discovery"); + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&bas_table[conn_id], 0, sizeof(T_BAS_LINK)); + bas_table[conn_id].disc_state = DISC_BAS_START; + if (client_by_uuid_srv_discovery(conn_id, bas_client, + GATT_UUID_BATTERY) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read battery level. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = false; + ret = bas_read_battery_level(conn_id); + ...... + } + * \endcode + */ +bool bas_read_battery_level(uint8_t conn_id) +{ + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_read_battery_level: failed invalid conn_id %d", conn_id); + return false; + } + if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL]) + { + uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL]; + if (client_attr_read(conn_id, bas_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + PROFILE_PRINT_ERROR0("bas_read_battery_level: false handle = 0"); + return false; +} +/** + * @brief Used by application, to set the notification flag. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_bascccd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool notify = p_parse_value->dw_param[1]; + bool ret; + ret = bas_set_notify(conn_id, notify); + ...... + } + * \endcode + */ +bool bas_set_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_set_notify: failed invalid conn_id %d", conn_id); + return false; + } + if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]) + { + uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, bas_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + bas_table[conn_id].write_notify_value = notify; + return true; + } + } + PROFILE_PRINT_ERROR0("bas_set_notify: false handle = 0"); + return false; +} + +/** + * @brief Used by application, to read the notification flag. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_basread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = false; + ret = bas_read_notify(conn_id); + ...... + } + * \endcode + */ +bool bas_read_notify(uint8_t conn_id) +{ + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_read_notify: failed invalid conn_id %d", conn_id); + return false; + } + if (bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]) + { + uint16_t handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]; + if (client_attr_read(conn_id, bas_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + PROFILE_PRINT_ERROR0("bas_read_battery_level: false handle = 0"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_bashdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_BAS_CACHE_LEN]; + bool ret = bas_get_hdl_cache(conn_id, hdl_cache, + sizeof(uint16_t) * HDL_BAS_CACHE_LEN); + + ...... + } + * \endcode + */ +bool bas_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (bas_table[conn_id].disc_state != DISC_BAS_DONE) + { + PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid state %d", bas_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_BAS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("bas_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, bas_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_BAS_FLAG) + { + bas_set_hdl_cache(conn_id, app_srvs_table.bas_hdl_cache, sizeof(uint16_t) * HDL_BAS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool bas_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (bas_table[conn_id].disc_state != DISC_BAS_IDLE) + { + PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid state %d", bas_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_BAS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("bas_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(bas_table[conn_id].hdl_cache, p_hdl_cache, len); + bas_table[conn_id].disc_state = DISC_BAS_DONE; + return true; +} + +static bool bas_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("bas_start_char_discovery"); + start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START]; + end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END]; + if (client_all_char_discovery(conn_id, bas_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool bas_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("bas_start_char_descriptor_discovery"); + start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL]; + end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, bas_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void bas_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_BAS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = BAS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("bas_client_discover_state_cb: discovery_state = %d", discovery_state); + if (bas_table[conn_id].disc_state == DISC_BAS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START] != 0) + || (bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END] != 0)) + { + if (bas_start_char_discovery(conn_id) == false) + { + bas_table[conn_id].disc_state = DISC_BAS_FAILED; + cb_flag = true; + } + } + /* No BAS handle found. Discover procedure complete. */ + else + { + bas_table[conn_id].disc_state = DISC_BAS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + if (bas_table[conn_id].properties & GATT_CHAR_PROP_NOTIFY) + { + //discovery cccd + if (bas_start_char_descriptor_discovery(conn_id) == false) + { + bas_table[conn_id].disc_state = DISC_BAS_FAILED; + cb_flag = true; + } + } + else + { + bas_table[conn_id].disc_state = DISC_BAS_DONE; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + bas_table[conn_id].disc_state = DISC_BAS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + bas_table[conn_id].disc_state = DISC_BAS_FAILED; + cb_flag = true; + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && bas_client_cb) + { + cb_data.cb_content.disc_state = bas_table[conn_id].disc_state; + (*bas_client_cb)(bas_client, conn_id, &cb_data); + } + return; +} + + +static void bas_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("bas_client_discover_result_cb: result_type = %d", result_type); + if (bas_table[conn_id].disc_state == DISC_BAS_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + bas_table[conn_id].hdl_cache[HDL_BAS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + uint16_t handle; + handle = result_data.p_char_uuid16_disc_data->value_handle; + if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_BAS_LEVEL) + { + bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL] = handle; + bas_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD] = + result_data.p_char_desc_uuid16_disc_data->handle; + } + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void bas_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_BAS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = bas_table[conn_id].hdl_cache; + cb_data.cb_type = BAS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("bas_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]) + { + if (bas_table[conn_id].write_notify_value) + { + cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_DISABLE; + } + } + else + { + return; + } + + if (bas_client_cb) + { + (*bas_client_cb)(bas_client, conn_id, &cb_data); + } + return; +} + +static void bas_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_BAS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = bas_table[conn_id].hdl_cache; + cb_data.cb_type = BAS_CLIENT_CB_TYPE_READ_RESULT; + + PROFILE_PRINT_INFO2("bas_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]) + { + cb_data.cb_content.read_result.type = BAS_READ_NOTIFY; + if (cause == GAP_SUCCESS) + { + uint16_t ccc_bit; + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("bas_client_read_result_cb: invalid cccd len %d", value_size); + return; + } + LE_ARRAY_TO_UINT16(ccc_bit, p_value); + + if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + cb_data.cb_content.read_result.data.notify = true; + } + else + { + cb_data.cb_content.read_result.data.notify = false; + } + } + } + else if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL]) + { + cb_data.cb_content.read_result.type = BAS_READ_BATTERY_LEVEL; + if (cause == GAP_SUCCESS) + { + if (value_size != 1) + { + PROFILE_PRINT_ERROR1("bas_client_read_result_cb: invalid battery value len %d", value_size); + return; + } + cb_data.cb_content.read_result.data.battery_level = *p_value; + } + } + else + { + return; + } + + if (bas_client_cb) + { + (*bas_client_cb)(bas_client, conn_id, &cb_data); + } + return; +} + +static T_APP_RESULT bas_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_BAS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + + hdl_cache = bas_table[conn_id].hdl_cache; + cb_data.cb_type = BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL]) + { + cb_data.cb_content.notify_data.battery_level = *p_value; + } + else + { + return APP_RESULT_SUCCESS; + } + + if (bas_client_cb) + { + app_result = (*bas_client_cb)(bas_client, conn_id, &cb_data); + } + + return app_result; +} + +static void bas_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("bas_client_disc_cb."); + if (conn_id >= bas_link_num) + { + PROFILE_PRINT_ERROR1("bas_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&bas_table[conn_id], 0, sizeof(T_BAS_LINK)); + return; +} +/** + * @brief BAS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS bas_client_cbs = +{ + bas_client_discover_state_cb, //!< Discovery State callback function pointer + bas_client_discover_result_cb, //!< Discovery result callback function pointer + bas_client_read_result_cb, //!< Read response callback function pointer + bas_client_write_result_cb, //!< Write result callback function pointer + bas_client_notify_ind_cb, //!< Notify Indicate callback function pointer + bas_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add bas client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + bas_client_id = bas_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID bas_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > BAS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("bas_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&bas_client, &bas_client_cbs)) + { + bas_client = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("bas_add_client:register fail"); + return bas_client; + } + PROFILE_PRINT_INFO1("bas_add_client: client id %d", bas_client); + + /* register callback for profile to inform application that some events happened. */ + bas_client_cb = app_cb; + bas_link_num = link_num; + size = bas_link_num * sizeof(T_BAS_LINK); + bas_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return bas_client; +} + diff --git a/src/ble/profile/client/bls_client.c b/src/ble/profile/client/bls_client.c new file mode 100644 index 0000000..a8bdfa1 --- /dev/null +++ b/src/ble/profile/client/bls_client.c @@ -0,0 +1,547 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file bls_client.c + * @brief Source file for client of internet protocol support service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-05 + * @version v1.0 + * ************************************************************************************* + */ +#include "string.h" +#include "trace.h" +#include "os_mem.h" +#include "bls_client.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_BLS_DISC_STATE disc_state; + bool write_notify_value; + bool write_indicate_value; + uint16_t properties; + uint16_t hdl_cache[HDL_BLS_CACHE_LEN]; +} T_BLS_LINK, *P_BLS_LINK; + +static P_BLS_LINK bls_table; +static uint8_t bls_link_num; + +static T_CLIENT_ID bls_cl_id = CLIENT_PROFILE_GENERAL_ID; +static P_FUN_GENERAL_APP_CB bls_cl_cb = NULL; + +bool bls_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("bls_start_discovery"); + + /* First clear handle cache. */ + memset(&bls_table[conn_id], 0, sizeof(T_BLS_LINK)); + bls_table[conn_id].disc_state = DISC_BLS_START; + if (client_by_uuid_srv_discovery(conn_id, bls_cl_id, + GATT_UUID_BLOOD_PRESSURE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool bls_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("bls_start_char_discovery"); + start_handle = bls_table[conn_id].hdl_cache[HDL_BLS_SRV_START]; + end_handle = bls_table[conn_id].hdl_cache[HDL_BLS_SRV_END]; + if (client_all_char_discovery(conn_id, bls_cl_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool bls_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("bls_start_char_descriptor_discovery"); + start_handle = bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT]; + end_handle = bls_table[conn_id].hdl_cache[HDL_BLS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, bls_cl_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void bls_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_BLS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = BLS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("bls_client_discover_state_cb: discovery_state = %d", discovery_state); + if (bls_table[conn_id].disc_state == DISC_BLS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((bls_table[conn_id].hdl_cache[HDL_BLS_SRV_START] != 0) + || (bls_table[conn_id].hdl_cache[HDL_BLS_SRV_END] != 0)) + { + if (bls_start_char_discovery(conn_id) == false) + { + bls_table[conn_id].disc_state = DISC_BLS_FAILED; + cb_flag = true; + } + } + /* No BLS handle found. Discover procedure complete. */ + else + { + bls_table[conn_id].disc_state = DISC_BLS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + if (bls_table[conn_id].properties & GATT_CHAR_PROP_READ) + { + //discovery cccd + if (bls_start_char_descriptor_discovery(conn_id) == false) + { + bls_table[conn_id].disc_state = DISC_BLS_FAILED; + cb_flag = true; + } + } + else + { + bls_table[conn_id].disc_state = DISC_BLS_DONE; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + bls_table[conn_id].disc_state = DISC_BLS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + bls_table[conn_id].disc_state = DISC_BLS_FAILED; + cb_flag = true; + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && bls_cl_cb) + { + cb_data.cb_content.disc_state = bls_table[conn_id].disc_state; + (*bls_cl_cb)(bls_cl_id, conn_id, &cb_data); + } + return; +} + + +static void bls_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("bls_client_discover_result_cb: result_type = %d", result_type); + if (bls_table[conn_id].disc_state == DISC_BLS_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + bls_table[conn_id].hdl_cache[HDL_BLS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + bls_table[conn_id].hdl_cache[HDL_BLS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + uint16_t handle; + handle = result_data.p_char_uuid16_disc_data->value_handle; + if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_BLP_MEASUREMENT) + { + bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT] = handle; + bls_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + else if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_INTERMEDIATE_CUFF_PRESSURE) + { + bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE] = handle; + bls_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } +#endif + else if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_BLP_FEATURE) + { + bls_table[conn_id].hdl_cache[HDL_BLS_BLP_FEATURE] = handle; + bls_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + uint16_t handle; + handle = result_data.p_char_desc_uuid16_disc_data->handle; + if ((handle > bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT]) + && (handle < bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE])) + { + bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD] = handle; + } +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + else if ((handle > bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE]) + && (handle < bls_table[conn_id].hdl_cache[HDL_BLS_BLP_FEATURE])) + { + bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD] = handle; + } +#endif + } + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void bls_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_BLS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = bls_table[conn_id].hdl_cache; + cb_data.cb_type = BLS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("bls_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD]) + { + if (bls_table[conn_id].write_indicate_value) + { + cb_data.cb_content.write_result.type = BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_DISABLE; + } + } +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + else if (handle == hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD]) + { + if (bls_table[conn_id].write_notify_value) + { + cb_data.cb_content.write_result.type = BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_DISABLE; + } + } +#endif + else + { + return; + } + + if (bls_cl_cb) + { + (*bls_cl_cb)(bls_cl_id, conn_id, &cb_data); + } + return; +} + +static void bls_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_BLS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = bls_table[conn_id].hdl_cache; + cb_data.cb_type = BLS_CLIENT_CB_TYPE_READ_RESULT; + + PROFILE_PRINT_INFO2("bls_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + if (handle == hdl_cache[HDL_BLS_BLP_FEATURE]) + { + cb_data.cb_content.read_result.type = BLS_READ_BLP_FEATURE; + if (cause == GAP_SUCCESS) + { + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("bls_client_read_result_cb: invalid battery value len %d", value_size); + return; + } + uint16_t blp_feature; + LE_STREAM_TO_UINT16(blp_feature, p_value); + cb_data.cb_content.read_result.data.blood_pressure_feature = blp_feature; + } + } + else + { + return; + } + + if (bls_cl_cb) + { + (*bls_cl_cb)(bls_cl_id, conn_id, &cb_data); + } + return; +} + +static T_APP_RESULT bls_client_notify_indicate_cb(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_BLS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + + hdl_cache = bls_table[conn_id].hdl_cache; + + if (handle == hdl_cache[HDL_BLS_BLP_MEASUREMENT]) + { + cb_data.cb_type = BLS_CLIENT_CB_TYPE_IND_BLOOD_PRESS_MEAS; + } +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + else if (handle == hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE]) + { + cb_data.cb_type = BLS_CLIENT_CB_TYPE_NIFY_INTER_CUFF_PRESS; + } +#endif + + if ((handle == hdl_cache[HDL_BLS_BLP_MEASUREMENT]) +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + || (handle == hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE]) +#endif + ) + { + T_BLOOD_PRESSURE_MEASURMENT blp_meas_value = {0}; + + LE_STREAM_TO_UINT8(blp_meas_value.bp_meas_flag, p_value); + + uint8_t bp_meas_systolic_value[2]; + uint8_t bp_meas_diastolic_value[2]; + uint8_t bp_meas_map_value[2]; + STREAM_TO_ARRAY(bp_meas_systolic_value, p_value, 2); + STREAM_TO_ARRAY(bp_meas_diastolic_value, p_value, 2); + STREAM_TO_ARRAY(bp_meas_map_value, p_value, 2); + + memcpy(blp_meas_value.bp_meas_compound_value.bp_meas_systolic_value, bp_meas_systolic_value, 2); + memcpy(blp_meas_value.bp_meas_compound_value.bp_meas_diastolic_value, bp_meas_diastolic_value, 2); + memcpy(blp_meas_value.bp_meas_compound_value.bp_meas_map_value, bp_meas_map_value, 2); + + if (blp_meas_value.bp_meas_flag & BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT) + { + LE_STREAM_TO_UINT16(blp_meas_value.time_stamp.year, p_value); + LE_STREAM_TO_UINT8(blp_meas_value.time_stamp.month, p_value); + LE_STREAM_TO_UINT8(blp_meas_value.time_stamp.day, p_value); + LE_STREAM_TO_UINT8(blp_meas_value.time_stamp.hours, p_value); + LE_STREAM_TO_UINT8(blp_meas_value.time_stamp.minutes, p_value); + LE_STREAM_TO_UINT8(blp_meas_value.time_stamp.seconds, p_value); + } + + if (blp_meas_value.bp_meas_flag & BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT) + { + uint8_t bp_meas_pulse_rate[2]; + STREAM_TO_ARRAY(bp_meas_pulse_rate, p_value, 2); + memcpy(blp_meas_value.bp_meas_pulse_rate, bp_meas_pulse_rate, sizeof(SFLOAT)); + } + + if (blp_meas_value.bp_meas_flag & BLS_FLAG_MEASUREMENT_USER_ID_BIT) + { + LE_STREAM_TO_UINT8(blp_meas_value.bp_meas_user_id, p_value); + } + + if (blp_meas_value.bp_meas_flag & BLS_FLAG_MEASUREMENT_STATUS_BIT) + { + uint16_t bp_meas_status; + LE_STREAM_TO_UINT16(bp_meas_status, p_value); + memcpy(&blp_meas_value.bp_meas_status, &bp_meas_status, sizeof(T_BLOOD_PRESSUREE_MEAS_STATUS)); + } + + memcpy(&cb_data.cb_content.blp_meas_notify_indicate_data.blood_presure_mesaurment, &blp_meas_value, + sizeof(T_BLOOD_PRESSURE_MEASURMENT)); + } + + else + { + return APP_RESULT_SUCCESS; + } + if (bls_cl_cb) + { + app_result = (*bls_cl_cb)(bls_cl_id, conn_id, &cb_data); + } + + return app_result; +} + +static void bls_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("bls_client_disc_cb."); + memset(&bls_table[conn_id], 0, sizeof(T_BLS_LINK)); + return; +} + +bool bls_read_blp_feature(uint8_t conn_id) +{ + if (conn_id >= bls_link_num) + { + PROFILE_PRINT_ERROR1("bls_read_blp_feature: failed invalid conn_id %d", conn_id); + return false; + } + if (bls_table[conn_id].hdl_cache[HDL_BLS_BLP_FEATURE]) + { + uint16_t handle = bls_table[conn_id].hdl_cache[HDL_BLS_BLP_FEATURE]; + if (client_attr_read(conn_id, bls_cl_id, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + PROFILE_PRINT_ERROR0("bls_read_blp_feature: false handle = 0"); + return false; +} + +bool bls_write_notify_indicate(uint8_t conn_id, T_BLS_WRTIE_TYPE write_type) +{ + if (conn_id >= bls_link_num) + { + PROFILE_PRINT_ERROR1("bls_set_notify_indicate: failed invalid conn_id %d", conn_id); + return false; + } + switch (write_type) + { + case BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_ENABLE: + { + if (bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD]) + { + uint16_t handle = bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD]; + PROFILE_PRINT_ERROR1("bls_set_notify_indicate: handle %d", handle); + + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = 1; + if (client_attr_write(conn_id, bls_cl_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + bls_table[conn_id].write_notify_value = 1; + return true; + } + } + PROFILE_PRINT_ERROR0("bls_set_notify: false handle = 0"); + return false; + } + + case BLS_WRITE_NOTIFY_INTER_CUFF_PRESS_DISABLE: + { + if (bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD]) + { + uint16_t handle = bls_table[conn_id].hdl_cache[HDL_BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = 0; + if (client_attr_write(conn_id, bls_cl_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + bls_table[conn_id].write_notify_value = 0; + return true; + } + } + PROFILE_PRINT_ERROR0("bls_set_notify: false handle = 0"); + return false; + } + + case BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_ENABLE: + { + if (bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD]) + { + uint16_t handle = bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD]; + PROFILE_PRINT_ERROR1("bls_set_notify_indicate: handle %d", handle); + + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = 2; + if (client_attr_write(conn_id, bls_cl_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + bls_table[conn_id].write_indicate_value = 1; + return true; + } + } + PROFILE_PRINT_ERROR0("bls_set_notify: false handle = 0"); + return false; + } + + case BLS_WRITE_INDICATE_BLOOD_PRESS_MEAS_DISABLE: + { + if (bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD]) + { + uint16_t handle = bls_table[conn_id].hdl_cache[HDL_BLS_BLP_MEASUREMENT_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = 0; + if (client_attr_write(conn_id, bls_cl_id, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + bls_table[conn_id].write_indicate_value = 1; + return true; + } + } + PROFILE_PRINT_ERROR0("bls_set_notify: false handle = 0"); + return false; + } + + default: + return false; + + } +} + +/** + * @brief IPS service client callback function pointer. + */ +const T_FUN_CLIENT_CBS bls_cl_cbs = +{ + bls_client_discover_state_cb, //!< Discovery State callback function pointer + bls_client_discover_result_cb, //!< Discovery result callback function pointer + bls_client_read_result_cb, //!< Read response callback function pointer + bls_client_write_result_cb, //!< Write result callback function pointer + bls_client_notify_indicate_cb, //!< Notify Indicate callback function pointer + bls_client_disc_cb //!< Link disconnection callback function pointer +}; + +T_CLIENT_ID bls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > BLS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("bls_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&bls_cl_id, &bls_cl_cbs)) + { + bls_cl_id = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("bls_add_client: register fail"); + return bls_cl_id; + } + + PROFILE_PRINT_INFO1("bls_add_client: client id %d", bls_cl_id); + bls_cl_cb = app_cb; + bls_link_num = link_num; + size = bls_link_num * sizeof(T_BLS_LINK); + bls_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return bls_cl_id; +} diff --git a/src/ble/profile/client/dfu_client.c b/src/ble/profile/client/dfu_client.c new file mode 100644 index 0000000..62f8ca3 --- /dev/null +++ b/src/ble/profile/client/dfu_client.c @@ -0,0 +1,1343 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dfu_client.c + * @brief dfu service client source file. + * @details + * @author bill + * @date 2017-8-28 + * @version v1.0 + ****************************************************************************** + * @attention + *

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    + ****************************************************************************** + */ +#include +#include +#include "gap_conn_le.h" +#include "gap_scan.h" +#include "aes_api.h" +#include "mem_types.h" +#include "os_mem.h" +#include "os_sched.h" +#include "otp.h" +#include "dfu_api.h" +#include "patch_header_check.h" +#include "trace.h" +#include "dfu_client.h" + + +/*============================================================================* + * Macros + *============================================================================*/ + +/** + * @brief dfu client Link control block definition. + */ +typedef struct +{ + T_DFU_DISC_STATE disc_state; + uint16_t properties; //for what + uint16_t hdl_cache[HDL_DFU_CACHE_LEN]; +} T_DFU_LINK, *P_DFU_LINK; + + +/*============================================================================* + * Local varibles + *============================================================================*/ +static P_DFU_LINK dfu_table; +static uint8_t dfu_link_num; + +/**< Callback used to send data to app from Dfu client layer. */ +static P_FUN_GENERAL_APP_CB pf_dfu_client_cb = NULL; +static P_FUN_GENERAL_APP_CB pf_dfu_client_app_info_cb = NULL; + +P_FUN_DFU_CLIENT_INIT_APP_CB pf_dfu_client_init __attribute__((weak)) = NULL; +/**< Dfu client ID. */ +static T_CLIENT_ID dfu_client = CLIENT_PROFILE_GENERAL_ID; + +/* for record data that target send by notification*/ +static uint8_t dfu_temp_cp_notify_msg[20]; //for cache control point masg +static uint8_t dfu_temp_cp_notify_msg_len; + +static T_DFU_CTX dfu_client_ctx; +static T_DFU_CLIENT_FSM_WRITE dfu_fsm_write = DFU_FSM_WRITE_IDLE; +static uint8_t buf_check_retry_cnt = 0; + +const uint8_t dfu_data_uuid[16] = {GATT_UUID128_DFU_DATA}; +const uint8_t dfu_control_point_uuid[16] = {GATT_UUID128_DFU_CONTROL_POINT}; +const uint8_t dfu_service_uuid[16] = {GATT_UUID128_DFU_SERVICE}; + + +/*============================================================================* + * Functions + *============================================================================*/ + +static void swap_buf(uint8_t *dst, const uint8_t *src, uint16_t len) +{ + int i; + if (dst == NULL || src == NULL) + { + return; + } + + for (i = 0; i < len; i++) + { + dst[len - 1 - i] = src[i]; + } +} + +/** + * @brief get 16bit data swapped. + * + * @param val 16bit data to be swapped. + * @return value after being swapped. +*/ +static uint16_t swap_16(uint16_t val) +{ + uint16_t result; + + /* Idiom Recognition for REV16 */ + result = ((val & 0xff) << 8) | ((val & 0xff00) >> 8); + + return result; +} + +bool dfu_encrypt(uint8_t image[16]) +{ + bool ret; + uint8_t image_tmp[16] = {0}; + swap_buf(image_tmp, image, 16); + ret = aes256_ecb_encrypt_msb2lsb(image_tmp, (uint8_t *)OTP->aes_key, image_tmp); + swap_buf(image, image_tmp, 16); + return ret; +} + +uint16_t dfu_client_temp_crc_cal(uint8_t *p_temp, uint32_t length, uint16_t init_cksum16) +{ + uint16_t temp_checksum16 = init_cksum16; + uint16_t *p16 = (uint16_t *)p_temp; + + for (uint32_t i = 0; i < length / 2; ++i) + { + temp_checksum16 = temp_checksum16 ^ (*p16); + ++p16; + } + return temp_checksum16; +} + +uint16_t dfu_client_buf_crc_cal(uint8_t *buf, uint32_t length) +{ + uint16_t checksum16 = dfu_client_temp_crc_cal(buf, length, 0); + return swap_16(checksum16); +} + +void dfu_client_set_dfu_ctx_value(T_DFU_SET_CLIENT_CTX_TYPE type, void *p_value) +{ + DFU_PRINT_INFO1("dfu_client_set_dfu_ctx_value: type=%d", type); + if (p_value) + { + switch (type) + { + case DFU_SET_FEATURE: + dfu_client_ctx.dfu_feature = *(T_DFU_CLIENT_FEATURE_TYPE *)p_value; + break; + case DFU_SET_MODE_VALUE: + dfu_client_ctx.ota_mode.value = *(uint8_t *)p_value; + break; + case DFU_SET_MAX_BUF_SIZE: + dfu_client_ctx.max_buffer_size = *(uint32_t *)p_value; + break; + case DFU_SET_DFU_IMG_ADDR: + dfu_client_ctx.dfu_img_start_addr = *(uint32_t *)p_value; + DFU_PRINT_INFO1("dfu_client_set_dfu_ctx_value: dfu_img_start_addr=0x%x", + dfu_client_ctx.dfu_img_start_addr); + break; + case DFU_SET_DFU_IMG_VER: + dfu_client_ctx.dfu_img_version = *(uint32_t *)p_value; + break; + case DFU_SET_NORMAL_OTA_FLAG: + dfu_client_ctx.is_normal_ota = *(bool *)p_value; + break; + default: + break; + } + } +} + +/** + * @brief Used by application, to set the handles in Dfu handle cache. + * @param handle_type: handle types of this specific profile. + * @param handle_value: handle value to set. + * @retval true--set success. + * flase--set failed. + */ +bool dfu_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= dfu_link_num) + { + DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (dfu_table[conn_id].disc_state != DISC_DFU_IDLE) + { + DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid state %d", + dfu_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_DFU_CACHE_LEN) + { + DFU_PRINT_ERROR1("dfu_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(dfu_table[conn_id].hdl_cache, p_hdl_cache, len); + dfu_table[conn_id].disc_state = DISC_DFU_DONE; + return true; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dfu_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= dfu_link_num) + { + DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (dfu_table[conn_id].disc_state != DISC_DFU_DONE) + { + DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid state %d", + dfu_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_DFU_CACHE_LEN) + { + DFU_PRINT_ERROR1("dfu_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, dfu_table[conn_id].hdl_cache, len); + return true; +} + + +/** + * @brief Used by application, to start the discovery procedure of Dfu server. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_start_discovery(uint8_t conn_id) +{ + if (conn_id >= dfu_link_num) + { + DFU_PRINT_ERROR1("dfu_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + + DFU_PRINT_INFO0("dfu_client_start_discovery!"); + /* First clear handle cache. */ + memset(&dfu_table[conn_id], 0, sizeof(T_DFU_LINK)); + dfu_table[conn_id].disc_state = DISC_DFU_START; + if (client_by_uuid128_srv_discovery(conn_id, dfu_client, + (uint8_t *)dfu_service_uuid) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + + +/** + * @brief Used by application, read data from server by using handles. + * @param readCharType: one of characteristic that has the readable property. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_read_by_handle(uint8_t conn_id, T_DFU_READ_TYPE type) +{ + bool hdl_valid = false; + uint16_t handle = 0; + + if (conn_id >= dfu_link_num) + { + DFU_PRINT_ERROR1("dfu_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + switch (type) + { + case DFU_READ_CP_CCCD: + if (dfu_table[conn_id].hdl_cache[DFU_READ_CP_CCCD]) + { + handle = dfu_table[conn_id].hdl_cache[DFU_READ_CP_CCCD]; + hdl_valid = true; + } + break; + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, dfu_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + DFU_PRINT_INFO1("dfu_client_read_by_handle fail! type=%d", type); + return false; +} + +/** + * @brief Used by application, read data from server by using UUIDs. + * @param readCharType: one of characteristic that has the readable property. + * @retval true--send request to upper stack success. + * false--send request to upper stack failed. + */ +bool dfu_client_read_by_uuid(uint8_t conn_id, T_DFU_READ_TYPE type) +{ + uint16_t start_handle; + uint16_t end_handle; + uint16_t uuid16; + switch (type) + { + case DFU_READ_CP_CCCD: + start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP] + 1; + end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END]; + uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; + break; + default: + return false; + } + + if (client_attr_read_using_uuid(conn_id, dfu_client, start_handle, end_handle, uuid16, + NULL) == GAP_CAUSE_SUCCESS) + { + return true; + } + DFU_PRINT_INFO1("dfu_client_read_by_uuid fail! type=%d", type); + return false; +} + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param command: 0--disable the notification, 1--enable the notification. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_cp_cccd_set(uint8_t conn_id, bool command) +{ + uint16_t handle; + uint16_t length; + uint8_t *pdata; + uint16_t cccd_value; + handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD]; + if (handle) + { + cccd_value = command ? 1 : 0; + length = sizeof(uint16_t); + pdata = (uint8_t *)&cccd_value; + if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_REQ, handle, length, + pdata) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + DFU_PRINT_INFO1("dfu_client_cp_cccd_set fail! handle=0x%x", handle); + return false; +} + +/** + * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic. + * @param ctl_pnt_ptr: pointer of control point data to write. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_cp_write(uint8_t conn_id, uint8_t *pdata, uint16_t length) +{ + uint16_t handle; + dfu_fsm_write = DFU_FSM_WRITE_WAIT_WRITE_RESP; + handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP]; + if (handle) + { + if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_REQ, handle, length, + pdata) == GAP_CAUSE_SUCCESS) + { + DFU_PRINT_INFO3("==>dfu_client_cp_write success: conn_id=%d, opcode=0x%x, len=%d", + conn_id, pdata[0], length); + return true; + } + } + + DFU_PRINT_INFO1("==>dfu_client_cp_write fail! handle=0x%x", handle); + return false; +} + +/** + * @brief Used internal, to send write request to peer server's V5 Control Point Characteristic. + * @param ctl_pnt_ptr: pointer of control point data to write. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +bool dfu_client_data_write(uint8_t conn_id, uint8_t *pdata, uint16_t length) +{ + uint16_t handle; + dfu_fsm_write = DFU_FSM_WRITE_DFU_DATA; + handle = dfu_table[conn_id].hdl_cache[HDL_DFU_DATA]; + if (handle) + { + if (client_attr_write(conn_id, dfu_client, GATT_WRITE_TYPE_CMD, handle, length, + pdata) == GAP_CAUSE_SUCCESS) + { + DFU_PRINT_INFO2("==>dfu_client_data_write success: conn_id=%d, len=%d", conn_id, length); + return true; + } + } + + DFU_PRINT_INFO1("dfu_client_data_write fail! handle=0x%x", handle); + return false; +} + +/** + * @brief Used internal, start the discovery of Dfu characteristics. + * NOTE--user can offer this interface for application if required. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +static bool dfu_client_start_all_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + DFU_PRINT_INFO0("dfu_client_start_all_char_discovery"); + start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START]; + end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END]; + return (client_all_char_discovery(conn_id, dfu_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS); +} + +/** + * @brief Used internal, start the discovery of Dfu characteristics descriptor. + * NOTE--user can offer this interface for application if required. + * @retval true--send request to upper stack success. + * flase--send request to upper stack failed. + */ +static bool dfu_client_start_all_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + DFU_PRINT_INFO0("dfu_client_start_all_char_descriptor_discovery"); + start_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_CP]; + end_handle = dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END]; + return (client_all_char_descriptor_discovery(conn_id, dfu_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS); +} + + +/** + * @brief Called by profile client layer, when discover state of discovery procedure changed. + * @param discoveryState: current service discovery state. + * @retval ProfileResult_Success--procedure OK. + * other--procedure exception. + */ +static void dfu_client_disc_state_cb(uint8_t conn_id, T_DISCOVERY_STATE disc_state) +{ + bool cb_flag = false; + + T_DFU_CLIENT_CB_DATA cb_data; + memset(&cb_data, 0, sizeof(T_DFU_CLIENT_CB_DATA)); + cb_data.cb_type = DFU_CLIENT_CB_TYPE_DISC_STATE; + + DFU_PRINT_INFO1("dfu_client_disc_state_cb: disc_state = %d", disc_state); + if (dfu_table[conn_id].disc_state == DISC_DFU_START) + { + switch (disc_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START] != 0) + || (dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END] != 0)) + { + DFU_PRINT_INFO0("GG2 dfu_client_disc_state_cb: Start Find all characteristic!"); + if (dfu_client_start_all_char_discovery(conn_id) == false) + { + cb_data.cb_content.disc_state = DISC_DFU_FAIL; + cb_flag = true; + } + } + /* No dfu service handle found. Discover procedure complete. */ + else + { + cb_data.cb_content.disc_state = DISC_DFU_FAIL; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + + //discovery cccd + if (dfu_client_start_all_char_descriptor_discovery(conn_id) == false) + { + dfu_table[conn_id].disc_state = DISC_DFU_FAIL; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + /* Find the next descriptor to be discovered. */ + cb_data.cb_content.disc_state = DISC_DFU_DONE; + cb_flag = true; + break; + default: + DFU_PRINT_INFO0("dfu_client_disc_state_cb: Invalid Discovery State!"); + break; + } + } + + if (cb_data.cb_content.disc_state == DISC_DFU_DONE) + { + /* Discovery Simple BLE service procedure successfully done. */ + DFU_PRINT_INFO0("==>dfu_client_disc_state_cb: discover procedure done."); + if (dfu_client_cp_cccd_set(conn_id, 1)) //enable server notification + { + dfu_fsm_write = DFU_FSM_WRITE_CCCD_ENABLE; + DFU_PRINT_INFO0("==>dfu_client_disc_state_cb: Enable CCCD."); + } + } + else if (cb_data.cb_content.disc_state == DISC_DFU_FAIL) + { + /* Discovery Request failed. */ + DFU_PRINT_INFO0("==>dfu client hdl msg: discover request failed."); + } + else + { + //don't handle type + } + + /* Send discover state to application if needed. */ + if (cb_flag && pf_dfu_client_cb) + { + (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data); + } +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param resultType: indicate which type of value discovered in service discovery procedure. + * @param resultData: value discovered. + * @retval ProfileResult_Success--procedure OK. + * other--procedure exception. + */ +static void dfu_client_disc_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: result_type=%d", result_type); + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + /* send service handle range to application. */ + DFU_PRINT_INFO2("==>dfu_client_disc_result_cb: Primary service Found! Set dfu start_handle=0x%4x, end_handle=0x%4x", + result_data.p_srv_disc_data->att_handle, result_data.p_srv_disc_data->end_group_handle); + dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_START] = result_data.p_srv_disc_data->att_handle; + dfu_table[conn_id].hdl_cache[HDL_DFU_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + case DISC_RESULT_CHAR_UUID128: + /* we should inform intrested handles to upper application. */ + if (0 == memcmp(result_data.p_char_uuid128_disc_data->uuid128, dfu_data_uuid, 16)) + { + DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: Set dfu_data handle=0x%4x", + result_data.p_char_uuid128_disc_data->value_handle); + dfu_table[conn_id].hdl_cache[HDL_DFU_DATA] = result_data.p_char_uuid128_disc_data->value_handle; + } + else if (0 == memcmp(result_data.p_char_uuid128_disc_data->uuid128, dfu_control_point_uuid, 16)) + { + DFU_PRINT_INFO1("==>dfu_client_disc_result_cb: Set dfu_control_point handle=0x%4x", + result_data.p_char_uuid128_disc_data->value_handle); + dfu_table[conn_id].hdl_cache[HDL_DFU_CP] = result_data.p_char_uuid128_disc_data->value_handle; + } + break; + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use clientAPI_AllCharDescriptorDiscovery. */ + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == + GATT_UUID_CHAR_CLIENT_CONFIG) //GATT Client Characteristic Configuration descriptors uuid + { + uint16_t temp_handle = result_data.p_char_desc_uuid16_disc_data->handle; + DFU_PRINT_INFO2("==>dfu_client_disc_result_cb: Set dfu_cccd handle=0x%4x, properties=0x%x", + temp_handle, result_data.p_char_uuid16_disc_data->properties); + dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD] = temp_handle; + dfu_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } + break; + default: + DFU_PRINT_INFO0("dfu_client_disc_result_cb: Invalid Discovery Result Type!"); + break; + } +} + +/** + * @brief Called by profile client layer, when read request responsed. + * @param reqResult: read request from peer device success or not. + * @param wHandle: handle of the value in read response. + * @param iValueSize: size of the value in read response. + * @param pValue: pointer to the value in read response. + * @retval ProfileResult_Success--procedure OK. + * other--procedure exception. + */ +static void dfu_client_read_result_cb(uint8_t conn_id, uint16_t cause, uint16_t handle, + uint16_t len, uint8_t *pvalue) +{ + T_DFU_CLIENT_CB_DATA cb_data; + cb_data.cb_type = DFU_CLIENT_CB_TYPE_READ_RESULT; + cb_data.cb_content.read_result.cause = cause; + DFU_PRINT_INFO3("==>dfu_client_read_result_cb: cause=%d, handle=0x%x, size=%d", cause, + handle, len); + /* If read req success, branch to fetch value and send to application. */ + if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD]) + { + cb_data.cb_content.read_result.type = DFU_READ_CP_CCCD; + if (cause == GAP_SUCCESS && len == sizeof(uint16_t)) + { + uint16_t cccd_value; + LE_ARRAY_TO_UINT16(cccd_value, pvalue); + cb_data.cb_content.read_result.data.dfu_cp_cccd = cccd_value & + GATT_CLIENT_CHAR_CONFIG_NOTIFY; + } + } + + /* Inform application the read result. */ + if (pf_dfu_client_cb) + { + (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data); + } +} + +/** + * @brief Called by profile client layer, when write request complete. + * @param reqResult: write request send success or not. + * @retval ProfileResult_Success--procedure OK. + * other--procedure exception. + */ +static void dfu_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, uint16_t handle, + uint16_t cause, uint8_t credits) +{ + T_DFU_CLIENT_CB_DATA cb_data; + cb_data.cb_type = DFU_CLIENT_CB_TYPE_WRITE_RESULT; + cb_data.cb_content.write_result.cause = cause; + + DFU_PRINT_INFO4("==>dfu_client_write_result_cb: cause=%d, handle=0x%x, type=%d, credits=%d", + cause, handle, type, credits); + /* If write req success, branch to fetch value and send to application. */ + if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP_CCCD]) + + { + cb_data.cb_content.write_result.type = DFU_WRITE_CP_CCCD; + } + else if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP]) + { + cb_data.cb_content.write_result.type = DFU_WRITE_CP; + } + else if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_DATA]) + { + cb_data.cb_content.write_result.type = DFU_WRITE_DATA; + } + else + { + DFU_PRINT_ERROR1("==>dfu_client_write_result_cb: invalid handle=0x%x!", handle); + return; + } + + /* Inform application the write result. */ + if (pf_dfu_client_cb) + { + (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data); + } +} + +/** + * @brief Called by profile client layer, when notification or indication arrived. + * @param wHandle: handle of the value in received data. + * @param iValueSize: size of the value in received data. + * @param pValue: pointer to the value in received data. + * @retval ProfileResult_Success--procedure OK. + * other--procedure exception. + */ +static T_APP_RESULT dfu_client_notify_indicate_cb(uint8_t conn_id, bool notify, + uint16_t handle, uint16_t len, uint8_t *pvalue) +{ + T_APP_RESULT app_result = APP_RESULT_REJECT; + T_DFU_CLIENT_CB_DATA cb_data; + + DFU_PRINT_INFO3("==>dfu_client_notify_indicate_cb: handle=0x%x, len=%d, is notify=%d", + handle, len, notify); + if (handle == dfu_table[conn_id].hdl_cache[HDL_DFU_CP]) + { + cb_data.cb_type = DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + cb_data.cb_content.notif_ind_data.type = DFU_RECEIVE_CP_NOTIFY; + cb_data.cb_content.notif_ind_data.value.len = len; + cb_data.cb_content.notif_ind_data.value.pdata = pvalue; + + /* Inform application the notif/ind result. */ + if (pf_dfu_client_cb) + { + (*pf_dfu_client_cb)(dfu_client, conn_id, &cb_data); + } + app_result = APP_RESULT_SUCCESS; + } + + return app_result; +} + +static void dfu_client_disconnect_cb(uint8_t conn_id) +{ + DFU_PRINT_INFO0("dfu_client_disc_cb"); + if (conn_id >= dfu_link_num) + { + DFU_PRINT_ERROR1("dfu_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&dfu_table[conn_id], 0, sizeof(T_DFU_LINK)); + return; +} + +/** + * @brief procedure that client send control point cmd to server. + * @param conn_id: connection id. + * @param opcode: control point opcode. + */ +void dfu_client_process_control_point(uint8_t conn_id, T_DFU_CP_OPCODE opcode) +{ + uint8_t data[DFU_LENGTH_MAX]; + data[0] = opcode; + + DFU_PRINT_INFO1("===>dfu_client_process_control_point: opcode=0x%x", opcode); + switch (opcode) + { + case DFU_OPCODE_START_DFU: //0x1 + { + uint8_t *pheader = (uint8_t *)dfu_client_ctx.dfu_img_start_addr; + dfu_client_ctx.dfu_img_total_length = ((T_IMG_CTRL_HEADER_FORMAT *)pheader)->payload_len + + IMG_HEADER_SIZE; + DFU_PRINT_INFO3("==>dfu_client_process_control_point: START_DFU img_id=0x%x, ic_type=0x%x, dfu_img_total_len=%d", + dfu_client_ctx.dfu_ctrl_header.image_id, + dfu_client_ctx.dfu_ctrl_header.ic_type, + dfu_client_ctx.dfu_img_total_length); + + memcpy(data + 1, pheader, DFU_HEADER_SIZE); + memset(data + 1 + DFU_HEADER_SIZE, 0, 4); + //aes encrypt when ota + if (dfu_client_ctx.ota_mode.mode_flag.aesflg) + { + DFU_PRINT_INFO1("===>Ctrl Header before encryped: %b", TRACE_BINARY(16, data + 1)); + dfu_encrypt(data + 1); + DFU_PRINT_INFO1("===>Ctrl Header after encryped: %b", TRACE_BINARY(16, data + 1)); + } + dfu_client_cp_write(conn_id, data, DFU_LENGTH_START_DFU); + //update offset + dfu_client_ctx.curr_offset = DFU_HEADER_SIZE; + } + break; + case DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: //0x2 + { + LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id); + LE_UINT32_TO_ARRAY(data + 3, dfu_client_ctx.curr_offset); + dfu_client_cp_write(conn_id, data, DFU_LENGTH_RECEIVE_FW_IMAGE_INFO); + } + break; + case DFU_OPCODE_VALID_FW: //0x3 + { + DFU_PRINT_INFO1("===>DFU_OPCODE_VALID_FW: image_id=0x%x", dfu_client_ctx.dfu_ctrl_header.image_id); + LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id); + dfu_client_cp_write(conn_id, data, DFU_LENGTH_VALID_FW); + } + break; + case DFU_OPCODE_ACTIVE_IMAGE_RESET: //0x4 + { + dfu_client_cp_write(conn_id, data, DFU_LENGTH_ACTIVE_IMAGE_RESET); + } + break; + case DFU_OPCODE_SYSTEM_RESET: //0x5 + { + dfu_client_cp_write(conn_id, data, DFU_LENGTH_SYSTEM_RESET); + } + break; + case DFU_OPCODE_REPORT_TARGET_INFO: //0x6 + { + DFU_PRINT_INFO1("===>DFU_OPCODE_REPORT_TARGET_INFO: image_id=0x%x", + dfu_client_ctx.dfu_ctrl_header.image_id); + LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_ctrl_header.image_id); + dfu_client_cp_write(conn_id, data, DFU_LENGTH_REPORT_TARGET_INFO); + } + break; + case DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: //0x7 + { + } + break; + case DFU_OPCODE_BUFFER_CHECK_EN: //0x9 + { + dfu_client_cp_write(conn_id, data, DFU_LENGTH_BUFFER_CHECK_EN); + } + break; + case DFU_OPCODE_REPORT_BUFFER_CRC: //0xa + { + DFU_PRINT_INFO2("===>DFU_OPCODE_REPORT_BUFFER_CRC: dfu_buf_check_size=0x%x, dfu_buf_check_crc_val", + dfu_client_ctx.dfu_buf_check_size, + dfu_client_ctx.dfu_buf_check_crc_val); + + LE_UINT16_TO_ARRAY(data + 1, dfu_client_ctx.dfu_buf_check_size); + LE_UINT16_TO_ARRAY(data + 3, dfu_client_ctx.dfu_buf_check_crc_val); + dfu_client_cp_write(conn_id, data, DFU_LENGTH_REPORT_BUFFER_CRC); + } + break; + case DFU_OPCODE_COPY_IMG: + { + } + break; + default: + break; + } +} + +/** + * @brief procedure that client send image data to server. + * @param conn_id: connection id. + */ +bool dfu_client_push_image(uint8_t conn_id) +{ + uint16_t mtu_size = 0; + uint16_t push_img_size = 0; + uint32_t image_size = 0; + uint8_t *p_dfu_header; + uint8_t *pdata; + + p_dfu_header = (uint8_t *)dfu_client_ctx.dfu_img_start_addr; + //DFU_PRINT_INFO1("==>dfu_client_push_image: p_dfu_header=0x%x", p_dfu_header); + + if (dfu_fsm_write == DFU_FSM_WRITE_WAIT_WRITE_RESP) + { + // in case that the credit is bigger then the buffer check packet num + DFU_PRINT_INFO0("==>dfu_client_push_image fail! Waiting for control point response!"); + return false; + } + + mtu_size = (dfu_client_ctx.mtu_size - 3) & 0xfff0; //mtu size down align 16 bytes + image_size = dfu_client_ctx.dfu_img_total_length - dfu_client_ctx.curr_offset; + push_img_size = (image_size > mtu_size ? mtu_size : image_size); //get min value + DFU_PRINT_INFO3("==>dfu_client_push_image: MIN(mtu_size=%d, img_size=%d)= push_img_size %d", + mtu_size, image_size, push_img_size); + + if (dfu_client_ctx.dfu_pkt_counter == (dfu_client_ctx.dfu_pkt_num - 1) && + !dfu_client_ctx.ota_mode.mode_flag.buf_check_en) + { + push_img_size = dfu_client_ctx.dfu_last_pkt_size; + } + DFU_PRINT_INFO3("==>dfu_client_push_image: push_img_size=%d, curr_offset=%d, dfu_img_total_length=%d", + push_img_size, dfu_client_ctx.curr_offset, dfu_client_ctx.dfu_img_total_length); + + pdata = os_mem_alloc(RAM_TYPE_DATA_ON, push_img_size); //send one packet(mtu size) or left img size + if (pdata == NULL) + { + return false; + } + + memcpy(pdata, p_dfu_header + dfu_client_ctx.curr_offset, push_img_size); + if (dfu_client_ctx.ota_mode.mode_flag.aesflg && dfu_client_ctx.ota_mode.mode_flag.aesmode) + { + uint8_t *ptmp = pdata; + for (uint16_t loop = 0; loop < push_img_size / 16; loop++) //only encrypt 16 bytes align + { + dfu_encrypt(ptmp); + ptmp += 16; + } + } + + if (dfu_client_data_write(conn_id, pdata, push_img_size)) + { + dfu_client_ctx.curr_offset += push_img_size; + + /*Target Enable Buffer Check Case*/ + if (dfu_client_ctx.ota_mode.mode_flag.buf_check_en) //enable buffer check + { + if (!dfu_client_ctx.dfu_pkt_counter) + { + dfu_client_ctx.dfu_buf_check_crc_val = 0; + } + dfu_client_ctx.dfu_pkt_counter++; + dfu_client_ctx.dfu_buf_check_crc_val = dfu_client_temp_crc_cal(pdata, push_img_size, + dfu_client_ctx.dfu_buf_check_crc_val); + /*can do buffer check or not*/ + if (dfu_client_ctx.dfu_pkt_counter == dfu_client_ctx.dfu_pkt_num || + dfu_client_ctx.curr_offset == dfu_client_ctx.dfu_img_total_length) + { + dfu_client_ctx.dfu_buf_check_crc_val = swap_16(dfu_client_ctx.dfu_buf_check_crc_val); + dfu_client_ctx.dfu_buf_check_size = push_img_size + + (dfu_client_ctx.dfu_pkt_counter - 1) * mtu_size; + /*send opcode 0xa*/ + dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_BUFFER_CRC); + dfu_client_ctx.dfu_pkt_counter = 0; + } + } + else //disable buffer check + { + DFU_PRINT_INFO0("==>dfu_client_push_image: buffer check disable"); + dfu_client_ctx.dfu_pkt_counter++; + if (dfu_client_ctx.dfu_pkt_counter == dfu_client_ctx.dfu_pkt_num) + { + DFU_PRINT_INFO0("==>dfu_client_push_image: buffer check disable, target need write flash"); + //wait for slave write image to flash + os_delay(200); + dfu_client_ctx.dfu_pkt_counter = 0; + } + } + os_mem_free(pdata); + return true; + } + else + { + DFU_PRINT_INFO0("==>dfu_client_push_image: fail write data"); + + os_mem_free(pdata); + return false; + } +} + + +void dfu_client_handle_cp_notify_msg(uint8_t conn_id, uint8_t *p_notif_data, uint16_t len) +{ + /*Notification Format: notify_opcode(1 byte)+cp opcode(1 byte)+error code(1 byte)+ payload(different length)*/ + uint8_t notify_opcode = p_notif_data[0]; + uint8_t opcode = p_notif_data[1]; + T_DFU_ARV_ERROR_CODE error_code = (T_DFU_ARV_ERROR_CODE)p_notif_data[2]; + if (notify_opcode != DFU_OPCODE_NOTIFICATION) + { + DFU_PRINT_INFO1("==>dfu_client_handle_cp_notify_msg: invalid notify_opcode=0x%x!", notify_opcode); + return; + } + + DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: opcode=0x%x, len=%d", opcode, len); + switch (opcode) + { + case DFU_OPCODE_BUFFER_CHECK_EN: //0x9 + { + if (len == DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN) + { + LE_ARRAY_TO_UINT16(dfu_client_ctx.max_buffer_size, p_notif_data + 3); + LE_ARRAY_TO_UINT16(dfu_client_ctx.mtu_size, p_notif_data + 5); + DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: max_buffer_size=0x%x, mtu_size=0x%x", + dfu_client_ctx.max_buffer_size, dfu_client_ctx.mtu_size); + + if (error_code == DFU_ARV_SUCCESS) + { + //target enable buffer check + + dfu_client_ctx.dfu_pkt_num = dfu_client_ctx.max_buffer_size / + ((dfu_client_ctx.mtu_size - 3) & 0xfff0); + dfu_client_ctx.dfu_pkt_counter = 0; + DFU_PRINT_INFO1("==>dfu_client_handle_cp_notify_msg: Target buffer check enable, dfu_pkt_num=%d", + dfu_client_ctx.dfu_pkt_num); + } + else + { + uint32_t max_buffer_size = dfu_client_ctx.max_buffer_size - (dfu_client_ctx.max_buffer_size % 20); + uint16_t mtu_size = (dfu_client_ctx.mtu_size - 3) & 0xfff0; + dfu_client_ctx.dfu_pkt_num = (max_buffer_size + mtu_size - 1) / mtu_size; + dfu_client_ctx.dfu_last_pkt_size = (max_buffer_size % mtu_size) ? (max_buffer_size % mtu_size) : + mtu_size; + dfu_client_ctx.dfu_pkt_counter = 0; + DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: Target buffer check disable, max_buffer_size=%d, dfu_pkt_num=%d", + max_buffer_size, dfu_client_ctx.dfu_pkt_num); + + } + + dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_TARGET_INFO); + } + } + break; + case DFU_OPCODE_REPORT_TARGET_INFO: //0x6 + { + if (len == DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO) + { + LE_ARRAY_TO_UINT32(dfu_client_ctx.target_img_version, p_notif_data + 3); + LE_ARRAY_TO_UINT32(dfu_client_ctx.curr_offset, p_notif_data + 7); + DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: target_version=0x%x, img_id=0x%x", + dfu_client_ctx.target_img_version, + dfu_client_ctx.dfu_ctrl_header.image_id); + + DFU_PRINT_INFO5("dfu_client_handle_cp_notify_msg: target_version=%d.%d.%d.%d, dfu_client_ctx.curr_offset=0x%x", + MAJOR_IMG_VER(dfu_client_ctx.target_img_version), + MINOR_IMG_VER(dfu_client_ctx.target_img_version), + REVISION_IMG_VER(dfu_client_ctx.target_img_version), + RESERVE_IMG_VER(dfu_client_ctx.target_img_version), + dfu_client_ctx.curr_offset); + if (DFU_FEATURE_AUTO_COPY_DFU == dfu_client_ctx.dfu_feature) + { + uint32_t le_target_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.target_img_version); + uint32_t le_dfu_ver = 0; + if (dfu_client_ctx.dfu_ctrl_header.image_id == AppPatch) + { + //init dfu_client_ctx.dfu_img_version in format T_IMAGE_VERSION + get_active_bank_image_version(AppPatch, (T_IMAGE_VERSION *)&dfu_client_ctx.dfu_img_version); + + le_dfu_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.dfu_img_version); + DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: le_dfu_ver=0x%x, le_target_ver=0x%x", + le_dfu_ver, le_target_ver); + //compare target image version with dfu img version to determine continue dfu procedure or not + if (le_dfu_ver <= le_target_ver) + { + DBG_DIRECT("auto Copy OTA: app no need ota!"); + + dfu_client_ctx.dfu_ctrl_header.image_id = RomPatch; + dfu_client_ctx.dfu_img_start_addr = get_header_addr_by_img_id(RomPatch); + /*get target patch image version*/ + dfu_client_process_control_point(conn_id, DFU_OPCODE_REPORT_TARGET_INFO); + return; + } + } + else if (dfu_client_ctx.dfu_ctrl_header.image_id == RomPatch) + { + get_active_bank_image_version(RomPatch, (T_IMAGE_VERSION *)&dfu_client_ctx.dfu_img_version); + + le_dfu_ver = IMAGE_VERSION_TO_LE_UINT32(dfu_client_ctx.dfu_img_version); + + DFU_PRINT_INFO2("dfu_client_handle_cp_notify_msg: le_dfu_ver=0x%x, le_target_ver=0x%x", + le_dfu_ver, le_target_ver); + //if dfu patch version less then and equal target img version, don't OTA + if (le_dfu_ver <= le_target_ver) + { + DBG_DIRECT("auto Copy OTA: patch no need OTA!"); + return; + } + } + else + { + return; + } + + dfu_client_process_control_point(conn_id, DFU_OPCODE_START_DFU); + } + else // not auto copy dfu + { + dfu_client_ctx.dfu_img_version = ((T_IMG_HEADER_FORMAT *) + dfu_client_ctx.dfu_img_start_addr)->git_ver.ver_info.version; + /*if only support upgrade, need compare version value in litte endian */ + dfu_client_process_control_point(conn_id, DFU_OPCODE_START_DFU); + } + + + /*notify application*/ + if (pf_dfu_client_app_info_cb) + { + T_DFU_CLIENT_CB_MSG cb_msg; + cb_msg.conn_id = conn_id; + cb_msg.type = DFU_CB_START; + pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg); + } + } + } + break; + case DFU_OPCODE_START_DFU: //0x1 + { + if (len == DFU_NOTIFY_LENGTH_START_DFU && error_code == DFU_ARV_SUCCESS) + { + //start push image, make use of credits + for (uint8_t loop = 0; loop < 8; loop++) + { + dfu_client_push_image(conn_id); + } + } + else + { + if (pf_dfu_client_app_info_cb) + { + T_DFU_CLIENT_CB_MSG cb_msg; + cb_msg.conn_id = conn_id; + cb_msg.type = DFU_CB_FAIL; + cb_msg.data.dfu_fail_reason = DFU_FAIL_START_DFU; + pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg); + } + } + } + break; + case DFU_OPCODE_REPORT_BUFFER_CRC: //0xa + { + if (len == DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC) + { + uint32_t target_offset; + LE_ARRAY_TO_UINT32(target_offset, p_notif_data + 3); + DFU_PRINT_INFO2("==>dfu_client_handle_cp_notify_msg: target_offset=%d, dfu_client_ctx.curr_offset=%d", + target_offset, dfu_client_ctx.curr_offset); + + /*if buffer check fail, only retry 3 times*/ + if (error_code != DFU_ARV_SUCCESS) + { + DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: target buffer check fail!"); + buf_check_retry_cnt++; + if (buf_check_retry_cnt >= 3) + { + DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: one packet retry buffer check 3 times fail!"); + dfu_client_process_control_point(conn_id, DFU_OPCODE_SYSTEM_RESET); + + if (pf_dfu_client_app_info_cb) + { + T_DFU_CLIENT_CB_MSG cb_msg; + cb_msg.conn_id = conn_id; + cb_msg.type = DFU_CB_FAIL; + cb_msg.data.dfu_fail_reason = DFU_FAIL_BUF_CHECK; + pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg); + } + + return; + } + } + else + { + DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: target buffer check success!"); + buf_check_retry_cnt = 0; + } + + dfu_client_ctx.curr_offset = target_offset; + if (dfu_client_ctx.dfu_img_total_length > dfu_client_ctx.curr_offset) + { + DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: Image transmitting (Buffer Check Enable)"); + dfu_client_push_image(conn_id); + } + else + { + //buffer check enable image trans done + DFU_PRINT_INFO0("==>dfu_client_handle_cp_notify_msg: Image trans done (Buffer Check Enable)"); + dfu_client_process_control_point(conn_id, DFU_OPCODE_VALID_FW); + } + } + } + break; + case DFU_OPCODE_VALID_FW: //0x3 + { + if (len == DFU_NOTIFY_LENGTH_VALID_FW) + { + T_DFU_CP_OPCODE next_opcode; + next_opcode = (error_code == DFU_ARV_SUCCESS) ? DFU_OPCODE_ACTIVE_IMAGE_RESET : + DFU_OPCODE_SYSTEM_RESET; + dfu_client_process_control_point(conn_id, next_opcode); + + if (pf_dfu_client_app_info_cb) + { + T_DFU_CLIENT_CB_MSG cb_msg; + cb_msg.conn_id = conn_id; + cb_msg.type = (error_code == DFU_ARV_SUCCESS) ? DFU_CB_END : DFU_CB_FAIL; + cb_msg.data.dfu_fail_reason = (error_code == DFU_ARV_SUCCESS) ? DFU_SUCCESS : DFU_FAIL_VALIDATE_FW; + pf_dfu_client_app_info_cb(dfu_client, conn_id, &cb_msg); + } + } + } + break; + default: //other opcode no ack + break; + } +} + + +T_APP_RESULT dfu_client_handle_read_cb(uint8_t conn_id, T_DFU_READ_RESULT *pcb_read_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + switch (pcb_read_data->type) + { + case DFU_READ_CP_CCCD: + DFU_PRINT_INFO1("==>dfu_client_handle_read_cb: dfu_cp_cccd=%d(1:CCCD Enable)", + pcb_read_data->data.dfu_cp_cccd); + break; + default: + break; + } + return result; +} + +T_APP_RESULT dfu_client_handle_write_cb(uint8_t conn_id, T_DFU_WRITE_RESULT *pcb_write_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: type=%d(0: write cp, 1: write cp ccd, 2: write data)", + pcb_write_data->type); + DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: dfu_fsm_write=%d(0:idle, 1:cccd_enabled, 2: writed_data, 3: wait for rsp )", + dfu_client_ctx.dfu_fsm_write); + if (pcb_write_data->cause == 0) + { + switch (pcb_write_data->type) + { + case DFU_WRITE_CP_CCCD: + DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_CP_CCCD", + dfu_fsm_write); + if (dfu_fsm_write == DFU_FSM_WRITE_CCCD_ENABLE) + { + T_IMG_HEADER_FORMAT *p_header = (T_IMG_HEADER_FORMAT *)dfu_client_ctx.dfu_img_start_addr; + dfu_client_ctx.dfu_ctrl_header.image_id = p_header->ctrl_header.image_id; + dfu_client_process_control_point(conn_id, DFU_OPCODE_BUFFER_CHECK_EN); + } + break; + case DFU_WRITE_DATA: + DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_DATA, dfu_fsm_write=%d.", + dfu_fsm_write); + if (dfu_fsm_write == DFU_FSM_WRITE_DFU_DATA) + { + if (dfu_client_ctx.dfu_img_total_length > dfu_client_ctx.curr_offset) + { + DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: DFU_WRITE_DATA, continue push image!"); + dfu_client_push_image(conn_id); + } + else + { + if (!dfu_client_ctx.ota_mode.mode_flag.buf_check_en) + { + /*when not enable buf check, img trans done, verify img*/ + DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: Img trans done(BufCheckDisable), validate fw"); + dfu_client_process_control_point(conn_id, DFU_OPCODE_VALID_FW); + } + } + } + break; + case DFU_WRITE_CP: + DFU_PRINT_INFO1("==>dfu_client_handle_write_cb: DFU_WRITE_CP, dfu_fsm_write=%d.", + dfu_fsm_write); + if (dfu_fsm_write == DFU_FSM_WRITE_WAIT_WRITE_RESP) + { + //means received write response + dfu_fsm_write = DFU_FSM_WRITE_IDLE; + if (dfu_temp_cp_notify_msg_len) + { + //means first received notification then received write response + DFU_PRINT_INFO2("==>dfu_client_handle_write_cb: DFU_WRITE_CP, dfu_fsm_write=%d, dfu_cp_temp_msg_len=%d", + dfu_fsm_write, dfu_temp_cp_notify_msg_len); + dfu_client_handle_cp_notify_msg(conn_id, dfu_temp_cp_notify_msg, dfu_temp_cp_notify_msg_len); + dfu_temp_cp_notify_msg_len = 0; + } + } + break; + default: + break; + } + } + else + { + DFU_PRINT_INFO3("==>dfu_client_handle_write_cb: write data fail! type=%d, cause=0x%x, dfu_fsm_write=%d", + pcb_write_data->type, pcb_write_data->cause, dfu_fsm_write); + DFU_PRINT_INFO0("==>dfu_client_handle_write_cb: le_disconnect"); + le_disconnect(conn_id); + } + + return result; +} + +T_APP_RESULT dfu_client_handle_notif_ind_cb(uint8_t conn_id, + T_DFU_NOTIFY_INDICATE_DATA *pcb_notif_ind_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: type=%d(0: DFU_RECEIVE_CP_NOTIFY)", + pcb_notif_ind_data->type); + switch (pcb_notif_ind_data->type) + { + case DFU_RECEIVE_CP_NOTIFY: + { + DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: dfu_fsm_write=%d(if 0 hdl cp msg, else cache msg)", + dfu_fsm_write); + if (dfu_fsm_write == DFU_FSM_WRITE_IDLE) + { + dfu_client_handle_cp_notify_msg(conn_id, pcb_notif_ind_data->value.pdata, + pcb_notif_ind_data->value.len); + } + else + { + //cache + dfu_temp_cp_notify_msg_len = pcb_notif_ind_data->value.len; + memcpy(dfu_temp_cp_notify_msg, pcb_notif_ind_data->value.pdata, + dfu_temp_cp_notify_msg_len > 20 ? 20 : dfu_temp_cp_notify_msg_len); + DFU_PRINT_INFO1("==>dfu_client_handle_notif_ind_cb: cached received notification, len=%d", + dfu_temp_cp_notify_msg_len); + } + } + break; + default: + break; + } + return result; +} + +/*profile callback to handle msg*/ +T_APP_RESULT dfu_client_handle_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_DFU_CLIENT_CB_DATA *pcb_data = (T_DFU_CLIENT_CB_DATA *)p_data; + DFU_PRINT_INFO1("==>dfu_client_handle_cb: cb_type=%d(0: disc, 1: read, 2: write, 3: notify)", + pcb_data->cb_type); + switch (pcb_data->cb_type) + { + case DFU_CLIENT_CB_TYPE_DISC_STATE: + break; + case DFU_CLIENT_CB_TYPE_READ_RESULT: + result = dfu_client_handle_read_cb(conn_id, &pcb_data->cb_content.read_result); + break; + case DFU_CLIENT_CB_TYPE_WRITE_RESULT: + result = dfu_client_handle_write_cb(conn_id, &pcb_data->cb_content.write_result); + break; + case DFU_CLIENT_CB_TYPE_NOTIF_IND_RESULT: + result = dfu_client_handle_notif_ind_cb(conn_id, &pcb_data->cb_content.notif_ind_data); + break; + default: + break; + } + + return result; +} + +/** + * @brief Dfu Client Callbacks. +*/ +const T_FUN_CLIENT_CBS dfu_client_cbs = +{ + dfu_client_disc_state_cb, //!< Discovery State callback function pointer + dfu_client_disc_result_cb, //!< Discovery result callback function pointer + dfu_client_read_result_cb, //!< Read response callback function pointer + dfu_client_write_result_cb, //!< Write result callback function pointer + dfu_client_notify_indicate_cb, //!< Notify Indicate callback function pointer + dfu_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief add Dfu client to application. + * @param appCB: pointer of app callback function to handle specific client module data. + * @retval Client ID of the specific client module. + */ +T_CLIENT_ID dfu_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > DFU_MAX_LINKS) + { + DFU_PRINT_ERROR1("dfu_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&dfu_client, &dfu_client_cbs)) + { + dfu_client = CLIENT_PROFILE_GENERAL_ID; + DFU_PRINT_ERROR0("dfu_client_add: fail!"); + return dfu_client; + } + DFU_PRINT_INFO1("dfu_client_add: client ID = %d", dfu_client); + + dfu_link_num = link_num; + size = dfu_link_num * sizeof(T_DFU_LINK); + dfu_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + /* register callback for profile to inform application that some events happened. */ + pf_dfu_client_cb = dfu_client_handle_cb; + pf_dfu_client_app_info_cb = app_cb; + + if (pf_dfu_client_init) + { + pf_dfu_client_init(); + } + + return dfu_client; +} + + diff --git a/src/ble/profile/client/dis_client.c b/src/ble/profile/client/dis_client.c new file mode 100644 index 0000000..c445f4a --- /dev/null +++ b/src/ble/profile/client/dis_client.c @@ -0,0 +1,825 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dis_client.c + * @brief Dis BLE client source file. + * @details + * @author ken + * @date 2017-12-05 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_DIS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_DIS_CACHE_LEN]; +} T_DIS_LINK, *P_DIS_LINK; + +static P_DIS_LINK dis_table; +static uint8_t dis_link_num; + +/**< dis client ID. */ +static T_CLIENT_ID dis_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from dis client layer. */ +static P_FUN_GENERAL_APP_CB dis_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of lls server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("dis_client_start_discovery"); + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK)); + dis_table[conn_id].disc_state = DISC_DIS_START; + if (client_by_uuid_srv_discovery(conn_id, dis_client, + GATT_UUID_DEVICE_INFORMATION_SERVICE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_read_by_handle(uint8_t conn_id, T_DIS_READ_TYPE read_type) +{ + bool hdl_valid = false; + uint16_t handle; + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case DIS_READ_SYSTEM_ID: + if (dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_SYSTEM_ID]; + hdl_valid = true; + } + break; + case DIS_READ_MODEL_NUMBER: + if (dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_MODEL_NUMBER]; + hdl_valid = true; + } + break; + case DIS_READ_SERIAL_NUMBER: + if (dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_SERIAL_NUMBER]; + hdl_valid = true; + } + break; + case DIS_READ_FIRMWARE_REVISION: + if (dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_FIRMWARE_REVISION]; + hdl_valid = true; + } + break; + case DIS_READ_HARDWARE_REVISION: + if (dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_HARDWARE_REVISION]; + hdl_valid = true; + } + break; + case DIS_READ_SOFTWARE_REVISION: + if (dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_SOFTWARE_REVISION]; + hdl_valid = true; + } + break; + case DIS_READ_MANUFACTURER_NAME: + if (dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_MANUFACTURER_NAME]; + hdl_valid = true; + } + break; + case DIS_READ_IEEE_CERTIF_DATA_LIST: + if (dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST]; + hdl_valid = true; + } + break; + case DIS_READ_PNP_ID: + if (dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID]) + { + handle = dis_table[conn_id].hdl_cache[HDL_DIS_PNP_ID]; + hdl_valid = true; + } + break; + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, dis_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("dis_client_read_by_handle: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool dis_client_read_by_uuid(uint8_t conn_id, + T_DIS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +{ + uint16_t start_handle; + uint16_t end_handle; + uint16_t uuid16; + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_read_by_uuid: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case DIS_READ_SYSTEM_ID: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_SYSTEM_ID; + break; + case DIS_READ_MODEL_NUMBER: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_MODEL_NUMBER; + break; + case DIS_READ_SERIAL_NUMBER: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_SERIAL_NUMBER; + break; + case DIS_READ_FIRMWARE_REVISION: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_FIRMWARE_REVISION; + break; + case DIS_READ_HARDWARE_REVISION: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_HARDWARE_REVISION; + break; + case DIS_READ_SOFTWARE_REVISION: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_SOFTWARE_REVISION; + break; + case DIS_READ_MANUFACTURER_NAME: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_MANUFACTURER_NAME; + break; + case DIS_READ_IEEE_CERTIF_DATA_LIST: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST; + break; + case DIS_READ_PNP_ID: + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + uuid16 = GATT_UUID_CHAR_PNP_ID; + break; + + default: + return false; + } + + if (client_attr_read_using_uuid(conn_id, dis_client, start_handle, end_handle, + uuid16, NULL) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +///** +// * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. +// * @param[in] conn_id connection ID. +// * @param[in] notify 0--disable the notification, 1--enable the notification. +// * @retval true send request to upper stack success. +// * @retval false send request to upper stack failed. +// */ +//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify) +//{ +// if (conn_id >= kns_link_num) +// { +// PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]) +// { +// uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = notify ? 1 : 0; +// if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind) +//{ +// if (conn_id >= simp_link_num) +// { +// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) +// { +// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = ind ? 2 : 0; +// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to write data of write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, +// T_GATT_WRITE_TYPE type) +//{ +// if (conn_id >= lls_link_num) +// { +// PROFILE_PRINT_ERROR1("lls_client_write_char: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA]) +// { +// uint16_t handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA]; +// if (client_attr_write(conn_id, lls_client, type, handle, +// length, p_value) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("lls_ble_client_write_char: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dis_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (dis_table[conn_id].disc_state != DISC_DIS_DONE) + { + PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid state %d", + dis_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("dis_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, dis_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool dis_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (dis_table[conn_id].disc_state != DISC_DIS_IDLE) + { + PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid state %d", + dis_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_DIS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("dis_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(dis_table[conn_id].hdl_cache, p_hdl_cache, len); + dis_table[conn_id].disc_state = DISC_DIS_DONE; + return true; +} + +static bool dis_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("dis_client_start_ias_char_discovery"); + start_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_START]; + end_handle = dis_table[conn_id].hdl_cache[HDL_DIS_SRV_END]; + if (client_all_char_discovery(conn_id, dis_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +//static bool lls_client_start_char_descriptor_discovery(uint8_t conn_id) +//{ +// uint16_t start_handle; +// uint16_t end_handle; + +// PROFILE_PRINT_INFO0("lls_client_start_char_descriptor_discovery"); +// start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_NOTIFY_KEY]; +// end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END]; +// if (client_all_char_descriptor_discovery(conn_id, lls_client, start_handle, +// end_handle) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// return false; +//} +static void dis_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_DIS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = DIS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("dis_client_discover_state_cb: discovery_state %d", discovery_state); + if (dis_table[conn_id].disc_state == DISC_DIS_START) + { + uint16_t *hdl_cache; + hdl_cache = dis_table[conn_id].hdl_cache; + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hdl_cache[HDL_DIS_SRV_START] != 0) + || (hdl_cache[HDL_DIS_SRV_END] != 0)) + { + if (dis_client_start_char_discovery(conn_id) == false) + { + dis_table[conn_id].disc_state = DISC_DIS_FAILED; + cb_flag = true; + } + } + /* No Ias BLE service handle found. Discover procedure complete. */ + else + { + dis_table[conn_id].disc_state = DISC_DIS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + dis_table[conn_id].disc_state = DISC_DIS_DONE; + cb_flag = true; + break; + case DISC_STATE_FAILED: + dis_table[conn_id].disc_state = DISC_DIS_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("dis_handle_discover_state: Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && dis_client_cb) + { + cb_data.cb_content.disc_state = dis_table[conn_id].disc_state; + (*dis_client_cb)(dis_client, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param conn_id: connection ID. + * @param result_type: indicate which type of value discovered in service discovery procedure. + * @param result_data: value discovered. + * @retval None + */ +static void dis_client_discover_result_cb(uint8_t conn_id, + T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("dis_client_discover_result_cb: result_type %d", result_type); + if (dis_table[conn_id].disc_state == DISC_DIS_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = dis_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hdl_cache[HDL_DIS_SRV_START] = result_data.p_srv_disc_data->att_handle; + hdl_cache[HDL_DIS_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + case DISC_RESULT_CHAR_UUID128: + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_SYSTEM_ID: + hdl_cache[HDL_DIS_SYSTEM_ID] = handle; + break; + case GATT_UUID_CHAR_MODEL_NUMBER: + hdl_cache[HDL_DIS_MODEL_NUMBER] = handle; + break; + case GATT_UUID_CHAR_SERIAL_NUMBER: + hdl_cache[HDL_DIS_SERIAL_NUMBER] = handle; + break; + case GATT_UUID_CHAR_FIRMWARE_REVISION: + hdl_cache[HDL_DIS_FIRMWARE_REVISION] = handle; + break; + case GATT_UUID_CHAR_HARDWARE_REVISION: + hdl_cache[HDL_DIS_HARDWARE_REVISION] = handle; + break; + case GATT_UUID_CHAR_SOFTWARE_REVISION: + hdl_cache[HDL_DIS_SOFTWARE_REVISION] = handle; + break; + case GATT_UUID_CHAR_MANUFACTURER_NAME: + hdl_cache[HDL_DIS_MANUFACTURER_NAME] = handle; + break; + case GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST: + hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST] = handle; + break; + case GATT_UUID_CHAR_PNP_ID: + hdl_cache[HDL_DIS_PNP_ID] = handle; + break; + default: + /* have no intrest on this handle. */ + break; + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use client_all_char_descriptor_discovery. */ + break; + + default: + APP_PRINT_ERROR0("lls_handle_discover_result: Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void dis_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_DIS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = dis_table[conn_id].hdl_cache; + + cb_data.cb_type = DIS_CLIENT_CB_TYPE_READ_RESULT; + + APP_PRINT_INFO2("dis_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_DIS_SYSTEM_ID]) + { + cb_data.cb_content.read_result.type = DIS_READ_SYSTEM_ID; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_MODEL_NUMBER]) + { + cb_data.cb_content.read_result.type = DIS_READ_MODEL_NUMBER; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_SERIAL_NUMBER]) + { + cb_data.cb_content.read_result.type = DIS_READ_SERIAL_NUMBER; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_FIRMWARE_REVISION]) + { + cb_data.cb_content.read_result.type = DIS_READ_FIRMWARE_REVISION; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_HARDWARE_REVISION]) + { + cb_data.cb_content.read_result.type = DIS_READ_HARDWARE_REVISION; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_SOFTWARE_REVISION]) + { + cb_data.cb_content.read_result.type = DIS_READ_SOFTWARE_REVISION; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_MANUFACTURER_NAME]) + { + cb_data.cb_content.read_result.type = DIS_READ_MANUFACTURER_NAME; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_IEEE_CERTIF_DATA_LIST]) + { + cb_data.cb_content.read_result.type = DIS_READ_IEEE_CERTIF_DATA_LIST; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_DIS_PNP_ID]) + { + cb_data.cb_content.read_result.type = DIS_READ_PNP_ID; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else + { + return; + } + /* Inform application the read result. */ + if (dis_client_cb) + { + (*dis_client_cb)(dis_client, conn_id, &cb_data); + } + + return; +} + +//static void dis_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, +// uint16_t handle, uint16_t cause, +// uint8_t credits) +//{ +// T_LLS_CLIENT_CB_DATA cb_data; +// uint16_t *hdl_cache; +// hdl_cache = dis_table[conn_id].hdl_cache; +// cb_data.cb_type = DIS_CLIENT_CB_TYPE_WRITE_RESULT; + +// PROFILE_PRINT_INFO2("dis_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); +// cb_data.cb_content.write_result.cause = cause; + +// if (handle == hdl_cache[HDL_DIS_PARA]) +// { +// cb_data.cb_content.write_result.type = DIS_WRITE_PARA; +// } +// else +// { +// return; +// } +// /* Inform application the write result. */ +// if (dis_client_cb) +// { +// (*dis_client_cb)(lls_client, conn_id, &cb_data); +// } + +// return; +//} + +//static T_APP_RESULT lls_client_notif_ind_result_cb(uint8_t conn_id, bool notify, +// uint16_t handle, +// uint16_t value_size, uint8_t *p_value) +//{ +// T_APP_RESULT app_result = APP_RESULT_SUCCESS; +// T_KNS_CLIENT_CB_DATA cb_data; +// uint16_t *hdl_cache; +// hdl_cache = kns_table[conn_id].hdl_cache; + +// cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + +// if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY]) +// { +// cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY; +// cb_data.cb_content.notif_ind_data.data.value_size = value_size; +// cb_data.cb_content.notif_ind_data.data.p_value = p_value; +// } +// else +// { +// return app_result; +// } +// /* Inform application the notif/ind result. */ +// if (kns_client_cb) +// { +// app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data); +// } + +// return app_result; +//} + +static void dis_client_disconnect_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("dis_client_disconnect_cb."); + if (conn_id >= dis_link_num) + { + PROFILE_PRINT_ERROR1("dis_client_disconnect_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&dis_table[conn_id], 0, sizeof(T_DIS_LINK)); + return; +} + +/** + * @brief Ias BLE Client Callbacks. +*/ +const T_FUN_CLIENT_CBS dis_client_cbs = +{ + dis_client_discover_state_cb, //!< Discovery State callback function pointer + dis_client_discover_result_cb, //!< Discovery result callback function pointer + dis_client_read_result_cb, //!< Read response callback function pointer + NULL,//lls_client_write_result_cb, //!< Write result callback function pointer + NULL,//kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer + dis_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add dis service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + dis_client_id = dis_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID dis_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > DIS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("dis_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&dis_client, &dis_client_cbs)) + { + dis_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("dis_add_client failed"); + return dis_client; + } + APP_PRINT_INFO1("dis_add_client: dis_client %d", dis_client); + + /* register callback for profile to inform application that some events happened. */ + dis_client_cb = app_cb; + dis_link_num = link_num; + size = dis_link_num * sizeof(T_DIS_LINK); + dis_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return dis_client; +} + diff --git a/src/ble/profile/client/gaps_client.c b/src/ble/profile/client/gaps_client.c new file mode 100644 index 0000000..3c689ef --- /dev/null +++ b/src/ble/profile/client/gaps_client.c @@ -0,0 +1,500 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gaps_client.c + * @brief GAPS client source file. + * @details + * @author jane + * @date 2016-02-18 + * @version v0.1 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +/** + * @brief GAPS Client Link control block defination. + */ +typedef struct +{ + T_GAPS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_GAPS_CACHE_LEN]; +} T_GAPS_LINK, *P_GAPS_LINK; + +/** @brief GAPS Client link table */ +static P_GAPS_LINK gaps_table; +static uint8_t gaps_link_num; + +/**< GAPS client ID. */ +static T_CLIENT_ID gaps_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from GAPS client layer. */ +static P_FUN_GENERAL_APP_CB gaps_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of GAP service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gapdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = gaps_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool gaps_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("gaps_start_discovery"); + /* First clear handle cache. */ + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + memset(&gaps_table[conn_id], 0, sizeof(T_GAPS_LINK)); + gaps_table[conn_id].disc_state = DISC_GAPS_START; + if (client_by_uuid_srv_discovery(conn_id, gaps_client, + GATT_UUID_GAP) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gapread(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + T_GAPS_READ_TYPE read_type = (T_GAPS_READ_TYPE)p_parse_value->dw_param[1]; + bool ret = gaps_read(conn_id, read_type); + ...... + } + * \endcode + */ +bool gaps_read(uint8_t conn_id, T_GAPS_READ_TYPE read_type) +{ + bool hdl_valid = false; + uint16_t handle; + uint16_t *hdl_cache; + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_read: failed invalid conn_id %d", conn_id); + return false; + } + hdl_cache = gaps_table[conn_id].hdl_cache; + + PROFILE_PRINT_INFO1("gaps_read: charType = %d", read_type); + + switch (read_type) + { + case GAPS_READ_DEVICE_NAME: + if (hdl_cache[HDL_GAPS_DEVICE_NAME]) + { + handle = hdl_cache[HDL_GAPS_DEVICE_NAME]; + hdl_valid = true; + } + break; + case GAPS_READ_APPEARANCE: + if (hdl_cache[HDL_GAPS_APPEARANCE]) + { + handle = hdl_cache[HDL_GAPS_APPEARANCE]; + hdl_valid = true; + } + break; + case GAPS_READ_CENTRAL_ADDR_RESOLUTION: + if (hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION]) + { + handle = hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION]; + hdl_valid = true; + } + break; + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, gaps_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + PROFILE_PRINT_WARN0("gaps_read: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in,out] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gaphdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_GAPS_CACHE_LEN]; + uint8_t hdl_idx; + bool ret = gaps_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN); + ...... + } + * \endcode + */ +bool gaps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (gaps_table[conn_id].disc_state != DISC_GAPS_DONE) + { + PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_GAPS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, gaps_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_GAPS_FLAG) + { + gaps_set_hdl_cache(conn_id, app_srvs_table.gaps_hdl_cache, sizeof(uint16_t) * HDL_GAPS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool gaps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (gaps_table[conn_id].disc_state != DISC_GAPS_IDLE) + { + PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_GAPS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("gaps_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(gaps_table[conn_id].hdl_cache, p_hdl_cache, len); + gaps_table[conn_id].disc_state = DISC_GAPS_DONE; + return true; +} + +/** + * @brief Used by application, to check Resolvable Private Address Only Characteristics whether existing. + * @param[in] conn_id connection ID. + * @param[in,out] p_is_exist whether existing + * @retval true success. + * @retval false failed. + */ +bool gaps_check_resolvable_private_addr_only_char(uint8_t conn_id, bool *p_is_exist) +{ + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (gaps_table[conn_id].disc_state != DISC_GAPS_DONE) + { + PROFILE_PRINT_ERROR1("gaps_get_hdl_cache: failed invalid state %d", gaps_table[conn_id].disc_state); + return false; + } + if (gaps_table[conn_id].hdl_cache[HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY] == 0) + { + *p_is_exist = false; + } + else + { + *p_is_exist = true; + } + return true; +} + +static bool gaps_client_start_gap_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("gap_client_start_gap_char_discovery"); + start_handle = gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START]; + end_handle = gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END]; + if (client_all_char_discovery(conn_id, gaps_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void gaps_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_GAPS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = GAPS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("gaps_client_discover_state_cb: discovery_state %d", discovery_state); + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START] != 0) + || (gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END] != 0)) + { + if (gaps_client_start_gap_char_discovery(conn_id) == false) + { + gaps_table[conn_id].disc_state = DISC_GAPS_FAILED; + cb_flag = true; + } + } + /* No GAP service handle found. Discover procedure complete. */ + else + { + gaps_table[conn_id].disc_state = DISC_GAPS_FAILED; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DONE: + gaps_table[conn_id].disc_state = DISC_GAPS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + PROFILE_PRINT_ERROR0("DISC_STATE_FAILED"); + gaps_table[conn_id].disc_state = DISC_GAPS_FAILED; + cb_flag = true; + break; + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + /* Send discover state to application if needed. */ + if (cb_flag && gaps_client_cb) + { + cb_data.cb_content.disc_state = gaps_table[conn_id].disc_state; + (*gaps_client_cb)(gaps_client, conn_id, &cb_data); + } + return; +} + +static void gaps_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("gap_client_discover_result_cb: result_type = %d", result_type); + uint16_t handle; + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + gaps_table[conn_id].hdl_cache[HDL_GAPS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + /* we should inform intrested handles to upper application. */ + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_DEVICE_NAME: + gaps_table[conn_id].hdl_cache[HDL_GAPS_DEVICE_NAME] = handle; + break; + case GATT_UUID_CHAR_APPEARANCE: + gaps_table[conn_id].hdl_cache[HDL_GAPS_APPEARANCE] = handle; + break; + case GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION: + gaps_table[conn_id].hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION] = handle; + PROFILE_PRINT_INFO0("GATT_UUID_CHAR_CENTRAL_ADDRESS_RESOLUTION found"); + break; + case GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY: + gaps_table[conn_id].hdl_cache[HDL_GAPS_RESOLVABLE_PRIVATE_ADDR_ONLY] = handle; + PROFILE_PRINT_INFO0("GATT_UUID_CHAR_RESOLVABLE_PRIVATE_ADDRESS_ONLY found"); + break; + default: + /* have no intrest on this handle. */ + break; + } + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + + return; +} + +static void gaps_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_GAPS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = gaps_table[conn_id].hdl_cache; + cb_data.cb_type = GAPS_CLIENT_CB_TYPE_READ_RESULT; + cb_data.cb_content.read_result.cause = cause; + + PROFILE_PRINT_INFO2("gap_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + + if (handle == hdl_cache[HDL_GAPS_APPEARANCE]) + { + cb_data.cb_content.read_result.type = GAPS_READ_APPEARANCE; + if (cause == GAP_SUCCESS) + { + uint16_t appearance; + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("gaps_client_read_result_cb: invalid cccd len %d", value_size); + return; + } + LE_ARRAY_TO_UINT16(appearance, p_value); + cb_data.cb_content.read_result.data.appearance = appearance; + } + } + else if (handle == hdl_cache[HDL_GAPS_DEVICE_NAME]) + { + cb_data.cb_content.read_result.type = GAPS_READ_DEVICE_NAME; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.device_name.value_size = value_size; + cb_data.cb_content.read_result.data.device_name.p_value = p_value; + } + } + else if (handle == hdl_cache[HDL_GAPS_CENTRAL_ADDR_RESOLUTION]) + { + cb_data.cb_content.read_result.type = GAPS_READ_CENTRAL_ADDR_RESOLUTION; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.central_addr_res = *p_value; + } + } + else + { + return; + } + + /* Inform application the read result. */ + if (gaps_client_cb) + { + (*gaps_client_cb)(gaps_client, conn_id, &cb_data); + } + return; +} + + +static void gaps_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("gap_client_disc_cb."); + if (conn_id >= gaps_link_num) + { + PROFILE_PRINT_ERROR1("gaps_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&gaps_table[conn_id], 0, sizeof(T_GAPS_LINK)); + return; +} +/** + * @brief GAPS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS gaps_client_cbs = +{ + gaps_client_discover_state_cb, //!< Discovery State callback function pointer + gaps_client_discover_result_cb, //!< Discovery result callback function pointer + gaps_client_read_result_cb, //!< Read response callback function pointer + NULL, //!< Write result callback function pointer + NULL, //!< Notify Indicate callback function pointer + gaps_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add gap service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + gaps_client_id = gaps_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID gaps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > GAPS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("gaps_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&gaps_client, &gaps_client_cbs)) + { + gaps_client = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("gaps_add_client Fail !!!"); + return gaps_client; + } + PROFILE_PRINT_INFO1("gaps_add_client: client ID = %d", gaps_client); + + /* register callback for profile to inform application that some events happened. */ + gaps_client_cb = app_cb; + gaps_link_num = link_num; + size = gaps_link_num * sizeof(T_GAPS_LINK); + gaps_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return gaps_client; +} + diff --git a/src/ble/profile/client/gatts_client.c b/src/ble/profile/client/gatts_client.c new file mode 100644 index 0000000..a539ce7 --- /dev/null +++ b/src/ble/profile/client/gatts_client.c @@ -0,0 +1,479 @@ +/** +***************************************************************************************** +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gatts_client.c + * @brief GATTS client source file. + * @details + * @author + * @date 2019-05-27 + * @version v0.1 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +/** + * @brief GATTS Client Link control block definition. + */ +typedef struct +{ + T_GATTS_DISC_STATE disc_state; + bool write_ind_value; + uint16_t hdl_cache[HDL_GATTS_CACHE_LEN]; +} T_GATTS_LINK, *P_GATTS_LINK; + +/** @brief GATTS Client link table */ +static P_GATTS_LINK gatts_table; +static uint8_t gatts_link_num; + +/**< GATTS client ID. */ +static T_CLIENT_ID gatts_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from GATTS client layer. */ +static P_FUN_GENERAL_APP_CB gatts_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of GATT service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gattsdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = gatts_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool gatts_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("gatts_start_discovery"); + /* First clear handle cache. */ + if (conn_id >= gatts_link_num) + { + PROFILE_PRINT_ERROR1("gatts_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + memset(&gatts_table[conn_id], 0, sizeof(T_GATTS_LINK)); + gatts_table[conn_id].disc_state = DISC_GATTS_START; + if (client_by_uuid_srv_discovery(conn_id, gatts_client, + GATT_UUID_GATT) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to enable or disable the indication of peer server's Service Changed Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool gatts_client_set_service_changed_ind(uint8_t conn_id, bool ind) +{ + if (conn_id >= gatts_link_num) + { + PROFILE_PRINT_ERROR1("gatts_client_set_service_changed_ind: failed invalid conn_id %d", conn_id); + return false; + } + + if (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD]) + { + uint16_t handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = ind ? 2 : 0; + if (client_attr_write(conn_id, gatts_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + gatts_table[conn_id].write_ind_value = ind; + return true; + } + } + + APP_PRINT_WARN0("gatts_client_set_service_changed_ind: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in,out] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_gattshdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_GATTS_CACHE_LEN]; + uint8_t hdl_idx; + bool ret = gatts_get_hdl_cache(conn_id, hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN); + ...... + } + * \endcode + */ +bool gatts_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= gatts_link_num) + { + PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (gatts_table[conn_id].disc_state != DISC_GATTS_DONE) + { + PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid state %d", + gatts_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_GATTS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("gatts_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, gatts_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_GATTS_FLAG) + { + gatts_set_hdl_cache(conn_id, app_srvs_table.gatts_hdl_cache, sizeof(uint16_t) * HDL_GATTS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool gatts_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= gatts_link_num) + { + PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (gatts_table[conn_id].disc_state != DISC_GATTS_IDLE) + { + PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid state %d", + gatts_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_GATTS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("gatts_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(gatts_table[conn_id].hdl_cache, p_hdl_cache, len); + gatts_table[conn_id].disc_state = DISC_GATTS_DONE; + return true; +} + +static bool gatts_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("gatts_client_start_gap_char_discovery"); + start_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START]; + end_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END]; + if (client_all_char_discovery(conn_id, gatts_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool gatts_client_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("gatts_client_start_char_descriptor_discovery"); + start_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED]; + end_handle = gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, gatts_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void gatts_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_GATTS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = GATTS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("gatts_client_discover_state_cb: discovery_state %d", discovery_state); + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START] != 0) + || (gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END] != 0)) + { + if (gatts_client_start_char_discovery(conn_id) == false) + { + gatts_table[conn_id].disc_state = DISC_GATTS_FAILED; + cb_flag = true; + } + } + /* No GATT service handle found. Discover procedure complete. */ + else + { + gatts_table[conn_id].disc_state = DISC_GATTS_FAILED; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DONE: + if (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED] != 0) + { + if (gatts_client_start_char_descriptor_discovery(conn_id) == false) + { + gatts_table[conn_id].disc_state = DISC_GATTS_FAILED; + cb_flag = true; + } + } + else + { + gatts_table[conn_id].disc_state = DISC_GATTS_FAILED; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + gatts_table[conn_id].disc_state = DISC_GATTS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + PROFILE_PRINT_ERROR0("DISC_STATE_FAILED"); + gatts_table[conn_id].disc_state = DISC_GATTS_FAILED; + cb_flag = true; + break; + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + /* Send discover state to application if needed. */ + if (cb_flag && gatts_client_cb) + { + cb_data.cb_content.disc_state = gatts_table[conn_id].disc_state; + (*gatts_client_cb)(gatts_client, conn_id, &cb_data); + } + return; +} + +static void gatts_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("gatts_client_discover_result_cb: result_type = %d", result_type); + if (gatts_table[conn_id].disc_state == DISC_GATTS_START) + { + uint16_t handle; + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + gatts_table[conn_id].hdl_cache[HDL_GATTS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + /* we should inform intrested handles to upper application. */ + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_SERVICE_CHANGED: + gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED] = handle; + break; + + default: + /* have no intrest on this handle. */ + break; + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + handle = result_data.p_char_desc_uuid16_disc_data->handle; + if ((handle > gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED]) + && (gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD] == 0)) + { + gatts_table[conn_id].hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD] = handle; + } + } + break; + + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + return; +} + +static void gatts_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_GATTS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = gatts_table[conn_id].hdl_cache; + cb_data.cb_type = GATTS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("gatts_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_GATTS_SERVICE_CHANGED_CCCD]) + { + if (gatts_table[conn_id].write_ind_value) + { + cb_data.cb_content.write_result.type = GATTS_WRITE_SERVICE_CHANGED_IND_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = GATTS_WRITE_SERVICE_CHANGED_IND_DISABLE; + } + } + else + { + return; + } + /* Inform application the write result. */ + if (gatts_client_cb) + { + (*gatts_client_cb)(gatts_client, conn_id, &cb_data); + } + + return; +} + +static T_APP_RESULT gatts_client_notif_ind_result_cb(uint8_t conn_id, bool notify, + uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_GATTS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = gatts_table[conn_id].hdl_cache; + + cb_data.cb_type = GATTS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_GATTS_SERVICE_CHANGED]) + { + cb_data.cb_content.notif_ind_data.type = GATTS_SERVICE_CHANGED_INDICATE; + cb_data.cb_content.notif_ind_data.data.value_size = value_size; + cb_data.cb_content.notif_ind_data.data.p_value = p_value; + } + else + { + return app_result; + } + /* Inform application the notif/ind result. */ + if (gatts_client_cb) + { + app_result = (*gatts_client_cb)(gatts_client, conn_id, &cb_data); + } + + return app_result; +} + +static void gatts_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("gatts_client_disc_cb."); + if (conn_id >= gatts_link_num) + { + PROFILE_PRINT_ERROR1("gatts_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&gatts_table[conn_id], 0, sizeof(T_GATTS_LINK)); + return; +} +/** + * @brief GATTS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS gatts_client_cbs = +{ + gatts_client_discover_state_cb, //!< Discovery State callback function pointer + gatts_client_discover_result_cb, //!< Discovery result callback function pointer + NULL, //!< Read response callback function pointer + gatts_client_write_result_cb, //!< Write result callback function pointer + gatts_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer + gatts_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add gatt service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + gatts_client_id = gatts_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID gatts_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > GATTS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("gatts_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&gatts_client, &gatts_client_cbs)) + { + gatts_client = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("gatts_add_client Fail !!!"); + return gatts_client; + } + PROFILE_PRINT_INFO1("gatts_add_client: client ID = %d", gatts_client); + + /* register callback for profile to inform application that some events happened. */ + gatts_client_cb = app_cb; + gatts_link_num = link_num; + size = gatts_link_num * sizeof(T_GATTS_LINK); + gatts_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return gatts_client; +} + diff --git a/src/ble/profile/client/gcs_client.c b/src/ble/profile/client/gcs_client.c new file mode 100644 index 0000000..d7e38b6 --- /dev/null +++ b/src/ble/profile/client/gcs_client.c @@ -0,0 +1,417 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file gcs_client.c + * @brief General Common Services client source file. + * @details + * @author jane + * @date 2018-12-13 + * @version v0.1 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +/** + * @brief GCS Client Link control block defination. + */ +typedef struct +{ + T_GCS_DISCOV_TYPE discov_type; + uint16_t result_num; + T_GCS_DISCOV_RESULT *p_result_table; +} T_GCS_LINK; + +/** @brief GAPS Client link table */ +static T_GCS_LINK *gcs_table = NULL; +static uint8_t gcs_link_num = 0; +static uint16_t gcs_max_discov_table_num = 0; +/**< GATTS client ID. */ +static T_CLIENT_ID gcs_cl_id = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from gcs client layer. */ +static P_FUN_GENERAL_APP_CB gcs_client_cb = NULL; + +T_GAP_CAUSE gcs_all_primary_srv_discovery(uint8_t conn_id) +{ + T_GAP_CAUSE cause; + cause = client_all_primary_srv_discovery(conn_id, gcs_cl_id); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR2("gcs_all_primary_srv_discovery: failed, conn_id %d, cause %d", + conn_id, cause); + } + else + { + gcs_table[conn_id].discov_type = GCS_ALL_PRIMARY_SRV_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_by_uuid128_srv_discovery(uint8_t conn_id, uint8_t *p_uuid128) +{ + T_GAP_CAUSE cause; + cause = client_by_uuid128_srv_discovery(conn_id, gcs_cl_id, p_uuid128); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR3("gcs_by_uuid128_srv_discovery: failed, conn_id %d, cause %d, p_uuid128 %p", + conn_id, cause, p_uuid128); + } + else + { + gcs_table[conn_id].discov_type = GCS_BY_UUID128_SRV_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_by_uuid_srv_discovery(uint8_t conn_id, uint16_t uuid16) +{ + T_GAP_CAUSE cause; + cause = client_by_uuid_srv_discovery(conn_id, gcs_cl_id, uuid16); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR3("gcs_by_uuid_srv_discovery: failed, conn_id %d, cause %d, uuid16 0x%x", + conn_id, cause, uuid16); + } + else + { + gcs_table[conn_id].discov_type = GCS_BY_UUID_SRV_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_all_char_discovery(uint8_t conn_id, uint16_t start_handle, uint16_t end_handle) +{ + T_GAP_CAUSE cause; + cause = client_all_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR4("gcs_all_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x", + conn_id, cause, start_handle, end_handle); + } + else + { + gcs_table[conn_id].discov_type = GCS_ALL_CHAR_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_by_uuid_char_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16) +{ + T_GAP_CAUSE cause; + cause = client_by_uuid_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle, uuid16); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR5("gcs_by_uuid_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, uuid16 0x%x", + conn_id, cause, start_handle, end_handle, uuid16); + } + else + { + gcs_table[conn_id].discov_type = GCS_BY_UUID_CHAR_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_by_uuid128_char_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint8_t *p_uuid128) +{ + T_GAP_CAUSE cause; + cause = client_by_uuid128_char_discovery(conn_id, gcs_cl_id, start_handle, end_handle, p_uuid128); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR5("gcs_by_uuid128_char_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, p_uuid128 %p", + conn_id, cause, start_handle, end_handle, p_uuid128); + } + else + { + gcs_table[conn_id].discov_type = GCS_BY_UUID128_CHAR_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_all_char_descriptor_discovery(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle) +{ + T_GAP_CAUSE cause; + cause = client_all_char_descriptor_discovery(conn_id, gcs_cl_id, start_handle, end_handle); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR4("gcs_all_char_descriptor_discovery: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x", + conn_id, cause, start_handle, end_handle); + } + else + { + gcs_table[conn_id].discov_type = GCS_ALL_CHAR_DESC_DISCOV; + } + return cause; +} + +T_GAP_CAUSE gcs_attr_read(uint8_t conn_id, uint16_t handle) +{ + T_GAP_CAUSE cause; + cause = client_attr_read(conn_id, gcs_cl_id, handle); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR3("gcs_attr_read: failed, conn_id %d, cause %d, handle 0x%x", + conn_id, cause, handle); + } + return cause; +} + +T_GAP_CAUSE gcs_attr_read_using_uuid16(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint16_t uuid16) +{ + T_GAP_CAUSE cause; + cause = client_attr_read_using_uuid(conn_id, gcs_cl_id, start_handle, end_handle, uuid16, NULL); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR5("gcs_attr_read_using_uuid16: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, uuid16 0x%x", + conn_id, cause, start_handle, end_handle, uuid16); + } + return cause; +} + +T_GAP_CAUSE gcs_attr_read_using_uuid128(uint8_t conn_id, uint16_t start_handle, + uint16_t end_handle, uint8_t *p_uuid128) +{ + T_GAP_CAUSE cause; + cause = client_attr_read_using_uuid(conn_id, gcs_cl_id, start_handle, end_handle, 0, p_uuid128); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR5("gcs_attr_read_using_uuid128: failed, conn_id %d, cause %d, start_handle 0x%x, end_handle 0x%x, p_uuid128 %p", + conn_id, cause, start_handle, end_handle, p_uuid128); + } + return cause; +} + +T_GAP_CAUSE gcs_attr_ind_confirm(uint8_t conn_id) +{ + T_GAP_CAUSE cause; + cause = client_attr_ind_confirm(conn_id); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR2("gcs_attr_ind_confirm: failed, conn_id %d, cause %d", + conn_id, cause); + } + return cause; +} + +T_GAP_CAUSE gcs_attr_write(uint8_t conn_id, T_GATT_WRITE_TYPE write_type, uint16_t handle, + uint16_t length, uint8_t *p_data) +{ + T_GAP_CAUSE cause; + cause = client_attr_write(conn_id, gcs_cl_id, write_type, handle, length, p_data); + if (cause != GAP_CAUSE_SUCCESS) + { + APP_PRINT_ERROR5("gcs_attr_write: failed, conn_id %d, cause %d, write_type %d, handle 0x%x, length %d", + conn_id, cause, write_type, handle, length); + } + return cause; +} + +static bool gcs_client_add_discov_result(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + T_GCS_LINK *p_gcs_link; + T_GCS_DISCOV_RESULT *p_discov_result; + if (conn_id >= gcs_link_num) + { + APP_PRINT_ERROR1("gcs_client_add_discov_result: invalid conn_id %d", conn_id); + return false; + } + p_gcs_link = &gcs_table[conn_id]; + if (p_gcs_link->result_num >= gcs_max_discov_table_num) + { + APP_PRINT_ERROR1("gcs_client_add_discov_result: failed, gcs_max_discov_table_num %d", + gcs_max_discov_table_num); + return false; + } + p_discov_result = &(p_gcs_link->p_result_table[p_gcs_link->result_num]); + memcpy(&(p_discov_result->result_data), result_data.p_srv_disc_data, + sizeof(T_GCS_DISCOV_RESULT_DATA)); + p_discov_result->result_type = result_type; + p_gcs_link->result_num += 1; + return true; +} + +static bool gcs_client_clear_discov_table(uint8_t conn_id) +{ + if (conn_id < gcs_link_num) + { + gcs_table[conn_id].result_num = 0; + return true; + } + return false; +} + +static void gcs_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + T_GCS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = GCS_CLIENT_CB_TYPE_DISC_RESULT; + cb_data.cb_content.discov_result.discov_type = gcs_table[conn_id].discov_type; + APP_PRINT_INFO1("gcs discovery_state %d", discovery_state); + if (discovery_state == DISC_STATE_FAILED || gcs_table[conn_id].result_num == 0) + { + cb_data.cb_content.discov_result.is_success = false; + cb_data.cb_content.discov_result.result_num = 0; + cb_data.cb_content.discov_result.p_result_table = NULL; + } + else + { + cb_data.cb_content.discov_result.is_success = true; + cb_data.cb_content.discov_result.result_num = gcs_table[conn_id].result_num; + cb_data.cb_content.discov_result.p_result_table = gcs_table[conn_id].p_result_table; + } + if (gcs_client_cb) + { + (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data); + } + gcs_client_clear_discov_table(conn_id); + return; +} + +static void gcs_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("gcs_client_discover_result_cb: result_type = %d", result_type); + gcs_client_add_discov_result(conn_id, result_type, result_data); + + return; +} + +static void gcs_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_GCS_CLIENT_CB_DATA cb_data; + APP_PRINT_INFO2("gcs_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + + cb_data.cb_type = GCS_CLIENT_CB_TYPE_READ_RESULT; + cb_data.cb_content.read_result.cause = cause; + cb_data.cb_content.read_result.handle = handle; + cb_data.cb_content.read_result.value_size = value_size; + cb_data.cb_content.read_result.p_value = p_value; + + if (gcs_client_cb) + { + (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data); + } + + return; +} + +static void gcs_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_GCS_CLIENT_CB_DATA cb_data; + APP_PRINT_INFO2("gcs_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + + cb_data.cb_type = GCS_CLIENT_CB_TYPE_WRITE_RESULT; + cb_data.cb_content.write_result.cause = cause; + cb_data.cb_content.write_result.handle = handle; + cb_data.cb_content.write_result.type = type; + + if (gcs_client_cb) + { + (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data); + } + return; +} + +static T_APP_RESULT gcs_client_notify_ind_cb(uint8_t conn_id, bool notify, + uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_GCS_CLIENT_CB_DATA cb_data; + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + + cb_data.cb_type = GCS_CLIENT_CB_TYPE_NOTIF_IND; + cb_data.cb_content.notif_ind.notify = notify; + cb_data.cb_content.notif_ind.handle = handle; + cb_data.cb_content.notif_ind.value_size = value_size; + cb_data.cb_content.notif_ind.p_value = p_value; + + if (gcs_client_cb) + { + app_result = (*gcs_client_cb)(gcs_cl_id, conn_id, &cb_data); + } + return app_result; +} + +static void gcs_client_disc_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("gcs_client_disc_cb."); + if (conn_id < gcs_link_num) + { + gcs_table[conn_id].result_num = 0; + } +} + +/** + * @brief GATTS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS gcs_client_cbs = +{ + gcs_client_discover_state_cb, //!< Discovery State callback function pointer + gcs_client_discover_result_cb, //!< Discovery result callback function pointer + gcs_client_read_result_cb, //!< Read response callback function pointer + gcs_client_write_result_cb, //!< Write result callback function pointer + gcs_client_notify_ind_cb, //!< Notify Indicate callback function pointer + gcs_client_disc_cb //!< Link disconnection callback function pointer +}; + +T_CLIENT_ID gcs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num, + uint16_t max_discov_table_size) +{ + uint8_t i; + uint16_t size; + if (link_num > GCS_MAX_LINKS) + { + APP_PRINT_ERROR1("gcs_add_client: invalid link_num %d", link_num); + return 0xff; + } + + gcs_client_cb = app_cb; + gcs_link_num = link_num; + gcs_max_discov_table_num = max_discov_table_size; + size = gcs_link_num * sizeof(T_GCS_LINK); + gcs_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + if (gcs_table == NULL) + { + APP_PRINT_ERROR0("gcs_add_client: allocate link table mem fail"); + gcs_cl_id = 0xff; + return gcs_cl_id; + } + size = gcs_max_discov_table_num * sizeof(T_GCS_DISCOV_RESULT); + for (i = 0; i < gcs_link_num; i++) + { + + gcs_table[i].p_result_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + if (gcs_table[i].p_result_table == NULL) + { + APP_PRINT_ERROR0("gcs_add_client: allocate discov table mem fail"); + gcs_cl_id = 0xff; + return gcs_cl_id; + } + } + if (false == client_register_spec_client_cb(&gcs_cl_id, &gcs_client_cbs)) + { + gcs_cl_id = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("gcs_add_client: register fail"); + return gcs_cl_id; + } + + APP_PRINT_INFO1("gcs_add_client: client id %d", gcs_cl_id); + return gcs_cl_id; +} + diff --git a/src/ble/profile/client/hids_client.c b/src/ble/profile/client/hids_client.c new file mode 100644 index 0000000..46f8941 --- /dev/null +++ b/src/ble/profile/client/hids_client.c @@ -0,0 +1,1139 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_client.c + * @brief + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef enum +{ + HDIS_REPORT_VALUE_HANDLE, + HDIS_REPORT_CCCD_HANDLE, + HDIS_REPORT_REF_HANDLE +} T_HIDS_HANDLE_TYPE; + +/** + * @brief HID Host Link control block definition. + */ +typedef struct +{ + T_HIDS_CLIENT_DISC_STATE disc_state; + bool enable_cccd_proc; + uint8_t *p_report_map; //allocate mem + uint16_t report_map_len; + uint8_t report_idx; + uint8_t read_proc_flag; + uint8_t read_flags; + uint8_t protocol_mode; + uint8_t report_num; + HID_INFO_ATTRB hids_info; + uint16_t hdl_cache[HDL_HIDS_CACHE_LEN]; + T_HIDS_CLIENT_REPORT report[HIDS_CLIENT_MAX_REPORT_NUM]; +} T_HIDS_CLIENT_LINK, *P_HIDS_CLIENT_LINK; + +static P_HIDS_CLIENT_LINK hids_client_table; +static uint8_t hids_client_link_num; + +/**< HID client ID. */ +static T_CLIENT_ID hids_client_id = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from HID client layer. */ +static P_FUN_GENERAL_APP_CB hids_client_cb = NULL; + + +T_HIDS_CLIENT_REPORT *hids_report_add(uint8_t conn_id, uint16_t hdl_report_value) +{ + T_HIDS_CLIENT_LINK *p_hids_link; + T_HIDS_CLIENT_REPORT *p_report = NULL; + PROFILE_PRINT_INFO2("[HIDS]: hids_report_add: conn_id %d, reprot value handle 0x%x", conn_id, + hdl_report_value); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_report_add: failed, invalid conn_id %d", conn_id); + return NULL; + } + p_hids_link = &hids_client_table[conn_id]; + if (p_hids_link->report_num >= HIDS_CLIENT_MAX_REPORT_NUM) + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_report_add: failed, exceed HIDS_CLIENT_MAX_REPORT_NUM"); + return NULL; + } + p_report = &p_hids_link->report[p_hids_link->report_num]; + p_report->hdl_report_value = hdl_report_value; + p_hids_link->report_num++; + + PROFILE_PRINT_INFO1("[HIDS]: hids_report_add: report_num 0x%x", p_hids_link->report_num); + + return p_report; +} + +T_HIDS_CLIENT_REPORT *hids_report_find_by_handle(uint8_t conn_id, T_HIDS_HANDLE_TYPE type, + uint16_t handle) +{ + uint8_t i; + T_HIDS_CLIENT_LINK *p_hids_link; + T_HIDS_CLIENT_REPORT *p_report = NULL; + PROFILE_PRINT_INFO1("[HIDS]: hids_report_find_by_handle: conn_id %d", conn_id); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_report_find_by_handle: failed, invalid conn_id %d", conn_id); + return NULL; + } + p_hids_link = &hids_client_table[conn_id]; + + for (i = 0; i < p_hids_link->report_num; i++) + { + uint16_t compare_handle; + p_report = &p_hids_link->report[i]; + if (type == HDIS_REPORT_VALUE_HANDLE) + { + compare_handle = p_report->hdl_report_value; + } + else if (type == HDIS_REPORT_CCCD_HANDLE) + { + compare_handle = p_report->hdl_report_cccd; + } + else + { + compare_handle = p_report->hdl_report_reference; + } + if (compare_handle == handle) + { + return p_report; + } + } + GAP_PRINT_ERROR0("[HIDS]: hids_report_find_by_handle: not found"); + return NULL; +} + +T_HIDS_CLIENT_REPORT *hids_report_find_by_id(uint8_t conn_id, uint8_t report_id, + T_HIDS_REPORT_TYPE type) +{ + uint8_t i; + T_HIDS_CLIENT_LINK *p_hids_link; + T_HIDS_CLIENT_REPORT *p_report = NULL; + PROFILE_PRINT_INFO1("[HIDS]: hids_report_find_by_id: conn_id %d", conn_id); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_report_find_by_id: failed, invalid conn_id %d", conn_id); + return NULL; + } + p_hids_link = &hids_client_table[conn_id]; + + for (i = 0; i < p_hids_link->report_num; i++) + { + p_report = &p_hids_link->report[i]; + + if ((p_report->report_ref.report_id == report_id) + && ((p_report->report_ref.report_type == type) || type == HIDS_RESERVED_REPORT)) + { + return p_report; + } + } + GAP_PRINT_ERROR0("[HIDS]: hids_report_find_by_id: not found"); + return NULL; +} + +T_HIDS_CLIENT_REPORT *hids_report_check_desc_handle(uint8_t conn_id, uint16_t handle) +{ + uint8_t i; + T_HIDS_CLIENT_LINK *p_hids_link; + T_HIDS_CLIENT_REPORT *p_report = NULL; + PROFILE_PRINT_INFO2("[HIDS]: hids_report_check_desc_handle: conn_id %d, handle 0x%x", conn_id, + handle); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_report_check_desc_handle: failed, invalid conn_id %d", conn_id); + return NULL; + } + p_hids_link = &hids_client_table[conn_id]; + + for (i = 0; i < p_hids_link->report_num; i++) + { + p_report = &p_hids_link->report[i]; + if ((handle == p_report->hdl_report_value + 1) || + (handle == p_report->hdl_report_value + 2)) + { + return p_report; + } + } + GAP_PRINT_ERROR0("[HIDS]: hids_report_check_desc_handle: not found"); + return NULL; +} + +/** + * @brief Used by application, to start the discovery procedure of battery service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hiddis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = hid_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool hids_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("[HIDS]: hids_start_discovery"); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hid_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + if (hids_client_table[conn_id].p_report_map != NULL) + { + os_mem_free(hids_client_table[conn_id].p_report_map); + } + memset(&hids_client_table[conn_id], 0, sizeof(T_HIDS_CLIENT_LINK)); + hids_client_table[conn_id].disc_state = DISC_HIDS_START; + if (client_by_uuid_srv_discovery(conn_id, hids_client_id, + GATT_UUID_HID) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +bool hids_enable_all_cccd(uint8_t conn_id) +{ + uint8_t i; + uint16_t cccd_bits = 1; + PROFILE_PRINT_INFO0("[HIDS]: hids_enable_all_cccd"); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_enable_all_cccd: failed invalid conn_id %d", conn_id); + return false; + } + if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE || + hids_client_table[conn_id].enable_cccd_proc) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_enable_all_cccd: failed invalid state %d", + hids_client_table[conn_id].disc_state); + return false; + } + + for (i = 0; i < hids_client_table[conn_id].report_num; i++) + { + if (hids_client_table[conn_id].report[i].hdl_report_cccd != 0) + { + if (client_attr_write(conn_id, hids_client_id, GATT_WRITE_TYPE_REQ, + hids_client_table[conn_id].report[i].hdl_report_cccd, + sizeof(uint16_t), (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + hids_client_table[conn_id].report_idx = i; + hids_client_table[conn_id].enable_cccd_proc = true; + return true; + } + else + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_enable_all_cccd: call client_attr_write failed"); + return false; + } + } + } + return true; +} + +bool hids_write_report(uint8_t conn_id, uint8_t report_id, T_HIDS_REPORT_TYPE report_type, + uint16_t length, uint8_t *p_value, T_GATT_WRITE_TYPE type) +{ + T_HIDS_CLIENT_REPORT *p_report; + PROFILE_PRINT_INFO0("[HIDS]: hids_write_report"); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_write_report: failed invalid conn_id %d", conn_id); + return false; + } + + p_report = hids_report_find_by_id(conn_id, report_id, report_type); + if (p_report != NULL) + { + + if (client_attr_write(conn_id, hids_client_id, type, + p_report->hdl_report_value, + length, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + else + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_write_report: call client_attr_write failed"); + return false; + } + } + + return false; +} + +bool hids_read_saved_data(uint8_t conn_id, T_HIDS_READ_TYPE read_type, T_HIDS_READ_VALUE *p_value) +{ + bool ret = true; + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_read_saved_data: failed invalid conn_id %d", conn_id); + return false; + } + switch (read_type) + { + case HIDS_READ_PROTOCOL_MODE: + { + if (hids_client_table[conn_id].read_flags & HIDS_READ_PROTOCOL_MODE_BIT) + { + p_value->value_size = 1; + p_value->p_value = &hids_client_table[conn_id].protocol_mode; + } + else + { + ret = false; + } + } + break; + + case HIDS_READ_REPORT_MAP: + { + if (hids_client_table[conn_id].read_flags & HIDS_READ_REPORT_MAP_BIT) + { + p_value->value_size = hids_client_table[conn_id].report_map_len; + p_value->p_value = hids_client_table[conn_id].p_report_map; + } + else + { + ret = false; + } + } + break; + + case HIDS_READ_HID_INFO: + { + if (hids_client_table[conn_id].read_flags & HIDS_READ_HID_INFO_BIT) + { + p_value->value_size = sizeof(HID_INFO_ATTRB); + p_value->p_value = (uint8_t *)&hids_client_table[conn_id].hids_info; + } + else + { + ret = false; + } + + } + break; + + default: + { + ret = false; + + } + break; + } + + if (ret == false) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_read_saved_data failed: read_type %d", read_type); + } + + return ret; +} + +void hids_print_infos(uint8_t conn_id) +{ + int8_t i; + PROFILE_PRINT_INFO1("[HIDS]: hids_print_infos: conn_id %d", conn_id); + if (conn_id >= hids_client_link_num) + { + return; + } + for (i = 0; i < HDL_HIDS_CACHE_LEN; i++) + { + PROFILE_PRINT_INFO2("[HIDS]: hdl_cache[%d]: 0x%x", i, hids_client_table[conn_id].hdl_cache[i]); + } + for (i = 0; i < hids_client_table[conn_id].report_num; i++) + { + PROFILE_PRINT_INFO3("[HIDS]: report[%d]: report_id 0x%x, report_type 0x%x", + i, hids_client_table[conn_id].report[i].report_ref.report_id, + hids_client_table[conn_id].report[i].report_ref.report_type); + PROFILE_PRINT_INFO3(" hdl_report_value 0x%x, hdl_report_cccd 0x%x, hdl_report_reference 0x%x", + hids_client_table[conn_id].report[i].hdl_report_value, + hids_client_table[conn_id].report[i].hdl_report_cccd, + hids_client_table[conn_id].report[i].hdl_report_reference); + } + PROFILE_PRINT_INFO5("[HIDS]: read_flags 0x%x, protocol_mode 0x%x, hids_info %b, report_map[%d] %b", + hids_client_table[conn_id].read_flags, + hids_client_table[conn_id].protocol_mode, + TRACE_BINARY(4, &hids_client_table[conn_id].hids_info), + hids_client_table[conn_id].report_map_len, + TRACE_BINARY(hids_client_table[conn_id].report_map_len, hids_client_table[conn_id].p_report_map)); + +} + +bool hids_read(uint8_t conn_id, T_HIDS_READ_TYPE read_type) +{ + uint16_t handle = 0; + PROFILE_PRINT_INFO1("[HIDS]: hids_read: type %d", read_type); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_read: failed invalid conn_id %d", conn_id); + return false; + } + + if (read_type == HIDS_READ_PROTOCOL_MODE) + { + handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE]; + } + else if (read_type == HIDS_READ_REPORT_MAP) + { + handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_REPORT_MAP]; + } + else if (read_type == HIDS_READ_HID_INFO) + { + handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_HID_INFO]; + } + + if (handle) + { + if (client_attr_read(conn_id, hids_client_id, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + PROFILE_PRINT_ERROR0("[HIDS]: hids_read: failed"); + return false; +} + +void hids_start_read(uint8_t conn_id, uint16_t cause) +{ + bool cb_flag = false; + T_HIDS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = HIDS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO2("[HIDS]: hids_start_read: read_proc_flag 0x%x, cause 0x%x", + hids_client_table[conn_id].read_proc_flag, cause); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_start_read: failed invalid conn_id %d", conn_id); + return; + } + + if (hids_client_table[conn_id].report_idx == hids_client_table[conn_id].report_num) + { + hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_REPORT_REF_BIT; + hids_client_table[conn_id].report_idx = 0; + } + + if ((cause == GAP_SUCCESS) && (hids_client_table[conn_id].read_proc_flag != 0)) + { + do + { + if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_PROTOCOL_MODE_BIT) + { + hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_PROTOCOL_MODE_BIT; + if (hids_read(conn_id, HIDS_READ_PROTOCOL_MODE)) + { + break; + } + } + if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_HID_INFO_BIT) + { + hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_HID_INFO_BIT; + if (hids_read(conn_id, HIDS_READ_HID_INFO) == false) + { + cb_flag = true; + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + } + break; + } + + if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_REPORT_MAP_BIT) + { + hids_client_table[conn_id].read_proc_flag &= ~HIDS_READ_REPORT_MAP_BIT; + if (hids_read(conn_id, HIDS_READ_REPORT_MAP) == false) + { + cb_flag = true; + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + } + break; + } + if (hids_client_table[conn_id].read_proc_flag & HIDS_READ_REPORT_REF_BIT) + { + uint16_t handle = + hids_client_table[conn_id].report[hids_client_table[conn_id].report_idx].hdl_report_reference; + if (handle) + { + if (client_attr_read(conn_id, hids_client_id, handle) == GAP_CAUSE_SUCCESS) + { + break; + } + } + cb_flag = true; + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + } + } + while (0); + } + else + { + if (cause == GAP_SUCCESS) + { + cb_flag = true; + hids_client_table[conn_id].disc_state = DISC_HIDS_DONE; + } + else + { + cb_flag = true; + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && hids_client_cb) + { + cb_data.cb_content.disc_state = hids_client_table[conn_id].disc_state; + (*hids_client_cb)(hids_client_id, conn_id, &cb_data); + } +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in,out] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hidhdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + T_HIDS_CLIENT_STORAGE_INFO hids_client_info; + bool ret = hids_get_hdl_cache(conn_id, (&hids_client_info)); + ...... + } + * \endcode + */ +bool hids_get_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info) +{ + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_get_hdl_cache: failed invalid state %d", + hids_client_table[conn_id].disc_state); + return false; + } + + memcpy(p_storage_info, (&(hids_client_table[conn_id].read_flags)), + sizeof(T_HIDS_CLIENT_STORAGE_INFO)); + p_storage_info->read_flags &= ~HIDS_READ_REPORT_MAP_BIT; + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_HID_FLAG) + { + hids_set_hdl_cache(conn_id, (&(app_srvs_table.hids_client_info))); + } + if (!(app_srvs_table.hids_client_info.read_flags & HIDS_READ_REPORT_MAP_BIT)) + { + APP_PRINT_INFO0("app_discov_services: read report map"); + hids_read_report_map(conn_id); + } + ...... + } + * \endcode + */ +bool hids_set_hdl_cache(uint8_t conn_id, T_HIDS_CLIENT_STORAGE_INFO *p_storage_info) +{ + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (hids_client_table[conn_id].disc_state != DISC_HIDS_IDLE) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_set_hdl_cache: failed invalid state %d", + hids_client_table[conn_id].disc_state); + return false; + } + + memcpy((&(hids_client_table[conn_id].read_flags)), p_storage_info, + sizeof(T_HIDS_CLIENT_STORAGE_INFO)); + hids_client_table[conn_id].disc_state = DISC_HIDS_DONE; + return true; +} + +bool hids_read_report_map(uint8_t conn_id) +{ + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_read_report_map: failed invalid conn_id %d", conn_id); + return false; + } + if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_read_report_map: failed invalid state %d", + hids_client_table[conn_id].disc_state); + return false; + } + return hids_read(conn_id, HIDS_READ_REPORT_MAP); +} + +bool hids_handle_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value) +{ + if (hids_client_table[conn_id].p_report_map != NULL) + { + os_mem_free(hids_client_table[conn_id].p_report_map); + } + + hids_client_table[conn_id].p_report_map = os_mem_zalloc(RAM_TYPE_DATA_ON, value_size); + if (hids_client_table[conn_id].p_report_map != NULL) + { + memcpy(hids_client_table[conn_id].p_report_map, p_value, value_size); + hids_client_table[conn_id].report_map_len = value_size; + hids_client_table[conn_id].read_flags |= HIDS_READ_REPORT_MAP_BIT; + PROFILE_PRINT_INFO0("[HIDS]: hids_handle_report_map: handle report map success"); + return true; + } + else + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_handle_report_map: handle report map failed, allocate memory failed"); + return false; + } +} + +bool hids_set_report_map(uint8_t conn_id, uint16_t value_size, uint8_t *p_value) +{ + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_set_report_map: failed invalid conn_id %d", conn_id); + return false; + } + if (hids_client_table[conn_id].disc_state != DISC_HIDS_DONE) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_set_report_map: failed invalid state %d", + hids_client_table[conn_id].disc_state); + return false; + } + + if (value_size != 0) + { + if (hids_handle_report_map(conn_id, value_size, p_value)) + { + PROFILE_PRINT_INFO0("[HIDS]: hids_set_report_map: configuration of report map success"); + return true; + } + else + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_set_report_map: configuration of report map failed"); + return false; + } + } + else + { + PROFILE_PRINT_ERROR0("[HIDS]: hids_set_report_map: configuration of report map failed, invalid size"); + return false; + } +} + +static bool hids_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("[HIDS]: hids_client_start_char_discovery"); + start_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START]; + end_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END]; + if (client_all_char_discovery(conn_id, hids_client_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool hids_client_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("[HIDS]: hids_client_start_char_descriptor_discovery"); + start_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START]; + end_handle = hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, hids_client_id, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void hids_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_HIDS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = HIDS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("[HIDS]: hids_client_discover_state_cb: discovery_state = %d", discovery_state); + if (hids_client_table[conn_id].disc_state == DISC_HIDS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START] != 0) + || (hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END] != 0)) + { + if (hids_client_start_char_discovery(conn_id) == false) + { + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + cb_flag = true; + } + } + /* No HID handle found. Discover procedure complete. */ + else + { + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + if (hids_client_table[conn_id].hdl_cache[HDL_HIDS_CHAR_REPORT_MAP] != 0) + { + //discovery cccd + if (hids_client_start_char_descriptor_discovery(conn_id) == false) + { + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + cb_flag = true; + } + } + else + { + hids_client_table[conn_id].disc_state = DISC_HIDS_DONE; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + hids_client_table[conn_id].read_proc_flag = HIDS_READ_HID_INFO_BIT | HIDS_READ_PROTOCOL_MODE_BIT | + HIDS_READ_REPORT_MAP_BIT | HIDS_READ_REPORT_REF_BIT; + hids_start_read(conn_id, GAP_SUCCESS); + break; + + case DISC_STATE_FAILED: + hids_client_table[conn_id].disc_state = DISC_HIDS_FAILED; + cb_flag = true; + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && hids_client_cb) + { + cb_data.cb_content.disc_state = hids_client_table[conn_id].disc_state; + (*hids_client_cb)(hids_client_id, conn_id, &cb_data); + } + return; +} + + +static void hids_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("[HIDS]: hids_client_discover_result_cb: result_type = %d", result_type); + if (hids_client_table[conn_id].disc_state == DISC_HIDS_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = hids_client_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + hids_client_table[conn_id].hdl_cache[HDL_HIDS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_HID_INFO: + hdl_cache[HDL_HIDS_CHAR_HID_INFO] = handle; + break; + + case GATT_UUID_CHAR_REPORT_MAP: + hdl_cache[HDL_HIDS_CHAR_REPORT_MAP] = handle; + break; + + case GATT_UUID_CHAR_HID_CONTROL_POINT: + hdl_cache[HDL_HIDS_CHAR_HID_CONTROL_POINT] = handle; + break; + + case GATT_UUID_CHAR_PROTOCOL_MODE: + hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE] = handle; + break; + + case GATT_UUID_CHAR_REPORT: + { + hids_report_add(conn_id, handle); + } + break; + + default: + /* have no intrest on this handle. */ + break; + } + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + handle = result_data.p_char_desc_uuid16_disc_data->handle; + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + T_HIDS_CLIENT_REPORT *p_report = hids_report_check_desc_handle(conn_id, handle); + if (p_report != NULL) + { + p_report->hdl_report_cccd = handle; + PROFILE_PRINT_INFO1("[HIDS]: Found report cccd handle 0x%x", handle); + } + } + else if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_REPORT_REFERENCE) + { + T_HIDS_CLIENT_REPORT *p_report = hids_report_check_desc_handle(conn_id, handle); + if (p_report != NULL) + { + p_report->hdl_report_reference = handle; + PROFILE_PRINT_INFO1("[HIDS]: Found report ref handle 0x%x", handle); + + } + } + break; + + default: + PROFILE_PRINT_ERROR0("[HIDS]: Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void hids_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_HIDS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = HIDS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("[HIDS]: hids_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (hids_client_table[conn_id].enable_cccd_proc) + { + if (cause == GAP_SUCCESS) + { + uint8_t i = hids_client_table[conn_id].report_idx; + uint16_t cccd_bits = 1; + + if (handle == hids_client_table[conn_id].report[i].hdl_report_cccd) + { + i++; + for (; i < hids_client_table[conn_id].report_num; i++) + { + if (hids_client_table[conn_id].report[i].hdl_report_cccd != 0) + { + if (client_attr_write(conn_id, hids_client_id, GATT_WRITE_TYPE_REQ, + hids_client_table[conn_id].report[i].hdl_report_cccd, + sizeof(uint16_t), (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + hids_client_table[conn_id].report_idx = i; + hids_client_table[conn_id].enable_cccd_proc = true; + return; + } + else + { + cb_data.cb_content.write_result.cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: hids_enable_all_cccd: call client_attr_write failed"); + } + } + } + } + else + { + cb_data.cb_content.write_result.cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR2("[HIDS]: hids_client_write_result_cb: invalid cccd handle 0x%x, hande 0x%x", + handle, hids_client_table[conn_id].report[i].hdl_report_cccd); + } + } + hids_client_table[conn_id].report_idx = 0; + hids_client_table[conn_id].enable_cccd_proc = false; + cb_data.cb_content.write_result.type = HIDS_WRITE_ALL_REPORT_CCCD; + } + else + { + T_HIDS_CLIENT_REPORT *p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_VALUE_HANDLE, + handle); + if (p_report != NULL) + { + cb_data.cb_content.write_result.type = HIDS_WRITE_REPORT; + cb_data.cb_content.write_result.report_ref = p_report->report_ref; + } + else + { + return; + } + } + + if (hids_client_cb) + { + (*hids_client_cb)(hids_client_id, conn_id, &cb_data); + } + return; +} + +static void hids_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + uint16_t *hdl_cache; + hdl_cache = hids_client_table[conn_id].hdl_cache; + if (hids_client_table[conn_id].disc_state == DISC_HIDS_START) + { + if (cause == ATT_SUCCESS) + { + if (handle == hdl_cache[HDL_HIDS_CHAR_HID_INFO]) + { + if (value_size == 4) + { + memcpy(&(hids_client_table[conn_id].hids_info), p_value, value_size); + hids_client_table[conn_id].read_flags |= HIDS_READ_HID_INFO_BIT; + PROFILE_PRINT_INFO0("[HIDS]: Read hid info success"); + } + else + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: Read hid info failed, invalid size"); + } + } + else if (handle == hdl_cache[HDL_HIDS_CHAR_REPORT_MAP]) + { + if (value_size != 0) + { + if (!(hids_handle_report_map(conn_id, value_size, p_value))) + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + } + } + else + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: Read report map failed, invalid size"); + } + } + else if (handle == hdl_cache[HDL_HIDS_CHAR_PROTOCOL_MODE]) + { + if (value_size == 1) + { + hids_client_table[conn_id].protocol_mode = *p_value; + hids_client_table[conn_id].read_flags |= HIDS_READ_PROTOCOL_MODE_BIT; + PROFILE_PRINT_INFO0("[HIDS]: Read protocol mode success"); + } + else + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: Read protocol mode failed, invalid size"); + } + } + else + { + T_HIDS_CLIENT_REPORT *p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_REF_HANDLE, + handle); + if (p_report != NULL && value_size == 2) + { + p_report->report_ref.report_id = *p_value; + p_report->report_ref.report_type = (T_HIDS_REPORT_TYPE) * (p_value + 1); + } + else + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: Read report ref, invalid size"); + } + hids_client_table[conn_id].report_idx++; + } + hids_start_read(conn_id, cause); + } + else + { + hids_start_read(conn_id, cause); + } + } + else if (hids_client_table[conn_id].disc_state == DISC_HIDS_DONE) + { + if (handle == hdl_cache[HDL_HIDS_CHAR_REPORT_MAP]) + { + T_HIDS_CLIENT_CB_DATA cb_data; + + if (cause == ATT_SUCCESS) + { + if (value_size != 0) + { + if (!(hids_handle_report_map(conn_id, value_size, p_value))) + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + } + } + else + { + cause = GATT_ERR | GATT_ERR_INVALID_PARAM; + PROFILE_PRINT_ERROR0("[HIDS]: Read report map failed, invalid size"); + } + } + + cb_data.cb_type = HIDS_CLIENT_CB_TYPE_READ_RESULT; + cb_data.cb_content.read_result.type = HIDS_READ_RESULT_REPORT_MAP; + cb_data.cb_content.read_result.cause = cause; + (*hids_client_cb)(hids_client_id, conn_id, &cb_data); + } + } + return; +} + +static T_APP_RESULT hids_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_HIDS_CLIENT_CB_DATA cb_data; + T_HIDS_CLIENT_REPORT *p_report; + cb_data.cb_type = HIDS_CLIENT_CB_TYPE_NOTIF_RESULT; + + p_report = hids_report_find_by_handle(conn_id, HDIS_REPORT_VALUE_HANDLE, handle); + if (p_report == NULL) + { + return APP_RESULT_SUCCESS; + } + cb_data.cb_content.notify_data.type = HIDS_REPORT_NOTIFY; + cb_data.cb_content.notify_data.data.report_id = p_report->report_ref.report_id; + cb_data.cb_content.notify_data.data.value_size = value_size; + cb_data.cb_content.notify_data.data.p_value = p_value; + + if (hids_client_cb) + { + app_result = (*hids_client_cb)(hids_client_id, conn_id, &cb_data); + } + + return app_result; +} + +static void hids_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("[HIDS]: hids_client_disc_cb."); + if (conn_id >= hids_client_link_num) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + if (hids_client_table[conn_id].p_report_map != NULL) + { + os_mem_free(hids_client_table[conn_id].p_report_map); + } + memset(&hids_client_table[conn_id], 0, sizeof(T_HIDS_CLIENT_LINK)); + return; +} + +/** + * @brief HID Client Callbacks. +*/ +const T_FUN_CLIENT_CBS hids_client_cbs = +{ + hids_client_discover_state_cb, //!< Discovery State callback function pointer + hids_client_discover_result_cb, //!< Discovery result callback function pointer + hids_client_read_result_cb, //!< Read response callback function pointer + hids_client_write_result_cb, //!< Write result callback function pointer + hids_client_notify_ind_cb, //!< Notify Indicate callback function pointer + hids_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add hid client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + hids_client_id = hid_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID hids_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > HIDS_CLIENT_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("[HIDS]: hids_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&hids_client_id, &hids_client_cbs)) + { + hids_client_id = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("[HIDS]: hids_add_client:register fail"); + return hids_client_id; + } + PROFILE_PRINT_INFO1("[HIDS]: hids_add_client: client id %d", hids_client_id); + + /* register callback for profile to inform application that some events happened. */ + hids_client_cb = app_cb; + hids_client_link_num = link_num; + size = hids_client_link_num * sizeof(T_HIDS_CLIENT_LINK); + hids_client_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return hids_client_id; +} + diff --git a/src/ble/profile/client/hrs_client.c b/src/ble/profile/client/hrs_client.c new file mode 100644 index 0000000..4ce7f1a --- /dev/null +++ b/src/ble/profile/client/hrs_client.c @@ -0,0 +1,509 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hrs_client.c + * @brief + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +/** + * @brief HRS client Link control block definition. + */ +typedef struct +{ + T_HRS_DISC_STATE disc_state; + bool write_notify_value; + uint16_t properties; + uint16_t hdl_cache[HDL_HRS_CACHE_LEN]; +} T_HRS_LINK, *P_HRS_LINK; + +static P_HRS_LINK hrs_table; +static uint8_t hrs_link_num; + +/**< HRS client ID. */ +static T_CLIENT_ID hrs_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from HRS client layer. */ +static P_FUN_GENERAL_APP_CB hrs_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of heart rate service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hrsdis(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool ret = hrs_start_discovery(conn_id); + ...... + } + * \endcode + */ +bool hrs_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("hrs_start_discovery"); + if (conn_id >= hrs_link_num) + { + PROFILE_PRINT_ERROR1("hrs_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&hrs_table[conn_id], 0, sizeof(T_HRS_LINK)); + hrs_table[conn_id].disc_state = DISC_HRS_START; + if (client_by_uuid_srv_discovery(conn_id, hrs_client, + GATT_UUID_SERVICE_HEART_RATE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to set the notification flag of heart rate measurement. + * @param[in] conn_id connection ID. + * @param[in] notify value to enable or disable notify. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hrsmeascccd(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + bool notify = p_parse_value->dw_param[1]; + bool ret; + ret = hrs_set_heart_rate_measurement_notify(conn_id, notify); + ...... + } + * \endcode + */ +bool hrs_set_heart_rate_measurement_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= hrs_link_num) + { + PROFILE_PRINT_ERROR1("hrs_set_heart_rate_measurement_notify: failed invalid conn_id %d", conn_id); + return false; + } + if (hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT_CCCD]) + { + uint16_t handle = hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, hrs_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + hrs_table[conn_id].write_notify_value = notify; + return true; + } + } + PROFILE_PRINT_ERROR0("hrs_set_heart_rate_measurement_notify: false handle = 0"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_hrshdl(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint16_t hdl_cache[HDL_HRS_CACHE_LEN]; + bool ret = hrs_get_hdl_cache(conn_id, hdl_cache, + sizeof(uint16_t) * HDL_HRS_CACHE_LEN); + + ...... + } + * \endcode + */ +bool hrs_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= hrs_link_num) + { + PROFILE_PRINT_ERROR1("hrs_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (hrs_table[conn_id].disc_state != DISC_HRS_DONE) + { + PROFILE_PRINT_ERROR1("hrs_get_hdl_cache: failed invalid state %d", hrs_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_HRS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("hrs_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, hrs_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + * Example usage + * \code{.c} + void app_discov_services(uint8_t conn_id, bool start) + { + ...... + if (app_srvs_table.srv_found_flags & APP_DISCOV_HRS_FLAG) + { + hrs_set_hdl_cache(conn_id, app_srvs_table.hrs_hdl_cache, sizeof(uint16_t) * HDL_HRS_CACHE_LEN); + } + ...... + } + * \endcode + */ +bool hrs_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= hrs_link_num) + { + PROFILE_PRINT_ERROR1("hrs_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (hrs_table[conn_id].disc_state != DISC_HRS_IDLE) + { + PROFILE_PRINT_ERROR1("hrs_set_hdl_cache: failed invalid state %d", hrs_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_HRS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("hrs_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(hrs_table[conn_id].hdl_cache, p_hdl_cache, len); + hrs_table[conn_id].disc_state = DISC_HRS_DONE; + return true; +} + +static bool hrs_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("hrs_start_char_discovery"); + start_handle = hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_START]; + end_handle = hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_END]; + if (client_all_char_discovery(conn_id, hrs_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool hrs_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("hrs_start_char_descriptor_discovery"); + start_handle = hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT]; + end_handle = hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, hrs_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static void hrs_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_HRS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = HRS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("hrs_client_discover_state_cb: discovery_state = %d", discovery_state); + if (hrs_table[conn_id].disc_state == DISC_HRS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_START] != 0) + || (hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_END] != 0)) + { + if (hrs_start_char_discovery(conn_id) == false) + { + hrs_table[conn_id].disc_state = DISC_HRS_FAILED; + cb_flag = true; + } + } + /* No HRS handle found. Discover procedure complete. */ + else + { + hrs_table[conn_id].disc_state = DISC_HRS_FAILED; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DONE: + if (hrs_table[conn_id].properties & GATT_CHAR_PROP_NOTIFY) + { + //discovery cccd + if (hrs_start_char_descriptor_discovery(conn_id) == false) + { + hrs_table[conn_id].disc_state = DISC_HRS_FAILED; + cb_flag = true; + } + } + else + { + hrs_table[conn_id].disc_state = DISC_HRS_DONE; + cb_flag = true; + } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + hrs_table[conn_id].disc_state = DISC_HRS_DONE; + cb_flag = true; + break; + + case DISC_STATE_FAILED: + hrs_table[conn_id].disc_state = DISC_HRS_FAILED; + cb_flag = true; + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && hrs_client_cb) + { + cb_data.cb_content.disc_state = hrs_table[conn_id].disc_state; + (*hrs_client_cb)(hrs_client, conn_id, &cb_data); + } + return; +} + + +static void hrs_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("hrs_client_discover_result_cb: result_type = %d", result_type); + if (hrs_table[conn_id].disc_state == DISC_HRS_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + hrs_table[conn_id].hdl_cache[HDL_HRS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + uint16_t handle; + handle = result_data.p_char_uuid16_disc_data->value_handle; + if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT) + { + hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT] = handle; + hrs_table[conn_id].properties = result_data.p_char_uuid16_disc_data->properties; + } + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + uint16_t handle; + handle = result_data.p_char_desc_uuid16_disc_data->handle; + if (handle == hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT] + 1) + { + hrs_table[conn_id].hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT_CCCD] = handle; + } + } + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void hrs_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_HRS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = hrs_table[conn_id].hdl_cache; + cb_data.cb_type = HRS_CLIENT_CB_TYPE_READ_RESULT; + + PROFILE_PRINT_INFO2("hrs_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + if (handle == hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT]) + { + cb_data.cb_content.read_result.cause = cause; + } + + if (hrs_client_cb) + { + (*hrs_client_cb)(hrs_client, conn_id, &cb_data); + } + return; +} + +static void hrs_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_HRS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = hrs_table[conn_id].hdl_cache; + cb_data.cb_type = HRS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("hrs_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT_CCCD]) + { + if (hrs_table[conn_id].write_notify_value) + { + cb_data.cb_content.write_result.type = HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_ENABLE; + } + else + { + cb_data.cb_content.write_result.type = HRS_WRITE_HEART_RATE_MEASUREMENT_NOTIFY_DISABLE; + } + } + else + { + return; + } + + if (hrs_client_cb) + { + (*hrs_client_cb)(hrs_client, conn_id, &cb_data); + } + return; +} + +static T_APP_RESULT hrs_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_HRS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + + hdl_cache = hrs_table[conn_id].hdl_cache; + cb_data.cb_type = HRS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_HRS_HEART_RATE_MEASUREMENT]) + { + cb_data.cb_content.notify_data.type = HRS_FROM_HEART_RATE_MEASUREMENT; + cb_data.cb_content.notify_data.value_size = value_size; + cb_data.cb_content.notify_data.p_value = p_value; + } + else + { + return APP_RESULT_SUCCESS; + } + + if (hrs_client_cb) + { + app_result = (*hrs_client_cb)(hrs_client, conn_id, &cb_data); + } + + return app_result; +} + +static void hrs_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("hrs_client_disc_cb."); + if (conn_id >= hrs_link_num) + { + PROFILE_PRINT_ERROR1("hrs_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&hrs_table[conn_id], 0, sizeof(T_HRS_LINK)); + return; +} +/** + * @brief HRS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS hrs_client_cbs = +{ + hrs_client_discover_state_cb, //!< Discovery State callback function pointer + hrs_client_discover_result_cb, //!< Discovery result callback function pointer + hrs_client_read_result_cb, //!< Read response callback function pointer + hrs_client_write_result_cb, //!< Write result callback function pointer + hrs_client_notify_ind_cb, //!< Notify Indicate callback function pointer + hrs_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add hrs client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + hrs_client_id = hrs_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID hrs_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > HRS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("hrs_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&hrs_client, &hrs_client_cbs)) + { + hrs_client = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("hrs_add_client:register fail"); + return hrs_client; + } + PROFILE_PRINT_INFO1("hrs_add_client: client id %d", hrs_client); + + /* register callback for profile to inform application that some events happened. */ + hrs_client_cb = app_cb; + hrs_link_num = link_num; + size = hrs_link_num * sizeof(T_HRS_LINK); + hrs_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return hrs_client; +} + diff --git a/src/ble/profile/client/ias_client.c b/src/ble/profile/client/ias_client.c new file mode 100644 index 0000000..2f42a04 --- /dev/null +++ b/src/ble/profile/client/ias_client.c @@ -0,0 +1,533 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ias_client.c + * @brief Ias BLE client source file. + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_IAS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_IAS_CACHE_LEN]; +} T_IAS_LINK, *P_IAS_LINK; + +static P_IAS_LINK ias_table; +static uint8_t ias_link_num; + +/**< ias client ID. */ +static T_CLIENT_ID ias_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from ias client layer. */ +static P_FUN_GENERAL_APP_CB ias_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of ias server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ias_client_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("ias_client_start_discovery"); + if (conn_id >= ias_link_num) + { + PROFILE_PRINT_ERROR1("ias_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&ias_table[conn_id], 0, sizeof(T_IAS_LINK)); + ias_table[conn_id].disc_state = DISC_IAS_START; + if (client_by_uuid_srv_discovery(conn_id, ias_client, + GATT_UUID_IMMEDIATE_ALERT_SERVICE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool ias_client_read_by_handle(uint8_t conn_id, T_IAS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +//{ +// bool hdl_valid = false; +// uint16_t handle; +// if (conn_id >= ias_link_num) +// { +// PROFILE_PRINT_ERROR1("ias_client_read_by_handle: failed invalid conn_id %d", conn_id); +// return false; +// } + +// switch (read_type) +// { +// case IAS_READ_V1_READ: +// if (ias_table[conn_id].hdl_cache[HDL_IAS_V1_READ]) +// { +// handle = ias_table[conn_id].hdl_cache[HDL_IAS_V1_READ]; +// hdl_valid = true; +// } +// break; +// default: +// return false; +// } + +// if (hdl_valid) +// { +// if (client_attr_read(conn_id, ias_client, handle) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("ias_client_read_by_handle: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool ias_client_read_by_uuid(uint8_t conn_id, T_IAS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +//{ +// uint16_t start_handle; +// uint16_t end_handle; +// uint16_t uuid16; +// if (conn_id >= ias_link_num) +// { +// PROFILE_PRINT_ERROR1("ias_client_read_by_uuid: failed invalid conn_id %d", conn_id); +// return false; +// } + +// switch (read_type) +// { +// case IAS_READ_V1_READ: +// start_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_START]; +// end_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_END]; +// uuid16 = GATT_UUID_CHAR_ALERT_LEVEL; +// break; +// default: +// return false; +// } + +// if (client_attr_read_using_uuid(conn_id, ias_client, start_handle, end_handle, +// uuid16, NULL) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// return false; +//} + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify) +//{ +// if (conn_id >= simp_link_num) +// { +// PROFILE_PRINT_ERROR1("simp_ble_client_set_v3_notify: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]) +// { +// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = notify ? 1 : 0; +// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("simp_ble_client_set_v3_notify: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind) +//{ +// if (conn_id >= simp_link_num) +// { +// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) +// { +// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = ind ? 2 : 0; +// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to write data of V2 write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ias_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type) +{ + if (conn_id >= ias_link_num) + { + PROFILE_PRINT_ERROR1("ias_client_write_v2_char: failed invalid conn_id %d", conn_id); + return false; + } + + if (ias_table[conn_id].hdl_cache[HDL_IAS_WRITE]) + { + uint16_t handle = ias_table[conn_id].hdl_cache[HDL_IAS_WRITE]; + if (client_attr_write(conn_id, ias_client, type, handle, + length, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("ias_ble_client_write_char: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ias_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ias_link_num) + { + PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ias_table[conn_id].disc_state != DISC_IAS_DONE) + { + PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid state %d", + ias_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_IAS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("ias_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, ias_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ias_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ias_link_num) + { + PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ias_table[conn_id].disc_state != DISC_IAS_IDLE) + { + PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid state %d", + ias_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_IAS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("ias_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(ias_table[conn_id].hdl_cache, p_hdl_cache, len); + ias_table[conn_id].disc_state = DISC_IAS_DONE; + return true; +} + +static bool ias_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("ias_client_start_ias_char_discovery"); + start_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_START]; + end_handle = ias_table[conn_id].hdl_cache[HDL_IAS_SRV_END]; + if (client_all_char_discovery(conn_id, ias_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +//static bool ias_client_start_char_descriptor_discovery(uint8_t conn_id) +//{ +// uint16_t start_handle; +// uint16_t end_handle; + +// PROFILE_PRINT_INFO0("ias_client_start_char_descriptor_discovery"); +// start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY]; +// end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END]; +// if (client_all_char_descriptor_discovery(conn_id, simp_client, start_handle, +// end_handle) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// return false; +//} +static void ias_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_IAS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = IAS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("ias_client_discover_state_cb: discovery_state %d", discovery_state); + if (ias_table[conn_id].disc_state == DISC_IAS_START) + { + uint16_t *hdl_cache; + hdl_cache = ias_table[conn_id].hdl_cache; + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hdl_cache[HDL_IAS_SRV_START] != 0) + || (hdl_cache[HDL_IAS_SRV_END] != 0)) + { + if (ias_client_start_char_discovery(conn_id) == false) + { + ias_table[conn_id].disc_state = DISC_IAS_FAILED; + cb_flag = true; + } + } + /* No Ias BLE service handle found. Discover procedure complete. */ + else + { + ias_table[conn_id].disc_state = DISC_IAS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + ias_table[conn_id].disc_state = DISC_IAS_DONE; + cb_flag = true; + break; + case DISC_STATE_FAILED: + ias_table[conn_id].disc_state = DISC_IAS_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("ias_handle_discover_state: Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && ias_client_cb) + { + cb_data.cb_content.disc_state = ias_table[conn_id].disc_state; + (*ias_client_cb)(ias_client, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param conn_id: connection ID. + * @param result_type: indicate which type of value discovered in service discovery procedure. + * @param result_data: value discovered. + * @retval None + */ +static void ias_client_discover_result_cb(uint8_t conn_id, + T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("ias_client_discover_result_cb: result_type %d", result_type); + if (ias_table[conn_id].disc_state == DISC_IAS_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = ias_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hdl_cache[HDL_IAS_SRV_START] = result_data.p_srv_disc_data->att_handle; + hdl_cache[HDL_IAS_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_ALERT_LEVEL: + hdl_cache[HDL_IAS_WRITE] = handle; + break; + default: + /* have no intrest on this handle. */ + break; + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use client_all_char_descriptor_discovery. */ + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + handle = result_data.p_char_desc_uuid16_disc_data->handle; + } + break; + + default: + APP_PRINT_ERROR0("ias_handle_discover_result: Invalid Discovery Result Type!"); + break; + } + } + return; +} + +static void ias_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_IAS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ias_table[conn_id].hdl_cache; + cb_data.cb_type = IAS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("ias_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_IAS_WRITE]) + { + cb_data.cb_content.write_result.type = IAS_WRITE_ALERT; + } + else + { + return; + } + /* Inform application the write result. */ + if (ias_client_cb) + { + (*ias_client_cb)(ias_client, conn_id, &cb_data); + } + + return; +} + + +static void ias_client_disconnect_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("ias_client_disconnect_cb."); + if (conn_id >= ias_link_num) + { + PROFILE_PRINT_ERROR1("ias_client_disconnect_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&ias_table[conn_id], 0, sizeof(T_IAS_LINK)); + return; +} + +/** + * @brief Ias BLE Client Callbacks. +*/ +const T_FUN_CLIENT_CBS ias_client_cbs = +{ + ias_client_discover_state_cb, //!< Discovery State callback function pointer + ias_client_discover_result_cb, //!< Discovery result callback function pointer + NULL, //!< Read response callback function pointer + ias_client_write_result_cb, //!< Write result callback function pointer + NULL, //!< Notify Indicate callback function pointer + ias_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add ias service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + ias_client_id = ias_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID ias_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > IAS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("ias_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&ias_client, &ias_client_cbs)) + { + ias_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("ias_add_client failed"); + return ias_client; + } + APP_PRINT_INFO1("ias_add_client: ias_client %d", ias_client); + + /* register callback for profile to inform application that some events happened. */ + ias_client_cb = app_cb; + ias_link_num = link_num; + size = ias_link_num * sizeof(T_IAS_LINK); + ias_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return ias_client; +} + diff --git a/src/ble/profile/client/ipss_client.c b/src/ble/profile/client/ipss_client.c new file mode 100644 index 0000000..1181e6e --- /dev/null +++ b/src/ble/profile/client/ipss_client.c @@ -0,0 +1,102 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ipss_client.c + * @brief Source file for client of internet protocol support service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-05 + * @version v1.0 + * ************************************************************************************* + */ +#include "trace.h" +#include "os_mem.h" +#include "profile_client.h" +#include "ipss.h" + + +static T_CLIENT_ID ipss_cl_id = CLIENT_PROFILE_GENERAL_ID; +//static P_FUN_GENERAL_APP_CB ipss_cl_gen_cb = NULL; + +/** + * @brief discover IPS service by service uuid . + * + * @param[in] conn_id connection id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool ipss_find_srv_dcl(uint8_t conn_id) +{ + if (client_by_uuid_srv_discovery(conn_id, ipss_cl_id, GATT_UUID_IPSS) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief IPS discover result callback. + * + * @param[in] conn_id connection id. + * @param[in] result_type result type @ref T_DISCOVERY_RESULT_TYPE + * @param[in] result_data result data @ref T_DISCOVERY_RESULT_DATA + * @return void + */ +static void ipss_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + { + uint16_t start_handle = result_data.p_srv_disc_data->att_handle; + uint16_t end_handle = result_data.p_srv_disc_data->end_group_handle; + APP_PRINT_INFO2("ipss_discover_result_cb: start handle %x, end handle %d", start_handle, + end_handle); + break; + } + + default: + break; + + } +} + +/** + * @brief IPS service client callback function pointer. + */ +const T_FUN_CLIENT_CBS ipss_cl_cbs = +{ + NULL, //!< Discovery State callback function pointer + ipss_discover_result_cb, //!< Discovery result callback function pointer + NULL, //!< Read response callback function pointer + NULL, //!< Write result callback function pointer + NULL, //!< Notify Indicate callback function pointer + NULL //!< Link disconnection callback function pointer +}; + +/** + * @brief add IPS service client. + * + * @param[in] p_func pointer of app callback function called by client. + * @return client id. + */ +uint8_t ipss_add_client(void *p_func) +{ + if (false == client_register_spec_client_cb(&ipss_cl_id, &ipss_cl_cbs)) + { + ipss_cl_id = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("ipss_add_client: register fail"); + } + else + { + //ipss_cl_gen_cb = (P_FUN_GENERAL_APP_CB)p_func; + } + + PROFILE_PRINT_INFO1("ipss_add_client: client id %d", ipss_cl_id); + + return ipss_cl_id; +} + diff --git a/src/ble/profile/client/kns_client.c b/src/ble/profile/client/kns_client.c new file mode 100644 index 0000000..3fd38d2 --- /dev/null +++ b/src/ble/profile/client/kns_client.c @@ -0,0 +1,653 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ias_client.c + * @brief Ias BLE client source file. + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_KNS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_KNS_CACHE_LEN]; +} T_KNS_LINK, *P_KNS_LINK; + +static P_KNS_LINK kns_table; +static uint8_t kns_link_num; +const uint8_t GATT_UUID128_PARAM[16] = {0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD1, 0xFF, 0x00, 0x00}; +const uint8_t GATT_UUID128_KEY[16] = {0xA6, 0xF6, 0xF6, 0x07, 0x4D, 0xC4, 0x9D, 0x98, 0x6D, 0x45, 0x29, 0xBB, 0xD2, 0xFF, 0x00, 0x00}; +/**< kns client ID. */ +static T_CLIENT_ID kns_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from kns client layer. */ +static P_FUN_GENERAL_APP_CB kns_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of ias server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("kns_client_start_discovery"); + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&kns_table[conn_id], 0, sizeof(T_KNS_LINK)); + kns_table[conn_id].disc_state = DISC_KNS_START; + if (client_by_uuid128_srv_discovery(conn_id, kns_client, + (uint8_t *)GATT_UUID128_KNS_SERVICE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_read_by_handle(uint8_t conn_id, + T_KNS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +{ + bool hdl_valid = false; + uint16_t handle; + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case KNS_READ_PARAM: + if (kns_table[conn_id].hdl_cache[HDL_KNS_PARA]) + { + handle = kns_table[conn_id].hdl_cache[HDL_KNS_PARA]; + hdl_valid = true; + } + break; + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, kns_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("kns_client_read_by_handle: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_read_by_uuid(uint8_t conn_id, + T_KNS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +{ + uint16_t start_handle; + uint16_t end_handle; + uint8_t *uuid128; + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_read_by_uuid: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case KNS_READ_PARAM: + start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_START]; + end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END]; + uuid128 = (uint8_t *)GATT_UUID128_PARAM; + break; + default: + return false; + } + + if (client_attr_read_using_uuid(conn_id, kns_client, start_handle, end_handle, + 0, uuid128) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_set_v3_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id); + return false; + } + + if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]) + { + uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind) +//{ +// if (conn_id >= simp_link_num) +// { +// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) +// { +// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = ind ? 2 : 0; +// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to write data of V2 write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool kns_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type) +{ + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_write_v2_char: failed invalid conn_id %d", conn_id); + return false; + } + + if (kns_table[conn_id].hdl_cache[HDL_KNS_PARA]) + { + uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_PARA]; + if (client_attr_write(conn_id, kns_client, type, handle, + length, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("kns_ble_client_write_v2_char: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool kns_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (kns_table[conn_id].disc_state != DISC_KNS_DONE) + { + PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid state %d", + kns_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_KNS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("kns_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, kns_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool kns_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (kns_table[conn_id].disc_state != DISC_KNS_IDLE) + { + PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid state %d", + kns_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_KNS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("kns_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(kns_table[conn_id].hdl_cache, p_hdl_cache, len); + kns_table[conn_id].disc_state = DISC_KNS_DONE; + return true; +} + +static bool kns_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("kns_client_start_ias_char_discovery"); + start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_START]; + end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END]; + if (client_all_char_discovery(conn_id, kns_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool kns_client_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("kns_client_start_char_descriptor_discovery"); + start_handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY]; + end_handle = kns_table[conn_id].hdl_cache[HDL_KNS_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, kns_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} +static void kns_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_KNS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = KNS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("kns_client_discover_state_cb: discovery_state %d", discovery_state); + if (kns_table[conn_id].disc_state == DISC_KNS_START) + { + uint16_t *hdl_cache; + hdl_cache = kns_table[conn_id].hdl_cache; + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hdl_cache[HDL_KNS_SRV_START] != 0) + || (hdl_cache[HDL_KNS_SRV_END] != 0)) + { + if (kns_client_start_char_discovery(conn_id) == false) + { + kns_table[conn_id].disc_state = DISC_KNS_FAILED; + cb_flag = true; + } + } + /* No Ias BLE service handle found. Discover procedure complete. */ + else + { + kns_table[conn_id].disc_state = DISC_KNS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + if (hdl_cache[HDL_KNS_NOTIFY_KEY] != 0) + { + if (kns_client_start_char_descriptor_discovery(conn_id) == false) + { + kns_table[conn_id].disc_state = DISC_KNS_FAILED; + cb_flag = true; + } + } + else + { + kns_table[conn_id].disc_state = DISC_KNS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + kns_table[conn_id].disc_state = DISC_KNS_DONE; + cb_flag = true; + break; + case DISC_STATE_FAILED: + kns_table[conn_id].disc_state = DISC_KNS_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("kns_handle_discover_state: Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && kns_client_cb) + { + cb_data.cb_content.disc_state = kns_table[conn_id].disc_state; + (*kns_client_cb)(kns_client, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param conn_id: connection ID. + * @param result_type: indicate which type of value discovered in service discovery procedure. + * @param result_data: value discovered. + * @retval None + */ +static void kns_client_discover_result_cb(uint8_t conn_id, + T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("kns_client_discover_result_cb: result_type %d", result_type); + if (kns_table[conn_id].disc_state == DISC_KNS_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = kns_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hdl_cache[HDL_KNS_SRV_START] = result_data.p_srv_disc_data->att_handle; + hdl_cache[HDL_KNS_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + case DISC_RESULT_CHAR_UUID128: + handle = result_data.p_char_uuid128_disc_data->value_handle; + if (!memcmp(result_data.p_char_uuid128_disc_data->uuid128, GATT_UUID128_PARAM, 16)) + { + hdl_cache[HDL_KNS_PARA] = handle; + } + else if (!memcmp(result_data.p_char_uuid128_disc_data->uuid128, GATT_UUID128_KEY, 16)) + { + hdl_cache[HDL_KNS_NOTIFY_KEY] = handle; + } + break; + + case DISC_RESULT_CHAR_UUID16: + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use client_all_char_descriptor_discovery. */ + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + handle = result_data.p_char_desc_uuid16_disc_data->handle; + + if ((handle > hdl_cache[HDL_KNS_NOTIFY_KEY]) + && (hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD] == 0)) + { + hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD] = handle; + } + } + break; + + default: + APP_PRINT_ERROR0("kns_handle_discover_result: Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void kns_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_KNS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = kns_table[conn_id].hdl_cache; + + cb_data.cb_type = KNS_CLIENT_CB_TYPE_READ_RESULT; + + APP_PRINT_INFO2("kns_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_KNS_PARA]) + { + cb_data.cb_content.read_result.type = KNS_READ_PARAM; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]) + { + cb_data.cb_content.read_result.type = KNS_READ_KEY_NOTIFY_CCCD; + if (cause == GAP_SUCCESS) + { + uint16_t ccc_bit; + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("kns_client_read_result_cb: invalid cccd len %d", value_size); + return; + } + LE_ARRAY_TO_UINT16(ccc_bit, p_value); + + if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + cb_data.cb_content.read_result.data.v3_notify_cccd = true; + } + else + { + cb_data.cb_content.read_result.data.v3_notify_cccd = false; + } + } + } + else + { + return; + } + /* Inform application the read result. */ + if (kns_client_cb) + { + (*kns_client_cb)(kns_client, conn_id, &cb_data); + } + + return; +} + +static void kns_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_KNS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = kns_table[conn_id].hdl_cache; + cb_data.cb_type = KNS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("kns_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_KNS_PARA]) + { + cb_data.cb_content.write_result.type = KNS_WRITE_PARAM; + } + else if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]) + { + cb_data.cb_content.write_result.type = KNS_WRITE_KEY_NOTIFY_CCCD; + } + else + { + return; + } + /* Inform application the write result. */ + if (kns_client_cb) + { + (*kns_client_cb)(kns_client, conn_id, &cb_data); + } + + return; +} + +static T_APP_RESULT kns_client_notif_ind_result_cb(uint8_t conn_id, bool notify, + uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_KNS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = kns_table[conn_id].hdl_cache; + + cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY]) + { + cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY; + cb_data.cb_content.notif_ind_data.data.value_size = value_size; + cb_data.cb_content.notif_ind_data.data.p_value = p_value; + } + else + { + return app_result; + } + /* Inform application the notif/ind result. */ + if (kns_client_cb) + { + app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data); + } + + return app_result; +} + +static void kns_client_disconnect_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("kns_client_disconnect_cb."); + if (conn_id >= kns_link_num) + { + PROFILE_PRINT_ERROR1("kns_client_disconnect_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&kns_table[conn_id], 0, sizeof(T_KNS_LINK)); + return; +} + +/** + * @brief Ias BLE Client Callbacks. +*/ +const T_FUN_CLIENT_CBS kns_client_cbs = +{ + kns_client_discover_state_cb, //!< Discovery State callback function pointer + kns_client_discover_result_cb, //!< Discovery result callback function pointer + kns_client_read_result_cb, //!< Read response callback function pointer + kns_client_write_result_cb, //!< Write result callback function pointer + kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer + kns_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add kns service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + kns_client_id = kns_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID kns_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > KNS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("kns_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&kns_client, &kns_client_cbs)) + { + kns_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("ias_add_client failed"); + return kns_client; + } + APP_PRINT_INFO1("kns_add_client: kns_client %d", kns_client); + + /* register callback for profile to inform application that some events happened. */ + kns_client_cb = app_cb; + kns_link_num = link_num; + size = kns_link_num * sizeof(T_KNS_LINK); + kns_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return kns_client; +} + diff --git a/src/ble/profile/client/lls_client.c b/src/ble/profile/client/lls_client.c new file mode 100644 index 0000000..0739c41 --- /dev/null +++ b/src/ble/profile/client/lls_client.c @@ -0,0 +1,623 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file lls_client.c + * @brief Lls BLE client source file. + * @details + * @author ken + * @date 2017-12-05 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_LLS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_LLS_CACHE_LEN]; +} T_LLS_LINK, *P_LLS_LINK; + +static P_LLS_LINK lls_table; +static uint8_t lls_link_num; + +/**< lls client ID. */ +static T_CLIENT_ID lls_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from lls client layer. */ +static P_FUN_GENERAL_APP_CB lls_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of lls server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("lls_client_start_discovery"); + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&lls_table[conn_id], 0, sizeof(T_LLS_LINK)); + lls_table[conn_id].disc_state = DISC_LLS_START; + if (client_by_uuid_srv_discovery(conn_id, lls_client, + GATT_UUID_LINK_LOSS_SERVICE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_read_by_handle(uint8_t conn_id, T_LLS_READ_TYPE read_type) +{ + bool hdl_valid = false; + uint16_t handle; + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case LLS_READ_PARA: + if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA]) + { + handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA]; + hdl_valid = true; + } + break; + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, lls_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("lls_client_read_by_handle: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_read_by_uuid(uint8_t conn_id, + T_LLS_READ_TYPE read_type)//~~~~~~~~~~~~~~~~~~will delete +{ + uint16_t start_handle; + uint16_t end_handle; + uint16_t uuid16; + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_read_by_uuid: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case LLS_READ_PARA: + start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_START]; + end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END]; + uuid16 = GATT_UUID_CHAR_ALERT_LEVEL; + break; + default: + return false; + } + + if (client_attr_read_using_uuid(conn_id, lls_client, start_handle, end_handle, + uuid16, NULL) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +///** +// * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. +// * @param[in] conn_id connection ID. +// * @param[in] notify 0--disable the notification, 1--enable the notification. +// * @retval true send request to upper stack success. +// * @retval false send request to upper stack failed. +// */ +//bool lls_client_set_v3_notify(uint8_t conn_id, bool notify) +//{ +// if (conn_id >= kns_link_num) +// { +// PROFILE_PRINT_ERROR1("kns_client_set_v3_notify: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]) +// { +// uint16_t handle = kns_table[conn_id].hdl_cache[HDL_KNS_NOTIFY_KEY_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = notify ? 1 : 0; +// if (client_attr_write(conn_id, kns_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("kns_client_set_v3_notify: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +//bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind) +//{ +// if (conn_id >= simp_link_num) +// { +// PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id); +// return false; +// } + +// if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) +// { +// uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; +// uint16_t length = sizeof(uint16_t); +// uint16_t cccd_bits = ind ? 2 : 0; +// if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, +// length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// } + +// APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!"); +// return false; +//} + +/** + * @brief Used by application, to write data of write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool lls_client_write_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type) +{ + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_write_char: failed invalid conn_id %d", conn_id); + return false; + } + + if (lls_table[conn_id].hdl_cache[HDL_LLS_PARA]) + { + uint16_t handle = lls_table[conn_id].hdl_cache[HDL_LLS_PARA]; + if (client_attr_write(conn_id, lls_client, type, handle, + length, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("lls_ble_client_write_char: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool lls_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (lls_table[conn_id].disc_state != DISC_LLS_DONE) + { + PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid state %d", + lls_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_LLS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("lls_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, lls_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool lls_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (lls_table[conn_id].disc_state != DISC_LLS_IDLE) + { + PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid state %d", + lls_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_LLS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("lls_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(lls_table[conn_id].hdl_cache, p_hdl_cache, len); + lls_table[conn_id].disc_state = DISC_LLS_DONE; + return true; +} + +static bool lls_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("lls_client_start_ias_char_discovery"); + start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_START]; + end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END]; + if (client_all_char_discovery(conn_id, lls_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +//static bool lls_client_start_char_descriptor_discovery(uint8_t conn_id) +//{ +// uint16_t start_handle; +// uint16_t end_handle; + +// PROFILE_PRINT_INFO0("lls_client_start_char_descriptor_discovery"); +// start_handle = lls_table[conn_id].hdl_cache[HDL_LLS_NOTIFY_KEY]; +// end_handle = lls_table[conn_id].hdl_cache[HDL_LLS_SRV_END]; +// if (client_all_char_descriptor_discovery(conn_id, lls_client, start_handle, +// end_handle) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// return false; +//} +static void lls_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_LLS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = LLS_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("lls_client_discover_state_cb: discovery_state %d", discovery_state); + if (lls_table[conn_id].disc_state == DISC_LLS_START) + { + uint16_t *hdl_cache; + hdl_cache = lls_table[conn_id].hdl_cache; + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hdl_cache[HDL_LLS_SRV_START] != 0) + || (hdl_cache[HDL_LLS_SRV_END] != 0)) + { + if (lls_client_start_char_discovery(conn_id) == false) + { + lls_table[conn_id].disc_state = DISC_LLS_FAILED; + cb_flag = true; + } + } + /* No Ias BLE service handle found. Discover procedure complete. */ + else + { + lls_table[conn_id].disc_state = DISC_LLS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + lls_table[conn_id].disc_state = DISC_LLS_DONE; + cb_flag = true; + break; + case DISC_STATE_FAILED: + lls_table[conn_id].disc_state = DISC_LLS_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("lls_handle_discover_state: Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && lls_client_cb) + { + cb_data.cb_content.disc_state = lls_table[conn_id].disc_state; + (*lls_client_cb)(lls_client, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param conn_id: connection ID. + * @param result_type: indicate which type of value discovered in service discovery procedure. + * @param result_data: value discovered. + * @retval None + */ +static void lls_client_discover_result_cb(uint8_t conn_id, + T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("lls_client_discover_result_cb: result_type %d", result_type); + if (lls_table[conn_id].disc_state == DISC_LLS_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = lls_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hdl_cache[HDL_LLS_SRV_START] = result_data.p_srv_disc_data->att_handle; + hdl_cache[HDL_LLS_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + case DISC_RESULT_CHAR_UUID128: + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_ALERT_LEVEL: + hdl_cache[HDL_LLS_PARA] = handle; + break; + default: + /* have no intrest on this handle. */ + break; + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use client_all_char_descriptor_discovery. */ + break; + + default: + APP_PRINT_ERROR0("lls_handle_discover_result: Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void lls_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_LLS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = lls_table[conn_id].hdl_cache; + + cb_data.cb_type = LLS_CLIENT_CB_TYPE_READ_RESULT; + + APP_PRINT_INFO2("lls_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_LLS_PARA]) + { + cb_data.cb_content.read_result.type = LLS_READ_PARA; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } +// else if (handle == hdl_cache[HDL_LLS_NOTIFY_KEY_CCCD]) +// { +// cb_data.cb_content.read_result.type = LLS_READ_KEY_NOTIFY_CCCD; +// if (cause == GAP_SUCCESS) +// { +// uint16_t ccc_bit; +// if (value_size != 2) +// { +// PROFILE_PRINT_ERROR1("kns_client_read_result_cb: invalid cccd len %d", value_size); +// return; +// } +// LE_ARRAY_TO_UINT16(ccc_bit, p_value); + +// if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY) +// { +// cb_data.cb_content.read_result.data.v3_notify_cccd = true; +// } +// else +// { +// cb_data.cb_content.read_result.data.v3_notify_cccd = false; +// } +// } +// } + else + { + return; + } + /* Inform application the read result. */ + if (lls_client_cb) + { + (*lls_client_cb)(lls_client, conn_id, &cb_data); + } + + return; +} + +static void lls_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_LLS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = lls_table[conn_id].hdl_cache; + cb_data.cb_type = LLS_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("lls_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_LLS_PARA]) + { + cb_data.cb_content.write_result.type = LLS_WRITE_PARA; + } + else + { + return; + } + /* Inform application the write result. */ + if (lls_client_cb) + { + (*lls_client_cb)(lls_client, conn_id, &cb_data); + } + + return; +} + +//static T_APP_RESULT lls_client_notif_ind_result_cb(uint8_t conn_id, bool notify, +// uint16_t handle, +// uint16_t value_size, uint8_t *p_value) +//{ +// T_APP_RESULT app_result = APP_RESULT_SUCCESS; +// T_KNS_CLIENT_CB_DATA cb_data; +// uint16_t *hdl_cache; +// hdl_cache = kns_table[conn_id].hdl_cache; + +// cb_data.cb_type = KNS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + +// if (handle == hdl_cache[HDL_KNS_NOTIFY_KEY]) +// { +// cb_data.cb_content.notif_ind_data.type = KNS_KEY_NOTIFY; +// cb_data.cb_content.notif_ind_data.data.value_size = value_size; +// cb_data.cb_content.notif_ind_data.data.p_value = p_value; +// } +// else +// { +// return app_result; +// } +// /* Inform application the notif/ind result. */ +// if (kns_client_cb) +// { +// app_result = (*kns_client_cb)(kns_client, conn_id, &cb_data); +// } + +// return app_result; +//} + +static void lls_client_disconnect_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("lls_client_disconnect_cb."); + if (conn_id >= lls_link_num) + { + PROFILE_PRINT_ERROR1("lls_client_disconnect_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&lls_table[conn_id], 0, sizeof(T_LLS_LINK)); + return; +} + +/** + * @brief Ias BLE Client Callbacks. +*/ +const T_FUN_CLIENT_CBS lls_client_cbs = +{ + lls_client_discover_state_cb, //!< Discovery State callback function pointer + lls_client_discover_result_cb, //!< Discovery result callback function pointer + lls_client_read_result_cb, //!< Read response callback function pointer + lls_client_write_result_cb, //!< Write result callback function pointer + NULL,//kns_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer + lls_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add lls service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + lls_client_id = lls_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID lls_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > LLS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("lls_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&lls_client, &lls_client_cbs)) + { + lls_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("lls_add_client failed"); + return lls_client; + } + APP_PRINT_INFO1("lls_add_client: lls_client %d", lls_client); + + /* register callback for profile to inform application that some events happened. */ + lls_client_cb = app_cb; + lls_link_num = link_num; + size = lls_link_num * sizeof(T_LLS_LINK); + lls_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return lls_client; +} + diff --git a/src/ble/profile/client/ota_client.c b/src/ble/profile/client/ota_client.c new file mode 100644 index 0000000..475f076 --- /dev/null +++ b/src/ble/profile/client/ota_client.c @@ -0,0 +1,644 @@ +/** +***************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ota_client.c + * @brief ota service client source file. + * @details + * @author + * @date + * @version + ****************************************************************************** + * @attention + *

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include "trace.h" +#include "gap_conn_le.h" +#include "bt_types.h" +#include "mem_types.h" +#include "os_mem.h" +#include "ota_client.h" +/** + * @brief OTA client Link control block definition. + */ +typedef struct +{ + T_OTA_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_OTA_CACHE_LEN]; +} T_OTA_LINK, *P_OTA_LINK; + + +static P_OTA_LINK ota_table; +static uint8_t ota_link_num; + +/**< OTA client ID. */ +static T_CLIENT_ID ota_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from OTA client layer. */ +static P_FUN_GENERAL_APP_CB ota_client_cb = NULL; + +const uint8_t ota_service_uuid[16] = {GATT_UUID_OTA_SERVICE}; + +/** + * @brief Used by application, to start the discovery procedure of OTA server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ota_client_start_discovery(uint8_t conn_id) +{ + DFU_PRINT_INFO0("ota_client_start_discovery"); + if (conn_id >= ota_link_num) + { + DFU_PRINT_ERROR1("ota_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&ota_table[conn_id], 0, sizeof(T_OTA_LINK)); + ota_table[conn_id].disc_state = DISC_OTA_START; + if (client_by_uuid128_srv_discovery(conn_id, ota_client, + (uint8_t *)ota_service_uuid) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + + +static bool ota_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("ota_client_start_char_discovery"); + start_handle = ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START]; + end_handle = ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END]; + if (client_all_char_discovery(conn_id, ota_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ota_client_read_by_handle(uint8_t conn_id, T_OTA_READ_TYPE read_type) +{ + bool hdl_valid = false; + uint16_t handle; + if (conn_id >= ota_link_num) + { + DFU_PRINT_ERROR1("ota_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case OTA_READ_DEVICE_MAC: + if (ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_MAC]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_MAC]; + hdl_valid = true; + } + break; + case OTA_READ_PATCH_VER: + if (ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_VER]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_VER]; + hdl_valid = true; + } + break; + case OTA_READ_APP_VER: + if (ota_table[conn_id].hdl_cache[HDL_OTA_APP_VER]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_APP_VER]; + hdl_valid = true; + } + break; + case OTA_READ_PATCH_EXT_VER: + if (ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_EXT_VER]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_PATCH_EXT_VER]; + hdl_valid = true; + } + break; + case OTA_READ_DEVICE_INFO: + if (ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_INFO]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_DEVICE_INFO]; + hdl_valid = true; + } + break; + case OTA_READ_IMG_VER: + if (ota_table[conn_id].hdl_cache[HDL_OTA_IMG_VER]) + { + handle = ota_table[conn_id].hdl_cache[HDL_OTA_IMG_VER]; + hdl_valid = true; + } + break; + + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, ota_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("ota_client_read_by_handle: Request fail! Please check!"); + return false; +} + + +/** + * @brief Used by application, to write ota cmd write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool ota_client_write_char(uint8_t conn_id, T_OTA_WRTIE_TYPE write_type) +{ + if (conn_id >= ota_link_num) + { + DFU_PRINT_ERROR1("ota_client_write_char: failed invalid conn_id %d", conn_id); + return false; + } + + switch (write_type) + { + case OTA_WRITE_CMD: + { + DFU_PRINT_INFO1("ota_client_write_char: write handle 0x%x", + ota_table[conn_id].hdl_cache[HDL_OTA_CMD]); + if (ota_table[conn_id].hdl_cache[HDL_OTA_CMD]) + { + uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_CMD]; + uint8_t ota_cmd = OTA_WRITE_OTA_CMD_CHAR_VAL; + if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle, + sizeof(ota_cmd), &ota_cmd) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + break; + } + case OTA_WRITE_TEST_MODE: + { + if (ota_table[conn_id].hdl_cache[HDL_OTA_TEST_MODE]) + { + uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_TEST_MODE]; + uint8_t test_mode = OTA_WRITE_TEST_MODE_CHAR_VAL; + if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle, + sizeof(test_mode), &test_mode) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + break; + } + case OTA_WRITE_IMG_COUNTER: + { + if (ota_table[conn_id].hdl_cache[HDL_OTA_IMG_COUNTER]) + { + uint16_t handle = ota_table[conn_id].hdl_cache[HDL_OTA_IMG_COUNTER]; + uint8_t img_counter = OTA_WRITE_OTA_IMG_COUNTER_CHAR_VAL; + if (client_attr_write(conn_id, ota_client, GATT_WRITE_TYPE_CMD, handle, + sizeof(img_counter), &img_counter) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + break; + } + default: + break; + + } + + DFU_PRINT_WARN1("ota_client_write_char fail! write_type=%d", write_type); + return false; +} + + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ota_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ota_link_num) + { + DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ota_table[conn_id].disc_state != DISC_OTA_DONE) + { + DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid state %d", + ota_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_OTA_CACHE_LEN) + { + DFU_PRINT_ERROR1("ota_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, ota_table[conn_id].hdl_cache, len); + return true; +} +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool ota_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= ota_link_num) + { + DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (ota_table[conn_id].disc_state != DISC_OTA_IDLE) + { + DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid state %d", + ota_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_OTA_CACHE_LEN) + { + DFU_PRINT_ERROR1("ota_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(ota_table[conn_id].hdl_cache, p_hdl_cache, len); + ota_table[conn_id].disc_state = DISC_OTA_DONE; + return true; +} + + +static void ota_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_OTA_CLIENT_CB_DATA cb_data; + cb_data.cb_type = OTA_CLIENT_CB_TYPE_DISC_STATE; + + DFU_PRINT_INFO1("ota_client_discover_state_cb: discovery_state = %d", discovery_state); + if (ota_table[conn_id].disc_state == DISC_OTA_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START] != 0) + || (ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END] != 0)) + { + if (ota_client_start_char_discovery(conn_id) == false) + { + ota_table[conn_id].disc_state = DISC_OTA_FAILED; + cb_flag = true; + } + } + /* No ota handle found. Discover procedure complete. */ + else + { + ota_table[conn_id].disc_state = DISC_OTA_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + ota_table[conn_id].disc_state = DISC_OTA_DONE; + cb_flag = true; + break; + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + break; + default: + DFU_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && ota_client_cb) + { + cb_data.cb_content.disc_state = ota_table[conn_id].disc_state; + (*ota_client_cb)(ota_client, conn_id, &cb_data); + } + return; +} + + +static void ota_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = ota_table[conn_id].hdl_cache; + DFU_PRINT_INFO1("ota_client_discover_result_cb: result_type = %d", result_type); + if (ota_table[conn_id].disc_state == DISC_OTA_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + DFU_PRINT_INFO0("DISC_RESULT_SRV_DATA"); + ota_table[conn_id].hdl_cache[HDL_OTA_SRV_START] = + result_data.p_srv_disc_data->att_handle; + ota_table[conn_id].hdl_cache[HDL_OTA_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + DFU_PRINT_INFO2("DISC_RESULT_CHAR_UUID16: handle 0x%x, uuid 0x%x", + result_data.p_char_uuid16_disc_data->value_handle, + result_data.p_char_uuid16_disc_data->uuid16); + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_OTA: + hdl_cache[HDL_OTA_CMD] = handle; + break; + case GATT_UUID_CHAR_MAC: + hdl_cache[HDL_OTA_DEVICE_MAC] = handle; + break; + case GATT_UUID_CHAR_PATCH: + hdl_cache[HDL_OTA_PATCH_VER] = handle; + break; + case GATT_UUID_CHAR_APP_VERSION: + hdl_cache[HDL_OTA_APP_VER] = handle; + break; + case GATT_UUID_CHAR_PATCH_EXTENSION: + hdl_cache[HDL_OTA_PATCH_EXT_VER] = handle; + break; + case GATT_UUID_CHAR_TEST_MODE: + hdl_cache[HDL_OTA_TEST_MODE] = handle; + break; + case GATT_UUID_CHAR_DEVICE_INFO: + hdl_cache[HDL_OTA_DEVICE_INFO] = handle; + break; + case GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE: + hdl_cache[HDL_OTA_IMG_COUNTER] = handle; + break; + case GATT_UUID_CHAR_IMAGE_VERSION: + hdl_cache[HDL_OTA_IMG_VER] = handle; + break; + default: + /* have no intrest on this handle. */ + break; + } + } + break; + + default: + DFU_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void ota_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_OTA_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ota_table[conn_id].hdl_cache; + cb_data.cb_type = OTA_CLIENT_CB_TYPE_READ_RESULT; + + DFU_PRINT_INFO2("ota_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_OTA_DEVICE_MAC]) + { + cb_data.cb_content.read_result.type = OTA_READ_DEVICE_MAC; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_OTA_PATCH_VER]) + { + cb_data.cb_content.read_result.type = OTA_READ_PATCH_VER; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_OTA_APP_VER]) + { + cb_data.cb_content.read_result.type = OTA_READ_APP_VER; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_OTA_PATCH_EXT_VER]) + { + cb_data.cb_content.read_result.type = OTA_READ_PATCH_EXT_VER; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_OTA_DEVICE_INFO]) + { + cb_data.cb_content.read_result.type = OTA_READ_DEVICE_INFO; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_OTA_IMG_VER]) + { + cb_data.cb_content.read_result.type = OTA_READ_IMG_VER; + if (cause == GAP_SUCCESS) + { + //ota header, secure boot, patch, app version + cb_data.cb_content.read_result.data.p_value = p_value; + cb_data.cb_content.read_result.data.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.value_size = 0; + } + } + else + { + return; + } + + if (ota_client_cb) + { + (*ota_client_cb)(ota_client, conn_id, &cb_data); + } + return; +} + +static void ota_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, + uint16_t cause, + uint8_t credits) +{ + T_OTA_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = ota_table[conn_id].hdl_cache; + cb_data.cb_type = OTA_CLIENT_CB_TYPE_WRITE_RESULT; + + DFU_PRINT_INFO2("ota_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_OTA_CMD]) + { + cb_data.cb_content.write_result.type = OTA_WRITE_CMD; + } + else if (handle == hdl_cache[HDL_OTA_TEST_MODE]) + { + cb_data.cb_content.write_result.type = OTA_WRITE_TEST_MODE; + } + else if (handle == hdl_cache[HDL_OTA_IMG_COUNTER]) + { + cb_data.cb_content.write_result.type = OTA_WRITE_IMG_COUNTER; + } + else + { + return; + } + + /* Inform application the write result. */ + if (ota_client_cb) + { + (*ota_client_cb)(ota_client, conn_id, &cb_data); + } + return; +} + + +/** + * @brief OTA Client Callbacks. +*/ +const T_FUN_CLIENT_CBS ota_client_cbs = +{ + ota_client_discover_state_cb, //!< Discovery State callback function pointer + ota_client_discover_result_cb, //!< Discovery result callback function pointer + ota_client_read_result_cb, //!< Read response callback function pointer + ota_client_write_result_cb, //!< Write result callback function pointer + NULL, //ota_client_notify_ind_cb, //!< Notify Indicate callback function pointer + NULL//ota_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief add Dfu client to application. + * @param appCB: pointer of app callback function to handle specific client module data. + * @retval Client ID of the specific client module. + */ +T_CLIENT_ID ota_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > OTA_MAX_LINKS) + { + DFU_PRINT_ERROR1("ota_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&ota_client, &ota_client_cbs)) + { + ota_client = CLIENT_PROFILE_GENERAL_ID; + DFU_PRINT_ERROR0("ota_client_add: fail!"); + return ota_client; + } + DFU_PRINT_INFO1("ota_client_add: client ID = %d", ota_client); + ota_link_num = link_num; + size = ota_link_num * sizeof(T_OTA_LINK); + ota_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + /* register callback for profile to inform application that some events happened. */ + ota_client_cb = app_cb; + return ota_client; + +} + +/** + * @brief ota client connect target device. + * @param p_le_scan_info: filtered scan info + */ +void ota_client_connect_device(T_LE_SCAN_INFO *p_le_scan_info) +{ + DFU_PRINT_INFO1("ota_client_connect_device: p_le_scan_info->adv_type = %d", + p_le_scan_info->adv_type); + if (p_le_scan_info->adv_type != GAP_ADV_EVT_TYPE_UNDIRECTED) + { + return; + } + + T_GAP_LE_CONN_REQ_PARAM conn_req_param; + conn_req_param.scan_interval = 0x10; + conn_req_param.scan_window = 0x10; + conn_req_param.conn_interval_min = 0x80; + conn_req_param.conn_interval_max = 0x80; + conn_req_param.conn_latency = 0; + conn_req_param.supv_tout = 1000; + conn_req_param.ce_len_min = 2 * (conn_req_param.conn_interval_min - 1); + conn_req_param.ce_len_max = 2 * (conn_req_param.conn_interval_max - 1); + le_set_conn_param(GAP_CONN_PARAM_1M, &conn_req_param); + T_GAP_CAUSE cause; + if (GAP_CAUSE_SUCCESS == (cause = le_connect(GAP_PHYS_CONN_INIT_1M_BIT, p_le_scan_info->bd_addr, + p_le_scan_info->remote_addr_type, + GAP_LOCAL_ADDR_LE_PUBLIC, 1000))) + { + DFU_PRINT_INFO2("ota_client_connect_device: try connecting %s, remote_addr_type=%d", + TRACE_BDADDR(p_le_scan_info->bd_addr), p_le_scan_info->remote_addr_type); + } + else + { + DFU_PRINT_INFO1("ota_client_connect_device: FAIL cause=%d!", cause); + } + + + return; +} diff --git a/src/ble/profile/client/simple_ble_client.c b/src/ble/profile/client/simple_ble_client.c new file mode 100644 index 0000000..f769576 --- /dev/null +++ b/src/ble/profile/client/simple_ble_client.c @@ -0,0 +1,725 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file simple_ble_client.c + * @brief Simple BLE client source file. + * @details + * @author jane + * @date 2016-02-18 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + T_SIMP_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_SIMBLE_CACHE_LEN]; +} T_SIMP_LINK, *P_SIMP_LINK; + +static P_SIMP_LINK simp_table; +static uint8_t simp_link_num; + +/**< Simple BLE client ID. */ +static T_CLIENT_ID simp_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from Simple BLE client layer. */ +static P_FUN_GENERAL_APP_CB simp_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of Simple BLE server. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("simp_ble_client_start_discovery"); + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&simp_table[conn_id], 0, sizeof(T_SIMP_LINK)); + simp_table[conn_id].disc_state = DISC_SIMP_START; + if (client_by_uuid_srv_discovery(conn_id, simp_client, + GATT_UUID_SIMPLE_PROFILE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read data from server by using handles. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_read_by_handle(uint8_t conn_id, T_SIMP_READ_TYPE read_type) +{ + bool hdl_valid = false; + uint16_t handle; + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_read_by_handle: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case SIMP_READ_V1_READ: + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V1_READ]) + { + handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V1_READ]; + hdl_valid = true; + } + break; + case SIMP_READ_V3_NOTIFY_CCCD: + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]) + { + handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]; + hdl_valid = true; + } + break; + case SIMP_READ_V4_INDICATE_CCCD: + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) + { + handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; + hdl_valid = true; + } + break; + + default: + return false; + } + + if (hdl_valid) + { + if (client_attr_read(conn_id, simp_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("simp_ble_client_read_by_handle: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to read data from server by using UUIDs. + * @param[in] conn_id connection ID. + * @param[in] read_type one of characteristic that has the readable property. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_read_by_uuid(uint8_t conn_id, T_SIMP_READ_TYPE read_type) +{ + uint16_t start_handle; + uint16_t end_handle; + uint16_t uuid16; + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_read_by_uuid: failed invalid conn_id %d", conn_id); + return false; + } + + switch (read_type) + { + case SIMP_READ_V1_READ: + start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_START]; + end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END]; + uuid16 = GATT_UUID_CHAR_SIMPLE_V1_READ; + break; + case SIMP_READ_V3_NOTIFY_CCCD: + start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY]; + end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE]; + uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; + break; + case SIMP_READ_V4_INDICATE_CCCD: + start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE]; + end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END]; + uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; + break; + default: + return false; + } + + if (client_attr_read_using_uuid(conn_id, simp_client, start_handle, end_handle, + uuid16, NULL) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to enable or disable the notification of peer server's V3 Notify Characteristic. + * @param[in] conn_id connection ID. + * @param[in] notify 0--disable the notification, 1--enable the notification. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_set_v3_notify(uint8_t conn_id, bool notify) +{ + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_set_v3_notify: failed invalid conn_id %d", conn_id); + return false; + } + + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]) + { + uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = notify ? 1 : 0; + if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("simp_ble_client_set_v3_notify: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to enable or disable the indication of peer server's V4 Indicate Characteristic. + * @param[in] conn_id connection ID. + * @param[in] ind 0--disable the indication, 1--enable the indication. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_set_v4_ind(uint8_t conn_id, bool ind) +{ + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_set_v4_ind: failed invalid conn_id %d", conn_id); + return false; + } + + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) + { + uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]; + uint16_t length = sizeof(uint16_t); + uint16_t cccd_bits = ind ? 2 : 0; + if (client_attr_write(conn_id, simp_client, GATT_WRITE_TYPE_REQ, handle, + length, (uint8_t *)&cccd_bits) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("simp_ble_client_set_v4_ind: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to write data of V2 write Characteristic. + * @param[in] conn_id connection ID. + * @param[in] length write data length + * @param[in] p_value point the value to write + * @param[in] type write type. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + */ +bool simp_ble_client_write_v2_char(uint8_t conn_id, uint16_t length, uint8_t *p_value, + T_GATT_WRITE_TYPE type) +{ + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_write_v2_char: failed invalid conn_id %d", conn_id); + return false; + } + + if (simp_table[conn_id].hdl_cache[HDL_SIMBLE_V2_WRITE]) + { + uint16_t handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V2_WRITE]; + if (client_attr_write(conn_id, simp_client, type, handle, + length, p_value) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + + APP_PRINT_WARN0("simp_ble_client_write_v2_char: Request fail! Please check!"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool simp_ble_client_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (simp_table[conn_id].disc_state != DISC_SIMP_DONE) + { + PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid state %d", + simp_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("simp_ble_client_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, simp_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + */ +bool simp_ble_client_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (simp_table[conn_id].disc_state != DISC_SIMP_IDLE) + { + PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid state %d", + simp_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_SIMBLE_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("simp_ble_client_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(simp_table[conn_id].hdl_cache, p_hdl_cache, len); + simp_table[conn_id].disc_state = DISC_SIMP_DONE; + return true; +} + +static bool simp_ble_client_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + APP_PRINT_INFO0("simp_ble_client_start_simp_char_discovery"); + start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_START]; + end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END]; + if (client_all_char_discovery(conn_id, simp_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +static bool simp_ble_client_start_char_descriptor_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("simp_ble_client_start_char_descriptor_discovery"); + start_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_V3_NOTIFY]; + end_handle = simp_table[conn_id].hdl_cache[HDL_SIMBLE_SRV_END]; + if (client_all_char_descriptor_discovery(conn_id, simp_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} +static void simp_ble_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_SIMP_CLIENT_CB_DATA cb_data; + cb_data.cb_type = SIMP_CLIENT_CB_TYPE_DISC_STATE; + + APP_PRINT_INFO1("simp_ble_client_discover_state_cb: discovery_state %d", discovery_state); + if (simp_table[conn_id].disc_state == DISC_SIMP_START) + { + uint16_t *hdl_cache; + hdl_cache = simp_table[conn_id].hdl_cache; + + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((hdl_cache[HDL_SIMBLE_SRV_START] != 0) + || (hdl_cache[HDL_SIMBLE_SRV_END] != 0)) + { + if (simp_ble_client_start_char_discovery(conn_id) == false) + { + simp_table[conn_id].disc_state = DISC_SIMP_FAILED; + cb_flag = true; + } + } + /* No Simple BLE service handle found. Discover procedure complete. */ + else + { + simp_table[conn_id].disc_state = DISC_SIMP_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + if (hdl_cache[HDL_SIMBLE_V3_NOTIFY] != 0) + { + if (simp_ble_client_start_char_descriptor_discovery(conn_id) == false) + { + simp_table[conn_id].disc_state = DISC_SIMP_FAILED; + cb_flag = true; + } + } + else + { + simp_table[conn_id].disc_state = DISC_SIMP_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DESCRIPTOR_DONE: + simp_table[conn_id].disc_state = DISC_SIMP_DONE; + cb_flag = true; + break; + case DISC_STATE_FAILED: + simp_table[conn_id].disc_state = DISC_SIMP_FAILED; + cb_flag = true; + break; + default: + APP_PRINT_ERROR0("simp_handle_discover_state: Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && simp_client_cb) + { + cb_data.cb_content.disc_state = simp_table[conn_id].disc_state; + (*simp_client_cb)(simp_client, conn_id, &cb_data); + } + return; +} + +/** + * @brief Called by profile client layer, when discover result fetched. + * @param conn_id: connection ID. + * @param result_type: indicate which type of value discovered in service discovery procedure. + * @param result_data: value discovered. + * @retval None + */ +static void simp_ble_client_discover_result_cb(uint8_t conn_id, + T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + APP_PRINT_INFO1("simp_ble_client_discover_result_cb: result_type %d", result_type); + if (simp_table[conn_id].disc_state == DISC_SIMP_START) + { + uint16_t handle; + uint16_t *hdl_cache; + hdl_cache = simp_table[conn_id].hdl_cache; + + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + hdl_cache[HDL_SIMBLE_SRV_START] = result_data.p_srv_disc_data->att_handle; + hdl_cache[HDL_SIMBLE_SRV_END] = result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + handle = result_data.p_char_uuid16_disc_data->value_handle; + switch (result_data.p_char_uuid16_disc_data->uuid16) + { + case GATT_UUID_CHAR_SIMPLE_V1_READ: + hdl_cache[HDL_SIMBLE_V1_READ] = handle; + break; + + case GATT_UUID_CHAR_SIMPLE_V2_WRITE: + hdl_cache[HDL_SIMBLE_V2_WRITE] = handle; + break; + + case GATT_UUID_CHAR_SIMPLE_V3_NOTIFY: + hdl_cache[HDL_SIMBLE_V3_NOTIFY] = handle; + break; + + case GATT_UUID_CHAR_SIMPLE_V4_INDICATE: + hdl_cache[HDL_SIMBLE_V4_INDICATE] = handle; + break; + + default: + /* have no intrest on this handle. */ + break; + } + + break; + + case DISC_RESULT_CHAR_DESC_UUID16: + /* When use client_all_char_descriptor_discovery. */ + if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) + { + handle = result_data.p_char_desc_uuid16_disc_data->handle; + if ((handle > hdl_cache[HDL_SIMBLE_V3_NOTIFY]) + && (handle < hdl_cache[HDL_SIMBLE_V4_INDICATE])) + { + hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD] = handle; + } + else if ((handle > hdl_cache[HDL_SIMBLE_V4_INDICATE]) && + (hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD] == 0)) + { + hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD] = handle; + } + } + break; + + default: + APP_PRINT_ERROR0("simp_handle_discover_result: Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +static void simp_ble_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_SIMP_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = simp_table[conn_id].hdl_cache; + + cb_data.cb_type = SIMP_CLIENT_CB_TYPE_READ_RESULT; + + APP_PRINT_INFO2("simp_ble_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_SIMBLE_V1_READ]) + { + cb_data.cb_content.read_result.type = SIMP_READ_V1_READ; + if (cause == GAP_SUCCESS) + { + cb_data.cb_content.read_result.data.v1_read.p_value = p_value; + cb_data.cb_content.read_result.data.v1_read.value_size = value_size; + } + else + { + cb_data.cb_content.read_result.data.v1_read.value_size = 0; + } + } + else if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]) + { + cb_data.cb_content.read_result.type = SIMP_READ_V3_NOTIFY_CCCD; + if (cause == GAP_SUCCESS) + { + uint16_t ccc_bit; + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("simp_ble_client_read_result_cb: invalid cccd len %d", value_size); + return; + } + LE_ARRAY_TO_UINT16(ccc_bit, p_value); + + if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + cb_data.cb_content.read_result.data.v3_notify_cccd = true; + } + else + { + cb_data.cb_content.read_result.data.v3_notify_cccd = false; + } + } + } + else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) + { + cb_data.cb_content.read_result.type = SIMP_READ_V4_INDICATE_CCCD; + if (cause == GAP_SUCCESS) + { + uint16_t ccc_bit; + if (value_size != 2) + { + PROFILE_PRINT_ERROR1("simp_ble_client_read_result_cb: invalid cccd len %d", value_size); + return; + } + LE_ARRAY_TO_UINT16(ccc_bit, p_value); + + if (ccc_bit & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + cb_data.cb_content.read_result.data.v4_indicate_cccd = true; + } + else + { + cb_data.cb_content.read_result.data.v4_indicate_cccd = false; + } + } + } + else + { + return; + } + /* Inform application the read result. */ + if (simp_client_cb) + { + (*simp_client_cb)(simp_client, conn_id, &cb_data); + } + + return; +} + +static void simp_ble_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, + uint16_t handle, uint16_t cause, + uint8_t credits) +{ + T_SIMP_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = simp_table[conn_id].hdl_cache; + cb_data.cb_type = SIMP_CLIENT_CB_TYPE_WRITE_RESULT; + + PROFILE_PRINT_INFO2("simp_ble_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.write_result.cause = cause; + + if (handle == hdl_cache[HDL_SIMBLE_V2_WRITE]) + { + cb_data.cb_content.write_result.type = SIMP_WRITE_V2_WRITE; + } + else if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY_CCCD]) + { + cb_data.cb_content.write_result.type = SIMP_WRITE_V3_NOTIFY_CCCD; + } + else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE_CCCD]) + { + cb_data.cb_content.write_result.type = SIMP_WRITE_V4_INDICATE_CCCD; + } + else + { + return; + } + /* Inform application the write result. */ + if (simp_client_cb) + { + (*simp_client_cb)(simp_client, conn_id, &cb_data); + } + + return; +} + +static T_APP_RESULT simp_ble_client_notif_ind_result_cb(uint8_t conn_id, bool notify, + uint16_t handle, + uint16_t value_size, uint8_t *p_value) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + T_SIMP_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = simp_table[conn_id].hdl_cache; + + cb_data.cb_type = SIMP_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + + if (handle == hdl_cache[HDL_SIMBLE_V3_NOTIFY]) + { + cb_data.cb_content.notif_ind_data.type = SIMP_V3_NOTIFY; + cb_data.cb_content.notif_ind_data.data.value_size = value_size; + cb_data.cb_content.notif_ind_data.data.p_value = p_value; + } + else if (handle == hdl_cache[HDL_SIMBLE_V4_INDICATE]) + { + cb_data.cb_content.notif_ind_data.type = SIMP_V4_INDICATE; + cb_data.cb_content.notif_ind_data.data.value_size = value_size; + cb_data.cb_content.notif_ind_data.data.p_value = p_value; + } + else + { + return app_result; + } + /* Inform application the notif/ind result. */ + if (simp_client_cb) + { + app_result = (*simp_client_cb)(simp_client, conn_id, &cb_data); + } + + return app_result; +} + +static void simp_ble_client_disconnect_cb(uint8_t conn_id) +{ + APP_PRINT_INFO0("simp_ble_client_disconnect_cb."); + if (conn_id >= simp_link_num) + { + PROFILE_PRINT_ERROR1("simp_ble_client_disconnect_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&simp_table[conn_id], 0, sizeof(T_SIMP_LINK)); + return; +} + +/** + * @brief Simple BLE Client Callbacks. +*/ +const T_FUN_CLIENT_CBS simp_ble_client_cbs = +{ + simp_ble_client_discover_state_cb, //!< Discovery State callback function pointer + simp_ble_client_discover_result_cb, //!< Discovery result callback function pointer + simp_ble_client_read_result_cb, //!< Read response callback function pointer + simp_ble_client_write_result_cb, //!< Write result callback function pointer + simp_ble_client_notif_ind_result_cb, //!< Notify Indicate callback function pointer + simp_ble_client_disconnect_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add simple ble service client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + simple_ble_client_id = simp_ble_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID simp_ble_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > SIMP_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("simp_ble_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&simp_client, &simp_ble_client_cbs)) + { + simp_client = CLIENT_PROFILE_GENERAL_ID; + APP_PRINT_ERROR0("simp_ble_add_client failed"); + return simp_client; + } + APP_PRINT_INFO1("simp_ble_add_client: simp_client %d", simp_client); + + /* register callback for profile to inform application that some events happened. */ + simp_client_cb = app_cb; + simp_link_num = link_num; + size = simp_link_num * sizeof(T_SIMP_LINK); + simp_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return simp_client; +} + diff --git a/src/ble/profile/client/tps_client.c b/src/ble/profile/client/tps_client.c new file mode 100644 index 0000000..9878b21 --- /dev/null +++ b/src/ble/profile/client/tps_client.c @@ -0,0 +1,469 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file tps_client.c + * @brief + * @details + * @author ken + * @date 2017-12-06 + * @version v1.0 + ****************************************************************************** + */ + +/** Add Includes here **/ +#include +#include +#include +#include + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +#define GATT_UUID_TX_POWER_SERVICE 0x1804 +#define GATT_UUID_CHAR_TX_LEVEL 0x2A07 +/** + * @brief TPS client Link control block defination. + */ +typedef struct +{ + T_TPS_DISC_STATE disc_state; + uint16_t hdl_cache[HDL_TPS_CACHE_LEN]; +} T_TPS_LINK, *P_TPS_LINK; + +static P_TPS_LINK tps_table; +static uint8_t tps_link_num; + +/**< TPS client ID. */ +static T_CLIENT_ID tps_client = CLIENT_PROFILE_GENERAL_ID; +/**< Callback used to send data to app from TPS client layer. */ +static P_FUN_GENERAL_APP_CB tps_client_cb = NULL; + +/** + * @brief Used by application, to start the discovery procedure of battery service. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + */ +bool tps_start_discovery(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("tps_start_discovery"); + if (conn_id >= tps_link_num) + { + PROFILE_PRINT_ERROR1("bas_start_discovery: failed invalid conn_id %d", conn_id); + return false; + } + /* First clear handle cache. */ + memset(&tps_table[conn_id], 0, sizeof(T_TPS_LINK)); + tps_table[conn_id].disc_state = DISC_TPS_START; + if (client_by_uuid_srv_discovery(conn_id, tps_client, + GATT_UUID_TX_POWER_SERVICE) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +/** + * @brief Used by application, to read tx power level. + * @param[in] conn_id connection ID. + * @retval true send request to upper stack success. + * @retval false send request to upper stack failed. + * + */ +bool tps_read_power_level(uint8_t conn_id) +{ + if (conn_id >= tps_link_num) + { + PROFILE_PRINT_ERROR1("tps_read_battery_level: failed invalid conn_id %d", conn_id); + return false; + } + if (tps_table[conn_id].hdl_cache[HDL_TPS_PARA]) + { + uint16_t handle = tps_table[conn_id].hdl_cache[HDL_TPS_PARA]; + if (client_attr_read(conn_id, tps_client, handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + } + PROFILE_PRINT_ERROR0("tps_read_battery_level: false handle = 0"); + return false; +} + +/** + * @brief Used by application, to get handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + */ +bool tps_get_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= tps_link_num) + { + PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (tps_table[conn_id].disc_state != DISC_TPS_DONE) + { + PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid state %d", tps_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_TPS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("tps_get_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(p_hdl_cache, tps_table[conn_id].hdl_cache, len); + return true; +} + +/** + * @brief Used by application, to set handle cache. + * @param[in] conn_id connection ID. + * @param[in] p_hdl_cache pointer of the handle cache table + * @param[in] len the length of handle cache table + * @retval true success. + * @retval false failed. + * + */ +bool tps_set_hdl_cache(uint8_t conn_id, uint16_t *p_hdl_cache, uint8_t len) +{ + if (conn_id >= tps_link_num) + { + PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid conn_id %d", conn_id); + return false; + } + if (tps_table[conn_id].disc_state != DISC_TPS_IDLE) + { + PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid state %d", tps_table[conn_id].disc_state); + return false; + } + if (len != sizeof(uint16_t) * HDL_TPS_CACHE_LEN) + { + PROFILE_PRINT_ERROR1("tps_set_hdl_cache: failed invalid len %d", len); + return false; + } + memcpy(tps_table[conn_id].hdl_cache, p_hdl_cache, len); + tps_table[conn_id].disc_state = DISC_TPS_DONE; + return true; +} + +static bool tps_start_char_discovery(uint8_t conn_id) +{ + uint16_t start_handle; + uint16_t end_handle; + + PROFILE_PRINT_INFO0("tps_start_char_discovery"); + start_handle = tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START]; + end_handle = tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END]; + if (client_all_char_discovery(conn_id, tps_client, start_handle, + end_handle) == GAP_CAUSE_SUCCESS) + { + return true; + } + return false; +} + +//static bool bas_start_char_descriptor_discovery(uint8_t conn_id) +//{ +// uint16_t start_handle; +// uint16_t end_handle; + +// PROFILE_PRINT_INFO0("bas_start_char_descriptor_discovery"); +// start_handle = bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL]; +// end_handle = bas_table[conn_id].hdl_cache[HDL_BAS_SRV_END]; +// if (client_all_char_descriptor_discovery(conn_id, bas_client, start_handle, +// end_handle) == GAP_CAUSE_SUCCESS) +// { +// return true; +// } +// return false; +//} + +static void tps_client_discover_state_cb(uint8_t conn_id, T_DISCOVERY_STATE discovery_state) +{ + bool cb_flag = false; + T_TPS_CLIENT_CB_DATA cb_data; + cb_data.cb_type = TPS_CLIENT_CB_TYPE_DISC_STATE; + + PROFILE_PRINT_INFO1("tps_client_discover_state_cb: discovery_state = %d", discovery_state); + if (tps_table[conn_id].disc_state == DISC_TPS_START) + { + switch (discovery_state) + { + case DISC_STATE_SRV_DONE: + /* Indicate that service handle found. Start discover characteristic. */ + if ((tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START] != 0) + || (tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END] != 0)) + { + if (tps_start_char_discovery(conn_id) == false) + { + tps_table[conn_id].disc_state = DISC_TPS_FAILED; + cb_flag = true; + } + } + /* No TPS handle found. Discover procedure complete. */ + else + { + tps_table[conn_id].disc_state = DISC_TPS_FAILED; + cb_flag = true; + } + break; + case DISC_STATE_CHAR_DONE: + tps_table[conn_id].disc_state = DISC_TPS_DONE; + cb_flag = true; +// if (tps_table[conn_id].properties & GATT_CHAR_PROP_NOTIFY) +// { +// //discovery cccd +// if (tps_start_char_descriptor_discovery(conn_id) == false) +// { +// tps_table[conn_id].disc_state = DISC_TPS_FAILED; +// cb_flag = true; +// } +// } +// else +// { +// tps_table[conn_id].disc_state = DISC_TPS_DONE; +// cb_flag = true; +// } + break; + + case DISC_STATE_CHAR_DESCRIPTOR_DONE: +// bas_table[conn_id].disc_state = DISC_BAS_DONE; +// cb_flag = true; + break; + + case DISC_STATE_FAILED: + tps_table[conn_id].disc_state = DISC_TPS_FAILED; + cb_flag = true; + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery State!"); + break; + } + } + + /* Send discover state to application if needed. */ + if (cb_flag && tps_client_cb) + { + cb_data.cb_content.disc_state = tps_table[conn_id].disc_state; + (*tps_client_cb)(tps_client, conn_id, &cb_data); + } + return; +} + + +static void tps_client_discover_result_cb(uint8_t conn_id, T_DISCOVERY_RESULT_TYPE result_type, + T_DISCOVERY_RESULT_DATA result_data) +{ + PROFILE_PRINT_INFO1("tps_client_discover_result_cb: result_type = %d", result_type); + if (tps_table[conn_id].disc_state == DISC_TPS_START) + { + switch (result_type) + { + case DISC_RESULT_SRV_DATA: + tps_table[conn_id].hdl_cache[HDL_TPS_SRV_START] = + result_data.p_srv_disc_data->att_handle; + tps_table[conn_id].hdl_cache[HDL_TPS_SRV_END] = + result_data.p_srv_disc_data->end_group_handle; + break; + + case DISC_RESULT_CHAR_UUID16: + { + uint16_t handle; + handle = result_data.p_char_uuid16_disc_data->value_handle; + if (result_data.p_char_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_TX_LEVEL) + { + tps_table[conn_id].hdl_cache[HDL_TPS_PARA] = handle; + } + } + break; + + case DISC_RESULT_CHAR_DESC_UUID16: +// if (result_data.p_char_desc_uuid16_disc_data->uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) +// { +// bas_table[conn_id].hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD] = +// result_data.p_char_desc_uuid16_disc_data->handle; +// } + break; + + default: + PROFILE_PRINT_ERROR0("Invalid Discovery Result Type!"); + break; + } + } + + return; +} + +//static void bas_client_write_result_cb(uint8_t conn_id, T_GATT_WRITE_TYPE type, +// uint16_t handle, +// uint16_t cause, +// uint8_t credits) +//{ +// T_BAS_CLIENT_CB_DATA cb_data; +// uint16_t *hdl_cache; +// hdl_cache = bas_table[conn_id].hdl_cache; +// cb_data.cb_type = BAS_CLIENT_CB_TYPE_WRITE_RESULT; + +// PROFILE_PRINT_INFO2("bas_client_write_result_cb: handle 0x%x, cause 0x%x", handle, cause); +// cb_data.cb_content.write_result.cause = cause; + +// if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL_CCCD]) +// { +// if (bas_table[conn_id].write_notify_value) +// { +// cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_ENABLE; +// } +// else +// { +// cb_data.cb_content.write_result.type = BAS_WRITE_NOTIFY_DISABLE; +// } +// } +// else +// { +// return; +// } + +// if (bas_client_cb) +// { +// (*bas_client_cb)(bas_client, conn_id, &cb_data); +// } +// return; +//} + +static void tps_client_read_result_cb(uint8_t conn_id, uint16_t cause, + uint16_t handle, uint16_t value_size, uint8_t *p_value) +{ + T_TPS_CLIENT_CB_DATA cb_data; + uint16_t *hdl_cache; + hdl_cache = tps_table[conn_id].hdl_cache; + cb_data.cb_type = TPS_CLIENT_CB_TYPE_READ_RESULT; + + PROFILE_PRINT_INFO2("tps_client_read_result_cb: handle 0x%x, cause 0x%x", handle, cause); + cb_data.cb_content.read_result.cause = cause; + + if (handle == hdl_cache[HDL_TPS_PARA]) + { + cb_data.cb_content.read_result.type = TPS_READ_PARA; + if (cause == GAP_SUCCESS) + { + if (value_size != 1) + { + PROFILE_PRINT_ERROR1("tps_client_read_result_cb: invalid battery value len %d", value_size); + return; + } + cb_data.cb_content.read_result.data.txpower_level = *p_value; + } + } + else + { + return; + } + + if (tps_client_cb) + { + (*tps_client_cb)(tps_client, conn_id, &cb_data); + } + return; +} + +//static T_APP_RESULT tps_client_notify_ind_cb(uint8_t conn_id, bool notify, uint16_t handle, +// uint16_t value_size, uint8_t *p_value) +//{ +// T_APP_RESULT app_result = APP_RESULT_SUCCESS; +// T_BAS_CLIENT_CB_DATA cb_data; +// uint16_t *hdl_cache; + +// hdl_cache = bas_table[conn_id].hdl_cache; +// cb_data.cb_type = BAS_CLIENT_CB_TYPE_NOTIF_IND_RESULT; + +// if (handle == hdl_cache[HDL_BAS_BATTERY_LEVEL]) +// { +// cb_data.cb_content.notify_data.battery_level = *p_value; +// } +// else +// { +// return APP_RESULT_SUCCESS; +// } + +// if (bas_client_cb) +// { +// app_result = (*bas_client_cb)(bas_client, conn_id, &cb_data); +// } + +// return app_result; +//} + +static void tps_client_disc_cb(uint8_t conn_id) +{ + PROFILE_PRINT_INFO0("tps_client_disc_cb."); + if (conn_id >= tps_link_num) + { + PROFILE_PRINT_ERROR1("tps_client_disc_cb: failed invalid conn_id %d", conn_id); + return; + } + memset(&tps_table[conn_id], 0, sizeof(T_TPS_LINK)); + return; +} +/** + * @brief BAS Client Callbacks. +*/ +const T_FUN_CLIENT_CBS tps_client_cbs = +{ + tps_client_discover_state_cb, //!< Discovery State callback function pointer + tps_client_discover_result_cb, //!< Discovery result callback function pointer + tps_client_read_result_cb, //!< Read response callback function pointer + NULL,//bas_client_write_result_cb, //!< Write result callback function pointer + NULL,//bas_client_notify_ind_cb, //!< Notify Indicate callback function pointer + tps_client_disc_cb //!< Link disconnection callback function pointer +}; + +/** + * @brief Add tps client to application. + * @param[in] app_cb pointer of app callback function to handle specific client module data. + * @param[in] link_num initialize link num. + * @return Client ID of the specific client module. + * @retval 0xff failed. + * @retval other success. + * + * Example usage + * \code{.c} + void app_le_profile_init(void) + { + client_init(1); + tps_client_id = tps_add_client(app_client_callback, APP_MAX_LINKS); + } + * \endcode + */ +T_CLIENT_ID tps_add_client(P_FUN_GENERAL_APP_CB app_cb, uint8_t link_num) +{ + uint16_t size; + if (link_num > TPS_MAX_LINKS) + { + PROFILE_PRINT_ERROR1("tps_add_client: invalid link_num %d", link_num); + return 0xff; + } + if (false == client_register_spec_client_cb(&tps_client, &tps_client_cbs)) + { + tps_client = CLIENT_PROFILE_GENERAL_ID; + PROFILE_PRINT_ERROR0("tps_add_client:register fail"); + return tps_client; + } + PROFILE_PRINT_INFO1("tps_add_client: client id %d", tps_client); + + /* register callback for profile to inform application that some events happened. */ + tps_client_cb = app_cb; + tps_link_num = link_num; + size = tps_link_num * sizeof(T_TPS_LINK); + tps_table = os_mem_zalloc(RAM_TYPE_DATA_ON, size); + + return tps_client; +} + diff --git a/src/ble/profile/module/srv_uuid.c b/src/ble/profile/module/srv_uuid.c new file mode 100644 index 0000000..c21c8d0 --- /dev/null +++ b/src/ble/profile/module/srv_uuid.c @@ -0,0 +1,114 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file srv_uuid.c +* @brief the general implementation for GATT server. +* @author +* @date 2020-09-10 +* @version v1.0 +********************************************************************************************************* +*/ + +#include +#include "trace.h" +#include "os_mem.h" +#include "srv_uuid.h" + +T_SRV_CHAR_TBL *srv_uuid_create_tbl(const T_ATTRIB_APPL *p_att_tbl, uint16_t att_tbl_size) +{ + T_SRV_CHAR_TBL *p_tbl; + uint16_t p_num = att_tbl_size / sizeof(T_ATTRIB_APPL); + uint16_t mem_size; + uint8_t char_cur_num = 0; + + APP_PRINT_ERROR1("srv_uuid_create_tbl: p_num %d", p_num); + if ((p_att_tbl == NULL) || (att_tbl_size == 0)) + { + return NULL; + } + + uint16_t char_type = 0; + for (uint8_t i = 0; i < p_num; i++) + { + memcpy(&char_type, &p_att_tbl->type_value[0], 2); + if (char_type == GATT_UUID_CHARACTERISTIC) + { + char_cur_num++; + } + p_att_tbl++; + } + + mem_size = sizeof(T_SRV_CHAR_TBL) + (char_cur_num - 1) * sizeof(T_SRV_UUID_TBL); + APP_PRINT_INFO2("srv_uuid_create_tbl: char_num %d, mem_size %d", char_cur_num, mem_size); + p_tbl = os_mem_zalloc(RAM_TYPE_DATA_ON, mem_size); + + p_tbl->char_num = char_cur_num; + p_att_tbl = p_att_tbl - p_num; + + uint8_t num = 0; + for (uint8_t i = 0; i < p_num; i++) + { + memcpy(&char_type, &p_att_tbl->type_value[0], 2); + if (char_type == GATT_UUID_CHARACTERISTIC) + { + p_att_tbl ++; + memcpy(&p_tbl->p_char_tbl[num].char_uuid16, &p_att_tbl->type_value[0], 2); + p_tbl->p_char_tbl[num].char_index = i + 1; + num++; + } + else + { + p_att_tbl++; + } + } + return p_tbl; +} + +T_SRV_UUID_TBL *srv_find_uuid_by_index(T_SRV_CHAR_TBL *p_srv, uint8_t index) +{ + if (p_srv == NULL) + { + return NULL; + } + + if (p_srv->char_num != 0) + { + uint8_t i = 0; + for (i = 0; i < p_srv->char_num; i++) + { + if (p_srv->p_char_tbl[i].char_index == index) + { + APP_PRINT_INFO1("srv_find_uuid_by_index: char_num %d", i); + return &p_srv->p_char_tbl[i]; + } + } + } + APP_PRINT_ERROR2("srv_find_uuid_by_index: failed, p_srv->char_num %d, index %d", + p_srv->char_num, index); + return NULL; +} + +T_SRV_UUID_TBL *srv_find_index_by_uuid(T_SRV_CHAR_TBL *p_srv, uint16_t uuid16) +{ + if (p_srv == NULL) + { + return NULL; + } + + if (p_srv->char_num != 0) + { + uint8_t i = 0; + for (i = 0; i < p_srv->char_num; i++) + { + if (p_srv->p_char_tbl[i].char_uuid16 == uuid16) + { + return &p_srv->p_char_tbl[i]; + } + } + } + APP_PRINT_ERROR2("srv_find_index_by_uuid: failed, p_srv->char_num %d, uuid16 %d", + p_srv->char_num, uuid16); + return NULL; +} + diff --git a/src/ble/profile/module/srv_uuid.h b/src/ble/profile/module/srv_uuid.h new file mode 100644 index 0000000..8c23c45 --- /dev/null +++ b/src/ble/profile/module/srv_uuid.h @@ -0,0 +1,48 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file srv_uuid.h + * @brief Head file for server structure. + * @details Common data struct definition. + * @author + * @date 2020-09-10 + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef SRV_UUID_H +#define SRV_UUID_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "profile_server.h" +#include "gatt.h" + +typedef struct +{ + uint16_t char_uuid16; + uint8_t char_index; +} T_SRV_UUID_TBL; + +typedef struct +{ + uint8_t char_num; + T_SRV_UUID_TBL p_char_tbl[1]; +} T_SRV_CHAR_TBL; + +T_SRV_CHAR_TBL *srv_uuid_create_tbl(const T_ATTRIB_APPL *p_att_tbl, uint16_t att_tbl_size); +T_SRV_UUID_TBL *srv_find_uuid_by_index(T_SRV_CHAR_TBL *p_srv, uint8_t index); +T_SRV_UUID_TBL *srv_find_index_by_uuid(T_SRV_CHAR_TBL *p_srv, uint16_t uuid16); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SRV_UUID_H */ diff --git a/src/ble/profile/server/atvv_service.c b/src/ble/profile/server/atvv_service.c new file mode 100644 index 0000000..d9fea47 --- /dev/null +++ b/src/ble/profile/server/atvv_service.c @@ -0,0 +1,392 @@ +enum { __FILE_NUM__ = 0 }; + +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file atvv_service.c +* @brief ATV voice service source file. +* @details Interfaces to access ATV voice service. +* @author Chenjie Jin +* @date 2020-03-11 +* @version v0.1 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "board.h" +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "atvv_service.h" + +#if (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW) + +/*============================================================================* + * Global Variables + *============================================================================*/ +T_ATVV_GLOBAL_DATA atvv_global_data; + +/*============================================================================* + * Local Variables + *============================================================================*/ +static P_FUN_SERVER_GENERAL_CB pfn_atvv_cb = NULL; + +const uint8_t GATT_UUID_ATVV_SERVICE[16] = {0x64, 0xB6, 0x17, 0xF6, 0x01, 0xAF, 0x7D, 0xBC, 0x05, 0x4F, 0x21, 0x5A, 0x01, 0x00, 0x5E, 0xAB}; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL atvv_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)GATT_UUID_ATVV_SERVICE, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* ATVV_CHAR_TX */ + /* Characteristic Definition, 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 2 */ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */ + { /* bTypeValue */ + GATT_UUID_ATV_CHAR_TX + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + + /* ATVV_CHAR_RX */ + /* Characteristic, 3 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 4 */ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */ + { /* bTypeValue */ + GATT_UUID_ATV_CHAR_RX + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* client characteristic configuration, 5 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /* ATVV_CHAR_CTL */ + /* Characteristic, 6 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 7 */ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* wFlags */ + { /* bTypeValue */ + GATT_UUID_ATV_CHAR_CTL + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* client characteristic configuration, 8 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +}; +/**< @brief ATV Voice service size definition. */ +const int atvv_attr_tbl_size = sizeof(atvv_attr_tbl); + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief read characteristic data from service. + * + * @param conn_id Connection ID. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Offset of characteritic to be read. + * @param p_length Length of getting characteristic data. + * @param pp_value Pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT attv_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + + PROFILE_PRINT_INFO2("bas_attr_read_cb attrib_index = %d offset %x", attrib_index, offset); + + switch (attrib_index) + { + case GATT_SVC_ATVV_CHAR_RX_VALUE_INDEX: + { + T_ATVV_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = ATVV_READ_CHAR_RX_INDEX; + if (pfn_atvv_cb) + { + cause = pfn_atvv_cb(service_id, (void *)&callback_data); + } + + if (cause != APP_RESULT_SUCCESS) + { + memset(atvv_global_data.char_rx_data_buff, 0, ATVV_CHAR_RX_DATA_LEN); + } + *pp_value = atvv_global_data.char_rx_data_buff; + *p_length = ATVV_CHAR_RX_DATA_LEN; + } + break; + + case GATT_SVC_ATVV_CHAR_CTL_VALUE_INDEX: + { + T_ATVV_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = ATVV_READ_CHAR_CTL_INDEX; + if (pfn_atvv_cb) + { + cause = pfn_atvv_cb(service_id, (void *)&callback_data); + } + + if (cause != APP_RESULT_SUCCESS) + { + memset(atvv_global_data.char_ctl_data_buff, 0, ATVV_CHAR_CTL_DATA_LEN); + } + + *pp_value = atvv_global_data.char_ctl_data_buff; + *p_length = ATVV_CHAR_CTL_DATA_LEN; + } + break; + + default: + { + PROFILE_PRINT_ERROR1("attv_attr_read_cb attrib_index = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return (cause); +} + +void atvv_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t length, uint8_t *p_value) +{ + T_ATVV_CALLBACK_DATA callback_data; + + APP_PRINT_INFO4("atvv_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d", + conn_id, service_id, attrib_index, length); + + if (GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX == attrib_index) + { + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_type = ATVV_WRITE_CHAR_TX_INDEX; + callback_data.msg_data.write.write_parameter.report_data.len = length; + callback_data.msg_data.write.write_parameter.report_data.report = p_value; + + if (pfn_atvv_cb) + { + pfn_atvv_cb(service_id, (void *)&callback_data); + } + } +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length Length of writing characteristic data. + * @param[in] p_value Pointer to characteristic data. + * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb. + * @return TProfileResult +*/ +T_APP_RESULT atvv_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + APP_PRINT_INFO1("atvv_attr_write_cb write_type = 0x%x", write_type); + + *p_write_ind_post_proc = atvv_write_post_callback; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + } + else if (attrib_index == GATT_SVC_ATVV_CHAR_TX_VALUE_INDEX) + { + cause = APP_RESULT_SUCCESS; + } + else + { + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + return cause; +} + + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id Connection ID. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None +*/ +void atvv_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_ATVV_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + bool handle = true; + + PROFILE_PRINT_INFO2("atvv_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SVC_ATVV_CHAR_RX_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = ATVV_CHAR_RX_NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = ATVV_CHAR_RX_NOTIFY_DISABLE; + } + break; + + case GATT_SVC_ATVV_CHAR_CTL_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = ATVV_CHAR_CTL_NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = ATVV_CHAR_CTL_NOTIFY_DISABLE; + } + break; + + default: + handle = false; + break; + } + /* Notify Application. */ + if (pfn_atvv_cb && (handle == true)) + { + pfn_atvv_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief ATV Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS atvv_cbs = +{ + attv_attr_read_cb, // Read callback function pointer + atvv_attr_write_cb, // Write callback function pointer + atvv_cccd_update_cb // CCCD update callback function pointer +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief add ATV voice service to application. + * + * @param[in] pFunc pointer of app callback function called by profile. + * @return service ID auto generated by profile layer. + * @retval ServiceId + */ +uint8_t atvv_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)atvv_attr_tbl, + atvv_attr_tbl_size, + atvv_cbs)) + { + APP_PRINT_ERROR1("atvv_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_atvv_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +#endif /* (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW) */ + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/bas.c b/src/ble/profile/server/bas.c new file mode 100644 index 0000000..0438f44 --- /dev/null +++ b/src/ble/profile/server/bas.c @@ -0,0 +1,374 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file bas.c +* @brief Battery service source file. +* @details Interfaces to access Battery service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "bas.h" +#include "bas_config.h" + +/*============================================================================* + * Macros + *============================================================================*/ +#define GATT_UUID_BATTERY 0x180F +#define GATT_UUID_CHAR_BAS_LEVEL 0x2A19 + +#define GATT_SVC_BAS_BATTERY_LEVEL_INDEX 2 /**< @brief Index for battery level chars's value */ +#define GATT_SVC_BAS_CHAR_CCCD_INDEX 3 /**< @brief CCCD Index for battery level chars's value */ + +/*============================================================================* + * Local Variables + *============================================================================*/ +/**< BatteryLevel value. */ +static uint8_t battery_level = 0; +static bool bas_read_battery_level_pending = false; +/**< Function pointer used to send event to application from pxp profile. */ +/**< Initiated in PXP_AddService. */ +static P_FUN_SERVER_GENERAL_CB pfn_bas_cb = NULL; + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL bas_attr_tbl[] = +{ + /*----------------- Battery Service -------------------*/ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_BATTERY), /* service UUID */ + HI_WORD(GATT_UUID_BATTERY) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* p_value_context */ + GATT_PERM_READ /* permissions */ + }, + + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), +#if BAS_BATTERY_LEVEL_NOTIFY_SUPPORT + (GATT_CHAR_PROP_READ | /* characteristic properties */ + GATT_CHAR_PROP_NOTIFY) +#else + GATT_CHAR_PROP_READ +#endif + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Battery Level value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BAS_LEVEL), + HI_WORD(GATT_UUID_CHAR_BAS_LEVEL) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + } +#if BAS_BATTERY_LEVEL_NOTIFY_SUPPORT + , + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ + } +#endif +}; + +/**< @brief Battery service size definition. */ +const static uint16_t bas_attr_tbl_size = sizeof(bas_attr_tbl); + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief Set a battery service parameter. + * + * NOTE: You can call this function with a battery service parameter type and it will set the + * battery service parameter. Battery service parameters are defined in @ref T_BAS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Battery service parameter type: @ref T_BAS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 80; + bas_set_parameter(BAS_PARAM_BATTERY_LEVEL, 1, &battery_level); + } + * \endcode + */ +bool bas_set_parameter(T_BAS_PARAM_TYPE param_type, uint8_t length, uint8_t *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR1("bas_set_parameter: unknown param_type 0x%02x", param_type); + } + break; + + case BAS_PARAM_BATTERY_LEVEL: + { + if (length != sizeof(uint8_t)) + { + ret = false; + } + else + { + battery_level = p_value[0]; + } + } + break; + } + + return ret; +} + +/** + * @brief Send notify battery level notification data . + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] battery_level Battery level value. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool bas_battery_level_value_notify(uint8_t conn_id, uint8_t service_id, uint8_t battery_level) +{ + return server_send_data(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX, &battery_level, + sizeof(battery_level), GATT_PDU_TYPE_ANY); +} + +/** + * @brief Confirm for read battery level value request. + * + * @param[in] conn_id Callback when service attribute was read/write. + * @param[in] service_id Callback when service attribute was read/write. + * @param[in] battery_level Callback when service attribute was read/write. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_read_confirm(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool bas_battery_level_value_read_confirm(uint8_t conn_id, uint8_t service_id, + uint8_t battery_level) +{ + if (bas_read_battery_level_pending == true) + { + bas_read_battery_level_pending = false; + return server_attr_read_confirm(conn_id, service_id, GATT_SVC_BAS_BATTERY_LEVEL_INDEX, + &battery_level, sizeof(battery_level), APP_RESULT_SUCCESS); + } + else + { + return false; + } +} + +/** + * @brief read characteristic data from service. + * + * @param conn_id Connection ID. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Offset of characteritic to be read. + * @param p_length Length of getting characteristic data. + * @param pp_value Pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT bas_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + + PROFILE_PRINT_INFO2("bas_attr_read_cb: attrib_index %d offset %d", attrib_index, offset); + + switch (attrib_index) + { + default: + { + PROFILE_PRINT_ERROR0("bas_attr_read_cb: unknown attrib_index"); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + + case GATT_SVC_BAS_BATTERY_LEVEL_INDEX: + { + T_BAS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + callback_data.msg_data.read_value_index = BAS_READ_BATTERY_LEVEL; + cause = pfn_bas_cb(service_id, (void *)&callback_data); + if (cause == APP_RESULT_PENDING) + { + bas_read_battery_level_pending = true; + } + + *pp_value = &battery_level; + *p_length = sizeof(battery_level); + } + break; + } + return (cause); +} + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id Connection ID. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None +*/ +void bas_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_BAS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool handle = true; + PROFILE_PRINT_INFO2("bas_cccd_update_cb: index %d ccc_bits 0x%04x", index, ccc_bits); + + switch (index) + { + case GATT_SVC_BAS_CHAR_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = BAS_NOTIFY_BATTERY_LEVEL_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = BAS_NOTIFY_BATTERY_LEVEL_DISABLE; + } + break; + } + default: + { + handle = false; + break; + } + + } + + if (pfn_bas_cb && (handle == true)) + { + pfn_bas_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief BAS Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS bas_cbs = +{ + bas_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + bas_cccd_update_cb // CCCD update callback function pointer +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief Add battery service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bas_id = bas_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID bas_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)bas_attr_tbl, + bas_attr_tbl_size, + bas_cbs)) + { + PROFILE_PRINT_ERROR1("bas_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_bas_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/bcs.c b/src/ble/profile/server/bcs.c new file mode 100644 index 0000000..1df5b0c --- /dev/null +++ b/src/ble/profile/server/bcs.c @@ -0,0 +1,494 @@ +/********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rigbcs reserved. +********************************************************************************************************** +* @file bcs.c +* @brief Body Composition Service source file. +* @details Interfaces to access Body Composition Service. +* @author +* @date 2017-9-21 +* @version v1.0 +********************************************************************************************************* +*/ +#include "stdint.h" +#include "gatt.h" +#include +#include "trace.h" +#include "profile_server.h" +#include "bcs.h" + + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +#define BCS_BODY_COMPOSITION_FEATURE_INDEX 2 +#define BCS_BODY_COMPOSITION_MEASUREMENT_INDEX 4 +#define BCS_BODY_COMPOSITION_MEASUREMENT_CCCD_INDEX 5 + +T_BODY_COMPOSITION_FEATURE bcs_body_composition_feature = {0}; +static uint8_t bcs_measurement_value_for_indicate[BCS_MEASUREMENT_VALUE_MAX_LEN] = {0}; +static uint8_t bcs_measurement_remain_value_for_indicate[10] = {0}; + +static uint8_t bcs_measurement_value_actual_length = 0; +static uint8_t bcs_measurement_value_first_length = 0; +static uint8_t bcs_measurement_value_second_length = 0; +static uint8_t bcs_measurement_value_consecutive_flag = 0; + +static uint8_t report_mtu = 20; + +/**< Function pointer used to send event to application from location and navigation profile. */ +static P_FUN_SERVER_GENERAL_CB pfn_bcs_cb = NULL; + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL bcs_attr_tbl[] = +{ + /*----------------- Body Composition Service -------------------*/ + /* <>, .. 0,*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_BODY_COMPOSITION), /* service UUID */ + HI_WORD(GATT_UUID_BODY_COMPOSITION) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1,*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_READ/* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Body Composition Feature 2,*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BODY_COMPOSITION_FEATURE), + HI_WORD(GATT_UUID_CHAR_BODY_COMPOSITION_FEATURE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ/* wPermissions */ + }, + + /* <>, .. 3,*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_INDICATE/* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Body Composition Measurement 4,*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BODY_COMPOSITION_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_BODY_COMPOSITION_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration 5,*/ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ + } +}; +/**< @brief Body Composition service size definition. */ +const static uint16_t bcs_attr_tbl_size = sizeof(bcs_attr_tbl); + +bool bcs_set_parameter(T_BCS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR0("bcs_set_parameter failed\n"); + } + break; + + case BCS_PARAM_BODY_COMPOSITION_FEATURE: + { + if (len != sizeof(uint32_t)) + { + ret = false; + } + else + { + memcpy(&bcs_body_composition_feature, p_value, len); + } + } + break; + } + return ret; +} + +void bcs_format_measurement_value(T_BCS_BODY_COMPOSITION_MEASUREMENT *p_data) +{ + uint8_t cur_offset = 2; + uint8_t remain_cur_offset = 2; + + T_BODY_COMPOSITION_MEASUREMENT_FLAG flag = {0}; + T_BODY_COMPOSITION_MEASUREMENT_FLAG remain_flag = {0}; + + flag.bcs_measurement_units_bit = p_data->bcs_measurement_flag.bcs_measurement_units_bit; + remain_flag.bcs_measurement_units_bit = p_data->bcs_measurement_flag.bcs_measurement_units_bit; + + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->body_fat_percentage, 2); + cur_offset += 2; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->body_fat_percentage, + 2); + remain_cur_offset += 2; + + if (p_data->bcs_measurement_flag.bcs_time_stamp_present_bit & + bcs_body_composition_feature.bcs_feature_time_stamp_support_bit & 1) + { + flag.bcs_time_stamp_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->time_stamp, 7); + cur_offset += 7; + } + + if (p_data->bcs_measurement_flag.bcs_user_id_bit & + bcs_body_composition_feature.bcs_feature_multiple_users_support_bit & 1) + { + flag.bcs_user_id_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->user_id, + 1); + cur_offset += 1; + } + + if (p_data->bcs_measurement_flag.bcs_basal_metabolism_present_bit & + bcs_body_composition_feature.bcs_feature_basal_metabolism_support_bit & 1) + { + flag.bcs_basal_metabolism_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->basal_metabolism, + 2); + cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_muscle_percentage_present_bit & + bcs_body_composition_feature.bcs_feature_muscle_percentage_support_bit & 1) + { + flag.bcs_muscle_percentage_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->muscle_percentage, + 2); + cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_muscle_mass_present_bit & + bcs_body_composition_feature.bcs_feature_muscle_mass_support_bit & 1) + { + flag.bcs_muscle_mass_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->muscle_mass, + 2); + cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_fat_free_mass_present_bit & + bcs_body_composition_feature.bcs_feature_fat_free_mass_support_bit & 1) + { + flag.bcs_fat_free_mass_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->fat_free_mass, + 2); + cur_offset += 2; + } + bcs_measurement_value_first_length = cur_offset; + + if (p_data->bcs_measurement_flag.bcs_soft_lean_mass_present_bit & + bcs_body_composition_feature.bcs_feature_soft_lean_mass_support_bit & 1) + { + flag.bcs_soft_lean_mass_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->soft_lean_mass, + 2); + cur_offset += 2; + bcs_measurement_value_first_length += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_first_length -= 2; + flag.bcs_soft_lean_mass_present_bit = 0; + remain_flag.bcs_soft_lean_mass_present_bit = 1; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->soft_lean_mass, + 2); + remain_cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_body_water_mass_present_bit & + bcs_body_composition_feature.bcs_feature_body_water_mass_support_bit & 1) + { + flag.bcs_body_water_mass_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->body_water_mass, + 2); + cur_offset += 2; + bcs_measurement_value_first_length += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_first_length -= 2; + flag.bcs_body_water_mass_present_bit = 0; + remain_flag.bcs_body_water_mass_present_bit = 1; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->body_water_mass, + 2); + remain_cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_impedance_present_bit & + bcs_body_composition_feature.bcs_feature_impedance_support_bit & 1) + { + flag.bcs_impedance_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->impedance, + 2); + cur_offset += 2; + bcs_measurement_value_first_length += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_first_length -= 2; + flag.bcs_impedance_present_bit = 0; + remain_flag.bcs_impedance_present_bit = 1; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->impedance, + 2); + remain_cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_weight_present_bit & + bcs_body_composition_feature.bcs_feature_weight_support_bit & 1) + { + flag.bcs_weight_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->weight, + 2); + cur_offset += 2; + bcs_measurement_value_first_length += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_first_length -= 2; + flag.bcs_weight_present_bit = 0; + remain_flag.bcs_weight_present_bit = 1; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->weight, + 2); + remain_cur_offset += 2; + } + + if (p_data->bcs_measurement_flag.bcs_height_present_bit & + bcs_body_composition_feature.bcs_feature_height_support_bit & 1) + { + flag.bcs_height_present_bit = 1; + memcpy(&bcs_measurement_value_for_indicate[cur_offset], &p_data->height, + 2); + cur_offset += 2; + bcs_measurement_value_first_length += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_first_length -= 2; + flag.bcs_height_present_bit = 0; + remain_flag.bcs_height_present_bit = 1; + memcpy(&bcs_measurement_remain_value_for_indicate[remain_cur_offset], &p_data->height, + 2); + remain_cur_offset += 2; + } + + if (cur_offset > report_mtu) + { + bcs_measurement_value_consecutive_flag = 1; + flag.bcs_multiple_packet_measurement_bit = 1; + remain_flag.bcs_multiple_packet_measurement_bit = 1; + } + + memcpy(&bcs_measurement_value_for_indicate, &flag, 2); + memcpy(&bcs_measurement_remain_value_for_indicate, &remain_flag, 2); + + bcs_measurement_value_actual_length = cur_offset; + bcs_measurement_value_second_length = remain_cur_offset; +} + +bool bcs_body_composition_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, + T_BCS_BODY_COMPOSITION_MEASUREMENT *p_data) +{ + APP_PRINT_INFO0("bcs_body_composition_measurement_value_indicate"); + bcs_format_measurement_value(p_data); + + if (bcs_measurement_value_consecutive_flag) + { + return server_send_data(conn_id, service_id, BCS_BODY_COMPOSITION_MEASUREMENT_INDEX, + (uint8_t *)&bcs_measurement_value_for_indicate, + bcs_measurement_value_first_length, GATT_PDU_TYPE_INDICATION); + } + + return server_send_data(conn_id, service_id, BCS_BODY_COMPOSITION_MEASUREMENT_INDEX, + (uint8_t *)&bcs_measurement_value_for_indicate, + bcs_measurement_value_actual_length, GATT_PDU_TYPE_INDICATION); +} + +bool bcs_measurement_value_consecutive_indicate(uint8_t conn_id, T_SERVER_ID service_id) +{ + uint8_t ret = false; + if (bcs_measurement_value_consecutive_flag) + { + APP_PRINT_INFO0("bcs_measurement_value_consecutive_indicate: send remain data"); + + server_send_data(conn_id, service_id, BCS_BODY_COMPOSITION_MEASUREMENT_INDEX, + (uint8_t *)&bcs_measurement_remain_value_for_indicate, + bcs_measurement_value_second_length, GATT_PDU_TYPE_INDICATION); + + bcs_measurement_value_consecutive_flag = 0; + ret = true; + } + return ret; +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT bcs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + T_BCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + PROFILE_PRINT_INFO2("bcs_attr_read_cb: attrib_index %d offset %d", attrib_index, offset); + + switch (attrib_index) + { + default: + { + PROFILE_PRINT_ERROR0("bcs_attr_read_cb: unknown attrib_index"); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + + case BCS_BODY_COMPOSITION_FEATURE_INDEX: + { + callback_data.conn_id = conn_id; + cause = pfn_bcs_cb(service_id, (void *)&callback_data); + + *pp_value = (uint8_t *)&bcs_body_composition_feature; + *p_length = sizeof(bcs_body_composition_feature); + } + break; + } + return (cause); +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void bcs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_BCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool handle = true; + PROFILE_PRINT_INFO2("bcs_cccd_update_cb: index %d ccc_bits 0x%04x", index, ccc_bits); + + switch (index) + { + case BCS_BODY_COMPOSITION_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + callback_data.msg_data.notification_indification_index = + BCS_INDICATE_BODY_COMPOSITIONT_MEASUREMENT_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = + BCS_INDICATE_BODY_COMPOSITIONT_MEASUREMENT_DISABLE; + } + break; + } + + default: + { + handle = false; + break; + } + } + + if (pfn_bcs_cb && (handle == true)) + { + pfn_bcs_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief Body Composition Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS bcs_cbs = +{ + bcs_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + bcs_cccd_update_cb // CCCD update callback function pointer +}; + +T_SERVER_ID bcs_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)bcs_attr_tbl, + bcs_attr_tbl_size, + bcs_cbs)) + { + PROFILE_PRINT_ERROR1("bcs_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + pfn_bcs_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + + return service_id; +} diff --git a/src/ble/profile/server/bls.c b/src/ble/profile/server/bls.c new file mode 100644 index 0000000..c9cc110 --- /dev/null +++ b/src/ble/profile/server/bls.c @@ -0,0 +1,385 @@ +/**************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rigbls reserved. +***************************************************************************************** + + * @file bls.c + * @brief blood pressure service source file. + * @details Interface to access the blood pressure service. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +#include "trace.h" +#include +#include "profile_server.h" +#include "bls.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +#define BLS_BLOOD_PRESSURE_MEASUREMENT_INDEX 2 + +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT +#define BLS_INTERMEDIATE_CUFF_PRESSURE_INDEX 5 +#define BLS_BLOOD_PRESSURE_FEATURE_INDEX 8 +#else +#define BLS_BLOOD_PRESSURE_FEATURE_INDEX 5 +#endif + +#define BLS_BLOOD_PRESSURE_MEASUREMENT_CCCD_INDEX 3 + +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT +#define BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD_INDEX 6 +#endif + +static uint16_t bls_blood_pressure_feature = 0; + +static uint8_t bls_measurement_value_for_notify_indicate[BLS_MEASUREMENT_VALUE_MAX_LEN]; +static uint8_t bls_measurement_value_actual_length = 0; + +static P_FUN_SERVER_GENERAL_CB pfn_bls_cb = NULL; + +/** @brief profile/service definition. */ +const T_ATTRIB_APPL bls_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_BLOOD_PRESSURE), /* service UUID */ + HI_WORD(GATT_UUID_BLOOD_PRESSURE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_INDICATE /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Blood Pressure Measurement characteristic value ---2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BLP_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_BLP_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration 3*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } + +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + , + /* <>, .. 4*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Intermediate Cuff Pressure characteristic value ---5*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_INTERMEDIATE_CUFF_PRESSURE), + HI_WORD(GATT_UUID_CHAR_INTERMEDIATE_CUFF_PRESSURE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif /**< end of INTERMEDIATE_CUFF_PRESSURE_SUPPORT */ + + , + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*---Blood Pressure Feature characteristic value ---8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BLP_FEATURE), + HI_WORD(GATT_UUID_CHAR_BLP_FEATURE), + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } +}; + +/**< @brief blood pressure service size definition. */ +const static uint16_t bls_attr_tbl_size = sizeof(bls_attr_tbl); + +bool bls_set_parameter(T_BLS_PARAM_TYPE param_type, uint8_t length, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR1("bls_set_parameter: unknown param_type 0x%02x", param_type); + } + break; + + + case BLS_PARAM_BLOOD_PRESUREE_FEATURE: + { + if (length != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&bls_blood_pressure_feature, p_value, 2); + } + } + break; + } + + return ret; +} + +void bls_format_measurement_value(T_BLOOD_PRESSURE_MEASURMENT *p_data) +{ + uint8_t cur_offset = 0; + + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], &p_data->bp_meas_flag, 1); + cur_offset += 1; + + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], + &p_data->bp_meas_compound_value, 6); + cur_offset += 6; + + if (p_data->bp_meas_flag & BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT) + { + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], &p_data->time_stamp, 7); + cur_offset += 7; + } + + if (p_data->bp_meas_flag & BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT) + { + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], &p_data->bp_meas_pulse_rate, + 2); + cur_offset += 2; + } + + if (p_data->bp_meas_flag & BLS_FLAG_MEASUREMENT_USER_ID_BIT) + { + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], &p_data->bp_meas_user_id, + 1); + cur_offset += 1; + } + + if (p_data->bp_meas_flag & BLS_FLAG_MEASUREMENT_STATUS_BIT) + { + memcpy(&bls_measurement_value_for_notify_indicate[cur_offset], &p_data->bp_meas_status, + 2); + cur_offset += 2; + } + + bls_measurement_value_actual_length = cur_offset; + +} + +bool bls_blood_pressure_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, + T_BLOOD_PRESSURE_MEASURMENT *p_data) +{ + APP_PRINT_INFO0("bls_blood_pressure_measurement_value_indicate"); + bls_format_measurement_value(p_data); + + return server_send_data(conn_id, service_id, BLS_BLOOD_PRESSURE_MEASUREMENT_INDEX, + (uint8_t *)&bls_measurement_value_for_notify_indicate, + bls_measurement_value_actual_length, GATT_PDU_TYPE_INDICATION); +} + +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT +bool bls_intermediate_cuff_pressure_value_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_BLOOD_PRESSURE_MEASURMENT *p_data) +{ + APP_PRINT_INFO0("bls_intermediate_cuff_pressure_value_notify"); + bls_format_measurement_value(p_data); + + return server_send_data(conn_id, service_id, BLS_INTERMEDIATE_CUFF_PRESSURE_INDEX, + (uint8_t *)&bls_measurement_value_for_notify_indicate, bls_measurement_value_actual_length, + GATT_PDU_TYPE_NOTIFICATION); +} +#endif + +T_APP_RESULT bls_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + T_BLS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + PROFILE_PRINT_INFO2("bls_attr_read_cb: attrib_index %d offset %d", attrib_index, offset); + + switch (attrib_index) + { + default: + { + PROFILE_PRINT_ERROR0("bls_attr_read_cb: unknown attrib_index"); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + + case BLS_BLOOD_PRESSURE_FEATURE_INDEX: + { + callback_data.conn_id = conn_id; + cause = pfn_bls_cb(service_id, (void *)&callback_data); + + *pp_value = (uint8_t *)&bls_blood_pressure_feature; + *p_length = sizeof(bls_blood_pressure_feature); + } + break; + } + return (cause); +} + +void bls_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_BLS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool handle = true; + PROFILE_PRINT_INFO2("bls_cccd_update_cb: index %d ccc_bits 0x%04x", index, ccc_bits); + + switch (index) + { + case BLS_BLOOD_PRESSURE_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + callback_data.msg_data.notification_indification_index = + BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = + BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_DISABLE; + } + break; + } +#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT + case BLS_INTERMEDIATE_CUFF_PRESSURE_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = + BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = + BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_DISABLE; + } + break; + } +#endif + default: + { + handle = false; + break; + } + + } + + if (pfn_bls_cb && (handle == true)) + { + pfn_bls_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief BLS Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS bls_cbs = +{ + bls_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + bls_cccd_update_cb // CCCD update callback function pointer +}; + +T_SERVER_ID bls_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)bls_attr_tbl, + bls_attr_tbl_size, + bls_cbs)) + { + PROFILE_PRINT_ERROR1("bls_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_bls_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} diff --git a/src/ble/profile/server/cscs.c b/src/ble/profile/server/cscs.c new file mode 100644 index 0000000..f72392c --- /dev/null +++ b/src/ble/profile/server/cscs.c @@ -0,0 +1,956 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file cscs.c +* @brief CSC profile interfaces called in profile.c. +* @details Interfaces to get and put csc characteristics value and csc control point procedure. +* @author ethan_su +* @date 2017-10-11 +* @version v1.0 +********************************************************************************************************* +*/ +#include "trace.h" +#include +#include "gatt.h" +#include "cscs.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +typedef struct +{ + uint8_t csc_measurement_notify_enable: 1; + uint8_t sc_cp_indicate_enable: 1; + uint8_t rfu: 6; +} CSCS_NOTIFY_INDICATE_FLAG; + +/** @brief CSC service related UUIDs. */ +#define GATT_UUID_CSCS 0x1816 +#define GATT_UUID_CHAR_CSCS_MEASUREMENT 0x2A5B +#define GATT_UUID_CHAR_CSCS_FEATURE 0x2A5C +#define GATT_UUID_CHAR_SENSOR_LOCATION 0x2A5D +#define GATT_UUID_CHAR_SC_CONTROL_POINT 0x2A55 + + +/**< CSC measurement data. */ +static T_CSCS_MEASUREMENT cscs_measurement; +/**< CSC feature that CSC service supported, can be configured by user. */ +static uint16_t cscs_feature; +/**< CSC current sensor location, where the CSC sensor located. */ +static uint8_t cscs_cur_sens_location; +/**< CSC supported sensor location list, can be configured by user. */ +static uint16_t cscs_sens_loc_list; +/**< CSC control point data. */ +static T_CSCS_CONTROL_POINT cscs_control_point = {0}; +/**< CSC control point indication enable flag. */ +static CSCS_NOTIFY_INDICATE_FLAG cscs_notify_indicate_flag = {0}; +/**< Function pointer used to send event to application from CSC profile. Initiated in cscs_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_cscs_cb = NULL; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL cscs_attr_tbl[] = +{ + /*-------------------------- CSC Service ---------------------------*/ + /* <>, .. Index 0 */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_CSCS), /* service UUID */ + HI_WORD(GATT_UUID_CSCS) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. Index 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- CSC Measurement characteristic value --- Index 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CSCS_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_CSCS_MEASUREMENT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration Index 3 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /* <>, .. Index 4 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- CSC Features characteristic value --- Index 5 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CSCS_FEATURE), + HI_WORD(GATT_UUID_CHAR_CSCS_FEATURE), + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } + +#ifdef CSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT + , + /* <>, .. Index 6 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- CSC sensor location characteristic value --- Index 7 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SENSOR_LOCATION), + HI_WORD(GATT_UUID_CHAR_SENSOR_LOCATION) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + } +#endif + +#ifdef CSCS_SC_CONTROL_POINT_SUPPORT + , + /* <>, .. Index 8 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- CSC SC Control Point value --- Index 9 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + /* client characteristic configuration Index 10 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif + +}; +/**< @brief CSC service size definition. */ +const int32_t cscs_attr_tbl_size = sizeof(cscs_attr_tbl); + +/** + * @brief Set a cycling speed and cadence service parameter. + * + * NOTE: You can call this function with a cycling speed and cadence service parameter type and it will set the + * cycling speed and cadence service parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Cycling speed and cadence service parameter type: @ref T_CSCS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + cscs_set_parameter(CSCS_PARAM_CTL_PNT_PROG_CLR, 0, NULL); + } + * \endcode + */ +bool cscs_set_parameter(T_CSCS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + uint8_t inc_flag = cscs_measurement.value[0]; + + switch (param_type) + { + default: + ret = false; + break; + case CSCS_PARAM_CSCS_FEATURE: + memcpy(&cscs_feature, p_value, 2); + break; + + case CSCS_PARAM_INC_FLAG: + cscs_measurement.value[0] = *(uint8_t *)p_value; + inc_flag = cscs_measurement.value[0]; + cscs_measurement.cur_length = 1; + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + cscs_measurement.cur_length += 6; + } + if (inc_flag & CSCS_INC_CRANK_REVOL_MASK) + { + cscs_measurement.cur_length += 4; + } + break; + case CSCS_PARAM_WHEEL_REVOL: + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_UINT32_TO_ARRAY(cscs_measurement.value + 1, *(uint32_t *)p_value); + } + else + { + ret = false; + } + break; + case CSCS_PARAM_WHEEL_EVT_TIME: + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_UINT16_TO_ARRAY(cscs_measurement.value + 5, *(uint16_t *)p_value); + } + else + { + ret = false; + } + break; + case CSCS_PARAM_CRANK_REVOL: + if (inc_flag & CSCS_INC_CRANK_REVOL_MASK) + { + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_UINT16_TO_ARRAY(cscs_measurement.value + 7, *(uint16_t *)p_value); + } + else + { + LE_UINT16_TO_ARRAY(cscs_measurement.value + 1, *(uint16_t *)p_value); + } + } + else + { + ret = false; + } + break; + case CSCS_PARAM_CRANK_EVT_TIME: + if (inc_flag & CSCS_INC_CRANK_REVOL_MASK) + { + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_UINT16_TO_ARRAY(cscs_measurement.value + 9, *(uint16_t *)p_value); + } + else + { + LE_UINT16_TO_ARRAY(cscs_measurement.value + 3, *(uint16_t *)p_value); + } + } + else + { + ret = false; + } + break; + case CSCS_PARAM_SENSOR_LOC: + cscs_cur_sens_location = *(uint8_t *)p_value; + break; + case CSCS_PARAM_CTL_PNT_PROG_CLR: + cscs_control_point.value[0] = CSCS_CP_OPCODE_RESERVED; + break; + } + + if (!ret) + { + PROFILE_PRINT_INFO0("CSC parameter set failed\n"); + } + + return ret; +} + +/** + * @brief Get a cycling speed and cadence parameter. + * + * NOTE: You can call this function with a cycling speed and cadence parameter type and it will get a + * gulcose parameter. Cycling speed and cadence service parameters are defined in @ref T_CSCS_PARAM_TYPE. + * + * @param[in] param_type Cycling speed and cadence parameter type: @ref T_CSCS_PARAM_TYPE + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + int record_num; + gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num); + } + * \endcode + */ +bool cscs_get_parameter(T_CSCS_PARAM_TYPE param_type, void *p_value) +{ + bool ret = true; + uint8_t inc_flag = cscs_measurement.value[0]; + + switch (param_type) + { + default: + ret = false; + break; + case CSCS_PARAM_INC_FLAG: + *(uint8_t *)p_value = cscs_measurement.value[0]; + break; + case CSCS_PARAM_WHEEL_REVOL: + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 1); + } + else + { + ret = false; + } + break; + case CSCS_PARAM_WHEEL_EVT_TIME: + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 5); + } + else + { + ret = false; + } + break; + case CSCS_PARAM_CRANK_REVOL: + if (inc_flag & CSCS_INC_CRANK_REVOL_MASK) + { + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 7); + } + else + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 1); + } + } + else + { + ret = false; + } + break; + case CSCS_PARAM_CRANK_EVT_TIME: + if (inc_flag & CSCS_INC_CRANK_REVOL_MASK) + { + if (inc_flag & CSCS_INC_WHEEL_REVOL_MASK) + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 9); + } + else + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, cscs_measurement.value + 3); + } + } + else + { + ret = false; + } + break; + case CSCS_PARAM_SENSOR_LOC: + *(uint8_t *)p_value = cscs_cur_sens_location; + break; + } + + if (!ret) + { + PROFILE_PRINT_INFO0("cscs parameter get failed\n"); + } + + return ret; +} + +/** + * @brief display control point response. + * + * @param cscs_ctl_pnt_ptr pointer to CSC control point data. + * @return none + * @retval void +*/ +static void cscs_ctl_pnt_display_rsp(T_CSCS_CONTROL_POINT *cscs_ctl_pnt_ptr) +{ + PROFILE_PRINT_INFO1("cscs cp response: req_op_code=0x%x", cscs_ctl_pnt_ptr->value[1]); + PROFILE_PRINT_INFO1("rsp_code=0x%x", cscs_ctl_pnt_ptr->value[2]); +} + +/** + * @brief whether the sensor location supported. + * + * @param[in] sens_location sensor location to be judged(CSC sensor support or not). + * @return support result. + * @retval 1 support + * @retval 0 not support +*/ +static bool cscs_sens_loc_supported(uint8_t sens_location) +{ + uint8_t result = false; + if ((cscs_sens_loc_list >> sens_location) & 0x0001) + { + result = true; + } + + return (result); +} + +/** + * @brief set cumulative response. + * + * @param[in] conn_id Connection id. + * @param[in] serviceID + * @return none + * @retval void +*/ +static void cscs_ctl_pnt_set_cumulative(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = CSCS_CP_OPCODE_SET_CUMULATIVE; + cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + +/** + * @brief update sensor location response. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] rsp_code Response Code. + * @return none + * @retval void +*/ +static void cscs_ctl_pnt_update_sens_loc(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = CSCS_CP_OPCODE_UPDATE_SENS_LOC; + cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + +/** + * @brief supported sensor location response. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] rsp_code Response Code. + * @return none + * @retval void +*/ +static void cscs_ctl_pnt_req_sens_loc_list(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code) +{ + uint8_t op_code = CSCS_CP_OPCODE_REQ_SENS_LOC_LIST; + cscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + +static uint8_t cscs_hanlde_ctl_pnt_proc2(uint8_t service_id, uint16_t write_length, + uint8_t *p_value) +{ + T_CSCS_CALLBACK_DATA callback_data; + uint8_t resp_code = CSCS_CP_RSPCODE_SUCCESS; + uint16_t parameter_length = 0; + memcpy(cscs_control_point.value, p_value, write_length); + if (write_length >= 1) + { + parameter_length = write_length - 1; + } + + PROFILE_PRINT_INFO1("cscs_hanlde_ctl_pnt_proc2 request: op_code=0x%x", cscs_control_point.value[0]); + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = cscs_control_point.value[0]; + + switch (cscs_control_point.value[0]) + { + + case CSCS_CP_OPCODE_SET_CUMULATIVE: + { + if (parameter_length == 4) + { + memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_value, + &cscs_control_point.value[1], 4); + } + else + { + resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + + break; + + case CSCS_CP_OPCODE_UPDATE_SENS_LOC: + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.sensor_location_value, + &cscs_control_point.value[1], 1); + if (callback_data.msg_data.write.cp_parameter.sensor_location_value >= CSCS_SENSOR_LOC_MAX) + { + resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case CSCS_CP_OPCODE_REQ_SENS_LOC_LIST: + { + if (parameter_length == 0) + { + } + else + { + resp_code = CSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + default: + { + resp_code = CSCS_CP_RSPCODE_OPCODE_UNSUPPORT; + } + break; + } + + if (resp_code == CSCS_CP_RSPCODE_SUCCESS) + { + pfn_cscs_cb(service_id, (void *)&callback_data); + } + return resp_code; +} + + +/** + * @brief handle control point write (request). + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] write_length Write request data length. + * @param[in] value_ptr Pointer to write request data. + * @return none + * @retval void +*/ +static void cscs_ctl_pnt_handle_req(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t write_length, uint8_t *p_value) +{ + uint8_t resp_code = CSCS_CP_RSPCODE_SUCCESS; + + memcpy(cscs_control_point.value, p_value, write_length); + cscs_control_point.cur_length = write_length; + + PROFILE_PRINT_INFO1("csccp request: op_code=0x%x", cscs_control_point.value[0]); + + resp_code = cscs_hanlde_ctl_pnt_proc2(service_id, write_length, p_value); + + if (resp_code == CSCS_CP_RSPCODE_SUCCESS) + { + switch (cscs_control_point.value[0]) + { + default: + resp_code = CSCS_CP_RSPCODE_OPCODE_UNSUPPORT; + break; + case CSCS_CP_OPCODE_SET_CUMULATIVE: + if ((cscs_feature & CSCS_SUPPORT_WHEEL_REVOL_MASK) && + (cscs_measurement.value[0] & CSCS_INC_WHEEL_REVOL_MASK)) + { + cscs_ctl_pnt_set_cumulative(conn_id, service_id, resp_code); + return; + } + break; + case CSCS_CP_OPCODE_UPDATE_SENS_LOC: + if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK) + { + cscs_ctl_pnt_update_sens_loc(conn_id, service_id, resp_code); + return; + } + break; + case CSCS_CP_OPCODE_REQ_SENS_LOC_LIST: + if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK) + { + cscs_ctl_pnt_req_sens_loc_list(conn_id, service_id, resp_code); + return; + } + break; + } + } + + /* Send indication to client when request opcode not supported. */ + cscs_ctl_pnt_indicate(conn_id, service_id, cscs_control_point.value[0], resp_code); +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT cscs_attr_read(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("cscs_attr_read, attr not found, index=%d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + case GATT_SVC_CSCS_FEATURE_INDEX: + { + T_CSCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = CSCS_READ_CSCS_FEATURE; + pfn_cscs_cb(service_id, &callback_data); + + *pp_value = (uint8_t *)&cscs_feature; + *p_length = sizeof(cscs_feature); + } + break; + case GATT_SVC_CSCS_SENS_LOC_INDEX: + if (cscs_feature & CSCS_SUPPORT_MULTI_SENSOR_MASK) + { + T_CSCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = CSCS_READ_SENSOR_LOCATION; + pfn_cscs_cb(service_id, &callback_data); + *pp_value = (uint8_t *)&cscs_cur_sens_location; + *p_length = sizeof(cscs_cur_sens_location); + } + else + { + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return (cause); +} + + + + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] length length of value to be written. + * @param[in] p_value value to be written. + * @param[in] p_write_ind_post_proc pointer of a function to handle control point write. + * @return Profile procedure result +*/ +T_APP_RESULT cscs_attr_write(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + if (GATT_SVC_CSCS_CTL_PNT_INDEX == attrib_index) + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > CSCS_MAX_CTL_PNT_VALUE) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + /* Make sure Control Point is not "Process already in progress". */ + else if (CSCS_CTL_PNT_OPERATE_ACTIVE(cscs_control_point.value[0])) + { + cause = (T_APP_RESULT)0x80;//ProfileResult_AppErr_ProcAlreadyInProgress + } + /* Make sure Control Point is configured indication enable. */ + else if (false == cscs_notify_indicate_flag.sc_cp_indicate_enable) + { + cause = (T_APP_RESULT)0x81;//ProfileResult_AppErr_CccdImproperlyConfigured + } + else + { + /* handle SCCP request after sending write response */ + *p_write_ind_post_proc = cscs_ctl_pnt_handle_req; + } + } + else + { + PROFILE_PRINT_ERROR2("cscs_attr_write Error attrib_index = 0x%x length=%d", attrib_index, length); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + return cause; +} + +/** + * @brief Send measurement value notification data . + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + uint8_t conn_id = p_parse_value->dw_param[0]; + cscs_set_parameter(CSCS_PARAM_WHEEL_REVOL, sizeof(cscs_cul_value), &cscs_cul_value); + op_result = cscs_meas_value_notify(conn_id, cscs_id); + } + * \endcode + */ +bool cscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + uint16_t attrib_index = GATT_SVC_CSCS_MEASUREMENT_INDEX; + uint8_t *p_data = cscs_measurement.value; + uint16_t dataLen = cscs_measurement.cur_length; + + PROFILE_PRINT_INFO0("cscs measurement notification"); + return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen, + GATT_PDU_TYPE_NOTIFICATION); +} + +/** + * @brief Send control point indication. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] op_code Op code. + * @param[in] rsp_code Response code. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + */ +bool cscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code, + uint8_t rsp_code) +{ + uint16_t attrib_index = GATT_SVC_CSCS_CTL_PNT_INDEX; + uint8_t sens_location; + uint8_t param_offset; + uint8_t *p_data; + uint16_t data_len; + + cscs_control_point.value[1] = cscs_control_point.value[0]; /* Control Point request opcode. */ + cscs_control_point.value[2] = rsp_code; + cscs_control_point.value[0] = CSCS_CP_OPCODE_RSP_CODE; + cscs_control_point.cur_length = 3 * sizeof(uint8_t); + + /* Diff RspType, different indication contents. */ + if (op_code == CSCS_CP_OPCODE_REQ_SENS_LOC_LIST) + { + /* get sensor location list */ + for (sens_location = CSCS_SENSOR_LOC_OTHER, param_offset = 3; sens_location < CSCS_SENSOR_LOC_MAX; + sens_location++) + { + if (cscs_sens_loc_supported(sens_location)) + { + cscs_control_point.value[param_offset] = sens_location; + param_offset++; + } + } + cscs_control_point.cur_length = param_offset; + } + + cscs_ctl_pnt_display_rsp(&cscs_control_point); + p_data = cscs_control_point.value; + data_len = cscs_control_point.cur_length; + + // send indication to client + return server_send_data(conn_id, service_id, attrib_index, p_data, data_len, + GATT_PDU_TYPE_INDICATION); +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void cscs_cccd_update(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_CSCS_CALLBACK_DATA callback_data; + bool handle = false; + PROFILE_PRINT_INFO2("cscs_cccd_update index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SVC_CSCS_MEAS_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE; + cscs_notify_indicate_flag.csc_measurement_notify_enable = true; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE; + cscs_notify_indicate_flag.csc_measurement_notify_enable = false; + } + handle = true; + break; + case GATT_SVC_CSCS_CTL_PNT_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_SC_CP_ENABLE; + cscs_notify_indicate_flag.sc_cp_indicate_enable = true; + + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = CSCS_NOTIFY_INDICATE_SC_CP_DISABLE; + cscs_notify_indicate_flag.sc_cp_indicate_enable = false; + } + handle = true; + break; + default: + break; + } + /* Notify Application. */ + if (pfn_cscs_cb && (handle == true)) + { + pfn_cscs_cb(service_id, (void *)&callback_data); + } +} + +/** + * @brief CSC Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS cscs_cbs = +{ + cscs_attr_read, // Read callback function pointer + cscs_attr_write, // Write callback function pointer + cscs_cccd_update // CCCD update callback function pointer +}; + +/** + * @brief Add cycling speed and cadence service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + cscs_id = cscs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID cscs_add_service(void *p_func) +{ + T_SERVER_ID service_id; + + /* Initiate CSC service related data, modify according to user's demand. */ + cscs_feature = CSCS_ALL_FEATURE_SUPPORTED; + cscs_measurement.value[0] = CSCS_INC_ALL_PRESENTS; + cscs_measurement.cur_length = CSCS_MAX_MEASUREMENT_VALUE; + cscs_sens_loc_list = CSCS_ALL_SENS_LOC_SUPPORTED; + cscs_cur_sens_location = CSCS_SENSOR_LOC_REAL_WHEEL; + + /* register CSC service to profile layer. */ + if (false == server_add_service(&service_id, + (uint8_t *)cscs_attr_tbl, + cscs_attr_tbl_size, + cscs_cbs)) + { + PROFILE_PRINT_ERROR1("cscs_add_service: serviceId %d", service_id); + service_id = 0xff; + return service_id; + } + + /* register callback for profile to inform application that some events happened. */ + pfn_cscs_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + + diff --git a/src/ble/profile/server/dfu_service.c b/src/ble/profile/server/dfu_service.c new file mode 100644 index 0000000..412b501 --- /dev/null +++ b/src/ble/profile/server/dfu_service.c @@ -0,0 +1,1174 @@ +#include +#include "gatt.h" +#include "gap_conn_le.h" +#include "patch_header_check.h" +#include "rtl876x_wdg.h" +#include "flash_device.h" +#include "dfu_flash.h" +#include "dfu_api.h" +#include "dfu_service.h" +#include "otp.h" +#include "trace.h" +#include "board.h" +#include "otp_config.h" +#if (AON_WDG_ENABLE == 1) +#include "rtl876x_aon_wdg.h" +#endif + +/*============================================================================* + * Macros + *============================================================================*/ + +//#define CAL_OFFSET(type, member) ((size_t)(&((type *)0)->member)) + +/*============================================================================* + * External Variables + *============================================================================*/ +T_DFU_PARA g_dfu_para; +uint8_t *p_ota_temp_buffer_head; +uint16_t g_ota_tmp_buf_used_size; +uint8_t temp_image_num = 0; +T_TEMP_IMAGE_INFO temp_image_info[IMAGE_MAX - SecureBoot]; + + +/*============================================================================* + * Local Variables + *============================================================================*/ +uint8_t ota_temp_buffer_head[DFU_TEMP_BUFFER_SIZE]; +static bool buffer_check_en = false; +bool is_ota_procedure = false; +static uint32_t dfu_resend_offset = 0; +static T_SERVER_ID dfu_service_id; + +P_FUN_SERVER_GENERAL_CB pfn_dfu_service_cb = NULL; + +const uint8_t SILENCE_GATT_UUID128_DFU_SERVICE[16] = {GATT_UUID128_DFU_SERVICE}; + +T_ATTRIB_APPL gatt_dfu_service_table[] = +{ + + /*-------------------------- DFU Service ---------------------------*/ + /* <>, .. */ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* flags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* type_value */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)SILENCE_GATT_UUID128_DFU_SERVICE, /* p_value_context */ + GATT_PERM_READ /* permissions */ + }, + + + + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP/* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /*--- DFU packet characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_DFU_DATA + }, + 0, /* bValueLen */ + NULL, +#if DFU_SERVER_REQUIRE_AUTH + GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */ +#else + GATT_PERM_WRITE /* permissions */ +#endif + }, + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_NOTIFY) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /*--- DFU Control Point value ---*/ + { + ATTRIB_FLAG_VALUE_APPL | ATTRIB_FLAG_UUID_128BIT, /* flags */ + { /* type_value */ + GATT_UUID128_DFU_CONTROL_POINT + }, + 0, /* bValueLen */ + NULL, +#if DFU_SERVER_REQUIRE_AUTH + GATT_PERM_WRITE_AUTHEN_MITM_REQ /* permissions */ +#else + GATT_PERM_WRITE /* permissions */ +#endif + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if DFU_SERVER_REQUIRE_AUTH + (GATT_PERM_READ | GATT_PERM_WRITE_AUTHEN_MITM_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + } + +}; + + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief dfu_buffer_check_process + * + * @param buffer_check_size size for buffer check. + * @param buffer_crc calced buffer crc value. + * @return None +*/ +void dfu_buffer_check_process(uint8_t conn_id, uint16_t buffer_check_size, uint16_t buffer_crc) +{ + uint8_t notif_data[DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC] = {0}; + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_REPORT_BUFFER_CRC; + + T_DFU_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE; + + if (buffer_check_size > DFU_TEMP_BUFFER_SIZE) + { + //invalid para + DFU_PRINT_ERROR3("<==dfu_buffer_check_process: invalid buffer_check_size=%d(>%d), cur_offset=%d", + buffer_check_size, DFU_TEMP_BUFFER_SIZE, g_dfu_para.cur_offset); + g_ota_tmp_buf_used_size = 0; + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + + if (g_ota_tmp_buf_used_size == buffer_check_size || + g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length) + { + if (dfu_check_buf_crc(p_ota_temp_buffer_head, g_ota_tmp_buf_used_size, buffer_crc)) + { + //crc error + DFU_PRINT_ERROR1("<==dfu_buffer_check_process: Buf CRC Error! cur_offset=%d", + g_dfu_para.cur_offset); + g_ota_tmp_buf_used_size = 0; + notif_data[2] = DFU_ARV_FAIL_CRC_ERROR; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + + else //crc ok + { + //1. devrypt data + if (OTP->ota_with_encryption_data) + { + dfu_hw_aes_decrypt_image(p_ota_temp_buffer_head, p_ota_temp_buffer_head, g_ota_tmp_buf_used_size); + } + //2. write flash + uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id, + g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset, + g_ota_tmp_buf_used_size, (uint32_t *)p_ota_temp_buffer_head, false); + + if (result == 0) + { + uint32_t updated_success_len = g_ota_tmp_buf_used_size; + callback_data.msg_data.write.opcode = DFU_WRITE_DOING; + callback_data.msg_data.write.length = 4; + callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len; + if (pfn_dfu_service_cb) + { + T_APP_RESULT w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + g_dfu_para.cur_offset += g_ota_tmp_buf_used_size; + + if ((g_dfu_para.cur_offset - dfu_resend_offset) >= FMC_SEC_SECTION_LEN) + { + dfu_resend_offset += FMC_SEC_SECTION_LEN; + } + g_ota_tmp_buf_used_size = 0; + DFU_PRINT_INFO2("<==dfu_buffer_check_process: dfu_update Success! cur_offset=%d, dfu_resend_offset=%d", + g_dfu_para.cur_offset, dfu_resend_offset); + notif_data[2] = DFU_ARV_SUCCESS; //valid + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + else + { + DFU_PRINT_ERROR1("<==dfu_buffer_check_process: dfu_update Fail result=%d", result); + + result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, dfu_resend_offset); + if (result) + { + //erase fail + g_ota_tmp_buf_used_size = 0; + g_dfu_para.cur_offset = dfu_resend_offset; + DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d", + g_dfu_para.cur_offset); + + notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + + if ((g_dfu_para.cur_offset - dfu_resend_offset) > FMC_SEC_SECTION_LEN) //need erase two sector + { + DFU_PRINT_INFO0("<==dfu_buffer_check_process:Need erase two sectors"); + result = dfu_flash_erase_sector_with_retry(g_dfu_para.ctrl_header.image_id, + dfu_resend_offset + FMC_SEC_SECTION_LEN); + if (result) + { + //erase fail + g_ota_tmp_buf_used_size = 0; + g_dfu_para.cur_offset = dfu_resend_offset; + DFU_PRINT_ERROR1("<==dfu_buffer_check_process: erase flash fail 3 times! cur_offset=%d", + g_dfu_para.cur_offset); + + notif_data[2] = DFU_ARV_FAIL_ERASE_ERROR; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + + } + //erase ok + g_ota_tmp_buf_used_size = 0; + g_dfu_para.cur_offset = dfu_resend_offset; + DFU_PRINT_INFO1("<==dfu_buffer_check_process: erase ok! cur_offset=%d", g_dfu_para.cur_offset); + notif_data[2] = DFU_ARV_FAIL_PROG_ERROR; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } + } + } + else + { + DFU_PRINT_ERROR4("<==dfu_buffer_check_process: Error buffer_check_size=%d,buf_used_size=%d,cur_offset=%d,image_total_length=%d", + buffer_check_size, g_ota_tmp_buf_used_size, + g_dfu_para.cur_offset, g_dfu_para.image_total_length); + //flush buffer. + g_ota_tmp_buf_used_size = 0; + notif_data[2] = DFU_ARV_FAIL_LENGTH_ERROR; + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_BUFFER_CRC, GATT_PDU_TYPE_NOTIFICATION); + return; + } +} + +void dfu_notify_conn_para_update_req(uint8_t conn_id, T_DFU_ARV_ERROR_CODE error_code) +{ + if (g_dfu_para.dfu_conn_para_update_in_progress == true) + { + g_dfu_para.dfu_conn_para_update_in_progress = false; + uint8_t notif_data[3] = {0}; + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ; + notif_data[2] = error_code; + + DFU_PRINT_INFO1("<==dfu_notify_conn_para_update_req error_code=0x%x", error_code); + /* Connection Param Update rejected, we should notify the fail result to remote device. */ + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_CONN_PARA_UPDATE_REQ, GATT_PDU_TYPE_NOTIFICATION); + } +} + +void dfu_service_handle_valid_fw(uint8_t conn_id) +{ + uint8_t notif_data[DFU_NOTIFY_LENGTH_VALID_FW] = {0}; + bool check_result = false; + bool is_enable_bank_switch = is_ota_support_bank_switch(); + + if (is_enable_bank_switch) + { + check_result = dfu_check_checksum(g_dfu_para.ctrl_header.image_id, 0); + } + else + { + check_result = dfu_check_checksum(temp_image_info[temp_image_num].image_id, + temp_image_info[temp_image_num].image_offset); + } + DFU_PRINT_INFO1("dfu_service_handle_valid_fw: check_result=%d (1: Success, 0: Fail)", check_result); + + if (check_result) + { + if (!is_enable_bank_switch) + { + temp_image_num ++; + DFU_PRINT_INFO1("DFU_OPCODE_VALID_FW: temp_image_num=%d ", temp_image_num); + } + + notif_data[2] = DFU_ARV_SUCCESS; + } + else + { + notif_data[2] = DFU_ARV_FAIL_CRC_ERROR; + } + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_VALID_FW; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_VALID_FW, GATT_PDU_TYPE_NOTIFICATION); +} + + +void dfu_service_handle_active_image(void) +{ + if (!is_ota_support_bank_switch()) + { + uint32_t base_addr = 0; + T_IMG_CTRL_HEADER_FORMAT *p_header = NULL; + if (IMAGE_USER_DATA == g_dfu_para.ctrl_header.image_id) + { + /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */ + base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE; + } + else + { + /* check OTA temp or running bank to see if received image is OK.*/ + base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id); + } + + for (uint8_t i = 0; i < temp_image_num; i++) + { + p_header = (T_IMG_CTRL_HEADER_FORMAT *)(base_addr + temp_image_info[i].image_offset); + dfu_set_image_ready(p_header); + } + } + +} + +/** + * @brief dfu_service_handle_control_point_req + * + * @param length control point cmd length. + * @param p_value control point cmd address.. + * @return None +*/ +void dfu_service_handle_control_point_req(uint8_t conn_id, uint16_t length, + uint8_t *p_value) +{ + T_APP_RESULT w_cause = APP_RESULT_SUCCESS; + T_DFU_CTRL_POINT dfu_control_point; + uint8_t *p = p_value + 1; + uint8_t notif_data[DFU_NOTIFY_LENGTH_MAX] = {0}; + + T_DFU_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_attrib_index = INDEX_DFU_CONTROL_POINT_CHAR_VALUE; + + dfu_control_point.opcode = *p_value; + DFU_PRINT_TRACE2("==>dfu_service_handle_control_point_req: opcode=0x%x, length=%d", + dfu_control_point.opcode, length); + + if (dfu_control_point.opcode >= DFU_OPCODE_MAX || dfu_control_point.opcode <= DFU_OPCODE_MIN) + { + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = dfu_control_point.opcode; + notif_data[2] = 0xff; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION); + return; + } + + switch (dfu_control_point.opcode) + { + case DFU_OPCODE_START_DFU: //0x01 + if (length == DFU_LENGTH_START_DFU)/*4 bytes is padding for encrypt*/ + { + if (OTP->ota_with_encryption_data) + { + DFU_PRINT_INFO1("ctrl header before decryped=%b", TRACE_BINARY(16, p)); + dfu_hw_aes_decrypt_image(p, p, 16); + DFU_PRINT_INFO1("ctrl header after decryped=%b", TRACE_BINARY(16, p)); + } + + dfu_control_point.start_dfu.ic_type = (*p); + p += 1; + dfu_control_point.start_dfu.secure_version = (*p); + p += 1; + LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.ctrl_flag.value, p); + p += 2; + LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.image_id, p); + p += 2; + LE_ARRAY_TO_UINT16(dfu_control_point.start_dfu.crc16, p); + p += 2; + LE_ARRAY_TO_UINT32(dfu_control_point.start_dfu.payload_len, p); + + DFU_PRINT_INFO6("DFU_OPCODE_START_DFU: ic_type=0x%x, secure_version=0x%x, ctrl_flag.value=0x%x, image_id=0x%x,crc16=0x%x, payload_len=%d", + dfu_control_point.start_dfu.ic_type, + dfu_control_point.start_dfu.secure_version, + dfu_control_point.start_dfu.ctrl_flag.value, + dfu_control_point.start_dfu.image_id, + dfu_control_point.start_dfu.crc16, + dfu_control_point.start_dfu.payload_len + ); + g_dfu_para.ctrl_header.ic_type = dfu_control_point.start_dfu.ic_type; + g_dfu_para.ctrl_header.ctrl_flag.value = dfu_control_point.start_dfu.ctrl_flag.value; + g_dfu_para.ctrl_header.image_id = dfu_control_point.start_dfu.image_id; + g_dfu_para.ctrl_header.crc16 = dfu_control_point.start_dfu.crc16; + g_dfu_para.ctrl_header.payload_len = dfu_control_point.start_dfu.payload_len; + g_dfu_para.image_total_length = g_dfu_para.ctrl_header.payload_len + IMG_HEADER_SIZE; + + /*check if start dfu fileds are vaild*/ + if (g_dfu_para.ctrl_header.ic_type == DEFINED_IC_TYPE) + { + if (((g_dfu_para.ctrl_header.image_id >= OTA) && (g_dfu_para.ctrl_header.image_id < IMAGE_MAX)) + || (g_dfu_para.ctrl_header.image_id == IMAGE_USER_DATA)) + { + is_ota_procedure = true; + + /*disable bank switch, need record temp image info*/ + if (!is_ota_support_bank_switch()) + { + temp_image_info[temp_image_num].image_id = (T_IMG_ID)g_dfu_para.ctrl_header.image_id; +// temp_image_info[temp_image_num].image_size = UP_ALIGN(g_dfu_para.image_total_length, FMC_SEC_SECTION_LEN); + temp_image_info[temp_image_num].image_size = g_dfu_para.image_total_length; + if (temp_image_num == 0) + { + temp_image_info[temp_image_num].image_offset = 0; + } + else + { + temp_image_info[temp_image_num].image_offset = temp_image_info[temp_image_num - 1].image_offset + + temp_image_info[temp_image_num - 1].image_size; + } + } + DFU_PRINT_INFO4("DFU_OPCODE_START_DFU: image_num=%d, image_id=0x%x, image_size=0x%x, image_offset=0x%x", + temp_image_num, temp_image_info[temp_image_num].image_id, + temp_image_info[temp_image_num].image_size, temp_image_info[temp_image_num].image_offset); + + callback_data.msg_data.write.opcode = DFU_WRITE_START; + callback_data.msg_data.write.length = DFU_HEADER_SIZE; + callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id, + 0 + temp_image_info[temp_image_num].image_offset, DFU_HEADER_SIZE, + (uint32_t *)&g_dfu_para.ctrl_header, true); + if (result) + { + DBG_DIRECT("DFU_OPCODE_START_DFU: dfu_update fail=%d", result); + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + else + { + g_dfu_para.cur_offset += DFU_HEADER_SIZE; + DFU_PRINT_INFO0("DFU_OPCODE_START_DFU: start success!"); + + uint32_t updated_success_len = DFU_HEADER_SIZE; + callback_data.msg_data.write.opcode = DFU_WRITE_DOING; + callback_data.msg_data.write.length = 4; + callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_START_DFU; + notif_data[2] = DFU_ARV_SUCCESS; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION); + } + + + } + else + { + DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: image id=0x%x Error!", g_dfu_para.ctrl_header.image_id); + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_START_DFU; + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION); + return; + } + } + else + { + DFU_PRINT_ERROR1("DFU_OPCODE_START_DFU: ic type=0x%x Error!", g_dfu_para.ctrl_header.ic_type); + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_START_DFU; + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_START_DFU, GATT_PDU_TYPE_NOTIFICATION); + return; + } + } + break; + + case DFU_OPCODE_RECEIVE_FW_IMAGE_INFO://0x02 + if (length == DFU_LENGTH_RECEIVE_FW_IMAGE_INFO) + { + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p); + p += 2; + LE_ARRAY_TO_UINT32(g_dfu_para.cur_offset, p); + if ((g_dfu_para.cur_offset == 0) || (g_dfu_para.cur_offset == DFU_HEADER_SIZE)) + { + g_ota_tmp_buf_used_size = 0; + dfu_resend_offset = 0; + } + DFU_PRINT_INFO3("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: image_id=0x%x, cur_offset=%d, g_ota_tmp_buf_used_size=%d", + g_dfu_para.ctrl_header.image_id, g_dfu_para.cur_offset, g_ota_tmp_buf_used_size); + } + else + { + DFU_PRINT_ERROR1("DFU_OPCODE_RECEIVE_FW_IMAGE_INFO: length=%d Error!", length); + } + break; + + case DFU_OPCODE_VALID_FW://0x03 + + if (length == DFU_LENGTH_VALID_FW) + { + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p); + DFU_PRINT_TRACE1("DFU_OPCODE_VALID_FW: image_id=0x%x", g_dfu_para.ctrl_header.image_id); + + /*if ota large img, need modify wdg timeout period*/ + if (OTP->wdgEnableInRom && g_dfu_para.image_total_length > 0x100000) + { + /*1M and less---4s, 2M and less---8s,..., 8M and less---32s*/ + uint32_t img_align_len = ((g_dfu_para.image_total_length + (0x100000 - 1)) & (~(0x100000 - 1))); + uint8_t wdg_period_4s = (img_align_len / 0x100000); + uint16_t div_factor = (32 * wdg_period_4s - 1); + DFU_PRINT_TRACE2("DFU_OPCODE_VALID_FW: Change WDG Period to %ds, div_factor=%d", wdg_period_4s << 2, + div_factor); + WDG_Config(div_factor, 15, RESET_ALL); //31 - 4s, 63 - 8s + } + /*It is not recommended to do things that take a long time in upperstack task cb. + So dfu service cb need send msg to app task to handle checksum image if support silent ota. + While app task must handle IO_MSG_TYPE_DFU_VALID_FW by calling dfu_service_handle_valid_fw. + */ +#if (AON_WDG_ENABLE == 1) + bool aon_wdg_en = AON_WDG_IsEnable(); + if (aon_wdg_en) + { + aon_wdg_disable(); + } +#endif + } + else + { + DFU_PRINT_ERROR1("DFU_OPCODE_VALID_FW: length=%d Error!", length); + } + break; + + case DFU_OPCODE_ACTIVE_IMAGE_RESET://0x04 + { + /*when disable bank switch, need set image ready*/ + dfu_service_handle_active_image(); + + /*notify bootloader to reset and use new image*/ + DFU_PRINT_INFO0("DFU_OPCODE_ACTIVE_IMAGE_RESET"); + callback_data.msg_data.write.opcode = DFU_WRITE_END; + callback_data.msg_data.write.length = DFU_HEADER_SIZE; + callback_data.msg_data.write.p_value = (uint8_t *)&g_dfu_para.ctrl_header; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + if (!is_ota_support_bank_switch()) + { + /*note: must unlock flash bp for ota copy before reset when not support bank switch*/ + unlock_flash_bp_all(); + } + } + break; + + case DFU_OPCODE_SYSTEM_RESET://0x05 + { + /*whatever cause ota fail, clinet will send this cmd to reset device*/ + DBG_DIRECT("DFU_OPCODE_SYSTEM_RESET"); + + /*if select not active image by Phone even if image transport successful. Not for single bank user data*/ + if (g_dfu_para.ctrl_header.image_id >= OTA && g_dfu_para.ctrl_header.image_id < IMAGE_MAX) + { + + uint32_t temp_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)g_dfu_para.ctrl_header.image_id); + + T_IMG_CTRL_HEADER_FORMAT *p_temp_header = (T_IMG_CTRL_HEADER_FORMAT *)temp_addr; + if (p_temp_header && !p_temp_header->ctrl_flag.flag_value.not_ready) + { + flash_erase_locked(FLASH_ERASE_SECTOR, temp_addr); + } + } + + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_SYSTEM_RESET_CMD; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + break; + + case DFU_OPCODE_REPORT_TARGET_INFO://0x06 + if (length == DFU_LENGTH_REPORT_TARGET_INFO) + { + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p); + dfu_report_target_fw_info(g_dfu_para.ctrl_header.image_id, &g_dfu_para.origin_image_version, + (uint32_t *)&g_dfu_para.cur_offset); + g_dfu_para.cur_offset = 0; + DFU_PRINT_INFO3("DFU_OPCODE_REPORT_TARGET_INFO: image_id=0x%x,origin_image_ver=0x%x, cur_offset=%d", + g_dfu_para.ctrl_header.image_id, g_dfu_para.origin_image_version, g_dfu_para.cur_offset); + + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_REPORT_TARGET_INFO; + notif_data[2] = DFU_ARV_SUCCESS; + + LE_UINT32_TO_ARRAY(¬if_data[3], g_dfu_para.origin_image_version); + LE_UINT32_TO_ARRAY(¬if_data[7], g_dfu_para.cur_offset); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_REPORT_TARGET_INFO, GATT_PDU_TYPE_NOTIFICATION); + } + else + { + DFU_PRINT_ERROR1("DFU_OPCODE_REPORT_TARGET_INFO: length=%d Error!", length); + } + break; + + case DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ://0x07 + { + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ; + + if (length == DFU_LENGTH_CONN_PARA_TO_UPDATE_REQ) + { + if (g_dfu_para.dfu_conn_para_update_in_progress) + { + DFU_PRINT_ERROR0("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: OTA ConnParaUpdInProgress!"); + notif_data[2] = DFU_ARV_FAIL_OPERATION; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION); + } + else + { + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t conn_latency; + uint16_t superv_tout; + + LE_ARRAY_TO_UINT16(conn_interval_min, p_value + 1); + LE_ARRAY_TO_UINT16(conn_interval_max, p_value + 3); + LE_ARRAY_TO_UINT16(conn_latency, p_value + 5); + LE_ARRAY_TO_UINT16(superv_tout, p_value + 7); + + if (le_update_conn_param(0, conn_interval_min, conn_interval_max, conn_latency, + superv_tout, conn_interval_min * 2 - 2, conn_interval_max * 2 - 2) == GAP_CAUSE_SUCCESS) + { + /* Connection Parameter Update Request sent successfully, means this procedure is in progress. */ + g_dfu_para.dfu_conn_para_update_in_progress = true; + DFU_PRINT_INFO4("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: conn_min=0x%x, conn_max=0x%x, latcy=0x%x, timeout=0x%x", + conn_interval_min, conn_interval_max, conn_latency, superv_tout); + } + else + { + notif_data[2] = DFU_ARV_FAIL_OPERATION; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION); + } + } + } + else + { + /*TODO: to be masked.*/ + DFU_PRINT_ERROR1("DFU_OPCODE_CONN_PARA_TO_UPDATE_REQ: length=%d Error!", length); + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION); + } + } + break; + + case DFU_OPCODE_BUFFER_CHECK_EN: //0x09 + { + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &g_dfu_para.mtu_size, conn_id); + DFU_PRINT_TRACE2("DFU_OPCODE_BUFFER_CHECK_EN: mtu_size=%d, max_bufffer_size=%d", + g_dfu_para.mtu_size, + DFU_TEMP_BUFFER_SIZE); + + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_BUFFER_CHECK_EN; +#if (DFU_BUFFER_CHECK_ENABLE == 1) + buffer_check_en = true; + notif_data[2] = DFU_ARV_SUCCESS; +#else + buffer_check_en = false; + notif_data[2] = DFU_ARV_FAIL_OPERATION; +#endif + LE_UINT16_TO_ARRAY(¬if_data[3], DFU_TEMP_BUFFER_SIZE); + LE_UINT8_TO_ARRAY(¬if_data[5], g_dfu_para.mtu_size); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_BUFFER_CHECK_EN, GATT_PDU_TYPE_NOTIFICATION); + } + break; + + case DFU_OPCODE_REPORT_BUFFER_CRC: //0x0a + { + uint16_t mBufSize; + uint16_t mCrcVal; + LE_ARRAY_TO_UINT16(mBufSize, p); + p += 2; + LE_ARRAY_TO_UINT16(mCrcVal, p); + DFU_PRINT_INFO2("DFU_OPCODE_REPORT_BUFFER_CRC: mBufSize=0x%x, mCrcVal=0x%x", mBufSize, mCrcVal); + dfu_buffer_check_process(conn_id, mBufSize, mCrcVal); + } + break; + + case DFU_OPCODE_RECEIVE_IC_TYPE://0x0b + { + uint8_t ic_type = 0; //0 means invalid ic type + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_RECEIVE_IC_TYPE; + if (dfu_report_target_ic_type(OTA, &ic_type)) + { + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + notif_data[3] = ic_type; + } + else + { + notif_data[2] = DFU_ARV_SUCCESS; + notif_data[3] = ic_type; + } + DFU_PRINT_INFO1("DFU_OPCODE_RECEIVE_IC_TYPE: ic_type=0x%x", ic_type); + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_RECEIVE_IC_TYPE, GATT_PDU_TYPE_NOTIFICATION); + } + break; + +#if (ENABLE_BANK_SWITCH_COPY_APP_DATA == 1) + case DFU_OPCODE_COPY_IMG://0x0c + { + uint32_t dlAddress, dlSize; + LE_ARRAY_TO_UINT16(g_dfu_para.ctrl_header.image_id, p); + p += 2; + LE_ARRAY_TO_UINT32(dlAddress, p); + p += 4; + LE_ARRAY_TO_UINT32(dlSize, p); + DFU_PRINT_TRACE2("DFU_OPCODE_COPY_IMG: dlAddress=0x%x,dlSize=0x%x", dlAddress, + dlSize); + + notif_data[0] = DFU_OPCODE_NOTIFICATION; + notif_data[1] = DFU_OPCODE_COPY_IMG; + + if (dfu_copy_img(g_dfu_para.ctrl_header.image_id, dlAddress, dlSize)) + { + notif_data[2] = DFU_ARV_SUCCESS; + } + else + { + notif_data[2] = DFU_ARV_FAIL_INVALID_PARAMETER; + } + server_send_data(conn_id, dfu_service_id, INDEX_DFU_CONTROL_POINT_CHAR_VALUE, \ + notif_data, DFU_NOTIFY_LENGTH_ARV, GATT_PDU_TYPE_NOTIFICATION); + } + break; +#endif //end ENABLE_BANK_SWITCH_COPY_APP_DATA + + default: + { + DFU_PRINT_TRACE1("dfu_service_handle_control_point_req: Unknown Opcode=0x%x", + dfu_control_point.opcode); + } + break; + } +} + + +/** + * @brief dfu_service_handle_packet_req + * + * @param length data reviewed length. + * @param p_value data receive point address. + * @return None +*/ +void dfu_service_handle_packet_req(uint8_t conn_id, uint16_t length, uint8_t *p_value) +{ + T_APP_RESULT w_cause = APP_RESULT_SUCCESS; + T_DFU_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_attrib_index = INDEX_DFU_PACKET_VALUE; + callback_data.msg_data.write.length = length; + callback_data.msg_data.write.p_value = p_value; + + DFU_PRINT_INFO4("dfu_service_handle_packet_req: length=%d, cur_offset=%d, g_ota_tmp_buf_used_size=%d, image_total_length=%d", + length, g_dfu_para.cur_offset, + g_ota_tmp_buf_used_size, g_dfu_para.image_total_length); + + /*if haven't started dfu, send data directly, do nothing*/ + if (!is_ota_procedure) + { + return; + } + + if (buffer_check_en == true) + { + /*to avoid memory overflow*/ + if (g_ota_tmp_buf_used_size + length > DFU_TEMP_BUFFER_SIZE) + { + DFU_PRINT_ERROR3("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d", + g_ota_tmp_buf_used_size, length, DFU_TEMP_BUFFER_SIZE); + + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + else + { + memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length); + g_ota_tmp_buf_used_size += length; + } + } + else + { + /*when disable buffer check, Default client send 20bytes per packet*/ + uint32_t max_buffer_size = DFU_TEMP_BUFFER_SIZE - (DFU_TEMP_BUFFER_SIZE % 20); + /*0.check memcpy buffer boundary*/ + if (g_ota_tmp_buf_used_size + length > max_buffer_size) + { + DBG_DIRECT("<==dfu_service_handle_packet_req: Buf overflow! ota_tmp_buf_used_size=%d,length=%d, max_buffer_size=%d", + g_ota_tmp_buf_used_size, length, max_buffer_size); + + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_MAX_BUFFER_SIZE; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + + /*0.check total length*/ + if (g_dfu_para.cur_offset + g_ota_tmp_buf_used_size + length > g_dfu_para.image_total_length) + { + DFU_PRINT_ERROR1("<==dfu_service_handle_packet_req: received data total length beyond image_total_length(%d bytes)", + g_dfu_para.image_total_length); + + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_EXCEED_IMG_TOTAL_LEN; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + + /*start handle received data*/ + //1. deceypt data + if (OTP->ota_with_encryption_data) + { + dfu_hw_aes_decrypt_image(p_value, p_value, length); + } + + //2. copy received data to buffer + memcpy(p_ota_temp_buffer_head + g_ota_tmp_buf_used_size, p_value, length); + g_ota_tmp_buf_used_size += length; + + //3. write to flash + if (g_ota_tmp_buf_used_size == max_buffer_size || + g_dfu_para.cur_offset + g_ota_tmp_buf_used_size == g_dfu_para.image_total_length) + { + uint32_t result = dfu_update(g_dfu_para.ctrl_header.image_id, + g_dfu_para.cur_offset + temp_image_info[temp_image_num].image_offset, + g_ota_tmp_buf_used_size, + (uint32_t *)p_ota_temp_buffer_head, false); + if (result) + { + DBG_DIRECT("Buffer check disable: dfu_update fail=%d", result); + + /*eflash write fail, we should restart ota procedure.*/ + T_DFU_FAIL_REASON dfu_fail_reason = DFU_FAIL_UPDATE_FLASH; + callback_data.msg_data.write.opcode = DFU_WRITE_FAIL; + callback_data.msg_data.write.length = sizeof(T_DFU_FAIL_REASON); + callback_data.msg_data.write.p_value = (uint8_t *)&dfu_fail_reason; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + dfu_fw_reboot(false); + } + else + { + uint32_t updated_success_len = g_ota_tmp_buf_used_size; + callback_data.msg_data.write.opcode = DFU_WRITE_DOING; + callback_data.msg_data.write.length = 4; + callback_data.msg_data.write.p_value = (uint8_t *)&updated_success_len; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(dfu_service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + /*update varibals value*/ + g_dfu_para.cur_offset += g_ota_tmp_buf_used_size; + g_ota_tmp_buf_used_size = 0; + } + } + } + +} + +/** + * @brief write characteristic data from service. + * + * @param ServiceID ServiceID to be written. + * @param iAttribIndex Attribute index of characteristic. + * @param wLength length of value to be written. + * @param pValue value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT dfu_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT w_cause = APP_RESULT_SUCCESS; + T_DFU_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_attrib_index = attrib_index; + callback_data.msg_data.write.length = length; + callback_data.msg_data.write.p_value = p_value; + + /* Notify Application. */ + callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_ENTER; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return w_cause; + } + } + + if (attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE) + { + dfu_service_handle_control_point_req(conn_id, length, p_value); + } + else if (attrib_index == INDEX_DFU_PACKET_VALUE) + { + dfu_service_handle_packet_req(conn_id, length, p_value); + } + else + { + DFU_PRINT_INFO1("dfu_attr_write_cb fail! attrib_index=%d", attrib_index); + w_cause = APP_RESULT_ATTR_NOT_FOUND; + } + + /* Notify Application. */ + callback_data.msg_data.write.opcode = DFU_WRITE_ATTR_EXIT; + if (pfn_dfu_service_cb) + { + w_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data); + if (w_cause != APP_RESULT_SUCCESS) + { + return w_cause; + } + } + + return w_cause; +} + +/** + * @brief update CCCD bits from stack. + * + * @param ServiceId Service ID. + * @param Index Attribute index of characteristic data. + * @param wCCCBits CCCD bits from stack. + * @return None +*/ +void dfu_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_DFU_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool b_handle = true; + DFU_PRINT_INFO2("dfu_cccd_update_cb: index=%d, ccc_bits=0x%x", index, ccc_bits); + switch (index) + { + case INDEX_DFU_CHAR_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = DFU_NOTIFY_ENABLE; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = DFU_NOTIFY_DISABLE; + } + break; + } + default: + { + b_handle = false; + break; + } + + } + /* Notify Application. */ + if (pfn_dfu_service_cb && (b_handle == true)) + { + T_APP_RESULT update_cause = pfn_dfu_service_cb(service_id, (void *)&callback_data); + if (update_cause != APP_RESULT_SUCCESS) + { + return; + } + } + + return; +} + +/** + * @brief OTA ble Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS DfuServiceCBs = +{ + NULL, // Read callback function pointer + dfu_attr_write_cb, // Write callback function pointer + dfu_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief add OTA ble service to application. + * + * @param pFunc pointer of app callback function called by profile. + * @return service ID auto generated by profile layer. + * @retval ServiceId +*/ +uint8_t dfu_add_service(void *pFunc) +{ + if (false == server_add_service(&dfu_service_id, + (uint8_t *)gatt_dfu_service_table, + sizeof(gatt_dfu_service_table), + DfuServiceCBs)) + { + DFU_PRINT_ERROR1("dfu_add_service: service_id=%d", dfu_service_id); + dfu_service_id = 0xff; + return dfu_service_id; + } + pfn_dfu_service_cb = (P_FUN_SERVER_GENERAL_CB)pFunc; + p_ota_temp_buffer_head = ota_temp_buffer_head; + + return dfu_service_id; +} + + diff --git a/src/ble/profile/server/dis.c b/src/ble/profile/server/dis.c new file mode 100644 index 0000000..069e68c --- /dev/null +++ b/src/ble/profile/server/dis.c @@ -0,0 +1,707 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file dis.c +* @brief Device Information service source file. +* @details Interfaces to access Device Information service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "dis.h" +#include "dis_config.h" +#include "fmna_version.h" // 添加fmna_version.h头文件 + +/*============================================================================* + * Macros + *============================================================================*/ +/** @brief IEEE 11073 authoritative body values. */ +#define DIS_IEEE_11073_BODY_EMPTY 0 +#define DIS_IEEE_11073_BODY_IEEE 1 +#define DIS_IEEE_11073_BODY_CONTINUA 2 +#define DIS_IEEE_11073_BODY_EXP 254 + +/** @brief DIS related UUIDs */ +#define GATT_UUID_DEVICE_INFORMATION_SERVICE 0x180A + +#define GATT_UUID_CHAR_SYSTEM_ID 0x2A23 +#define GATT_UUID_CHAR_MODEL_NUMBER 0x2A24 +#define GATT_UUID_CHAR_SERIAL_NUMBER 0x2A25 +#define GATT_UUID_CHAR_FIRMWARE_REVISION 0x2A26 +#define GATT_UUID_CHAR_HARDWARE_REVISION 0x2A27 +#define GATT_UUID_CHAR_SOFTWARE_REVISION 0x2A28 +#define GATT_UUID_CHAR_MANUFACTURER_NAME 0x2A29 +#define GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST 0x2A2A +#define GATT_UUID_CHAR_PNP_ID 0x2A50 + +/*============================================================================* + * Local Variables + *============================================================================*/ +static P_FUN_SERVER_GENERAL_CB pfn_dis_cb = NULL; + + +#if DIS_CHAR_SYSTEM_ID_SUPPORT +/**< DIS service System ID. */ +//static uint8_t dis_system_id[DIS_SYSTEM_ID_LENGTH] = {0, 1, 2, 0, 0, 3, 4, 5}; + +static uint8_t dis_system_id[DIS_SYSTEM_ID_LENGTH] = "0x16"; +static uint8_t dis_system_id_len = 4; + +#endif + + +#if DIS_CHAR_PNP_ID_SUPPORT +/**< DIS service PnP ID. */ +static uint8_t dis_pnp_id[DIS_PNP_ID_LENGTH] = +{ + 1, // Vendor ID source (1=Bluetooth SIG) + LO_WORD(0x005D), HI_WORD(0x005D), // Vendor ID (Realtek Semiconductor Corporation) + LO_WORD(0x0000), HI_WORD(0x0000), // Product ID (vendor-specific) + LO_WORD(0x0100), HI_WORD(0x0100) // Product version (vendor-assigned-JJ.M.N) +}; +#endif + +#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT +/**< DIS service Manufacturer Name. A null-terminated byte is reserved*/ +static uint8_t dis_manufacturer_name[DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH] = "SWISSDIGITAL DESIGN"; +static uint8_t dis_manufacturer_name_len = 19; +#endif + +#if DIS_CHAR_MODEL_NUMBER_SUPPORT +/**< DIS service Model Number. A null-terminated byte is reserved*/ +static uint8_t dis_model_number[DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH] = {FW_VERSION_MAJOR_NUMBER, FW_VERSION_MINOR_NUMBER, FW_VERSION_REVISION_NUMBER}; // 使用统一的版本号定义 +static uint8_t dis_model_number_len = 3; +#endif + +#if DIS_CHAR_SERIAL_NUMBER_SUPPORT +/**< DIS service Serial Number. A null-terminated byte is reserved*/ +static uint8_t dis_serial_number[DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH] = "SD02524H00000001"; +static uint8_t dis_serial_number_len = 16; +#endif + +#if DIS_CHAR_HARDWARE_REVISION_SUPPORT +/**< DIS service Hardware Revision. A null-terminated byte is reserved*/ +static uint8_t dis_hardware_rev[DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH] = {FW_VERSION_MAJOR_NUMBER, FW_VERSION_MINOR_NUMBER, FW_VERSION_REVISION_NUMBER}; // 使用统一的版本号定义 +static uint8_t dis_hardware_rev_len = 3; +#endif + +#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT +/**< DIS service Firmware Revision. A null-terminated byte is reserved*/ +static uint8_t dis_firmware_rev[DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH] = {FW_VERSION_MAJOR_NUMBER, FW_VERSION_MINOR_NUMBER, FW_VERSION_REVISION_NUMBER}; // 使用统一的版本号定义 +static uint8_t dis_firmware_rev_len = 3; // 修改为正确的长度3 +#endif + +#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT +/**< DIS service Software Revision. A null-terminated byte is reserved*/ +static uint8_t dis_software_rev[DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH] = {FW_VERSION_MAJOR_NUMBER, FW_VERSION_MINOR_NUMBER, FW_VERSION_REVISION_NUMBER}; // 使用统一的版本号定义 +static uint8_t dis_software_rev_len = 3; +#endif + +#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT +/**< DIS service IEEE 11073-20601 Regulatory Certification Data List. */ +static uint8_t dis_ieee_data_list[DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH] = +{ + DIS_IEEE_11073_BODY_EXP, // Authoritative body type + 0x00, // Authoritative body structure type + // Authoritative body data follows below: + 'e', 'x', 'p', 'e', 'r', 'i', 'm', 'e', 'n', 't', 'a', 'l' +}; +static uint8_t dis_ieee_data_list_len = 14; +#endif + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL dis_attr_tbl[] = +{ + /*----------------- Device Information Service -------------------*/ + /* <> */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_DEVICE_INFORMATION_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_DEVICE_INFORMATION_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* p_value_context */ + GATT_PERM_READ /* permissions */ + } + +#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Manufacturer Name String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_MANUFACTURER_NAME), + HI_WORD(GATT_UUID_CHAR_MANUFACTURER_NAME) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_MODEL_NUMBER_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Model Number characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_MODEL_NUMBER), + HI_WORD(GATT_UUID_CHAR_MODEL_NUMBER) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_SERIAL_NUMBER_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Serial Number String String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SERIAL_NUMBER), + HI_WORD(GATT_UUID_CHAR_SERIAL_NUMBER) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_HARDWARE_REVISION_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Manufacturer Name String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_HARDWARE_REVISION), + HI_WORD(GATT_UUID_CHAR_HARDWARE_REVISION) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Firmware revision String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_FIRMWARE_REVISION), + HI_WORD(GATT_UUID_CHAR_FIRMWARE_REVISION) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Manufacturer Name String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SOFTWARE_REVISION), + HI_WORD(GATT_UUID_CHAR_SOFTWARE_REVISION) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_SYSTEM_ID_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* System ID String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SYSTEM_ID), + HI_WORD(GATT_UUID_CHAR_SYSTEM_ID) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT + , + + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Manufacturer Name String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST), + HI_WORD(GATT_UUID_CHAR_IEEE_CERTIF_DATA_LIST) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif + +#if DIS_CHAR_PNP_ID_SUPPORT + , + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + /* Manufacturer Name String characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_PNP_ID), + HI_WORD(GATT_UUID_CHAR_PNP_ID) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + } +#endif +}; +/**< @brief DIS service size definition. */ +const uint16_t dis_attr_tbl_size = sizeof(dis_attr_tbl); + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief Set a device information service parameter. + * + * NOTE: You can call this function with a device information service parameter type and it will set the + * device information service parameter. Device information service parameters are defined in @ref T_DIS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Device information service parameter type: @ref T_DIS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + const uint8_t dis_manufacture_name[] = "Realtek BT"; + dis_set_parameter(DIS_PARAM_MANUFACTURER_NAME, + sizeof(dis_manufacture_name), + (void *)dis_manufacture_name); + } + * \endcode + */ +bool dis_set_parameter(T_DIS_PARAM_TYPE param_type, uint8_t length, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + ret = false; + break; + +#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT + case DIS_PARAM_MANUFACTURER_NAME: + if (length > DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH) + { + length = DIS_CHAR_MANUFACTURER_NAME_STR_MAX_LENGTH; + } + dis_manufacturer_name_len = length; + memcpy(dis_manufacturer_name, p_value, length); + break; +#endif + +#if DIS_CHAR_MODEL_NUMBER_SUPPORT + case DIS_PARAM_MODEL_NUMBER: + if (length > DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH) + { + length = DIS_CHAR_MODEL_NUMBER_STR_MAX_LENGTH; + } + dis_model_number_len = length; + memcpy(dis_model_number, p_value, length); + break; +#endif + +#if DIS_CHAR_SERIAL_NUMBER_SUPPORT + case DIS_PARAM_SERIAL_NUMBER: + if (length > DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH) + { + length = DIS_CHAR_SERIAL_NUMBER_STR_MAX_LENGTH; + } + dis_serial_number_len = length; + memcpy(dis_serial_number, p_value, length); + + break; +#endif + +#if DIS_CHAR_HARDWARE_REVISION_SUPPORT + case DIS_PARAM_HARDWARE_REVISION: + if (length > DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH) + { + length = DIS_CHAR_HARDWARE_REVISION_STR_MAX_LENGTH; + } + dis_hardware_rev_len = length; + memcpy(dis_hardware_rev, p_value, length); + break; +#endif + +#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT + case DIS_PARAM_FIRMWARE_REVISION: + if (length > DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH) + { + length = DIS_CHAR_FIRMWARE_REVISION_STR_MAX_LENGTH; + } + dis_firmware_rev_len = length; + memcpy(dis_firmware_rev, p_value, length); + break; +#endif + +#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT + case DIS_PARAM_SOFTWARE_REVISION: + if (length > DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH) + { + length = DIS_CHAR_SOFTWARE_REVISION_STR_MAX_LENGTH; + } + dis_software_rev_len = length; + memcpy(dis_software_rev, p_value, length); + break; +#endif + +#if DIS_CHAR_SYSTEM_ID_SUPPORT + case DIS_PARAM_SYSTEM_ID: + if (length > DIS_SYSTEM_ID_LENGTH) + { + length = DIS_SYSTEM_ID_LENGTH; + } + dis_system_id_len = length; + memcpy(dis_system_id, p_value, length); + break; +#endif + +#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT + case DIS_PARAM_IEEE_DATA_LIST: + if (length > DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH) + { + length = DIS_CHAR_IEEE_CERTIF_DATA_LIST_MAX_LENGTH; + } + dis_ieee_data_list_len = length; + memcpy(dis_ieee_data_list, p_value, length); + break; +#endif + +#if DIS_CHAR_PNP_ID_SUPPORT + case DIS_PARAM_PNP_ID: + if (length > DIS_PNP_ID_LENGTH) + { + length = DIS_PNP_ID_LENGTH; + } + dis_ieee_data_list_len = length; + memcpy(dis_pnp_id, p_value, length); + break; +#endif + } + + if (!ret) + { + PROFILE_PRINT_ERROR0("dis_set_parameter: parameter set failed"); + } + + return ret; +} + +/** + * @brief Read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be read. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset offset of characteritic to be read. + * @param[in,out] length_ptr length of getting characteristic data. + * @param[in,out] pp_value pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT dis_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *length_ptr, uint8_t **pp_value) +{ + T_DIS_CALLBACK_DATA callback_data; + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *length_ptr = 0; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("dis_attr_read_cb: attrib_index %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + +#if DIS_CHAR_SYSTEM_ID_SUPPORT + case GATT_SVC_DIS_SYSTEM_ID_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_SYSTEM_ID_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_system_id; +// *length_ptr = sizeof(dis_system_id); + *length_ptr = dis_system_id_len; + break; +#endif + +#if DIS_CHAR_MANUFACTURER_NAME_SUPPORT + case GATT_SVC_DIS_MANU_NAME_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_MANU_NAME_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_manufacturer_name; + *length_ptr = dis_manufacturer_name_len; + break; +#endif + +#if DIS_CHAR_SERIAL_NUMBER_SUPPORT + case GATT_SVC_DIS_SERIAL_NUM_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_SERIAL_NUM_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_serial_number; + *length_ptr = dis_serial_number_len; + break; +#endif + +#if DIS_CHAR_FIRMWARE_REVISION_SUPPORT + case GATT_SVC_DIS_FIRMWARE_REV_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_FIRMWARE_REV_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_firmware_rev; + *length_ptr = dis_firmware_rev_len; + break; +#endif + +#if DIS_CHAR_HARDWARE_REVISION_SUPPORT + case GATT_SVC_DIS_HARDWARE_REV_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_HARDWARE_REV_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_hardware_rev; + *length_ptr = dis_hardware_rev_len; + break; +#endif + +#if DIS_CHAR_SOFTWARE_REVISION_SUPPORT + case GATT_SVC_DIS_SOFTWARE_REV_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_SOFTWARE_REV_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_software_rev; + *length_ptr = dis_software_rev_len; + break; +#endif + +#if DIS_CHAR_IEEE_CERTIF_DATA_LIST_SUPPORT + case GATT_SVC_DIS_IEEE_CERT_STR_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_IEEE_CERT_STR_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_ieee_data_list; + *length_ptr = dis_ieee_data_list_len; + break; +#endif + +#if DIS_CHAR_PNP_ID_SUPPORT + case GATT_SVC_DIS_PNP_ID_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_PNP_ID_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_pnp_id; + *length_ptr = sizeof(dis_pnp_id); + break; +#endif + +#if DIS_CHAR_MODEL_NUMBER_SUPPORT + case GATT_SVC_DIS_MODEL_NUM_INDEX: + callback_data.msg_data.read_value_index = DIS_READ_MODEL_NUM_INDEX; + pfn_dis_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&dis_model_number; + *length_ptr = dis_model_number_len; + break; +#endif + + } + + PROFILE_PRINT_INFO2("dis_attr_read_cb: attrib_index %d, *length_ptr %d", + attrib_index, + *length_ptr); + return (cause); +} + +const T_FUN_GATT_SERVICE_CBS dis_cbs = +{ + dis_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + NULL // Authorization callback function pointer +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief Add device information service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + dis_id = dis_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID dis_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)dis_attr_tbl, + dis_attr_tbl_size, + dis_cbs)) + { + PROFILE_PRINT_ERROR1("dis_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_dis_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/ftms.c b/src/ble/profile/server/ftms.c new file mode 100644 index 0000000..6d60341 --- /dev/null +++ b/src/ble/profile/server/ftms.c @@ -0,0 +1,7076 @@ +/**************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + + * @file ftms.c + * @brief fitness machine service source file. + * @details Interface to access the fitness machine service. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +#include "trace.h" +#include +#include "gatt.h" +#include "srv_uuid.h" +#include "gap_conn_le.h" +#include "os_mem.h" +#include "bt_types.h" +#include "ftms.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT +#define FTMS_TM_DATA_FLAG_LEN 2 +#define FTMS_TM_TOTAL_DISTANCE_LEN 3 +#define FTMS_TM_INCLINATION_RAMP_ANGLE_LEN 4 +#define FTMS_TM_ELEVATION_GAIN_LEN 4 +#define FTMS_TM_EXPENDED_ENERGY_LEN 5 +#define FTMS_TM_BELT_FORCE_POWER_OUTPUT_LEN 4 +#define FTMS_TM_INSTANTANEOUS_SPEED_LEN 2 +#endif +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT +#define FTMS_STEPC_DATA_FLAG_LEN 2 +#define FTMS_STEPC_FLOOR_STEP_COUNT_LEN 4 +#define FTMS_STEPC_EXPENDED_ENERGY_LEN 5 +#endif +#if FTMS_CHAR_ROWER_DATA_SUPPORT +#define FTMS_RW_DATA_FLAG_LEN 2 +#define FTMS_RW_STROKE_RATE_COUNT_LEN 3 +#define FTMS_RW_TOTAL_DISTANCE_LEN 3 +#define FTMS_RW_EXPENDED_ENERGY_LEN 5 +#endif +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT +#define FTMS_IB_DATA_FLAG_LEN 2 +#define FTMS_IB_TOTAL_DISTANCE_LEN 3 +#define FTMS_IB_EXPENDED_ENERGY_LEN 5 +#define FTMS_IB_INSTANTANEOUS_SPEED_LEN 2 +#endif +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT +#define FTMS_CT_DATA_FLAG_LEN 3 +#define FTMS_CT_TOTAL_DISTANCE_LEN 3 +#define FTMS_CT_STEP_PER_MINUTE_STEP_RATE_LEN 4 +#define FTMS_CT_ELEVATION_GAIN_LEN 4 +#define FTMS_CT_INCLINATION_RAMP_ANGLE_LEN 4 +#define FTMS_CT_EXPENDED_ENERGY_LEN 5 +#define FTMS_CT_INSTANTANEOUS_SPEED_LEN 2 +#endif +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT +#define FTMS_STAIRC_DATA_FLAG_LEN 2 +#define FTMS_STAIRC_EXPENDED_ENERGY_LEN 5 +#define FTMS_STAIRC_FLOORS_LEN 2 +#endif + +#define FTMS_MAX_CTL_PNT_PARAM_LEN 18 + +typedef struct +{ + uint16_t cur_flag; + uint16_t send_flag; + uint16_t data_len; + uint16_t offset; + uint8_t no_more_data; + uint32_t ct_cur_flag; + uint32_t ct_send_flag; +} T_FTMS_NOTIFY_FLAG; + +typedef enum +{ + FTMS_STATUS_START_RESUME = 0x01, + FTMS_STATUS_STOP_PAUSE, +} T_FTMS_STATUS; + +typedef struct +{ + uint8_t cur_length; + uint8_t param[FTMS_MAX_CTL_PNT_PARAM_LEN]; +} T_FTMS_CONTROL_POINT; + +typedef struct +{ + uint16_t ftms_treadmill_data_notify_enable: 1; + uint16_t ftms_step_climber_data_notify_enable: 1; + uint16_t ftms_rower_data_notify_enable: 1; + uint16_t ftms_indoor_bike_data_notify_enable: 1; + uint16_t ftms_cp_indicate_enable: 1; + uint16_t ftms_status_notify_enable: 1; + uint16_t ftms_train_status_notify_enable: 1; + uint16_t ftms_cross_trainer_data_notify_enable: 1; + uint16_t ftms_stair_climber_data_notify_enable: 1; + uint16_t rfu: 7; +} T_FTMS_NOTIFY_INDICATE_FLAG; + +typedef struct +{ + T_FTMS_FEATURE ftms_feature; +#if FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT + T_FTMS_SUPPORT_SPEED_RANGE support_speed_range; +#endif +#if FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT + T_FTMS_SUPPORT_INCLINATION_RANGE support_inclination_range; +#endif +#if FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT + T_FTMS_SUPPORT_RESISTANCE_LEVEL_RANGE support_resistance_level_range; +#endif +#if FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT + T_FTMS_SUPPORT_POWER_RANGE support_power_range; +#endif +#if FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT + T_FTMS_SUPPORT_HR_RANGE support_heart_rate_range; +#endif +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + T_FTMS_CONTROL_POINT ftms_control_point; + bool control_permission; + uint8_t ftms_cur_status; + uint8_t ftms_cp_indication_status_flag; +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + T_FTMS_SPIN_DOWN_RESP_PARAM ftms_sd_rsp_param; +#endif +#endif + T_FTMS_NOTIFY_INDICATE_FLAG ftms_notify_indicate_flag; +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + uint16_t treadmill_data_flag; + uint8_t *ftms_treadmill_notify_data; + uint8_t *ftms_treadmill_send_data; + T_FTMS_NOTIFY_FLAG ftms_treadmill_notify_flag; +#endif +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + uint16_t step_climber_data_flag; + uint8_t *ftms_step_climber_notify_data; + uint8_t *ftms_step_climber_send_data; + T_FTMS_NOTIFY_FLAG ftms_step_climber_notify_flag; +#endif +#if FTMS_CHAR_ROWER_DATA_SUPPORT + uint16_t rower_data_flag; + uint8_t *ftms_rower_notify_data; + uint8_t *ftms_rower_send_data; + T_FTMS_NOTIFY_FLAG ftms_rower_notify_flag; +#endif +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT + uint16_t indoor_bike_data_flag; + uint8_t *ftms_indoor_bike_notify_data; + uint8_t *ftms_indoor_bike_send_data; + T_FTMS_NOTIFY_FLAG ftms_indoor_bike_notify_flag; +#endif +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + uint32_t cross_trainer_data_flag; + uint8_t *ftms_cross_trainer_notify_data; + uint8_t *ftms_cross_trainer_send_data; + T_FTMS_NOTIFY_FLAG ftms_cross_trainer_notify_flag; +#endif +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + uint16_t stair_climber_data_flag; + uint8_t *ftms_stair_climber_notify_data; + uint8_t *ftms_stair_climber_send_data; + T_FTMS_NOTIFY_FLAG ftms_stair_climber_notify_flag; +#endif + T_SRV_CHAR_TBL *ftms_srv_char_tbl; +} T_FTMS_PARAM; + +static T_FTMS_PARAM ftms_var; +P_FUN_SERVER_GENERAL_CB pfn_ftms_cb; + +/** @brief profile/service definition. */ +const T_ATTRIB_APPL ftms_att_tbl[] = +{ + /* <>, ..0 */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_FITNESS_MACHINE), /* service UUID */ + HI_WORD(GATT_UUID_FITNESS_MACHINE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. Fitness Machine Feature*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + + (GATT_CHAR_PROP_READ) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*---Fitness Machine Feature characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_FITNESS_MACHINE_FEATURE), + HI_WORD(GATT_UUID_FITNESS_MACHINE_FEATURE) + }, + 0, /* bValueLen */ + NULL, + (GATT_PERM_READ) /* wPermissions */ + }, +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + /* <>, .. Treadmill Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Treadmill Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_TREADMILL_DATA), + HI_WORD(GATT_UUID_TREADMILL_DATA) + }, + 0, /* variable size */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + /* <>, .. Step Climber Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Step Climber Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_STEP_CLIMBER_DATA), + HI_WORD(GATT_UUID_STEP_CLIMBER_DATA), + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_ROWER_DATA_SUPPORT + /* <>, .. Rower Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Rower Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_ROWER_DATA), + HI_WORD(GATT_UUID_ROWER_DATA) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if GATT_UUID_INDOOR_BIKE_DATA + /* <>, .. Indoor Bike Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Indoor Bike Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_INDOOR_BIKE_DATA), + HI_WORD(GATT_UUID_INDOOR_BIKE_DATA) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + /* <>, .. Cross Trainer Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Cross Trainer Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CROSS_TRAINER_DATA), + HI_WORD(GATT_UUID_CROSS_TRAINER_DATA) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + /* <>, .. Stair Climber Data*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Stair Climber Data characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_STAIR_CLIMBER_DATA), + HI_WORD(GATT_UUID_STAIR_CLIMBER_DATA) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT + /* <>, .. Training Status */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_READ | /* characteristic properties */ + GATT_CHAR_PROP_NOTIFY) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Training Status characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_TRAINING_STATUS), + HI_WORD(GATT_UUID_TRAINING_STATUS) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + (GATT_PERM_READ | GATT_PERM_NOTIF_IND) /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT + /* <>, .. Supported Speed Range*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Supported Speed Range characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_SUPPORT_SPEED_RANGE), + HI_WORD(GATT_UUID_SUPPORT_SPEED_RANGE) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +#if FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT + /* <>, .. Supported Inclination Range*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Supported Inclination Range characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_SUPPORT_INCLINATION_RANGE), + HI_WORD(GATT_UUID_SUPPORT_INCLINATION_RANGE) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +#if FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT + /* <>, .. Supported Resistance level Range*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Supported Resistance level Range characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_SUPPORT_RESISTANCE_LEVEL_RANGE), + HI_WORD(GATT_UUID_SUPPORT_RESISTANCE_LEVEL_RANGE) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +#if FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT + /* <>, .. Supported Heart Rate Range*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Supported Heart Rate Range characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_SUPPORT_HEART_RATE_RANGE), + HI_WORD(GATT_UUID_SUPPORT_HEART_RATE_RANGE) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +#if FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT + /* <>, .. Supported Power Range*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Supported Power Range characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_SUPPORT_POWER_RANGE), + HI_WORD(GATT_UUID_SUPPORT_POWER_RANGE) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + /* <>, .. Fitness Machine Control Point*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Fitness Machine Control Point characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_FTMS_CONTROL_POINT), + HI_WORD(GATT_UUID_FTMS_CONTROL_POINT) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + (GATT_PERM_WRITE_ENCRYPTED_REQ | /* wPermissions */ + GATT_PERM_NOTIF_IND_ENCRYPTED_REQ) + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +#if (FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT || FTMS_CHAR_FTMS_STATUS_SUPPORT) + /* <>, .. Fitness Machine Status*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Fitness Machine Status characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_FITNESS_MACHINE_STATUS), + HI_WORD(GATT_UUID_FITNESS_MACHINE_STATUS) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_NOTIF_IND /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif +}; + +const static uint16_t ftms_attr_tbl_size = sizeof(ftms_att_tbl); + +bool ftms_set_parameter(T_FTMS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + PROFILE_PRINT_INFO1("ftms_set_parameter: param_type 0x%x", param_type); + + switch (param_type) + { + case FTMS_PARAM_FTMS_FEATURE: + { + memcpy(&ftms_var.ftms_feature, p_value, len); + } + break; + +#if FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT + case FTMS_PARAM_SUPPORT_SPEED_RANGE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_SPEED_SPT_MASK) + { + memcpy(&ftms_var.support_speed_range, p_value, len); + } + else + { + PROFILE_PRINT_ERROR0("ftms_set_parameter:supported speed range not support!"); + } + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT + case FTMS_PARAM_SUPPORT_INCLINATION_RANGE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_INCLINATION_SPT_MASK) + { + memcpy(&ftms_var.support_inclination_range, p_value, len); + } + else + { + PROFILE_PRINT_ERROR0("ftms_set_parameter:supported inclination range not support!"); + } + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT + case FTMS_PARAM_SUPPORT_RESISTANCE_LEVEL_RANGE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_RESISTANCE_SPT_MASK) + { + memcpy(&ftms_var.support_resistance_level_range, p_value, len); + } + else + { + PROFILE_PRINT_ERROR0("ftms_set_parameter:supported resistance level range not support!"); + } + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT + case FTMS_PARAM_SUPPORT_POWER_RANGE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_POWER_SPT_MASK) + { + memcpy(&ftms_var.support_power_range, p_value, len); + } + else + { + PROFILE_PRINT_ERROR0("ftms_set_parameter:supported power range not support!"); + } + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT + case FTMS_PARAM_SUPPORT_HR_RANGE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_HR_SPT_MASK) + { + memcpy(&ftms_var.support_heart_rate_range, p_value, len); + } + else + { + PROFILE_PRINT_ERROR0("ftms_set_parameter:supported heart rate range not support!"); + } + } + break; +#endif + +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + case FTMS_PARAM_TREADMILL_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT16(ftms_var.treadmill_data_flag, p); + } + break; +#endif + +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + case FTMS_PARAM_STEP_CLIMBER_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT16(ftms_var.step_climber_data_flag, p); + } + break; +#endif + +#if FTMS_CHAR_ROWER_DATA_SUPPORT + case FTMS_PARAM_ROWER_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT16(ftms_var.rower_data_flag, p); + } + break; +#endif + +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT + case FTMS_PARAM_INDOOR_BIKE_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT16(ftms_var.indoor_bike_data_flag, p); + } + break; +#endif + +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + case FTMS_PARAM_CTL_PNT_PROG_CLR: + { + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESERVED; + } + break; +#endif + +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + case FTMS_PARAM_SD_RESP_PARAM: + { + memcpy(&ftms_var.ftms_sd_rsp_param, p_value, len); + } + break; +#endif + +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + case FTMS_PARAM_CROSS_TRAINER_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT24(ftms_var.cross_trainer_data_flag, p); + } + break; +#endif + +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + case FTMS_PARAM_STAIR_CLIMBER_DATA_FLAG: + { + uint8_t *p = (uint8_t *)p_value; + LE_STREAM_TO_UINT16(ftms_var.stair_climber_data_flag, p); + } + break; +#endif + + default: + { + ret = false; + } + break; + } + + return ret; +} + +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT +uint16_t ftms_treadmill_data_length(void) +{ + uint16_t data_length = FTMS_TM_INSTANTANEOUS_SPEED_LEN; + if (ftms_var.treadmill_data_flag & FTMS_TM_AVE_SPEED_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK) + { + data_length += FTMS_TM_TOTAL_DISTANCE_LEN; + } + if (ftms_var.treadmill_data_flag & FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + data_length += FTMS_TM_INCLINATION_RAMP_ANGLE_LEN; + } + if (ftms_var.treadmill_data_flag & FTMS_TM_ELEVATION_GAIN_PRESENT_MASK) + { + data_length += FTMS_TM_ELEVATION_GAIN_LEN; + } + if (ftms_var.treadmill_data_flag & FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_AVERAGE_PACE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK) + { + data_length += FTMS_TM_EXPENDED_ENERGY_LEN; + } + if (ftms_var.treadmill_data_flag & FTMS_TM_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.treadmill_data_flag & FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK) + { + data_length += FTMS_TM_BELT_FORCE_POWER_OUTPUT_LEN; + } + + return data_length; +} + +void ftms_save_treadmill_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_TREADMILL_DATA *p_treadmill_data) +{ + ftms_var.ftms_treadmill_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + + uint16_t offset = 0; + uint8_t *p; + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->instantaneous_speed); + offset += 2; + + ftms_var.ftms_treadmill_notify_flag.offset = FTMS_TM_INSTANTANEOUS_SPEED_LEN; + + if (ftms_var.treadmill_data_flag & FTMS_TM_AVE_SPEED_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_AVERAGE_SPEED_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->average_speed); + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_TOTAL_DISTANCE_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT24_TO_STREAM(p, p_treadmill_data->total_distance); + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 3); + } + + offset += 3; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_INCLINATION_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->inclination); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->ramp_angle_set); + offset += 2; + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + } + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_ELEVATION_GAIN_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELEVATION_GAIN_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->positive_elevation_gain); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->negative_elevation_gain); + offset += 2; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 4); + offset += 4; + } + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_PACE_SPT_MASK) + { + ftms_var.ftms_treadmill_notify_data[offset] = p_treadmill_data->instantaneous_pace; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_AVERAGE_PACE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_PACE_SPT_MASK) + { + ftms_var.ftms_treadmill_notify_data[offset] = p_treadmill_data->average_pace; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->total_energy); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->energy_per_hour); + offset += 2; + + ftms_var.ftms_treadmill_notify_data[offset] = p_treadmill_data->energy_per_minute; + offset += 1; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_treadmill_notify_data[offset] = p_treadmill_data->heart_rate; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_treadmill_notify_data[offset] = p_treadmill_data->metabolic_equivalent; + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->remain_time); + } + else + { + memset(ftms_var.ftms_treadmill_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.treadmill_data_flag & FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_BELT_FORCE_POWER_OUTPUT_SPT_MASK) + { + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->force_on_belt); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_treadmill_data->power_output); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + + p = ftms_var.ftms_treadmill_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + } +} + +void ftms_get_treadmill_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_TM_DATA_FLAG_LEN; + ftms_var.ftms_treadmill_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_treadmill_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_treadmill_data: get data fail"); + return; + } + + ftms_var.treadmill_data_flag &= FTMS_TM_NO_MORE_DATA_PRESENT; + ftms_var.ftms_treadmill_notify_flag.send_flag = ftms_var.treadmill_data_flag; + offset += 2; + memcpy(ftms_var.ftms_treadmill_send_data + offset, ftms_var.ftms_treadmill_notify_data, + data_length); + ftms_var.ftms_treadmill_notify_flag.data_len = len; + + if (ftms_var.ftms_treadmill_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_notify_data); + ftms_var.ftms_treadmill_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_treadmill_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_treadmill_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_treadmill_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_treadmill_notify_flag.offset; + + if (ftms_var.ftms_treadmill_notify_flag.no_more_data == 0) + { + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_MORE_DATA_MASK; + offset += FTMS_TM_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_treadmill_notify_flag.send_flag &= FTMS_TM_NO_MORE_DATA_PRESENT; + offset += FTMS_TM_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_treadmill_send_data + offset, ftms_var.ftms_treadmill_notify_data, 2); + offset += 2; + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_AVE_SPEED_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 2); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_AVE_SPEED_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_AVE_SPEED_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK) + { + if ((len - offset) >= FTMS_TM_TOTAL_DISTANCE_LEN) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 3); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK; + offset += 3; + total_offset += 3; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + if ((len - offset) >= FTMS_TM_INCLINATION_RAMP_ANGLE_LEN) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 4); + offset += 4; + total_offset += 4; + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_ELEVATION_GAIN_PRESENT_MASK) + { + if ((len - offset) >= FTMS_TM_ELEVATION_GAIN_LEN) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 4); + offset += 4; + total_offset += 4; + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_ELEVATION_GAIN_PRESENT_MASK; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_ELEVATION_GAIN_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 1); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_INSTANTANEOUS_PACE_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_AVERAGE_PACE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 1); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_AVERAGE_PACE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_AVERAGE_PACE_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_TM_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 5); + offset += 5; + total_offset += 5; + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_EXPENDED_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 1); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 1); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 2); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 2); + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_REMAIN_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_treadmill_notify_flag.cur_flag & FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK) + { + if ((len - offset) >= FTMS_TM_BELT_FORCE_POWER_OUTPUT_LEN) + { + memcpy(ftms_var.ftms_treadmill_send_data + offset, + ftms_var.ftms_treadmill_notify_data + total_offset, 4); + offset += 4; + total_offset += 4; + ftms_var.ftms_treadmill_notify_flag.send_flag |= FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK; + ftms_var.ftms_treadmill_notify_flag.cur_flag &= (~FTMS_TM_BELT_FORCE_POWER_OUTPUT_PRESENT_MASK); + } + else + { + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = total_offset; + + if ((data_length - total_offset + FTMS_TM_INSTANTANEOUS_SPEED_LEN) <= + (len - FTMS_TM_DATA_FLAG_LEN)) + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_treadmill_notify_flag.data_len = offset; + ftms_var.ftms_treadmill_notify_flag.offset = 0; + ftms_var.ftms_treadmill_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_treadmill_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_notify_data); + ftms_var.ftms_treadmill_notify_data = NULL; + } + } +} + +bool ftms_send_treadmill_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + bool ret = false; + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_TREADMILL_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_treadmill_data(conn_id, data_length); + + if (ftms_var.ftms_treadmill_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_treadmill_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_treadmill_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_treadmill_send_data, + ftms_var.ftms_treadmill_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_treadmill_send_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_send_data); + ftms_var.ftms_treadmill_send_data = NULL; + } + + ftms_var.ftms_treadmill_notify_flag.send_flag = 0; + ftms_var.ftms_treadmill_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_treadmill_notify_flag.cur_flag = + ftms_var.treadmill_data_flag & FTMS_TM_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_treadmill_notify_flag.cur_flag) + { + ftms_get_treadmill_data(conn_id, data_length); + + if (ftms_var.ftms_treadmill_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_treadmill_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_treadmill_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_treadmill_send_data, + ftms_var.ftms_treadmill_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_treadmill_send_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_send_data); + ftms_var.ftms_treadmill_send_data = NULL; + } + + ftms_var.ftms_treadmill_notify_flag.send_flag = 0; + ftms_var.ftms_treadmill_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_treadmill_send_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_send_data); + ftms_var.ftms_treadmill_send_data = NULL; + } + + ftms_var.ftms_treadmill_notify_flag.send_flag = 0; + ftms_var.ftms_treadmill_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_treadmill_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_TREADMILL_DATA *p_treadmill_data) +{ + bool ret = true; + + if (ftms_var.ftms_notify_indicate_flag.ftms_treadmill_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_treadmill_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_treadmill_data_length(); + ftms_save_treadmill_notify_data(conn_id, data_length, p_treadmill_data); + + return ftms_send_treadmill_data(conn_id, service_id, data_length); +} +#endif + +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT +uint16_t ftms_step_climber_data_length(void) +{ + uint16_t data_length = FTMS_STEPC_FLOOR_STEP_COUNT_LEN; + if (ftms_var.step_climber_data_flag & FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_AVE_STEP_RATE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK) + { + data_length += FTMS_STEPC_EXPENDED_ENERGY_LEN; + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.step_climber_data_flag & FTMS_STEPC_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + + return data_length; +} + +void ftms_save_step_climber_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_STEP_CLIMBER_DATA *p_step_climber_data) +{ + ftms_var.ftms_step_climber_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + uint16_t offset = 0; + uint8_t *p; + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->floor); + offset += 2; + + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->step_count); + offset += 2; + + ftms_var.ftms_step_climber_notify_flag.offset = FTMS_STEPC_FLOOR_STEP_COUNT_LEN; + + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STEP_COUNT_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->step_count); + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_AVE_STEP_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STEP_COUNT_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->average_step_rate); + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELEVATION_GAIN_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->positive_elevation_gain); + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->positive_elevation_gain); + offset += 2; + + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->positive_elevation_gain); + offset += 2; + + ftms_var.ftms_step_climber_notify_data[offset] = p_step_climber_data->energy_per_minute; + offset += 1; + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_step_climber_notify_data[offset] = p_step_climber_data->heart_rate; + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_step_climber_notify_data[offset] = p_step_climber_data->metabolic_equivalent; + + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.step_climber_data_flag & FTMS_STEPC_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_step_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_step_climber_data->remain_time); + } + else + { + memset(ftms_var.ftms_step_climber_notify_data + offset, 0xFF, 2); + } + } +} + +void ftms_get_step_climber_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_STEPC_DATA_FLAG_LEN; + ftms_var.ftms_step_climber_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_step_climber_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_step_climber_data: get data fail"); + return; + } + + ftms_var.step_climber_data_flag &= FTMS_STEPC_NO_MORE_DATA_PRESENT; + ftms_var.ftms_step_climber_notify_flag.send_flag = ftms_var.step_climber_data_flag; + offset += 2; + memcpy(ftms_var.ftms_step_climber_send_data + offset, ftms_var.ftms_step_climber_notify_data, + data_length); + ftms_var.ftms_step_climber_notify_flag.data_len = len; + + if (ftms_var.ftms_step_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_notify_data); + ftms_var.ftms_step_climber_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_step_climber_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_step_climber_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_step_climber_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_step_climber_notify_flag.offset; + + if (ftms_var.ftms_step_climber_notify_flag.no_more_data == 0) + { + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_MORE_DATA_MASK; + offset += FTMS_STEPC_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_step_climber_notify_flag.send_flag &= FTMS_STEPC_NO_MORE_DATA_PRESENT; + offset += FTMS_STEPC_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_step_climber_send_data + offset, ftms_var.ftms_step_climber_notify_data, 4); + offset += FTMS_STEPC_FLOOR_STEP_COUNT_LEN; + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 2); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_STEP_PER_MINUTE_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_AVE_STEP_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 2); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_AVE_STEP_RATE_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_TM_TOTAL_DISTANCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & + FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= + (~FTMS_STEPC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_STEPC_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 5); + offset += 5; + total_offset += 5; + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_EXPEND_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 1); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 1); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 2); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_step_climber_notify_flag.cur_flag & FTMS_STEPC_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_step_climber_send_data + offset, + ftms_var.ftms_step_climber_notify_data + total_offset, 2); + ftms_var.ftms_step_climber_notify_flag.send_flag |= FTMS_STEPC_REMAIN_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_step_climber_notify_flag.cur_flag &= (~FTMS_STEPC_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STEPC_FLOOR_STEP_COUNT_LEN) <= + (len - FTMS_STEPC_FLOOR_STEP_COUNT_LEN)) + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_step_climber_notify_flag.data_len = offset; + ftms_var.ftms_step_climber_notify_flag.offset = 0; + ftms_var.ftms_step_climber_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_step_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_notify_data); + ftms_var.ftms_step_climber_notify_data = NULL; + } + } +} + +bool ftms_send_step_climber_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + bool ret = false; + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_STEP_CLIMBER_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_step_climber_data(conn_id, data_length); + + if (ftms_var.ftms_step_climber_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_step_climber_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_step_climber_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_step_climber_send_data, + ftms_var.ftms_step_climber_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_step_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_send_data); + ftms_var.ftms_step_climber_send_data = NULL; + } + + ftms_var.ftms_step_climber_notify_flag.send_flag = 0; + ftms_var.ftms_step_climber_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_step_climber_notify_flag.cur_flag = + ftms_var.step_climber_data_flag & FTMS_STEPC_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_step_climber_notify_flag.cur_flag) + { + ftms_get_step_climber_data(conn_id, data_length); + + if (ftms_var.ftms_step_climber_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_step_climber_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_step_climber_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_step_climber_send_data, + ftms_var.ftms_step_climber_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_step_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_send_data); + ftms_var.ftms_step_climber_send_data = NULL; + } + + ftms_var.ftms_step_climber_notify_flag.send_flag = 0; + ftms_var.ftms_step_climber_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_step_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_send_data); + ftms_var.ftms_step_climber_send_data = NULL; + } + + ftms_var.ftms_step_climber_notify_flag.send_flag = 0; + ftms_var.ftms_step_climber_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_step_climber_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_STEP_CLIMBER_DATA *step_climber_data) +{ + bool ret = true; + if (ftms_var.ftms_notify_indicate_flag.ftms_step_climber_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_step_climber_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_step_climber_data_length(); + ftms_save_step_climber_notify_data(conn_id, data_length, step_climber_data); + + return ftms_send_step_climber_data(conn_id, service_id, data_length); +} +#endif + +#if FTMS_CHAR_ROWER_DATA_SUPPORT +uint16_t ftms_rower_data_length(void) +{ + uint16_t data_length = FTMS_RW_STROKE_RATE_COUNT_LEN; + if (ftms_var.rower_data_flag & FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK) + { + data_length += FTMS_RW_TOTAL_DISTANCE_LEN; + } + if (ftms_var.rower_data_flag & FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_AVE_PACE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_AVE_POWER_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_RESISTANCE_LEVEL_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_EXPEND_ENERGY_PRESENT_MASK) + { + data_length += FTMS_RW_EXPENDED_ENERGY_LEN; + } + if (ftms_var.rower_data_flag & FTMS_RW_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.rower_data_flag & FTMS_RW_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + + return data_length; +} + +void ftms_save_rower_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_ROWER_DATA *p_rower_data) +{ + ftms_var.ftms_rower_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + uint16_t offset = 0; + uint8_t *p; + ftms_var.ftms_rower_notify_data[offset] = p_rower_data->stroke_rate; + offset += 1; + + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->stroke_count); + offset += 2; + + ftms_var.ftms_rower_notify_flag.offset = FTMS_RW_STROKE_RATE_COUNT_LEN; + + if (ftms_var.rower_data_flag & FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_CADENCE_SPT_MASK) + { + ftms_var.ftms_rower_notify_data[offset] = p_rower_data->average_stroke_rate; + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.rower_data_flag & FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_TOTAL_DISTANCE_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT24_TO_STREAM(p, p_rower_data->total_distance); + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 3); + } + + offset += 3; + } + + if (ftms_var.rower_data_flag & FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_PACE_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->instantaneous_pace); + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_AVE_PACE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_PACE_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->average_pace); + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->instantaneous_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_AVE_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->average_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_RESISTANCE_LEVEL_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_RESISTANCE_LEVEL_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->resistance_level); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_EXPEND_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->total_energy); + offset += 2; + + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->energy_per_hour); + offset += 2; + + ftms_var.ftms_rower_notify_data[offset] = p_rower_data->energy_per_minute; + offset += 1; + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + + if (ftms_var.rower_data_flag & FTMS_RW_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_rower_notify_data[offset] = p_rower_data->heart_rate; + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.rower_data_flag & FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_rower_notify_data[offset] = p_rower_data->metabolic_equivalent; + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.rower_data_flag & FTMS_RW_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.rower_data_flag & FTMS_RW_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_rower_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_rower_data->remain_time); + } + else + { + memset(ftms_var.ftms_rower_notify_data + offset, 0xFF, 2); + } + } +} + +void ftms_get_rower_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_RW_DATA_FLAG_LEN; + ftms_var.ftms_rower_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_rower_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_rower_data: get data fail"); + return; + } + + ftms_var.ftms_rower_notify_flag.send_flag = ftms_var.rower_data_flag &= + FTMS_RW_NO_MORE_DATA_PRESENT; + offset += FTMS_RW_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_rower_send_data + offset, + ftms_var.ftms_rower_notify_data, data_length); + ftms_var.ftms_rower_notify_flag.data_len = len; + + if (ftms_var.ftms_rower_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_notify_data); + ftms_var.ftms_rower_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_rower_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_rower_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_rower_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_rower_notify_flag.offset; + + if (ftms_var.ftms_rower_notify_flag.no_more_data == 0) + { + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_MORE_DATA_MASK; + offset += FTMS_RW_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_rower_notify_flag.send_flag &= FTMS_RW_NO_MORE_DATA_PRESENT; + offset += FTMS_RW_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data, 3); + offset += FTMS_RW_STROKE_RATE_COUNT_LEN; + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 1); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_AVE_STROKE_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK) + { + if ((len - offset) >= FTMS_RW_TOTAL_DISTANCE_LEN) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 3); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK; + offset += 3; + total_offset += 3; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_TOTAL_DISTANCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_INSTANTANEOUS_PACE_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_AVE_PACE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_AVE_PACE_PRESENT_MASK; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_AVE_PACE_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_INSTANTANEOUS_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_AVE_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_AVE_POWER_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_AVE_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_RESISTANCE_LEVEL_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_RESISTANCE_LEVEL_MASK; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_RESISTANCE_LEVEL_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_EXPEND_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_RW_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 5); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_EXPEND_ENERGY_PRESENT_MASK; + offset += 5; + total_offset += 5; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_EXPEND_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 1); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 1); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_rower_notify_flag.cur_flag & FTMS_RW_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_rower_send_data + offset, ftms_var.ftms_rower_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_rower_notify_flag.send_flag |= FTMS_RW_REMAIN_TIME_PRESENT_MASK; + ftms_var.ftms_rower_notify_flag.cur_flag &= (~FTMS_RW_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_RW_STROKE_RATE_COUNT_LEN) <= (len - FTMS_RW_DATA_FLAG_LEN)) + { + ftms_var.ftms_rower_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_rower_notify_flag.data_len = offset; + ftms_var.ftms_rower_notify_flag.offset = 0; + ftms_var.ftms_rower_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_rower_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_notify_data); + ftms_var.ftms_rower_notify_data = NULL; + } + } +} + +bool ftms_send_rower_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + bool ret = false; + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_ROWER_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_rower_data(conn_id, data_length); + + if (ftms_var.ftms_rower_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_rower_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_rower_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_rower_send_data, + ftms_var.ftms_rower_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_rower_send_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_send_data); + ftms_var.ftms_rower_send_data = NULL; + } + + ftms_var.ftms_rower_notify_flag.send_flag = 0; + ftms_var.ftms_rower_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_rower_notify_flag.cur_flag = + ftms_var.rower_data_flag & FTMS_RW_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_rower_notify_flag.cur_flag) + { + ftms_get_rower_data(conn_id, data_length); + + if (ftms_var.ftms_rower_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_rower_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_rower_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_rower_send_data, + ftms_var.ftms_rower_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_rower_send_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_send_data); + ftms_var.ftms_rower_send_data = NULL; + } + + ftms_var.ftms_rower_notify_flag.send_flag = 0; + ftms_var.ftms_rower_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_rower_send_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_send_data); + ftms_var.ftms_rower_send_data = NULL; + } + + ftms_var.ftms_rower_notify_flag.send_flag = 0; + ftms_var.ftms_rower_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_rower_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_ROWER_DATA *p_rower_data) +{ + bool ret = true; + if (ftms_var.ftms_notify_indicate_flag.ftms_rower_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_rower_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_rower_data_length(); + ftms_save_rower_notify_data(conn_id, data_length, p_rower_data); + + return ftms_send_rower_data(conn_id, service_id, data_length); +} +#endif + +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT +uint16_t ftms_indoor_bike_data_length(void) +{ + uint16_t data_length = FTMS_IB_INSTANTANEOUS_SPEED_LEN; + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_SPEED_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_INSTANTANEOUS_CADENCE_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_CADENCE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK) + { + data_length += FTMS_IB_TOTAL_DISTANCE_LEN; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_POWER_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_EXPEND_ENERGY_PRESENT_MASK) + { + data_length += FTMS_IB_EXPENDED_ENERGY_LEN; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + + return data_length; +} + +void ftms_save_indoor_bike_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_INDOOR_BIKE_DATA *p_indoor_bike_data) +{ + ftms_var.ftms_indoor_bike_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + uint16_t offset = 0; + uint8_t *p; + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->instantaneous_speed); + offset += 2; + + ftms_var.ftms_indoor_bike_notify_flag.offset = FTMS_IB_INSTANTANEOUS_SPEED_LEN; + + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_SPEED_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_AVERAGE_SPEED_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->average_speed); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.indoor_bike_data_flag & FTMS_IB_INSTANTANEOUS_CADENCE_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_CADENCE_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->instantaneous_cadence); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_CADENCE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_CADENCE_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->average_cadence); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_TOTAL_DISTANCE_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT24_TO_STREAM(p, p_indoor_bike_data->total_distance); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 3); + } + + offset += 3; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_RESISTANCE_LEVEL_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->resistance_level); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->instantaneous_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_AVE_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->average_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_EXPEND_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->total_energy); + offset += 2; + + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->energy_per_hour); + offset += 2; + + ftms_var.ftms_indoor_bike_notify_data[offset] = p_indoor_bike_data->energy_per_minute; + offset += 1; + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_indoor_bike_notify_data[offset] = p_indoor_bike_data->heart_rate; + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_indoor_bike_notify_data[offset] = p_indoor_bike_data->metabolic_equivalent; + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + if (ftms_var.indoor_bike_data_flag & FTMS_IB_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_indoor_bike_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_indoor_bike_data->remain_time); + } + else + { + memset(ftms_var.ftms_indoor_bike_notify_data + offset, 0xFF, 2); + } + } +} + +void ftms_get_indoor_bike_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_IB_DATA_FLAG_LEN; + ftms_var.ftms_indoor_bike_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_indoor_bike_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_indoor_bike_data: get data fail"); + return; + } + + ftms_var.indoor_bike_data_flag &= FTMS_IB_NO_MORE_DATA_PRESENT; + ftms_var.ftms_indoor_bike_notify_flag.send_flag = ftms_var.indoor_bike_data_flag; + offset += FTMS_IB_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, ftms_var.ftms_indoor_bike_notify_data, + data_length); + ftms_var.ftms_indoor_bike_notify_flag.data_len = len; + + if (ftms_var.ftms_indoor_bike_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_notify_data); + ftms_var.ftms_indoor_bike_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_indoor_bike_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_indoor_bike_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_indoor_bike_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_indoor_bike_notify_flag.offset; + + if (ftms_var.ftms_indoor_bike_notify_flag.no_more_data == 0) + { + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_MORE_DATA_MASK; + offset += FTMS_IB_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.send_flag &= FTMS_IB_NO_MORE_DATA_PRESENT; + offset += FTMS_IB_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, ftms_var.ftms_indoor_bike_notify_data, 2); + offset += FTMS_IB_INSTANTANEOUS_SPEED_LEN; + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_AVE_SPEED_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_AVE_SPEED_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_AVE_SPEED_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_INSTANTANEOUS_CADENCE_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_INSTANTANEOUS_CADENCE_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_INSTANTANEOUS_CADENCE_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_AVE_CADENCE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_AVE_CADENCE_PRESENT_MASK; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_AVE_CADENCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK) + { + if ((len - offset) >= FTMS_IB_TOTAL_DISTANCE_LEN) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 3); + offset += 3; + total_offset += 3; + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_TOTAL_DISTANCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_RESISTANCE_LEVEL_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_INSTANTANEOUS_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_AVE_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_AVE_POWER_PRESENT_MASK; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_AVE_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_EXPEND_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_IB_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 5); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_EXPEND_ENERGY_PRESENT_MASK; + offset += 5; + total_offset += 5; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_EXPEND_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 1); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 1); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_indoor_bike_notify_flag.cur_flag & FTMS_IB_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_indoor_bike_send_data + offset, + ftms_var.ftms_indoor_bike_notify_data + total_offset, 2); + offset += 2; + total_offset += 2; + ftms_var.ftms_indoor_bike_notify_flag.send_flag |= FTMS_IB_REMAIN_TIME_PRESENT_MASK; + ftms_var.ftms_indoor_bike_notify_flag.cur_flag &= (~FTMS_IB_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_IB_INSTANTANEOUS_SPEED_LEN) <= (FTMS_IB_DATA_FLAG_LEN)) + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_indoor_bike_notify_flag.data_len = offset; + ftms_var.ftms_indoor_bike_notify_flag.offset = 0; + ftms_var.ftms_indoor_bike_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_indoor_bike_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_notify_data); + ftms_var.ftms_indoor_bike_notify_data = NULL; + } + } +} + +bool ftms_send_indoor_bike_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + bool ret = false; + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_INDOOR_BIKE_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_indoor_bike_data(conn_id, data_length); + + if (ftms_var.ftms_indoor_bike_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_indoor_bike_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_indoor_bike_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_indoor_bike_send_data, + ftms_var.ftms_indoor_bike_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_indoor_bike_send_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_send_data); + ftms_var.ftms_indoor_bike_send_data = NULL; + } + + ftms_var.ftms_indoor_bike_notify_flag.send_flag = 0; + ftms_var.ftms_indoor_bike_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_indoor_bike_notify_flag.cur_flag = + ftms_var.indoor_bike_data_flag & FTMS_IB_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_indoor_bike_notify_flag.cur_flag) + { + ftms_get_indoor_bike_data(conn_id, data_length); + + if (ftms_var.ftms_indoor_bike_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_indoor_bike_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_indoor_bike_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_indoor_bike_send_data, + ftms_var.ftms_indoor_bike_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_indoor_bike_send_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_send_data); + ftms_var.ftms_indoor_bike_send_data = NULL; + } + + ftms_var.ftms_indoor_bike_notify_flag.send_flag = 0; + ftms_var.ftms_indoor_bike_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_indoor_bike_send_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_send_data); + ftms_var.ftms_indoor_bike_send_data = NULL; + } + + ftms_var.ftms_indoor_bike_notify_flag.send_flag = 0; + ftms_var.ftms_indoor_bike_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_indoor_bike_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_INDOOR_BIKE_DATA *p_indoor_bike_data) +{ + bool ret = true; + if (ftms_var.ftms_notify_indicate_flag.ftms_indoor_bike_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_indoor_bike_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_indoor_bike_data_length(); + ftms_save_indoor_bike_notify_data(conn_id, data_length, p_indoor_bike_data); + + return ftms_send_indoor_bike_data(conn_id, service_id, data_length); +} +#endif + +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT +uint16_t ftms_cross_trainer_data_length(void) +{ + uint16_t data_length = FTMS_CT_INSTANTANEOUS_SPEED_LEN; + if (ftms_var.cross_trainer_data_flag & FTMS_CT_AVE_SPEED_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK) + { + data_length += FTMS_CT_TOTAL_DISTANCE_LEN; + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_STEP_COUNT_PRESENT_MASK) + { + data_length += FTMS_CT_STEP_PER_MINUTE_STEP_RATE_LEN; + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_STRIDE_COUNT_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_ELEVATION_GAIN_PRESENT_MASK) + { + data_length += FTMS_CT_ELEVATION_GAIN_LEN; + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + data_length += FTMS_CT_INCLINATION_RAMP_ANGLE_LEN; + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_AVE_POWER_PRESENT_MASK) + { + data_length += sizeof(int16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_EXPEND_ENERGY_PRESENT_MASK) + { + data_length += FTMS_CT_EXPENDED_ENERGY_LEN; + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.cross_trainer_data_flag & FTMS_CT_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + + return data_length; +} + +void ftms_save_cross_trainer_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_CROSS_TRAINER_DATA *p_cross_trainer_data) +{ + ftms_var.ftms_cross_trainer_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + uint16_t offset = 0; + uint8_t *p; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->instantaneous_speed); + + offset += FTMS_CT_INSTANTANEOUS_SPEED_LEN; + + ftms_var.ftms_cross_trainer_notify_flag.offset = FTMS_CT_INSTANTANEOUS_SPEED_LEN; + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_AVE_SPEED_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_AVERAGE_SPEED_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->average_speed); + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_TOTAL_DISTANCE_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT24_TO_STREAM(p, p_cross_trainer_data->total_distance); + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 3); + } + + offset += 3; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_STEP_COUNT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STEP_COUNT_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->inclination); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->ramp_angle_set); + offset += 2; + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_STRIDE_COUNT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STRIDE_COUNT_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->stride_count); + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_ELEVATION_GAIN_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELEVATION_GAIN_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->positive_elevation_gain); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->negative_elevation_gain); + offset += 2; + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 4); + offset += 4; + } + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_INCLINATION_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->inclination); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->ramp_angle_set); + offset += 2; + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + offset += 2; + } + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_RESISTANCE_LEVEL_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->resistance_level); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->instantaneous_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_AVE_POWER_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_POWER_MEASUREMENT_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->average_power); + } + else + { + uint16_t invalid_data = 0x7FFF; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, invalid_data); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_EXPEND_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->total_energy); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->energy_per_hour); + offset += 2; + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT8_TO_STREAM(p, p_cross_trainer_data->energy_per_minute); + offset += 1; + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_cross_trainer_notify_data[offset] = p_cross_trainer_data->heart_rate; + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_cross_trainer_notify_data[offset] = p_cross_trainer_data->metabolic_equivalent; + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.cross_trainer_data_flag & FTMS_CT_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_cross_trainer_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_cross_trainer_data->remain_time); + } + else + { + memset(ftms_var.ftms_cross_trainer_notify_data + offset, 0xFF, 2); + } + } +} + +void ftms_get_cross_trainer_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_CT_DATA_FLAG_LEN; + ftms_var.ftms_cross_trainer_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_cross_trainer_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_cross_trainer_data: get data fail"); + return; + } + + ftms_var.cross_trainer_data_flag &= FTMS_CT_NO_MORE_DATA_PRESENT; + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag = ftms_var.cross_trainer_data_flag; + offset += FTMS_CT_DATA_FLAG_LEN; + + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, ftms_var.ftms_cross_trainer_notify_data, + data_length); + ftms_var.ftms_cross_trainer_notify_flag.data_len = len; + + if (ftms_var.ftms_cross_trainer_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_notify_data); + ftms_var.ftms_cross_trainer_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_cross_trainer_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_cross_trainer_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_cross_trainer_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_cross_trainer_notify_flag.offset; + + if (ftms_var.ftms_cross_trainer_notify_flag.no_more_data == 0) + { + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_MORE_DATA_MASK; + offset += FTMS_CT_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag &= FTMS_CT_NO_MORE_DATA_PRESENT; + offset += FTMS_CT_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data, 2); + offset += FTMS_CT_INSTANTANEOUS_SPEED_LEN; + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_AVE_SPEED_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_AVE_SPEED_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_AVE_SPEED_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK) + { + if ((len - offset) >= FTMS_CT_TOTAL_DISTANCE_LEN) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 3); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK; + offset += 3; + total_offset += 3; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_TOTAL_DISTANCE_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_STEP_COUNT_PRESENT_MASK) + { + if ((len - offset) >= FTMS_CT_STEP_PER_MINUTE_STEP_RATE_LEN) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 4); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_STEP_COUNT_PRESENT_MASK; + offset += 4; + total_offset += 4; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_STEP_COUNT_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_STRIDE_COUNT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_STRIDE_COUNT_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_STRIDE_COUNT_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_ELEVATION_GAIN_PRESENT_MASK) + { + if ((len - offset) >= FTMS_CT_ELEVATION_GAIN_LEN) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 4); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_ELEVATION_GAIN_PRESENT_MASK; + offset += 4; + total_offset += 4; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_ELEVATION_GAIN_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & + FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK) + { + if ((len - offset) >= FTMS_CT_INCLINATION_RAMP_ANGLE_LEN) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 4); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= + FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK; + offset += 4; + total_offset += 4; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= + (~FTMS_CT_INCLINATION_RAMP_ANGLE_SET_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_RESISTANCE_LEVEL_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_INSTANTANEOUS_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_AVE_POWER_PRESENT_MASK) + { + if ((len - offset) >= sizeof(int16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_AVE_POWER_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_AVE_POWER_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_EXPEND_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_CT_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 5); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_EXPEND_ENERGY_PRESENT_MASK; + offset += 5; + total_offset += 5; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_EXPEND_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 1); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 1); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & FTMS_CT_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_cross_trainer_send_data + offset, + ftms_var.ftms_cross_trainer_notify_data + total_offset, 2); + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag |= FTMS_CT_REMAIN_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag &= (~FTMS_CT_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_CT_INSTANTANEOUS_SPEED_LEN) <= (len - FTMS_CT_DATA_FLAG_LEN)) + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_cross_trainer_notify_flag.data_len = offset; + ftms_var.ftms_cross_trainer_notify_flag.offset = 0; + ftms_var.ftms_cross_trainer_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_cross_trainer_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_notify_data); + ftms_var.ftms_cross_trainer_notify_data = NULL; + } + } +} + +bool ftms_send_cross_trainer_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + bool ret = false; + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_CROSS_TRAINER_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_cross_trainer_data(conn_id, data_length); + + if (ftms_var.ftms_cross_trainer_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_cross_trainer_send_data; + LE_UINT24_TO_STREAM(p, ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_cross_trainer_send_data, + ftms_var.ftms_cross_trainer_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_cross_trainer_send_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_send_data); + ftms_var.ftms_cross_trainer_send_data = NULL; + } + + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag = 0; + ftms_var.ftms_cross_trainer_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag = + ftms_var.cross_trainer_data_flag & FTMS_CT_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_cross_trainer_notify_flag.ct_cur_flag & (~FTMS_CT_MOVEMENT_DIRECTION_MASK)) + { + ftms_get_cross_trainer_data(conn_id, data_length); + + if (ftms_var.ftms_cross_trainer_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_cross_trainer_send_data; + LE_UINT24_TO_STREAM(p, ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_cross_trainer_send_data, + ftms_var.ftms_cross_trainer_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_cross_trainer_send_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_send_data); + ftms_var.ftms_cross_trainer_send_data = NULL; + } + + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag = 0; + ftms_var.ftms_cross_trainer_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_cross_trainer_send_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_send_data); + ftms_var.ftms_cross_trainer_send_data = NULL; + } + + ftms_var.ftms_cross_trainer_notify_flag.ct_send_flag = 0; + ftms_var.ftms_cross_trainer_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_cross_trainer_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_CROSS_TRAINER_DATA *p_cross_trainer_data) +{ + bool ret = true; + if (ftms_var.ftms_notify_indicate_flag.ftms_cross_trainer_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_cross_trainer_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_cross_trainer_data_length(); + ftms_save_cross_trainer_notify_data(conn_id, data_length, p_cross_trainer_data); + + return ftms_send_cross_trainer_data(conn_id, service_id, data_length); +} +#endif + +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT +uint16_t ftms_stair_climber_data_length(void) +{ + uint16_t data_length = FTMS_STAIRC_FLOORS_LEN; + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK) + { + data_length += FTMS_STAIRC_EXPENDED_ENERGY_LEN; + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_HEART_RATE_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + data_length += sizeof(uint8_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK) + { + data_length += sizeof(uint16_t); + } + + return data_length; +} + +void ftms_save_stair_climber_notify_data(uint8_t conn_id, uint16_t data_length, + T_FTMS_STAIR_CLIMBER_DATA *p_stair_climber_data) +{ + ftms_var.ftms_stair_climber_notify_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + uint16_t offset = 0; + uint8_t *p; + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->floors); + offset += 2; + + ftms_var.ftms_stair_climber_notify_flag.offset = FTMS_STAIRC_FLOORS_LEN; + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STEP_COUNT_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->step_per_minute); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STEP_COUNT_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->average_step_rate); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELEVATION_GAIN_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->positive_elevation_gain); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_STRIDE_COUNT_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->stride_count); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_EXPENDED_ENERGY_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->total_energy); + offset += 2; + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->energy_per_hour); + offset += 2; + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT8_TO_STREAM(p, p_stair_climber_data->energy_per_minute); + offset += 1; + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 5); + offset += 5; + } + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_HEART_RATE_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_HR_MEASUREMENT_SPT_MASK) + { + ftms_var.ftms_stair_climber_notify_data[offset] = p_stair_climber_data->heart_rate; + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_METABOLIC_EQUIVALENT_SPT_MASK) + { + ftms_var.ftms_stair_climber_notify_data[offset] = + p_stair_climber_data->metabolic_equivalent; + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 1); + } + + offset += 1; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_ELAPSED_TIME_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->elapsed_time); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + + offset += 2; + } + + if (ftms_var.stair_climber_data_flag & FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK) + { + if (ftms_var.ftms_feature.features_field & FTMS_FEAT_REMAIN_TIME_SPT_MASK) + { + p = ftms_var.ftms_stair_climber_notify_data + offset; + LE_UINT16_TO_STREAM(p, p_stair_climber_data->remain_time); + } + else + { + memset(ftms_var.ftms_stair_climber_notify_data + offset, 0xFF, 2); + } + } +} + +void ftms_get_stair_climber_data(uint8_t conn_id, uint16_t data_length) +{ + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + uint16_t len = 0; + uint16_t offset = 0; + + if (data_length <= (mtu_size - 5)) + { + len = data_length + FTMS_STAIRC_DATA_FLAG_LEN; + ftms_var.ftms_stair_climber_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_stair_climber_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_stair_climber_data: get data fail"); + return; + } + + ftms_var.stair_climber_data_flag &= FTMS_STAIRC_NO_MORE_DATA_PRESENT; + ftms_var.ftms_stair_climber_notify_flag.send_flag = ftms_var.stair_climber_data_flag; + offset += FTMS_STAIRC_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_stair_climber_send_data + offset, ftms_var.ftms_stair_climber_notify_data, + data_length); + ftms_var.ftms_stair_climber_notify_flag.data_len = len; + + if (ftms_var.ftms_stair_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_notify_data); + ftms_var.ftms_stair_climber_notify_data = NULL; + } + } + else + { + uint16_t total_offset = 0; + len = mtu_size - 3; + + ftms_var.ftms_stair_climber_send_data = os_mem_zalloc(RAM_TYPE_DATA_ON, len); + + if (ftms_var.ftms_stair_climber_send_data == NULL) + { + PROFILE_PRINT_ERROR0("ftms_get_stair_climber_data: get data fail"); + return; + } + + total_offset = ftms_var.ftms_stair_climber_notify_flag.offset; + + if (ftms_var.ftms_stair_climber_notify_flag.no_more_data == 0) + { + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_MORE_DATA_MASK; + offset += FTMS_STAIRC_DATA_FLAG_LEN; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.send_flag &= FTMS_STAIRC_NO_MORE_DATA_PRESENT; + offset += FTMS_STAIRC_DATA_FLAG_LEN; + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data, 2); + offset += FTMS_STAIRC_FLOORS_LEN; + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_STEP_PER_MINUTE_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_AVE_STEP_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & + FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= + FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= + (~FTMS_STAIRC_POSITIVE_ELEVATION_GAIN_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_STRIDE_COUNT_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK) + { + if ((len - offset) >= FTMS_STAIRC_EXPENDED_ENERGY_LEN) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 5); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK; + offset += 5; + total_offset += 5; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_EXPEND_ENERGY_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_HEART_RATE_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 1); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_HEART_RATE_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_HEART_RATE_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & + FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint8_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 1); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK; + offset += 1; + total_offset += 1; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= + (~FTMS_STAIRC_METABOLIC_EQUIVALENT_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_ELAPSED_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + if (ftms_var.ftms_stair_climber_notify_flag.cur_flag & FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK) + { + if ((len - offset) >= sizeof(uint16_t)) + { + memcpy(ftms_var.ftms_stair_climber_send_data + offset, + ftms_var.ftms_stair_climber_notify_data + total_offset, 2); + ftms_var.ftms_stair_climber_notify_flag.send_flag |= FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK; + offset += 2; + total_offset += 2; + ftms_var.ftms_stair_climber_notify_flag.cur_flag &= (~FTMS_STAIRC_REMAIN_TIME_PRESENT_MASK); + } + else + { + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = total_offset; + + if ((data_length - offset + FTMS_STAIRC_FLOORS_LEN) <= (len - FTMS_STAIRC_DATA_FLAG_LEN)) + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 1; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + } + + return; + } + } + + ftms_var.ftms_stair_climber_notify_flag.data_len = offset; + ftms_var.ftms_stair_climber_notify_flag.offset = 0; + ftms_var.ftms_stair_climber_notify_flag.no_more_data = 0; + + if (ftms_var.ftms_stair_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_notify_data); + ftms_var.ftms_stair_climber_notify_data = NULL; + } + } +} + +bool ftms_send_stair_climber_data(uint8_t conn_id, T_SERVER_ID service_id, uint16_t data_length) +{ + bool ret = false; + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_STAIR_CLIMBER_DATA); + uint16_t attrib_index = p_char->char_index; + + if (data_length <= (mtu_size - 5)) + { + ftms_get_stair_climber_data(conn_id, data_length); + + if (ftms_var.ftms_stair_climber_send_data == NULL) + { + return ret; + } + + uint8_t *p = ftms_var.ftms_stair_climber_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_stair_climber_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_stair_climber_send_data, + ftms_var.ftms_stair_climber_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + } + + if (ftms_var.ftms_stair_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_send_data); + ftms_var.ftms_stair_climber_send_data = NULL; + } + + ftms_var.ftms_stair_climber_notify_flag.send_flag = 0; + ftms_var.ftms_stair_climber_notify_flag.data_len = 0; + } + else + { + ftms_var.ftms_stair_climber_notify_flag.cur_flag = + ftms_var.stair_climber_data_flag & FTMS_STAIRC_NO_MORE_DATA_PRESENT; + + while (ftms_var.ftms_stair_climber_notify_flag.cur_flag) + { + ftms_get_stair_climber_data(conn_id, data_length); + + if (ftms_var.ftms_stair_climber_send_data == NULL) + { + ret = false; + return ret; + } + + uint8_t *p = ftms_var.ftms_stair_climber_send_data; + LE_UINT16_TO_STREAM(p, ftms_var.ftms_stair_climber_notify_flag.send_flag); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_stair_climber_send_data, + ftms_var.ftms_stair_climber_notify_flag.data_len, GATT_PDU_TYPE_NOTIFICATION)) + { + if (ftms_var.ftms_stair_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_send_data); + ftms_var.ftms_stair_climber_send_data = NULL; + } + + ftms_var.ftms_stair_climber_notify_flag.send_flag = 0; + ftms_var.ftms_stair_climber_notify_flag.data_len = 0; + ret = true; + } + else + { + if (ftms_var.ftms_stair_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_send_data); + ftms_var.ftms_stair_climber_send_data = NULL; + } + + ftms_var.ftms_stair_climber_notify_flag.send_flag = 0; + ftms_var.ftms_stair_climber_notify_flag.data_len = 0; + ret = false; + return ret; + } + } + } + + return ret; +} + +bool ftms_stair_climber_data_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_FTMS_STAIR_CLIMBER_DATA *p_stair_climber_data) +{ + bool ret = true; + if (ftms_var.ftms_notify_indicate_flag.ftms_stair_climber_data_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_stair_climber_data_notify:FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + uint16_t data_length = ftms_stair_climber_data_length(); + ftms_save_stair_climber_notify_data(conn_id, data_length, p_stair_climber_data); + + return ftms_send_stair_climber_data(conn_id, service_id, data_length); +} +#endif + +#if (FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT || FTMS_CHAR_FTMS_STATUS_SUPPORT) +bool ftms_status_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, + T_FTMS_CP_PARAMETER param, uint8_t param_len) +{ + bool ret = true; + + if (ftms_var.ftms_notify_indicate_flag.ftms_status_notify_enable == 0) + { + ret = false; + PROFILE_PRINT_INFO0("ftms_status_notify: FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_FITNESS_MACHINE_STATUS); + uint16_t attrib_index = p_char->char_index; + uint16_t data_length = param_len + 1; + uint8_t status_data[param_len + 1]; + status_data[0] = opcode; + uint8_t offset = 1; + + switch (opcode) + { + case FTMS_STATUS_OP_RESET: + {} + break; + + case FTMS_STATUS_OP_STOP_PAUSE_BY_USER: + { + status_data[offset] = param.ctrl_information; + } + break; + + case FTMS_STATUS_OP_STOP_BY_SAFETY_KEY: + {} + break; + + case FTMS_STATUS_OP_START_RESUME_BY_USER: + {} + break; + + case FTMS_STATUS_OP_TGT_SPEED_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_speed); + } + break; + + case FTMS_STATUS_OP_TGT_INCLINE_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_inclination); + } + break; + + case FTMS_STATUS_OP_TGT_RESISTANCE_LEVEL_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_resistance_level); + } + break; + + case FTMS_STATUS_OP_TGT_POWER_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_power); + } + break; + + case FTMS_STATUS_OP_TGT_HR_CHANGE: + { + status_data[offset] = param.target_heart_rate; + } + break; + + case FTMS_STATUS_OP_TGT_EXPEND_ENERGY_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_expended_energy); + } + break; + + case FTMS_STATUS_OP_TGT_STEP_NUM_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_step_num); + } + break; + + case FTMS_STATUS_OP_TGT_STRIDE_NUM_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_stride_num); + } + break; + + case FTMS_STATUS_OP_TGT_DISTANCE_CHANGE: + { + LE_UINT24_TO_ARRAY(&status_data[offset], param.target_distance); + } + break; + + case FTMS_STATUS_OP_TGT_TRAIN_TIME_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_training_time); + } + break; + + case FTMS_STATUS_OP_TWO_HR_ZONE_TIME_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_two_zones_hr_time.fat_burn_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_two_zones_hr_time.fat_burn_zone_time); + } + break; + + case FTMS_STATUS_OP_THREE_HR_ZONE_TIME_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_three_zones_hr_time.light_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_three_zones_hr_time.moderate_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_three_zones_hr_time.hard_zone_time); + } + break; + + case FTMS_STATUS_OP_FIVE_HR_ZONE_TIME_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_five_zones_hr_time.very_light_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_five_zones_hr_time.light_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_five_zones_hr_time.moderate_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_five_zones_hr_time.hard_zone_time); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.target_five_zones_hr_time.maximum_zone_time); + } + break; + + case FTMS_STATUS_OP_IB_SIMULATE_PARAM_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], + param.set_indoor_bike_simulation_param.wind_speed); + offset += 2; + LE_UINT16_TO_ARRAY(&status_data[offset], + param.set_indoor_bike_simulation_param.grade); + offset += 2; + LE_UINT8_TO_ARRAY(&status_data[offset], + param.set_indoor_bike_simulation_param.rolling_resistance_coefficient); + offset += 1; + LE_UINT8_TO_ARRAY(&status_data[offset], + param.set_indoor_bike_simulation_param.wind_resistance_coefficient); + } + break; + + case FTMS_STATUS_OP_WHEEL_CIRCUMFERENCE_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.wheel_circumference); + } + break; + + case FTMS_STATUS_OP_SPIN_DOWN_STATUS: + { + status_data[offset] = param.spin_down_status_value; + } + break; + + case FTMS_STATUS_OP_TGT_CADENCE_CHANGE: + { + LE_UINT16_TO_ARRAY(&status_data[offset], param.target_cadence); + } + break; + + case FTMS_STATUS_OP_CONTROL_PERMISSION_LOST: + { +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + ftms_var.control_permission = false; +#endif + } + break; + + default: + { + ret = false; + PROFILE_PRINT_ERROR1("ftms_status_notify:invalid opcode 0x%x", opcode); + } + break; + } + + if (ret) + { + ret = server_send_data(conn_id, service_id, attrib_index, status_data, data_length, + GATT_PDU_TYPE_NOTIFICATION); + } + + + return ret; +} +#endif + +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT +static void ftms_ctl_pnt_display_rsp(T_FTMS_CONTROL_POINT *ftms_ctl_pnt_ptr) +{ + PROFILE_PRINT_INFO1("ftms cp response: req_op_code=0x%x", ftms_ctl_pnt_ptr->param[1]); + PROFILE_PRINT_INFO1("ftms rsp_code = 0x%x", ftms_ctl_pnt_ptr->param[2]); +} + +bool ftms_ctl_pnt_indication(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, + uint8_t rsp_code) +{ + bool ret = true; + + if (ftms_var.ftms_notify_indicate_flag.ftms_cp_indicate_enable == 0) + { + ret = false; + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESERVED; + PROFILE_PRINT_ERROR0("ftms_ctl_pnt_indication: FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_FTMS_CONTROL_POINT); + uint16_t attrib_index = p_char->char_index; + + ftms_var.ftms_control_point.param[1] = opcode; + ftms_var.ftms_control_point.param[2] = rsp_code; + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESPONSE_CODE; + + if (opcode == FTMS_CP_OPCODE_SPIN_DOWN_CTRL) + { +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + uint8_t offset = 3; + ftms_var.ftms_control_point.cur_length = 3 * sizeof(uint8_t) + + sizeof(T_FTMS_SPIN_DOWN_RESP_PARAM); + LE_UINT16_TO_ARRAY(&ftms_var.ftms_control_point.param[offset], + ftms_var.ftms_sd_rsp_param.target_speed_low); + offset += 2; + LE_UINT16_TO_ARRAY(&ftms_var.ftms_control_point.param[offset], + ftms_var.ftms_sd_rsp_param.target_speed_high); +#endif + } + else + { + ftms_var.ftms_control_point.cur_length = 3 * sizeof(uint8_t); + } + + ftms_ctl_pnt_display_rsp(&ftms_var.ftms_control_point); + + if (server_send_data(conn_id, service_id, attrib_index, ftms_var.ftms_control_point.param, + ftms_var.ftms_control_point.cur_length, GATT_PDU_TYPE_INDICATION)) + { + PROFILE_PRINT_INFO0("ftms_ctl_pnt_indication:server_send_data and set status doing success"); + } + else + { + ret = false; + PROFILE_PRINT_ERROR0("ftms_ctl_pnt_indication:server_send_data fail"); + } + + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESERVED; + return ret; +} + +static void ftms_ctl_pnt_request_control(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = FTMS_CP_OPCODE_REQUEST_CONTROL; + ftms_var.control_permission = true; + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} + +static void ftms_ctl_pnt_reset(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = FTMS_CP_OPCODE_RESET; + ftms_var.ftms_cur_status = 0; + ftms_var.control_permission = false; + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} + +static void ftms_ctl_pnt_start_resume(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = FTMS_CP_OPCODE_START_RESUME; + if (ftms_var.ftms_cur_status == FTMS_STATUS_START_RESUME) + { + rsp_code = FTMS_CP_RSPCODE_OPERATION_FAILED; + } + else + { + ftms_var.ftms_cur_status = FTMS_STATUS_START_RESUME; + } + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} + +static void ftms_ctl_pnt_stop_pause(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = FTMS_CP_OPCODE_STOP_PAUSE; + if (ftms_var.ftms_cur_status == FTMS_STATUS_STOP_PAUSE) + { + rsp_code = FTMS_CP_RSPCODE_OPERATION_FAILED; + } + else + { + ftms_var.ftms_cur_status = FTMS_STATUS_STOP_PAUSE; + } + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} + +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT +static void ftms_ctl_pnt_spin_down_ctrl(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = FTMS_CP_OPCODE_SPIN_DOWN_CTRL; + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} +#endif + +static void ftms_ctl_pnt_write_target_data(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code, + uint8_t rsp_code) +{ + ftms_ctl_pnt_indication(conn_id, service_id, op_code, rsp_code); +} + +static uint8_t ftms_handle_ctl_pnt_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t write_length, uint8_t *p_value) +{ + T_FTMS_CALLBACK_DATA callback_data; + T_SRV_UUID_TBL *p_char; + p_char = srv_find_uuid_by_index(ftms_var.ftms_srv_char_tbl, attrib_index); + uint8_t resp_code = FTMS_CP_RSPCODE_SUCCESS; + uint16_t parameter_length = 0; + uint8_t offset = 1; + + memcpy(ftms_var.ftms_control_point.param, p_value, write_length); + callback_data.conn_id = conn_id; + callback_data.char_uuid = p_char->char_uuid16; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = ftms_var.ftms_control_point.param[0]; + + if (write_length >= 1) + { + parameter_length = write_length - 1; + } + + if (ftms_var.ftms_control_point.param[0] == FTMS_CP_OPCODE_REQUEST_CONTROL) + { + if (parameter_length == 0) + { + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + switch (ftms_var.ftms_control_point.param[0]) + { + case FTMS_CP_OPCODE_RESET: + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 0) + { + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + break; + + case FTMS_CP_OPCODE_START_RESUME: + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 0) + { + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + break; + + case FTMS_CP_OPCODE_STOP_PAUSE: + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.ctrl_information, + &ftms_var.ftms_control_point.param[offset], 1); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_SPEED: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_SPEED_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_speed, + &ftms_var.ftms_control_point.param[offset]); + if ((callback_data.msg_data.write.cp_parameter.target_speed > + ftms_var.support_speed_range.max_speed) || + (callback_data.msg_data.write.cp_parameter.target_speed < + ftms_var.support_speed_range.min_speed)) + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_INCLINATION: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_INCLINATION_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_inclination, + &ftms_var.ftms_control_point.param[offset]); + if ((callback_data.msg_data.write.cp_parameter.target_inclination > + ftms_var.support_inclination_range.max_inclination) || + (callback_data.msg_data.write.cp_parameter.target_inclination < + ftms_var.support_inclination_range.min_inclination)) + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_RESISTANCE_LEVEL: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_RESISTANCE_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_resistance_level, + &ftms_var.ftms_control_point.param[offset]); + if ((callback_data.msg_data.write.cp_parameter.target_resistance_level > + ftms_var.support_resistance_level_range.max_resistance_level) || + (callback_data.msg_data.write.cp_parameter.target_resistance_level < + ftms_var.support_resistance_level_range.min_resistance_level)) + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_POWER: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_POWER_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_power, + &ftms_var.ftms_control_point.param[offset]); + if ((callback_data.msg_data.write.cp_parameter.target_power > + ftms_var.support_power_range.max_power) || + (callback_data.msg_data.write.cp_parameter.target_power < + ftms_var.support_power_range.min_power)) + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_HEART_RATE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_SET_HR_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 1) + { + callback_data.msg_data.write.cp_parameter.target_heart_rate = + ftms_var.ftms_control_point.param[offset]; + if ((callback_data.msg_data.write.cp_parameter.target_heart_rate > + ftms_var.support_heart_rate_range.max_heart_rate) || + (callback_data.msg_data.write.cp_parameter.target_heart_rate < + ftms_var.support_heart_rate_range.min_heart_rate)) + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_EXPEND_ENERGY: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_EXPENDED_ENERGY_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_expended_energy, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_STEP_NUM: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_STEP_NUM_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_step_num, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_STRIDE_NUM: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_STRIDE_NUM_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_stride_num, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_DISTANCE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_DISTANCE_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 3) + { + LE_ARRAY_TO_UINT24(callback_data.msg_data.write.cp_parameter.target_distance, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_TRAINING_TIME: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_TRAINING_TIME_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_training_time, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_TWO_HR_ZONES_TIME: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_TWO_HR_ZONES_TIME_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 4) + { + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_two_zones_hr_time.fat_burn_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_two_zones_hr_time.fitness_zones_time, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_THREE_HR_ZONES_TIME: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_THREE_HR_ZONES_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 6) + { + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_three_zones_hr_time.light_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_three_zones_hr_time.moderate_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_three_zones_hr_time.hard_zone_time, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_TGT_FIVE_HR_ZONES_TIME: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_FIVE_HR_ZONES_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 10) + { + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_five_zones_hr_time.very_light_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_five_zones_hr_time.light_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_five_zones_hr_time.moderate_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_five_zones_hr_time.hard_zone_time, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.target_five_zones_hr_time.maximum_zone_time, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + case FTMS_CP_OPCODE_SET_INDOOR_BIKE_SIMULATION_PARAM: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_INDOOR_BIKE_SIMULATION_PARAM_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 6) + { + LE_ARRAY_TO_UINT16( + callback_data.msg_data.write.cp_parameter.set_indoor_bike_simulation_param.wind_speed, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.set_indoor_bike_simulation_param.grade, + &ftms_var.ftms_control_point.param[offset]); + offset += 2; + LE_ARRAY_TO_UINT8( + callback_data.msg_data.write.cp_parameter.set_indoor_bike_simulation_param.rolling_resistance_coefficient, + &ftms_var.ftms_control_point.param[offset]); + offset += 1; + LE_ARRAY_TO_UINT8( + callback_data.msg_data.write.cp_parameter.set_indoor_bike_simulation_param.wind_resistance_coefficient, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + +#if FTMS_CHAR_CP_SET_WHEEL_CIRCUMFERENCE_SUPPORT + case FTMS_CP_OPCODE_SET_WHEEL_CIRCUMFERENCE: + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.wheel_circumference, + &ftms_var.ftms_control_point.param[offset]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + + } + + } + break; +#endif + +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + case FTMS_CP_OPCODE_SPIN_DOWN_CTRL: + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.ctrl_param, + &ftms_var.ftms_control_point.param[offset], 1); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + break; +#endif + + case FTMS_CP_OPCODE_SET_TGT_CADENCE: + { + if (ftms_var.ftms_feature.target_setting_field & FTMS_TGT_CADENCE_CONFIG_SPT_MASK) + { + if (!ftms_var.control_permission) + { + resp_code = FTMS_CP_RSPCODE_CONTROL_NOT_PERMITTED; + } + else + { + if (parameter_length == 2) + { + LE_ARRAY_TO_UINT16(callback_data.msg_data.write.cp_parameter.target_cadence, + &ftms_var.ftms_control_point.param[1]); + } + else + { + resp_code = FTMS_CP_RSPCODE_INVALID_PARAMETER; + } + } + } + else + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + } + break; + + default: + { + resp_code = FTMS_CP_RSPCODE_OPCODE_NOT_SUPPORT; + } + break; + } + } + + if (resp_code == FTMS_CP_RSPCODE_SUCCESS) + { + pfn_ftms_cb(service_id, (void *)&callback_data); + } + + return resp_code; +} + +static void ftms_ctl_pnt_handle_req(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t write_length, uint8_t *p_value) +{ + uint8_t resp_code = FTMS_CP_RSPCODE_SUCCESS; + memcpy(ftms_var.ftms_control_point.param, p_value, write_length); + ftms_var.ftms_control_point.cur_length = write_length; + resp_code = ftms_handle_ctl_pnt_proc(conn_id, service_id, attrib_index, write_length, p_value); + + if (resp_code == FTMS_CP_RSPCODE_SUCCESS) + { + switch (ftms_var.ftms_control_point.param[0]) + { + case FTMS_CP_OPCODE_REQUEST_CONTROL: + { + ftms_ctl_pnt_request_control(conn_id, service_id, resp_code); + } + break; + + case FTMS_CP_OPCODE_RESET: + { + ftms_ctl_pnt_reset(conn_id, service_id, resp_code); + } + break; + + case FTMS_CP_OPCODE_START_RESUME: + { + ftms_ctl_pnt_start_resume(conn_id, service_id, resp_code); + } + break; + + case FTMS_CP_OPCODE_STOP_PAUSE: + { + ftms_ctl_pnt_stop_pause(conn_id, service_id, resp_code); + } + break; +#if FTMS_CHAR_CP_SPIN_DOWN_CTRL_SUPPORT + case FTMS_CP_OPCODE_SPIN_DOWN_CTRL: + { + ftms_ctl_pnt_spin_down_ctrl(conn_id, service_id, resp_code); + } + break; +#endif + + default: + { + ftms_ctl_pnt_write_target_data(conn_id, service_id, + ftms_var.ftms_control_point.param[0], resp_code); + } + break; + } + } + else + { + ftms_ctl_pnt_indication(conn_id, service_id, ftms_var.ftms_control_point.param[0], resp_code); + } +} +#endif + + +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT +bool ftms_train_status_notify(uint8_t conn_id, T_SERVER_ID service_id, uint16_t string_len, + T_FTMS_TRAIN_STATUS *p_train_status_data) +{ + bool ret = false; + + if (ftms_var.ftms_notify_indicate_flag.ftms_train_status_notify_enable == 0) + { + PROFILE_PRINT_INFO0("ftms_train_status_notify: FTMS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_TRAINING_STATUS); + uint16_t attrib_index = p_char->char_index; + uint8_t *p_data = NULL; + uint16_t data_len = 0; + uint8_t offset = 0; + uint8_t *p; + + uint16_t mtu_size; + le_get_conn_param(GAP_PARAM_CONN_MTU_SIZE, &mtu_size, conn_id); + + if (p_train_status_data->flag & FTMS_TS_STRING_PRESENT_MASK) + { + if (string_len && p_train_status_data->train_status_string == NULL) + { + PROFILE_PRINT_ERROR0("ftms_train_status_notify: no training status string!"); + return ret; + } + + if (string_len <= (mtu_size - 5)) + { + data_len = string_len + 2 * sizeof(uint8_t); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_len); + p_train_status_data->flag &= (~FTMS_TS_EXTENDED_STRING_PRESENT_MASK); + + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->flag); + offset += 1; + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->train_status); + offset += 1; + memcpy(p_data + offset, p_train_status_data->train_status_string, string_len); + } + else + { + data_len = mtu_size - 3; + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_len); + p_train_status_data->flag |= FTMS_TS_EXTENDED_STRING_PRESENT_MASK; + + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->flag); + offset += 1; + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->train_status); + offset += 1; + memcpy(p_data + offset, p_train_status_data->train_status_string, string_len); + } + } + else + { + data_len = 2 * sizeof(uint8_t); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_len); + p_train_status_data->flag &= (~FTMS_TS_EXTENDED_STRING_PRESENT_MASK); + + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->flag); + offset += 1; + p = p_data + offset; + LE_UINT8_TO_STREAM(p, p_train_status_data->train_status); + offset += 1; + } + + if (server_send_data(conn_id, service_id, attrib_index, p_data, data_len, + GATT_PDU_TYPE_NOTIFICATION)) + { + ret = true; + PROFILE_PRINT_INFO0("ftms_train_status_notify:server_send_data and set status doing success"); + } + else + { + PROFILE_PRINT_ERROR0("ftms_train_status_notify:server_send_data fail"); + } + + if (p_data != NULL) + { + os_mem_free(p_data); + } + + return ret; +} + +bool ftms_train_status_read_confirm(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t *p_data, uint16_t len, T_APP_RESULT cause) +{ + T_SRV_UUID_TBL *p_char; + p_char = srv_find_index_by_uuid(ftms_var.ftms_srv_char_tbl, GATT_UUID_TRAINING_STATUS); + uint16_t attrib_index = p_char->char_index; + + return server_attr_read_confirm(conn_id, service_id, attrib_index, p_data, len, cause); +} +#endif + +T_APP_RESULT ftms_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_SRV_UUID_TBL *p_char; + p_char = srv_find_uuid_by_index(ftms_var.ftms_srv_char_tbl, attrib_index); + + uint8_t *p_data = NULL; + uint8_t *p; + uint16_t data_length = 0; + + PROFILE_PRINT_INFO1("ftms_attr_read_cb: char_uuid16 0x%x", p_char->char_uuid16); + + switch (p_char->char_uuid16) + { + case GATT_UUID_FITNESS_MACHINE_FEATURE: + { + data_length = sizeof(ftms_var.ftms_feature); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT32_TO_STREAM(p, ftms_var.ftms_feature.features_field); + LE_UINT32_TO_STREAM(p, ftms_var.ftms_feature.target_setting_field); + } + break; + +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT + case GATT_UUID_TRAINING_STATUS: + { + T_FTMS_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.char_uuid = GATT_UUID_TRAINING_STATUS; + + cause = pfn_ftms_cb(service_id, &callback_data); + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_SPEED_RANGE_SUPPORT + case GATT_UUID_SUPPORT_SPEED_RANGE: + { + data_length = sizeof(ftms_var.support_speed_range); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT16_TO_STREAM(p, ftms_var.support_speed_range.min_speed); + LE_UINT16_TO_STREAM(p, ftms_var.support_speed_range.max_speed); + LE_UINT16_TO_STREAM(p, ftms_var.support_speed_range.min_speed_increment); + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_INCLINATION_RANGE_SUPPORT + case GATT_UUID_SUPPORT_INCLINATION_RANGE: + { + data_length = sizeof(ftms_var.support_inclination_range); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT16_TO_STREAM(p, ftms_var.support_inclination_range.min_inclination); + LE_UINT16_TO_STREAM(p, ftms_var.support_inclination_range.max_inclination); + LE_UINT16_TO_STREAM(p, ftms_var.support_inclination_range.min_inclination_increment); + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_RESISTANCE_LEVEL_RANGE_SUPPORT + case GATT_UUID_SUPPORT_RESISTANCE_LEVEL_RANGE: + { + data_length = sizeof(ftms_var.support_resistance_level_range); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT16_TO_STREAM(p, ftms_var.support_resistance_level_range.min_resistance_level); + LE_UINT16_TO_STREAM(p, ftms_var.support_resistance_level_range.max_resistance_level); + LE_UINT16_TO_STREAM(p, ftms_var.support_resistance_level_range.min_resistance_level_increment); + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_HR_RANGE_SUPPORT + case GATT_UUID_SUPPORT_HEART_RATE_RANGE: + { + data_length = sizeof(ftms_var.support_heart_rate_range); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT8_TO_STREAM(p, ftms_var.support_heart_rate_range.min_heart_rate); + LE_UINT8_TO_STREAM(p, ftms_var.support_heart_rate_range.max_heart_rate); + LE_UINT8_TO_STREAM(p, ftms_var.support_heart_rate_range.min_hr_increment); + } + break; +#endif + +#if FTMS_CHAR_SUPPORT_POWER_RANGE_SUPPORT + case GATT_UUID_SUPPORT_POWER_RANGE: + { + data_length = sizeof(ftms_var.support_power_range); + p_data = os_mem_zalloc(RAM_TYPE_DATA_ON, data_length); + p = p_data; + LE_UINT16_TO_STREAM(p, ftms_var.support_power_range.min_power); + LE_UINT16_TO_STREAM(p, ftms_var.support_power_range.max_power); + LE_UINT16_TO_STREAM(p, ftms_var.support_power_range.min_power_increment); + } + break; +#endif + + default: + { + cause = APP_RESULT_ATTR_NOT_FOUND; + PROFILE_PRINT_ERROR1("ftms_attr_read_cb Error not found attribute char_uuid 0x%x", + p_char->char_uuid16); + } + break; + } + + if (cause == APP_RESULT_SUCCESS) + { + if (server_attr_read_confirm(conn_id, service_id, attrib_index, p_data, + data_length, APP_RESULT_SUCCESS)) + { + cause = APP_RESULT_PENDING; + } + + if (p_data != NULL) + { + os_mem_free(p_data); + } + } + + return cause; +} + +T_APP_RESULT ftms_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_SRV_UUID_TBL *p_char; + p_char = srv_find_uuid_by_index(ftms_var.ftms_srv_char_tbl, attrib_index); + + PROFILE_PRINT_INFO2("ftms_attr_write_cb:attrib_index %d, char_uuid16 0x%x", + attrib_index, p_char->char_uuid16); + +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + if (p_char->char_uuid16 == GATT_UUID_FTMS_CONTROL_POINT) + { + if ((length > FTMS_MAX_CTL_PNT_PARAM_LEN) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else if (FTMS_CTL_PNT_OPERATE_ACTIVE(ftms_var.ftms_control_point.param[0])) + { + cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS; + } + /* Make sure Control Point is configured indication enable. */ + else if (false == ftms_var.ftms_notify_indicate_flag.ftms_cp_indicate_enable) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + else + { + *p_write_ind_post_proc = ftms_ctl_pnt_handle_req; + } + } + else + { + PROFILE_PRINT_ERROR2("ftms_attr_write_cb Error char_uuid16 0x%x, length %d", + p_char->char_uuid16, length); + cause = APP_RESULT_ATTR_NOT_FOUND; + } +#endif + + return cause; +} + +void ftms_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_FTMS_CALLBACK_DATA callback_data; + bool handle = true; + T_SRV_UUID_TBL *p_char; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + p_char = srv_find_uuid_by_index(ftms_var.ftms_srv_char_tbl, index - 1); + + PROFILE_PRINT_INFO2("ftms_cccd_update_cb:char_uuid16 0x%x ccc_bits %x", p_char->char_uuid16, + ccc_bits); + + switch (p_char->char_uuid16) + { +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + case GATT_UUID_TREADMILL_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_treadmill_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_TREADMILL_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_TREADMILL_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_treadmill_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_TREADMILL_DATA_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + case GATT_UUID_CROSS_TRAINER_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_cross_trainer_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_CROSS_TRAINER_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_CROSS_TRAINER_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_cross_trainer_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_CROSS_TRAINER_DATA_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + case GATT_UUID_STEP_CLIMBER_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_step_climber_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_step_climber_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + case GATT_UUID_STAIR_CLIMBER_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_stair_climber_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_STAIR_CLIMBER_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_STEP_CLIMBER_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_stair_climber_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_STAIR_CLIMBER_DATA_DISABLE; + } + + } + break; +#endif +#if FTMS_CHAR_ROWER_DATA_SUPPORT + case GATT_UUID_ROWER_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_rower_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_ROWER_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_ROWER_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_rower_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_ROWER_DATA_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT + case GATT_UUID_INDOOR_BIKE_DATA: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_indoor_bike_data_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_INDOOR_BIKE_DATA_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_INDOOR_BIKE_DATA_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_indoor_bike_data_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_INDOOR_BIKE_DATA_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + case GATT_UUID_FTMS_CONTROL_POINT: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + ftms_var.ftms_notify_indicate_flag.ftms_cp_indicate_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_FTMS_CP_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_FTMS_CP_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_cp_indicate_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_FTMS_CP_DISABLE; + } + } + break; +#endif +#if FTMS_CHAR_TRAINING_STATUS_SUPPORT + case GATT_UUID_TRAINING_STATUS: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_train_status_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_TRAIN_STATUS_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_TRAIN_STATUS_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_train_status_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_TRAIN_STATUS_DISABLE; + } + } + break; +#endif +#if (FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT || FTMS_CHAR_CP_SET_WHEEL_CIRCUMFERENCE_SUPPORT) + case GATT_UUID_FITNESS_MACHINE_STATUS: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + ftms_var.ftms_notify_indicate_flag.ftms_status_notify_enable = 1; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_FTMS_STATUS_ENABLE; + PROFILE_PRINT_INFO0("ftms_cccd_update_cb: FTMS_NOTIFY_INDICATE_FTMS_STATUS_ENABLE"); + } + else + { + ftms_var.ftms_notify_indicate_flag.ftms_status_notify_enable = 0; + callback_data.msg_data.notification_indication_index = + FTMS_NOTIFY_INDICATE_FTMS_STATUS_DISABLE; + } + } + break; +#endif + + default: + { + handle = false; + PROFILE_PRINT_ERROR1("ftms_cccd_update_cb: char_uuid16 0x%x", p_char->char_uuid16); + } + break; + } + + if (pfn_ftms_cb && (handle == true)) + { + pfn_ftms_cb(service_id, (void *)&callback_data); + } +} + +void ftms_flags_clear(void) +{ + PROFILE_PRINT_ERROR0("ftms_flags_clear"); + +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + memset(&ftms_var.ftms_treadmill_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_treadmill_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_notify_data); + ftms_var.ftms_treadmill_notify_data = NULL; + } + + if (ftms_var.ftms_treadmill_send_data != NULL) + { + os_mem_free(ftms_var.ftms_treadmill_send_data); + ftms_var.ftms_treadmill_send_data = NULL; + } + +#endif + +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + memset(&ftms_var.ftms_step_climber_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_step_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_notify_data); + ftms_var.ftms_step_climber_notify_data = NULL; + } + + if (ftms_var.ftms_step_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_step_climber_send_data); + ftms_var.ftms_step_climber_send_data = NULL; + } +#endif + +#if FTMS_CHAR_ROWER_DATA_SUPPORT + memset(&ftms_var.ftms_rower_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_rower_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_notify_data); + ftms_var.ftms_rower_notify_data = NULL; + } + + if (ftms_var.ftms_rower_send_data != NULL) + { + os_mem_free(ftms_var.ftms_rower_send_data); + ftms_var.ftms_rower_send_data = NULL; + } +#endif + +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT + memset(&ftms_var.ftms_indoor_bike_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_indoor_bike_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_notify_data); + ftms_var.ftms_indoor_bike_notify_data = NULL; + } + + if (ftms_var.ftms_indoor_bike_send_data != NULL) + { + os_mem_free(ftms_var.ftms_indoor_bike_send_data); + ftms_var.ftms_indoor_bike_send_data = NULL; + } +#endif + +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + memset(&ftms_var.ftms_cross_trainer_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_cross_trainer_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_notify_data); + ftms_var.ftms_cross_trainer_notify_data = NULL; + } + + if (ftms_var.ftms_cross_trainer_send_data != NULL) + { + os_mem_free(ftms_var.ftms_cross_trainer_send_data); + ftms_var.ftms_cross_trainer_send_data = NULL; + } +#endif + +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + memset(&ftms_var.ftms_stair_climber_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); + if (ftms_var.ftms_stair_climber_notify_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_notify_data); + ftms_var.ftms_stair_climber_notify_data = NULL; + } + + if (ftms_var.ftms_stair_climber_send_data != NULL) + { + os_mem_free(ftms_var.ftms_stair_climber_send_data); + ftms_var.ftms_stair_climber_send_data = NULL; + } +#endif + +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESERVED; + ftms_var.control_permission = false; + ftms_var.ftms_cur_status = 0; +#endif +} + +const T_FUN_GATT_SERVICE_CBS ftms_cbs = +{ + ftms_attr_read_cb, // Read callback function pointer + ftms_attr_write_cb, // Write callback function pointer + ftms_cccd_update_cb // CCCD update callback function pointer +}; + +T_SERVER_ID ftms_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)ftms_att_tbl, + ftms_attr_tbl_size, + ftms_cbs)) + { + PROFILE_PRINT_ERROR1("ftms_add_service: service_id %d", service_id); + service_id = 0xff; + return service_id; + } + + ftms_var.ftms_srv_char_tbl = srv_uuid_create_tbl(ftms_att_tbl, ftms_attr_tbl_size); +#if FTMS_CHAR_FTMS_CTRL_PNT_SUPPORT + ftms_var.control_permission = false; + ftms_var.ftms_control_point.cur_length = 0; + ftms_var.ftms_control_point.param[0] = FTMS_CP_OPCODE_RESERVED; +#endif +#if FTMS_CHAR_TREADMILL_DATA_SUPPORT + memset(&ftms_var.ftms_treadmill_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif +#if FTMS_CHAR_STEP_CLIMBER_DATA_SUPPORT + memset(&ftms_var.ftms_step_climber_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif +#if FTMS_CHAR_ROWER_DATA_SUPPORT + memset(&ftms_var.ftms_rower_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif +#if FTMS_CHAR_INDOOR_BIKE_DATA_SUPPORT + memset(&ftms_var.ftms_indoor_bike_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif +#if FTMS_CHAR_CROSS_TRAINER_DATA_SUPPORT + memset(&ftms_var.ftms_cross_trainer_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif +#if FTMS_CHAR_STAIR_CLIMBER_DATA_SUPPORT + memset(&ftms_var.ftms_stair_climber_notify_flag, 0, sizeof(T_FTMS_NOTIFY_FLAG)); +#endif + + pfn_ftms_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + + return service_id; +} + +/** + * @brief Prepare a new record in database. + * @return void. + * + */ diff --git a/src/ble/profile/server/ghss_gatt_srv.c b/src/ble/profile/server/ghss_gatt_srv.c new file mode 100644 index 0000000..0df0ece --- /dev/null +++ b/src/ble/profile/server/ghss_gatt_srv.c @@ -0,0 +1,1462 @@ +/**************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rigghss reserved. +***************************************************************************************** + + * @file ghss.c + * @brief Generic Health Sensor Service source file. + * @details Interface to access the Generic Health Sensor Service. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ +#include "trace.h" +#include +#include "profile_server.h" +#include "ghss_gatt_srv.h" +#include "bt_types.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + uint8_t ghss_live_obs_notify_indicate_enable: 1; + uint8_t ghss_stored_obs_notify_indicate_enable: 1; + uint8_t ghss_racp_indicate_enable: 1; + uint8_t ghss_ghs_cp_indicate_enable: 1; + uint8_t rfu: 4; +} T_GHSS_NOTIFY_INDICATE_FLAG; + +/**< Function pointer used to send event to application from GHSS profile. */ +static P_FUN_GHSS_SERVER_APP_CB pfn_ghss_cb = NULL; + +T_GHSS_NOTIFY_INDICATE_FLAG ghss_notify_indicate_flag = {0}; + +/** @brief profile/service definition. */ +const T_ATTRIB_APPL ghss_attr_tbl[] = +{ + /* <> */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_GENERIC_HEALTH_SENSOR), /* service UUID */ + HI_WORD(GATT_UUID_GENERIC_HEALTH_SENSOR) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), +#if (GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT && GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT) + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_INDICATE +#elif GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT + GATT_CHAR_PROP_NOTIFY +#elif GHSS_CHAR_LIVE_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT + GATT_CHAR_PROP_INDICATE +#endif + /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Live Health Observations characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS), + HI_WORD(GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), +#if (GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT && GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT) + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_INDICATE +#elif GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_NOTIFY_SUPPORT + GATT_CHAR_PROP_NOTIFY +#elif GHSS_CHAR_STORED_GHSS_HEALTH_OBS_PROP_INDICATE_SUPPORT + GATT_CHAR_PROP_INDICATE +#endif + /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Stored Health Observations characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS), + HI_WORD(GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Record Access Control Point characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT) + }, + 0, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* <> */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Health Sensor Features characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_GHS_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_GHS_CONTROL_POINT) + }, + 0, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +}; + +/**< @brief Generic Health Sensor Service size definition. */ +const uint16_t ghss_char_num = sizeof(ghss_attr_tbl) / sizeof(T_ATTRIB_APPL); + +uint16_t ghss_format_health_obs_body_optional_value_length(T_GHSS_HEALTH_OBS_BODY *p_value) +{ + uint16_t val_len = 0; + T_GHSS_HOB_FLAGS flags = p_value->flags; + + // Mandatory for all single observations but not for observation bundles. + if (flags.observation_type_present) + { + val_len += 4; + } + + // Stored observations shall have a time stamp. Live observations optional. + if (flags.time_stamp_present) + { + val_len += (1 + 6 + 1 + 1); + } + + if (flags.measurement_duration_present) + { + val_len += 4; + } + + if (flags.measurement_status_present) + { + val_len += 2; + } + + if (flags.observation_id_present) + { + val_len += 4; + } + + if (flags.patient_present) + { + val_len += 1; + } + + if (flags.supplemental_information_present) + { + uint8_t count = p_value->suppl_info.count; + val_len += 1; + + if (count) + { + val_len += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_value_length: Invalid supplemental information count %d", + count); + return 0; + } + } + + if (flags.derived_from_present) + { + uint8_t count = p_value->derived_from.count; + val_len += 1; + + if (count) + { + val_len += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_value_length: Invalid derived from count %d", + count); + return 0; + } + } + + if (flags.is_member_of_present) + { + uint8_t count = p_value->is_mem_of.count; + val_len += 1; + + if (count) + { + val_len += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_value_length: Invalid is member of count %d", + count); + return 0; + } + } + + if (flags.tlvs_present) + { + uint8_t num_of_tlv_attr = p_value->tlvs.num_of_tlv_attr; + val_len += 1; + + for (uint8_t i = 0; i < num_of_tlv_attr; i++) + { + val_len += (4 + 2 + 1); + uint16_t length = p_value->tlvs.p_tlvs_value[i].length; + val_len += length; + } + } + + return val_len; +} + +uint16_t ghss_format_health_obs_body_obs_value_length(T_GHSS_HOB_CLASS_TYPE type, + T_GHSS_HOB_VALUE *p_value) +{ + uint16_t val_len = 0; + + // Mandatory part + switch (type) + { + case GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION: + { + val_len += (2 + 4); + } + break; + + case GHSS_HOB_CLASS_TYPE_SIMPLE_DISCRETE_OBSERVATION: + { + val_len += 4; + } + break; + + case GHSS_HOB_CLASS_TYPE_STRING_OBSERVATION: + { + T_GHSS_HOBV_STRING_OBS *p_obs_value = &p_value->string_obs; + uint16_t length = p_obs_value->length; + val_len += (2 + length); + } + break; + + case GHSS_HOB_CLASS_TYPE_SAMPLE_ARRAY_OBSERVATION: + { + T_GHSS_HOBV_SAMPLE_ARRAY_OBS *p_obs_value = &p_value->sample_array_obs; + val_len += (2 + 4 + 4 + 4 + 1 + 1 + 4); + uint8_t bytes = p_obs_value->bytes_per_period; + uint32_t number = p_obs_value->number_of_samples; + val_len += (bytes * number); + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_DISCRETE_EVENT_OBSERVATION: + { + T_GHSS_HOBV_COMPOUND_DISCRETE_EVENT_OBS *p_obs_value = &p_value->compound_discrete_event_obs; + uint8_t number = p_obs_value->number_of_components; + val_len += 1; + val_len += (4 * number); + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_STATE_EVENT_OBSERVATION: + { + T_GHSS_HOBV_COMPOUND_STATE_EVENT_OBS *p_obs_value = &p_value->compound_state_event_obs; + uint8_t size = p_obs_value->size; + val_len += 1; + val_len += (3 * size); + } + break; + + case GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION: //only for obs_bdl_value + { + T_GHSS_HOB_TLVS *p_obs_value = &p_value->tlv_encoded_obs; + uint8_t number = + p_obs_value->num_of_tlv_attr; + val_len += 1; + for (uint8_t i = 0; i < number; i++) + { + val_len += (4 + 2 + 1); + uint16_t length = + p_obs_value->p_tlvs_value[i].length; + val_len += length; + } + } + break; + + default: + APP_PRINT_ERROR1("ghss_format_health_obs_body_obs_value_length: Invalid Observation Class Type %d", + type); + return 0; + } + + return val_len; +} + +uint16_t ghss_format_health_obs_body_length(T_GHSS_HEALTH_OBS_BODY *p_value) +{ + uint16_t total_len = 0; + uint16_t err_idx = 0; + + APP_PRINT_INFO1("ghss_format_health_obs_body_length: Observation Class Type %d", + p_value->obs_class_type); + + // Mandatory part: obs_class_type & flags + total_len += (1 + 2); + + uint16_t value_len = ghss_format_health_obs_body_optional_value_length(p_value); + if (value_len == 0) + { + err_idx = 1; + goto error; + } + total_len += value_len; + + // Mandatory part + switch (p_value->obs_class_type) + { + case GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_SIMPLE_DISCRETE_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_STRING_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_SAMPLE_ARRAY_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_COMPOUND_DISCRETE_EVENT_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_COMPOUND_STATE_EVENT_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION: //only for obs_bdl_value + { + value_len = ghss_format_health_obs_body_obs_value_length(p_value->obs_class_type, + &p_value->obs_value); + if (value_len == 0) + { + err_idx = 2; + goto error; + } + total_len += value_len; + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_OBSERVATION: + { + uint8_t number = + p_value->obs_value.compound_obs.number_of_components; + total_len += 1; + + for (uint8_t i = 0; i < number; i++) + { + total_len += (4 + 1); + T_GHSS_HOB_VALUE *p_obs_value = (T_GHSS_HOB_VALUE *) + p_value->obs_value.compound_obs.p_component_value[i].p_value; + T_GHSS_HOB_CLASS_TYPE obs_type = + p_value->obs_value.compound_obs.p_component_value[i].component_value_type; + value_len = ghss_format_health_obs_body_obs_value_length(obs_type, p_obs_value); + if (value_len == 0) + { + err_idx = 3; + goto error; + } + total_len += value_len; + } + } + break; + + case GHSS_HOB_CLASS_TYPE_OBSERVATION_BUNDLE: + { + uint8_t number = p_value->obs_value.obs_bundle.number_of_obs; + total_len += 1; + + for (uint8_t n = 0; n < number; n++) + { + T_GHSS_HEALTH_OBS_BODY *p_obs_bdl_value = (T_GHSS_HEALTH_OBS_BODY *) + p_value->obs_value.obs_bundle.p_obs_bdl_value + n; + // Mandatory part: obs_class_type & flags + total_len += (1 + 2); + + value_len = ghss_format_health_obs_body_optional_value_length(p_obs_bdl_value); + + if (value_len == 0) + { + err_idx = 4; + goto error; + } + total_len += value_len; + + T_GHSS_HOB_VALUE *p_obs_value = (T_GHSS_HOB_VALUE *)&p_obs_bdl_value->obs_value; + + if (p_obs_bdl_value->obs_class_type == GHSS_HOB_CLASS_TYPE_COMPOUND_OBSERVATION) + { + uint8_t number = + p_obs_value->compound_obs.number_of_components; + total_len += 1; + + for (uint8_t i = 0; i < number; i++) + { + total_len += (4 + 1); + T_GHSS_HOB_VALUE *p_obs_components_value = (T_GHSS_HOB_VALUE *) + p_obs_value->compound_obs.p_component_value[i].p_value; + T_GHSS_HOB_CLASS_TYPE obs_components_type = + p_obs_value->compound_obs.p_component_value[i].component_value_type; + value_len = ghss_format_health_obs_body_obs_value_length(obs_components_type, + p_obs_components_value); + if (value_len == 0) + { + err_idx = 5; + goto error; + } + total_len += value_len; + } + } + else + { + value_len = ghss_format_health_obs_body_obs_value_length(p_obs_bdl_value->obs_class_type, + p_obs_value); + if (value_len == 0) + { + err_idx = 6; + goto error; + } + total_len += value_len; + } + total_len += 2; //Add uint16_t length + } + } + break; + + default: + err_idx = 7; + goto error; + } + + total_len += 2; //Add uint16_t length + + return total_len; + +error: + APP_PRINT_ERROR2("ghss_format_health_obs_body_obs_value_length: Observation Class Type %d, ERR IDX %d", + p_value->obs_class_type, err_idx); + return 0; +} + +uint16_t ghss_format_health_obs_body_optional_sending_value(T_GHSS_HEALTH_OBS_BODY *p_value, + uint16_t offset, + uint8_t **pp_temp_value) +{ + T_GHSS_HOB_FLAGS flags = p_value->flags; + uint16_t current_offset = offset; + + // Mandatory for all single observations but not for observation bundles. + if (flags.observation_type_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->obs_type, 4); + current_offset += 4; + } + // Stored observations shall have a time stamp. Live observations optional. + if (flags.time_stamp_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->time_stamp.flags, 1); + current_offset += 1; + + current_offset += 6; + for (uint8_t i = 6; i > 0; i--) + { + memcpy(&(*pp_temp_value)[current_offset - i], + &p_value->time_stamp.time_value[i - 1], 1); + } + + memcpy(&(*pp_temp_value)[current_offset], + &p_value->time_stamp.time_sync_source_type, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->time_stamp.tz_dst_offset, 1); + current_offset += 1; + } + + if (flags.measurement_duration_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->meas_duration, 4); + current_offset += 4; + } + + if (flags.measurement_status_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->meas_status, 2); + current_offset += 2; + } + + if (flags.observation_id_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->obs_id, 4); + current_offset += 4; + } + + if (flags.patient_present) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->patient, 1); + current_offset += 1; + } + + if (flags.supplemental_information_present) + { + uint8_t count = p_value->suppl_info.count; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->suppl_info.count, 1); + current_offset += 1; + + if (count) + { + memcpy(&(*pp_temp_value)[current_offset], + p_value->suppl_info.p_codes, + 4 * count); + current_offset += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_sending_value: Invalid supplemental information count %d", + count); + return 0; + } + } + + if (flags.derived_from_present) + { + uint8_t count = p_value->derived_from.count; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->derived_from.count, 1); + current_offset += 1; + + if (count) + { + memcpy(&(*pp_temp_value)[current_offset], + p_value->derived_from.p_obs_ids, + 4 * count); + current_offset += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_sending_value: Invalid derived from count %d", + count); + return 0; + } + } + + if (flags.is_member_of_present) + { + uint8_t count = p_value->is_mem_of.count; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->is_mem_of.count, 1); + current_offset += 1; + + if (count) + { + memcpy(&(*pp_temp_value)[current_offset], + p_value->is_mem_of.p_mem_ids, + 4 * count); + current_offset += (4 * count); + } + else + { + APP_PRINT_ERROR1("ghss_format_health_obs_body_optional_sending_value: Invalid is member of count %d", + count); + return 0; + } + } + + if (flags.tlvs_present) + { + uint8_t num_of_tlv_attr = p_value->tlvs.num_of_tlv_attr; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->tlvs.num_of_tlv_attr, 1); + current_offset += 1; + + for (uint8_t i = 0; i < num_of_tlv_attr; i++) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->tlvs.p_tlvs_value[i].type, 4); + current_offset += 4; + uint16_t length = p_value->tlvs.p_tlvs_value[i].length; + memcpy(&(*pp_temp_value)[current_offset], + &length, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->tlvs.p_tlvs_value[i].format_type, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + p_value->tlvs.p_tlvs_value[i].p_encoded_value, + length); + current_offset += length; + } + } + + return current_offset; +} + +uint16_t ghss_format_health_obs_body_obs_sending_value(T_GHSS_HOB_CLASS_TYPE type, + T_GHSS_HOB_VALUE *p_value, uint16_t offset, uint8_t **pp_temp_value) +{ + uint16_t current_offset = offset; + + // Mandatory part + switch (type) + { + case GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION: + { + T_GHSS_HOBV_NUMERIC_OBS *p_obs_value = &p_value->numeric_obs; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->unit_code, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->value, 4); + current_offset += 4; + + } + break; + + case GHSS_HOB_CLASS_TYPE_SIMPLE_DISCRETE_OBSERVATION: + { + T_GHSS_HOBV_SIMPLE_DISCRETE_OBS *p_obs_value = &p_value->simple_discrete_obs; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->value, 4); + current_offset += 4; + } + break; + + case GHSS_HOB_CLASS_TYPE_STRING_OBSERVATION: + { + T_GHSS_HOBV_STRING_OBS *p_obs_value = &p_value->string_obs; + uint16_t length = p_obs_value->length; + memcpy(&(*pp_temp_value)[current_offset], &length, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_value, length); + current_offset += length; + } + break; + + case GHSS_HOB_CLASS_TYPE_SAMPLE_ARRAY_OBSERVATION: + { + T_GHSS_HOBV_SAMPLE_ARRAY_OBS *p_obs_value = &p_value->sample_array_obs; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->unit_code, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->scale_factor, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->offset, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->sample_period, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->number_of_samples_per_period, + 1); + current_offset += 1; + uint8_t bytes = p_obs_value->bytes_per_period; + memcpy(&(*pp_temp_value)[current_offset], &bytes, 1); + current_offset += 1; + uint32_t number = p_obs_value->number_of_samples; + memcpy(&(*pp_temp_value)[current_offset], &number, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_sample, bytes * number); + current_offset += (bytes * number); + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_DISCRETE_EVENT_OBSERVATION: + { + T_GHSS_HOBV_COMPOUND_DISCRETE_EVENT_OBS *p_obs_value = &p_value->compound_discrete_event_obs; + uint8_t number = p_obs_value->number_of_components; + memcpy(&(*pp_temp_value)[current_offset], &number, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_value, 4 * number); + current_offset += (4 * number); + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_STATE_EVENT_OBSERVATION: + { + T_GHSS_HOBV_COMPOUND_STATE_EVENT_OBS *p_obs_value = &p_value->compound_state_event_obs; + uint8_t size = p_obs_value->size; + memcpy(&(*pp_temp_value)[current_offset], &size, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_mask_bits, size); + current_offset += size; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_state_event_mask_bits, + size); + current_offset += size; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_value, size); + current_offset += size; + } + break; + + case GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION: //only for obs_bdl_value + { + T_GHSS_HOB_TLVS *p_obs_value = &p_value->tlv_encoded_obs; + uint8_t number = + p_obs_value->num_of_tlv_attr; + memcpy(&(*pp_temp_value)[current_offset], &number, 1); + current_offset += 1; + for (uint8_t i = 0; i < number; i++) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->p_tlvs_value[i].type, 4); + current_offset += 4; + uint16_t length = + p_obs_value->p_tlvs_value[i].length; + memcpy(&(*pp_temp_value)[current_offset], &length, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->p_tlvs_value[i].format_type, + 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + p_obs_value->p_tlvs_value[i].p_encoded_value, + length); + current_offset += length; + } + } + break; + + default: + APP_PRINT_ERROR1("ghss_format_health_obs_body_obs_sending_value: Invalid Observation Class Type %d", + type); + return 0; + } + + return current_offset; +} + +uint16_t ghss_format_health_obs_sending_value(T_GHSS_OBS_REPORT_TYPE type, uint32_t idx, + T_GHSS_HEALTH_OBS_BODY *p_value, + uint8_t **pp_temp_value) +{ + T_GHSS_HOB_FLAGS flags = p_value->flags; + uint16_t current_offset = 0; + uint8_t err_idx = 0; + + APP_PRINT_INFO2("ghss_format_health_obs_sending_value: Report type %d, Observation Class Type %d", + type, p_value->obs_class_type); + + uint16_t hob_length = ghss_format_health_obs_body_length(p_value); + + if (hob_length == 0) + { + APP_PRINT_ERROR0("ghss_format_health_obs_sending_value: Invalid Length"); + return 0; + } + + uint16_t total_len = hob_length; + + if (type == GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS) + { + total_len += 4; + } + + *pp_temp_value = os_mem_alloc(RAM_TYPE_DATA_ON, total_len); + if (*pp_temp_value == NULL) + { + APP_PRINT_ERROR0("ghss_format_health_obs_sending_value: Allocate memory fail"); + return 0; + } + + if (type == GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS) + { + memcpy(&(*pp_temp_value)[current_offset], &idx, 4); + current_offset += 4; + } + + // Mandatory part + memcpy(&(*pp_temp_value)[current_offset], &p_value->obs_class_type, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + &hob_length, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], &flags, 2); + current_offset += 2; + + uint16_t offset = ghss_format_health_obs_body_optional_sending_value(p_value, current_offset, + pp_temp_value); + if (offset == 0) + { + err_idx = 1; + goto error; + } + current_offset = offset; + + // Mandatory part + switch (p_value->obs_class_type) + { + case GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_SIMPLE_DISCRETE_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_STRING_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_SAMPLE_ARRAY_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_COMPOUND_DISCRETE_EVENT_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_COMPOUND_STATE_EVENT_OBSERVATION: + case GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION: //only for obs_bdl_value + { + uint16_t offset = ghss_format_health_obs_body_obs_sending_value(p_value->obs_class_type, + &p_value->obs_value, current_offset, pp_temp_value); + if (offset == 0) + { + err_idx = 2; + goto error; + } + current_offset = offset; + } + break; + + case GHSS_HOB_CLASS_TYPE_COMPOUND_OBSERVATION: + { + uint8_t number = + p_value->obs_value.compound_obs.number_of_components; + memcpy(&(*pp_temp_value)[current_offset], &number, 1); + current_offset += 1; + + for (uint8_t i = 0; i < number; i++) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_value->obs_value.compound_obs.p_component_value[i].component_type, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + &p_value->obs_value.compound_obs.p_component_value[i].component_value_type, 1); + current_offset += 1; + + T_GHSS_HOB_VALUE *p_obs_value = (T_GHSS_HOB_VALUE *) + p_value->obs_value.compound_obs.p_component_value[i].p_value; + T_GHSS_HOB_CLASS_TYPE obs_type = + p_value->obs_value.compound_obs.p_component_value[i].component_value_type; + + uint16_t offset = ghss_format_health_obs_body_obs_sending_value(obs_type, p_obs_value, + current_offset, + pp_temp_value); + if (offset == 0) + { + err_idx = 3; + goto error; + } + current_offset = offset; + } + } + break; + + case GHSS_HOB_CLASS_TYPE_OBSERVATION_BUNDLE: + { + uint8_t number = p_value->obs_value.obs_bundle.number_of_obs; + memcpy(&(*pp_temp_value)[current_offset], &number, 1); + current_offset += 1; + + for (uint8_t n = 0; n < number; n++) + { + T_GHSS_HEALTH_OBS_BODY *p_obs_bdl_value = (T_GHSS_HEALTH_OBS_BODY *) + p_value->obs_value.obs_bundle.p_obs_bdl_value + n; + + uint16_t obs_bdl_len = ghss_format_health_obs_body_length(p_value); + + // Mandatory part + memcpy(&(*pp_temp_value)[current_offset], &p_obs_bdl_value->obs_class_type, 1); + current_offset += 1; + memcpy(&(*pp_temp_value)[current_offset], + &obs_bdl_len, 2); + current_offset += 2; + memcpy(&(*pp_temp_value)[current_offset], &p_obs_bdl_value->flags, 2); + current_offset += 2; + + uint16_t offset = ghss_format_health_obs_body_optional_sending_value(p_obs_bdl_value, + current_offset, pp_temp_value); + if (offset == 0) + { + err_idx = 4; + goto error; + } + current_offset = offset; + + T_GHSS_HOB_VALUE *p_obs_value = (T_GHSS_HOB_VALUE *)&p_obs_bdl_value->obs_value; + + if (p_obs_bdl_value->obs_class_type == GHSS_HOB_CLASS_TYPE_COMPOUND_OBSERVATION) + { + uint8_t number = + p_obs_value->compound_obs.number_of_components; + memcpy(&(*pp_temp_value)[current_offset], &number, 1); + current_offset += 1; + + for (uint8_t i = 0; i < number; i++) + { + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->compound_obs.p_component_value[i].component_type, 4); + current_offset += 4; + memcpy(&(*pp_temp_value)[current_offset], + &p_obs_value->compound_obs.p_component_value[i].component_value_type, 1); + current_offset += 1; + + T_GHSS_HOB_VALUE *p_obs_components_value = (T_GHSS_HOB_VALUE *) + p_obs_value->compound_obs.p_component_value[i].p_value; + T_GHSS_HOB_CLASS_TYPE obs_components_type = + p_obs_value->compound_obs.p_component_value[i].component_value_type; + uint16_t offset = ghss_format_health_obs_body_obs_sending_value(obs_components_type, + p_obs_components_value, + current_offset, pp_temp_value); + if (offset == 0) + { + err_idx = 5; + goto error; + } + current_offset = offset; + } + } + else + { + uint16_t offset = ghss_format_health_obs_body_obs_sending_value(p_obs_bdl_value->obs_class_type, + p_obs_value, + current_offset, pp_temp_value); + if (offset == 0) + { + err_idx = 6; + goto error; + } + current_offset = offset; + } + } + } + break; + + default: + err_idx = 7; + goto error; + } + + APP_PRINT_INFO2("ghss_format_health_obs_sending_value:total_len %d, current_offset %d", + total_len, current_offset); + return total_len; + +error: + APP_PRINT_ERROR2("ghss_format_health_obs_sending_value: Observation Class Type %d ERR IDX %d", + p_value->obs_class_type, err_idx); + os_mem_free(*pp_temp_value); + *pp_temp_value = NULL; + return 0; +} + +uint16_t ghss_format_health_obs_segment(uint8_t seg_count, uint8_t seg_num, uint16_t report_mtu, + uint8_t rolling_seg_count, uint16_t value_len, uint8_t *p_value, uint8_t **pp_seg) +{ + T_GHSS_HEALTH_OBS_SEG_HEADER segmentation_header = {0}; + uint16_t length = 0; + + APP_PRINT_INFO2("ghss_format_health_obs_segment: seg_count %d, seg_num %d", + seg_count, seg_num); + + if (rolling_seg_count > GHSS_MAX_ROLLING_SEGMENT_COUNTER) + { + APP_PRINT_ERROR1("ghss_format_health_obs_segment: Invalid rolling_seg_count %d", + rolling_seg_count); + return 0; + } + else + { + segmentation_header.rolling_segment_counter = rolling_seg_count; + } + + if (seg_num == 1) + { + segmentation_header.first_segment = 1; + segmentation_header.last_segment = 1; + length = value_len; + } + else if (seg_num > 1) + { + if (seg_count == 0) + { + segmentation_header.first_segment = 1; + segmentation_header.last_segment = 0; + length = report_mtu; + } + else if ((seg_count > 0) && (seg_count < (seg_num - 1))) + { + segmentation_header.first_segment = 0; + segmentation_header.last_segment = 0; + length = report_mtu; + } + else if (seg_count == seg_num - 1) + { + segmentation_header.first_segment = 0; + segmentation_header.last_segment = 1; + length = (value_len + seg_num) - seg_count * report_mtu; + } + } + + if (length < 2) + { + APP_PRINT_ERROR0("ghss_format_health_obs_segment: Invalid seg length"); + return 0; + } + + *pp_seg = os_mem_alloc(RAM_TYPE_DATA_ON, length); + + if (*pp_seg == NULL) + { + APP_PRINT_ERROR0("ghss_format_health_obs_segment: Allocate memory fail"); + return 0; + } + + memcpy(*pp_seg, &segmentation_header, 1); + memcpy(&(*pp_seg)[1], + &p_value[seg_count * 19], + length - 1); + + return length; +} + +bool ghss_check_cccd(uint16_t uuid) +{ + if (uuid == GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT) + { + if ((ghss_notify_indicate_flag.ghss_racp_indicate_enable == 1) && + (ghss_notify_indicate_flag.ghss_stored_obs_notify_indicate_enable == 1)) + { + return true; + } + } + else if (uuid == GATT_UUID_CHAR_GHS_CONTROL_POINT) + { + if (ghss_notify_indicate_flag.ghss_ghs_cp_indicate_enable == 1) + { + return true; + } + } + + return false; +} + +bool ghss_get_obs_report_attr_idx(T_GHSS_OBS_REPORT_TYPE report_type, uint16_t *p_attr_idx) +{ + bool ret = true; + + switch (report_type) + { + case GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS: + { + *p_attr_idx = gatt_svc_find_char_index_by_uuid16(ghss_attr_tbl, + GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS, + ghss_char_num); + break; + } + + case GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS: + { + *p_attr_idx = gatt_svc_find_char_index_by_uuid16(ghss_attr_tbl, + GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS, + ghss_char_num); + break; + } + + default: + ret = false; + break; + } + + return ret; +} + +bool ghss_get_cp_report_attr_idx(T_GHSS_CP_REPORT_TYPE report_type, uint16_t *p_attr_idx) +{ + bool ret = true; + + switch (report_type) + { + case GHSS_CP_REPORT_TYPE_RACP: + { + *p_attr_idx = gatt_svc_find_char_index_by_uuid16(ghss_attr_tbl, + GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT, + ghss_char_num); + break; + } + + case GHSS_CP_REPORT_TYPE_GHS_CP: + { + *p_attr_idx = gatt_svc_find_char_index_by_uuid16(ghss_attr_tbl, + GATT_UUID_CHAR_GHS_CONTROL_POINT, + ghss_char_num); + break; + } + + default: + ret = false; + break; + } + + return ret; +} + +bool ghss_send_health_obs_report(uint8_t conn_id, uint8_t service_id, + T_GHSS_CHAR_OBS_REPORT report_data) +{ + uint16_t attr_idx = 0; + T_GATT_PDU_TYPE pdu_type = GATT_PDU_TYPE_INDICATION; + + if (!ghss_get_obs_report_attr_idx(report_data.report_type, &attr_idx)) + { + APP_PRINT_ERROR0("ghss_send_cp_report: Get invalid attr idx"); + return false; + } + + if (report_data.is_notify) + { + pdu_type = GATT_PDU_TYPE_NOTIFICATION; + } + + return server_send_data(conn_id, service_id, attr_idx, report_data.obs_segment.p_obs_segment, + report_data.obs_segment.obs_segment_len, pdu_type); +} + +bool ghss_send_cp_report(uint8_t conn_id, uint8_t service_id, T_GHSS_CHAR_CP_REPORT report_data) +{ + uint16_t attr_idx = 0; + + if (!ghss_get_cp_report_attr_idx(report_data.report_type, &attr_idx)) + { + APP_PRINT_ERROR0("ghss_send_cp_report: Get invalid attr idx"); + return false; + } + + void *p_value; + uint16_t length; + + switch (report_data.report_type) + { + case GHSS_CP_REPORT_TYPE_RACP: + { + p_value = report_data.value.report_racp.p_racp; + length = report_data.value.report_racp.racp_len; + break; + } + + case GHSS_CP_REPORT_TYPE_GHS_CP: + { + p_value = report_data.value.p_ghs_cp; + length = sizeof(T_GHSS_GHS_CP_OPCODE); + break; + } + + default: + return false; + } + + return server_send_data(conn_id, service_id, attr_idx, p_value, + length, GATT_PDU_TYPE_INDICATION); +} + +T_APP_RESULT ghss_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_GHSS_SERVER_WRITE_IND write_ind = {0}; + T_CHAR_UUID char_uuid = gatt_svc_find_char_uuid_by_index(ghss_attr_tbl, attrib_index, + ghss_char_num); + + write_ind.char_uuid = char_uuid.uu.char_uuid16; + write_ind.service_id = service_id; + write_ind.write_type = write_type; + + APP_PRINT_INFO4("ghss_attr_write_cb: conn_id 0x%x, service_id 0x%x, char_uuid 0x%x, length %d", + conn_id, service_id, write_ind.char_uuid, length); + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (write_ind.char_uuid) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT: + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > sizeof(T_GHSS_RACP)) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else if (!ghss_check_cccd(write_ind.char_uuid)) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + else + { + write_ind.data.ghss_racp.opcode = (T_GHSS_RACP_OPCODE)p_value[0]; + write_ind.data.ghss_racp.operator = (T_GHSS_RACP_OPERATOR)p_value[1]; + memcpy(write_ind.data.ghss_racp.operand, &p_value[2], length - 2); + } + } + break; + + case GATT_UUID_CHAR_GHS_CONTROL_POINT: + { + if (!ghss_check_cccd(write_ind.char_uuid)) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + else if ((p_value[0] != GHSS_GHS_CP_OPCODE_START_SEND_LIVE_OBS) && + (p_value[0] != GHSS_GHS_CP_OPCODE_STOP_SEND_LIVE_OBS) && + (p_value[0] != GHSS_GHS_CP_OPCODE_SUCCESS)) + { + cause = (T_APP_RESULT)ATT_ERR_GHS_COMMAND_NOT_SUPPORTED; + } + else + { + write_ind.data.ghss_ghs_cp = (T_GHSS_GHS_CP_OPCODE)p_value[0]; + } + } + break; + } + + if (pfn_ghss_cb && (cause == APP_RESULT_SUCCESS)) + { + cause = pfn_ghss_cb(conn_id, GATT_MSG_GHSS_SERVER_WRITE_IND, (void *)&write_ind); + } + + return cause; +} + +void ghss_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_CHAR_UUID char_uuid = gatt_svc_find_char_uuid_by_index(ghss_attr_tbl, index, ghss_char_num); + T_GHSS_SERVER_CCCD_UPDATE cccd_update = {0}; + + cccd_update.service_id = service_id; + cccd_update.char_uuid = char_uuid.uu.char_uuid16; + cccd_update.cccd_cfg = ccc_bits; + + APP_PRINT_INFO2("ghss_cccd_update_cb index = %d ccc_bits 0x%x", index, ccc_bits); + + switch (cccd_update.char_uuid) + { + case GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS: + { + if (ccc_bits & (GATT_CLIENT_CHAR_CONFIG_INDICATE | GATT_CLIENT_CHAR_CONFIG_NOTIFY | + GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE)) + { + ghss_notify_indicate_flag.ghss_live_obs_notify_indicate_enable = 1; + } + else + { + ghss_notify_indicate_flag.ghss_live_obs_notify_indicate_enable = 0; + } + } + break; + + case GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS: + { + if (ccc_bits & (GATT_CLIENT_CHAR_CONFIG_INDICATE | GATT_CLIENT_CHAR_CONFIG_NOTIFY | + GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE)) + { + ghss_notify_indicate_flag.ghss_stored_obs_notify_indicate_enable = 1; + } + else + { + ghss_notify_indicate_flag.ghss_stored_obs_notify_indicate_enable = 0; + } + } + break; + + case GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + ghss_notify_indicate_flag.ghss_racp_indicate_enable = 1; + } + else + { + ghss_notify_indicate_flag.ghss_racp_indicate_enable = 0; + } + } + break; + + case GATT_UUID_CHAR_GHS_CONTROL_POINT: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + ghss_notify_indicate_flag.ghss_ghs_cp_indicate_enable = 1; + } + else + { + ghss_notify_indicate_flag.ghss_ghs_cp_indicate_enable = 0; + } + } + break; + + default: + break; + } + + if (pfn_ghss_cb && (cause == true)) + { + pfn_ghss_cb(conn_id, GATT_MSG_GHSS_SERVER_CCCD_UPDATE, (void *)&cccd_update); + } + + return; +} + +/** + * @brief GHSS Service Callbacks. + */ +const T_FUN_GATT_SERVICE_CBS ghss_cbs = +{ + NULL, // Read callback function pointer + ghss_attr_write_cb, // Write callback function pointer + ghss_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add Generic Health Sensor Service to the Host database. + */ +T_SERVER_ID ghss_reg_srv(P_FUN_GHSS_SERVER_APP_CB app_cb) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)ghss_attr_tbl, + sizeof(ghss_attr_tbl), + ghss_cbs)) + { + APP_PRINT_ERROR1("ghss_reg_srv: service_id %d", service_id); + service_id = 0xff; + } + + pfn_ghss_cb = app_cb; + return service_id; +} + diff --git a/src/ble/profile/server/gls.c b/src/ble/profile/server/gls.c new file mode 100644 index 0000000..50fcd40 --- /dev/null +++ b/src/ble/profile/server/gls.c @@ -0,0 +1,2016 @@ +/**************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + + * @file gls.c + * @brief glucose service source file. + * @details Interface to access the glucose service. + * @author bill + * @date 2017-6-8 + * @version v1.0 + * ************************************************************************************* + */ + +#include "trace.h" +#include +#include "gatt.h" +#include "gls.h" + + +/** @brief service related UUIDs. */ +#define GATT_UUID_GLUCOSE 0x1808 +#define GATT_UUID_CHAR_GLC_MEASUREMENT 0x2A18 +#define GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT 0x2A34 +#define GATT_UUID_CHAR_GLC_FEATURE 0x2A51 +#define GATT_UUID_CHAR_GLC_RACP 0x2A52 + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +/** Value of glucose feature characteristic. */ +static uint16_t features; + +/** glucose record access control point */ +T_GLC_RACP glc_racp; +T_PATIENT_RECORD *p_new_record; +/** flags of notification and indication for characteristic */ +static T_GLC_NOTIFY_INDICATE_FLAG glc_notify_indicate_flag = {0}; + +/** parameters used for splitting report records procedure */ +uint16_t gls_num_records_to_report = 0; +uint16_t gls_current_record_to_report = 0; +uint16_t gls_report_offset = 0; +uint8_t gls_send_data_flag = 0; +/** Flag used for aborting procedure */ +bool gls_abort_flag = false; +bool gls_abort_by_app_flag = false; + +/** Function pointer used to send event to application from GLS. Initiated in gls_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_gls_cb = NULL; + +/** @brief profile/service definition. */ +const T_ATTRIB_APPL gls_att_tbl[] = +{ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_GLUCOSE), /* service UUID */ + HI_WORD(GATT_UUID_GLUCOSE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Glucose Measurement characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } + +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + , + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Glucose Measurement Context characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT), + HI_WORD(GATT_UUID_CHAR_GLC_MEASUREMENT_CONTEXT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif /**< end of GLC_MEASUREMENT_CONTEXT_SUPPORT */ + + , + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Glucose features characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_GLC_FEATURE), + HI_WORD(GATT_UUID_CHAR_GLC_FEATURE), + }, + 2, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } + + , + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- Glucose Record Access Control Point value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_GLC_RACP), + HI_WORD(GATT_UUID_CHAR_GLC_RACP) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +}; + + +/** + * @brief Prepare a new record in database. + * @return void. + * + */ +void gls_prepare_new_record() +{ + PROFILE_PRINT_INFO4("gls_prepare_new_record database head: %d, tail: %d, num: %d, seq_num: %d\n", + glc_racp.record_db.head, glc_racp.record_db.tail, glc_racp.record_db.record_num, + glc_racp.record_db.seq_num); + p_new_record = &(glc_racp.record_db.records[glc_racp.record_db.tail]); + memset(p_new_record, 0, sizeof(T_PATIENT_RECORD)); + glc_racp.record_db.seq_num++; + p_new_record->glc_measurement_value.seq_num = glc_racp.record_db.seq_num; +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + p_new_record->glc_measurement_context.seq_num = glc_racp.record_db.seq_num; +#endif +} + +/** + * @brief Push a new record into database. + * @return void. + * + */ +void gls_push_new_record() +{ + if (((glc_racp.record_db.head - glc_racp.record_db.tail + GLC_RACP_DATABASE_SIZE) % + GLC_RACP_DATABASE_SIZE) == 1) + { + glc_racp.record_db.head = (glc_racp.record_db.head + 1) % GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.tail = (glc_racp.record_db.tail + 1) % GLC_RACP_DATABASE_SIZE; + } + else + { + glc_racp.record_db.tail = (glc_racp.record_db.tail + 1) % GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num++; + } + PROFILE_PRINT_INFO4("gls_push_new_record database head: %d, tail: %d, num: %d, seq_num: %d\n", + glc_racp.record_db.head, glc_racp.record_db.tail, glc_racp.record_db.record_num, + glc_racp.record_db.seq_num); +} + +/** + * @brief Set a GLS parameter. + * + * NOTE: You can call this function with a gulcose service parameter type and it will set the + * gulcose service parameter. Glucose service parameters are defined in @ref T_GLS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Glucose service parameter type: @ref T_GLS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GLC_MEASUREMENT_FLAG ms_flag = + { + 1, //time_offset + 1, //con_ts_loc + GLC_FLAGS_UNITS_MOL_L_ON, //con_units + 1, //ss_annuciation + 0, //ctxt_info_follows + 0 //rfu + }; + gls_set_parameter(GLS_PARAM_GLC_MS_FLAG, 1, &ms_flag); + } + * \endcode + */ +bool gls_set_parameter(T_GLS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + case GLS_PARAM_GLC_FEATURES: + if (len == 2) + { + LE_ARRAY_TO_UINT16(features, (uint8_t *) p_value); + } + else + { + ret = false; + } + break; + case GLS_PARAM_CTL_PNT_PROG_CLR: + glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED; + gls_num_records_to_report = 0; + gls_current_record_to_report = 0; + gls_report_offset = 0; + gls_send_data_flag = 0; + gls_abort_flag = false; // Make sure Abort Flag is clear after RACP procedure is over! + gls_abort_by_app_flag = false; // Make sure Abort by App Flag is clear after RACP procedure is over! + break; + case GLS_PARAM_GLC_MS_FLAG: + if (len == 1) + { + memcpy(&(p_new_record->glc_measurement_value.flags), p_value, 1); + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_BASE_TIME: + if (len == sizeof(TIMESTAMP)) + { + memcpy(p_new_record->glc_measurement_value.base_time, p_value, sizeof(TIMESTAMP)); + } + else + { + ret = false; + } + break; +#if (GLC_INCLUDE_TIME_OFFSET) + case GLS_PARAM_GLC_MS_TIME_OFFSET: + if (len == 2) + { + p_new_record->glc_measurement_value.time_offset = *(int16_t *)p_value; + p_new_record->glc_measurement_value.flags.time_offset = 1; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_CONC_TS_LOC) + case GLS_PARAM_GLC_MS_CONCENTRATION: + if (len == sizeof(SFLOAT)) + { + memcpy(&(p_new_record->glc_measurement_value.concentration), p_value, sizeof(SFLOAT)); + p_new_record->glc_measurement_value.flags.con_ts_loc = 1; + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_CONCENTRATION_UNITS: + if (len == 1) + { + p_new_record->glc_measurement_value.flags.con_units = *(uint8_t *)p_value; + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_TYPE_SAMPLE_LOCATION: + if (len == 1) + { + p_new_record->glc_measurement_value.type_sample_location = *(uint8_t *)p_value; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_SS_ANNUNC) + case GLS_PARAM_GLC_MS_SENSOR_STATUS_ANNUNCIATION: + if (len == 2) + { + memcpy(&(p_new_record->glc_measurement_value.ss_annunciation), p_value, 2); + p_new_record->glc_measurement_value.flags.ss_annuciation = 1; + } + else + { + ret = false; + } + break; +#endif +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + case GLS_PARAM_GLC_MS_CT_FLAG: + if (len == 1) + { + p_new_record->glc_measurement_context.flags = *(T_GLC_MSR_CTXT_FLAG *)p_value; + } + else + { + ret = false; + } + break; +#if (GLC_INCLUDE_CARBOHYDRATE) + case GLS_PARAM_GLC_MS_CT_CARBOHYDRATE_ID: + if (len == 1) + { + p_new_record->glc_measurement_context.carbohydrate_ID = *(uint8_t *)p_value; + p_new_record->glc_measurement_context.flags.carbohydrate = 1; + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_CT_CARBOHYDRATE: + if (len == sizeof(SFLOAT)) + { + memcpy(&(p_new_record->glc_measurement_context.carbohydrate), p_value, sizeof(SFLOAT)); + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_MEAL) + case GLS_PARAM_GLC_MS_CT_MEAL: + if (len == 1) + { + p_new_record->glc_measurement_context.meal = *(uint8_t *)p_value; + p_new_record->glc_measurement_context.flags.meal = 1; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_TESTER_HEALTH) + case GLS_PARAM_GLC_MS_CT_TESTER_HEALTH: + if (len == 1) + { + p_new_record->glc_measurement_context.tester_health = *(uint8_t *)p_value; + p_new_record->glc_measurement_context.flags.tester_health = 1; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_EXCERCISE) + case GLS_PARAM_GLC_MS_CT_EXERCISE_DURATION: + if (len == 2) + { + LE_ARRAY_TO_UINT16(p_new_record->glc_measurement_context.exercise_duration, (uint8_t *)p_value); + p_new_record->glc_measurement_context.flags.excercise = 1; + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_CT_EXERCISE_INTENSITY: + if (len == 1) + { + p_new_record->glc_measurement_context.exercise_intensity = *(uint8_t *)p_value; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_MEDICATION) + case GLS_PARAM_GLC_MS_CT_MEDICATION_ID: + if (len == 1) + { + p_new_record->glc_measurement_context.medication_ID = *(uint8_t *)p_value; + p_new_record->glc_measurement_context.flags.medication = 1; + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_CT_MEDICATION: + if (len == sizeof(SFLOAT)) + { + memcpy(&(p_new_record->glc_measurement_context.medication), p_value, sizeof(SFLOAT)); + } + else + { + ret = false; + } + break; + case GLS_PARAM_GLC_MS_CT_MEDICATION_UNITS: + if (len == 1) + { + p_new_record->glc_measurement_context.flags.medication_units = *(uint8_t *)p_value; + } + else + { + ret = false; + } + break; +#endif +#if (GLC_INCLUDE_HbA1c) + case GLS_PARAM_GLC_MS_CT_HbA1c: + if (len == sizeof(SFLOAT)) + { + memcpy(&(p_new_record->glc_measurement_context.hb_a1c), p_value, sizeof(SFLOAT)); + p_new_record->glc_measurement_context.flags.hb_a1c = 1; + } + else + { + ret = false; + } + break; +#endif +#endif + default: + ret = false; + break; + } + + if (!ret) + { + PROFILE_PRINT_ERROR1("gls_set_parameter gls parameter set failed: %d\n", param_type); + } + + return ret; +} + +/** + * @brief Get a GLS parameter. + * + * NOTE: You can call this function with a gulcose parameter type and it will get a + * gulcose parameter. Glucose parameters are defined in @ref T_GLS_PARAM_TYPE. + * + * @param[in] param_type Glucose parameter type: @ref T_GLS_PARAM_TYPE + * @param[in,out] len Pointer to the location to get the length of data. + * @param[in,out] p_value Pointer to the location to get the parameter value. This is dependent on + * the parameter type and will be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval GAP_CAUSE_SUCCESS Operation success. + * @retval GAP_CAUSE_INVALID_PARAM Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + int record_num; + gls_get_parameter(GLS_PARAM_RECORD_NUM, &len, &record_num); + } + * \endcode + */ +bool gls_get_parameter(T_GLS_PARAM_TYPE param_type, uint8_t *len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + case GLS_PARAM_GLC_FEATURES: + *len = sizeof(uint16_t); + LE_UINT16_TO_ARRAY(p_value, features); + break; + case GLS_PARAM_RECORD_NUM: + *len = sizeof(int); + memcpy(p_value, &glc_racp.record_db.record_num, sizeof(int)); + break; + case GLS_PARAM_RECORD_SEQ_NUM: + *len = sizeof(uint16_t); + memcpy(p_value, &glc_racp.record_db.seq_num, sizeof(uint16_t)); + break; + default: + *len = 0; + ret = false; + break; + } + + if (!ret) + { + PROFILE_PRINT_ERROR1("gls_get_parameter gls parameter get failed: %d\n", param_type); + } + + return ret; +} + +/** + * @brief Send measurement notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index Index. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_glc_measurement_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index) +{ + int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE; + + gls_send_data_flag = 1; + + T_GLC_MEASUREMENT_VALUE *pmeasurement_value = + &glc_racp.record_db.records[current].glc_measurement_value; + uint8_t temp_glc_measurement[sizeof(T_GLC_MEASUREMENT_VALUE)]; + uint8_t offset = 0; + if (index >= glc_racp.record_db.record_num) + { + PROFILE_PRINT_ERROR0("gls_glc_measurement_notify glucose measurement value access overflow!"); + return false; + } + if (current == glc_racp.record_db.tail) + { + PROFILE_PRINT_ERROR0("gls_glc_measurement_notify glucose measurement database: empty!"); + return false; + } + + memcpy(&temp_glc_measurement[offset], &pmeasurement_value->flags, 1); + offset += 1; + memcpy(&temp_glc_measurement[offset], &pmeasurement_value->seq_num, 2); + offset += 2; + memcpy(&temp_glc_measurement[offset], pmeasurement_value->base_time, 7); + offset += 7; + +#if (GLC_INCLUDE_TIME_OFFSET) + if (pmeasurement_value->flags.time_offset) + { + memcpy(&temp_glc_measurement[offset], &pmeasurement_value->time_offset, 2); + offset += 2; + } +#endif +#if (GLC_INCLUDE_CONC_TS_LOC) + if (pmeasurement_value->flags.con_ts_loc) + { + memcpy(&temp_glc_measurement[offset], pmeasurement_value->concentration, 2); + offset += 2; + memcpy(&temp_glc_measurement[offset], &pmeasurement_value->type_sample_location, 1); + offset += 1; + } +#endif +#if (GLC_INCLUDE_SS_ANNUNC) + if (pmeasurement_value->flags.ss_annuciation) + { + memcpy(&temp_glc_measurement[offset], &pmeasurement_value->ss_annunciation, 2); + offset += 2; + } +#endif + PROFILE_PRINT_INFO1("gls_glc_measurement_notify glucose measurement notification: index = %d \n", + index); + // send notification to client + return server_send_data(conn_id, service_id, GLS_CHAR_GLC_MEASUREMENT_INDEX, temp_glc_measurement, + offset, GATT_PDU_TYPE_NOTIFICATION); +} + +#if GLC_MEASUREMENT_CONTEXT_SUPPORT +/** + * @brief Send measurement context notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index Index. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_glc_measurement_context_notify(uint8_t conn_id, T_SERVER_ID service_id, uint8_t index) +{ + int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE; + + gls_send_data_flag = 2; + + T_GLC_MEASUREMENT_CONTEXT *pmeasurement_context = + &glc_racp.record_db.records[current].glc_measurement_context; + uint8_t temp_glc_measurement_ctxt[sizeof(T_GLC_MEASUREMENT_CONTEXT)]; + uint8_t offset = 0; + if (index >= glc_racp.record_db.record_num) + { + PROFILE_PRINT_ERROR0("gls_glc_measurement_context_notify glucose measurement context access overflow!"); + return false; + } + if (current == glc_racp.record_db.tail) + { + PROFILE_PRINT_ERROR0("gls_glc_measurement_context_notify glucose measurement database: Empty!"); + return false; + } + + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->flags, 1); + offset += 1; + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->seq_num, 2); + offset += 2; +#if (GLC_INCLUDE_EXT_FLAGS) + if (pmeasurement_context->flags.ext_flags) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->ext_flags, 1); + offset += 1; + } +#endif +#if (GLC_INCLUDE_CARBOHYDRATE) + if (pmeasurement_context->flags.carbohydrate) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->carbohydrate_ID, 1); + offset += 1; + memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->carbohydrate, 2); + offset += 2; + } +#endif +#if (GLC_INCLUDE_MEAL) + if (pmeasurement_context->flags.meal) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->meal, 1); + offset += 1; + } +#endif +#if (GLC_INCLUDE_TESTER_HEALTH) + if (pmeasurement_context->flags.tester_health) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->tester_health, 1); + offset += 1; + } +#endif +#if (GLC_INCLUDE_EXCERCISE) + if (pmeasurement_context->flags.excercise) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->exercise_duration, 2); + offset += 2; + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->exercise_intensity, 1); + offset += 1; + } +#endif +#if (GLC_INCLUDE_MEDICATION) + if (pmeasurement_context->flags.medication) + { + memcpy(&temp_glc_measurement_ctxt[offset], &pmeasurement_context->medication_ID, 1); + offset += 1; + memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->medication, 2); + offset += 2; + } +#endif +#if (GLC_INCLUDE_HbA1c) + if (pmeasurement_context->flags.hb_a1c) + { + memcpy(&temp_glc_measurement_ctxt[offset], pmeasurement_context->hb_a1c, 2); + offset += 2; + } +#endif + PROFILE_PRINT_INFO1("gls_glc_measurement_context_notify glucose measurement context notification: index = %d \n", + index); + // send notification to client + return server_send_data(conn_id, service_id, GLS_CHAR_GLC_MEASUREMENT_CONTEXT_INDEX, + temp_glc_measurement_ctxt, offset, GATT_PDU_TYPE_NOTIFICATION); +} +#endif + +/** + * @brief Indicate glucose racp procedure result to client. + * + * @param[in] service_id Service ID to notify. + * @param[in] rsp_code racp respondence code. + * @return Result of indication. + * @retval 0 FALSE + * @retval 1 TRUE + */ +bool gls_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + bool ret; + + gls_send_data_flag = 3; + + uint16_t attrib_index = GLS_CHAR_GLC_RACP_INDEX; + + glc_racp.ctrl_point.operand[0] = glc_racp.ctrl_point.op_code; + glc_racp.ctrl_point.operand[1] = rsp_code; + glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESP_CODE; + glc_racp.ctrl_point.op = GLC_RACP_OPERATOR_NULL; + + glc_racp.cp_length = sizeof(T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_OPERATOR) + sizeof( + T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_RESP_CODES); + + // send indication to client + ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *) &glc_racp.ctrl_point, + glc_racp.cp_length, GATT_PDU_TYPE_INDICATION); + PROFILE_PRINT_INFO1("gls_racp_response glucose racp resp: %d \n", rsp_code); + + //glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED; + + return ret; +} + +/** + * @brief Indicate number of glucose records to client. + * + * @param[in] service_id Service ID to notify. + * @param[in] num Number of glucose records. + * @return Result of indication. + * @retval 0 FALSE + * @retval 1 TRUE + */ +bool gls_racp_num_response(uint8_t conn_id, T_SERVER_ID service_id, uint16_t num) +{ + bool ret; + + gls_send_data_flag = 3; + + uint16_t attrib_index = GLS_CHAR_GLC_RACP_INDEX; + + LE_UINT16_TO_ARRAY(glc_racp.ctrl_point.operand, num); + glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_NBR_OF_RECS_RESP; + glc_racp.ctrl_point.op = GLC_RACP_OPERATOR_NULL; + + glc_racp.cp_length = sizeof(T_GLC_CTRL_POINT_OPCODE) + sizeof(T_GLC_CTRL_POINT_OPERATOR) + sizeof( + uint16_t); + + // send indication to client + ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *) &glc_racp.ctrl_point, + glc_racp.cp_length, GATT_PDU_TYPE_INDICATION); + PROFILE_PRINT_INFO1("gls_racp_num_response glucose racp num response: %d \n", num); + + //glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_RESERVED; + + return ret; +} + +/** + * @brief Indication in abort procedure. + * + * @param[in] service_id Service ID to notify. + * @return Result of indication. + * @retval 0 FALSE + * @retval 1 TRUE + */ +bool gls_abort_success_response(uint8_t conn_id, T_SERVER_ID service_id) +{ + glc_racp.ctrl_point.op_code = GLC_RACP_OPCODE_ABORT_OPERATION; + + PROFILE_PRINT_INFO0("gls_abort_success_response gls racp procedure has been aborted!"); + + return gls_racp_response(conn_id, service_id, GLC_RACP_RESP_SUCCESS); +} + +/** + * @brief Compare two timestamps. + * + * @param[in] time1 Time to compare. + * @param[in] time2 Time to compare. + * @return Result of comparison. + * @retval 1 Time1 > Time2 + * @retval 0 Time1 = Time2 + * @retval -1 Time1 < Time2 + */ +int time_cmp(const TIMESTAMP time1, const TIMESTAMP time2) +{ + uint16_t year1, year2; + LE_ARRAY_TO_UINT16(year1, (uint8_t *) time1); + LE_ARRAY_TO_UINT16(year2, (uint8_t *) time2); + if (year1 < year2) + { + return -1; + } + else if (year1 > year2) + { + return 1; + } + else + { + int length; + for (length = 0; length < 5; length++) + { + if (time1[2 + length] < time2[2 + length]) + { + return -1; + } + else if (time1[2 + length] > time2[2 + length]) + { + return 1; + } + else + ; + } + return 0; + } +} + +/** + * @brief Calculate user facing time by adding basetime and timeoffset. + * + * + * @param[in] time_in Connection id. + * @param[in] time_offset Service id. + * @param[in] time_out Battery level value. + * @return void. + * + * Example usage + * \code{.c} + void test(void) + { + user_face_time(time, 30, time); + } + * \endcode + */ +void user_face_time(TIMESTAMP time_in, int16_t time_offset, TIMESTAMP time_out) +{ + uint8_t carry; + uint16_t year; + LE_ARRAY_TO_UINT16(year, (uint8_t *) time_in); + + TIMESTAMP time_tmp = {0}; + time_tmp[4] = time_offset / 60; //hour + time_tmp[5] = time_offset % 60; //minute + + time_out[6] = time_in[6] + time_tmp[6]; //second + carry = 0; + + time_out[5] = time_in[5] + time_tmp[5] + carry; //minute + if (time_out[5] > 59) + { + time_out[5] -= 60; + carry = 1; + } + else + { + carry = 0; + } + + time_out[4] = time_in[4] + time_tmp[4] + carry; //hour + if (time_out[4] > 23) + { + time_out[4] -= 24; + carry = 1; + } + else + { + carry = 0; + } + + time_out[3] = time_in[3] + time_tmp[3] + carry; //day + +// switch (time_out[2]) +// { +// case 2: +// if(((year % 400) == 0) || (((year % 4) == 0) &&((year % 100) != 0))) //leap year +// { +// if(time_out[3] > 29) +// { +// time_out[3] -= 29; +// carry = 1; +// } +// else +// { +// carry = 0; +// } +// } +// else +// { +// if(time_out[3] > 28) +// { +// time_out[3] -= 28; +// carry = 1; +// } +// else +// { +// carry = 0; +// } +// } +// break; +// case 1: +// case 3: +// case 5: +// case 7: +// case 8: +// case 10: +// case 12: +// if(time_out[3] > 31) +// { +// time_out[3] -= 31; +// carry = 1; +// } +// else +// { +// carry = 0; +// } +// break; +// case 4: +// case 6: +// case 9: +// case 11: +// if(time_out[3] > 30) +// { +// time_out[3] -= 30; +// carry = 1; +// } +// else +// { +// carry = 0; +// } +// break; +// default: +// break; +// } + + uint8_t month_leap[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + uint8_t month_common[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (((year % 400) == 0) || (((year % 4) == 0) && ((year % 100) != 0))) //leap year + { + if (time_out[3] > month_leap[time_out[2]]) + { + time_out[3] -= month_leap[time_out[2]]; + carry = 1; + } + else + { + carry = 0; + } + } + else + { + if (time_out[3] > month_common[time_out[2]]) + { + time_out[3] -= month_common[time_out[2]]; + carry = 1; + } + else + { + carry = 0; + } + } + + time_out[2] = time_in[2] + time_tmp[2] + carry; //month + + if (time_out[2] > 12) + { + time_out[2] -= 12; + carry = 1; + } + else + { + carry = 0; + } + + uint16_t year_in; + uint16_t year_tmp; + LE_ARRAY_TO_UINT16(year_in, (uint8_t *) time_in); + LE_ARRAY_TO_UINT16(year_tmp, (uint8_t *) time_tmp); + LE_UINT16_TO_ARRAY(time_out, year_in + year_tmp + carry); //year +} + +/** + * @brief Check the write parameters of RACP, used in report/report num/delete opcode + * @returen None + */ +T_GLC_CTRL_POINT_RESP_CODES gls_racp_check() +{ + T_GLC_CTRL_POINT_RESP_CODES ret = GLC_RACP_RESP_SUCCESS; + + PROFILE_PRINT_INFO3("gls_racp_check glucose racp: opcode = %d, operator = %d, length = %d \n", + glc_racp.ctrl_point.op_code, glc_racp.ctrl_point.op, glc_racp.cp_length); + + if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_NULL) + { + ret = GLC_RACP_RESP_INVALID_OPERATOR; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS + || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST + || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST) + { + if (glc_racp.cp_length != 2) + { + ret = GLC_RACP_RESP_INVALID_OPERAND; + } + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ + || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ + || glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE) + { + if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_RESERVED) + { + ret = GLC_RACP_RESP_INVALID_OPERAND; + } + else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR) + { + if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE) + { + uint16_t min_seq; + uint16_t max_seq; + LE_ARRAY_TO_UINT16(min_seq, &glc_racp.ctrl_point.operand[1]); + LE_ARRAY_TO_UINT16(max_seq, &glc_racp.ctrl_point.operand[1 + sizeof(uint16_t)]); + if (min_seq > max_seq) + { + ret = GLC_RACP_RESP_INVALID_OPERAND; + } + } + } + else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME) + { + if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE) + { + if (time_cmp(&glc_racp.ctrl_point.operand[1], + &glc_racp.ctrl_point.operand[1 + sizeof(TIMESTAMP)]) > 0) + { + ret = GLC_RACP_RESP_INVALID_OPERAND; + } + } + } + else + { + /** glc_racp.ctrl_point.operand[0] > GLC_RACP_FILTER_TYPE_TIME */ + ret = GLC_RACP_RESP_OPERAND_NOT_SUPPORTED; + } + } + else + { + /** glc_racp.ctrl_point.operator > GLC_RACP_OPERATOR_LAST */ + ret = GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED; + } + return ret; +} + +/** + * @brief Find record by sequence number + * @param[in] op operator of the procedure. + * @param[in] set_seq sequence number referenced to. + * @return Absolute position of the found record + */ +int gls_find_records_by_seq_num(T_GLC_CTRL_POINT_OPERATOR op, uint16_t set_seq) +{ + int find; + if (op == GLC_RACP_OPERATOR_LT_EQ) + { + find = glc_racp.record_db.head; + while ((find != glc_racp.record_db.tail) && + (glc_racp.record_db.records[find].glc_measurement_value.seq_num <= set_seq)) + { + find = (find + 1) % GLC_RACP_DATABASE_SIZE; + } + if (find == glc_racp.record_db.head) /**< no record found */ + { + find = glc_racp.record_db.tail; + } + else + { + find -= 1; /**< record large than set_seq is found */ + } + } + else if (op == GLC_RACP_OPERATOR_GT_EQ) + { + find = glc_racp.record_db.head; + while ((find != glc_racp.record_db.tail) && + (glc_racp.record_db.records[find].glc_measurement_value.seq_num < set_seq)) + { + find = (find + 1) % GLC_RACP_DATABASE_SIZE; + } + } + else + { + find = glc_racp.record_db.tail; + } + return find; +} + +/** + * @brief Find record by timestamp + * @brief Should time_offset be taken into consideration when comparing user-interface time? + * PTS test shows that when writing the RACP using the User Facing Time filter type there is no timeoffset part. + * @param[in] op operator of the procedure. + * @param[in] set_time time referenced to. + * @return Absolute position of the found record + */ +int gls_find_records_by_time(T_GLC_CTRL_POINT_OPERATOR op, TIMESTAMP set_time) +{ + int find; + //TIMESTAMP user_time; + if (op == GLC_RACP_OPERATOR_LT_EQ) + { + find = glc_racp.record_db.head; + while (find != glc_racp.record_db.tail) + { + //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, TimeOffset, user_time); + //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, glc_racp.record_db.records[find].glc_measurement_value.time_offset, user_time); + //if (time_cmp(user_time, set_time) <= 0) + if (time_cmp(glc_racp.record_db.records[find].glc_measurement_value.base_time, set_time) <= 0) + { + find = (find + 1) % GLC_RACP_DATABASE_SIZE; + } + else + { + break; + } + } + if (find == glc_racp.record_db.head) /**< no record found */ + { + find = glc_racp.record_db.tail; + } + else + { + find -= 1; /**< record large than set_seq is found */ + } + } + else if (op == GLC_RACP_OPERATOR_GT_EQ) + { + find = glc_racp.record_db.head; + while (find != glc_racp.record_db.tail) + { + //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, TimeOffset, user_time); + //user_face_time(glc_racp.record_db.records[find].glc_measurement_value.base_time, glc_racp.record_db.records[find].glc_measurement_value.time_offset, user_time); + //if (time_cmp(user_time, set_time) < 0) + if (time_cmp(glc_racp.record_db.records[find].glc_measurement_value.base_time, set_time) < 0) + { + find = (find + 1) % GLC_RACP_DATABASE_SIZE; + } + else + { + break; + } + } + } + else + { + find = glc_racp.record_db.tail; + } + return find; +} + +/** + * @brief Find records that meets the conditions. + * @param[out] pnum num of records + * @param[out] pfirst absolute position of the first record + * @param[out] plast absolute position of the last record + * @return The check result of the procedure. + */ +T_GLC_CTRL_POINT_RESP_CODES gls_find_records(uint16_t *p_num, int *p_first, int *p_last) +{ + uint16_t num_of_records = 0; + int find1 = 0; + int find2 = 0; + T_GLC_CTRL_POINT_RESP_CODES ret; + ret = gls_racp_check(); + if (ret == GLC_RACP_RESP_SUCCESS) + { + if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS) + { + find1 = glc_racp.record_db.head; + find2 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + num_of_records = glc_racp.record_db.record_num; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ) + { + find1 = glc_racp.record_db.head; + if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR) + { + uint16_t seq; + LE_ARRAY_TO_UINT16(seq, &glc_racp.ctrl_point.operand[1]); + find2 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_LT_EQ, seq); + } + else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME) + { + find2 = gls_find_records_by_time(GLC_RACP_OPERATOR_LT_EQ, &glc_racp.ctrl_point.operand[1]); + } + else + { + find2 = glc_racp.record_db.tail; + } + if (find2 == glc_racp.record_db.tail) + { + num_of_records = 0; + } + else + { + num_of_records = (find2 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE + + 1; + } + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ) + { + if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR) + { + uint16_t seq; + LE_ARRAY_TO_UINT16(seq, &glc_racp.ctrl_point.operand[1]); + find1 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_GT_EQ, seq); + } + else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME) + { + find1 = gls_find_records_by_time(GLC_RACP_OPERATOR_GT_EQ, &glc_racp.ctrl_point.operand[1]); + } + else + { + find1 = glc_racp.record_db.tail; + } + find2 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + num_of_records = (glc_racp.record_db.tail - find1 + GLC_RACP_DATABASE_SIZE) % + GLC_RACP_DATABASE_SIZE; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE) + { + if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_SEQ_NBR) + { + uint16_t seq1; + uint16_t seq2; + LE_ARRAY_TO_UINT16(seq1, &glc_racp.ctrl_point.operand[1]); + LE_ARRAY_TO_UINT16(seq2, &glc_racp.ctrl_point.operand[1 + 2]); + + find1 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_GT_EQ, seq1); + find2 = gls_find_records_by_seq_num(GLC_RACP_OPERATOR_LT_EQ, seq2); + } + else if (glc_racp.ctrl_point.operand[0] == GLC_RACP_FILTER_TYPE_TIME) + { + find1 = gls_find_records_by_time(GLC_RACP_OPERATOR_GT_EQ, &glc_racp.ctrl_point.operand[1]); + find2 = gls_find_records_by_time(GLC_RACP_OPERATOR_LT_EQ, + &glc_racp.ctrl_point.operand[1 + sizeof(TIMESTAMP)]); + } + else + { + find1 = glc_racp.record_db.tail; + find2 = glc_racp.record_db.tail; + } + if (find1 == glc_racp.record_db.tail || find2 == glc_racp.record_db.tail) + { + num_of_records = 0; + } + else + { + num_of_records = (find2 - find1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE + 1; + } + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST) + { + find1 = glc_racp.record_db.head; + find2 = find1; + if (glc_racp.record_db.record_num == 0) + { + num_of_records = 0; + } + else + { + num_of_records = 1; + } + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST) + { + find1 = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + find2 = find1; + if (glc_racp.record_db.record_num == 0) + { + num_of_records = 0; + } + else + { + num_of_records = 1; + } + } + else + { + ret = GLC_RACP_RESP_OPERATOR_NOT_SUPPORTED; + return ret; + } + + if (p_num != 0) + { + *p_num = num_of_records; + } + if (p_first != 0) + { + *p_first = find1; + } + if (p_last != 0) + { + *p_last = find2; + } + PROFILE_PRINT_INFO3("gls_find_records glucose find records: num = %d, start = %d, end = %d\n", + num_of_records, find1, find2); + } + return ret; +} + +/** + * @brief Report number of records that meet the conditions. + * @param[in] service_id The service ID of glucose service + * @return None + */ +void gls_report_num_of_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + T_GLC_CTRL_POINT_RESP_CODES ret; + uint16_t num_of_records; + int find1, find2; + ret = gls_find_records(&num_of_records, &find1, &find2); + if (ret != GLC_RACP_RESP_SUCCESS) + { + gls_racp_response(conn_id, service_id, ret); + } + else + { + gls_racp_num_response(conn_id, service_id, num_of_records); + } +} + +/** + * @brief Report record + * @param[in] service_ID The service ID of glucose service + * @param[in] index The index of record + * Attention: For the purpose of good user experience, the input parameter index of this function is the offset of the head, not the pointer of data record. + */ +void gls_report_record(uint8_t conn_id, T_SERVER_ID service_id, int index) +{ + PROFILE_PRINT_INFO1("gls_report_record: %d\n", index); + gls_glc_measurement_notify(conn_id, service_id, index); +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + int current = (glc_racp.record_db.head + index) % GLC_RACP_DATABASE_SIZE; + if (glc_racp.record_db.records[current].glc_measurement_value.flags.ctxt_info_follows == 1) + { + gls_glc_measurement_context_notify(conn_id, service_id, index); + } +#endif +} + +/** + * @brief Report records that meet the conditions. + * @param[in] service_id The service ID of glucose service + * @return None + */ +void gls_report_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + T_GLC_CTRL_POINT_RESP_CODES ret; + uint16_t num_of_records; + int find1, find2; + ret = gls_find_records(&num_of_records, &find1, &find2); + if (ret == GLC_RACP_RESP_SUCCESS) + { + if (num_of_records == 0) + { + ret = GLC_RACP_RESP_NO_RECS_FOUND; + gls_racp_response(conn_id, service_id, ret); + } + else + { +// int offset = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; +// for (int index = 0; index < num_of_records; index++) +// { +// gls_report_record(service_ID, offset + index); // attention! +// VoidCheckAbortFlag(); +// } + gls_report_offset = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % + GLC_RACP_DATABASE_SIZE; + gls_num_records_to_report = num_of_records; + gls_current_record_to_report = 0; + if (false == gls_report_records_task(conn_id, service_id)) + { + gls_set_parameter(GLS_PARAM_CTL_PNT_PROG_CLR, 0, NULL); + } + } + } + else + { + gls_racp_response(conn_id, service_id, ret); + } +} + +/** + * @brief Report records sub procedure. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t battery_level = 90; + bas_battery_level_value_notify(conn_id, bas_id, battery_level); + } + * \endcode + */ +bool gls_report_records_task(uint8_t conn_id, T_SERVER_ID service_id) +{ + bool ret = true; + if (gls_abort_flag == true) + { + PROFILE_PRINT_INFO2("gls_report_records_task Glucose current record = %d, total = %d, procedure abort successfully!\n", + gls_current_record_to_report, gls_num_records_to_report); + gls_current_record_to_report = gls_num_records_to_report; // stop transmitting any data + ret = gls_abort_success_response(conn_id, service_id); + gls_abort_flag = false; + gls_abort_by_app_flag = false; // Abort procedure first, prior to abort by application + return ret; + } + + if (gls_abort_by_app_flag == true) + { + PROFILE_PRINT_INFO2("gls_report_records_task Glucose current record = %d, total = %d, procedure abort by app successfully!\n", + gls_current_record_to_report, gls_num_records_to_report); + gls_current_record_to_report = gls_num_records_to_report; // stop transmitting any data + ret = gls_racp_response(conn_id, service_id, GLC_RACP_RESP_PROC_NOT_COMPLETED); + gls_abort_by_app_flag = false; + return ret; + } + + PROFILE_PRINT_INFO3("gls_report_records_task Glucose report records, current = %d, total = %d, gls_send_data_flag = %d\n", + gls_current_record_to_report, gls_num_records_to_report, gls_send_data_flag); + + if (gls_send_data_flag == 1) + { +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + int current = (glc_racp.record_db.head + gls_report_offset + gls_current_record_to_report) % + GLC_RACP_DATABASE_SIZE; + if (glc_racp.record_db.records[current].glc_measurement_value.flags.ctxt_info_follows == 1) + { + ret = gls_glc_measurement_context_notify(conn_id, service_id, + gls_report_offset + gls_current_record_to_report); + } +#endif + gls_current_record_to_report += 1; + if (gls_send_data_flag == 2) // Glucose measurement context has been sent. + { + return ret; + } + } + + if (gls_current_record_to_report < gls_num_records_to_report) + { + ret = gls_glc_measurement_notify(conn_id, service_id, + gls_report_offset + gls_current_record_to_report); + } + else + { + if (gls_send_data_flag != 3) + { + ret = gls_racp_response(conn_id, service_id, GLC_RACP_RESP_SUCCESS); + } + else // clear control point + { + gls_set_parameter(GLS_PARAM_CTL_PNT_PROG_CLR, 0, NULL); + } + } + return ret; +} + +/** + * @brief Delete records that meet the conditions. + * @param[in] conn_id Connection id. + * @param[in] service_id The service ID of glucose service + * @return None + */ +void gls_delete_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + T_GLC_CTRL_POINT_RESP_CODES ret; + uint16_t num_of_records; + int find1, find2; + ret = gls_find_records(&num_of_records, &find1, &find2); + + PROFILE_PRINT_INFO3("gls_delete_records glucose delete records: num = %d, start = %d, end = %d\n", + num_of_records, find1, find2); + if (ret == GLC_RACP_RESP_SUCCESS) + { + if (num_of_records > 0) + { + if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_ALL_RECS) + { + glc_racp.record_db.head = glc_racp.record_db.tail; + glc_racp.record_db.record_num = 0; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LT_EQ) + { + glc_racp.record_db.head = (find2 + 1) % GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num -= num_of_records; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_GT_EQ) + { + glc_racp.record_db.tail = find1; + glc_racp.record_db.record_num -= num_of_records; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_RANGE) + { + int front = (find1 - glc_racp.record_db.head + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + int back = (glc_racp.record_db.tail - find2 - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + int num2move, move_from, move_to, loop; + if (front > back) + { + num2move = back; + move_from = (find2 + 1) % GLC_RACP_DATABASE_SIZE; + move_to = find1; + for (loop = 0; loop < num2move; loop++) + { + glc_racp.record_db.records[move_to] = glc_racp.record_db.records[move_from]; + move_from = (move_from + 1) % GLC_RACP_DATABASE_SIZE; + move_to = (move_to + 1) % GLC_RACP_DATABASE_SIZE; + } + glc_racp.record_db.tail = (glc_racp.record_db.tail - num_of_records + GLC_RACP_DATABASE_SIZE) % + GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num -= num_of_records; + } + else + { + num2move = front; + move_from = (find1 - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + move_to = find2; + for (loop = 0; loop < num2move; loop++) + { + glc_racp.record_db.records[move_to] = glc_racp.record_db.records[move_from]; + move_from = (move_from - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + move_to = (move_to - 1 + GLC_RACP_DATABASE_SIZE) % GLC_RACP_DATABASE_SIZE; + } + glc_racp.record_db.head = (glc_racp.record_db.head + num_of_records) % GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num -= num_of_records; + } + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_FIRST) + { + glc_racp.record_db.head = (glc_racp.record_db.head + 1) % GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num -= 1; + } + else if (glc_racp.ctrl_point.op == GLC_RACP_OPERATOR_LAST) + { + glc_racp.record_db.tail = (glc_racp.record_db.tail - 1 + GLC_RACP_DATABASE_SIZE) % + GLC_RACP_DATABASE_SIZE; + glc_racp.record_db.record_num -= 1; + } + else + { + ret = GLC_RACP_RESP_OPERAND_NOT_SUPPORTED; + } + } + else + { + ret = GLC_RACP_RESP_NO_RECS_FOUND; + } + } + gls_racp_response(conn_id, service_id, ret); +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result + */ +T_APP_RESULT gls_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_GLS_CALLBACK_DATA gls_upsteam_msg; + PROFILE_PRINT_INFO2("gls_attr_read_cb attribIndex = %d offset %x", attrib_index, offset); + *p_length = 0; + switch (attrib_index) + { + case GLS_CHAR_GLC_FEATURE_INDEX: + { + /* Notify Application. */ + if (pfn_gls_cb) + { + gls_upsteam_msg.msg_data.read_value_index = GLS_EVT_READ_FEATURE; + gls_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + pfn_gls_cb(service_id, (void *)&gls_upsteam_msg); + } + *pp_value = (uint8_t *) &features; + *p_length = sizeof(features); + } + break; + default: + { + PROFILE_PRINT_ERROR1("gls_attr_read_cb, attr not found, index=%d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return cause; +} + +/** + * @brief handle control point write (request). + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] write_length Write request data length. + * @param[in] p_value Pointer to write request data. + * @return none + * @retval void + */ +static void gls_ctl_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t write_length, uint8_t *p_value) +{ + T_GLS_CALLBACK_DATA GLS_upsteam_msg; + /** check if there is any operation running */ + if (write_length > sizeof(T_GLC_CONTROL_POINT)) + { + PROFILE_PRINT_ERROR1("gls_ctl_pnt_write_ind_post_proc GLS Control Point request error: OpCode=0x%x, invalid write length!", + p_value[0]); + return; + } + + PROFILE_PRINT_INFO4("gls_ctl_pnt_write_ind_post_proc Write GLS Control Point: OpCode = %d, operator = %d, length = %d, filter type = %d", + p_value[0], p_value[1], write_length, p_value[2]); + + /* Notify Application. */ + if (pfn_gls_cb) + { + GLS_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + memset(&GLS_upsteam_msg.msg_data.write, 0, sizeof(T_GLC_CONTROL_POINT)); + memcpy(&GLS_upsteam_msg.msg_data.write, p_value, write_length); + pfn_gls_cb(service_id, (void *)&GLS_upsteam_msg); + } + + if (p_value[0] != GLC_RACP_OPCODE_ABORT_OPERATION) + { + memset(&glc_racp.ctrl_point, 0, sizeof(T_GLC_CONTROL_POINT)); + memcpy(&glc_racp.ctrl_point, p_value, write_length); + glc_racp.cp_length = write_length; + switch (glc_racp.ctrl_point.op_code) + { + case GLC_RACP_OPCODE_REPORT_NBR_OF_RECS: + gls_report_num_of_records(conn_id, service_id); + break; + case GLC_RACP_OPCODE_REPORT_RECS: + gls_report_records(conn_id, service_id); + break; + case GLC_RACP_OPCODE_DELETE_RECS: + gls_delete_records(conn_id, service_id); + break; + default: + gls_racp_response(conn_id, service_id, GLC_RACP_RESP_OPCODE_NOT_SUPPORTED); + break; + } + } + else + { + if ((glc_racp.ctrl_point.op_code != GLC_RACP_OPCODE_RESERVED) && (gls_send_data_flag != 3)) + { + gls_abort_flag = true; + //while (gls_abort_flag == TRUE) ; /* halt until AbortFlag is disabled when procedure in progress has been aborted */ + } + else + { + gls_abort_success_response(conn_id, service_id); + } + } +} + +/** + * @brief Check CCCD configuration + * @return Result of check + * @retval TRUE + * @retval FALSE + */ +bool gls_check_cccd() +{ + if (0 == glc_notify_indicate_flag.GLC_measurement_notify_enable) + { + return false; + } + else if (0 == glc_notify_indicate_flag.GLC_measurement_context_notify_enable) + { + return false; + } + else if (0 == glc_notify_indicate_flag.GLC_RACP_indicate_enable) + { + return false; + } + else + { + return true; + } +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] length Length of value to be written. + * @param p_value Value to be written. + * @return Profile procedure result + */ +T_APP_RESULT gls_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO2("gls_attr_write_cb attrib_index = %d, length = %x", attrib_index, length); + switch (attrib_index) + { + case GLS_CHAR_GLC_RACP_INDEX: + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > sizeof(T_GLC_CONTROL_POINT)) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + /* Make sure Control Point is not "Process already in progress". */ + else if (GLC_RACP_OPERATION_ACTIVE(glc_racp.ctrl_point.op_code) && + (p_value[0] != GLC_RACP_OPCODE_ABORT_OPERATION)) + { + cause = (T_APP_RESULT)(ATT_ERR | GLC_ERR_PROC_ALREADY_IN_PROGRESS); + } + /* Make sure Control Point is configured indication enable. */ + else if (!gls_check_cccd()) + { + cause = (T_APP_RESULT)(ATT_ERR | GLC_ERR_CCCD_IMPROPERLY_CONFIGURED); + } + else + { + //wCause = GLS_Hanlde_CtlPntProc(ServiceId, wLength, pValue); + /** handle RACP request after sending write response */ + PROFILE_PRINT_INFO2("gls_attr_write_cb opcode: old = %d, new = %d\n", glc_racp.ctrl_point.op_code, + p_value[0]); + *p_write_ind_post_proc = gls_ctl_pnt_write_ind_post_proc; + } + + } + break; + + default: + { + PROFILE_PRINT_ERROR1("gls_attr_write_cb attribIndex = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return cause; +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None + */ +void gls_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_GLS_CALLBACK_DATA gls_upsteam_msg; + bool handle = true; + PROFILE_PRINT_INFO2("gls_cccd_update_cb Index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GLS_CHAR_GLC_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + glc_notify_indicate_flag.GLC_measurement_notify_enable = 1; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_NOTIFY_ENABLE; + } + else + { + // Disable Notification + glc_notify_indicate_flag.GLC_measurement_notify_enable = 0; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_NOTIFY_DISABLE; + } + } + break; +#if GLC_MEASUREMENT_CONTEXT_SUPPORT + case GLS_CHAR_GLC_MEASUREMENT_CONTEXT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + glc_notify_indicate_flag.GLC_measurement_context_notify_enable = 1; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_ENABLE; + } + else + { + // Disable Notification + glc_notify_indicate_flag.GLC_measurement_context_notify_enable = 0; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_MEASUREMENT_CONTEXT_NOTIFY_DISABLE; + } + } + break; +#endif + case GLS_CHAR_GLC_RACP_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + // Enable Notification + glc_notify_indicate_flag.GLC_RACP_indicate_enable = 1; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_RACP_INDICATE_ENABLE; + } + else + { + // Disable Notification + glc_notify_indicate_flag.GLC_RACP_indicate_enable = 0; + gls_upsteam_msg.msg_data.notify_indicate_index = GLS_EVT_GLC_RACP_INDICATE_DISABLE; + } + } + break; + default: + { + handle = false; + PROFILE_PRINT_ERROR1("gls_cccd_update_cb index = %d not found", index); + } + break; + } + /* Notify Application. */ + if (pfn_gls_cb && (handle == true)) + { + gls_upsteam_msg.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + pfn_gls_cb(service_id, (void *)&gls_upsteam_msg); + } +} + +/** + * @brief Simple Profile Service Callbacks. + */ +const T_FUN_GATT_SERVICE_CBS gls_cbs = +{ + gls_attr_read_cb, // Read callback function pointer + gls_attr_write_cb, // Write callback function pointer + gls_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add gulcose service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + gls_id = gls_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID gls_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)gls_att_tbl, + sizeof(gls_att_tbl), + gls_cbs)) + { + PROFILE_PRINT_ERROR1("gls_add_service: ServiceId %d", service_id); + service_id = 0xff; + return service_id; + } + glc_racp.record_db.record_num = 0; + glc_racp.record_db.head = 0; + glc_racp.record_db.tail = 0; + glc_racp.record_db.seq_num = GLC_RACP_INIT_SEQ_NBR_DEFAULT; + pfn_gls_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/** + * @brief Abort RACP procedure by app. + * + * @return void. + * + * Example usage + * \code{.c} + void test(void) + { + gls_abort_racp_procedure(); + } + * \endcode + */ +void gls_abort_racp_procedure(void) +{ + if ((glc_racp.ctrl_point.op_code != GLC_RACP_OPCODE_RESERVED) && (gls_send_data_flag != 3)) + { + gls_abort_by_app_flag = true; + } +} diff --git a/src/ble/profile/server/hids.c b/src/ble/profile/server/hids.c new file mode 100644 index 0000000..0f2bad5 --- /dev/null +++ b/src/ble/profile/server/hids.c @@ -0,0 +1,772 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "hids.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +T_HID_INFO hid_info = {0, 0, 0}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /* <>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + 0x00, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, + (GATT_PERM_READ) /* wPermissions */ + }, + + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /*report ID map reference descriptor .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + 0x00, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ) /* wPermissions */ + }, + + /* <>, .. 10*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 11*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /*report ID map reference descriptor .. 12*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + 0x00, + HID_FEATURE_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, + (GATT_PERM_READ) /* wPermissions */ + }, + + /* <>, .. 13*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ /* permissions */ + }, + + /* <>, .. 16*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ_AUTHEN_REQ /* permissions */ + }, + + /* HID boot keyboard input characteristic value .. 17*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* client characteristic configuration .. 18*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ + }, + + /* <>, .. 19*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ_AUTHEN_REQ /* permissions */ + }, + + /* HID boot keyboard output characteristic value .. 20*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* <>, .. 21*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID boot mouse input characteristic value .. 22*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + + /* client characteristic configuration .. 23*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ + }, + + /* <>, .. 24*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 25*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 26*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 27*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + } + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_KB_IN_REPORT: + break; + + case HID_BOOT_KB_OUT_REPORT: + break; + + case HID_BOOT_MS_IN_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/hids_kb.c b/src/ble/profile/server/hids_kb.c new file mode 100644 index 0000000..644cc82 --- /dev/null +++ b/src/ble/profile/server/hids_kb.c @@ -0,0 +1,851 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_kb.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "hids_kb.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + +/* Report ID for General Keyboard, change: 0x03 to 0x01 */ +#define HOGP_KB_REPORT_ID 0x03 +#define HOGP_MM_REPORT_ID 0x04 +#define MULTIMEDIA_KEYBOARD +T_HID_INFO hid_info = {0, 0, 0x0100}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + +const uint8_t hids_report_descriptor[] = +{ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_KB_REPORT_ID, /* REPORT_ID (3) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x08, /* REPORT_COUNT (8) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x91, 0x01, /* OUTPUT (Cnst,Var,Abs) */ + 0x95, 0x06, /* REPORT_COUNT (6) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xa4, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */ + 0x29, 0xa4, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ +#ifdef MULTIMEDIA_KEYBOARD + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_MM_REPORT_ID, /* REPORT_ID (4) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x18, /* REPORT_COUNT (24) */ + 0x09, 0xb5, /* USAGE (Scan Next Track) */ + 0x09, 0xb6, /* USAGE (Scan Previous Track) */ + 0x09, 0xb7, /* USAGE (Stop) */ + 0x09, 0xcd, /* USAGE (Play/Pause) */ + 0x09, 0xe2, /* USAGE (Mute) */ + 0x09, 0xe5, /* USAGE (Bass Boost) */ + 0x09, 0xe7, /* USAGE (Loudness) */ + 0x09, 0xe9, /* USAGE (Volume Increment) */ + 0x09, 0xea, /* USAGE (Volume Decrement) */ + 0x0a, 0x52, 0x01, /* USAGE (Bass Increment) */ + 0x0a, 0x53, 0x01, /* USAGE (Bass Decrement) */ + 0x0a, 0x54, 0x01, /* USAGE (Treble Increment) */ + 0x0a, 0x55, 0x01, /* USAGE (Treble Decrement) */ + 0x0a, 0x83, 0x01, /* USAGE (AL Consumer Control Configuration) */ + 0x0a, 0x8a, 0x01, /* USAGE (AL Email Reader) */ + 0x0a, 0x92, 0x01, /* USAGE (AL Calculator) */ + 0x0a, 0x94, 0x01, /* USAGE (AL Local Machine Browser) */ + 0x0a, 0x21, 0x02, /* USAGE (AC Search) */ + 0x0a, 0x23, 0x02, /* USAGE (AC Home) */ + 0x0a, 0x24, 0x02, /* USAGE (AC Back) */ + 0x0a, 0x25, 0x02, /* USAGE (AC Forward) */ + 0x0a, 0x26, 0x02, /* USAGE (AC Stop) */ + 0x0a, 0x27, 0x02, /* USAGE (AC Refresh) */ + 0x0a, 0x2a, 0x02, /* USAGE (AC Bookmarks) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0xc0 /* END_COLLECTION */ +#endif +}; + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KB_REPORT_ID, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 10*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 11*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 12*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_KB_REPORT_ID, + HID_FEATURE_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 13*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + }, + 0, /* bValueLen */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* permissions */ + }, + + /* <>, .. 16*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard input characteristic value .. 17*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* client characteristic configuration .. 18*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ + }, + + /* <>, .. 19*/ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID boot keyboard output characteristic value .. 20*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ + }, + + /* <>, .. 21*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 22*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 23*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 24*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + +#ifdef MULTIMEDIA_KEYBOARD + /* <>, .. 25*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value ,multimedia keyboard Input 26*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 3, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration 27*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor 28*/ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_MM_REPORT_ID, /* client char. config. bit field */ + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + } +#endif + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_KB_IN_REPORT: + break; + + case HID_BOOT_KB_OUT_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + + case GATT_SVC_HID_REPORT_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.output = *p_value; + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_KB_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/hids_ms.c b/src/ble/profile/server/hids_ms.c new file mode 100644 index 0000000..8e5a9fc --- /dev/null +++ b/src/ble/profile/server/hids_ms.c @@ -0,0 +1,861 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_ms.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-01 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "hids_ms.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_MS_IN_REPORT 0x2A33 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + +#define HOGP_MOUSE_REPORT_ID 1 +#define HOGP_VENDOR_REPORT_ID 0x10 + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +T_HID_INFO hid_info = {0, 0, 0}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + +const uint8_t hids_report_descriptor[] = +{ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) main item*/ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_MOUSE_REPORT_ID, /* REPORT_ID (1) */ + 0x09, 0x01, /* USAGE (Pointer) */ + 0xa1, 0x00, /* COLLECTION (Physical) */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Button 5) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x81, 0x01, /* INPUT (Cnst,Var,Abs) */ + + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) main item*/ + 0x09, 0x30, /* USAGE (X) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x16, 0x01, 0x80, /* LOGICAL_MINIMUM (-32767) */ + 0x26, 0xff, 0x7f, /* LOGICAL_MAXIMUM (32767) */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ + 0x09, 0x38, /* USAGE (Wheel) */ + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ + 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ + 0xc0, /* END_COLLECTION */ + 0xc0, /* END_COLLECTION */ + + 0x06, 0x01, 0xff, /* USAGE_PAGE (vendor) */ + 0x09, 0x01, /* USAGE (vendor) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_VENDOR_REPORT_ID, /* REPORT_ID (0x10) */ + 0x19, 0x00, /* USAGE_MINIMUM (0) */ + 0x29, 0xff, /* USAGE_MAXIMUM (0xff) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (0xff) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x04, /* REPORT_COUNT (4) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ +}; + + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /* <>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ +#endif + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_MOUSE_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif + }, + + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /* client characteristic configuration .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ +#endif + }, + + /*report ID map reference descriptor .. 10*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_VENDOR_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif + }, + + /* <>, .. 11*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 12*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /*report ID map reference descriptor .. 13*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_MOUSE_REPORT_ID, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif + }, + + /* <>, .. 14*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /*report ID map reference descriptor .. 16*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_MOUSE_REPORT_ID, + HID_FEATURE_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif + }, + + /* <>, .. 17*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 18*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ /* wPermissions */ +#endif + }, + + /* <>, .. 19*/ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), + }, + 0, /* bValueLen */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif /* permissions */ + }, + + /* <>, .. 20*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID boot mouse input characteristic value .. 21*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT), + HI_WORD(GATT_UUID_CHAR_BOOT_MS_IN_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + + /* client characteristic configuration .. 22*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* <>, .. 23*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 24*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ /* wPermissions */ +#endif + }, + + /* <>, .. 25*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 26*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + } + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_MS_IN_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + + case GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + + case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + + case GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + + case GATT_SVC_HID_REPORT_FEATURE_INDEX: + break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + + case GATT_SVC_HID_BOOT_MS_IN_REPORT_INDEX: + break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_MOUSE_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + case GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_VNEDOR_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + case GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_BOOT_MS_IN_REPORT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_MOUSE_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} diff --git a/src/ble/profile/server/hids_mulkb.c b/src/ble/profile/server/hids_mulkb.c new file mode 100644 index 0000000..4efd895 --- /dev/null +++ b/src/ble/profile/server/hids_mulkb.c @@ -0,0 +1,1032 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file hids_mulkb.c + * @brief Source file for using Human Interface Device Service. + * @details Global data and function implement. + * @author sonny_shen + * @date 2022-7-04 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "hids_mulkb.h" + + +#define GATT_UUID_HID 0x1812 +#define GATT_UUID_CHAR_PROTOCOL_MODE 0x2A4E +#define GATT_UUID_CHAR_REPORT 0x2A4D +#define GATT_UUID_CHAR_REPORT_MAP 0x2A4B +#define GATT_UUID_CHAR_BOOT_KB_IN_REPORT 0x2A22 +#define GATT_UUID_CHAR_BOOT_KB_OUT_REPORT 0x2A32 +#define GATT_UUID_CHAR_HID_INFO 0x2A4A +#define GATT_UUID_CHAR_HID_CONTROL_POINT 0x2A4C + +/* Report ID for General Keyboard, change: 0x03 to 0x01 */ +#define HOGP_KEYBOARD_REPORT_ID 0x01 +#define HOGP_CONSUMER_REPORT_ID 0x03 +#define HOGP_VENDOR_REPORT_ID 0x10 +#define MULTIMEDIA_KEYBOARD +T_HID_INFO hid_info = {0x0100, 0, 0}; +T_HID_PROTOCOL_MODE hid_protocol_mode = BOOT_PROTOCOL_MODE; +uint8_t hid_suspand_mode = 0; +uint16_t external_report_refer = 0; + + +// keyboard data format(full key unshocked) +//byte index USAGE ID Func +//0 0xE0 ~ 0xE7 LeftControl ~ RightGUI +//1 NULL Const Value 0 +//2 0x04 ~ 0x0B (A & a) ~ (H & h) +//3 0x0C ~ 0x13 (I & i) ~ (P & p) +// +//14 0x64 ~ 0x6B (Keyboard Non-US ) ~ (Keyboard F16) +const uint8_t hids_report_descriptor[] = +{ +#if FEATURE_SUPPORT_FULL_KEY_UNSHOCKED + /* REPORT_ID (1) */ + /*USAGE_PAGE (Generic Desktop)*/ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, HOGP_KEYBOARD_REPORT_ID, /* REPORT_ID (1) */ + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x08, // REPORT_COUNT (8) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0x04, // USAGE_MINIMUM (Keyboard a and A) + 0x29, 0x6A, // USAGE_MAXIMUM (Keyboard Application) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x67, // REPORT_COUNT (103) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + + 0x05, 0x08, // USAGE_PAGE (LEDs) + 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + 0x29, 0x05, // USAGE_MAXIMUM (Kana) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x05, // REPORT_COUNT (5) + 0x75, 0x01, // REPORT_SIZE (1) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x03, // REPORT_SIZE (3) + 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + 0xc0, // END_COLLECTION +#else + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_KEYBOARD_REPORT_ID, /* REPORT_ID (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x08, /* REPORT_COUNT (8) */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard Left Control) */ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x81, 0x02, /*input (Data,variable,Abs)*/ +// 0x95, 0x01, /* REPORT_COUNT (1) */ +// 0x75, 0x08, /* REPORT_SIZE (8) */ +// 0x81, 0x03, /*input (cons,variable,Abs)*/ + + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x03, /* REPORT_SIZE (3) */ + 0x91, 0x03, /* OUTPUT (cons,Var,Abs) */ + + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xFF, /* LOGICAL_MAXIMUM (164) */ /* Can be 255 */ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved-no event indicated) */ + 0x29, 0xFF, /* USAGE_MAXIMUM (Keyboard Application) */ /* Can be 255 */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ +#endif + + /* REPORT_ID (3) */ + /* USAGE_PAGE (Consumer) */ + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_CONSUMER_REPORT_ID, /* REPORT_ID (3) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x26, 0x80, 0x03, /* LOGICAL_MAXIMUM (896) */ + 0x19, 0x00, /* USAGE_MINIMUM */ + 0x2a, 0x80, 0x03, /* USAGE_MAXIMUM */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ + + /* REPORT_ID (4) */ + /*USAGE_PAGE (Generic Desktop)*/ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x80, /* USAGE (system control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, 0x04, /* REPORT_ID (4) */ + 0x19, 0x81, /* USAGE_MINIMUM (system power down)*/ + 0x29, 0x83, /* USAGE_MAXIMUM (system wake up)*/ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,value,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x05, /* REPORT_SIZE (5) */ + 0x81, 0x01, /* INPUT (cons,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ + + /* REPORT_ID (5) */ + /* USAGE_PAGE (Consumer) */ + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, 0x05, /* REPORT_ID (5) */ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x06, /* USAGE (Keyboard) */ + 0xa1, 0x02, /* COLLECTION (logical) */ + 0x06, 0x00, 0xFF, /* USAGE_PAGE (vendor defined) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0x0a, 0x03, 0xfe, /* USAGE (vendor defined) */ + 0x0a, 0x04, 0xfe, /* USAGE (vendor defined) */ + 0x81, 0x02, /* INPUT (Data,value,Abs) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x06, 0xff, 0x00, + 0x09, 0x03, + 0x81, 0x02, /* INPUT (Data,value,Abs) */ + 0x95, 0x05, /* REPORT_COUNT (5) */ + 0x81, 0x03, /* INPUT (cons,value,Abs) */ + 0xc0, /* END_COLLECTION */ + 0xc0, /* END_COLLECTION */ + + /* REPORT_ID (10) */ + /* USAGE_PAGE (Consumer) */ + 0x06, 0x01, 0xff, /* USAGE_PAGE (vendor) */ + 0x09, 0x01, /* USAGE (vendor) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HOGP_VENDOR_REPORT_ID, /* REPORT_ID (0x10) */ + 0x19, 0x00, /* USAGE_MINIMUM (0) */ + 0x29, 0xff, /* USAGE_MAXIMUM (0xff) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0xff, /* LOGICAL_MAXIMUM (0xff) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x04, /* REPORT_COUNT (4) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ +}; + +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +static const T_ATTRIB_APPL hids_attr_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Protocol Mode characteristic value ..2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, .. 3*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID KB Report characteristic value .. 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration .. 5*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 6*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KEYBOARD_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 7*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /*report ID map reference descriptor .. 9*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_KEYBOARD_REPORT_ID, + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 10*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID comsumer Report characteristic value .. 11*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + + /* client characteristic configuration .. 12*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + }, + + /*report ID map reference descriptor .. 13*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HOGP_CONSUMER_REPORT_ID, + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, + (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ + }, + + /* <>, .. 14*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Report characteristic value .. 15*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ +#endif + }, + + /* client characteristic configuration .. 16*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ +#endif + }, + + /*report ID map reference descriptor .. 17*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HOGP_VENDOR_REPORT_ID, + HID_INPUT_TYPE, + }, + 2, /* bValueLen */ + NULL,//(void*)&cPointerInputReportIdMap, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* wPermissions */ +#endif + }, + + + /*only write report id 1 and report id 3, need to add report id 4 and report id 5 later*/ + + + /* <>, .. 18*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID report map characteristic value .. 19*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + +// /* <>, .. 16*/ +// { +// ATTRIB_FLAG_VALUE_APPL, /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), +// HI_WORD(GATT_UUID_CHAR_EXTERNAL_REPORT_REFERENCE), +// }, +// 0, /* bValueLen */ +// (void *)NULL, +// GATT_PERM_READ_AUTHEN_REQ /* permissions */ +// }, + +// /* <>, .. 17*/ +// { +// ATTRIB_FLAG_VALUE_INCL, /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHARACTERISTIC), +// HI_WORD(GATT_UUID_CHARACTERISTIC), +// GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ +// /* characteristic UUID not needed here, is UUID of next attrib. */ +// }, +// 1, /* bValueLen */ +// NULL, +// GATT_PERM_READ /* permissions */ +// }, + +// /* HID boot keyboard input characteristic value .. 18*/ +// { +// ATTRIB_FLAG_VALUE_APPL, /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT), +// HI_WORD(GATT_UUID_CHAR_BOOT_KB_IN_REPORT) +// }, +// 0, /* variable size */ +// (void *)NULL, +// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +// }, + +// /* client characteristic configuration .. 19*/ +// { +// (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL), /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), +// HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), +// /* NOTE: this value has an instantiation for each client, a write to */ +// /* this attribute does not modify this default value: */ +// LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ +// HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) +// }, +// 2, /* bValueLen */ +// NULL, +// (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +// }, + +// /* <>, .. 20*/ +// { +// ATTRIB_FLAG_VALUE_INCL, /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHARACTERISTIC), +// HI_WORD(GATT_UUID_CHARACTERISTIC), +// GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ +// /* characteristic UUID not needed here, is UUID of next attrib. */ +// }, +// 1, /* bValueLen */ +// NULL, +// GATT_PERM_READ /* permissions */ +// }, + +// /* HID boot keyboard output characteristic value .. 21*/ +// { +// ATTRIB_FLAG_VALUE_APPL, /* flags */ +// { /* type_value */ +// LO_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT), +// HI_WORD(GATT_UUID_CHAR_BOOT_KB_OUT_REPORT) +// }, +// 0, /* variable size */ +// (void *)NULL, +// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +// }, + + /* <>, .. 20*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID Information characteristic value .. 21*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ /* wPermissions */ + }, + + /* <>, ...22*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* HID controlPoint characteristic value .. 23*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ + }, + +//#ifdef MULTIMEDIA_KEYBOARD +// /* <>, .. 25*/ +// { +// ATTRIB_FLAG_VALUE_INCL, /* wFlags */ +// { /* bTypeValue */ +// LO_WORD(GATT_UUID_CHARACTERISTIC), +// HI_WORD(GATT_UUID_CHARACTERISTIC), +// GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ +// //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ +// /* characteristic UUID not needed here, is UUID of next attrib. */ +// }, +// 1, /* bValueLen */ +// NULL, +// GATT_PERM_READ /* wPermissions */ +// }, + +// /* HID Report characteristic value ,multimedia keyboard Input 26*/ +// { +// ATTRIB_FLAG_VALUE_APPL, /* wFlags */ +// { /* bTypeValue */ +// LO_WORD(GATT_UUID_CHAR_REPORT), +// HI_WORD(GATT_UUID_CHAR_REPORT) +// }, +// 3, /* variable size */ +// (void *)NULL, +// GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* wPermissions */ +// }, + +// /* client characteristic configuration 27*/ +// { +// (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ +// ATTRIB_FLAG_CCCD_APPL), +// { /* bTypeValue */ +// LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), +// HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), +// /* NOTE: this value has an instantiation for each client, a write to */ +// /* this attribute does not modify this default value: */ +// LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ +// HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) +// }, +// 2, /* bValueLen */ +// NULL, +// (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ +// }, + +// /*report ID map reference descriptor 28*/ +// { +// (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ +// ATTRIB_FLAG_CCCD_APPL), +// { /* bTypeValue */ +// LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), +// HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), +// /* NOTE: this value has an instantiation for each client, a write to */ +// /* this attribute does not modify this default value: */ +// HOGP_MM_REPORT_ID, /* client char. config. bit field */ +// HID_INPUT_TYPE +// }, +// 2, /* bValueLen */ +// NULL, +// (GATT_PERM_READ_AUTHEN_REQ) /* wPermissions */ +// } +//#endif + +}; + +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(T_HIDS_PARAM_TYPE param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HID_PROTOCOL_MODE: + { + hid_protocol_mode = (T_HID_PROTOCOL_MODE) * ((uint8_t *)value_ptr); + } + break; + + case HID_REPORT_INPUT: + break; + + case HID_REPORT_OUTPUT: + break; + + case HID_REPORT_FEATURE: + break; + + case HID_REPORT_MAP: + break; + + case HID_EXTERNAL_REPORT_REFER: + { + external_report_refer = *(uint16_t *)value_ptr; + } + break; + + case HID_BOOT_KB_IN_REPORT: + break; + + case HID_BOOT_KB_OUT_REPORT: + break; + + case HID_INFO: + { + memcpy((void *)&hid_info, value_ptr, length); + } + break; + + case HID_CONTROL_POINT: + hid_suspand_mode = *((uint8_t *)value_ptr); + break; + + default: + ret = false; + break; + } + return ret; +} + + +static T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.conn_id = conn_id; + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_protocol_mode; + *p_length = sizeof(hid_protocol_mode); + break; + +// case GATT_SVC_HID_REPORT_INPUT_INDEX: +// break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + break; + +// case GATT_SVC_HID_REPORT_FEATURE_INDEX: +// break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + break; + + case GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_EXTERNAL_REPORT_REFER_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&external_report_refer; + *p_length = sizeof(external_report_refer); + break; + +// case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: +// break; + +// case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: +// break; + + case GATT_SVC_HID_INFO_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_INFO_INDEX; + cause = pfn_hids_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hid_info; + *p_length = sizeof(hid_info); + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + return cause; +} + + +static T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_PROTOCOL_MODE_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.protocol_mode = *p_value; + hids_set_parameter(HID_PROTOCOL_MODE, length, p_value); + break; + +// case GATT_SVC_HID_REPORT_INPUT_INDEX: +// break; + + case GATT_SVC_HID_REPORT_OUTPUT_INDEX: + callback_data.msg_data.read_value_index = GATT_SVC_HID_REPORT_OUTPUT_INDEX; + callback_data.msg_data.write_msg.write_type = write_type; + callback_data.msg_data.write_msg.write_parameter.output = *p_value; + break; + +// case GATT_SVC_HID_REPORT_FEATURE_INDEX: +// break; + + case GATT_SVC_HID_REPORT_MAP_INDEX: + break; + +// case GATT_SVC_HID_BOOT_KB_IN_REPORT_INDEX: +// break; + +// case GATT_SVC_HID_BOOT_KB_OUT_REPORT_INDEX: +// break; + + case GATT_SVC_HID_INFO_INDEX: + break; + + case GATT_SVC_HID_CONTROL_POINT_INDEX: + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + bool cause = true; + T_HID_CALLBACK_DATA callback_data; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + default: + cause = false; + break; + + case GATT_SVC_HID_REPORT_KEYBOARD_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_KEYBOARD_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + case GATT_SVC_HID_REPORT_CONSUMER_INPUT_CCCD_INDEX: + { + callback_data.msg_data.not_ind_data.index = GATT_SVC_HID_REPORT_CONSUMER_INPUT_CCCD_INDEX; + if (ccc_bits & GATT_PDU_TYPE_NOTIFICATION) + { + callback_data.msg_data.not_ind_data.value = NOTIFY_ENABLE; + } + else + { + callback_data.msg_data.not_ind_data.value = NOTIFY_DISABLE; + } + break; + } + + } + + if (pfn_hids_cb && (cause == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + + +/** + * @brief Send HIDS notification data . + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index hids characteristic index. + * @param[in] p_data report value pointer. + * @param[in] data_len length of report data. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = 0; + T_SERVER_ID service_id = hids_id; + uint8_t hid_report_input[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + hids_send_report(conn_id, service_id, GATT_SVC_HID_REPORT_INPUT_INDEX, hid_report_input, sizeof(hid_report_input)); + } + * \endcode + */ +bool hids_send_report(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint8_t *p_data, + uint16_t data_len) +{ + PROFILE_PRINT_INFO1("hids_send_report data_len %d", data_len); + return server_send_data(conn_id, service_id, index, p_data, data_len, GATT_PDU_TYPE_NOTIFICATION); +} + + + +uint16_t hids_attr_tbl_len = sizeof(hids_attr_tbl); + +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb, // Authorization callback function pointer +}; + +/** + * @brief Add HID service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hids_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hids_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, (uint8_t *)hids_attr_tbl, hids_attr_tbl_len, hids_cbs)) + { + PROFILE_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/hids_rmc.c b/src/ble/profile/server/hids_rmc.c new file mode 100644 index 0000000..8875354 --- /dev/null +++ b/src/ble/profile/server/hids_rmc.c @@ -0,0 +1,863 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file hids_rmc.c +* @brief Remote control HID service source file. +* @details Interfaces to access HIDS service. +* @author +* @date 2020-03-11 +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "profile_server.h" +#include "hids_rmc.h" +#include +#include +#include "board.h" + +/*============================================================================* + * Local Variables + *============================================================================*/ +static P_FUN_SERVER_GENERAL_CB pfn_hids_cb = NULL; + +static const uint8_t hids_report_descriptor[] = +{ + 0x05, 0x01, /* Usage Page(Generic Desktop) */ + 0x09, 0x06, /* Usage (Keyboard) */ + 0xa1, 0x01, /* Collection Application */ + + 0x05, 0x07, /* Usage Page (Keyboard) */ + 0x09, 0x06, /* Usage (Keyboard) */ + 0xa1, 0x01, /* Collection Application */ + 0x85, HIDS_KB_REPORT_ID, /* Report Id */ + 0x95, 0x08, /* Report Count */ + 0x75, 0x08, /* Report Size */ + 0x15, 0x00, /* Logical Minimum */ + 0x25, 0xff, /* Logical Maximum */ + 0x19, 0x00, /* Usage Minimum */ + 0x29, 0xff, /* Usage Maximun */ + 0x81, 0x00, /* Input */ + 0xc0, /* End Collection */ + +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD + 0x05, 0x0c, /* USAGE_PAGE (Consumer) */ + 0x09, 0x01, /* USAGE (Consumer Control) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HIDS_MM_KB_REPORT_ID, /* REPORT_ID (4) */ + 0x95, 0x03, /* report count */ + 0x75, 0x10, /* report size */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x26, 0x9C, 0x02, /* LOGICAL_MAXIMUM (1) */ + 0x19, 0x00, /* Usage Minimum */ + 0x2A, 0x9C, 0x02, /* Usage Maximun */ + 0x81, 0x00, /* INPUT (Data,Var,Abs) */ + 0xc0, /* END_COLLECTION */ +#endif + +#if SUPPORT_VOICE_FEATURE + 0x06, 0x00, 0xff, /* USAGE_PAGE (vendor define) */ + 0x09, 0x00, /* USAGE (Undefine) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, HIDS_VOICE_REPORT_ID, /* REPORT_ID (RMC_VENDOR_REPORT_ID_1) */ + 0x95, 0xff, /* Report Count */ + 0x75, 0x08, /* Report Size */ + 0x15, 0x00, /* Logical Minimum */ + 0x25, 0xff, /* Logical Maximum */ + 0x19, 0x00, /* Usage Minimum */ + 0x29, 0xff, /* Usage Maximun */ + 0x81, 0x00, /* Input */ + 0xc0, /* End Collection */ +#endif + + 0xc0 /* End Collection */ +}; + +static uint8_t hids_protocol_mode = REPORT_PROCOCOL_MODE; +static uint8_t hids_suspand_mode = 0; +static HID_INFO_ATTRB hids_info = {0, 0, 0x0100}; +static uint8_t *p_report_data = NULL; +static uint16_t RmcDataLen = 0; + + +const T_ATTRIB_APPL hids_attr_table[] = +{ + /*--------------------------HID Service ---------------------------*/ + /* <> 0 */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HID), /* service UUID */ + HI_WORD(GATT_UUID_HID) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* p_value_context */ + GATT_PERM_READ /* permissions */ + }, + + /* <> 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Information characteristic 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_HID_INFO), + HI_WORD(GATT_UUID_CHAR_HID_INFO) + }, + 4, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ /* permissions */ +#endif + }, + + /* <> 3 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID controlPoint characteristic 4 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_HID_CONTROL_POINT) + }, + 1, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* <> 5 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Protocol Mode characteristic 6 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_MODE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_MODE) + }, + 1, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* <> 7 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Report Map characteristic 8 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT_MAP), + HI_WORD(GATT_UUID_CHAR_REPORT_MAP) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ /* permissions */ +#endif + }, + + /* <> 9 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* Keyboard Input Report characteristic 10 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 8, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* client characteristic configuration 11 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + }, + + /* Keyboard Input Report reference descriptor 12 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HIDS_KB_REPORT_ID, /* client char. config. bit field */ + 1 + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* permissions */ +#endif + }, + +#if SUPPORT_VOICE_FEATURE + /* <> 13 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Report characteristic value, Voice Input 14 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 255, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* client characteristic configuration 15 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + }, + + /* Voice Input reference descriptor 16 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HIDS_VOICE_REPORT_ID, /* client char. config. bit field */ + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* permissions */ +#endif + }, + + /* <> 17 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Report characteristic value, Voice Output 18 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 0, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* Voice Output reference descriptor 19 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HIDS_VOICE_REPORT_ID, /* client char. config. bit field */ + HID_OUTPUT_TYPE + }, + 2, /* bValueLen */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* permissions */ +#endif + }, +#endif + +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD + /* <> 20 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY | GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* HID Report characteristic value, multimedia keyboard Input 21 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT), + HI_WORD(GATT_UUID_CHAR_REPORT) + }, + 3, /* variable size */ + (void *)NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ | GATT_PERM_WRITE /* permissions */ +#endif + }, + + /* client characteristic configuration 22 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + }, + + /* multimedia keyboard Input reference descriptor 23 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* flags */ + ATTRIB_FLAG_CCCD_APPL), + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + HI_WORD(GATT_UUID_CHAR_REPORT_REFERENCE), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + HIDS_MM_KB_REPORT_ID, /* client char. config. bit field */ + HID_INPUT_TYPE + }, + 2, /* bValueLen */ + NULL, +#if FEATURE_SUPPORT_HIDS_CHAR_AUTHEN_REQ + (GATT_PERM_READ_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ) /* permissions */ +#endif + } +#endif +}; + + +static uint16_t hids_attr_tbl_size = sizeof(hids_attr_table); + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief Set a HID service parameter. + * + * NOTE: You can call this function with a HID service parameter type and it will set the + * HID service parameter. HID service parameters are defined in @ref T_HIDS_PARAM_TYPE. + * + * @param[in] param_type HID service parameter type: @ref T_HIDS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t mode = 1; + hids_set_parameter(HID_PROTOCOL_MODE, 1, &mode); + } + * \endcode + */ +bool hids_set_parameter(uint8_t param_type, uint8_t length, void *value_ptr) +{ + bool ret = true; + + switch (param_type) + { + case HIDS_PARAM_PROTOCOL_MODE: + { + hids_protocol_mode = *((uint8_t *)value_ptr); + } + break; + case HIDS_PARAM_SUSPEND_MODE: + { + hids_suspand_mode = *((uint8_t *)value_ptr); + } + break; + case HIDS_PARAM_HID_INFO: + { + memcpy((void *)&hids_info, value_ptr, length); + } + break; + case HIDS_PARAM_REPORT: + { + RmcDataLen = length; + p_report_data = value_ptr; + } + break; + + default: + ret = false; + break; + + } + return ret; +} + +/** + * @brief read characteristic data from service. + * + * @param conn_id Connection ID. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Offset of characteritic to be read. + * @param p_length Length of getting characteristic data. + * @param pp_value Pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT hids_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + *p_length = 0; + + PROFILE_PRINT_INFO2("hids_attr_read_cb attrib_index = %d offset %x", attrib_index, offset); + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SRV_HID_KB_INPUT_INDEX: +#if SUPPORT_VOICE_FEATURE + case GATT_SRV_HID_VOICE_INPUT_INDEX: + case GATT_SRV_HID_VOICE_OUTPUT_INDEX: +#endif +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD + case GATT_SRV_HID_MM_KB_INPUT_INDEX: +#endif + { + callback_data.msg_data.read_value_index = HIDS_READ_PARAM_REPORT; + if (pfn_hids_cb) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + *pp_value = p_report_data; + *p_length = RmcDataLen; + if ((*p_length == 0) || (NULL == p_report_data)) + { + cause = APP_RESULT_APP_ERR; + } + } + break; + + case GATT_SVC_HID_INFO_INDEX: + { + callback_data.msg_data.read_value_index = HIDS_READ_PARAM_HID_INFO; + if (pfn_hids_cb) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + *pp_value = (uint8_t *)&hids_info; + *p_length = sizeof(hids_info); + } + break; + case GATT_SVC_HID_CONTROL_POINT_INDEX: + { + callback_data.msg_data.read_value_index = HIDS_READ_PARAM_SUSPEND_MODE; + if (pfn_hids_cb) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + *pp_value = &hids_suspand_mode; + *p_length = 1; + } + break; + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + { + callback_data.msg_data.read_value_index = HIDS_READ_PARAM_PROTOCOL_MODE; + if (pfn_hids_cb) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + *pp_value = &hids_protocol_mode; + *p_length = sizeof(hids_protocol_mode); + } + break; + case GATT_SVC_HID_REPORT_MAP_INDEX: + { + *pp_value = (uint8_t *)hids_report_descriptor; + *p_length = sizeof(hids_report_descriptor); + } + break; + } + + return cause; +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length Length of writing characteristic data. + * @param[in] p_value Pointer to characteristic data. + * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb. + * @return TProfileResult +*/ +T_APP_RESULT hids_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_HID_CALLBACK_DATA callback_data; + if (!p_value) + { + PROFILE_PRINT_ERROR2("hids_attr_write_cb: p_value %p length= 0x%x", p_value, length); + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; +#if SUPPORT_VOICE_FEATURE + case GATT_SRV_HID_VOICE_OUTPUT_INDEX: + APP_PRINT_INFO1("--> host write voice output 0x%x ", *p_value); + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_type = HID_WRITE_VIOCE_CMD; + callback_data.msg_data.write.write_parameter.voice_enable = *p_value; + break; +#endif + case GATT_SVC_HID_PROTOCOL_MODE_INDEX: + { + hids_protocol_mode = *p_value; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_type = HID_WRITE_PROTOCOL_MODE; + callback_data.msg_data.write.write_parameter.protocol_mode = *p_value; + + cause = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("--> host write hids_protocol_mode %d ", + hids_protocol_mode); + } + break; + case GATT_SVC_HID_CONTROL_POINT_INDEX: + { + hids_suspand_mode = *p_value; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_type = HID_WRITE_SUSPEND_MODE; + callback_data.msg_data.write.write_parameter.suspend_mode = *p_value; + + cause = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("--> host write hids_suspand_mode %d", + hids_suspand_mode); + } + break; + case GATT_SRV_HID_KB_INPUT_INDEX: +#if SUPPORT_VOICE_FEATURE + case GATT_SRV_HID_VOICE_INPUT_INDEX: +#endif +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD + case GATT_SRV_HID_MM_KB_INPUT_INDEX: +#endif + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_type = HID_WRITE_INPUT_REPORT; + callback_data.msg_data.write.write_parameter.report_data.reportLen = length; + callback_data.msg_data.write.write_parameter.report_data.report = p_value; + cause = APP_RESULT_SUCCESS; + } + break; + } + + if (pfn_hids_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id Connection ID. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None +*/ +void hids_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_HID_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + bool handle = true; + + PROFILE_PRINT_INFO2("hids_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SRV_HID_KB_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_KB_DISABLE; + } + } + break; +#if SUPPORT_VOICE_FEATURE + case (GATT_SRV_HID_VOICE_INPUT_CCCD_INDEX): + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_VOICE_ENABLE; + } + else if ((ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) == 0) + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_VOICE_DISABLE; + } + } + break; +#endif + +#if FEATURE_SUPPORT_MULTIMEDIA_KEYBOARD + case GATT_SRV_HID_MM_KB_INPUT_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_ENABLE; + + } + else + { + callback_data.msg_data.notification_indification_index = HID_NOTIFY_INDICATE_MM_KB_DISABLE; + } + break; +#endif + default: + handle = false; + break; + } + + if (pfn_hids_cb && (handle == true)) + { + pfn_hids_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief HID Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS hids_cbs = +{ + hids_attr_read_cb, // Read callback function pointer + hids_attr_write_cb, // Write callback function pointer + hids_cccd_update_cb // Authorization callback function pointer +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief Add HIDS service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bas_id = hids_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t hids_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)hids_attr_table, + hids_attr_tbl_size, + hids_cbs)) + { + APP_PRINT_ERROR1("hids_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + + pfn_hids_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/hrs.c b/src/ble/profile/server/hrs.c new file mode 100644 index 0000000..d1ae002 --- /dev/null +++ b/src/ble/profile/server/hrs.c @@ -0,0 +1,610 @@ +/********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file hrs.c +* @brief Heart Rate service source file. +* @details Interfaces to access Heart Rate service. +* @author +* @date 2017-9-21 +* @version v1.0 +********************************************************************************************************* +*/ +#include "stdint.h" +#include "gatt.h" +#include +#include "trace.h" +#include "profile_server.h" +#include "hrs.h" + + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +HRS_NOTIFY_INDICATE_FLAG hrs_notify_indicate_flag = {0}; +T_HEART_RATE_MEASUREMENT_VALUE hrs_heart_rate_measurement_value = {0}; +uint8_t hrs_body_sensor_location_value = 0; +T_HRS_CONTROL_POINT hrs_ctl_pnt = {0}; + + +/**< Function pointer used to send event to application from location and navigation profile. */ + +static P_FUN_SERVER_GENERAL_CB pfn_hrs_app_cb = NULL; + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL hrs_attr_tbl[] = +{ + /*----------------- Heart Rate Service -------------------*/ + /* <>, .. 0,*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_SERVICE_HEART_RATE), /* service UUID */ + HI_WORD(GATT_UUID_SERVICE_HEART_RATE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, Heart Rate Measurement*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_NOTIFY/* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Temperature Measurement value 2,*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NOTIF_IND/* wPermissions */ + }, + + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#ifdef HRS_BODY_SENSOR_LOCATION_CHAR_SUPPORT + , + /* <>Body Sensor Location*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_READ/* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION), + HI_WORD(GATT_UUID_CHAR_HRS_BODY_SENSOR_LOCATION) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } +#endif + +#ifdef HRS_ENERGY_EXPENDED_FEATURE_SUPPORT + , + /* <> Heart Rate Control Point*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE/* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_CP), + HI_WORD(GATT_UUID_CHAR_HRS_HEART_RATE_CP) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_WRITE/* wPermissions */ + } +#endif +}; + +/**< @brief Heart Rate service size definition. */ +const uint16_t hrs_attr_tbl_size = sizeof(hrs_attr_tbl); + +/** + * @brief Set a heart rate service parameter. + * + * NOTE: You can call this function with a heart rate service parameter type and it will set the + * heart rate service parameter. Heart rate service parameters are defined + * in @ref T_HRS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Heart rate service parameter type: @ref T_HRS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag; + flag.heart_rate_value_format_bit = 1; + flag.sensor_contact_status_bits = 3; + if (p_parse_value->param_count >= 1) + { + flag.sensor_contact_status_bits = p_parse_value->dw_param[1]; + } + + flag.energy_expended_status_bit = 1; + flag.rr_interval_bit = 1; + flag.rfu = 0; + + hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag); + } + * \endcode + */ + +bool hrs_set_parameter(T_HRS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR0("hrs_set_parameter failed\n"); + } + break; + + case HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&hrs_heart_rate_measurement_value.flag, p_value, len); + } + } + break; + + case HRS_HEART_RATE_MEASUREMENT_PARAM_MEASUREMENT_VALUE: + { + if (len != sizeof(uint16_t) && len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&hrs_heart_rate_measurement_value.heart_rate_measurement_value, p_value, len); + + } + } + break; + + case HRS_HEART_RATE_MEASUREMENT_PARAM_ENERGY_EXPENDED: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&hrs_heart_rate_measurement_value.energy_expended, p_value, len); + + } + } + break; + + case HRS_HEART_RATE_MEASUREMENT_PARAM_RR_INTERVAL: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&hrs_heart_rate_measurement_value.rr_interval, p_value, len); + + } + } + break; + + case HRS_BODY_SENSOR_LOCATION_PARAM_VALUE: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&hrs_body_sensor_location_value, p_value, len); + } + } + break; + + } + + return ret; +} + +/** + * @brief Send heart rate measurement value notification data. + * Application shall call @ref hrs_set_parameter to set heart rate measurement value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + + T_HEART_RATE_MEASUREMENT_VALUE_FLAG flag; + flag.heart_rate_value_format_bit = 1; + flag.sensor_contact_status_bits = 3; + if (p_parse_value->param_count >= 1) + { + flag.sensor_contact_status_bits = p_parse_value->dw_param[1]; + } + + flag.energy_expended_status_bit = 1; + flag.rr_interval_bit = 1; + flag.rfu = 0; + + hrs_set_parameter(HRS_HEART_RATE_MEASUREMENT_PARAM_FLAG, 1, &flag); + + op_result = hrs_heart_rate_measurement_value_notify(p_parse_value->dw_param[0], hrs_id); + } + * \endcode + */ +bool hrs_heart_rate_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + uint8_t heart_rate_measurement_value[HRS_HEART_RATE_MEASUREMENT_VALUE_MAX_LEN]; + uint8_t cur_offset = 0; + + memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.flag, 1); + cur_offset += 1; + + if (hrs_heart_rate_measurement_value.flag.heart_rate_value_format_bit == + Heart_Rate_Value_Format_UINT8) + { + memcpy(&heart_rate_measurement_value[cur_offset], + &hrs_heart_rate_measurement_value.heart_rate_measurement_value, 1); + cur_offset += 1; + } + else + { + memcpy(&heart_rate_measurement_value[cur_offset], + &hrs_heart_rate_measurement_value.heart_rate_measurement_value, 2); + cur_offset += 2; + } + + if (hrs_heart_rate_measurement_value.flag.energy_expended_status_bit) + { + memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.energy_expended, + 2); + cur_offset += 2; + } + + if (hrs_heart_rate_measurement_value.flag.rr_interval_bit) + { + memcpy(&heart_rate_measurement_value[cur_offset], &hrs_heart_rate_measurement_value.rr_interval, 2); + cur_offset += 2; + } + + PROFILE_PRINT_INFO0("hrs_heart_rate_measurement_value_notify"); + return server_send_data(conn_id, service_id, HRS_HEART_RATE_MEASUREMENT_VALUE_INDEX, + heart_rate_measurement_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); +} + +/** + * @brief handle control point write (request). + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param write_length Write request data length. + * @param value_ptr Pointer to write request data. + * @return none + * @retval void +*/ +static T_APP_RESULT hrs_hanlde_ctl_pnt_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t write_length, uint8_t *p_value) +{ + T_HRS_CALLBACK_DATA callback_data; + T_APP_RESULT cause = APP_RESULT_SUCCESS; + uint16_t parameter_length = 0; + memcpy(hrs_ctl_pnt.value, p_value, write_length); + if (write_length >= 1) + { + parameter_length = write_length - 1; + } + + PROFILE_PRINT_INFO1("hrs_hanlde_ctl_pnt_proc request: OpCode=0x%x", hrs_ctl_pnt.value[0]); + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = (T_HRS_HEART_RATE_CP_OPCODE)hrs_ctl_pnt.value[0]; + + + switch (hrs_ctl_pnt.value[0]) + { + case HRS_HEART_RATE_CP_OPCODE_RESET_ENERGY_EXPENDED: + { + if (!hrs_notify_indicate_flag.heart_rate_measurement_notify_enable) + { + cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS; + } + else if (parameter_length != 0) + { + cause = APP_RESULT_INVALID_PDU; + } + } + break; + + + default: + { + cause = APP_RESULT_APP_ERR; + } + break; + } + + pfn_hrs_app_cb(service_id, (void *)&callback_data); + return cause; +} + + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT hrs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + PROFILE_PRINT_INFO2("hrs_attr_read_cb iAttribIndex = %d iOffset %x", attrib_index, offset); + + *p_length = 0; + + switch (attrib_index) + { + case HRS_BODY_SENSOR_LOCATION_VALUE_INDEX: + { + T_HRS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = HRS_READ_BODY_SENSOR_LOCATION_VALUE; + pfn_hrs_app_cb(service_id, (void *)&callback_data); + + *p_length = sizeof(hrs_body_sensor_location_value); + memcpy(pp_value, &hrs_body_sensor_location_value, *p_length); + } + break; + + default: + { + PROFILE_PRINT_ERROR1("hrs_attr_read_cb iAttribIndex = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return cause; +} + + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] length length of value to be written. + * @param[in] p_value value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT hrs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO2("hrs_attr_write_cb iAttribIndex = %d wLength %x", attrib_index, length); + + switch (attrib_index) + { + case HRS_HEART_RATE_CP_VALUE_INDEX: + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > HRS_MAX_CTL_PNT_VALUE) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + /* Make sure Control Point is not "Process already in progress". */ + else if (HRS_CTL_PNT_OPERATE_ACTIVE(hrs_ctl_pnt.value[0])) + { + cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS; + } + /* Make sure Control Point is configured indication enable. */ + else if (!hrs_notify_indicate_flag.heart_rate_measurement_notify_enable) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + else + { + cause = hrs_hanlde_ctl_pnt_proc(conn_id, service_id, length, p_value); + } + + } + break; + + default: + { + PROFILE_PRINT_ERROR1("hrs_attr_write_cb iAttribIndex = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + hrs_ctl_pnt.value[0] = HRS_HEART_RATE_CP_OPCODE_RESERVED; + + return cause; +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void hrs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_HRS_CALLBACK_DATA hrs_callback_data; + bool bHandle = true; + + PROFILE_PRINT_INFO2("hrs_cccd_update_cb Index = %d wCCCDBits %x", index, ccc_bits); + + switch (index) + { + case HRS_HEART_RATE_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + hrs_notify_indicate_flag.heart_rate_measurement_notify_enable = 1; + hrs_callback_data.msg_data.notification_indification_index = + HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_ENABLE; + } + else + { + hrs_notify_indicate_flag.heart_rate_measurement_notify_enable = 0; + hrs_callback_data.msg_data.notification_indification_index = + HRS_NOTIFY_INDICATE_MEASUREMENT_VALUE_DISABLE; + } + } + break; + + + default: + { + bHandle = false; + PROFILE_PRINT_ERROR1("hrs_cccd_update_cb Index = %d not found", index); + } + break; + + } + /* Notify Application. */ + if (pfn_hrs_app_cb && (bHandle == true)) + { + pfn_hrs_app_cb(service_id, (void *)&hrs_callback_data); + } + + return; +} + +/** + * @brief Heart Rate Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS hrs_cbs = +{ + hrs_attr_read_cb, // Read callback function pointer + hrs_attr_write_cb, // Write callback function pointer + hrs_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add heart rate service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hrs_id = hrs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID hrs_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)hrs_attr_tbl, + hrs_attr_tbl_size, + hrs_cbs)) + { + PROFILE_PRINT_ERROR1("hrs_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + pfn_hrs_app_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + + return service_id; +} + + diff --git a/src/ble/profile/server/hts.c b/src/ble/profile/server/hts.c new file mode 100644 index 0000000..c9a46c9 --- /dev/null +++ b/src/ble/profile/server/hts.c @@ -0,0 +1,724 @@ +/** +********************************************************************************************************* +* Copyright(c) 2014, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file hts.c +* @brief Health Thermometer service source file. +* @details Interfaces to access Health Thermometer service. +* @author +* @date 2017-9-20 +* @version v1.0 +********************************************************************************************************* +*/ +#include "gatt.h" +#include "string.h" +#include "trace.h" +#include "hts.h" + + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +/**< Temperature Type value. */ +#define HTS_TEMPERATURE_TYPE_CHAR_SUPPORT +#define HTS_INTERMEDIATE_TEMPERATURE_CHAR_SUPPORT +#define HTS_MEASUREMENT_INTERVAL_CHAR_SUPPORT +#define HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT +#define HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT + + +#define HTS_TEMPERATURE_MEASUREMENT_INDEX 2 +#define HTS_TEMPERATURE_TYPE_INDEX 5 +#define HTS_INTERMEDIATE_TEMPERATURE_INDEX 7 +#define HTS_MEASUREMENT_INTERVAL_INDEX 10 +#define HTS_MEASUREMENT_INTERVAL_VALID_RANGE_INDEX 12 + +#define HTS_TEMPERATURE_MEASUREMENT_CCCD_INDEX 3 +#define HTS_INTERMEDIATE_TEMPERATURE_CCCD_INDEX 8 +#define HTS_MEASUREMENT_INTERVAL_CCCD_INDEX 11 + +#define GATT_UUID_HELTH_TEMPERATURE_SERVICE 0x1809 +#define GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL 0x2A21 +#define GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE 0x2A1E +#define GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT 0x2a1c +#define GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE 0x2a1d + +#define HTS_MEASUREMENT_VALUE_MAX_LEN 13 + +typedef struct +{ + T_HEALTH_THERMOMETER_MEASUREMENT_VALUE_FLAG flag; + uint32_t temp_celsius_value; + uint32_t temp_fahrenheit_value; + T_TIME_STAMP time_stamp; + uint8_t temper_next_desc; +} T_HTS_MESAURMENT; + +static T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; +static uint16_t hts_measurement_interval = 50; +static T_HTS_MEASUREMENT_INTERVAL_VALID_RANGE hts_measurement_interval_valid_range = {0}; + +static P_FUN_SERVER_GENERAL_CB pfn_hts_cb = NULL; + +static T_HTS_MESAURMENT hts_measurement = {0}; +static uint8_t hts_measurement_value_for_notify_indicate[HTS_MEASUREMENT_VALUE_MAX_LEN]; +static uint8_t hts_measurement_value_actual_length = 0; + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL hts_attr_tbl[] = +{ + /*----------------- Health Temperature Service -------------------*/ + /* <>, .. 0,*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_HELTH_TEMPERATURE_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_HELTH_TEMPERATURE_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. 1,*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_INDICATE /* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Temperature Measurement value 2,*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration 3*/ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } + +#ifdef HTS_TEMPERATURE_TYPE_CHAR_SUPPORT + , + /* <>, .. 4*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_READ /* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Temperature Type value 5*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE), + HI_WORD(GATT_UUID_CHAR_HTS_TEMPERATURE_TYPE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } +#endif + +#ifdef HTS_INTERMEDIATE_TEMPERATURE_CHAR_SUPPORT + , + /* <>, .. 6*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Intermediate Temperature value,7*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE), + HI_WORD(GATT_UUID_CHAR_HTS_INTERMEDIATE_TMPERATURE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration ,8*/ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif + +#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_SUPPORT + , + /* <>, .. ,9*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_READ /* characteristic properties */ +#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT + | GATT_CHAR_PROP_INDICATE +#endif +#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT + | GATT_CHAR_PROP_WRITE +#endif + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Measurement Interval value, 10*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL), + HI_WORD(GATT_UUID_CHAR_HTS_MEASUREMENT_INTERVAL) + }, + 0, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } + +#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_INDICATE_SUPPORT + , + /* client characteristic configuration, 11*/ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif + +#ifdef HTS_MEASUREMENT_INTERVAL_CHAR_WRITE_SUPPORT + , + /* valid range descriptor ,12*/ + { + ATTRIB_FLAG_VALUE_APPL, + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_VALID_RANGE), + HI_WORD(GATT_UUID_CHAR_VALID_RANGE), + + }, + 0, /* bValueLen */ + NULL, + (GATT_PERM_READ) /* wPermissions */ + } +#endif +#endif +}; +/**< @brief Health Temperature service size definition. */ +const uint16_t hts_attr_tbl_size = sizeof(hts_attr_tbl); + +/** + * @brief Set a health thermometer service parameter. + * + * NOTE: You can call this function with a health thermometer service parameter type and it will set the + * health thermometer service parameter. Health thermometer service parameters are defined + * in @ref T_HTS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Health thermometer service parameter type: @ref T_HTS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_measure_time_stamp.seconds += hts_measurement_interval; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + } + * \endcode + */ +bool hts_set_parameter(T_HTS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR0("hts_set_parameter failed\n"); + } + break; + case HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG: + { + memcpy(&hts_measurement.flag, p_value, 1); + } + break; + case HTS_PARAM_MEASUREMENT_TEMPERATUER_VALUE: + { + if (len != 4) + { + PROFILE_PRINT_ERROR0("hts_set_parameter Temperature value \n"); + break; + } + if (hts_measurement.flag.temp_value_units_bit == 0) + { + memcpy(&hts_measurement.temp_celsius_value, p_value, len); + } + else + { + memcpy(&hts_measurement.temp_fahrenheit_value, p_value, len); + } + } + break; + case HTS_PARAM_MEASUREMENT_TIME_STAMP: + { + if (len != sizeof(T_TIME_STAMP)) + { + PROFILE_PRINT_ERROR0("hts_set_parameter Temperature value \n"); + break; + } + memcpy(&hts_measurement.time_stamp, p_value, len); + } + break; + case HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE: + { + hts_measurement.temper_next_desc = *(uint8_t *)p_value; + } + break; + + case HTS_PARAM_MEASUREMENT_INTERVAL: + memcpy(&hts_measurement_interval, p_value, len); + break; + + case HTS_PARAM_VALID_RANGE: + memcpy(&hts_measurement_interval_valid_range, p_value, len); + break; + } + + return ret; +} + + +void hts_format_measurement_value() +{ + uint8_t cur_offset = 0; + + memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.flag, 1); + cur_offset += 1; + + if (hts_measurement.flag.temp_value_units_bit == 0) + { + memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.temp_celsius_value, + 4); + } + else + { + memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], + &hts_measurement.temp_fahrenheit_value, 4); + } + cur_offset += 4; + + if (hts_measurement.flag.temp_time_stamp_present_bit) + { + memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.time_stamp, 7); + cur_offset += 7; + } + + if (hts_measurement.flag.temp_type_present_bit) + { + memcpy(&hts_measurement_value_for_notify_indicate[cur_offset], &hts_measurement.temper_next_desc, + 1); + cur_offset += 1; + } + + hts_measurement_value_actual_length = cur_offset; + +} + +/** + * @brief Send measurement value indication data . + * Application shall call @ref hts_set_parameter to set intermediate temperature value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT | + HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_measure_time_stamp.seconds += hts_measurement_interval; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + + hts_measurement_value_indicate(p_parse_value->dw_param[0], hts_id); + } + * \endcode + */ +bool hts_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id) +{ + hts_format_measurement_value(); + return server_send_data(conn_id, service_id, HTS_TEMPERATURE_MEASUREMENT_INDEX, + (uint8_t *)&hts_measurement_value_for_notify_indicate, hts_measurement_value_actual_length, + GATT_PDU_TYPE_INDICATION); +} + +/** + * @brief Send intermediate temperature notification data. + * Application shall call @ref hts_set_parameter to set intermediate temperature value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t hts_flag = HTS_FLAG_MEASUREMENT_UINT_BIT + | HTS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT + | HTS_FLAG_MEASUREMENT_TYPE_PRESNET_BIT; + T_HTS_TEMPERATURE_TYPE temperature_type = HTS_TEMPERATURE_TYPE_ARMPIT; + + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPPARAM_FLAG, sizeof(hts_flag), &hts_flag); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(hts_measure_time_stamp), + &hts_measure_time_stamp); + hts_set_parameter(HTS_PARAM_MEASUREMENT_TEMPERATURE_TYPE, 1, &temperature_type); + + hts_intermediate_temperature_value_notify(p_parse_value->dw_param[0], hts_id); + + return RESULT_SUCESS; + + } + * \endcode + */ + +bool hts_intermediate_temperature_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + hts_format_measurement_value(); + return server_send_data(conn_id, service_id, HTS_INTERMEDIATE_TEMPERATURE_INDEX, + (uint8_t *)&hts_measurement_value_for_notify_indicate, hts_measurement_value_actual_length, + GATT_PDU_TYPE_NOTIFICATION); +} + +/** + * @brief Send measurement interval notification data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] seconds Measurement interval. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + uint16_t interval = 90; + hts_measurement_interval_notify(p_parse_value->dw_param[0], hts_id, interval); + } + * \endcode + */ + +bool hts_measurement_interval_notify(uint8_t conn_id, T_SERVER_ID service_id, uint16_t seconds) +{ + return server_send_data(conn_id, service_id, HTS_MEASUREMENT_INTERVAL_INDEX, (uint8_t *)&seconds, + sizeof(seconds), GATT_PDU_TYPE_NOTIFICATION); +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT hts_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + T_HTS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + + if (HTS_MEASUREMENT_INTERVAL_INDEX == attrib_index) + { + callback_data.msg_data.read_value_index = HTS_READ_MEASUREMENT_INTERVAL_VALUE; + pfn_hts_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hts_measurement_interval; + *p_length = sizeof(hts_measurement_interval); + } + else if (HTS_TEMPERATURE_TYPE_INDEX == attrib_index) + { + callback_data.msg_data.read_value_index = HTS_READ_TEMPERATURE_TYPE_VALUE; + pfn_hts_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&temperature_type; + *p_length = 1; + } + else if (HTS_MEASUREMENT_INTERVAL_VALID_RANGE_INDEX == attrib_index) + { + callback_data.msg_data.read_value_index = HTS_READ_VALID_RANGE_VALUE; + pfn_hts_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&hts_measurement_interval_valid_range; + *p_length = sizeof(hts_measurement_interval_valid_range); + } + + else + { + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + return cause; +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length length of value to be written. + * @param[in] p_value value to be written. + * @param[in] p_write_ind_post_proc value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT hts_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_ERROR2("hts_attr_write_cb iAttribIndex = %d wLength %x", attrib_index, length); + + switch (attrib_index) + { + case HTS_MEASUREMENT_INTERVAL_INDEX: + { + T_HTS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.write_index = HTS_WRITE_MEASUREMENT_INTERVAL_VALUE; + memcpy(&callback_data.msg_data.write.measurement_interval, p_value, 2); + pfn_hts_cb(service_id, (void *)&callback_data); + } + break; + + default: + { + PROFILE_PRINT_ERROR1("hts_attr_write_cb iAttribIndex = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return cause; +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void hts_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_HTS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + bool handle = true; + + PROFILE_PRINT_INFO2("HtsCccdUpdate Index = %d wCCCDBits %x", index, ccc_bits); + + switch (index) + { + case HTS_TEMPERATURE_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE) + { + // Enable Notification + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_ENABLE; + + } + else + { + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_TEMPERATURE_MEASUREMENT_VALUE_DISABLE; + } + } + break; + case HTS_INTERMEDIATE_TEMPERATURE_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE) + { + // Enable Notification + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_ENABLE; + + } + else + { + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_INTERMEDIATE_TEMPERATURE_VALUE_DISABLE; + } + break; + case HTS_MEASUREMENT_INTERVAL_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY_INDICATE) + { + // Enable Notification + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_ENABLE; + + } + else + { + callback_data.msg_data.notification_indification_index = + HTS_NOTIFY_INDICATE_MEASUREMENT_INTERVAL_VALUE_DISABLE; + } + break; + + default: + handle = false; + break; + + } + /* Notify Application. */ + if (pfn_hts_cb && (handle == true)) + { + pfn_hts_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief HTS Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS hts_cbs = +{ + hts_attr_read_cb, // Read callback function pointer + hts_attr_write_cb, // Write callback function pointer + hts_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add health thermometer service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + hts_id = hts_add_service(app_handle_profile_message); + } + * \endcode + */ + +T_SERVER_ID hts_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)hts_attr_tbl, + hts_attr_tbl_size, + hts_cbs)) + { + PROFILE_PRINT_ERROR1("hts_add_service: service_id %d", service_id); + service_id = 0xff; + } + pfn_hts_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; + +} + + diff --git a/src/ble/profile/server/ias.c b/src/ble/profile/server/ias.c new file mode 100644 index 0000000..6ecfd99 --- /dev/null +++ b/src/ble/profile/server/ias.c @@ -0,0 +1,175 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file ias.c +* @brief immediate alert level service source file. +* @details Interfaces to access immediate alert level service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ + +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "ias.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +///@cond +/** @brief IAS related services UUIDs */ +#define GATT_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 +#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06 + +/** @brief Index defines for Characteristic's value */ +#define GATT_SVC_PXP_IMMEDIATE_AlERT_VALUE_INDEX 2 +///@endcond + +static P_FUN_SERVER_GENERAL_CB pfn_ias_cb = NULL; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL ias_attr_tbl[] = +{ + /*----------------- Immediate Alert Service -------------------*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_IMMEDIATE_ALERT_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_IMMEDIATE_ALERT_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* Alert Level Characteristic */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Alert Level Characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_ALERT_LEVEL), + HI_WORD(GATT_UUID_CHAR_ALERT_LEVEL) + }, + 0, /* variable size */ + NULL, + GATT_PERM_WRITE | GATT_PERM_READ /* wPermissions */ + } +}; +/**< @brief IAS service size definition. */ +const int ias_attr_tbl_size = sizeof(ias_attr_tbl); + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length Length of writing characteristic data. + * @param[in] p_value Pointer to characteristic data. + * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb. + * @return TProfileResult +*/ +T_APP_RESULT ias_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_IAS_CALLBACK_DATA callback_data; + if (!p_value) + { + PROFILE_PRINT_ERROR2("ias_attr_write_cb: p_value %p length= 0x%x", p_value, length); + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_PXP_IMMEDIATE_AlERT_VALUE_INDEX: + if (length != sizeof(uint8_t)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write_alert_level = p_value[0]; + } + break; + } + if (pfn_ias_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_ias_cb(service_id, (void *)&callback_data); + } + + return cause; +} + +/********************************************************************* + * SERVICE CALLBACKS + */ +// IAS related Service Callbacks +const T_FUN_GATT_SERVICE_CBS ias_cbs = +{ + NULL, // Read callback function pointer + ias_attr_write_cb, // Write callback function pointer + NULL // CCCD update callback function pointer +}; + +/** + * @brief Add immediate alert service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + ias_id = ias_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID ias_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)ias_attr_tbl, + ias_attr_tbl_size, + ias_cbs)) + { + PROFILE_PRINT_ERROR1("ias_add_service: service_id %d", service_id); + service_id = 0xff; + } + + pfn_ias_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/ipss.c b/src/ble/profile/server/ipss.c new file mode 100644 index 0000000..f26358b --- /dev/null +++ b/src/ble/profile/server/ipss.c @@ -0,0 +1,75 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ipss.c + * @brief Source file for using internet protocol support service. + * @details Global data and function implement. + * @author Jeff_Zheng + * @date 2017-12-05 + * @version v1.0 + * ************************************************************************************* + */ + +#include +#include "trace.h" +#include "profile_server.h" +#include "ipss.h" + + + +static const T_ATTRIB_APPL ipss_attr_tbl[] = +{ + /* <> 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_IPSS), /* service UUID */ + HI_WORD(GATT_UUID_IPSS) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + } + +}; + +uint16_t ipss_attr_tbl_len = sizeof(ipss_attr_tbl); +//static P_FUN_SERVER_GENERAL_CB p_fn_ipss_cb = NULL; + +const T_FUN_GATT_SERVICE_CBS ipss_cbs = +{ + NULL, // Read callback function pointer + NULL, // Write callback function pointer + NULL, // Authorization callback function pointer +}; + +/** + * @brief add ipss service to application. + * + * @param[in] p_func pointer of app callback function called by profile. + * @return service id auto generated by profile layer. + * @retval service id + */ +uint8_t ipss_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, (uint8_t *)ipss_attr_tbl, ipss_attr_tbl_len, ipss_cbs)) + { + service_id = SERVICE_PROFILE_GENERAL_ID; + } + else + { + //p_fn_ipss_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + } + + PROFILE_PRINT_ERROR1("ipss_add_service: service_id %d", service_id); + + return service_id; +} + + + + diff --git a/src/ble/profile/server/lls.c b/src/ble/profile/server/lls.c new file mode 100644 index 0000000..1e04b4e --- /dev/null +++ b/src/ble/profile/server/lls.c @@ -0,0 +1,255 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file lls.c +* @brief link loss service source file. +* @details Interfaces to access link loss service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "lls.h" + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +///@cond +/** @brief LLS profile related services UUIDs. */ +#define GATT_UUID_LINK_LOSS_SERVICE 0x1803 +#define GATT_UUID_CHAR_ALERT_LEVEL 0x2A06 + +/** @brief LLS Attribute Index */ +#define GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX 2 +///@endcond + +static P_FUN_SERVER_GENERAL_CB pfn_lls_cb = NULL; +static uint8_t lls_alert_level = 0; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL lls_attr_tbl[] = +{ + /*----------------- Link Loss Service -------------------*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_LINK_LOSS_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_LINK_LOSS_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* Alert Level Characteristic */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_WRITE, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Alert Level Characteristic value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_ALERT_LEVEL), + HI_WORD(GATT_UUID_CHAR_ALERT_LEVEL) + }, + 0, /* variable size */ + NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + } +}; +/**< @brief LLS service size definition. */ +const int lls_attr_tbl_size = sizeof(lls_attr_tbl); + + +/** + * @brief Set a link loss service parameter. + * + * NOTE: You can call this function with a link loss service parameter type and it will set the + * link loss service parameter. Link loss service parameters are defined in @ref T_LLS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Link loss service parameter type: @ref T_LLS_PARAM_TYPE + * @param[in] length Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool lls_set_parameter(T_LLS_PARAM_TYPE param_type, uint8_t length, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + ret = false; + break; + case LLS_PARAM_LINK_LOSS_ALERT_LEVEL: + lls_alert_level = *(uint8_t *)p_value; + break; + } + + if (!ret) + { + PROFILE_PRINT_ERROR0("lls_set_parameter: lls alert level parameter set failed"); + } + + return ret; +} + + +/** + * @brief read characteristic data from service. + * + * @param conn_id connection id. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset offset of characteritic to be read. + * @param p_length length of getting characteristic data. + * @param pp_value pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT lls_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + T_LLS_CALLBACK_DATA callback_data; + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("lls_attr_read_cb default:attrib_index %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX: + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = LLS_READ_ALERT_LEVEL; + pfn_lls_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&lls_alert_level; + *p_length = sizeof(lls_alert_level); + PROFILE_PRINT_INFO2("lls_attr_read_cb: attrib_index %d, length %d", attrib_index, *p_length); + break; + } + + return (cause); +} + +/** + * @brief write characteristic data from service. + * + * @param conn_id connection id. + * @param service_id ServiceID to be written. + * @param attrib_index Attribute index of characteristic. + * @param length length of writing characteristic data. + * @param p_value pointer to characteristic data. + * @param p_write_ind_post_proc function pointer called after lls_attr_write_cb. + * @return T_APP_RESULT +*/ +T_APP_RESULT lls_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + T_LLS_CALLBACK_DATA callback_data; + if (!p_value) + { + PROFILE_PRINT_ERROR2("lls_attr_write_cb: p_value %p, length 0x%x", p_value, length); + cause = APP_RESULT_INVALID_PDU; + return cause; + } + + switch (attrib_index) + { + default: + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + case GATT_SVC_PXP_LINK_LOSS_ALERT_LEVEL_INDEX: + if (length != sizeof(uint8_t)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write_alert_level = p_value[0]; + } + break; + + } + if (pfn_lls_cb && (cause == APP_RESULT_SUCCESS)) + { + pfn_lls_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + + +// LLS related Service Callbacks +const T_FUN_GATT_SERVICE_CBS lls_cbs = +{ + lls_attr_read_cb, // Read callback function pointer + lls_attr_write_cb, // Write callback function pointer + NULL // CCCD update callback function pointer +}; + +/** + * @brief Add link loss service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + lls_id = lls_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID lls_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)lls_attr_tbl, + lls_attr_tbl_size, + lls_cbs)) + { + PROFILE_PRINT_ERROR1("lls_add_service: service_id %d", service_id); + service_id = 0xff; + } + + pfn_lls_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/lns.c b/src/ble/profile/server/lns.c new file mode 100644 index 0000000..978c316 --- /dev/null +++ b/src/ble/profile/server/lns.c @@ -0,0 +1,1712 @@ +/********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file lns.c +* @brief Location and Navigation Service source file. +* @details Interfaces to access Location and Navigation Service. +* @author +* @date 2017-09-22 +* @version v0.1 +********************************************************************************************************* +*/ + +#include "stdint.h" +#include "gatt.h" +#include +#include "trace.h" +#include "lns.h" + + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +#define LNS_POSITION_QUALITY_CHAR_SUPPORT +#define LNS_LN_CONTROL_POINT_CHAR_SUPPORT +#define LNS_LN_NAVIGATION_CHAR_SUPPORT + +#define LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN 10 + +#define LNS_LN_FEATURE_VALUE_INDEX 2//read +#define LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX 4//notify +#define LNS_LN_POSITION_QUALITY_VALUE_INDEX 7//read +#define LNS_LN_CP_VALUE_INDEX 9 //write, indicate +#define LNS_LN_NAVIGATION_VALUE_INDEX 12//notify + +#define LNS_LN_LOCATION_AND_SPEED_CCCD_INDEX 5 +#define LNS_LN_CP_CCCD_INDEX 10 +#define LNS_LN_NAVIGATION_CCCD_INDEX 13 + +#define GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION 0x1819 +#define GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED 0x2A67 +#define GATT_UUID_CHAR_LNS_NAVIGATION 0x2A68 +#define GATT_UUID_CHAR_LNS_POSITION_QUALITY 0x2A69 +#define GATT_UUID_CHAR_LNS_LN_FEATURE 0x2A6A +#define GATT_UUID_CHAR_LNS_LN_CP 0x2A6B + + + +#define LN_CP_RSPCODE_RESERVED 0x00 +#define LN_CP_RSPCODE_SUCCESS 0x01 +#define LN_CP_RSPCODE_OPCODE_UNSUPPORT 0x02 +#define LN_CP_RSPCODE_INVALID_PARAMETER 0x03 +#define LN_CP_RSPCODE_OPERATION_FAILED 0x04 + + +#define LN_CTL_PNT_OPERATE_ACTIVE(x) \ + ( (x == LN_CP_OPCODE_SET_CUMULATIVE_VALUE) || \ + (x == LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT) || \ + (x == LN_CP_OPCODE_NAVIGATION_CONTROL) || \ + (x == LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES) || \ + (x == LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE) || \ + (x == LN_CP_OPCODE_SELECT_ROUTE) || \ + (x == LN_CP_OPCODE_SET_FIX_RATE) || \ + (x == LN_CP_OPCODE_SET_ELEVATION) || \ + (x == LN_CP_OPCODE_RESPONSE_CODE) ) + +#define LNS_POSITION_AND_QUALITY_VALUE_MAX_LEN 16 +#define LNS_LOCATION_AND_SPEED_VALUE_MAX_LEN 28 +#define LNS_NAVIGATION_VALUE_MAX_LEN 19 + +uint32_t lns_ln_feature_support = 0xFFFFF; + +T_LNS_NOTIFY_INDICATE_FLAG lns_notify_indicate_flag = {0}; +T_LNS_CONTROL_POINT lns_ctl_pnt = {0}; + +T_POSITION_QUALITY_VALUE lns_position_quality_value = {0}; +uint8_t lns_pq_value_for_read_cfm[LNS_POSITION_AND_QUALITY_VALUE_MAX_LEN] = {0}; +uint8_t lns_pq_value_length_for_read_cfm = 0; + +LOCATION_AND_SPEED_VALUE lns_location_and_speed_value = {0}; +T_NAVIGATION_VALUE lns_navigation_value = {0}; +uint16_t lns_cp_number_of_route = 0; +uint8_t lns_cp_name_of_route[LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN] = {0}; +uint8_t lns_cp_name_of_route_len = 0; + +/**< Function pointer used to send event to application from location and navigation profile. */ + +static P_FUN_SERVER_GENERAL_CB pfn_lns_app_cb = NULL; + + +/**< @brief profile/service definition. */ +static const T_ATTRIB_APPL lns_attr_tbl[] = +{ + /*----------------- Health Temperature Service -------------------*/ + /* <>, .. 0,*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION), /* service UUID */ + HI_WORD(GATT_UUID_SERVICE_LOCATION_AND_NAVIGATION) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1, LN Feature*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Temperature Measurement value 2,*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LNS_LN_FEATURE), + HI_WORD(GATT_UUID_CHAR_LNS_LN_FEATURE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, ..Location and Speed */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED), + HI_WORD(GATT_UUID_CHAR_LNS_LOCATION_AND_SPEED) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + +#ifdef LNS_POSITION_QUALITY_CHAR_SUPPORT + /* <>, .. Position Quality*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LNS_POSITION_QUALITY), + HI_WORD(GATT_UUID_CHAR_LNS_POSITION_QUALITY) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif + +#ifdef LNS_LN_CONTROL_POINT_CHAR_SUPPORT + /* <>, .. LN Control Point*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Measurement Interval value*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LNS_LN_CP), + HI_WORD(GATT_UUID_CHAR_LNS_LN_CP) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_WRITE/* wPermissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +#endif + +#ifdef LNS_LN_NAVIGATION_CHAR_SUPPORT + /* <>, .. Navigation*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY/* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_LNS_NAVIGATION), + HI_WORD(GATT_UUID_CHAR_LNS_NAVIGATION) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NOTIF_IND_AUTHEN_REQ/* wPermissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif + +}; + +/**< @brief Health Temperature service size definition. */ +const uint16_t lns_attr_tbl_size = sizeof(lns_attr_tbl); + +/** + * @brief Set a Location And Navigation service parameter. + * + * NOTE: You can call this function with a Location And Navigation service parameter type and it will set the + * Location And Navigation service parameter. Location And Navigation service parameters are defined + * in @ref T_LNS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Location And Navigation service parameter type: @ref T_LNS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_LOCATION_AND_SPEED_VALUE_FLAG flag; + flag.instantaneous_speed_present = 1; + flag.total_distance_present = 1; + flag.location_present = 1; + flag.elevation_present = 1; + flag.heading_present = 1; + flag.rolling_time_present = 1; + flag.utc_time_present = 1; + flag.position_status = 1; + flag.speed_and_distance_format = 1; + flag.elevation_source = 1; + flag.heading_source = 1; + flag.rfu = 0; + + lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag); + } + * \endcode + */ +bool lns_set_parameter(T_LNS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR0("lns_set_parameter failed\n"); + } + break; + + case LNS_PARAM_LN_FEATURE_SUPPORT: + { + if (len != sizeof(uint32_t)) + { + ret = false; + } + else + { + memcpy(&lns_ln_feature_support, p_value, len); + } + } + break; + + //Location And Speed Value + case LNS_LAS_PARAM_INC_FLAG: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.flag, p_value, len); + } + } + break; + + case LNS_LAS_PARAM_INSTANTANEOUS_SPEED: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.instantaneous_speed, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_TOTAL_DISTANCE: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.total_distance, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_LOCATION_LATITUDE: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.location_latitude, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_LOCATION_LONGITUDE: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.location_latitude, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_ELEVATION: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.elevation, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_HEADING: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.heading, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_ROLLING_TIME: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.rolling_time, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_UTC_TIME: + { + if (len != 7) + { + ret = false; + } + else + { + memcpy(&lns_location_and_speed_value.utc_time, p_value, len); + + } + } + break; + + case LNS_LAS_PARAM_POSITION_STATUS: + { + lns_location_and_speed_value.flag.position_status = *(uint8_t *)p_value; + } + break; + + case LNS_LAS_PARAM_SPEED_AND_DISTANCE_FORMAT: + { + lns_location_and_speed_value.flag.speed_and_distance_format = *(uint8_t *)p_value; + } + break; + + case LNS_LAS_PARAM_ELEVATION_SOURCE: + { + lns_location_and_speed_value.flag.elevation_source = *(uint8_t *)p_value; + } + break; + + case LNS_LAS_PARAM_HEADING_SOURCE: + { + lns_location_and_speed_value.flag.heading_source = *(uint8_t *)p_value; + } + break; + + //Navigation value + case LNS_NAVIGATION_PARAM_INC_FLAG: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.flag, p_value, len); + } + } + break; + + case LNS_NAVIGATION_PARAM_BEARING: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.bearing, p_value, len); + + } + } + break; + + case LNS_NAVIGATION_PARAM_HEADING: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.bearing, p_value, len); + + } + } + break; + + case LNS_NAVIGATION_PARAM_REMAINING_DISTANCE: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.reamining_distance, p_value, len); + + } + } + break; + + case LNS_NAVIGATION_PARAM_REMAINING_VERTICAL_DISTANCE: + { + if (len != 3) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.reamining_vertical_distance, p_value, len); + + } + } + break; + + case LNS_NAVIGATION_PARAM_ESTIMATED_TIME_OF_ARRIVAL: + { + if (len != 7) + { + ret = false; + } + else + { + memcpy(&lns_navigation_value.estimated_time_of_arrival, p_value, len); + + } + } + break; + + case LNS_NAVIGATION_PARAM_POSITION_STATUS: + { + lns_navigation_value.flag.position_status = *(uint8_t *)p_value; + } + break; + case LNS_NAVIGATION_PARAM_HEADING_SOURCE: + { + lns_navigation_value.flag.heading_source = *(uint8_t *)p_value; + } + break; + + case LNS_NAVIGATION_PARAM_NAVIGATION_INDICATOR_TYPE: + { + lns_navigation_value.flag.navigation_indicator_type = *(uint8_t *)p_value; + } + break; + + case LNS_NAVIGATION_PARAM_WAYPOINT_REACHED: + { + lns_navigation_value.flag.waypoint_reached = *(uint8_t *)p_value; + } + break; + + case LNS_NAVIGATION_PARAM_DESTINATION_REACHED: + { + lns_navigation_value.flag.destination_reached = *(uint8_t *)p_value; + } + break; + + case LNS_PQ_PARAM_INC_FLAG: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.flag, p_value, len); + } + } + break; + + case LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_SOLUTION: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.number_of_beacons_in_solution, p_value, len); + } + } + break; + + case LNS_PQ_PARAM_NUMBER_OF_BEACONS_IN_VIEW: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.number_of_beacons_in_view, p_value, len); + } + } + break; + + + case LNS_PQ_PARAM_TIME_TO_FIRST_FIX: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.time_to_first_fix, p_value, len); + } + } + break; + + case LNS_PQ_PARAM_EHPE: + { + if (len != sizeof(uint32_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.ehpe, p_value, len); + } + } + break; + + case LNS_PQ_PARAM_EVPE: + { + if (len != sizeof(uint32_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.evpe, p_value, len); + } + } + break; + case LNS_PQ_PARAM_HDOP: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.hdop, p_value, len); + } + } + break; + + case LNS_PQ_PARAM_VDOP: + { + if (len != sizeof(uint8_t)) + { + ret = false; + } + else + { + memcpy(&lns_position_quality_value.vdop, p_value, len); + } + } + break; + + case LNS_CP_PARA_NUMBER_OF_ROUTE: + { + if (len != sizeof(uint16_t)) + { + ret = false; + } + else + { + memcpy(&lns_cp_number_of_route, p_value, len); + } + } + break; + + case LNS_CP_PARA_NAME_OF_ROUTE: + { + if (len > LNS_CP_PARA_NAME_OF_ROUTE_MAX_LEN) + { + ret = false; + } + else + { + memcpy(&lns_cp_name_of_route, p_value, len); + lns_cp_name_of_route_len = len; + } + } + break; + case LNS_PARAM_CTL_PNT_PROG_CLR: + { + if (len != 0) + { + ret = false; + } + else + { + lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESERVED; + } + } + break; + + } + + return ret; +} + +void lns_format_pq_value_for_read() +{ + uint8_t cur_offset = 0; + + memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.flag, 2); + cur_offset += 2; + + if (lns_position_quality_value.flag.number_of_beacons_in_solution_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], + &lns_position_quality_value.number_of_beacons_in_solution, 1); + cur_offset += 1; + } + + if (lns_position_quality_value.flag.number_of_beacons_in_view_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], + &lns_position_quality_value.number_of_beacons_in_view, 1); + cur_offset += 1; + } + + if (lns_position_quality_value.flag.time_to_first_fix_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.time_to_first_fix, 2); + cur_offset += 2; + } + + if (lns_position_quality_value.flag.ehpe_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.ehpe, 4); + cur_offset += 4; + } + + if (lns_position_quality_value.flag.evpe_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.evpe, 4); + cur_offset += 4; + } + + if (lns_position_quality_value.flag.hdop_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], &lns_position_quality_value.hdop, 1); + cur_offset += 1; + } + + if (lns_position_quality_value.flag.vdop_present) + { + memcpy(&lns_pq_value_for_read_cfm[cur_offset], + &lns_position_quality_value.vdop, 1); + cur_offset += 1; + } + + lns_pq_value_length_for_read_cfm = cur_offset; + +} + +uint8_t lns_get_fisrt_value_offset_to_notify() +{ + + uint8_t cur_offset = 2; + + if (lns_location_and_speed_value.flag.instantaneous_speed_present) + { + cur_offset += 2; + } + + if (lns_location_and_speed_value.flag.total_distance_present) + { + cur_offset += 3; + } + + if (lns_location_and_speed_value.flag.location_present) + { + cur_offset += 4; + cur_offset += 4; + } + + if (lns_location_and_speed_value.flag.elevation_present) + { + cur_offset += 3; + } + + if (lns_location_and_speed_value.flag.heading_present) + { + cur_offset += 2; + } + + + if (lns_location_and_speed_value.flag.rolling_time_present) + { + cur_offset += 1; + } + + if (cur_offset > 20) + { + return cur_offset - 1; + } + + + if (lns_location_and_speed_value.flag.utc_time_present) + { + cur_offset += 7; + } + + if (cur_offset > 20) + { + return cur_offset - 7; + } + + return cur_offset; + +} + +/** + * @brief Send location and speed value notification data. + * Application shall call @ref lns_set_parameter to set location and speed value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + T_LOCATION_AND_SPEED_VALUE_FLAG flag; + flag.instantaneous_speed_present = 1; + flag.total_distance_present = 1; + flag.location_present = 1; + flag.elevation_present = 1; + flag.heading_present = 1; + flag.rolling_time_present = 1; + flag.utc_time_present = 1; + flag.position_status = 1; + flag.speed_and_distance_format = 1; + flag.elevation_source = 1; + flag.heading_source = 1; + flag.rfu = 0; + + lns_set_parameter(LNS_LAS_PARAM_INC_FLAG, 2, &flag); + + op_result = lns_location_and_speed_value_notify(p_parse_value->dw_param[0], lns_id); + } + * \endcode + */ +bool lns_location_and_speed_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + bool ret = true; + + T_LOCATION_AND_SPEED_VALUE_FLAG flag = {0}; + uint8_t location_and_speed_value[20]; + + + uint8_t cur_offset = 2; + uint8_t first_notify_value_offset = lns_get_fisrt_value_offset_to_notify(); + + if (lns_location_and_speed_value.flag.instantaneous_speed_present) + { + flag.instantaneous_speed_present = 1; + memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.instantaneous_speed, 2); + cur_offset += 2; + } + + if (lns_location_and_speed_value.flag.total_distance_present) + { + flag.total_distance_present = 1; + memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.total_distance, 3); + cur_offset += 3; + } + + if (lns_location_and_speed_value.flag.location_present) + { + flag.location_present = 1; + memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.location_latitude, 4); + cur_offset += 4; + memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.location_longitute, 4); + cur_offset += 4; + } + + if (lns_location_and_speed_value.flag.elevation_present) + { + flag.elevation_present = 1; + memcpy(&location_and_speed_value[cur_offset], &lns_location_and_speed_value.elevation, 3); + cur_offset += 3; + } + + if (lns_location_and_speed_value.flag.heading_present) + { + flag.heading_present = 1; + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.heading, 2); + cur_offset += 2; + } + + if (cur_offset == first_notify_value_offset) + { + //copy flag + memcpy(&location_and_speed_value[0], &flag, 2); + //send first notification here + server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX, + location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); + + //send remain data + memset(&flag, 0, 2); + cur_offset = 2; + if (lns_location_and_speed_value.flag.rolling_time_present) + { + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.rolling_time, 1); + flag.rolling_time_present = 1; + cur_offset += 1; + } + + if (lns_location_and_speed_value.flag.utc_time_present) + { + + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.utc_time, 7); + flag.utc_time_present = 1; + cur_offset += 7; + } + memcpy(&location_and_speed_value[0], &flag, 2); + //send second notification + server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX, + location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); + + return ret; + } + + if (lns_location_and_speed_value.flag.rolling_time_present) + { + flag.rolling_time_present = 1; + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.rolling_time, 1); + cur_offset += 1; + } + + if (cur_offset == first_notify_value_offset) + { + //copy flag + memcpy(&location_and_speed_value[0], &flag, 2); + //send first notification here + server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX, + location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); + + + //send remain data + memset(&flag, 0, 2); + cur_offset = 2; + if (lns_location_and_speed_value.flag.utc_time_present) + { + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.utc_time, 7); + flag.utc_time_present = 1; + cur_offset += 7; + } + memcpy(&location_and_speed_value[0], &lns_location_and_speed_value.flag, 2); + //send second notification + server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX, + location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); + + return ret; + } + + if (lns_location_and_speed_value.flag.utc_time_present) + { + if (cur_offset <= 13) + { + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.utc_time, 7); + flag.utc_time_present = 1; + cur_offset += 7; + } + else if ((cur_offset > 13) && (cur_offset <= 19)) + { + memcpy(&location_and_speed_value[cur_offset], + &lns_location_and_speed_value.utc_time, (20 - cur_offset)); + flag.utc_time_present = 1; + cur_offset = 20; + } + } + memcpy(&location_and_speed_value[0], &lns_location_and_speed_value.flag, 2); + //send nortification + server_send_data(conn_id, service_id, LNS_LN_LOCATION_AND_SPEED_VALUE_INDEX, + location_and_speed_value, cur_offset, GATT_PDU_TYPE_NOTIFICATION); + + return ret; +} + +/** + * @brief Send navigation value notification data. + * Application shall call @ref lns_set_parameter to set navigation value first, + * and the call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + + T_NAVIGATION_VALUE_FLAG flag; + flag.remaining_distance_present = 1; + flag.remaining_vertical_distance_present = 1; + flag.estimated_time_of_arrival_present = 1; + flag.position_status = 1; + flag.heading_source = 1; + flag.navigation_indicator_type = 1; + flag.waypoint_reached = 1; + flag.destination_reached = 1; + flag.rfus = 0; + + lns_set_parameter(LNS_NAVIGATION_PARAM_INC_FLAG, 2, &flag); + + op_result = lns_navigation_value_notify(p_parse_value->dw_param[0], lns_id); + + } + * \endcode + */ +bool lns_navigation_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + uint8_t navigation_value[LNS_NAVIGATION_VALUE_MAX_LEN]; + uint8_t iCurOffset = 0; + + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.flag, 2); + iCurOffset += 2; + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.bearing, 2); + iCurOffset += 2; + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.heading, 2); + iCurOffset += 2; + + if (lns_navigation_value.flag.remaining_distance_present) + { + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.reamining_distance, 3); + iCurOffset += 3; + } + + if (lns_navigation_value.flag.remaining_vertical_distance_present) + { + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.reamining_vertical_distance, 3); + iCurOffset += 3; + } + + if (lns_navigation_value.flag.estimated_time_of_arrival_present) + { + memcpy(&navigation_value[iCurOffset], &lns_navigation_value.estimated_time_of_arrival, 7); + iCurOffset += 7; + } + + PROFILE_PRINT_INFO0("lns_navigation_value_notify"); + return server_send_data(conn_id, service_id, LNS_LN_NAVIGATION_VALUE_INDEX, navigation_value, + iCurOffset, GATT_PDU_TYPE_NOTIFICATION); +} + +bool lns_ln_ctl_pnt_value_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code, + uint8_t rsp_code, + uint8_t *p_parameter, uint8_t para_len) +{ + uint16_t attrib_index = LNS_LN_CP_VALUE_INDEX; + + uint8_t *p_data; + uint16_t data_len; + + lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESPONSE_CODE; + lns_ctl_pnt.value[1] = op_code; /* Control Point request opcode. */ + lns_ctl_pnt.value[2] = rsp_code; + + if (p_parameter != NULL && para_len != 0) + { + memcpy(&lns_ctl_pnt.value[3], p_parameter, para_len); + } + + lns_ctl_pnt.cur_length = 3 * sizeof(uint8_t) + para_len; + + + p_data = lns_ctl_pnt.value; + data_len = lns_ctl_pnt.cur_length; + + // send indication to client + return server_send_data(conn_id, service_id, attrib_index, p_data, data_len, + GATT_PDU_TYPE_INDICATION); +} + + + + +static void lns_ctl_pnt_set_cumulative_value(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_SET_CUMULATIVE_VALUE; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static void lns_ctl_pnt_mask_location_speed_char_content(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static void lns_ctl_pnt_navigation_control(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_NAVIGATION_CONTROL; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static void lns_ctl_pnt_request_number_of_routes(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code, uint16_t number_of_route) +{ + uint8_t op_code = LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, (uint8_t *)&number_of_route, + 2); +} + +static void lns_ctl_pnt_request_name_of_route(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code, uint8_t *pNameOfRoute, uint8_t len) +{ + uint8_t op_code = LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, pNameOfRoute, len); +} + +static void lns_ctl_pnt_select_route(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_SELECT_ROUTE; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static void lns_ctl_pnt_set_fix_rate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_SET_FIX_RATE; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static void lns_ctl_pnt_set_elevation(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = LN_CP_OPCODE_SET_ELEVATION; + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, op_code, rsp_code, NULL, 0); +} + +static uint8_t lns_hanlde_ctl_pnt_proc_2(uint8_t service_id, uint16_t write_length, + uint8_t *value_ptr) +{ + T_LNS_CALLBACK_DATA callback_data; + uint8_t resp_code = LN_CP_RSPCODE_SUCCESS; + uint16_t parameter_length = 0; + memcpy(lns_ctl_pnt.value, value_ptr, write_length); + if (write_length >= 1) + { + parameter_length = write_length - 1; + } + + PROFILE_PRINT_INFO1("lns_hanlde_ctl_pnt_proc request: OpCode=0x%x", lns_ctl_pnt.value[0]); + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = (T_LN_CP_OPCODE)lns_ctl_pnt.value[0]; + + switch (lns_ctl_pnt.value[0]) + { + case LN_CP_OPCODE_NAVIGATION_CONTROL: + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.navigation_control, + &lns_ctl_pnt.value[1], 1); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + + break; + + case LN_CP_OPCODE_SET_CUMULATIVE_VALUE: + { + if (parameter_length == 3) + { + memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_total_distance, + &lns_ctl_pnt.value[1], 3); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT: + { + if (parameter_length == 2) + { + memcpy(&callback_data.msg_data.write.cp_parameter.mask_location_and_speed, + &lns_ctl_pnt.value[1], 2); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES: + { + //no parameter + } + break; + case LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE: + { + if (parameter_length == 2) + { + memcpy(&callback_data.msg_data.write.cp_parameter.number_of_desired_route, + &lns_ctl_pnt.value[1], 1); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case LN_CP_OPCODE_SELECT_ROUTE: + { + if (parameter_length == 2) + { + memcpy(&callback_data.msg_data.write.cp_parameter.select_route_desired_route_number, + &lns_ctl_pnt.value[1], 2); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case LN_CP_OPCODE_SET_FIX_RATE: + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.set_fix_rate, + &lns_ctl_pnt.value[1], 1); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case LN_CP_OPCODE_SET_ELEVATION: + { + if (parameter_length == 3) + { + memcpy(&callback_data.msg_data.write.cp_parameter.set_elevation, + &lns_ctl_pnt.value[1], 3); + } + else + { + resp_code = LN_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + default: + { + resp_code = LN_CP_RSPCODE_OPCODE_UNSUPPORT; + } + break; + } + + if (resp_code == LN_CP_RSPCODE_SUCCESS) + { + pfn_lns_app_cb(service_id, (void *)&callback_data); + } + return resp_code; +} + +/** + * @brief handle control point write (request). + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] write_length write request data length. + * @param[in] value_ptr pointer to write request data. + * @return none + * @retval void +*/ +static T_APP_RESULT lns_hanlde_ctl_pnt_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t write_length, uint8_t *p_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + memcpy(lns_ctl_pnt.value, p_value, write_length); + + PROFILE_PRINT_INFO1("lns_hanlde_ctl_pnt_proc request: op_code=0x%x", lns_ctl_pnt.value[0]); + + switch (lns_ctl_pnt.value[0]) + { + case LN_CP_OPCODE_NAVIGATION_CONTROL: + { + if (!lns_notify_indicate_flag.navigation_enable) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + } + break; + + default: + { + } + break; + } + return cause; +} + +static void lns_ctl_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t write_length, uint8_t *p_value) +{ + uint8_t resp_code = LN_CP_RSPCODE_SUCCESS; + + bool error = false; + memcpy(lns_ctl_pnt.value, p_value, write_length); + lns_ctl_pnt.cur_length = write_length; + + PROFILE_PRINT_INFO1("lns_ctl_pnt_write_ind_post_proc: OpCode=0x%x", lns_ctl_pnt.value[0]); + + resp_code = lns_hanlde_ctl_pnt_proc_2(service_id, write_length, p_value); + + switch (lns_ctl_pnt.value[0]) + { + default: + { + error = true; + } + break; + + case LN_CP_OPCODE_SET_CUMULATIVE_VALUE: + { + lns_ctl_pnt_set_cumulative_value(conn_id, service_id, resp_code); + } + break; + + case LN_CP_OPCODE_MASK_LOCATION_AND_SPEED_CHAR_CONTENT: + { + lns_ctl_pnt_mask_location_speed_char_content(conn_id, service_id, resp_code); + } + break; + + case LN_CP_OPCODE_NAVIGATION_CONTROL: + { + lns_ctl_pnt_navigation_control(conn_id, service_id, resp_code); + } + break; + + case LN_CP_OPCODE_REQUEST_NUMBER_OF_ROUTES: + { + lns_ctl_pnt_request_number_of_routes(conn_id, service_id, resp_code, lns_cp_number_of_route); + } + break; + case LN_CP_OPCODE_REQUEST_NAME_OF_ROUTE: + { + lns_ctl_pnt_request_name_of_route(conn_id, service_id, resp_code, lns_cp_name_of_route, + lns_cp_name_of_route_len); + } + break; + + case LN_CP_OPCODE_SELECT_ROUTE: + { + lns_ctl_pnt_select_route(conn_id, service_id, resp_code); + } + break; + + case LN_CP_OPCODE_SET_FIX_RATE: + { + lns_ctl_pnt_set_fix_rate(conn_id, service_id, resp_code); + } + break; + + case LN_CP_OPCODE_SET_ELEVATION: + { + lns_ctl_pnt_set_elevation(conn_id, service_id, resp_code); + } + break; + } + + if (error) + { + lns_ln_ctl_pnt_value_indicate(conn_id, service_id, lns_ctl_pnt.value[0], + LN_CP_RSPCODE_OPCODE_UNSUPPORT, NULL, 0); + } + +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in] p_length length of getting characteristic data. + * @param[in] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT lns_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + PROFILE_PRINT_INFO2("lns_attr_read_cb iAttribIndex = %d iOffset %x", attrib_index, offset); + + *p_length = 0; + lns_ctl_pnt.value[0] = LN_CP_OPCODE_RESERVED;////// + + switch (attrib_index) + { + case LNS_LN_FEATURE_VALUE_INDEX: + { + *p_length = sizeof(lns_ln_feature_support); + *pp_value = (uint8_t *)&lns_ln_feature_support; + } + break; + + case LNS_LN_POSITION_QUALITY_VALUE_INDEX: + { + T_LNS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = LNS_READ_POSITION_QUALITY_VALUE; + pfn_lns_app_cb(service_id, (void *)&callback_data); + //after app call lns_set_parameter to set Position Quality Value, profile will response this value to remote device + lns_format_pq_value_for_read(); + *p_length = lns_pq_value_length_for_read_cfm; + *pp_value = lns_pq_value_for_read_cfm; + } + break; + + default: + { + PROFILE_PRINT_ERROR1("lns_attr_read_cb iAttribIndex = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return cause; +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param length length of value to be written. + * @param p_value value to be written. + * @param[in] p_write_ind_post_proc pointer of a function to handle attribute write. + * @return Profile procedure result +*/ +T_APP_RESULT lns_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO2("lns_attr_write_cb attrib_index = %d length %x", attrib_index, length); + + switch (attrib_index) + { + case LNS_LN_CP_VALUE_INDEX: + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > LNS_MAX_CTL_PNT_VALUE) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + /* Make sure Control Point is not "Process already in progress". */ + else if (lns_ctl_pnt.value[0] == LN_CP_OPCODE_RESPONSE_CODE) + { + PROFILE_PRINT_ERROR1("lns_attr_write_cb: lns_ctl_pnt.value[0] %d ", lns_ctl_pnt.value[0]); + cause = APP_RESULT_PROC_ALREADY_IN_PROGRESS; + } + /* Make sure Control Point is configured indication enable. */ + else if (!lns_notify_indicate_flag.ln_cp_indicate_enable) + { + cause = APP_RESULT_CCCD_IMPROPERLY_CONFIGURED; + } + else + { + cause = lns_hanlde_ctl_pnt_proc(conn_id, service_id, length, p_value); + if (cause == APP_RESULT_SUCCESS) + { + *p_write_ind_post_proc = lns_ctl_pnt_write_ind_post_proc; + } + else + { + *p_write_ind_post_proc = NULL; + } + } + + } + break; + + default: + { + PROFILE_PRINT_ERROR1("lns_attr_write_cb attrib_index = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return cause; +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void lns_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_LNS_CALLBACK_DATA callback_data; + bool bHandle = true; + + PROFILE_PRINT_INFO2("lns_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + case LNS_LN_LOCATION_AND_SPEED_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + lns_notify_indicate_flag.location_and_speed_notify_enable = 1; + callback_data.msg_data.notification_indification_index = + LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_ENABLE; + } + else + { + lns_notify_indicate_flag.location_and_speed_notify_enable = 0; + callback_data.msg_data.notification_indification_index = + LNS_NOTIFY_INDICATE_LOCATION_AND_SPEED_DISABLE; + } + } + break; + + case LNS_LN_CP_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + // Enable Indofication + lns_notify_indicate_flag.ln_cp_indicate_enable = 1; + callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_CP_ENABLE; + } + else + { + lns_notify_indicate_flag.ln_cp_indicate_enable = 0; + callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_CP_DISABLE; + } + + } + break; + + case LNS_LN_NAVIGATION_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + lns_notify_indicate_flag.navigation_enable = 1; + callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_NAVIGATION_ENABLE; + } + else + { + lns_notify_indicate_flag.navigation_enable = 0; + callback_data.msg_data.notification_indification_index = LNS_NOTIFY_INDICATE_NAVIGATION_DISABLE; + } + } + break; + + default: + { + bHandle = false; + PROFILE_PRINT_ERROR1("lns_cccd_update_cb Index = %d not found", index); + } + break; + + } + /* Notify Application. */ + if (pfn_lns_app_cb && (bHandle == true)) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + pfn_lns_app_cb(service_id, (void *)&callback_data); + } + return; +} + +/** + * @brief LOCATION AND NAVIGATION Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS lns_cbs = +{ + lns_attr_read_cb, // Read callback function pointer + lns_attr_write_cb, // Write callback function pointer + lns_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add location and navigation service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + lns_id = lns_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t lns_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)lns_attr_tbl, + lns_attr_tbl_size, + lns_cbs)) + { + PROFILE_PRINT_ERROR1("lns_add_service: ServiceId %d", service_id); + service_id = 0xff; + } + pfn_lns_app_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + + diff --git a/src/ble/profile/server/ota_service.c b/src/ble/profile/server/ota_service.c new file mode 100644 index 0000000..7838b10 --- /dev/null +++ b/src/ble/profile/server/ota_service.c @@ -0,0 +1,829 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file ota_service.c +* @brief +* @details +* @author Ken_mei +* @date 14-May-2018 +* @version v1.0.0 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +#include +#include "gatt.h" +#include "patch_header_check.h" +#include "ota_service.h" +#include "otp.h" +#include "trace.h" +#include "board.h" + +/*============================================================================* + * Micro + *============================================================================*/ +#define SOCV_CFG 0 +#define SYS_CFG 1 +#define OTA_HEADER 2 +#define SECURE_BOOT 3 +#define ROM_PATCH 4 +#define APP_IMG 5 +#define APP_DATA1 6 +#define APP_DATA2 7 +#define APP_DATA3 8 +#define APP_DATA4 9 +#define APP_DATA5 10 +#define APP_DATA6 11 + +#define IMAGE_NOEXIST 0 +#define IMAGE_LOCATION_BANK0 1 +#define IMAGE_LOCATION_BANK1 2 +#define IMAGE_FIX_BANK_EXIST 3 + +typedef struct +{ + uint8_t image_num; + uint16_t image_exist; + uint32_t image_indicator; +} T_OTA_ACTIVE_BANK_IMG_INFO; + +/*============================================================================* + * External Variables + *============================================================================*/ + +/*============================================================================* + * Local Variables + *============================================================================*/ +/**< Function pointer used to send event to application from BWPS extended profile. */ +P_FUN_SERVER_GENERAL_CB pfn_ota_service_cb = NULL; +uint8_t mac_addr[6]; +uint32_t patch_version = 0; +uint32_t patch_ext_version = 0; +uint32_t app_version = 0; +#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1) +uint16_t protocol_type = 0x0; +#endif +static uint32_t image_version[IMAGE_MAX - OTA] = {0}; +T_OTA_ACTIVE_BANK_IMG_INFO ota_active_bank_info; + +const uint8_t GATT_UUID_OTA_SERVICE[16] = { 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD0, 0x00, 0x00}; + +/**< @brief profile/service definition. +* here is an example of OTA service table +* including Write +*/ +const T_ATTRIB_APPL gatt_Ota_service_table[] = +{ + /*--------------------------OTA Service ---------------------------*/ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)GATT_UUID_OTA_SERVICE, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 1*/ //----------------------OTA CMD 1 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 2*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_OTA), + HI_WORD(GATT_UUID_CHAR_OTA), + }, + 2, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /* <>, .. 3, MAC Address*/ //------------------------MAC Address 2 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 4*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_MAC), + HI_WORD(GATT_UUID_CHAR_MAC), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 5, Patch version*/ //-------------------------Patch Version 3 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 6*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PATCH), + HI_WORD(GATT_UUID_CHAR_PATCH), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. 7 App version*/ //-----------------------------APP Version 4 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 8*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_APP_VERSION), + HI_WORD(GATT_UUID_CHAR_APP_VERSION), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* <>, .. 9 Patch extension version*/ //--------------------Patch Ext Version 5 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x0A*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PATCH_EXTENSION), + HI_WORD(GATT_UUID_CHAR_PATCH_EXTENSION), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0xB TEST MODE*/ //------------------------MP TEST MODE 6 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x0C*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_TEST_MODE), + HI_WORD(GATT_UUID_CHAR_TEST_MODE), + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + + /* <>, .. 0x0D OTA Device info*/ //---------------------------Device info 7 + { + ATTRIB_FLAG_VALUE_INCL, + { + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, + }, + 1, + NULL, + GATT_PERM_READ + }, + /* OTA Device info characteristic value 0x0E*/ + { + ATTRIB_FLAG_VALUE_APPL, + { + LO_WORD(GATT_UUID_CHAR_DEVICE_INFO), + HI_WORD(GATT_UUID_CHAR_DEVICE_INFO), + }, + 1, + (void *)NULL, + GATT_PERM_READ + }, + /* <>, .. 0x0F OTA IMAGE COUNT TO UPDATE*/ //----------------------NUM OF IMG TO UPDATA 8 + { + ATTRIB_FLAG_VALUE_INCL, + { + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE, + }, + 1, + NULL, + GATT_PERM_READ + }, + /* OTA IMAGE COUNT TO UPDATE characteristic value 0x10*/ + { + ATTRIB_FLAG_VALUE_APPL, + { + LO_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE), + HI_WORD(GATT_UUID_CHAR_IMAGE_COUNT_TO_UPDATE), + }, + 5, + (void *)NULL, + GATT_PERM_WRITE + }, + + /* <>, .. 0x11,ota pack img version*/ //-------------------------ota pack image version 9 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x12*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION0), + HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION0), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x13,ota pack img version*/ //-------------------------ota pack image version 9 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION1), + HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION1), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. 0x15,ota pack img version*/ //-------------------------ota pack image version 9 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x16*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_IMAGE_VERSION2), + HI_WORD(GATT_UUID_CHAR_IMAGE_VERSION2), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, + +#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1) + /* <>, .. 0x17,ota protocol type*/ //-------------------------ota protocol type 10 + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* OTA characteristic value 0x14*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE), + HI_WORD(GATT_UUID_CHAR_PROTOCOL_TYPE), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + }, +#endif +}; + + +/** + * @brief write characteristic data from service. + * + * @param ServiceID ServiceID to be written. + * @param iAttribIndex Attribute index of characteristic. + * @param wLength length of value to be written. + * @param pValue value to be written. + * @return Profile procedure result +*/ + +T_APP_RESULT ota_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_OTA_CALLBACK_DATA callback_data; + T_APP_RESULT wCause = APP_RESULT_SUCCESS; + + if (BLE_SERVICE_CHAR_OTA_INDEX == attrib_index) + { + /* Make sure written value size is valid. */ + if ((length != sizeof(uint8_t)) || (p_value == NULL)) + { + wCause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = OTA_WRITE_CHAR_VAL; + callback_data.msg_data.write.u.value = p_value[0]; + + if (pfn_ota_service_cb) + { + pfn_ota_service_cb(service_id, (void *)&callback_data); + } + } + } + else if (BLE_SERVICE_CHAR_IMAGE_COUNT_INDEX == attrib_index) + { + /* Make sure written value size is valid. */ + if ((length != OTA_CHAR_IMAGE_COUNT_LEN) || (p_value == NULL)) + { + wCause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = OTA_WRITE_IMAGE_COUNT_VAL; + callback_data.msg_data.write.u.update_image_info.image_count = p_value[0]; + callback_data.msg_data.write.u.update_image_info.update_patch_version = CHAR2SHORT(&p_value[1]); + callback_data.msg_data.write.u.update_image_info.update_app_version = CHAR2SHORT(&p_value[3]); + + if (pfn_ota_service_cb) + { + pfn_ota_service_cb(service_id, (void *)&callback_data); + } + } + } + else if (BLE_SERVICE_CHAR_TEST_MODE_INDEX == attrib_index) + { + /* Make sure written value size is valid. */ + if ((length != sizeof(uint8_t)) || (p_value == NULL)) + { + wCause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = OTA_WRITE_TEST_MODE_CHAR_VAL; + callback_data.msg_data.write.u.value = p_value[0]; + + if (pfn_ota_service_cb) + { + pfn_ota_service_cb(service_id, (void *)&callback_data); + } + } + } + else + { + DFU_PRINT_INFO2("==>[OTA]ota_attr_write_cb Error! attrib_index=0x%x, length=%d", + attrib_index, + length); + wCause = APP_RESULT_ATTR_NOT_FOUND; + } + return wCause; + +} + +/** + * @brief get OTA active bank image info + * @param[out] p_ota_image_info + * image_exist + * bit0: ota header, bit: fsbl, bit2: patch ..., bit9: appdata6, bit10: upperstack + * img_indicator + * Indications for each image version.each indication use 2bit. + * 00: image is not existed. + * 01: image is existed in bank0,ota should update image for bank1. + * 10: image is existed in bank1,ota should update image for bank0. + * 11: image is standalone. ota should update image for standalone. + * + * bit[1:0]: Image 0 + * bit[2N+1:2N]:Image N + + * Image indicator for bee3 is as below: + * Image 0 OTA Header File + * Image 1 Secure Boot Loader Image + * Image 2 ROM Patch Image + * Image 3 APP Image + * Image 4 APP Data1 File + * Image 5 APP Data2 File + * Image 6 APP Data3 File + * Image 7 APP Data4 File + * Image 8 APP Data5 File + * Image 9 APP Data6 File + * Image 10 Upperstack File +*/ +static void get_ota_active_bank_image_info(T_OTA_ACTIVE_BANK_IMG_INFO *p_ota_image_info) +{ + uint32_t image_location = IMAGE_NOEXIST; + bool enable_bank_switch = is_ota_support_bank_switch(); + p_ota_image_info->image_num = 0; + + if (enable_bank_switch) + { + uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0); + if (ota_bank0_addr == get_active_ota_bank_addr()) + { + image_location = IMAGE_LOCATION_BANK0; + } + else + { + image_location = IMAGE_LOCATION_BANK1; + } + } + else + { + image_location = IMAGE_FIX_BANK_EXIST; + } + + for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++) + { + if (0 != get_active_bank_image_size_by_img_id(image_id)) + { + p_ota_image_info->image_num++; + p_ota_image_info->image_exist |= BIT(image_id - OTA); + p_ota_image_info->image_indicator |= image_location << ((OTA_HEADER + image_id - OTA) * 2); + } + } +} +/** + * @brief read characteristic data from service. + * + * @param ServiceId ServiceID of characteristic data. + * @param iAttribIndex Attribute index of getting characteristic data. + * @param iOffset Used for Blob Read. + * @param piLength length of getting characteristic data. + * @param ppValue data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT ota_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT wCause = APP_RESULT_SUCCESS; + T_OTA_CALLBACK_DATA callback_data; + bool defer_handle = false; + + switch (attrib_index) + { + default: + DFU_PRINT_INFO1("==>ota_attr_read_cb: attrib_index=%d not found!", attrib_index); + wCause = APP_RESULT_ATTR_NOT_FOUND; + break; + case BLE_SERVICE_CHAR_MAC_ADDRESS_INDEX: + { + gap_get_param(GAP_PARAM_BD_ADDR, mac_addr); + uint8_t addr[6]; + for (int i = 0; i < 6; i++) + { + addr[i] = mac_addr[5 - i]; + } + memcpy(mac_addr, addr, 6); + *pp_value = (uint8_t *)mac_addr; + *p_length = sizeof(mac_addr); + } + break; + case BLE_SERVICE_CHAR_PATCH_INDEX: + { + T_IMG_HEADER_FORMAT *p_header; + uint32_t addr = get_header_addr_by_img_id(RomPatch); + p_header = (T_IMG_HEADER_FORMAT *)addr; + patch_version = p_header->git_ver.ver_info.version; + DFU_PRINT_INFO2("ota_attr_read_cb: Patch addr=0x%x, version=0x%x", addr, patch_version); + + *pp_value = (uint8_t *)&patch_version; + *p_length = sizeof(patch_version); + } + break; + + case BLE_SERVICE_CHAR_APP_VERSION_INDEX: + { + T_IMG_HEADER_FORMAT *p_header; + uint32_t addr = get_header_addr_by_img_id(AppPatch); + p_header = (T_IMG_HEADER_FORMAT *)addr; + app_version = p_header->git_ver.ver_info.version; + DFU_PRINT_INFO2("ota_attr_read_cb: APP addr=0x%x, version=0x%x", addr, app_version); + + *pp_value = (uint8_t *)&app_version; + *p_length = sizeof(app_version); + } + break; + + case BLE_SERVICE_CHAR_PATCH_EXTENSION_INDEX: //not used in bee2 + { + + } + break; + case BLE_SERVICE_CHAR_DEVICE_INFO_INDEX: + { + static T_DFU_DEVICE_INFO DeviceInfo; + T_IMG_HEADER_FORMAT *p_ota_header; + uint32_t ota_header_addr = get_header_addr_by_img_id(OTA); + p_ota_header = (T_IMG_HEADER_FORMAT *)ota_header_addr; + DeviceInfo.ic_type = DEFINED_IC_TYPE; + DeviceInfo.ota_version = 0x1; + DeviceInfo.secure_version = p_ota_header->ctrl_header.secure_version; + DFU_PRINT_INFO3("<==ota_attr_read_cb: ic_type=0x%x, ota_version=0x%x, OTA Header secure_version=0x%x", + DeviceInfo.ic_type, DeviceInfo.ota_version, DeviceInfo.secure_version); + + DeviceInfo.ota_mode.mode_flag.buf_check_en = DFU_BUFFER_CHECK_ENABLE; + DeviceInfo.max_buffer_size = DFU_TEMP_BUFFER_SIZE; + DeviceInfo.ota_mode.mode_flag.aesflg = OTP->ota_with_encryption_data; + DeviceInfo.ota_mode.mode_flag.aesmode = 1; + DFU_PRINT_INFO4("<==ota_attr_read_cb: bufChkEn=%d, bufsize=0x%x, aesflg=%d, aesmode=%d", + DeviceInfo.ota_mode.mode_flag.buf_check_en, DeviceInfo.max_buffer_size, + DeviceInfo.ota_mode.mode_flag.aesflg, DeviceInfo.ota_mode.mode_flag.aesmode); + + /* default disable copy app data img when bank switch */ + DeviceInfo.ota_mode.mode_flag.copy_img = 0; + + /* prepare img_indicator, if modify here need to sync with vaule + of BLE_SERVICE_CHAR_IMAGE_VERSION_INDEX */ + if (is_ota_support_bank_switch()) + { + //dual bank must support multiple image update + DeviceInfo.ota_mode.mode_flag.multi_img = 1; + uint32_t ota_bank0_addr = flash_get_bank_addr(FLASH_OTA_BANK_0); + if (ota_bank0_addr == get_active_ota_bank_addr()) + { + /* meaningful only when multi_img = 1 */ + DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_1) / FMC_SEC_SECTION_LEN; + } + else + { + /* meaningful only when multi_img = 1 */ + DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_BANK_0) / FMC_SEC_SECTION_LEN; + } + } + else + { +#if (SUPPORT_TEMP_COMBINED_OTA == 1) + DeviceInfo.ota_mode.mode_flag.multi_img = 1; +#else + DeviceInfo.ota_mode.mode_flag.multi_img = 0; +#endif + /* meaningful only when multi_img = 1 */ + DeviceInfo.temp_bank_size = flash_get_bank_size(FLASH_OTA_TMP) / FMC_SEC_SECTION_LEN; + } + /*read flash map info to set image indicator*/ + get_ota_active_bank_image_info(&ota_active_bank_info); + DeviceInfo.img_indicator = ota_active_bank_info.image_indicator; + + DFU_PRINT_INFO4("<==ota_attr_read_cb: copy_img=0x%x, multi_img=0x%x, temp_bank_size=0x%x, img_indicator=0x%x", + DeviceInfo.ota_mode.mode_flag.copy_img, DeviceInfo.ota_mode.mode_flag.multi_img, + DeviceInfo.temp_bank_size, DeviceInfo.img_indicator); + + + *pp_value = (uint8_t *)&DeviceInfo; + *p_length = sizeof(T_DFU_DEVICE_INFO); + } + break; + case BLE_SERVICE_CHAR_IMAGE_VERSION0_INDEX: + { + uint8_t index = 0; + T_IMAGE_VERSION image_ver; + + if (0 == ota_active_bank_info.image_num) + { + get_ota_active_bank_image_info(&ota_active_bank_info); + } + DFU_PRINT_INFO2("image_exist=0x%x(BIT0:OTA, BIT1:patch, ...), image_num=%d", + ota_active_bank_info.image_exist, ota_active_bank_info.image_num); + + for (T_IMG_ID image_id = OTA; image_id < IMAGE_MAX; image_id++) + { + if (ota_active_bank_info.image_exist & BIT(image_id - OTA)) + { + get_active_bank_image_version(image_id, &image_ver); + image_version[index] = image_ver.ver_info.version; + index ++; + DFU_PRINT_INFO2("image:0x%x exist!, version=0x%x", + image_id, image_ver.ver_info.version); + } + } + + *pp_value = (uint8_t *)image_version; + if (ota_active_bank_info.image_num > 5) + { + *p_length = 20; + } + else + { + *p_length = 4 * ota_active_bank_info.image_num; + } + DFU_PRINT_INFO5("Image Version[0-4]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", + image_version[0], image_version[1], image_version[2], image_version[3], image_version[4]); + + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX; + /*defer processing before ota start*/ + defer_handle = true; + } + break; + case BLE_SERVICE_CHAR_IMAGE_VERSION1_INDEX: + { + if (ota_active_bank_info.image_num > 5) + { + *pp_value = (uint8_t *)&image_version[5]; + if (ota_active_bank_info.image_num > 10) + { + *p_length = 20; + } + else + { + *p_length = 4 * (ota_active_bank_info.image_num - 5); + } + DFU_PRINT_INFO5("Image Version[5-9]: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", + image_version[5], image_version[6], image_version[7], image_version[8], image_version[9]); + } + else + { + *pp_value = NULL; + *p_length = 0; + } + + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX; + /*defer processing before ota start*/ + defer_handle = true; + } + break; + case BLE_SERVICE_CHAR_IMAGE_VERSION2_INDEX: + { + if (ota_active_bank_info.image_num > 10) + { + *pp_value = (uint8_t *)&image_version[10]; + *p_length = 4 * (ota_active_bank_info.image_num - 10); + //ota 11 images at most now + DFU_PRINT_INFO1("Image Version[10]: 0x%x", image_version[10]); + } + else + { + *pp_value = NULL; + *p_length = 0; + } + + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = OTA_READ_CHAR_IMAGE_VERSION_INDEX; + /*defer processing before ota start*/ + defer_handle = true; + } + break; +#if (SUPPORT_OTA_PROTOCOL_TYPE_CHARACTERISTIC == 1) + case BLE_SERVICE_CHAR_PROTOCOL_TYPE_INDEX: + { + protocol_type = 0x0012; + *pp_value = (uint8_t *)&protocol_type; + *p_length = sizeof(protocol_type); + } + break; +#endif + } + + /* Notify Application. */ + if (pfn_ota_service_cb && (defer_handle == true)) + { + pfn_ota_service_cb(service_id, (void *)&callback_data); + } + return (wCause); +} + + +/** + * @brief OTA ble Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS ota_service_cbs = +{ + ota_attr_read_cb, // Read callback function pointer + ota_attr_write_cb, // Write callback function pointer + NULL // CCCD update callback function pointer +}; + +/** + * @brief add OTA ble service to application. + * + * @param p_func pointer of app callback function called by profile. + * @return service ID auto generated by profile layer. + * @retval ServiceId +*/ +uint8_t ota_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)gatt_Ota_service_table, + sizeof(gatt_Ota_service_table), + ota_service_cbs)) + { + DFU_PRINT_ERROR1("<==ota_add_service: service_id=%d", service_id); + service_id = 0xff; + return service_id; + } + pfn_ota_service_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} diff --git a/src/ble/profile/server/plxs.c b/src/ble/profile/server/plxs.c new file mode 100644 index 0000000..9059125 --- /dev/null +++ b/src/ble/profile/server/plxs.c @@ -0,0 +1,1971 @@ +/** +*************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +*************************************************************************************** +* @file plxs.c +* @brief Pulse Oximeter Service source file. +* @details Interface to access the Pulse Oximeter Service. +* @author danni +* @date 2018-12-27 +* @version v1.0 +* ************************************************************************************* +*/ +#include "trace.h" +#include +#include +#include "plxs.h" + +/** @defgroup PLXS Pulse Oximeter Service + * @brief Pulse Oximeter Service + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup PLXS_SERVICE_UUID service related UUIDs. + * @{ + */ +#define GATT_UUID_PULSE_OXIMETER 0x1822 +#define GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT 0x2A5E +#define GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT 0x2A5F +#define GATT_UUID_CHAR_PLX_FEATURE 0x2A60 +#define GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT 0x2A52 +/** @} End of PLXS_SERVICE_UUID */ + +/** @brief Check PLXS Record Access Control Point operation is available or not. */ +#define PLXS_RACP_OPERATION_ACTIVE(x) (((x) >= PLXS_RACP_OPCODE_REPORT_RECS) && ((x) < PLXS_RACP_OPCODE_NBR_OF_RECS_RESP)) + +/** @defgroup PLXS_APP_ERROR_CODE profile specific attribute protocol application error codes + * @{ + */ +#define PLXS_ERR_PROC_ALREADY_IN_PROGRESS 0xFE +#define PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED 0xFD +/** @} End of PLXS_APP_ERROR_CODE */ + +/** @defgroup PLXS_SPOT_CHECK_FLAGS PLX Spot-check Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Spot-check + * Measurement Characteristic value + * @{ + */ +#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP 0x01 +#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x02 +#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x04 +#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x08 +#define PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_CLOCK_NOT_SET 0x10 +/** @} End of PLXS_SPOT_CHECK_FLAGS */ + +/** @defgroup PLXS_CONTINUOUS_MEAS_FLAGS PLX Continuous Measurement Characteristic Flags,The Flags field is an 8-bit bit field which indicates what fields are present in the PLX Continuous + * Measurement Characteristic value. + * @{ + */ +#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST 0x01 +#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW 0x02 +#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS 0x04 +#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS 0x08 +#define PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX 0x10 +/** @} End of PLXS_CONTINUOUS_MEAS_FLAGS */ + +/** @defgroup PLXS_FEASURES_FLAGS PLX Supported Features field. The Supported Features field is a 16-bit bit field which indicates feature support as well as what + * fields are present in the PLX Features characteristic. + * @{ + */ +#define PLXS_FEATURES_MEASUREMENT_STATUS 0x0001 +#define PLXS_FEATURES_DEVICE_SENSOR_STATUS 0x0002 +#define PLXS_FEATURES_MEASUREMENT_STORAGE 0x0004 +#define PLXS_FEATURES_TIMESTAMP 0x0008 +#define PLXS_FEATURES_SPO2PR_FAST_METRIC 0x0010 +#define PLXS_FEATURES_SPO2PR_SLOW_METRIC 0x0020 +#define PLXS_FEATURES_PULSE_AMPLITUDE_INDEX 0x0040 +#define PLXS_FEATURES_MULTIPLE_BONDS 0x0080 +/** @} End of PLXS_FEASURES_FLAGS */ +/** @} End of PLXS */ + +/** @brief The Server should be able to store 30 or more measurements*/ +#define PLXS_RACP_DATABASE_SIZE (PLXS_RACP_MAX_NBR_OF_STORED_RECS + 1) +/*============================================================================* + * Types + *============================================================================*/ +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT +typedef struct +{ + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measurement_value; + +} T_PLXS_PATIENT_RECORD; + +/** @brief data base for store spot check measurement value*/ +typedef struct +{ + T_PLXS_PATIENT_RECORD records[PLXS_RACP_DATABASE_SIZE]; + uint8_t record_num; + uint8_t head; + uint8_t tail; +} T_PLXS_RECORD_DATA_BASE; + +/** @brief PLXS Record Access Control Point OpCodes. */ +typedef enum +{ + PLXS_RACP_OPCODE_RESERVED = 0x00,/**< reserved for future use operator:N/A */ + PLXS_RACP_OPCODE_REPORT_RECS = 0x01,/**< report stored records(operator:All records)*/ + PLXS_RACP_OPCODE_DELETE_RECS = 0x02,/**< delete stored records(operator:All records)*/ + PLXS_RACP_OPCODE_ABORT_OPERATION = 0x03,/**< Abort operation(operator:Null 0x00)*/ + PLXS_RACP_OPCODE_REPORT_NBR_OF_RECS = 0x04,/**< report number of stored records(operator:All records)*/ + PLXS_RACP_OPCODE_NBR_OF_RECS_RESP = 0x05,/**< number of stored records response(operator:Null 0x00)*/ + PLXS_RACP_OPCODE_RESP_CODE = 0x06/**< response code (operator:Null 0x00)*/ +} T_PLXS_CTRL_POINT_OPCODE; + +/**@brief PLXS Record Access Control Point Operator. */ +typedef enum +{ + PLXS_RACP_OPERATOR_NULL = 0x00, + PLXS_RACP_OPERATOR_ALL_RECS = 0x01,/**< All records*/ + PLXS_RACP_OPERATOR_LT_EQ = 0x02,/**< less than or equal to*/ + PLXS_RACP_OPERATOR_GT_EQ = 0x03,/**< greater than or equal to*/ + PLXS_RACP_OPERATOR_RANGE = 0x04,/**< within range of */ + PLXS_RACP_OPERATOR_FIRST = 0x05,/**< first records*/ + PLXS_RACP_OPERATOR_LAST = 0x06/**< last records*/ +} T_PLXS_CTRL_POINT_OPERATOR; + +/** @brief Glucose Record Access Control Point Response Codes. */ +typedef enum +{ + PLXS_RACP_RESP_RESERVED = 0x00, + PLXS_RACP_RESP_SUCCESS = 0x01, + PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED = 0x02, + PLXS_RACP_RESP_INVALID_OPERATOR = 0x03, + PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED = 0x04, + PLXS_RACP_RESP_INVALID_OPERAND = 0x05, + PLXS_RACP_RESP_NO_RECS_FOUND = 0x06, + PLXS_RACP_RESP_ABORT_UNSUCCESSFUL = 0x07, + PLXS_RACP_RESP_PROC_NOT_COMPLETED = 0x08, + PLXS_RACP_RESP_OPERAND_NOT_SUPPORTED = 0x09 +} T_PLXS_CTRL_POINT_RESP_CODES; + +typedef struct +{ + T_PLXS_CTRL_POINT_OPCODE op_code; + T_PLXS_CTRL_POINT_OPERATOR op;/**< operator*/ + uint8_t operand[18]; +} T_PLXS_CONTROL_POINT; + +typedef struct +{ + T_PLXS_CONTROL_POINT ctrl_point; + uint8_t cp_length;/**< length of current operand of control point*/ + T_PLXS_RECORD_DATA_BASE record_db; +} T_PLXS_RACP; +/** @brief plxs report records procedure flags*/ +typedef struct +{ + uint16_t plxs_num_records_to_report; + uint16_t plxs_current_record_to_report; + uint16_t plxs_record_to_report_start_index; + uint16_t plxs_records_to_report_offset; + bool plxs_send_data_end_flag; +} T_PLXS_REPORT_RECORDS_FLAGS; +#endif +/** @brief notification or indiaction enabled or not.1:enabled,0: disabled*/ +typedef struct +{ + uint8_t spot_check_measurement_indication_enable: 1; + uint8_t continuous_measurement_notify_enable: 1; + uint8_t racp_indication_enable: 1; + uint8_t rfu: 5; +} T_PLXS_NOTIFY_INDICATE_FLAG; +/** @brief add flow control for notify and indicate*/ +typedef struct +{ + uint8_t spot_check_indication_status_flag; + uint8_t continuous_measurement_notify_status_flag; + uint8_t report_records_indication_status_flag; +} T_PLXS_DATA_SEND_STATUS_FLAGS; + +/******************************************************************************************************** +* local static and global variables defined here, only used in this source file. +********************************************************************************************************/ +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT +/**< @brief plxs record access control point struct*/ +static T_PLXS_RACP plxs_racp; +/**< @brief report stored repords procedure needs flags*/ +static T_PLXS_REPORT_RECORDS_FLAGS plxs_report_records_flags = {0, 0, 0, 0, 1}; +/**< @brief plxs abort procedure flags*/ +static bool plxs_abort_flag = false; +static bool plxs_abort_by_app_flag = false; +#endif +/**< @brief plxs feature characteristic value struct*/ +static T_PLXS_FEATURES_VALUE plxs_features; +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT +/**< @brief plxs spot check measurement flags*/ +static uint8_t plxs_spot_check_measurement_flags; +#endif +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT +/**< @brief plxs continuous measurement flags*/ +static uint8_t plxs_continuous_measurement_flags; +#endif +/**< @brief flags of notification and indication for characteristic */ +static T_PLXS_NOTIFY_INDICATE_FLAG plxs_notify_indicate_flag = {0}; + +static T_PLXS_DATA_SEND_STATUS_FLAGS plxs_data_send_status_flags = {PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE, + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE, + PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE + }; +/**< @brief Function pointer used to send event to application from plxs. Initiated in plxs_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_plxs_cb = NULL; + +/** @brief profile/service definition. */ +const T_ATTRIB_APPL plxs_att_tbl[] = +{ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /*wFlags*/ + { /*bTypeValue*/ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_PULSE_OXIMETER), /*service uuid*/ + HI_WORD(GATT_UUID_PULSE_OXIMETER) + }, + UUID_16BIT_SIZE, /*bValueLen*/ + NULL, /*pValueContext*/ + GATT_PERM_READ /*wPermissions*/ + + }, +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /*wFlags*/ + { /*bTypeValue*/ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_INDICATE /*characteristic properties*/ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /*bValueLen*/ + NULL, /*pValueContext*/ + GATT_PERM_READ /*wPermissions*/ + + }, + /*--- PLX Spot-check Measurement characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /*wFlags*/ + { + LO_WORD(GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_PLX_SPOT_CHECK_MEASUREMENT) + }, + 0, /*bValueLen*/ + NULL, /*pValueContext*/ + GATT_PERM_NONE /*wPermissions*/ + + }, + /*client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/*wFlags*/ + { + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value:*/ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /*bValueLen*/ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /*wPermissions*/ + }, +#endif + + +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, /*pValueContext*/ + GATT_PERM_READ /* wPermissions */ + }, + /*--- PLX Continuous Measurement characteristic value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_PLX_CONTINUOUS_MEASUREMENT) + }, + 0, /* bValueLen */ + NULL, /*pValueContext*/ + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value:*/ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + + }, + +#endif + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, /*pValueContext*/ + GATT_PERM_READ /* wPermissions */ + + }, + /*--- PLXS features characteristic value read ---*/ + { + ATTRIB_FLAG_VALUE_APPL, + { + LO_WORD(GATT_UUID_CHAR_PLX_FEATURE), + HI_WORD(GATT_UUID_CHAR_PLX_FEATURE) + + }, + 0, + NULL, + GATT_PERM_READ_AUTHEN_REQ + }, +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, + { + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, + NULL, + GATT_PERM_READ + + }, + /*--- PLXS Record Access Control Point value ---*/ + { + ATTRIB_FLAG_VALUE_APPL, + { + LO_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT) + }, + 0, + NULL, + GATT_PERM_WRITE_AUTHEN_REQ + }, + /* client characteristic configuration */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL),/* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value:*/ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, /*pValueContext*/ + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* wPermissions */ + } +#endif +}; +/******************************************************************************************************** +* functions +********************************************************************************************************/ +/** + * @brief init spot-check measurement characteristic flags, continuous measurement + * characteristic flags and feature characteristic flags according Macros defined in plxs_config.h + * + * @param[in] None + * @return None + * Example usage + * \code{.c} + T_SERVER_ID plxs_add_service(void * p_func) + { + plxs_flags_init(); + ...... + } + * \endcode + */ +void plxs_flags_init() +{ +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot check start +#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT //TIMESTAMP_SUPPORT start + plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP; +#endif //TIMESTAMP_SUPPORT end + +#if PLXS_MEASUREMENT_STATE_SUPPORT //MEASUREMENT_STATE_SUPPORT start + plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS; +#endif //MEASUREMENT_STATE_SUPPORT end + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT //DEVICE_AND_SENSOR_STATUS_SUPPORT start + plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS; +#endif //DEVICE_AND_SENSOR_STATUS_SUPPORT end + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX; +#endif + +#if PLXS_DEVICE_CLOCK_NOT_SET + plxs_spot_check_measurement_flags |= PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_CLOCK_NOT_SET; +#endif +#endif //spot check end + +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT // continueous measurement start +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT + plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST; +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT + plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW; +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS; +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS; +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + plxs_continuous_measurement_flags |= PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX; +#endif +#endif //continuous measurement end + +//plxs feature support bit init +#if PLXS_MEASUREMENT_STATE_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_MEASUREMENT_STATUS; + plxs_features.measurement_status_support_bits = PLXS_FEATURES_MEASUREMENT_STATUS_SUPPORTS; +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_DEVICE_SENSOR_STATUS; + plxs_features.device_and_sensor_status_support_bits = PLXS_FEATURES_DEVICE_SENSOR_STATUS_SUPPORTS; +#endif + +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_MEASUREMENT_STORAGE; +#endif + +#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_TIMESTAMP; +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_SPO2PR_FAST_METRIC; +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_SPO2PR_SLOW_METRIC; +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_PULSE_AMPLITUDE_INDEX; +#endif + +#if PLXS_MULTIPLE_BONDS_SUPPORT + plxs_features.supported_features |= PLXS_FEATURES_MULTIPLE_BONDS; +#endif +} +/** + * @brief Set PLX service parameter. + * set spot_check characteristic vaule ,continuous measurement characteristic value, + * feature characteristic value and racp characteristic value used parameters + * @param[in] param_type parameter type set by T_PLXS_PARAM_TYPE @refT_PLXS_PARAM_TYPE. + * @param[in] len type value length to be set + * @param[in] p_value type value to be set + * @return parameter set result. + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation failure. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_PLXS_FEATURES_VALUE plxs_features; + ...... + plxs_set_parameter(PLXS_PARAM_FEATURE_FLAGS, 2, &plxs_features); + return RESULT_SUCESS; + } + * \endcode + */ +T_PLXS_APP_RESULT plxs_set_parameter(T_PLXS_PARAM_TYPE param_type, uint8_t len, + void *p_value)////todo: just for bqb,maybe not used by user????? +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + if (p_value == NULL) + { + ret = PLXS_APP_RESULT_POINTER_NULL; + PROFILE_PRINT_ERROR0("plxs_set_parameter:PLXS_APP_RESULT_POINTER_NULL"); + return ret; + } + switch (param_type) + { + // set plxs feature value according to PLXS_PARAM_FEATURE_FLAGS + case PLXS_PARAM_FEATURE_FLAGS: + { + plxs_features = *((T_PLXS_FEATURES_VALUE *)p_value); + } + break; +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot-check start + case PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS: + { + //set plxs spot check measurement flags + if (len == 1) + { + plxs_spot_check_measurement_flags = *((uint8_t *)p_value); + } + else + { + ret = PLXS_APP_RESULT_INVALID_VALUE_SIZE; + } + } + break; +#endif //spot-check end + +# if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT//continuous-measurement start + case PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS: + { + //set continuous measurement flags + if (len == 1) + { + plxs_continuous_measurement_flags = *((uint8_t *)p_value); + } + else + { + ret = PLXS_APP_RESULT_INVALID_VALUE_SIZE; + } + } + break; +#endif //continuous-measurement end + default: + { + ret = PLXS_APP_RESULT_INVALID_TYPE; + } + break; + } + if (ret == PLXS_APP_RESULT_SUCCESS) + { + PROFILE_PRINT_INFO2("plxs_set_parameter success: param_type = %d,value = %x\n", param_type, + *(uint8_t *)p_value); + } + else + { + PROFILE_PRINT_ERROR2("plxs_set_parameter failed: param_type = %d,value = %x\n", param_type, + *(uint8_t *)p_value); + } + return ret; +} + +/** + * @brief get plxs parameters such as spot check measurement flags,continuous measurement flags or features supports @ref T_PLXS_PARAM_TYPE + * + * @param[in] param_type @ref T_PLXS_PARAM_TYPE + * @param[in,out] p_value get spot check measurement flags,continuous measurement flags or features supports + * @return plxs_get_parameter result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_plxs_feature_flags_set(T_USER_CMD_PARSED_VALUE *p_parse_value) + { + T_PLXS_FEATURES_VALUE plxs_features; + plxs_get_parameter(PLXS_PARAM_FEATURE_FLAGS, &plxs_features); + if (p_parse_value->dw_param[0] == 1) + { + //both measurement status and device sensor status not support + plxs_features.supported_features = plxs_features.supported_features & 0xFFFC; + } + ...... + } + * \endcode + */ +T_PLXS_APP_RESULT plxs_get_parameter(T_PLXS_PARAM_TYPE param_type, void *p_value) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + if (p_value == NULL) + { + ret = PLXS_APP_RESULT_POINTER_NULL; + PROFILE_PRINT_ERROR0("plxs_get_parameter:PLXS_APP_RESULT_POINTER_NULL"); + return ret; + } + switch (param_type) + { + case PLXS_PARAM_FEATURE_FLAGS: + { + //get feature value + memcpy((T_PLXS_FEATURES_VALUE *)p_value, &plxs_features, sizeof(T_PLXS_FEATURES_VALUE)); + } + break; +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT//continuous-measurement start + case PLXS_PARAM_CONTINUOUS_MEASUREMENT_FLAGS: + { + //get continuous measurement flags + memcpy((uint8_t *)p_value, &plxs_continuous_measurement_flags, 1); + } + break; +#endif //continuous-measurement end + +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT //spot-check start + case PLXS_PARAM_SPOT_CHECK_MEASUREMENT_FLAGS: + { + //get spot check measurement flags + memcpy((uint8_t *)p_value, &plxs_spot_check_measurement_flags, 1); + } + break; +#endif //spot-check end + default: + { + ret = PLXS_APP_RESULT_INVALID_TYPE; + } + } + return ret; +} + + +/** + * @brief pop record from database + * + * @param[in] p_spot_check_value pointer to p_spot_check_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE + * @return result + * @retval PLXS_APP_RESULT_SUCCESS operator success + * @retval others operator fail + */ +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT +T_PLXS_APP_RESULT pop_record_from_database(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_value) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + if (p_spot_check_value == NULL) + { + ret = PLXS_APP_RESULT_POINTER_NULL; + PROFILE_PRINT_ERROR0("pop_record_from_database:PLXS_APP_RESULT_POINTER_NULL"); + return ret; + } +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + if (plxs_racp.record_db.tail == plxs_racp.record_db.head) + { + PROFILE_PRINT_ERROR0("pop_record_from_database: PLXS_APP_RESULT_QUEUE_NULL"); + ret = PLXS_APP_RESULT_QUEUE_NULL; + return ret; + } + *p_spot_check_value = + plxs_racp.record_db.records[plxs_racp.record_db.head].plxs_spot_check_measurement_value; + plxs_racp.record_db.head = (plxs_racp.record_db.head + 1) % PLXS_RACP_DATABASE_SIZE; + plxs_racp.record_db.record_num--; +#else + PROFILE_PRINT_ERROR0("pop_record_from_database: not support"); + ret = PLXS_APP_RESULT_NOT_SUPPORT; +#endif + return ret; +} + +/** + * @brief push spot check measurement records to database + * @param[in] spot_check_value + * @return result + * @retval PLXS_APP_RESULT_SUCCESS operator success + * @retval others operator fail + * Example usage + * \code{.c} + void test_plxs(void) + { + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value; + //spot_check_indication_test + bool result = push_record_to_database(plxs_spot_check_measure_value); + if(result == PLXS_APP_RESULT_SUCCESS) + { + ...... + } + } + * \endcode + */ +T_PLXS_APP_RESULT push_record_to_database(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE spot_check_value) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + PROFILE_PRINT_INFO0("plxs_ push_record_to_database enter"); + if (((plxs_racp.record_db.tail + 1) % PLXS_RACP_DATABASE_SIZE) == plxs_racp.record_db.head) + { + PROFILE_PRINT_ERROR0("push_record_to_database database full delete the oldest record"); + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE spot_check_value; + pop_record_from_database(&spot_check_value); + } + plxs_racp.record_db.records[plxs_racp.record_db.tail].plxs_spot_check_measurement_value = + spot_check_value; + plxs_racp.record_db.tail = (plxs_racp.record_db.tail + 1) % PLXS_RACP_DATABASE_SIZE; + plxs_racp.record_db.record_num++; +#else + PROFILE_PRINT_ERROR0("plxs_ push_record_to_database not support"); + ret = PLXS_APP_RESULT_NOT_SUPPORT; +#endif + return ret; +} + +/** + * @brief send plxs spot check measurement characteristic indication from records database + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] index record index in database + * @return plxs_spot_check_measurement_value_store_indicate result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + bool plxs_report_records_task(uint8_t conn_id, T_SERVER_ID service_id) + { + if (plxs_spot_check_measurement_value_store_indicate(conn_id, service_id,plxs_report_records_flags.plxs_current_record_to_report++) == PLXS_APP_RESULT_SUCCESS) + { + PROFILE_PRINT_INFO1("plxs_report_records_task:record:%d,success",plxs_report_records_flags.plxs_current_record_to_report); + } + else + { + ret = false; + PROFILE_PRINT_ERROR1("plxs_report_records_task:record:%d,fail",plxs_report_records_flags.plxs_current_record_to_report); + } + } + * \endcode + */ +T_PLXS_APP_RESULT plxs_spot_check_measurement_value_store_indicate(uint8_t conn_id, + T_SERVER_ID service_id, uint8_t index) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO1("plxs_spot_check_measurement_value_store_indicate enter index = %d", index); + if (plxs_data_send_status_flags.report_records_indication_status_flag == + PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING + || plxs_data_send_status_flags.spot_check_indication_status_flag == + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING) + { + ret = PLXS_APP_RESULT_PENDING; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate:indication procedure is doing please send data later!!"); + return ret; + } + if (plxs_notify_indicate_flag.spot_check_measurement_indication_enable == 0) + { + ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate: PLXS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + int current = (plxs_report_records_flags.plxs_record_to_report_start_index + index) % + PLXS_RACP_DATABASE_SIZE; + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value = + &plxs_racp.record_db.records[current].plxs_spot_check_measurement_value; + uint8_t temp_spot_check_measurement_value[sizeof(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE)]; + uint8_t offset = 0; + if (index >= plxs_racp.record_db.record_num) + { + PROFILE_PRINT_ERROR2("plxs_spot_check_measurement_value_store_indicate access overflow, index = %d,total_record_num = %d", + index, plxs_racp.record_db.record_num); + ret = PLXS_APP_RESULT_INVALID_OFFSET; + return ret; + } + if (current == plxs_racp.record_db.tail) + { + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate database empty"); + ret = PLXS_APP_RESULT_QUEUE_NULL; + return ret; + } + memcpy(&temp_spot_check_measurement_value[offset], &plxs_spot_check_measurement_flags, 1); + offset += 1; + memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->spo2, 2); + offset += 2; + memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->pr, 2); + offset += 2; +#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP) + { + memcpy(&temp_spot_check_measurement_value[offset], &p_spot_check_measurement_value->time, 7); + offset += 7; + } +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS) + { + memcpy(&temp_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->measurement_status, 2); + offset += 2; + } +#endif + +# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS) + { + memcpy(&temp_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->device_and_sensor_status, 3); + offset += 3; + } +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX) + { + memcpy(&temp_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->pulse_amplitude_index, 2); + offset += 2; + } +#endif + + if (server_send_data(conn_id, service_id, PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX, + temp_spot_check_measurement_value, offset, GATT_PDU_TYPE_INDICATION)) + { + PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_store_indicate:server_send_data and set status doing success"); + plxs_data_send_status_flags.report_records_indication_status_flag = + PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING; + } + else + { + ret = PLXS_APP_RESULT_FAIL; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_store_indicate:server_send_data fail"); + plxs_data_send_status_flags.report_records_indication_status_flag = + PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE; + } + return ret; +} +#endif +/** + * @brief send plxs spot check measurement characteristic indication + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] p_spot_check_measurement_value @ref T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE + * @return plxs_spot_check_measurement_value_indicate result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + void test_plxs(void) + { + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE plxs_spot_check_measure_value; + ......//plxs_spot_check_measure_value initialization + bool result = plxs_spot_check_measurement_value_indicate(conn_id,plxs_srv_id,&plxs_spot_check_measure_value); + if(result == PLXS_APP_RESULT_SUCCESS) + { + } + } + * \endcode + */ +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT +T_PLXS_APP_RESULT plxs_spot_check_measurement_value_indicate(uint8_t conn_id, uint8_t service_id, + T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE *p_spot_check_measurement_value) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + if (p_spot_check_measurement_value == NULL) + { + ret = PLXS_APP_RESULT_POINTER_NULL; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate: PLXS_APP_RESULT_POINTER_NULL"); + return ret; + } + if (plxs_notify_indicate_flag.spot_check_measurement_indication_enable == 0) + { + ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate: PLXS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_indicate enter"); + if (plxs_data_send_status_flags.spot_check_indication_status_flag == + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + || plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS +#endif + ) + { + ret = PLXS_APP_RESULT_PENDING; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate:procedure is doing please send data later!!"); + return ret; + } + uint8_t temp_plxs_spot_check_measurement_value[sizeof(T_PLXS_SPOT_CHECK_MEASUREMENT_VALUE)]; + uint8_t offset = 0; + memcpy(&temp_plxs_spot_check_measurement_value[offset], &plxs_spot_check_measurement_flags, 1); + offset += 1; + memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->spo2, 2); + offset += 2; + memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->pr, 2); + offset += 2; + +#if PLXS_SPOT_CHECK_MEASUREMENT_TIMESTAMP_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_TIMESTAMP) + { + memcpy(&temp_plxs_spot_check_measurement_value[offset], &p_spot_check_measurement_value->time, 7); + offset += 7; + } +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_MEASUREMENT_STATUS) + { + memcpy(&temp_plxs_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->measurement_status, 2); + offset += 2; + } +#endif + +# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS) + { + memcpy(&temp_plxs_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->device_and_sensor_status, 3); + offset += 3; + } +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + if (plxs_spot_check_measurement_flags & PLXS_SPOT_CHECK_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX) + { + memcpy(&temp_plxs_spot_check_measurement_value[offset], + &p_spot_check_measurement_value->pulse_amplitude_index, 2); + offset += 2; + } +#endif + + if (server_send_data(conn_id, service_id, PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX, + temp_plxs_spot_check_measurement_value, offset, + GATT_PDU_TYPE_INDICATION)) + { + PROFILE_PRINT_INFO0("plxs_spot_check_measurement_value_indicate:server_send_data and set status doing success"); + plxs_data_send_status_flags.spot_check_indication_status_flag = + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING; + } + else + { + ret = PLXS_APP_RESULT_FAIL; + PROFILE_PRINT_ERROR0("plxs_spot_check_measurement_value_indicate:server_send_data fail"); + //if send fail data may be need to be stored +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + push_record_to_database(*p_spot_check_measurement_value); +#endif + plxs_data_send_status_flags.spot_check_indication_status_flag = + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE; + } + return ret; +} +#endif +/** + * @brief send plxs continuous measurement characteristic notification + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] plxs_continuous_measurement_value @ref T_PLXS_CONTINUOUS_MEASUREMENT_VALUE + * @return plxs_continuous_measurement_value_notify result + * @retval PLXS_APP_RESULT_SUCCESS Operation success. + * @retval others Operation fail. + * + * Example usage + * \code{.c} + void test_plxs(void) + { + ......//plxs_continuous_measurement_value initialization + bool result = plxs_continuous_measurement_value_notify( conn_id, plxs_srv_id,&plxs_continuous_measurement_value); + if(result == PLXS_APP_RESULT_SUCCESS) + { + PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify notify data send success!"); + } + } + * \endcode + */ +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT +T_PLXS_APP_RESULT plxs_continuous_measurement_value_notify(uint8_t conn_id, T_SERVER_ID service_id, + T_PLXS_CONTINUOUS_MEASUREMENT_VALUE *p_plxs_continuous_measurement_value) +{ + T_PLXS_APP_RESULT ret = PLXS_APP_RESULT_SUCCESS; + if (p_plxs_continuous_measurement_value == NULL) + { + ret = PLXS_APP_RESULT_POINTER_NULL; + PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:PLXS_APP_RESULT_POINTER_NULL"); + return ret; + } + if (plxs_notify_indicate_flag.continuous_measurement_notify_enable == 0) + { + ret = PLXS_APP_RESULT_CCCD_NOT_ENABLED; + PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify: PLXS_APP_RESULT_CCCD_NOT_ENABLED"); + return ret; + } + if (plxs_data_send_status_flags.continuous_measurement_notify_status_flag == + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING) + { + ret = PLXS_APP_RESULT_PENDING; + PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:procedure is doing please send data later!!"); + return ret; + } + uint8_t temp_plxs_continuous_measurement_value[sizeof(T_PLXS_CONTINUOUS_MEASUREMENT_VALUE)]; + uint8_t offset = 0; + + memcpy(&temp_plxs_continuous_measurement_value[offset], &plxs_continuous_measurement_flags, 1); + offset += 1; + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_normal.spo2, 2); + offset += 2; + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_normal.pr, 2); + offset += 2; +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_FAST_SUPPORT + if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_FAST) + { + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_fast.spo2, 2); + offset += 2; + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_fast.pr, 2); + offset += 2; + } +#endif + +#if PLXS_CONTINUOUS_MEASUREMENT_SPO2PR_SLOW_SUPPORT + if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_SPO2PR_SLOW) + { + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_slow.spo2, 2); + offset += 2; + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->spo2pr_slow.pr, 2); + offset += 2; + } +#endif + +#if PLXS_MEASUREMENT_STATE_SUPPORT + if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_MEASUREMENT_STATUS) + { + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->measurement_status, 2); + offset += 2; + } +#endif + +# if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_DEVICE_SENSOR_STATUS) + { + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->device_and_sensor_status, 3); + offset += 3; + } +#endif + +#if PLXS_PULSE_AMPLITUDE_INDEX_SUPPORT + if (plxs_continuous_measurement_flags & PLXS_CONTINUOUS_MEASUREMENT_FLAG_PULSE_AMPLITUDE_INDEX) + { + memcpy(&temp_plxs_continuous_measurement_value[offset], + &p_plxs_continuous_measurement_value->pulse_amplitude_index, 2); + offset += 2; + } +#endif + if (server_send_data(conn_id, service_id, PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX, + temp_plxs_continuous_measurement_value, offset, + GATT_PDU_TYPE_NOTIFICATION)) + { + PROFILE_PRINT_INFO0("plxs_continuous_measurement_value_notify:server_send_data and set status doing success"); + plxs_data_send_status_flags.continuous_measurement_notify_status_flag = + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING; + + } + else + { + ret = PLXS_APP_RESULT_FAIL; + PROFILE_PRINT_ERROR0("plxs_continuous_measurement_value_notify:server_send_data fail"); + plxs_data_send_status_flags.continuous_measurement_notify_status_flag = + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE; + } + return ret; +} +#endif +/** + * @brief check cccd enabled or disabled + * + * @param[in] None + * @return cccd check result + * @retval false Operation failure. + * @retval true Operation success. + */ +bool plxs_check_cccd() +{ + if ((0 == plxs_notify_indicate_flag.racp_indication_enable) || + (0 == plxs_notify_indicate_flag.spot_check_measurement_indication_enable)) + { + return false;//cccd not enabled return false + } + else + { + return true; + } +} +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result + */ +T_APP_RESULT plxs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO2("plxs_attr_read_cb attribIndex = %d offset %x", attrib_index, offset); + *p_length = 0; + static uint8_t temp_plxs_features[sizeof(T_PLXS_FEATURES_VALUE)] = {0}; + switch (attrib_index) + { + case PLXS_CHAR_FEATURE_INDEX: + { + memcpy(&temp_plxs_features[*p_length], &plxs_features.supported_features, + sizeof(plxs_features.supported_features)); + *p_length = sizeof(plxs_features.supported_features); +#if PLXS_MEASUREMENT_STATE_SUPPORT + if (plxs_features.supported_features & PLXS_FEATURES_MEASUREMENT_STATUS) + { + PROFILE_PRINT_INFO1("plxs_features.measurement_status 0x%x", + plxs_features.measurement_status_support_bits); + memcpy(&temp_plxs_features[*p_length], &plxs_features.measurement_status_support_bits, 2); + *p_length += 2; + } +#endif + +#if PLXS_DEVICE_AND_SENSOR_STATUS_SUPPORT + if (plxs_features.supported_features & PLXS_FEATURES_DEVICE_SENSOR_STATUS) + { + PROFILE_PRINT_INFO1("plxs_features.device_and_sensor_status 0x%x", + plxs_features.device_and_sensor_status_support_bits); + memcpy(&temp_plxs_features[*p_length], &plxs_features.device_and_sensor_status_support_bits, 3); + *p_length += 3; + } +#endif + *pp_value = temp_plxs_features; + } + break; + default: + { + PROFILE_PRINT_ERROR1("plxs_attr_read_cb, attr not found, index=%d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return cause; +} + + +/** + * @brief abort procedure. + * @param[in] None + * @return None + * + */ +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT +void plxs_abort_racp_procedure(void) +{ + if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS) + { + plxs_abort_by_app_flag = true; + } + else + { + PROFILE_PRINT_INFO0("plxs_abort_racp_procedure no procedure to abort by application"); + } +} + +/** + * @brief response report records number control point procedure result to client + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] num number of records + * @return report records number procedure result + */ +bool plxs_racp_num_response(uint8_t conn_id, T_SERVER_ID service_id, uint16_t num) +{ + bool ret; + T_PLXS_RACP temp_racp; + uint16_t attrib_index = PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX; + LE_UINT16_TO_ARRAY(temp_racp.ctrl_point.operand, num); + temp_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_NBR_OF_RECS_RESP; + temp_racp.ctrl_point.op = PLXS_RACP_OPERATOR_NULL; + temp_racp.cp_length = sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_OPERATOR) + + sizeof(uint16_t); + ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *)&temp_racp.ctrl_point, + temp_racp.cp_length, GATT_PDU_TYPE_INDICATION); + PROFILE_PRINT_INFO1("plxs_racp_num_response num of records: %d \n", num); + return ret; +} + +/** + * @brief response control point procedure result to client + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] opcode opcode + * @param[in] rsp_code + * @return response control point procedure result + */ +bool plxs_racp_response(uint8_t conn_id, T_SERVER_ID service_id, uint8_t opcode, uint8_t rsp_code) +{ + bool ret; + T_PLXS_RACP temp_racp; + uint16_t attrib_index = PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX; + + temp_racp.ctrl_point.operand[0] = opcode; + temp_racp.ctrl_point.operand[1] = rsp_code; + temp_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESP_CODE; + temp_racp.ctrl_point.op = PLXS_RACP_OPERATOR_NULL; + temp_racp.cp_length = sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_OPERATOR) + + sizeof(T_PLXS_CTRL_POINT_OPCODE) + sizeof(T_PLXS_CTRL_POINT_RESP_CODES); + + // send indication to client + ret = server_send_data(conn_id, service_id, attrib_index, (uint8_t *)&temp_racp.ctrl_point, + temp_racp.cp_length, GATT_PDU_TYPE_INDICATION); + PROFILE_PRINT_INFO1("plxs_racp_response code value: %d \n", rsp_code); + return ret; +} + +/** + * @brief delete spot check measurement records from database + * + * @param[in] None + * @return delete result + * @retval true success + * Example usage + * \code{.c} + void test_plxs(void) + { + delete_all_records_from_database(); + } + * \endcode + */ +bool delete_all_records_from_database() +{ + bool ret = true; + plxs_racp.record_db.tail = plxs_racp.record_db.head; + plxs_racp.record_db.record_num = 0; + return ret; +} + +/** + * @brief check if report records procedure has complete,if not complete continuous report records + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @return check result + * @retval false Operation failure. + * @retval true Operation success. + */ +bool plxs_check_records_report_complete(uint8_t conn_id, T_SERVER_ID service_id) +{ + + if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS) + { + PROFILE_PRINT_INFO1("plxs_records_to_report_offset:%d", + plxs_report_records_flags.plxs_records_to_report_offset); + plxs_report_records_flags.plxs_records_to_report_offset = + plxs_report_records_flags.plxs_current_record_to_report; + return false; + } + else + { + return true; + } +} + +/** + * @brief report spot check measurement value stored in database to client + * + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @return plxs report records task result + * @retval false Operation failure. + * @retval true Operation success. + */ +bool plxs_report_records_task(uint8_t conn_id, T_SERVER_ID service_id) +{ + bool ret = true; + if (plxs_abort_flag == true) + { + uint8_t opcode = PLXS_RACP_OPCODE_ABORT_OPERATION; + PROFILE_PRINT_INFO2("plxs_report_records_task request opcode = %x,response code value = %x", opcode, + PLXS_RACP_RESP_SUCCESS); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp_response(conn_id, service_id, opcode, PLXS_RACP_RESP_SUCCESS); + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + plxs_abort_flag = false; + plxs_report_records_flags.plxs_send_data_end_flag = true; + + return ret; + } + if (plxs_abort_by_app_flag == true) + { + PROFILE_PRINT_INFO2("plxs_report_records_task request opcode = %x,response code value = %x", + plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_PROC_NOT_COMPLETED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_PROC_NOT_COMPLETED); + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + plxs_abort_by_app_flag = false; + plxs_report_records_flags.plxs_send_data_end_flag = true; + return ret; + } + if (plxs_report_records_flags.plxs_send_data_end_flag == true) + { + PROFILE_PRINT_INFO0("plxs_report_records_task plxs_send_data_end_flag== true"); + //plxs_send_data_end_flag = false; + return ret; + } + if ((plxs_report_records_flags.plxs_current_record_to_report >= + plxs_report_records_flags.plxs_num_records_to_report) && + plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS) + { + PROFILE_PRINT_INFO0("plxs_report_records_task all records send success"); + plxs_report_records_flags.plxs_send_data_end_flag = true; + plxs_report_records_flags.plxs_current_record_to_report = 0; + //plxs_records_to_report_offset = 0; + //plxs_record_to_report_start_index = 0; + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_SUCCESS); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return true; + } + PROFILE_PRINT_INFO3("plxs_report_records_task current = %d, total = %d,start_index = %d ", + plxs_report_records_flags.plxs_current_record_to_report, + plxs_report_records_flags.plxs_num_records_to_report, + plxs_report_records_flags.plxs_record_to_report_start_index); + + if (plxs_spot_check_measurement_value_store_indicate(conn_id, service_id, + plxs_report_records_flags.plxs_current_record_to_report++) == PLXS_APP_RESULT_SUCCESS) + { + PROFILE_PRINT_INFO1("plxs_report_records_task:record:%d,success", + plxs_report_records_flags.plxs_current_record_to_report); + } + else + { + ret = false; + PROFILE_PRINT_ERROR1("plxs_report_records_task:record:%d,fail", + plxs_report_records_flags.plxs_current_record_to_report); + } + return ret; +} + +/** + * @brief plxs report records + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @return None + * + */ +void plxs_report_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + PROFILE_PRINT_INFO2(" plxs_report_records opcode = %x,operator = %x", + plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op); + if (plxs_racp.ctrl_point.op >= 7) + { + PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_INVALID_OPERATOR"); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS) + { + PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED"); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_INVALID_OPERATOR); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (plxs_racp.record_db.record_num == 0) + { + PROFILE_PRINT_ERROR0("plxs_report_records PLXS_RACP_RESP_NO_RECS_FOUND"); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_NO_RECS_FOUND); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return ; + } + else + { + + plxs_report_records_flags.plxs_record_to_report_start_index = plxs_racp.record_db.head; + plxs_report_records_flags.plxs_current_record_to_report = + plxs_report_records_flags.plxs_records_to_report_offset; + plxs_report_records_flags.plxs_send_data_end_flag = false; + plxs_report_records_flags.plxs_num_records_to_report = plxs_racp.record_db.record_num; + if (plxs_report_records_flags.plxs_records_to_report_offset >= + plxs_report_records_flags.plxs_num_records_to_report) + { + PROFILE_PRINT_ERROR0("plxs_report_records after first report success no records to be report"); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_NO_RECS_FOUND); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return ; + } + if (false == plxs_report_records_task(conn_id, service_id)) + { + PROFILE_PRINT_ERROR0("plxs_report_records_task false"); + plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_REPORT_RECS, + PLXS_RACP_RESP_PROC_NOT_COMPLETED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + plxs_report_records_flags.plxs_send_data_end_flag = true; + plxs_report_records_flags.plxs_current_record_to_report = + plxs_report_records_flags.plxs_records_to_report_offset; + }; + } +} + +/** + * @brief plxs_report_num_of_records + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @return None + * + */ +void plxs_report_num_of_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + PROFILE_PRINT_INFO2(" plxs_report_num_of_records opcode = %x,operator = %x", + plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op); + if (plxs_racp.ctrl_point.op >= 7) + { + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS) + { + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_INVALID_OPERATOR); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + uint16_t num_of_records; + num_of_records = plxs_racp.record_db.record_num; + plxs_racp_num_response(conn_id, service_id, num_of_records); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; +} + +/** + * @brief plxs delete records + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @return None + * + */ +void plxs_delete_records(uint8_t conn_id, T_SERVER_ID service_id) +{ + PROFILE_PRINT_INFO2(" plxs_delete_records opcode = %x,operator = %x", + plxs_racp.ctrl_point.op_code, plxs_racp.ctrl_point.op); + if (plxs_racp.ctrl_point.op >= 7) + { + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (plxs_racp.ctrl_point.op != PLXS_RACP_OPERATOR_ALL_RECS) + { + + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_INVALID_OPERATOR); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + delete_all_records_from_database(); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, PLXS_RACP_RESP_SUCCESS); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; +} + +/** + * @brief plxs_ctr_pnt_write_ind_post_proc + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] attrib_index attribute index + * @param[in] write_length write value length + * @param[in] p_value write value + * @return None + * + */ +static void plxs_ctr_pnt_write_ind_post_proc(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t write_length, uint8_t *p_value) +{ + if (write_length > 2) + { + PROFILE_PRINT_ERROR1("plxs_ctr_pnt_write_ind_post_proc invalid write length, error: operand = 0x%x", + p_value[2]); + plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_OPERAND_NOT_SUPPORTED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + PROFILE_PRINT_INFO4("plxs_ctr_pnt_write_ind_post_proc,opcode = 0x%x,operator = 0x%x,operand = 0x%x,write_length = 0x%x", + p_value[0], p_value[1], p_value[2], write_length); + if (p_value[0] != PLXS_RACP_OPCODE_ABORT_OPERATION) + { + memset(&plxs_racp.ctrl_point, 0, sizeof(T_PLXS_CONTROL_POINT)); + memcpy(&plxs_racp.ctrl_point, p_value, write_length); + plxs_racp.cp_length = write_length; + switch (plxs_racp.ctrl_point.op_code) + { + case PLXS_RACP_OPCODE_REPORT_NBR_OF_RECS: + { + PROFILE_PRINT_INFO1("plxs_report_num_of_records operator %d", plxs_racp.ctrl_point.op); + plxs_report_num_of_records(conn_id, service_id); + } + break; + case PLXS_RACP_OPCODE_REPORT_RECS: + { + PROFILE_PRINT_INFO1("plxs_report_records operator %d", plxs_racp.ctrl_point.op); + plxs_report_records(conn_id, service_id); + } + break; + case PLXS_RACP_OPCODE_DELETE_RECS: + { + plxs_delete_records(conn_id, service_id); + } + break; + default: + { + PROFILE_PRINT_INFO0("plxs_ctr_pnt_write_ind_post_proc PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED"); + plxs_racp_response(conn_id, service_id, plxs_racp.ctrl_point.op_code, + PLXS_RACP_RESP_OPCODE_NOT_SUPPORTED); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + } + break; + } + } + else + { + if (p_value[1] >= 7) + { + plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_OPERATOR_NOT_SUPPORTED); + /*in this case if abort fail,means that procedure did't end ,and should't set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + //plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (p_value[1] != PLXS_RACP_OPERATOR_NULL) + { + plxs_racp_response(conn_id, service_id, p_value[0], PLXS_RACP_RESP_INVALID_OPERATOR); + /*in this case if abort fail,means that procedure did't end ,and should't set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + //plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + return; + } + if (plxs_racp.ctrl_point.op_code == PLXS_RACP_OPCODE_REPORT_RECS) + { + //if procedure is doing set plxs_abort_flag is true + plxs_abort_flag = true; + } + else + { + PROFILE_PRINT_INFO0("plxs_ctr_pnt_write_ind_post_proc PLXS_RACP_OPCODE_ABORT_OPERATION SUCCESS"); + plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_ABORT_OPERATION, PLXS_RACP_RESP_SUCCESS); + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + } + } +} +#endif + +/** + * @brief clear flags if procedure fail or disconnect + * + * Example usage + * \code{.c} + void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause) + { + APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x", + conn_id, gap_conn_state, new_state, disc_cause); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))&& (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause); + } + plxs_flags_clear();//when disconnect clear plxs flags + le_adv_start(); + } + break; + } + } + * \endcode + */ +void plxs_flags_clear() +{ + PROFILE_PRINT_ERROR0("plxs_flags_clear"); +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + /*in this case when send response to client means that the procedure has end,should set plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED*/ + plxs_racp.ctrl_point.op_code = PLXS_RACP_OPCODE_RESERVED; + plxs_report_records_flags.plxs_send_data_end_flag = true; + plxs_report_records_flags.plxs_current_record_to_report = 0; + plxs_abort_flag = false; + plxs_abort_by_app_flag = false; + if (plxs_report_records_flags.plxs_records_to_report_offset >= + plxs_report_records_flags.plxs_num_records_to_report) + { + plxs_report_records_flags.plxs_records_to_report_offset = 0; + } +#endif + plxs_data_send_status_flags.continuous_measurement_notify_status_flag = + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_IDLE; + plxs_data_send_status_flags.report_records_indication_status_flag = + PLXS_STATUS_REPORT_RECORDS_INDICATION_IDLE; + plxs_data_send_status_flags.spot_check_indication_status_flag = + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_IDLE; +} +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type @ref T_WRITE_TYPE + * @param[in] length Length of value to be written. + * @param[in] p_value Value to be written. + * @param[in] p_write_ind_post_proc @ref P_FUN_WRITE_IND_POST_PROC + * @return Profile procedure result + */ +T_APP_RESULT plxs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + PROFILE_PRINT_INFO2("plxs_attr_write_cb: attrib_index %d, length 0x%x ", attrib_index, length); + switch (attrib_index) + { +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + case PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_INDEX : + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > sizeof(T_PLXS_CONTROL_POINT)) || (p_value == NULL)) + { + PROFILE_PRINT_INFO0("plxs_attr_write_cb APP_RESULT_INVALID_VALUE_SIZE"); + cause = APP_RESULT_INVALID_VALUE_SIZE; + }/* Make sure Control Point is not "Process already in progress". */ + else if (PLXS_RACP_OPERATION_ACTIVE(plxs_racp.ctrl_point.op_code) && + (p_value[0] != PLXS_RACP_OPCODE_ABORT_OPERATION)) + { + PROFILE_PRINT_INFO0("plxs_attr_write_cb PLXS_ERR_PROC_ALREADY_IN_PROGRESS"); + cause = (T_APP_RESULT)(ATT_ERR | PLXS_ERR_PROC_ALREADY_IN_PROGRESS); + } /* Make sure Control Point is configured indication enable. */ + else if (!plxs_check_cccd()) + { + PROFILE_PRINT_INFO0("plxs_attr_write_cb PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED"); + cause = (T_APP_RESULT)(ATT_ERR | PLXS_ERR_CCCD_IMPROPERLY_CONFIGURED); + }/*Process already in progress when abort, but abort operator not right*/ + else if (PLXS_RACP_OPERATION_ACTIVE(plxs_racp.ctrl_point.op_code) && + (p_value[0] == PLXS_RACP_OPCODE_ABORT_OPERATION) && + (p_value[1] != PLXS_RACP_OPERATOR_NULL)) + { + PROFILE_PRINT_INFO0("plxs_attr_write_cb abort operator invalid"); + cause = (T_APP_RESULT)(ATT_ERR | ATT_ERR_INVALID_VALUE); + } + else/** handle RACP request after sending write response */ + { + PROFILE_PRINT_INFO2("plxs_attr_write_cb opcode: old = %d, new = %d\n", plxs_racp.ctrl_point.op_code, + p_value[0]); + *p_write_ind_post_proc = plxs_ctr_pnt_write_ind_post_proc; + } + } + break; +#endif + default: + { + PROFILE_PRINT_ERROR1("plxs_attr_write_cb attribIndex %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return cause; +} +/** + * @brief plxs check report data send procedure to enable flow control of notification or indication + * @param[in] conn_id connection index + * @param[in] Service_id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] attribute_index attribute_index + * Example usage + * \code{.c} + T_APP_RESULT app_handle_profile_message(T_SERVER_ID service_id, void *p_data) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_para = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_para->eventId) + { + ...... + case PROFILE_EVT_SEND_DATA_COMPLETE: + ...... + else if (p_para->event_data.send_data_result.service_id == plxs_srv_id) + { + uint8_t conn_id = p_para->event_data.send_data_result.conn_id; + if (p_para->event_data.send_data_result.cause == GAP_SUCCESS) + { + plxs_check_report_data_send_procedure(conn_id, plxs_srv_id,p_para->event_data.send_data_result.attrib_idx); + } + else + { + APP_PRINT_ERROR1("PROFILE_EVT_SEND_DATA_COMPLETE failed,cause %x", p_para->event_data.send_data_result.cause); + } + } + break; + } + } + } + * \endcode + */ +void plxs_check_report_data_send_procedure(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attribute_index) +{ +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT + if (attribute_index == PLXS_CHAR_CONTINUOUS_MEASUREMENT_INDEX && + plxs_data_send_status_flags.continuous_measurement_notify_status_flag == + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DOING) + { + PROFILE_PRINT_INFO0("PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE"); + plxs_data_send_status_flags.continuous_measurement_notify_status_flag = + PLXS_STATUS_CONTINUOUS_MEASUREMENT_NOTIFY_DONE; + } +#endif +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT + if (attribute_index == PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX && + plxs_data_send_status_flags.spot_check_indication_status_flag == + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DOING) + { + PROFILE_PRINT_INFO0("PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE"); + plxs_data_send_status_flags.spot_check_indication_status_flag = + PLXS_STATUS_SPOT_CHECK_MEASUREMENT_INDICATION_DONE; + } +#endif +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + if (attribute_index == PLXS_CHAR_SPOT_CHECK_MENSUREMENT_INDEX && + plxs_data_send_status_flags.report_records_indication_status_flag == + PLXS_STATUS_REPORT_RECORDS_INDICATION_DOING) + { + PROFILE_PRINT_INFO0("PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE"); + plxs_data_send_status_flags.report_records_indication_status_flag = + PLXS_STATUS_REPORT_RECORDS_INDICATION_DONE; + if (plxs_check_records_report_complete(conn_id, service_id)) + { + APP_PRINT_INFO0("records report complete or condition not allow"); + } + else + { + if (false == plxs_report_records_task(conn_id, service_id)) + { + PROFILE_PRINT_ERROR0("plxs_report_records_task send fail"); + plxs_racp_response(conn_id, service_id, PLXS_RACP_OPCODE_REPORT_RECS, + PLXS_RACP_RESP_PROC_NOT_COMPLETED); + plxs_flags_clear(); + }; + } + } +#endif +} +/** + * @brief plxs_get_data_send_status + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @return plxs data send status + * @retval data send status @ref T_PLXS_DATA_SEND_STATUS_FLAGS + */ +T_PLXS_DATA_SEND_STATUS_FLAGS plxs_get_data_send_status(uint8_t conn_id, T_SERVER_ID service_id) +{ + return plxs_data_send_status_flags; +} +/** + * @brief plxs_set_data_send_status + * + * @param[in] conn_id conn_id + * @param[in] Service id generated by the BLE stack: @ref T_SERVER_ID. + * @param[in] data_send_status @ref T_PLXS_DATA_SEND_STATUS_FLAGS + * @return None + */ +void plxs_set_data_send_status(uint8_t conn_id, T_SERVER_ID service_id, + T_PLXS_DATA_SEND_STATUS_FLAGS data_send_status) +{ + plxs_data_send_status_flags = data_send_status; +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None + */ +void plxs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + PROFILE_PRINT_INFO1("plxs_cccd_update_cb index = %d ", index); + T_PLXS_CALLBACK_DATA plxs_upstream_msg; + bool is_handled = false; + plxs_upstream_msg.conn_id = conn_id; + plxs_upstream_msg.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + switch (index) + { +#if PLXS_CONTINUOUS_MEASUREMENT_SUPPORT + case PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + plxs_notify_indicate_flag.continuous_measurement_notify_enable = 1; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_ENABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD notify enable index = %d", + PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX); + } + else + { + plxs_notify_indicate_flag.continuous_measurement_notify_enable = 0; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_CONTINUOUS_MEASUREMENT_NOTIFY_DISABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD notify disable index = %d", + PLXS_CHAR_CONTINUOUS_MEASUREMENT_CCCD_INDEX); + } + is_handled = true; + } + break; +#endif + +#if PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT + case PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + plxs_notify_indicate_flag.spot_check_measurement_indication_enable = 1; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_ENABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD indication enable index = %d", + PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX); + } + else + { + plxs_notify_indicate_flag.spot_check_measurement_indication_enable = 0; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_SPOT_CHECK_MEASUREMENT_INDICATION_DISABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD indication disable index = %d", + PLXS_CHAR_SPOT_CHECK_MENSUREMENT_CCCD_INDEX); + } + is_handled = true; + } + break; +#endif + +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + case PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + plxs_notify_indicate_flag.racp_indication_enable = 1; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_RACP_INDICATION_ENABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD indication enable index = %d", + PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX); + } + else + { + plxs_notify_indicate_flag.racp_indication_enable = 0; + plxs_upstream_msg.msg_data.notify_indicate_index = PLXS_RACP_INDICATION_DISABLE; + PROFILE_PRINT_INFO1("PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD indication disable index = %d", + PLXS_CHAR_RECORS_ACCESS_CONTROL_POINT_CCCD_INDEX); + } + is_handled = true; + } + break; +#endif + default: + { + PROFILE_PRINT_ERROR1("plxs_cccd_update_cb index = %d not found", index); + } + break; + } + /* Notify Application. */ + if (pfn_plxs_cb && (is_handled == true)) + { + pfn_plxs_cb(service_id, (void *)&plxs_upstream_msg); + } +} +/** + * @brief plx Profile Service Callbacks. + */ +const T_FUN_GATT_SERVICE_CBS plxs_cbs = +{ + plxs_attr_read_cb, + plxs_attr_write_cb, + plxs_cccd_update_cb +}; + +/** + * @brief Add PLX service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void app_le_profile_init() + { + server_init(1); + plxs_srv_id = plxs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID plxs_add_service(void *p_func) +{ + plxs_flags_init(); + T_SERVER_ID service_id = 0xff; +#if (PLXS_SPOT_CHECK_MEASUREMENT_SUPPORT || PLXS_CONTINUOUS_MEASUREMENT_SUPPORT) + { + if (false == server_add_service(&service_id, + (uint8_t *)plxs_att_tbl, + sizeof(plxs_att_tbl), + plxs_cbs)) + { + PROFILE_PRINT_ERROR1("plxs_add_service:service_id %d", service_id); + service_id = 0xff; + return service_id; + } +#if PLXS_STORE_SPOT_CHECK_MEASUREMENT_SUPPORT + plxs_racp.record_db.record_num = 0; + plxs_racp.record_db.head = 0; + plxs_racp.record_db.tail = 0; + plxs_racp.cp_length = 0; +#endif + pfn_plxs_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; + } +#else + { + PROFILE_PRINT_ERROR0("SPOT_CHECK_MEASUREMENT and CONTINUOUS_MEASUREMENT Mandatory to support at least one "); + service_id = 0xff; + return service_id; + } +#endif +} diff --git a/src/ble/profile/server/rscs.c b/src/ble/profile/server/rscs.c new file mode 100644 index 0000000..547aff7 --- /dev/null +++ b/src/ble/profile/server/rscs.c @@ -0,0 +1,1012 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rscs.c +* @brief RSC service source file. +* @details Interfaces to get and put rsc characteristics value and rsc control point procedure. +* @author ethan_su +* @date 2017-10-10 +* @version v1.0 +********************************************************************************************************* +*/ +#include "trace.h" +#include +#include "gatt.h" +#include "rscs.h" + +#define GATT_UUID_RSC 0x1814 +#define GATT_UUID_CHAR_RSCS_MEASUREMENT 0x2A53 +#define GATT_UUID_CHAR_RSCS_FEATURE 0x2A54 +#define GATT_UUID_CHAR_SC_CONTROL_POINT 0x2A55 +#define GATT_UUID_CHAR_SENSOR_LOCATION 0x2A5D + + +#define RSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT +#define RSCS_SC_CONTROL_POINT_SUPPORT +/** @brief Index of each characteristic in RSC service database. */ +#define GATT_SVC_RSCS_MEASUREMENT_INDEX 2 +#define GATT_SVC_RSCS_FEATURE_INDEX 5 +#define GATT_SVC_RSCS_SENS_LOC_INDEX 7 +#define GATT_SVC_RSCS_CTL_PNT_INDEX 9 +#define GATT_SVC_RSCS_MEAS_CCCD_INDEX (GATT_SVC_RSCS_MEASUREMENT_INDEX + 1) +#define GATT_SVC_RSCS_CTL_PNT_CCCD_INDEX (GATT_SVC_RSCS_CTL_PNT_INDEX + 1) + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ + +typedef struct +{ + uint8_t rsc_measurement_notify_enable: 1; + uint8_t sc_cp_indicate_enable: 1; + uint8_t rfu: 6; +} RSCS_NOTIFY_INDICATE_FLAG; + +/** @brief Judge RSC Control Point operation is available or not. */ +#define RSCS_CTL_PNT_OPERATE_ACTIVE(x) \ + (((x >= RSCS_CP_OPCODE_SET_CUMULATIVE) && \ + (x <= RSCS_CP_OPCODE_REQ_SENS_LOC_LIST)) || \ + x == RSCS_CP_OPCODE_RSP_CODE ) + +/**< RSC measurement data. */ +static T_RSCS_MEASUREMENT rscs_measurement; +/**< RSC feature that RSC service supported, can be configured by user. */ +static uint16_t rscs_feature; +/**< RSC current sensor location, where the RSC sensor located. */ +static uint8_t rscs_cur_sens_location; +/**< RSC supported sensor location list, can be configured by user. */ +static uint16_t rscs_sens_loc_list; +/**< RSC control point data. */ +static T_RSCS_CONTROL_POINT rscs_control_point = {0}; +/**< RSC control point indication enable flag. */ +static RSCS_NOTIFY_INDICATE_FLAG rscs_notify_indicate_flag = {0}; +/**< Function pointer used to send event to application from RSC profile. Initiated in rscs_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_rscs_cb = NULL; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL rscs_attr_tbl[] = +{ + /*-------------------------- RSC Service ---------------------------*/ + /* <>, .. Index 0 */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_RSC), /* service UUID */ + HI_WORD(GATT_UUID_RSC) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. Index 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- RSC Measurement characteristic value --- Index 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_RSCS_MEASUREMENT), + HI_WORD(GATT_UUID_CHAR_RSCS_MEASUREMENT) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration Index 3 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /* <>, .. Index 4 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- RSC Features characteristic value --- Index 5 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_RSCS_FEATURE), + HI_WORD(GATT_UUID_CHAR_RSCS_FEATURE), + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } + +#ifdef RSCS_MULTIPLE_SENSOR_LOCATIONS_SUPPORT + , + /* <>, .. Index 6 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + //XXXXMJMJ GATT_CHAR_PROP_INDICATE, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- RSC sensor location characteristic value --- Index 7 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SENSOR_LOCATION), + HI_WORD(GATT_UUID_CHAR_SENSOR_LOCATION) + }, + 0, /* variable size */ + (void *)NULL, + GATT_PERM_READ /* wPermissions */ + } +#endif + +#ifdef RSCS_SC_CONTROL_POINT_SUPPORT + , + /* <>, .. Index 8 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | /* characteristic properties */ + GATT_CHAR_PROP_INDICATE) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /*--- RSC SC Control Point value --- Index 9 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT), + HI_WORD(GATT_UUID_CHAR_SC_CONTROL_POINT) + }, + 0, /* bValueLen, 0 : variable length */ + NULL, + GATT_PERM_WRITE /* wPermissions */ + }, + /* client characteristic configuration Index 10 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif +}; +/**< @brief RSC service size definition. */ +const int32_t rscs_attr_tbl_size = sizeof(rscs_attr_tbl); + +/** + * @brief Set a Running Speed and Cadence Service parameter. + * + * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will set the + * Running Speed and Cadence Service parameter. Running Speed and Cadence Service parameters are defined + * in @ref T_RSCS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint32_t total_distance = p_parse_value->dw_param[0]; + bool op_result; + + op_result = rscs_set_parameter(RSCS_PARAM_TOTALDISTANCE, 4, (uint8_t*)&total_distance); + + if ( op_result ) + { + rscs_get_parameter( RSCS_PARAM_TOTALDISTANCE, &total_distance ); + data_uart_print("set total_distance = %d\r\n", total_distance); + } + else + { + data_uart_print("rscs_set_parameter total_distance failed\r\n"); + } + } + * \endcode + */ +bool rscs_set_parameter(T_RSCS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + uint8_t inc_flag = rscs_measurement.value[0]; + + switch (param_type) + { + default: + ret = false; + break; + case RSCS_PARAM_CSCS_FEATURE: + memcpy(&rscs_feature, p_value, 2); + break; + case RSCS_PARAM_INC_FLAG: + rscs_measurement.value[0] = *(uint8_t *)p_value; + inc_flag = rscs_measurement.value[0]; + rscs_measurement.cur_length = 4; + if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK) + { + rscs_measurement.cur_length += 2; + } + if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK) + { + rscs_measurement.cur_length += 4; + } + break; + case RSCS_PARAM_SPEED: + LE_UINT16_TO_ARRAY(rscs_measurement.value + 1, *(uint16_t *)p_value); + break; + case RSCS_PARAM_CADENCE: + rscs_measurement.value[3] = *(uint8_t *)p_value; + break; + case RSCS_PARAM_STRIDE_LENGTH: + if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK) + { + LE_UINT16_TO_ARRAY(rscs_measurement.value + 4, *(uint16_t *)p_value) ; + } + else + { + ret = false; + } + break; + case RSCS_PARAM_TOTALDISTANCE: + if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK) + { + if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK) + { + LE_UINT32_TO_ARRAY(rscs_measurement.value + 6, *(uint32_t *)p_value); + } + else + { + LE_UINT32_TO_ARRAY(rscs_measurement.value + 4, *(uint32_t *)p_value); + } + } + else + { + ret = false; + } + break; + case RSCS_PARAM_SENSOR_LOC: + rscs_cur_sens_location = *(uint8_t *)p_value; + break; + case RSCS_PARAM_CTL_PNT_PROG_CLR: + rscs_control_point.value[0] = RSCS_CP_OPCODE_RESERVED; + break; + } + + if (!ret) + { + PROFILE_PRINT_INFO0("rscs parameter set failed\n"); + } + + return ret; +} + +/** + * @brief Get a Running Speed and Cadence Service parameter. + * + * NOTE: You can call this function with a Running Speed and Cadence Service parameter type and it will get the + * parameter. Running Speed and Cadence Service parameters are defined in @ref T_RSCS_PARAM_TYPE. + * + * @param[in] param_type Running Speed and Cadence Service parameter type: @ref T_RSCS_PARAM_TYPE + * @param[in] p_value Pointer to data to read. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t bFlag; + + rscs_get_parameter(RSCS_PARAM_INC_FLAG, &bFlag); + } + * \endcode + */ +bool rscs_get_parameter(T_RSCS_PARAM_TYPE param_type, void *p_value) +{ + bool ret = true; + uint8_t inc_flag = rscs_measurement.value[0]; + + switch (param_type) + { + default: + ret = false; + break; + case RSCS_PARAM_INC_FLAG: + *(uint8_t *)p_value = rscs_measurement.value[0]; + break; + case RSCS_PARAM_SPEED: + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, rscs_measurement.value + 1); + break; + case RSCS_PARAM_CADENCE: + *(uint8_t *)p_value = rscs_measurement.value[3]; + break; + case RSCS_PARAM_STRIDE_LENGTH: + if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK) + { + LE_ARRAY_TO_UINT16(*(uint16_t *)p_value, rscs_measurement.value + 4); + } + else + { + ret = false; + } + break; + case RSCS_PARAM_TOTALDISTANCE: + if (inc_flag & RSCS_INC_TOTAL_DISTANCE_MASK) + { + if (inc_flag & RSCS_INC_STRIDE_LENGTH_MASK) + { + LE_ARRAY_TO_UINT32(*(uint32_t *)p_value, rscs_measurement.value + 6); + } + else + { + LE_ARRAY_TO_UINT32(*(uint32_t *)p_value, rscs_measurement.value + 4); + } + } + else + { + ret = false; + } + break; + case RSCS_PARAM_SENSOR_LOC: + *(uint8_t *)p_value = rscs_cur_sens_location; + break; + } + + if (!ret) + { + PROFILE_PRINT_INFO0("rscs parameter get failed\n"); + } + + return ret; +} + +/** + * @brief display control point response. + * + * @param RSCS_ctl_pnt_ptr pointer to RSC control point data. + * @return none + * @retval void +*/ +static void rscs_ctl_pnt_display_rsp(T_RSCS_CONTROL_POINT *rscs_ctl_pnt_ptr) +{ + PROFILE_PRINT_INFO1("RSCCP response: ReqOpCode=0x%x", rscs_ctl_pnt_ptr->value[1]); + PROFILE_PRINT_INFO1("rsp_code=0x%x", rscs_ctl_pnt_ptr->value[2]); +} + +/** + * @brief whether the sensor location supported. + * + * @param sens_location sensor location to be judged(RSC sensor support or not). + * @return support result. + * @retval 1 support + * @retval 0 not support +*/ +static bool rscs_sens_loc_supported(uint8_t sens_location) +{ + uint8_t result = false; + if ((rscs_sens_loc_list >> sens_location) & 0x0001) + { + result = true; + } + return (result); +} + +/** + * @brief send response to client, control point indication procedure. + * + * @param service_id service ID of service. + * @param op_code control point request opcode type. + * @param rsp_code control point response code to indicate to client. + * @return indication action result + * @retval 1 TRUE + * @retval 0 FALSE +*/ +bool rscs_ctl_pnt_indicate(uint8_t conn_id, T_SERVER_ID service_id, uint8_t op_code, + uint8_t rsp_code) +{ + uint16_t attrib_index = GATT_SVC_RSCS_CTL_PNT_INDEX; + uint8_t sens_location; + uint8_t param_offset; + uint8_t *p_data; + uint16_t dataLen; + + rscs_control_point.value[1] = rscs_control_point.value[0]; /* Control Point request opcode. */ + rscs_control_point.value[2] = rsp_code; + rscs_control_point.value[0] = RSCS_CP_OPCODE_RSP_CODE; + rscs_control_point.cur_length = 3 * sizeof(uint8_t); + + /* Diff RspType, different indication contents. */ + if (op_code == RSCS_CP_OPCODE_REQ_SENS_LOC_LIST) + { + /* get sensor location list */ + for (sens_location = RSCS_SENSOR_LOC_OTHER, param_offset = 3; sens_location < RSCS_SENSOR_LOC_MAX; + sens_location++) + { + if (rscs_sens_loc_supported(sens_location)) + { + rscs_control_point.value[param_offset] = sens_location; + param_offset++; + } + } + rscs_control_point.cur_length = param_offset; + } + + rscs_ctl_pnt_display_rsp(&rscs_control_point); + p_data = rscs_control_point.value; + dataLen = rscs_control_point.cur_length; + + // send indication to client + return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen, + GATT_PDU_TYPE_INDICATION); +} + + +/** + * @brief set cumulative response. + * + * @param service_id + * @return none + * @retval void +*/ +static void rscs_ctl_pnt_set_cumulative(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + uint8_t op_code = RSCS_CP_OPCODE_SET_CUMULATIVE; + rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + + +static void rscs_ctl_pnt_start_calib(uint8_t conn_id, T_SERVER_ID service_id, bool result) +{ + uint8_t op_code = RSCS_CP_OPCODE_SET_CUMULATIVE; + uint8_t rsp_code; + if (result == true) + { + rsp_code = RSCS_CP_RSPCODE_SUCCESS; + } + else + { + rsp_code = RSCS_CP_RSPCODE_OPERATION_FAILED; + } + rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + +/** + * @brief Send Running Speed and Cadence Service value indication data, + * send indication of result of calibration to client. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @param[in] result calibration result. + * + * @return none; + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t conn_id = p_parse_value->dw_param[0]; + uint8_t result = p_parse_value->dw_param[1]; + rscs_calib_resutl_indicate(conn_id, rscs_id, result); + data_uart_print("cmd_rscs_calib_result_indicate result= %d\r\n", result); + } + * \endcode + */ +void rscs_calib_resutl_indicate(uint8_t conn_id, T_SERVER_ID service_id, bool result) +{ + rscs_ctl_pnt_start_calib(conn_id, service_id, result); +} + +/** + * @brief update sensor location response. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] rsp_code Response Code. + * @return none + * @retval void +*/ +static void rscs_ctl_pnt_update_sens_loc(uint8_t conn_id, T_SERVER_ID service_id, uint8_t rsp_code) +{ + + uint8_t op_code = RSCS_CP_OPCODE_UPDATE_SENS_LOC; + rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + +/** + * @brief supported sensor location response. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] rsp_code Response Code. + * @return none + * @retval void +*/ +static void rscs_ctl_pnt_req_sens_loc_list(uint8_t conn_id, T_SERVER_ID service_id, + uint8_t rsp_code) +{ + uint8_t op_code = RSCS_CP_OPCODE_REQ_SENS_LOC_LIST; + rscs_ctl_pnt_indicate(conn_id, service_id, op_code, rsp_code); +} + + +static uint8_t rscs_hanlde_ctl_pnt_proc_2(uint8_t service_id, uint16_t write_length, + uint8_t *value_ptr) +{ + T_RSCS_CALLBACK_DATA callback_data; + uint8_t resp_code = RSCS_CP_RSPCODE_SUCCESS; + uint16_t parameter_length = 0; + memcpy(rscs_control_point.value, value_ptr, write_length); + if (write_length >= 1) + { + parameter_length = write_length - 1; + } + + PROFILE_PRINT_INFO1("rscs_hanlde_ctl_pnt_proc_2 request: OpCode=0x%x", rscs_control_point.value[0]); + + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write.opcode = rscs_control_point.value[0]; + + switch (rscs_control_point.value[0]) + { + + case RSCS_CP_OPCODE_SET_CUMULATIVE: + { + if (parameter_length == 4) + { + memcpy(&callback_data.msg_data.write.cp_parameter.cumulative_value, + &rscs_control_point.value[1], 4); + } + else + { + resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + + break; + + case RSCS_CP_OPCODE_START_CALIBRATION: + { + if (parameter_length == 0) + { + } + else + { + resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + case RSCS_CP_OPCODE_UPDATE_SENS_LOC: + { + if (parameter_length == 1) + { + memcpy(&callback_data.msg_data.write.cp_parameter.sensor_location_value, + &rscs_control_point.value[1], 1); + if (callback_data.msg_data.write.cp_parameter.sensor_location_value >= RSCS_SENSOR_LOC_MAX) + { + resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + else + { + resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + case RSCS_CP_OPCODE_REQ_SENS_LOC_LIST: + { + if (parameter_length == 0) + { + } + else + { + resp_code = RSCS_CP_RSPCODE_INVALID_PARAMETER; + } + } + break; + + default: + { + resp_code = RSCS_CP_RSPCODE_OPCODE_UNSUPPORT; + } + break; + } + + if (resp_code == RSCS_CP_RSPCODE_SUCCESS) + { + pfn_rscs_cb(service_id, (void *)&callback_data); + } + return resp_code; +} + + + +/** + * @brief handle control point write (request). + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] write_length write request data length. + * @param[in] value_ptr pointer to write request data. + * @return none + * @retval void +*/ +static void rscs_ctl_pnt_handle_req(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t write_length, uint8_t *value_ptr) +{ + uint8_t resp_code = RSCS_CP_RSPCODE_SUCCESS; + memcpy(rscs_control_point.value, value_ptr, write_length); + rscs_control_point.cur_length = write_length; + + PROFILE_PRINT_INFO1("rscscp request: op_code=0x%x", rscs_control_point.value[0]); + + resp_code = rscs_hanlde_ctl_pnt_proc_2(service_id, write_length, value_ptr); + + if (resp_code == RSCS_CP_RSPCODE_SUCCESS) + { + + switch (rscs_control_point.value[0]) + { + default: + break; + case RSCS_CP_OPCODE_SET_CUMULATIVE: + if ((rscs_feature & RSCS_SUPPORT_TOTAL_DISTANCE_MASK) && + (rscs_measurement.value[0] & RSCS_INC_TOTAL_DISTANCE_MASK)) + { + rscs_ctl_pnt_set_cumulative(conn_id, service_id, resp_code); + return; + } + break; + case RSCS_CP_OPCODE_START_CALIBRATION: + if (rscs_feature & RSCS_SUPPORT_CALIBRATE_MASK) + { + + return; + } + break; + case RSCS_CP_OPCODE_UPDATE_SENS_LOC: + if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK) + { + rscs_ctl_pnt_update_sens_loc(conn_id, service_id, resp_code); + return; + } + break; + case RSCS_CP_OPCODE_REQ_SENS_LOC_LIST: + if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK) + { + rscs_ctl_pnt_req_sens_loc_list(conn_id, service_id, resp_code); + return; + } + break; + } + } + + /* Send indication to client when request opcode not supported. */ + rscs_ctl_pnt_indicate(conn_id, service_id, rscs_control_point.value[0], resp_code); +} + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length length of getting characteristic data. + * @param[in,out] pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT rscs_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("rscs_attr_read_cb, Attr not found, index = %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + case GATT_SVC_RSCS_FEATURE_INDEX: + { + T_RSCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = RSCS_READ_RSCS_FEATURE; + pfn_rscs_cb(service_id, &callback_data); + + *pp_value = (uint8_t *)&rscs_feature; + *p_length = sizeof(rscs_feature); + + } + break; + case GATT_SVC_RSCS_SENS_LOC_INDEX: + if (rscs_feature & RSCS_SUPPORT_MULTI_SENSOR_MASK) + { + T_RSCS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = RSCS_READ_SENSOR_LOCATION; + pfn_rscs_cb(service_id, &callback_data); + *pp_value = (uint8_t *)&rscs_cur_sens_location; + *p_length = sizeof(rscs_cur_sens_location); + } + else + { + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + + return cause; +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] length length of value to be written. + * @param[in] p_value value to be written. + * @param[in] p_write_ind_post_proc pointer of a function to handle control point write. + * @return Profile procedure result +*/ +T_APP_RESULT rscs_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + if (GATT_SVC_RSCS_CTL_PNT_INDEX == attrib_index) + { + /* Attribute value has variable size, make sure written value size is valid. */ + if ((length > RSCS_MAX_CTL_PNT_VALUE) || (p_value == NULL)) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + /* Make sure Control Point is not "Process already in progress". */ + else if (RSCS_CTL_PNT_OPERATE_ACTIVE(rscs_control_point.value[0])) + { + cause = (T_APP_RESULT)0x80;//ProfileResult_AppErr_ProcAlreadyInProgress + } + /* Make sure Control Point is configured indication enable. */ + else if (!rscs_notify_indicate_flag.sc_cp_indicate_enable) + { + cause = (T_APP_RESULT)0x81;//ProfileResult_AppErr_CccdImproperlyConfigured + } + else + { + /* handle SCCP request after sending write response */ + *p_write_ind_post_proc = rscs_ctl_pnt_handle_req; + } + } + else + { + PROFILE_PRINT_ERROR2("rscs_attr_write_cb Error attrib_index = 0x%x length=%d", attrib_index, + length); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + return cause; +} + +/** + * @brief Send Running Speed and Cadence Service value notification data. + * Application shall call @ref rscs_set_parameter to set value first, + * and then call this api to send the notication value. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * + * @return service id @ref T_SERVER_ID. + * + * Example usage + * \code{.c} + void test(void) + { + bool op_result; + uint8_t flag = RSCS_INC_ALL_PRESENTS; + + rscs_set_parameter(RSCS_PARAM_INC_FLAG, 1, &flag); + + op_result = rscs_meas_value_notify(p_parse_value->dw_param[0], rscs_id); + + if ( op_result ) + { + data_uart_print("Notify RSC measurement value succeed\r\n"); + } + else + { + data_uart_print("Notify RSC measurement value failed\r\n"); + } + + } + * \endcode + */ +bool rscs_meas_value_notify(uint8_t conn_id, T_SERVER_ID service_id) +{ + uint16_t attrib_index = GATT_SVC_RSCS_MEASUREMENT_INDEX; + uint8_t *p_data = rscs_measurement.value; + uint16_t dataLen = rscs_measurement.cur_length; + + PROFILE_PRINT_INFO0("rscs measurement notification"); + return server_send_data(conn_id, service_id, attrib_index, p_data, dataLen, + GATT_PDU_TYPE_NOTIFICATION); +} + + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void rscs_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_RSCS_CALLBACK_DATA callback_data; + bool handle = false; + PROFILE_PRINT_INFO2("rscs_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SVC_RSCS_MEAS_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE; + rscs_notify_indicate_flag.rsc_measurement_notify_enable = true; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_MEASUREMENT_ENABLE; + rscs_notify_indicate_flag.rsc_measurement_notify_enable = false; + } + handle = true; + break; + + case GATT_SVC_RSCS_CTL_PNT_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_SC_CP_ENABLE; + rscs_notify_indicate_flag.sc_cp_indicate_enable = true; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = RSCS_NOTIFY_INDICATE_SC_CP_DISABLE; + rscs_notify_indicate_flag.sc_cp_indicate_enable = false; + } + handle = true; + break; + default: + break; + } + /* Notify Application. */ + if (pfn_rscs_cb && (handle == true)) + { + pfn_rscs_cb(service_id, (void *)&callback_data); + } +} + +/** + * @brief RSC Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS rscs_cbs = +{ + rscs_attr_read_cb, // Read callback function pointer + rscs_attr_write_cb, // Write callback function pointer + rscs_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add Running Speed and Cadence Service. + * + * @param[in] p_func Callback when service attribute was read/write. + * + * @return service id @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + rscs_id = rscs_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID rscs_add_service(void *p_func) +{ + T_SERVER_ID service_id; + + /* Initiate RSC service related data, modify according to user's demand. */ + rscs_feature = RSCS_ALL_FEATURE_SUPPORTED; + rscs_measurement.value[0] = RSCS_INC_ALL_PRESENTS; + rscs_measurement.cur_length = RSCS_MAX_MEASUREMENT_VALUE; + rscs_sens_loc_list = RSCS_ALL_SENS_LOC_SUPPORTED; + rscs_cur_sens_location = RSCS_SENSOR_LOC_TOP_OF_SHOE; + + /* register RSC service to profile layer. */ + if (false == server_add_service(&service_id, + (uint8_t *)rscs_attr_tbl, + rscs_attr_tbl_size, + rscs_cbs)) + { + PROFILE_PRINT_ERROR1("rscs_add_service: service_id %d", service_id); + service_id = 0xff; + return service_id; + } + + /* register callback for profile to inform application that some events happened. */ + pfn_rscs_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + + diff --git a/src/ble/profile/server/simple_ble_service.c b/src/ble/profile/server/simple_ble_service.c new file mode 100644 index 0000000..4776994 --- /dev/null +++ b/src/ble/profile/server/simple_ble_service.c @@ -0,0 +1,478 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file simple_ble_service.c +* @brief simple BLE profile source file. +* @details Demonstration of how to implement a self-definition profile. +* @author +* @date +* @version +********************************************************************************************************* +*/ + +#include +#include +#include +#include + + +#define SIMPLE_BLE_SERVICE_CHAR_V1_READ_INDEX 0x02 +#define SIMPLE_BLE_SERVICE_CHAR_V2_WRITE_INDEX 0x05 +#define SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX 0x07 +#define SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX 0x0a +#define SIMPLE_BLE_SERVICE_CHAR_NOTIFY_CCCD_INDEX (SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX + 1) +#define SIMPLE_BLE_SERVICE_CHAR_INDICATE_CCCD_INDEX (SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX + 1) + + + +T_SERVER_ID simp_service_id; +/**< Value of simple read characteristic. */ +static uint8_t simple_char_read_value[SIMP_READ_V1_MAX_LEN]; +static uint16_t simple_char_read_len = 1; +char v1_user_descr[] = "V1 read characteristic"; + +/**< Function pointer used to send event to application from simple profile. Initiated in simp_ble_service_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_simp_ble_service_cb = NULL; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL simple_ble_service_tbl[] = +{ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_SIMPLE_PROFILE), /* service UUID */ + HI_WORD(GATT_UUID_SIMPLE_PROFILE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* p_value_context */ + GATT_PERM_READ /* permissions */ + }, + /* <> demo for read */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SIMPLE_V1_READ), + HI_WORD(GATT_UUID_CHAR_SIMPLE_V1_READ) + }, + 0, /* bValueLen */ + NULL, +#if SIMP_SRV_AUTHEN_EN + GATT_PERM_READ_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_READ /* permissions */ +#endif + }, + { + ATTRIB_FLAG_VOID | ATTRIB_FLAG_ASCII_Z, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_USER_DESCR), + HI_WORD(GATT_UUID_CHAR_USER_DESCR), + }, + (sizeof(v1_user_descr) - 1), /* bValueLen */ + (void *)v1_user_descr, + GATT_PERM_READ /* permissions */ + }, + /* <> demo for write */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SIMPLE_V2_WRITE), + HI_WORD(GATT_UUID_CHAR_SIMPLE_V2_WRITE) + }, + 0, /* bValueLen */ + NULL, +#if SIMP_SRV_AUTHEN_EN + GATT_PERM_WRITE_AUTHEN_REQ /* permissions */ +#else + GATT_PERM_WRITE /* permissions */ +#endif + }, + /* <>, demo for notify */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_NOTIFY) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SIMPLE_V3_NOTIFY), + HI_WORD(GATT_UUID_CHAR_SIMPLE_V3_NOTIFY) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* permissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if SIMP_SRV_AUTHEN_EN + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + }, + /* <> demo for indicate */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_INDICATE) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_SIMPLE_V4_INDICATE), + HI_WORD(GATT_UUID_CHAR_SIMPLE_V4_INDICATE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* permissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, +#if SIMP_SRV_AUTHEN_EN + (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ) /* permissions */ +#else + (GATT_PERM_READ | GATT_PERM_WRITE) /* permissions */ +#endif + }, +}; + +/** + * @brief Set service related data from application. + * + * @param[in] param_type parameter type to set. + * @param[in] len value length to be set. + * @param[in] p_value value to set. + * @return parameter set result. + * @retval 0 false + * @retval 1 true + */ +bool simp_ble_service_set_parameter(T_SIMP_PARAM_TYPE param_type, uint16_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + ret = false; + break; + case SIMPLE_BLE_SERVICE_PARAM_V1_READ_CHAR_VAL: + if (len <= SIMP_READ_V1_MAX_LEN) + { + memcpy(simple_char_read_value, p_value, len); + simple_char_read_len = len; + } + else + { + ret = false; + } + break; + } + + if (!ret) + { + APP_PRINT_ERROR0("simp_ble_service_set_parameter failed"); + } + + return ret; +} + +/** + * @brief read characteristic data from service. + * + * @param service_id ServiceID of characteristic data. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Used for Blob Read. + * @param p_length length of getting characteristic data. + * @param pp_value data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT simp_ble_service_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + switch (attrib_index) + { + default: + APP_PRINT_ERROR1("simp_ble_service_attr_read_cb, Attr not found, index %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + case SIMPLE_BLE_SERVICE_CHAR_V1_READ_INDEX: + { + TSIMP_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = SIMP_READ_V1; + callback_data.conn_id = conn_id; + if (pfn_simp_ble_service_cb) + { + pfn_simp_ble_service_cb(service_id, (void *)&callback_data); + } + *pp_value = simple_char_read_value; + *p_length = simple_char_read_len; + } + break; + + } + + return (cause); +} + + +void simple_write_post_callback(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t length, uint8_t *p_value) +{ + APP_PRINT_INFO4("simple_write_post_callback: conn_id %d, service_id %d, attrib_index 0x%x, length %d", + conn_id, service_id, attrib_index, length); +} +/** + * @brief write characteristic data from service. + * + * @param conn_id + * @param service_id ServiceID to be written. + * @param attrib_index Attribute index of characteristic. + * @param length length of value to be written. + * @param p_value value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT simp_ble_service_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value, + P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + TSIMP_CALLBACK_DATA callback_data; + T_APP_RESULT cause = APP_RESULT_SUCCESS; + APP_PRINT_INFO1("simp_ble_service_attr_write_cb write_type = 0x%x", write_type); + *p_write_ind_post_proc = simple_write_post_callback; + if (SIMPLE_BLE_SERVICE_CHAR_V2_WRITE_INDEX == attrib_index) + { + /* Make sure written value size is valid. */ + if (p_value == NULL) + { + cause = APP_RESULT_INVALID_VALUE_SIZE; + } + else + { + /* Notify Application. */ + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.conn_id = conn_id; + callback_data.msg_data.write.opcode = SIMP_WRITE_V2; + callback_data.msg_data.write.write_type = write_type; + callback_data.msg_data.write.len = length; + callback_data.msg_data.write.p_value = p_value; + + if (pfn_simp_ble_service_cb) + { + pfn_simp_ble_service_cb(service_id, (void *)&callback_data); + } + } + } + else + { + APP_PRINT_ERROR2("simp_ble_service_attr_write_cb Error: attrib_index 0x%x, length %d", + attrib_index, + length); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + return cause; +} + +/** + * @brief send notification of simple notify characteristic value. + * + * @param[in] conn_id connection id + * @param[in] service_id service ID of service. + * @param[in] p_value characteristic value to notify + * @param[in] length characteristic value length to notify + * @return notification action result + * @retval 1 true + * @retval 0 false + */ +bool simp_ble_service_send_v3_notify(uint8_t conn_id, T_SERVER_ID service_id, void *p_value, + uint16_t length) +{ + APP_PRINT_INFO0("simp_ble_service_send_v3_notify"); + // send notification to client + return server_send_data(conn_id, service_id, SIMPLE_BLE_SERVICE_CHAR_V3_NOTIFY_INDEX, p_value, + length, + GATT_PDU_TYPE_ANY); +} + +/** + * @brief send indication of simple indicate characteristic value. + * + * @param[in] conn_id connection id + * @param[in] service_id service ID of service. + * @param[in] p_value characteristic value to notify + * @param[in] length characteristic value length to notify + * @return notification action result + * @retval 1 true + * @retval 0 false + */ +bool simp_ble_service_send_v4_indicate(uint8_t conn_id, T_SERVER_ID service_id, void *p_value, + uint16_t length) +{ + APP_PRINT_INFO0("simp_ble_service_send_v4_indicate"); + // send indication to client + return server_send_data(conn_id, service_id, SIMPLE_BLE_SERVICE_CHAR_V4_INDICATE_INDEX, p_value, + length, GATT_PDU_TYPE_ANY); +} + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id connection id. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param cccbits CCCD bits from stack. + * @return None +*/ +void simp_ble_service_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, + uint16_t cccbits) +{ + TSIMP_CALLBACK_DATA callback_data; + bool is_handled = false; + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + APP_PRINT_INFO2("simp_ble_service_cccd_update_cb: index = %d, cccbits 0x%x", index, cccbits); + switch (index) + { + case SIMPLE_BLE_SERVICE_CHAR_NOTIFY_CCCD_INDEX: + { + if (cccbits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + // Enable Notification + callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V3_ENABLE; + } + else + { + // Disable Notification + callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V3_DISABLE; + } + is_handled = true; + } + break; + case SIMPLE_BLE_SERVICE_CHAR_INDICATE_CCCD_INDEX: + { + if (cccbits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + // Enable Indication + callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V4_ENABLE; + } + else + { + // Disable Indication + callback_data.msg_data.notification_indification_index = SIMP_NOTIFY_INDICATE_V4_DISABLE; + } + is_handled = true; + } + break; + + default: + break; + } + /* Notify Application. */ + if (pfn_simp_ble_service_cb && (is_handled == true)) + { + pfn_simp_ble_service_cb(service_id, (void *)&callback_data); + } +} + +/** + * @brief Simple ble Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS simp_ble_service_cbs = +{ + simp_ble_service_attr_read_cb, // Read callback function pointer + simp_ble_service_attr_write_cb, // Write callback function pointer + simp_ble_service_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add simple BLE service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + */ +T_SERVER_ID simp_ble_service_add_service(void *p_func) +{ + if (false == server_add_service(&simp_service_id, + (uint8_t *)simple_ble_service_tbl, + sizeof(simple_ble_service_tbl), + simp_ble_service_cbs)) + { + APP_PRINT_ERROR0("simp_ble_service_add_service: fail"); + simp_service_id = 0xff; + return simp_service_id; + } + + pfn_simp_ble_service_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return simp_service_id; +} + diff --git a/src/ble/profile/server/sps.c b/src/ble/profile/server/sps.c new file mode 100644 index 0000000..747bf76 --- /dev/null +++ b/src/ble/profile/server/sps.c @@ -0,0 +1,337 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file sps.c +* @brief SPS service source file. +* @details Interfaces to access SPS service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ +#include "stdint.h" +#include "string.h" +#include "trace.h" +#include "profile_server.h" +#include "sps.h" +#include "sps_config.h" + + +///@cond +/** @brief ScanParameters service related UUIDs. */ +#define GATT_UUID_SPS 0x1813 +#define GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW 0x2A4F +#define GATT_UUID_CHAR_SCAN_REFRESH 0x2A31 + +/** @brief defines for Characteristic Index in Scan parameters Service */ +#define GATT_SVC_SPS_SCAN_INTERVAL_INDEX 2 /**< @brief Index for Scan Interval chars's value */ +#define GATT_SVC_SPS_SCAN_REFRESH_INDEX 4 /**< @brief Index for Scan refresh chars's value */ +#define GATT_SVC_SPS_SCAN_REFRESH_CCCD_INDEX 5/**< @brief CCCD Index for Scan Interval chars's value */ +///@endcond + + +/**< SPS Refresh Value. */ +static uint8_t sps_refresh_value __attribute__((unused)) = 0; +/**< Function pointer used to send event to application from sps profile. */ +static P_FUN_SERVER_GENERAL_CB pfn_sps_cb = NULL; + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL sps_attr_tbl[] = +{ + /*--------------------------ScanParameters Service------------------*/ + /* <>, .. */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_SPS), /* service UUID */ + HI_WORD(GATT_UUID_SPS) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Scan Interval Window Char value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW), + HI_WORD(GATT_UUID_CHAR_SCAN_INTERVAL_WINDOW) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* <>, .. */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_NOTIFY /* characteristic properties */ + ) + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + } +#if SPS_CHAR_SCAN_REFRESH_SUPPORT + , + /* Scan Refresh Char value */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_SCAN_REFRESH), + HI_WORD(GATT_UUID_CHAR_SCAN_REFRESH) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + } +#endif +}; +/**< @brief SPS service size definition. */ +const uint16_t sps_attr_tbl_size = sizeof(sps_attr_tbl); + +/** + * @brief Set a scan paramter service parameter. + * + * NOTE: You can call this function with a scan paramter service parameter type and it will set the + * scan paramter service parameter. Scan paramter service parameters are defined in @ref T_SPS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Scan paramter service parameter type: @ref T_SPS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t refresh_value = 10; + sps_set_parameter(SPS_PARAM_SCAN_REFRESH, 1, &refresh_value); + } + * \endcode + */ +bool sps_set_parameter(T_SPS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + /* invalid param to set. */ + ret = false; + break; + case SPS_PARAM_SCAN_REFRESH: + sps_refresh_value = *((uint8_t *)p_value); + break; + } + + if (!ret) + { + PROFILE_PRINT_ERROR0("sps_set_parameter: SPS parameter set failed"); + } + + return ret; +} + + +/** + * @brief send notification. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID of service. + * @param[in] sps_refresh_value characteristic value to notify + * @return notification action result + * @retval 1 TRUE + * @retval 0 FALSE + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t sps_refresh_value = 10; + sps_scan_interval_window_value_notify(conn_id, sps_id, sps_refresh_value); + } + * \endcode + */ +bool sps_scan_interval_window_value_notify(uint8_t conn_id, uint8_t service_id, + uint8_t sps_refresh_value) +{ + return server_send_data(conn_id, service_id, GATT_SVC_SPS_SCAN_REFRESH_INDEX, + (uint8_t *)&sps_refresh_value, sizeof(sps_refresh_value), GATT_PDU_TYPE_ANY); +} + + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length Length of value to be written. + * @param[in] p_value Value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT sps_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + + T_APP_RESULT cause = APP_RESULT_SUCCESS; + if ((GATT_SVC_SPS_SCAN_INTERVAL_INDEX == attrib_index) && (length == 4) && p_value) + { + uint16_t scan_interval = ((uint16_t)p_value[1] << 8) && (0xff00) + p_value[0]; + uint16_t scan_window = ((uint16_t)p_value[2] << 8) && (0xff00) + p_value[3]; + + T_SPS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.conn_id = conn_id; + callback_data.msg_data.write.write_type = SPS_WRITE_SCAN_INTERVAL_WINDOW; + callback_data.msg_data.write.write_parameter.scan.scan_interval = scan_interval; + callback_data.msg_data.write.write_parameter.scan.scan_window = scan_window; + + if (pfn_sps_cb) + { + pfn_sps_cb(service_id, (void *)&callback_data); + } + } + else + { + PROFILE_PRINT_ERROR2("sps_attr_write_cb: attrib_index 0x%x, length %d", attrib_index, length); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + return cause; + +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void sps_cccd_update_cb(uint8_t conn_id, uint8_t service_id, uint16_t index, uint16_t ccc_bits) +{ + T_SPS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.conn_id = conn_id; + bool handle = false; + PROFILE_PRINT_INFO2("sps_cccd_update_cb: index %d ccc_bits %x", index, ccc_bits); + + switch (index) + { + case GATT_SVC_SPS_SCAN_REFRESH_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = SPS_NOTIFY_INDICATE_SCAN_REFRESH_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = SPS_NOTIFY_INDICATE_SCAN_REFRESH_DISABLE; + } + handle = true; + break; + } + default: + break; + } + + if (pfn_sps_cb && (handle == true)) + { + pfn_sps_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief SPS Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS sps_cbs = +{ + NULL, // Read callback function pointer + sps_attr_write_cb, // Write callback function pointer + sps_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add scan parameters service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + sps_id = sps_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID sps_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)sps_attr_tbl, + sps_attr_tbl_size, + sps_cbs)) + { + PROFILE_PRINT_ERROR1("sps_add_service: service_id %d", service_id); + service_id = 0xff; + return service_id; + } + pfn_sps_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/profile/server/tps.c b/src/ble/profile/server/tps.c new file mode 100644 index 0000000..29e289d --- /dev/null +++ b/src/ble/profile/server/tps.c @@ -0,0 +1,468 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file tps.c +* @brief Tx Power service source file. +* @details Interfaces to access Tx Power service. +* @author +* @date +* @version v1.0 +********************************************************************************************************* +*/ +#include "string.h" +#include "stdlib.h" // 添加stdlib.h以支持rand()函数 +#include "trace.h" +#include "profile_server.h" +#include "tps.h" +#include "fmna_version.h" +#include "trace.h" +#include "fmna_connection_platform.h" + + +/* 添加宏定义用于版本读取请求 */ +#define TPS_READ_FIRMWARE_VERSION 2 +#define TPS_READ_SYSTEM_ID 3 +#define TPS_READ_SERIAL_NUMBER 4 + +/*** + * + * if REAL_SN = 0 TEST_SN = 1 + * + * if REAL_SN = 1 TEST_SN = 0 + * + ***/ + +#define REAL_SN 0 +#define TEST_SN 1 + +/*** + * + * if REAL_SYS_ID = 0 TEST_SYS_ID = 1 + * + * if REAL_SYS_ID = 1 TEST_SYS_ID = 0 + * + ***/ + +#define REAL_SYS_ID 0 +#define TEST_SYS_ID 1 + +#if REAL_SN +static uint8_t m_serial_number[SERIAL_NUMBER_RAW_BLEN]; +#endif + +#define GATT_UUID_TX_POWER_SERVICE 0x1804 +#define GATT_UUID_CHAR_TX_LEVEL 0x2A07 +#define GATT_UUID_CHAR_FIRMWARE_VERSION 0x2A28 +#define SYSTEM_ID 0x2A23 +#define SERIAL_NUMBER 0x2A29 + +// 更新索引常量以匹配新的属性表结构 +#define TPS_TX_POWER_VALUE_INDEX 2 // 保持不变 +#define TPS_FIRMWARE_VERSION_INDEX 4 +#define TPS_SYSTEM_ID_INDEX 6 +#define TPS_SERIAL_NUMBER_INDEX 8 + +static uint8_t tx_power_value = 0; +static uint8_t firmware_version_str[3] = {FW_VERSION_MAJOR_NUMBER,FW_VERSION_MINOR_NUMBER,FW_VERSION_REVISION_NUMBER}; // 用于存储版本号字符串 + +#if TEST_SYS_ID + +static uint8_t system_id_value[1] = {0x16}; // 示例系统ID + +#endif + +#if REAL_SYS_ID + +static uint8_t system_id_value[1] = {0}; + +/** + * @brief 初始化系统ID值 + * @details 如果当前system_id_value为0,则生成随机值 + */ +static void tps_init_system_id(void) +{ + // 检查当前值是否为0,如果是则生成随机值 + if (system_id_value[0] == 0) + { + // 生成随机的系统ID值(0x01-0xFF之间) + // 在实际应用中,可能需要使用硬件随机数生成器或其他更安全的方式 + system_id_value[0] = (uint8_t)((rand() % 255) + 1); + DBG_DIRECT("TPS: Generated random system ID: 0x%02X\n", system_id_value[0]); + } +} +#endif + +#if TEST_SN +static uint8_t serial_number_value[16] = {'S','D','0','2','5','2','4','H','0','0','0','0','0','0','0','1'}; // 示例序列号 +#endif + +#if REAL_SN + //static uint8_t serial_number_value[16] = {0}; +#endif +static P_FUN_SERVER_GENERAL_CB pfn_tps_cb = NULL; + + +/**< @brief profile/service definition. */ +const T_ATTRIB_APPL tps_attr_tbl[] = +{ + /*----------------- TX Power Service -------------------*/ + /* 索引 0: 主要服务声明 */ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_TX_POWER_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_TX_POWER_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 1: Tx Power Level Characteristic声明 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 2: Tx Power Level Characteristic value (UUID 0x2A07) */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_TX_LEVEL), + HI_WORD(GATT_UUID_CHAR_TX_LEVEL) + }, + 0, /* variable size */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 3: Firmware Version Characteristic声明 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 4: Firmware Version Characteristic value (UUID 0x2A28) */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { + LO_WORD(GATT_UUID_CHAR_FIRMWARE_VERSION), + HI_WORD(GATT_UUID_CHAR_FIRMWARE_VERSION) + }, + 5, /* firmware_version_str的实际大小 */ + "1.1.1", + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 5: System ID Characteristic声明 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 6: System ID Characteristic value (UUID 0x2A23) */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { + LO_WORD(SYSTEM_ID), + HI_WORD(SYSTEM_ID) + }, + 1, /* system_id_value的实际大小 */ + "0x16", + GATT_PERM_READ + }, + + /* 索引 7: Serial Number Characteristic声明 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* 索引 8: Serial Number Characteristic value (UUID 0x2A29) */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { + LO_WORD(SERIAL_NUMBER), + HI_WORD(SERIAL_NUMBER) + }, + 16, /* 序列号长度 */ + "SD02524H00000001", + GATT_PERM_READ + } +}; + +/**< @brief TPS profile related services size definition. */ +const static int tps_attr_tbl_size = sizeof(tps_attr_tbl); + +/** + * @brief Set a Tx power service parameter. + * + * NOTE: You can call this function with a tx power service parameter type and it will set the + * tx power service parameter. Tx power service parameters are defined in @ref T_TPS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Tx power service parameter type: @ref T_TPS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (example: data type of uint16 will be cast to + * uint16 pointer). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t tx_power = 0; + tps_set_parameter(TPS_PARAM_TX_POWER, 1, &tx_power); + } + * \endcode + */ +bool tps_set_parameter(T_TPS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + /* invalid param to set. */ + ret = false; + break; + + case TPS_PARAM_TX_POWER: + tx_power_value = *(uint8_t *)p_value; + break; + + case TSP_PARAM_FIRMWARE: + if (len <= sizeof(firmware_version_str)) + { + memcpy(firmware_version_str, p_value, len); + } + else + { + ret = false; + } + break; + + case TPS_PARAM_SYSTEM_ID: + if (len <= sizeof(system_id_value)) + { + memcpy(system_id_value, p_value, len); + } + else + { + ret = false; + } + break; + + case TPS_PARAM_SERIAL_NUMBER: + if (len <= sizeof(serial_number_value)) + { + memcpy(serial_number_value, p_value, len); + } + else + { + ret = false; + } + break; + } + + if (!ret) + { + PROFILE_PRINT_ERROR0("tps_set_parameter: TPS parameter set failed"); + } + + return ret; +} + + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be read. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset offset of characteritic to be read. + * @param[in,out] length_ptr length of getting characteristic data. + * @param[in,out] pp_value pointer to pointer of characteristic value to be read. + * @return TProfileResult +*/ +T_APP_RESULT tps_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *length_ptr, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *length_ptr = 0; + T_TPS_CALLBACK_DATA callback_data; + + // 检查偏移量是否有效 + if (offset > 0) + { + PROFILE_PRINT_ERROR1("tps_attr_read_cb: offset %d not supported", offset); + cause = APP_RESULT_ATTR_NOT_FOUND; + return cause; + } + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("tps_attr_read_cb: attrib_index %d", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + break; + + case TPS_TX_POWER_VALUE_INDEX: + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = TPS_READ_TX_POWER_VALUE; + pfn_tps_cb(service_id, (void *)&callback_data); + + *pp_value = (uint8_t *)&tx_power_value; + *length_ptr = sizeof(tx_power_value); + break; + + case TPS_FIRMWARE_VERSION_INDEX: + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = TPS_READ_FIRMWARE_VERSION; + pfn_tps_cb(service_id, (void *)&callback_data); + + *pp_value = firmware_version_str; + *length_ptr = sizeof(firmware_version_str); + PROFILE_PRINT_INFO1("tps_attr_read_cb: firmware version index %d", attrib_index); + break; + + case TPS_SYSTEM_ID_INDEX: + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = TPS_READ_SYSTEM_ID; + pfn_tps_cb(service_id, (void *)&callback_data); + + *pp_value = system_id_value; + *length_ptr = sizeof(system_id_value); + PROFILE_PRINT_INFO1("tps_attr_read_cb: system ID index %d", attrib_index); + break; + + case TPS_SERIAL_NUMBER_INDEX: + callback_data.conn_id = conn_id; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = TPS_READ_SERIAL_NUMBER; + pfn_tps_cb(service_id, (void *)&callback_data); + + *pp_value = serial_number_value; + *length_ptr = sizeof(serial_number_value); + PROFILE_PRINT_INFO1("tps_attr_read_cb: serial number index %d", attrib_index); + break; + } + + PROFILE_PRINT_INFO2("tps_attr_read_cb: attrib_index %d, *length_ptr %d", attrib_index, *length_ptr); + + return (cause); +} + + +// TPS related Service Callbacks +const T_FUN_GATT_SERVICE_CBS tps_cbs = +{ + tps_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + NULL // CCCD update callback function pointer +}; + +/** + * @brief Add tx power service to the BLE stack database. + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + tps_id = tps_add_service(app_handle_profile_message); + } + * \endcode + */ + +#if REAL_SN +/** + * @brief 初始化序列号值,从m_serial_number复制到serial_number_value + */ +static void tps_init_serial_number(void) +{ + // 调用平台API获取序列号 + fmna_connection_platform_get_serial_number(m_serial_number, SERIAL_NUMBER_RAW_BLEN); + + // 复制序列号到serial_number_value数组 + // 确保不会越界,serial_number_value大小为16,SERIAL_NUMBER_RAW_BLEN也为16 + memcpy(serial_number_value, m_serial_number, + (SERIAL_NUMBER_RAW_BLEN <= sizeof(serial_number_value)) ? SERIAL_NUMBER_RAW_BLEN : sizeof(serial_number_value)); + + PROFILE_PRINT_INFO0("tps_init_serial_number: Serial number initialized"); +} +#endif + + +T_SERVER_ID tps_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)tps_attr_tbl, + tps_attr_tbl_size, + tps_cbs)) + { + PROFILE_PRINT_ERROR1("tps_add_service: service_id %d", service_id); + service_id = 0xff; + } + + pfn_tps_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + +#if REAL_SYS_ID + // 初始化系统ID(如果需要) + tps_init_system_id(); +#endif + +#if REAL_SN + // 初始化序列号值 + tps_init_serial_number(); + #endif + + return service_id; +} + diff --git a/src/ble/profile/server/vendor_service.c b/src/ble/profile/server/vendor_service.c new file mode 100644 index 0000000..7da9528 --- /dev/null +++ b/src/ble/profile/server/vendor_service.c @@ -0,0 +1,282 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file vendor_service.c +* @brief Vendor service source file. +* @details Interfaces to access Vendor service. +* @author +* @date 2020-03-11 +* @version v1.0 +********************************************************************************************************* +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "board.h" +#include "string.h" +#include "trace.h" +#include "gatt.h" +#include "profile_server.h" +#include "vendor_service.h" +#include "gap.h" +#include "mem_config.h" +#include "app_section.h" +#include "overlay_mgr.h" + +/*============================================================================* + * Global Variables + *============================================================================*/ +uint8_t vendor_svc_handshake_values[16] = {0}; + +/*============================================================================* + * Local Variables + *============================================================================*/ +static P_FUN_SERVER_GENERAL_CB pfn_vendor_svc_cb = NULL; +static const uint8_t GATT_UUID_VENDOR_SERVICE[16] = {0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFF, 0xD1, 0x00, 0x00}; + +/**< @brief profile/service definition. +* here is an example of OTA service table +* including Write +*/ +const T_ATTRIB_APPL vendor_svc_bas_attr_tbl[] = +{ + /*--------------------------Vendor Service ---------------------------*/ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)GATT_UUID_VENDOR_SERVICE, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* <> 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE_NO_RSP | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* characteristic value 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_VENDOR_HANDSHAKE), + HI_WORD(GATT_UUID_CHAR_VENDOR_HANDSHAKE), + }, + 1, /* variable size */ + (void *)NULL, + GATT_PERM_READ | GATT_PERM_WRITE /* wPermissions */ + }, + + /* client characteristic configuration 3 */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /* <> 4 */ + { + ATTRIB_FLAG_VALUE_INCL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_WRITE | GATT_CHAR_PROP_WRITE_NO_RSP) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* characteristic value 5 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_CHAR_VENDOR_TEST_MODE), + HI_WORD(GATT_UUID_CHAR_VENDOR_TEST_MODE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_WRITE /* permissions */ + }, +}; + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief write characteristic data from service. + * + * @param ServiceID ServiceID to be written. + * @param iAttribIndex Attribute index of characteristic. + * @param wLength length of value to be written. + * @param pValue value to be written. + * @return Profile procedure result +*/ +T_APP_RESULT vendor_svc_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + bool handle = true; + T_VENDOR_CALLBACK_DATA callback_data; + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + APP_PRINT_INFO1("[vendor_svc_attr_write_cb] attrib_index is %d", attrib_index); + + if (BLE_SERVICE_CHAR_VENDOR_HANDSHAKE_INDEX == attrib_index) + { + /* Make sure written value size is valid. */ + if ((length != 16) || (p_value == NULL)) + { + handle = false; + cause = APP_RESULT_APP_ERR; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write_msg.write_type = VENDOR_WRITE_HANDSHAKE; + callback_data.msg_data.write_msg.write_parameter.report_data.len = length; + callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value; + } + } + else if (BLE_SERVICE_CHAR_VENDOR_TEST_MODE_INDEX == attrib_index) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE; + callback_data.msg_data.write_msg.write_type = VENDOR_WRITE_TEST_MODE; + callback_data.msg_data.write_msg.write_parameter.report_data.len = length; + callback_data.msg_data.write_msg.write_parameter.report_data.report = p_value; + } + else + { + handle = false; + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + if ((pfn_vendor_svc_cb) && (handle == true)) + { + pfn_vendor_svc_cb(service_id, (void *)&callback_data); + } + + return cause; + +} + +/** + * @brief update CCCD bits from stack. + * + * @param ServiceId Service ID. + * @param Index Attribute index of characteristic data. + * @param wCCCBits CCCD bits from stack. + * @return None +*/ +void vendor_svc_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, + uint16_t ccc_bits) +{ + bool handle = true; + T_VENDOR_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + + APP_PRINT_INFO2("[vendor_svc_cccd_update_cb] index = %d, ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SVC_VENDOR_HANDSHAKE_CHAR_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = VENDOR_NOTIFY_ENABLE; + } + else + { + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indification_index = VENDOR_NOTIFY_DISABLE; + } + break; + } + default: + { + handle = false; + break; + } + } + + if (pfn_vendor_svc_cb && (handle == true)) + { + /* Notify Application */ + pfn_vendor_svc_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief Vendor Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS vendor_svc_cbs = +{ + NULL, // Read callback function pointer + vendor_svc_attr_write_cb, // Write callback function pointer + vendor_svc_cccd_update_cb // CCCD update callback function pointer +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief Add vendor service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + bas_id = vendor_svc_add_service(app_handle_profile_message); + } + * \endcode + */ +uint8_t vendor_svc_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)vendor_svc_bas_attr_tbl, + sizeof(vendor_svc_bas_attr_tbl), + vendor_svc_cbs)) + { + APP_PRINT_INFO1("vendor_svc_add_service: service_id %d", service_id); + service_id = 0xff; + return service_id; + } + pfn_vendor_svc_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/voice_service.c b/src/ble/profile/server/voice_service.c new file mode 100644 index 0000000..5c9abd1 --- /dev/null +++ b/src/ble/profile/server/voice_service.c @@ -0,0 +1,327 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file voice_service.c +* @brief This file provides a vendor defined voice profile. +* @details +* @author +* @date 2020-03-11 +* @version v1.1 +****************************************************************************** +* @attention +*

    © COPYRIGHT 2015 Realtek Semiconductor Corporation

    +****************************************************************************** +*/ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include "trace.h" +#include "gatt.h" +#include "gap.h" +#include "string.h" +#include "gap_conn_le.h" +#include "gap_msg.h" +#include "voice_service.h" + +/*============================================================================* + * Local Variables + *============================================================================*/ +const uint8_t GATT_UUID128_VOICE_SRV[16] = { 0x12, 0xA2, 0x4D, 0x2E, 0xFE, 0x14, 0x48, 0x8e, 0x93, 0xD2, 0x17, 0x3C, 0xFD, 0x03, 0x00, 0x00}; + +static P_FUN_SERVER_GENERAL_CB pfn_voice_cb = NULL; + +/**@brief profile/service definition. +* here is the Voice Service table +*/ +const T_ATTRIB_APPL VOICE_SERVICE_GATT_TABLE[] = +{ + /*--------------------------Voice Service ---------------------------*/ + /* <>, 0 */ + { + (ATTRIB_FLAG_VOID | ATTRIB_FLAG_LE), /* wFlags */ + { + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), /* bTypeValue */ + }, + UUID_128BIT_SIZE, /* bValueLen */ + (void *)GATT_UUID128_VOICE_SRV, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + + /* VOICE_CHAR_TX */ + /* Characteristic Definition, 1 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_WRITE, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_VOICE_CHAR_CTL), + HI_WORD(GATT_UUID_VOICE_CHAR_CTL) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_WRITE /* permissions */ + }, + + /* VOICE_CHAR_DATA */ + /* Characteristic, 3 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 4 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_VOICE_CHAR_DATA), + HI_WORD(GATT_UUID_VOICE_CHAR_DATA) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* client characteristic configuration, 5 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + + /* VOICE_CHAR_CMD */ + /* Characteristic, 6 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ | GATT_CHAR_PROP_NOTIFY, /* characteristic properties */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* Characteristic Value, 7 */ + { + ATTRIB_FLAG_VALUE_APPL, /* flags */ + { /* type_value */ + LO_WORD(GATT_UUID_VOICE_CHAR_CMD), + HI_WORD(GATT_UUID_VOICE_CHAR_CMD) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* permissions */ + }, + + /* client characteristic configuration, 8 */ + { + (ATTRIB_FLAG_VALUE_INCL | /* wFlags */ + ATTRIB_FLAG_CCCD_APPL), + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, +}; + +/*============================================================================* + * Local Functions + *============================================================================*/ +/** + * @brief read characteristic data from service. + * + * @param conn_id Connection ID. + * @param service_id ServiceID to be read. + * @param attrib_index Attribute index of getting characteristic data. + * @param offset Offset of characteritic to be read. + * @param p_length Length of getting characteristic data. + * @param pp_value Pointer to pointer of characteristic value to be read. + * @return T_APP_RESULT +*/ +T_APP_RESULT voice_attr_read_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + *p_length = 0; + + PROFILE_PRINT_INFO2("voice_attr_read_cb attrib_index = %d offset %x", attrib_index, offset); + + switch (attrib_index) + { + default: + { + PROFILE_PRINT_ERROR1("voice_attr_read_cb attrib_index = %d not found", attrib_index); + cause = APP_RESULT_ATTR_NOT_FOUND; + } + break; + } + return (cause); +} + +/** + * @brief write characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID to be written. + * @param[in] attrib_index Attribute index of characteristic. + * @param[in] write_type Write type. + * @param[in] length Length of writing characteristic data. + * @param[in] p_value Pointer to characteristic data. + * @param[in] p_write_ind_post_proc Function pointer after ias_attr_write_cb. + * @return TProfileResult +*/ +T_APP_RESULT voice_attr_write_cb(uint8_t conn_id, uint8_t service_id, uint16_t attrib_index, + T_WRITE_TYPE write_type, + uint16_t length, uint8_t *p_value, P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc) +{ + T_APP_RESULT cause = APP_RESULT_SUCCESS; + + APP_PRINT_INFO1("voice_attr_write_cb write_type = 0x%x", write_type); + + if (!p_value) + { + cause = APP_RESULT_INVALID_PDU; + } + else if (attrib_index == GATT_SRV_VOICE_CHAR_CTL_VALUE_INDEX) + { + cause = APP_RESULT_SUCCESS; + } + else + { + cause = APP_RESULT_ATTR_NOT_FOUND; + } + + return cause; + +} + +/** + * @brief update CCCD bits from stack. + * + * @param conn_id Connection ID. + * @param service_id Service ID. + * @param index Attribute index of characteristic data. + * @param ccc_bits CCCD bits from stack. + * @return None +*/ +void voice_cccd_update_cb(uint8_t conn_id, uint8_t service_id, uint16_t index, uint16_t ccc_bits) +{ + T_VOICE_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + bool handle = true; + + PROFILE_PRINT_INFO2("voice_cccd_update_cb index = %d ccc_bits %x", index, ccc_bits); + switch (index) + { + case GATT_SRV_VOICE_CHAR_DATA_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_DATA_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_DATA_DISABLE; + } + break; + + case GATT_SRV_VOICE_CHAR_CMD_CCCD_INDEX: + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_NOTIFY) + { + callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_CMD_ENABLE; + } + else + { + callback_data.msg_data.notification_indification_index = VOICE_NOTIFY_CMD_DISABLE; + } + break; + + default: + handle = false; + break; + } + /* Notify Application. */ + if (pfn_voice_cb && (handle == true)) + { + pfn_voice_cb(service_id, (void *)&callback_data); + } + + return; +} + +/** + * @brief Vendor ble Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS VOICE_SERVICE_CBS = +{ + voice_attr_read_cb, /*Read callback function pointer*/ + voice_attr_write_cb, /*Write callback function pointer*/ + voice_cccd_update_cb, /*CCCD update callback function pointer*/ +}; + +/*============================================================================* + * Global Functions + *============================================================================*/ +/** + * @brief add Vendor ble service to application. + * + * @param p_func pointer of app callback function called by profile. + * @return service ID auto generated by profile layer. + * @retval service_id +*/ +uint8_t voice_service_add_service(void *p_func) +{ + uint8_t service_id; + if (false == server_add_service(&service_id, + (uint8_t *)VOICE_SERVICE_GATT_TABLE, + sizeof(VOICE_SERVICE_GATT_TABLE), + VOICE_SERVICE_CBS)) + { + APP_PRINT_ERROR1("[voice_service_add_service]failed, service_id = %d", service_id); + service_id = 0xff; + return service_id; + } + pfn_voice_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + APP_PRINT_INFO1("[voice_service_add_service] service_id = %d", service_id); + return service_id; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/ble/profile/server/wss.c b/src/ble/profile/server/wss.c new file mode 100644 index 0000000..26f3b6b --- /dev/null +++ b/src/ble/profile/server/wss.c @@ -0,0 +1,502 @@ +/** +********************************************************************************************************* +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file wss.c +* @brief weight scale service source file. +* @details Interface to access the weight scale service. +* @author Vera +* @date +* @version v1.0 +********************************************************************************************************* +*/ +#include "trace.h" +#include +#include "gatt.h" +#include "wss.h" + + +/* Weight scale service UUID */ +#define GATT_UUID_WEIGHT_SCALE_SERVICE 0x181D +/* Weight scale feature characteristic UUID*/ +#define GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ 0x2A9E +/* Weight measurement characteristic UUID*/ +#define GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE 0x2A9D + +/** @brief The Maximum Length of Weight Measurement Value*/ +#define WSS_MEASUREMENT_VALUE_MAX_LEN 15 + + +/** @brief Index of each characteristic in weight scale service database. */ +#define WEIGHT_SCALE_SERVICE_CHAR_FEATURE_READ_INDEX 0x02 +#define WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX 0x04 +#define WEIGHT_SCALE_SERVICE_CHAR_INDICATE_CCCD_INDEX (WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX + 1) + +#define WSS_FEATURE_TIMESTAMP_SUPPORTED 1 +#define WSS_FEATURE_MULTIUSERS_SUPPORTED 1 +#define WSS_FEATURE_BMI_SUPPORTED 1 +#define WSS_FEATURE_WEIGHTMEASUREMENT_RESOLUTION 1 +#define WSS_FEATURE_HEIGHTMEASUREMENT_RESOLUTION 1 + +/******************************************************************************************************** +* local static variables defined here, only used in this source file. +********************************************************************************************************/ +/**< Value of weight scale feature read characteristic. */ +static T_WEIGHT_SCALE_FEATURE_VALUE weight_scale_char_read_value = +{ + WSS_FEATURE_TIMESTAMP_SUPPORTED, + WSS_FEATURE_MULTIUSERS_SUPPORTED, + WSS_FEATURE_BMI_SUPPORTED, + WSS_FEATURE_WEIGHTMEASUREMENT_RESOLUTION, + WSS_FEATURE_HEIGHTMEASUREMENT_RESOLUTION, + 0 +}; + +/**< Function pointer used to send event to application from Weight Scale Service. Initiated in wss_add_service. */ +static P_FUN_SERVER_GENERAL_CB pfn_wss_cb = NULL; +/**< Measurement Related Value. */ +static T_WSS_MEASUREMENT wss_measurement = {0}; +static uint8_t wss_measurement_value_for_indicate[WSS_MEASUREMENT_VALUE_MAX_LEN]; +static uint8_t wss_measurement_value_actual_length = 0; + +/**< @brief service definition. */ +/**< Attribute Table */ +static const T_ATTRIB_APPL wss_tbl[] = +{ + /* <>, .. 0*/ + { + (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE), /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_PRIMARY_SERVICE), + HI_WORD(GATT_UUID_PRIMARY_SERVICE), + LO_WORD(GATT_UUID_WEIGHT_SCALE_SERVICE), /* service UUID */ + HI_WORD(GATT_UUID_WEIGHT_SCALE_SERVICE) + }, + UUID_16BIT_SIZE, /* bValueLen */ + NULL, /* pValueContext */ + GATT_PERM_READ /* wPermissions */ + }, + /* <> for read , .. 1*/ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + GATT_CHAR_PROP_READ /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Weight Scale Feature value , .. 2 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ), + HI_WORD(GATT_UUID_CHAR_WEIGHT_SCALE_FEATURE_READ) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + + /* <> for indicate , .. 3 */ + { + ATTRIB_FLAG_VALUE_INCL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHARACTERISTIC), + HI_WORD(GATT_UUID_CHARACTERISTIC), + (GATT_CHAR_PROP_INDICATE) /* characteristic properties */ + /* characteristic UUID not needed here, is UUID of next attrib. */ + }, + 1, /* bValueLen */ + NULL, + GATT_PERM_READ /* wPermissions */ + }, + /* Weight Measurement value , .. 4 */ + { + ATTRIB_FLAG_VALUE_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE), + HI_WORD(GATT_UUID_CHAR_WEIGHT_MEASUREMENT_INDICATE) + }, + 0, /* bValueLen */ + NULL, + GATT_PERM_NONE /* wPermissions */ + }, + /* client characteristic configuration , .. 5 */ + { + ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL, /* wFlags */ + { /* bTypeValue */ + LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG), + /* NOTE: this value has an instantiation for each client, a write to */ + /* this attribute does not modify this default value: */ + LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT), /* client char. config. bit field */ + HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT) + }, + 2, /* bValueLen */ + NULL, + (GATT_PERM_READ | GATT_PERM_WRITE) /* wPermissions */ + }, + +}; + +/** + * @brief Set a weight scale service parameter. + * + * NOTE: You can call this function with a weight scale service parameter type and it will set the + * weight scale service parameter. Weight scale service parameters are defined in @ref T_WSS_PARAM_TYPE. + * If the "len" field sets to the size of a "uint16_t" ,the + * "p_value" field must point to a data with type of "uint16_t". + * + * @param[in] param_type Weight scale service parameter type: @ref T_WSS_PARAM_TYPE + * @param[in] len Length of data to write + * @param[in] p_value Pointer to data to write. This is dependent on + * the parameter type and WILL be cast to the appropriate + * data type (For example: if data type of param is uint16_t, p_value will be cast to + * pointer of uint16_t). + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint32_t weight_feature = 0x0000001f; + wss_set_parameter(WSS_PARAM_FEATURE_READ_CHAR_VAL, 4, &weight_feature); + } + * \endcode + */ +bool wss_set_parameter(T_WSS_PARAM_TYPE param_type, uint8_t len, void *p_value) +{ + bool ret = true; + + switch (param_type) + { + default: + { + ret = false; + PROFILE_PRINT_ERROR0("wss_set_parameter failed\n"); + } + break; + case WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG: + { + if (len != 1) + { + PROFILE_PRINT_ERROR0("wss_set_parameter measurement weightParam Flag \n"); + } + memcpy(&wss_measurement.flag, p_value, len); + } + break; + case WSS_PARAM_MEASUREMENT_WEIGHT_VALUE: + { + if (len != 2) + { + PROFILE_PRINT_ERROR0("wss_set_parameter measurement weight value \n"); + break; + } + if (wss_measurement.flag.measurement_units == 0) + { + memcpy(&wss_measurement.weight_si_value, p_value, len); + } + else + { + memcpy(&wss_measurement.weight_imperial_value, p_value, len); + } + } + break; + case WSS_PARAM_MEASUREMENT_TIME_STAMP: + { + if (len != sizeof(T_WSS_TIME_STAMP)) + { + PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement time stamp \n"); + break; + } + + memcpy(&wss_measurement.time_stamp, p_value, len); + + } + break; + case WSS_PARAM_MEASUREMENT_USERID: + { + if (len != 1) + { + PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement user_id \n"); + break; + } + + memcpy(&wss_measurement.user_id, p_value, len); + } + break; + case WSS_PARAM_MEASUREMENT_BMI: + { + if (len != 2) + { + PROFILE_PRINT_ERROR0("wss_set_parameter weight measurement bmi \n"); + break; + } + + memcpy(&wss_measurement.bmi, p_value, len); + + } + break; + case WSS_PARAM_MEASUREMENT_HEIGHT_VALUE: + { + if (len != 2) + { + PROFILE_PRINT_ERROR0("wss_set_parameter height value \n"); + break; + } + if (wss_measurement.flag.measurement_units == 0) + { + memcpy(&wss_measurement.height_si_value, p_value, len); + } + else + { + memcpy(&wss_measurement.height_imperial_value, p_value, len); + } + + } + break; + case WSS_PARAM_FEATURE_READ_CHAR_VAL: + { + if (len != 4) + { + PROFILE_PRINT_ERROR0("wss_set_parameter feature value \n"); + break; + } + memcpy(&weight_scale_char_read_value, p_value, len); + + } + } + + if (!ret) + { + PROFILE_PRINT_ERROR0("wss_set_parameter failed\n"); + } + if (ret) + { + PROFILE_PRINT_INFO0("wss_set_parameter success\n"); + } + + return ret; +} + + +void wss_format_measurement_value() +{ + uint8_t cur_offset = 0; + + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.flag, 1); + cur_offset += 1; + + if (wss_measurement.flag.measurement_units == 0) + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.weight_si_value, 2); + } + else + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.weight_imperial_value, 2); + } + cur_offset += 2; + + if (wss_measurement.flag.time_stamp_present) + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.time_stamp, 7); + cur_offset += 7; + } + + if (wss_measurement.flag.user_id_present) + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.user_id, 1); + cur_offset += 1; + } + if (wss_measurement.flag.bmi_and_height_present) + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.bmi, 2); + cur_offset += 2; + if (wss_measurement.flag.measurement_units == 0) + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.height_si_value, 2); + } + else + { + memcpy(&wss_measurement_value_for_indicate[cur_offset], &wss_measurement.height_imperial_value, 2); + } + cur_offset += 2; + } + + wss_measurement_value_actual_length = cur_offset; + +} + + +/** + * @brief read characteristic data from service. + * + * @param[in] conn_id Connection id. + * @param[in] service_id ServiceID of characteristic data. + * @param[in] attrib_index Attribute index of getting characteristic data. + * @param[in] offset Used for Blob Read. + * @param[in,out] p_length Length of getting characteristic data. + * @param[in,out] pp_value Data got from service. + * @return Profile procedure result +*/ +T_APP_RESULT wss_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t attrib_index, + uint16_t offset, uint16_t *p_length, uint8_t **pp_value) +{ + T_APP_RESULT wCause = APP_RESULT_SUCCESS; + + switch (attrib_index) + { + default: + PROFILE_PRINT_ERROR1("wss_attr_read_cb, Attr not found, index=%d", attrib_index); + wCause = APP_RESULT_ATTR_NOT_FOUND; + break; + case WEIGHT_SCALE_SERVICE_CHAR_FEATURE_READ_INDEX: + { + PROFILE_PRINT_INFO1("wss_attr_read_cb, index = %d", attrib_index); + + T_WSS_CALLBACK_DATA callback_data; + callback_data.msg_type = SERVICE_CALLBACK_TYPE_READ_CHAR_VALUE; + callback_data.msg_data.read_value_index = WEIGHT_SCALE_READ_FEATURE; + pfn_wss_cb(service_id, (void *)&callback_data); + *pp_value = (uint8_t *)&weight_scale_char_read_value; + *p_length = sizeof(weight_scale_char_read_value); + PROFILE_PRINT_INFO2("wss_attr_read_cb weight_scale_char_read_value = %x,Length = %d", + weight_scale_char_read_value, *p_length); + } + break; + } + + return (wCause); +} + +/** + * @brief Send measurement indication data. + * + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service id. + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + uint8_t wm_flag = WSS_FLAG_MEASUREMENT_UINT_BIT + | WSS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT + | WSS_FLAG_MEASUREMENT_USERID_PRESNET_BIT + | WSS_FLAG_MEASUREMENT_BMI_PRESNET_BIT; + + wss_set_parameter(WSS_PARAM_MEASUREMENT_WEIGHTPARAM_FLAG, sizeof(wm_flag), &wm_flag); + wss_set_parameter(WSS_PARAM_MEASUREMENT_TIME_STAMP, sizeof(wss_measure_time_stamp), + &wss_measure_time_stamp); + wss_measurement_indicate(p_parse_value->dw_param[0], wss_id); + } + * \endcode + */ +bool wss_measurement_indicate(uint8_t conn_id, T_SERVER_ID service_id) +{ + wss_format_measurement_value(); + + PROFILE_PRINT_INFO0("WeightScaleService_Measurement_Indicate"); + // send indication to client + return server_send_data(conn_id, service_id, WEIGHT_SCALE_SERVICE_CHAR_MEASUREMENT_INDICATE_INDEX, + (uint8_t *)&wss_measurement_value_for_indicate, wss_measurement_value_actual_length, + GATT_PDU_TYPE_INDICATION); +} + +/** + * @brief update CCCD bits from stack. + * + * @param[in] conn_id Connection id. + * @param[in] service_id Service ID. + * @param[in] index Attribute index of characteristic data. + * @param[in] ccc_bits CCCD bits from stack. + * @return None +*/ +void wss_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index, uint16_t ccc_bits) +{ + T_WSS_CALLBACK_DATA callback_data; + bool handle = false; + PROFILE_PRINT_INFO2("wss_cccd_update_cb Index = %d wCCCDBits %x", index, ccc_bits); + switch (index) + { + case WEIGHT_SCALE_SERVICE_CHAR_INDICATE_CCCD_INDEX: + { + if (ccc_bits & GATT_CLIENT_CHAR_CONFIG_INDICATE) + { + // Enable Indication + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indication_index = WSS_INDICATE_WEIGHT_MEASUREMENT_ENABLE; + } + else + { + // Disable Indication + callback_data.msg_type = SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION; + callback_data.msg_data.notification_indication_index = WSS_INDICATE_WEIGHT_MEASUREMENT_DISABLE; + } + handle = true; + } + break; + default: + break; + } + if (pfn_wss_cb && (handle == true)) + { + pfn_wss_cb(service_id, (void *)&callback_data); + } +} + +/** + * @brief Weight Scale Service Callbacks. +*/ +const T_FUN_GATT_SERVICE_CBS wss_cbs = +{ + wss_attr_read_cb, // Read callback function pointer + NULL, // Write callback function pointer + wss_cccd_update_cb // CCCD update callback function pointer +}; + +/** + * @brief Add Weight scale service to the BLE stack database. + * + * + * @param[in] p_func Callback when service attribute was read, write or cccd update. + * @return Service id generated by the BLE stack: @ref T_SERVER_ID. + * @retval 0xFF Operation failure. + * @retval Others Service id assigned by stack. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(1); + wss_id = wss_add_service(app_handle_profile_message); + } + * \endcode + */ +T_SERVER_ID wss_add_service(void *p_func) +{ + T_SERVER_ID service_id; + if (false == server_add_service(&service_id, + (uint8_t *)wss_tbl, + sizeof(wss_tbl), + wss_cbs)) + { + PROFILE_PRINT_ERROR1("wss_add_service: ServiceId %d", service_id); + service_id = 0xff; + return service_id; + } + PROFILE_PRINT_INFO1("wss_add_service: ServiceId %d", service_id); + pfn_wss_cb = (P_FUN_SERVER_GENERAL_CB)p_func; + return service_id; +} + diff --git a/src/ble/sample/ams.c b/src/ble/sample/ams.c new file mode 100644 index 0000000..3d022c3 --- /dev/null +++ b/src/ble/sample/ams.c @@ -0,0 +1,142 @@ +/** +***************************************************************************************** +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ams.c + * @brief This file handles AMS Client routines. + * @author + * @date + * @version + ************************************************************************************** +*/ +#include "app_flags.h" +#if F_BT_AMS_CLIENT_SUPPORT +#include +#include +#include +#include +#include + +T_CLIENT_ID ams_client; + +/** + * @brief ams clinet callback handle message from upperstack + */ +T_APP_RESULT ams_client_cb(T_CLIENT_ID client_id, uint8_t conn_id, void *p_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_AMS_CB_DATA *p_cb_data = (T_AMS_CB_DATA *)p_data; + + switch (p_cb_data->cb_type) + { + case AMS_CLIENT_CB_TYPE_DISC_STATE: + switch (p_cb_data->cb_content.disc_state) + { + case AMS_DISC_DONE: + APP_PRINT_INFO0("ams_client_cb: discover procedure done."); + ams_subscribe_remote_cmd(conn_id, true); + break; + case AMS_DISC_FAILED: + APP_PRINT_ERROR0("ams_client_cb: discover request failed."); + break; + default: + break; + } + break; + + case AMS_CLIENT_CB_TYPE_NOTIF_IND_RESULT: + switch (p_cb_data->cb_content.notify_data.type) + { + case AMS_NOTIFY_FROM_REMOTE_CMD: + APP_PRINT_INFO2("AMS_NOTIFY_FROM_REMOTE_CMD: data[%d]: %b", + p_cb_data->cb_content.notify_data.value_size, + TRACE_BINARY(p_cb_data->cb_content.notify_data.value_size, + p_cb_data->cb_content.notify_data.p_value)); + break; + case AMS_NOTIFY_FROM_ENTITY_UPD: + APP_PRINT_INFO2("AMS_NOTIFY_FROM_ENTITY_UPD: data[%d]: %b", + p_cb_data->cb_content.notify_data.value_size, + TRACE_BINARY(p_cb_data->cb_content.notify_data.value_size, + p_cb_data->cb_content.notify_data.p_value)); + break; + default: + break; + } + break; + + case AMS_CLIENT_CB_TYPE_READ_RESULT: + switch (p_cb_data->cb_content.read_data.type) + { + case AMS_READ_FROM_ENTITY_UPD: + APP_PRINT_INFO3("AMS_READ_FROM_ENTITY_UPD: cause 0x%x, data[%d]: %b", + p_cb_data->cb_content.read_data.cause, + p_cb_data->cb_content.read_data.value_size, + TRACE_BINARY(p_cb_data->cb_content.read_data.value_size, p_cb_data->cb_content.read_data.p_value)); + break; + default: + break; + } + break; + + case AMS_CLIENT_CB_TYPE_WRITE_RESULT: + { + if (p_cb_data->cb_content.write_result.cause != ATT_SUCCESS) + { + APP_PRINT_ERROR1("AMS_CLIENT_CB_TYPE_WRITE_RESULT: Failed, cause 0x%x", + p_cb_data->cb_content.write_result.cause); + } + switch (p_cb_data->cb_content.write_result.type) + { + case AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE: + APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_NOTIFY_ENABLE"); + ams_subscribe_entity_upd(conn_id, true); + break; + + case AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE: + APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_NOTIFY_DISABLE"); + break; + + case AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE: + APP_PRINT_INFO0("AMS_WRITE_ENTITY_UPD_NOTIFY_ENABLE"); + + break; + case AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE: + APP_PRINT_INFO0("AMS_WRITE_ENTITY_UPD_NOTIFY_DISABLE"); + break; + + case AMS_WRITE_ENTITY_ATTR_VALUE: + APP_PRINT_INFO0("AMS_WRITE_ENTITY_ATTR_VALUE"); + break; + + case AMS_WRITE_REMOTE_CMD_VALUE: + APP_PRINT_INFO0("AMS_WRITE_REMOTE_CMD_VALUE"); + break; + + default: + break; + } + } + break; + + case AMS_CLIENT_CB_TYPE_DISCONNECT_INFO: + { + APP_PRINT_INFO1("AMS_CLIENT_CB_TYPE_DISCONNECT_INFO: conn_id = 0x%x", conn_id); + } + break; + + default: + break; + } + return result; +} + +/** + * @brief App register ams client to upperstack. + */ +void ams_init(uint8_t link_num) +{ + ams_client = ams_add_client(ams_client_cb, link_num); +} + +#endif + diff --git a/src/ble/sample/ams.h b/src/ble/sample/ams.h new file mode 100644 index 0000000..bc2a8a1 --- /dev/null +++ b/src/ble/sample/ams.h @@ -0,0 +1,33 @@ +/** +********************************************************************************************************* +* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file ams.h +* @brief +* @details +* @author +* @date +* @version +* ********************************************************************************************************* +*/ + + +#ifndef _AMS_H__ +#define _AMS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define AMS_LINK_NUM 1 + +void ams_init(uint8_t link_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/ble/sample/ghss_sample.c b/src/ble/sample/ghss_sample.c new file mode 100644 index 0000000..34caf00 --- /dev/null +++ b/src/ble/sample/ghss_sample.c @@ -0,0 +1,734 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ghss_sample.c + * @brief This file handles GHSS routines. + * @author + * @date + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2017 Realtek Semiconductor Corporation

    + ************************************************************************************** + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include "trace.h" +#include "ghss_sample.h" +#include "user_cmd.h" +#include "bt_gatt_svc.h" + +extern const T_ATTRIB_APPL ghss_attr_tbl[]; +extern const uint16_t ghss_char_num; + +/** Record Access Control Point related variables. */ +T_GHSS_RACP ghss_send_racp; +uint8_t ghss_send_racp_length; +T_GHSS_GHS_CP_OPCODE ghss_send_ghs_cp; + +T_GHSS_LINK_MGR ghss_link; + +/** When GHSS Record Access Control Point Operand Filter Type takes effect, use the array to save + * the report idx of found stored records. */ +uint32_t racp_find_report_idx[GHSS_MAX_STORED_HEALTH_OBS_NUM] = {0}; +/** Report number of found stored records. */ +uint32_t racp_find_report_num = 0; + +/** The Rolling Segment Counter is incremented per segment during a connection. If the Rolling Segment Counter is equal to a value of 63, then the counter rolls over to 0 when it is next incremented. */ +uint8_t rolling_segment_counter = 0; + +/** Stored records related variables. */ +uint32_t stored_record_number = 0; +T_OS_QUEUE ghss_stored_hob_record_list; + +/** Health Observation Body. */ +T_GHSS_HEALTH_OBS_BODY ghss_health_obs_body = {GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION}; + +/*============================================================================* + * Functions + *============================================================================*/ +void app_ghss_racp_find_stored_obs_record_by_num(uint32_t min_num, uint32_t max_num) +{ + racp_find_report_num = 0; + memset(&racp_find_report_idx, 0, GHSS_MAX_STORED_HEALTH_OBS_NUM); + + for (uint32_t i = 0; i < stored_record_number; i++) + { + if (i >= min_num) + { + racp_find_report_idx[racp_find_report_num] = i; + racp_find_report_num += 1; + } + } +} + +void app_ghss_racp_find_stored_obs_record_by_time(uint8_t *p_min_time, uint8_t *p_max_time) +{ + racp_find_report_num = 0; + memset(&racp_find_report_idx, 0, GHSS_MAX_STORED_HEALTH_OBS_NUM); + + uint8_t min_time[6] = {0}; + uint8_t max_time[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + + if (p_min_time) + { + memcpy(&min_time, p_min_time, 6); + } + + if (p_max_time) + { + memcpy(&max_time, p_max_time, 6); + } + + for (uint32_t i = 0; i < stored_record_number; i++) + { + uint8_t time[6] = {0}; + + app_ghss_find_stored_health_obs_body_by_idx(i); + memcpy(time, ghss_health_obs_body.time_stamp.time_value, 6); + + if ((memcmp(time, min_time, 6) >= 0) && + (memcmp(time, max_time, 6) <= 0)) + { + racp_find_report_idx[racp_find_report_num] = i; + racp_find_report_num += 1; + } + } +} + +void app_ghss_handle_racp(uint8_t *p_value) +{ + T_GHSS_RACP_OPCODE opcode = (T_GHSS_RACP_OPCODE)p_value[0]; + T_GHSS_RACP_OPERATOR operator = (T_GHSS_RACP_OPERATOR)p_value[1]; + ghss_send_racp_length = 2; + APP_PRINT_INFO2("app_ghss_handle_racp Opcode %d, Operator %d", opcode, operator); + + if ((opcode == GHSS_RACP_OPCODE_COMB_REPORT_RECS) || + (opcode == GHSS_RACP_OPCODE_REPORT_NBR_OF_RECS)) + { + if (ghss_link.rcv_ghs_cp == GHSS_GHS_CP_OPCODE_START_SEND_LIVE_OBS) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Server Busy"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_SERVER_BUSY; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + return; + } + + switch (operator) + { + case GHSS_RACP_OPERATOR_NULL: + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Invalid Operator"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_INVALID_OPERATOR; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + break; + + case GHSS_RACP_OPERATOR_ALL_RECS: + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + racp_find_report_num = stored_record_number; + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + } + break; + + case GHSS_RACP_OPERATOR_FIRST: + case GHSS_RACP_OPERATOR_LAST: + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + racp_find_report_num = 1; + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + } + break; + + case GHSS_RACP_OPERATOR_GT_EQ: + { + uint8_t type = p_value[2]; + + if ((type < GHSS_RACP_OPERAND_REC_NUM) || (type > GHSS_RACP_OPERAND_TIME)) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Operand Not Supported"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_OPERAND_NOT_SUPPORTED; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + else if (type == GHSS_RACP_OPERAND_REC_NUM) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + uint32_t min_num; + memcpy(&min_num, &p_value[3], 4); + app_ghss_racp_find_stored_obs_record_by_num(min_num, stored_record_number); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + else if (type == GHSS_RACP_OPERAND_TIME) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + app_ghss_racp_find_stored_obs_record_by_time(&p_value[3], NULL); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + } + break; + + case GHSS_RACP_OPERATOR_LT_EQ: + { + uint8_t type = p_value[2]; + + if ((type < GHSS_RACP_OPERAND_REC_NUM) || (type > GHSS_RACP_OPERAND_TIME)) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Operand Not Supported"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_OPERAND_NOT_SUPPORTED; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + else if (type == GHSS_RACP_OPERAND_REC_NUM) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + uint32_t max_num; + memcpy(&max_num, &p_value[3], 4); + app_ghss_racp_find_stored_obs_record_by_num(0, max_num); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + else if (type == GHSS_RACP_OPERAND_TIME) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + app_ghss_racp_find_stored_obs_record_by_time(NULL, &p_value[3]); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + } + break; + + case GHSS_RACP_OPERATOR_RANGE: + { + uint8_t type = p_value[2]; + + if ((type < GHSS_RACP_OPERAND_REC_NUM) || (type > GHSS_RACP_OPERAND_TIME)) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Operand Not Supported"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_OPERAND_NOT_SUPPORTED; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + else if (type == GHSS_RACP_OPERAND_REC_NUM) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + uint32_t min_num; + uint32_t max_num; + memcpy(&min_num, &p_value[3], 4); + memcpy(&max_num, &p_value[7], 4); + app_ghss_racp_find_stored_obs_record_by_num(min_num, max_num); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + else if (type == GHSS_RACP_OPERAND_TIME) + { + ghss_send_racp.opcode = (T_GHSS_RACP_OPCODE)(opcode + 1); + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + app_ghss_racp_find_stored_obs_record_by_time(&p_value[3], &p_value[9]); + memcpy(ghss_send_racp.operand, &racp_find_report_num, 4); + ghss_send_racp_length += 4; + APP_PRINT_INFO2("app_ghss_handle_racp: type %d, racp_find_report_num %d", type, + racp_find_report_num); + } + } + break; + + default: + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Operator Not Supported"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_OPERATOR_NOT_SUPPORTED; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + break; + } + } + + if (!GHSS_RACP_OPERATION_ACTIVE(opcode)) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: Opcode Not Supported"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_OPCODE_NOT_SUPPORTED; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + ghss_send_racp_length += 2; + } + + if (ghss_send_racp.opcode == GHSS_RACP_OPCODE_COMB_REPORT_RESP) + { + if (racp_find_report_num == 0) + { + APP_PRINT_ERROR0("app_ghss_handle_racp: NO Records Found"); + + ghss_send_racp.opcode = GHSS_RACP_OPCODE_RESP_CODE; + ghss_send_racp.operator = GHSS_RACP_OPERATOR_NULL; + memcpy(ghss_send_racp.operand, &opcode, 1); + T_GHSS_RACP_RESP_CODES operand = GHSS_RACP_RESP_NO_RECS_FOUND; + memcpy(&ghss_send_racp.operand[1], &operand, 1); + } + else + { + ghss_link.send_flag = GHSS_SEND_STORED_HEALTH_OBS_START; + APP_PRINT_INFO1("app_ghss_handle_racp: REPORT NUM %d", racp_find_report_num); + } + } + else if (opcode == GHSS_RACP_OPCODE_ABORT_OPERATION) + { + ghss_link.send_flag = GHSS_SEND_STORED_HEALTH_OBS_END; + } +} + +bool app_set_ghss_health_obs_body(uint16_t length, T_GHSS_HEALTH_OBS_BODY *p_value) +{ + if (((p_value->obs_class_type > GHSS_HOB_CLASS_TYPE_TLV_ENCODED_OBSERVATION) + && (p_value->obs_class_type < GHSS_HOB_CLASS_TYPE_OBSERVATION_BUNDLE)) + || (p_value->obs_class_type == 0)) + { + APP_PRINT_ERROR1("app_set_live_ghss_health_obs_body: Invalid Observation Class Type %d", + p_value->obs_class_type); + return false; + } + + memcpy(&ghss_health_obs_body, p_value, length); + + return true; +} + +bool app_modify_ghss_stored_health_obs_body(T_GHSS_MODIFY_STORED_HOB_TYPE type, uint32_t idx) +{ + switch (type) + { + case GHSS_MODIFY_STORED_HOB_TYPE_ADD: + { + if (idx > GHSS_MAX_STORED_HEALTH_OBS_NUM) + { + APP_PRINT_ERROR1("app_modify_ghss_stored_health_obs_body: Preset index too large, index %d", + idx); + return false; + } + /** Report idx shall be incremented by 1. */ + else if (idx != stored_record_number) + { + APP_PRINT_ERROR1("app_modify_ghss_stored_health_obs_body: Invalid index %d", + idx); + return false; + } + + T_GHSS_STORED_HOB_QUEUE_ELEM *p_new_preset_record = os_mem_alloc(RAM_TYPE_DATA_ON, + sizeof(T_GHSS_STORED_HOB_QUEUE_ELEM)); + if (p_new_preset_record != NULL) + { + p_new_preset_record->report_idx = idx; + memcpy(&p_new_preset_record->ghss_stored_health_obs_body, &ghss_health_obs_body, + sizeof(ghss_health_obs_body)); + os_queue_in(&ghss_stored_hob_record_list, p_new_preset_record); + stored_record_number++; + APP_PRINT_INFO2("ADD STORED OBS: index %d, stored_record_number %d", idx, stored_record_number); + } + else + { + APP_PRINT_ERROR0("app_modify_ghss_stored_health_obs_body: Allocate memory fail"); + return false; + } + + break; + } + + default: + break; + } + + return true; +} + +bool app_ghss_find_stored_health_obs_body_by_idx(uint32_t idx) +{ + T_GHSS_STORED_HOB_QUEUE_ELEM *p_new_preset_record = os_mem_alloc(RAM_TYPE_DATA_ON, + sizeof(T_GHSS_STORED_HOB_QUEUE_ELEM)); + + if (p_new_preset_record != NULL) + { + for (uint32_t i = 0; i < stored_record_number; i++) + { + p_new_preset_record = os_queue_out(&ghss_stored_hob_record_list); + + if (p_new_preset_record->report_idx == idx) + { + memcpy(&ghss_health_obs_body, &p_new_preset_record->ghss_stored_health_obs_body, + sizeof(p_new_preset_record->ghss_stored_health_obs_body)); + } + + os_queue_in(&ghss_stored_hob_record_list, p_new_preset_record); + } + + APP_PRINT_INFO1("app_ghss_find_stored_health_obs_body_by_idx FIND STORED IDX %d", idx); + } + else + { + APP_PRINT_ERROR0("app_ghss_find_stored_health_obs_body_by_idx: Allocate memory fail"); + return false; + } + + return true; +} + +/** + * @brief Format GHSS Health Observation segment value. + * + * + * @param[in] type Report type @ref T_GHSS_OBS_REPORT_TYPE. \n + * Only @ref GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS & @ref GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS takes effect. + * @param[in] idx Report idx of Stored Health Observation Body. + * @param[in] p_value GHSS Health Observation Body value. + * @param[in,out] pp_temp_value Pointer to pointer of Health Observation Body value needs to be sent. + * + * @return void. + */ +uint16_t app_ghss_format_health_obs_sending_value(T_GHSS_OBS_REPORT_TYPE type, uint32_t idx, + T_GHSS_HEALTH_OBS_BODY *p_value, uint8_t **pp_temp_value) +{ + if (ghss_link.p_value != NULL) + { + APP_PRINT_ERROR0("app_ghss_format_health_obs_sending_value: Value already exist"); + return 0; + } + + uint16_t total_length = ghss_format_health_obs_sending_value(type, idx, p_value, + &ghss_link.p_value); + + if (total_length == 0) + { + APP_PRINT_ERROR0("app_ghss_format_health_obs_sending_value: Format FAIL"); + return 0; + } + + if (total_length > (GHSS_MAX_REPORT_MTU_SIZE - 1)) + { + if (total_length % (GHSS_MAX_REPORT_MTU_SIZE - 1) == 0) + { + ghss_link.segment_number = total_length / (GHSS_MAX_REPORT_MTU_SIZE - 1); + } + else + { + ghss_link.segment_number = total_length / (GHSS_MAX_REPORT_MTU_SIZE - 1) + 1; + } + } + + ghss_link.is_using = true; + + APP_PRINT_INFO2("app_ghss_format_health_obs_sending_value: report type %d, segment_number %d", + type, ghss_link.segment_number); + return total_length; +} + +bool app_ghss_send_health_obs_indication_notification(uint8_t conn_id, T_SERVER_ID service_id, + T_GHSS_OBS_REPORT_TYPE report_type, + T_GATT_PDU_TYPE pdu_type, uint8_t seg_count, + uint32_t report_idx) +{ + bool ret = false; + + T_GHSS_CHAR_OBS_REPORT report_data = {GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS}; + report_data.report_type = report_type; + + if (conn_id != ghss_link.conn_id) + { + APP_PRINT_ERROR1("app_ghss_send_health_obs_indication_notification: Invalid conn_id", conn_id); + return ret; + } + + if (report_type == GHSS_OBS_REPORT_TYPE_STORED_HEALTH_OBS) + { + app_ghss_find_stored_health_obs_body_by_idx(report_idx); + } + + if (ghss_link.is_using == false) + { + if (ghss_link.p_value != NULL) + { + APP_PRINT_ERROR0("app_ghss_send_health_obs_indication_notification: Value already exist"); + return ret; + } + + uint16_t total_length = app_ghss_format_health_obs_sending_value(report_type, report_idx, + &ghss_health_obs_body, + &ghss_link.p_value); + + if (total_length == 0) + { + APP_PRINT_ERROR0("app_ghss_send_health_obs_indication_notification: Format value FAIL"); + return ret; + } + + ghss_link.value_len = total_length; + } + + uint16_t report_mtu = GHSS_MAX_REPORT_MTU_SIZE; + + uint16_t length = ghss_format_health_obs_segment(seg_count, ghss_link.segment_number, report_mtu, + rolling_segment_counter, ghss_link.value_len, ghss_link.p_value, + &ghss_link.p_seg); + + if (length == 0) + { + APP_PRINT_ERROR0("app_ghss_send_health_obs_indication_notification: Format segment FAIL"); + return ret; + } + + report_data.obs_segment.obs_segment_len = length; + report_data.obs_segment.p_obs_segment = ghss_link.p_seg; + + if (pdu_type == GATT_PDU_TYPE_NOTIFICATION) + { + report_data.is_notify = true; + } + else if (pdu_type == GATT_PDU_TYPE_INDICATION) + { + report_data.is_notify = false; + } + + ret = ghss_send_health_obs_report(conn_id, service_id, report_data); + + if (ret) + { + rolling_segment_counter++; + ghss_link.segment_count = seg_count; + + if (ghss_link.p_seg != NULL) + { + os_mem_free(ghss_link.p_seg); + ghss_link.p_seg = NULL; + } + } + + return ret; +} + +bool app_ghss_send_cp_report(uint8_t conn_id, T_SERVER_ID service_id, + T_GHSS_CP_REPORT_TYPE report_type) +{ + bool ret = false; + + T_GHSS_CHAR_CP_REPORT report_data; + report_data.report_type = report_type; + + if (report_type == GHSS_CP_REPORT_TYPE_RACP) + { + report_data.value.report_racp.racp_len = ghss_send_racp_length; + report_data.value.report_racp.p_racp = &ghss_send_racp; + } + else if (report_type == GHSS_CP_REPORT_TYPE_GHS_CP) + { + report_data.value.p_ghs_cp = &ghss_send_ghs_cp; + } + + ret = ghss_send_cp_report(conn_id, service_id, report_data); + + return ret; +} + +T_APP_RESULT app_ghss_handle_indication_notification(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_idx) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + + T_CHAR_UUID char_uuid = gatt_svc_find_char_uuid_by_index(ghss_attr_tbl, attrib_idx, ghss_char_num); + + switch (char_uuid.uu.char_uuid16) + { + case GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT: + { + if (ghss_link.send_flag == GHSS_SEND_STORED_HEALTH_OBS_START) + { + data_uart_print("Stop sending stored health obs\r\n"); + ghss_link.send_flag = GHSS_SEND_STORED_HEALTH_OBS_END; + } + break; + } + + case GATT_UUID_CHAR_GHS_CONTROL_POINT: + { + if (ghss_link.send_flag == GHSS_SEND_LIVE_HEALTH_OBS_START) + { + data_uart_print("Start sending live health obs\r\n"); + } + break; + } + + case GATT_UUID_CHAR_LIVE_HEALTH_OBSERVATIONS: + case GATT_UUID_CHAR_STORED_HEALTH_OBSERVATIONS: + { + if (conn_id == ghss_link.conn_id) + { + if (ghss_link.segment_count == ghss_link.segment_number - 1) + { + data_uart_print("Send health obs value complete\r\n"); + + if (ghss_link.p_value != NULL) + { + os_mem_free(ghss_link.p_value); + ghss_link.p_value = NULL; + } + ghss_link.is_using = false; + ghss_link.segment_count = 0; + ghss_link.segment_number = 0; + ghss_link.value_len = 0; + } + } + } + break; + + default: + break; + } + + return result; +} + +T_APP_RESULT app_ghss_handle_server_cb(uint8_t conn_id, uint8_t type, void *p_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + + APP_PRINT_INFO2("app_ghss_handle_server_cb: conn_id %d, type %d", conn_id, type); + ghss_link.conn_id = conn_id; + + switch (type) + { + case GATT_MSG_GHSS_SERVER_WRITE_IND: + { + T_GHSS_SERVER_WRITE_IND *p_write_ind = (T_GHSS_SERVER_WRITE_IND *)p_data; + + switch (p_write_ind->char_uuid) + { + case GATT_UUID_CHAR_RECORD_ACCESS_CONTROL_POINT: + { + /* Make sure Control Point is not "Process already in progress". */ + if ((p_write_ind->data.ghss_racp.opcode == GHSS_RACP_OPCODE_COMB_REPORT_RECS) + && (ghss_link.rcv_racp_opcode == p_write_ind->data.ghss_racp.opcode) + && (p_write_ind->data.ghss_racp.opcode != GHSS_RACP_OPCODE_ABORT_OPERATION) + && (ghss_link.send_flag == GHSS_SEND_STORED_HEALTH_OBS_START)) + { + result = APP_RESULT_PROC_ALREADY_IN_PROGRESS; + } + else + { + ghss_link.rcv_racp_opcode = p_write_ind->data.ghss_racp.opcode; + app_ghss_handle_racp((uint8_t *)&p_write_ind->data.ghss_racp); + data_uart_print("Start sending stored health obs\r\n"); + } + } + break; + + case GATT_UUID_CHAR_GHS_CONTROL_POINT: + { + ghss_link.rcv_ghs_cp = p_write_ind->data.ghss_ghs_cp; + if (ghss_link.rcv_ghs_cp == GHSS_GHS_CP_OPCODE_START_SEND_LIVE_OBS) + { + ghss_link.send_flag = GHSS_SEND_LIVE_HEALTH_OBS_START; + } + else if (ghss_link.rcv_ghs_cp == GHSS_GHS_CP_OPCODE_STOP_SEND_LIVE_OBS) + { + ghss_link.send_flag = GHSS_SEND_LIVE_HEALTH_OBS_END; + } + ghss_send_ghs_cp = GHSS_GHS_CP_OPCODE_SUCCESS; + } + break; + + default: + break; + } + } + break; + + default: + break; + } + + return result; +} + +void app_ghss_handle_conn_state(uint8_t conn_id) +{ + if (conn_id == ghss_link.conn_id) + { + ghss_link.rcv_racp_opcode = GHSS_RACP_OPCODE_RESERVED; + ghss_link.rcv_ghs_cp = GHSS_GHS_CP_OPCODE_RFU; + ghss_link.send_flag = GHSS_SEND_HEALTH_OBS_IDLE; + ghss_link.is_using = false; + ghss_link.segment_number = 0; + ghss_link.segment_count = 0; + ghss_link.value_len = 0; + + if (ghss_link.p_value != NULL) + { + os_mem_free(ghss_link.p_value); + ghss_link.p_value = NULL; + } + + if (ghss_link.p_seg != NULL) + { + os_mem_free(ghss_link.p_seg); + ghss_link.p_seg = NULL; + } + } +} + +void app_ghss_queue_list_init(void) +{ + os_queue_init(&ghss_stored_hob_record_list); +} + diff --git a/src/ble/sample/ghss_sample.h b/src/ble/sample/ghss_sample.h new file mode 100644 index 0000000..5c83ab1 --- /dev/null +++ b/src/ble/sample/ghss_sample.h @@ -0,0 +1,292 @@ +/** +***************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file ghss_sample.h + * @brief Head file for using Generic Health Sensor Service. + * @details GHSS data structs and external functions declaration developed based on bt_gatt_svc.h. + * @author + * @date + * @version v1.0 + * ************************************************************************************* + */ + +/* Define to prevent recursive inclusion */ +#ifndef _GHSS_SAMPLE_H_ +#define _GHSS_SAMPLE_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Add Includes here */ +#include "ghss_gatt_srv.h" + +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup GHSS_SAMPLE_Exported_Macros GHSS Sample Exported Macros + * @brief + * @{ + */ +/** @defgroup GHSS_SAMPLE_DEF + * @brief GHSS service sample defined numerical value + * @{ + */ +#define GHSS_MAX_STORED_HEALTH_OBS_NUM 5 +#define GHSS_MAX_REPORT_MTU_SIZE 20 +/** @} End of GHSS_SAMPLE_DEF */ + +/** End of GHSS_SAMPLE_Exported_Macros +* @} +*/ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup GHSS_SAMPLE_Exported_Types GHSS Sample Exported Types + * @brief + * @{ + */ + +/** @brief GHSS sending Health Observations flag. */ +typedef enum +{ + GHSS_SEND_HEALTH_OBS_IDLE, + GHSS_SEND_LIVE_HEALTH_OBS_START, + GHSS_SEND_LIVE_HEALTH_OBS_END, + GHSS_SEND_STORED_HEALTH_OBS_START, + GHSS_SEND_STORED_HEALTH_OBS_END, +} T_GHSS_SEND_HEALTH_OBS_FLAG; + +/** @brief GHSS link manager. */ +typedef struct +{ + uint8_t conn_id; + T_GHSS_RACP_OPCODE rcv_racp_opcode; + T_GHSS_GHS_CP_OPCODE rcv_ghs_cp; + T_GHSS_SEND_HEALTH_OBS_FLAG send_flag; + bool is_using; + uint16_t segment_number; + uint16_t segment_count; + uint16_t value_len; + uint8_t *p_value; + uint8_t *p_seg; +} T_GHSS_LINK_MGR; + +/** @brief GHSS modify Stored Health Observation Body list type. */ +typedef enum +{ + GHSS_MODIFY_STORED_HOB_TYPE_ADD = 0x01, +} T_GHSS_MODIFY_STORED_HOB_TYPE; + +/** @brief GHSS Stored Health Observation Body list. */ +typedef struct t_ghss_stored_hob_queue_elem +{ + struct t_ghss_stored_hob_queue_elem *p_next; + uint32_t report_idx; + T_GHSS_HEALTH_OBS_BODY ghss_stored_health_obs_body; +} T_GHSS_STORED_HOB_QUEUE_ELEM; + +/** End of GHSS_SAMPLE_Exported_Types +* @} +*/ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup GHSS_SAMPLE_Exported_Functions GHSS Sample Exported Functions + * @brief + * @{ + */ +/** + * @brief Set GHSS Health Observation Body. + * + * @param[in] length Length of data to write. + * @param[in] p_value Pointer to data to write @ref T_GHSS_HEALTH_OBS_BODY. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + * + * Example usage + * \code{.c} + void test(void) + { + T_GHSS_HEALTH_OBS_BODY ghss_health_obs_body; + T_GHSS_HOB_CLASS_TYPE obs_class_type = GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION; + + ghss_health_obs_body.obs_class_type = obs_class_type; + uint16_t flags = 0x43; + memcpy(&ghss_health_obs_body.flags, &flags, 2); + ghss_health_obs_body.obs_type = 0x24bb8; + ghss_health_obs_body.time_stamp.flags = 0x22; + uint8_t time_value[6] = {0, 0, 0x29, 0x2b, 0x9d, 0x72}; + memcpy(ghss_health_obs_body.time_stamp.time_value, time_value, 6); + ghss_health_obs_body.time_stamp.time_sync_source_type = 6; + ghss_health_obs_body.time_stamp.tz_dst_offset = 0; + ghss_health_obs_body.suppl_info.count = 1; + ghss_health_obs_body.suppl_info.p_codes = codes; + switch (obs_class_type) + { + case GHSS_HOB_CLASS_TYPE_NUMERIC_OBSERVATION: + { + ghss_health_obs_body.obs_value.numeric_obs.unit_code = 0x220; + ghss_health_obs_body.obs_value.numeric_obs.value = 0x62; + } + break; + ... + } + + app_set_ghss_health_obs_body(sizeof(ghss_health_obs_body), &ghss_health_obs_body); + } + * \endcode + */ +bool app_set_ghss_health_obs_body(uint16_t length, T_GHSS_HEALTH_OBS_BODY *p_value); + +/** + * @brief Modify Stored Health Observation Body list. + * + * @param[in] type Modify type @ref T_GHSS_MODIFY_STORED_HOB_TYPE. \n + * If type equals @ref GHSS_MODIFY_STORED_HOB_TYPE_ADD, the latest Health Observation Body set by @ref app_set_ghss_health_obs_body will be added to the list. + * @param[in] idx Report idx of Stored Health Observation Body. Report idx should be increased by one for each subsequently generated observation. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool app_modify_ghss_stored_health_obs_body(T_GHSS_MODIFY_STORED_HOB_TYPE type, uint32_t idx); + +/** + * @brief Find Stored Health Observation Body list by report idx. + * + * @param[in] idx Report idx of Stored Health Observation Body. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool app_ghss_find_stored_health_obs_body_by_idx(uint32_t idx); + +/** + * @brief Report Health Observations with a notification or indication. + * + * @param[in] conn_id Connection ID. + * @param[in] service_id Service ID. + * @param[in] report_type Report type @ref T_GHSS_OBS_REPORT_TYPE. + * @param[in] pdu_type GATT PDU type. + * @param[in] seg_count Current count of Health Observation segment needs to be sent. + * @param[in] report_idx Report idx of Stored Health Observation Body. \n + * If type equals @ref GHSS_OBS_REPORT_TYPE_LIVE_HEALTH_OBS, this parameter is not effective. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool app_ghss_send_health_obs_indication_notification(uint8_t conn_id, T_SERVER_ID service_id, + T_GHSS_OBS_REPORT_TYPE report_type, + T_GATT_PDU_TYPE pdu_type, uint8_t seg_count, + uint32_t report_idx); + +/** + * @brief Report Control Point with an indication. + * + * @param[in] conn_id Connection ID. + * @param[in] service_id Service ID. + * @param[in] report_type Report type @ref T_GHSS_CP_REPORT_TYPE. + * + * @return Operation result. + * @retval true Operation success. + * @retval false Operation failure. + */ +bool app_ghss_send_cp_report(uint8_t conn_id, T_SERVER_ID service_id, + T_GHSS_CP_REPORT_TYPE report_type); + +/** + * @brief Handle GHSS server callback. + * + * @param[in] conn_id Connection ID. + * @param[in] service_id Service ID. + * @param[in] attrib_idx Attribute index. + * + * @return Operation result. + * @retval APP_RESULT_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_APP_RESULT app_ghss_handle_indication_notification(uint8_t conn_id, T_SERVER_ID service_id, + uint16_t attrib_idx); + +/** + * @brief Handle GHSS server callback. + * + * @param[in] conn_id Connection ID. + * @param[in] type Callback message type @ref GHSS_SVC_CB_MSG. + * @param[in] p_data Pointer to data to handle. + * + * @return Operation result. + * @retval APP_RESULT_SUCCESS Operation success. + * @retval Others Operation failure. + */ +T_APP_RESULT app_ghss_handle_server_cb(uint8_t conn_id, uint8_t type, void *p_data); + +/** + * @brief Handle connection state GAP_CONN_STATE_CONNECTED. + * + * @param[in] conn_id Connection ID. + * + * @return void. + * + * Example usage + * \code{.c} + T_APP_RESULT app_handle_bt_status_message(T_IO_MSG *p_io_msg) + { + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_GAP_MSG gap_msg; + uint8_t conn_id; + memcpy(&gap_msg, &p_io_msg->u.param, sizeof(p_io_msg->u.param)); + uint16_t subtype = p_io_msg->subtype; + + switch (subtype) + { + case GAP_MSG_LE_CONN_STATE_CHANGE: + if (gap_msg.msg_data.gap_conn_state_change.new_state == GAP_CONN_STATE_CONNECTED) + { + app_ghss_handle_conn_state(gap_msg.msg_data.gap_conn_state_change.conn_id); + } + break; + ... + } + ... + } + * \endcode + */ +void app_ghss_handle_conn_state(uint8_t conn_id); + +/** + * @brief Init GHSS queue lists. + * + * @return void. + * + * Example usage + * \code{.c} + void profile_init() + { + server_init(service_num); + ghss_id = ghss_reg_srv(app_ghss_handle_server_cb); + app_ghss_queue_list_init(); + } + * \endcode + */ +void app_ghss_queue_list_init(void); + +/** @} End of GHSS_SAMPLE_Exported_Functions */ + +/** @} End of GHSS_SAMPLE */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _GHSS_SAMPLE_H_ */ + diff --git a/src/ble/upperstack_lib.c b/src/ble/upperstack_lib.c new file mode 100644 index 0000000..9a4dec8 --- /dev/null +++ b/src/ble/upperstack_lib.c @@ -0,0 +1,9970 @@ +/* http://srecord.sourceforge.net/ */ +#include "mem_config.h" +__attribute__((at(UPPERSTACK_FLASH_ADDR))) __attribute__((used)) const unsigned char +upperstack_lib_img[] = +{ + 0x09, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x10, 0x00, 0x90, 0x5A, 0x51, 0xFF, 0x97, 0x64, 0x65, 0x76, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB5, 0xF6, 0xF7, + 0x61, 0xDF, 0x07, 0x4B, 0x07, 0xA2, 0x0A, 0xA1, 0x4F, 0xF0, 0x04, 0x50, + 0xF9, 0xF7, 0x9C, 0xDD, 0x00, 0xF0, 0xB2, 0xF8, 0x00, 0xF0, 0xB5, 0xF8, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x9E, 0xB8, 0x5A, 0x51, 0xFF, 0x97, + 0x30, 0x2E, 0x30, 0x2E, 0x31, 0x2E, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x70, 0x70, 0x65, 0x72, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x20, 0x56, + 0x65, 0x72, 0x3A, 0x20, 0x25, 0x73, 0x2C, 0x20, 0x47, 0x43, 0x49, 0x44, + 0x3A, 0x20, 0x30, 0x78, 0x25, 0x78, 0x00, 0x00, 0x40, 0xBA, 0x70, 0x47, + 0xC0, 0xBA, 0x70, 0x47, 0x4F, 0xEA, 0x30, 0x00, 0x70, 0x47, 0x43, 0x1A, + 0x28, 0xBF, 0x9A, 0x42, 0x40, 0xF2, 0xAA, 0x80, 0x03, 0x2A, 0x10, 0x44, + 0x11, 0x44, 0x40, 0xF2, 0x26, 0x80, 0x10, 0xF0, 0x03, 0x0F, 0x1E, 0xBF, + 0x11, 0xF8, 0x01, 0x3D, 0x52, 0x1E, 0x00, 0xF8, 0x01, 0x3D, 0x10, 0xF0, + 0x03, 0x0F, 0x7F, 0xF4, 0xF6, 0xAF, 0x11, 0xF0, 0x03, 0x03, 0x00, 0xF0, + 0x3B, 0x80, 0x08, 0x3A, 0xC0, 0xF0, 0x0B, 0x80, 0x51, 0xF8, 0x04, 0x3D, + 0x08, 0x3A, 0x51, 0xF8, 0x04, 0xCD, 0x40, 0xF8, 0x04, 0x3D, 0x40, 0xF8, + 0x04, 0xCD, 0xFF, 0xF7, 0xF3, 0xBF, 0x12, 0x1D, 0x5C, 0xBF, 0x51, 0xF8, + 0x04, 0x3D, 0x40, 0xF8, 0x04, 0x3D, 0xAF, 0xF3, 0x00, 0x80, 0xD2, 0x07, + 0x24, 0xBF, 0x11, 0xF8, 0x01, 0x3D, 0x11, 0xF8, 0x01, 0xCD, 0x48, 0xBF, + 0x11, 0xF8, 0x01, 0x2C, 0x24, 0xBF, 0x00, 0xF8, 0x01, 0x3D, 0x00, 0xF8, + 0x01, 0xCD, 0x48, 0xBF, 0x00, 0xF8, 0x01, 0x2C, 0x70, 0x47, 0x43, 0x1A, + 0x28, 0xBF, 0x9A, 0x42, 0x40, 0xF2, 0x6A, 0x80, 0x10, 0x44, 0x10, 0xF0, + 0x03, 0x0F, 0x11, 0x44, 0x1E, 0xBF, 0x11, 0xF8, 0x01, 0x3D, 0x52, 0x1E, + 0x00, 0xF8, 0x01, 0x3D, 0x10, 0xF0, 0x03, 0x0F, 0x7F, 0xF4, 0xF6, 0xAF, + 0x10, 0x3A, 0xC0, 0xF0, 0x0A, 0x80, 0x10, 0xB5, 0x31, 0xE9, 0x18, 0x50, + 0x10, 0x3A, 0x20, 0xE9, 0x18, 0x50, 0xBF, 0xF4, 0xF9, 0xAF, 0xBD, 0xE8, + 0x10, 0x40, 0x53, 0x07, 0x24, 0xBF, 0x31, 0xE9, 0x08, 0x10, 0x20, 0xE9, + 0x08, 0x10, 0x44, 0xBF, 0x51, 0xF8, 0x04, 0x3D, 0x40, 0xF8, 0x04, 0x3D, + 0x12, 0xF0, 0x03, 0x0F, 0x08, 0xBF, 0x70, 0x47, 0xD2, 0x07, 0x28, 0xBF, + 0x31, 0xF8, 0x02, 0x3D, 0x48, 0xBF, 0x11, 0xF8, 0x01, 0x2C, 0x28, 0xBF, + 0x20, 0xF8, 0x02, 0x3D, 0x48, 0xBF, 0x00, 0xF8, 0x01, 0x2C, 0x70, 0x47, + 0x10, 0xB5, 0x00, 0x22, 0x03, 0x49, 0x04, 0x48, 0xF9, 0xF7, 0x47, 0xDD, + 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x84, 0xBE, 0x00, 0x00, 0xC0, 0x08, + 0x02, 0x30, 0x10, 0x21, 0x08, 0x48, 0x09, 0x49, 0x09, 0x4A, 0x2B, 0xF4, + 0x4E, 0xB6, 0x10, 0xB5, 0x08, 0x48, 0x09, 0x49, 0x09, 0x4A, 0x2B, 0xF4, + 0x48, 0xF6, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x48, 0x08, 0x49, 0x2B, 0xF4, + 0xC1, 0xB6, 0x00, 0x00, 0x00, 0x74, 0x20, 0x00, 0xD0, 0xB5, 0x82, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x20, 0x00, 0xD0, 0xB5, 0x82, 0x00, + 0xD0, 0x00, 0x00, 0x00, 0xD0, 0x74, 0x20, 0x00, 0x40, 0x05, 0x00, 0x00, + 0x2B, 0xF4, 0x2F, 0xB6, 0x2B, 0xF4, 0x72, 0xB6, 0x30, 0xB5, 0x89, 0xB0, + 0x04, 0x46, 0x01, 0x25, 0x20, 0x22, 0x0C, 0xA1, 0x68, 0x46, 0x2B, 0xF4, + 0x69, 0xF6, 0x22, 0x46, 0x69, 0x46, 0x10, 0x46, 0xFA, 0xF7, 0x1D, 0xDF, + 0x00, 0x21, 0x60, 0x5C, 0x40, 0x1C, 0x60, 0x54, 0x49, 0x1C, 0xC9, 0xB2, + 0x10, 0x29, 0xF8, 0xD3, 0x22, 0x46, 0x69, 0x46, 0x10, 0x46, 0xFA, 0xF7, + 0xE2, 0xDE, 0x09, 0xB0, 0x28, 0x46, 0x30, 0xBD, 0x97, 0x86, 0xC1, 0x98, + 0x70, 0xD3, 0x4D, 0xCF, 0xAF, 0xDA, 0x11, 0x3A, 0x80, 0xBC, 0xD1, 0x2A, + 0x4B, 0x1F, 0x9B, 0xD6, 0x4B, 0xA7, 0x4E, 0xA2, 0x96, 0x41, 0xB1, 0x35, + 0xFD, 0xC4, 0x27, 0x6B, 0x1C, 0xB5, 0x01, 0x24, 0x04, 0x23, 0x12, 0x28, + 0x24, 0xD0, 0x12, 0xDC, 0x09, 0x28, 0x48, 0xD0, 0x08, 0xDC, 0x01, 0x28, + 0x39, 0xD0, 0x03, 0x28, 0x3A, 0xD0, 0x05, 0x28, 0x3B, 0xD0, 0x07, 0x28, + 0x2A, 0xD1, 0x3B, 0xE0, 0x0B, 0x28, 0x3F, 0xD0, 0x0D, 0x28, 0x3D, 0xD0, + 0x11, 0x28, 0x23, 0xD1, 0x31, 0xE0, 0x1B, 0x28, 0x3E, 0xD0, 0x06, 0xDC, + 0x16, 0x28, 0x1F, 0xD0, 0x17, 0x28, 0x36, 0xD0, 0x18, 0x28, 0x19, 0xD1, + 0x1D, 0xE0, 0x1D, 0x28, 0x34, 0xD0, 0x52, 0x28, 0x02, 0xD0, 0xD2, 0x28, + 0x12, 0xD1, 0x06, 0xE0, 0x03, 0x29, 0x0F, 0xD2, 0x00, 0x24, 0x12, 0x28, + 0x04, 0xD1, 0x13, 0x60, 0x02, 0xE0, 0x0F, 0x29, 0x08, 0xDA, 0x00, 0x24, + 0xCD, 0xE9, 0x00, 0x12, 0x03, 0x46, 0x03, 0x22, 0x12, 0x49, 0x13, 0x48, + 0xF9, 0xF7, 0xAF, 0xDC, 0x20, 0x46, 0x1C, 0xBD, 0x05, 0x29, 0x02, 0xD3, + 0xFA, 0xE7, 0x02, 0x29, 0xF8, 0xD0, 0x00, 0x24, 0xE9, 0xE7, 0x05, 0x29, + 0xEB, 0xD1, 0xF3, 0xE7, 0x03, 0x29, 0xE8, 0xD1, 0xF0, 0xE7, 0x06, 0x29, + 0xE5, 0xDB, 0xED, 0xE7, 0x05, 0x29, 0xE2, 0xDB, 0xEA, 0xE7, 0x04, 0x29, + 0xDF, 0xDB, 0xE7, 0xE7, 0x00, 0x29, 0xDC, 0xD0, 0xE4, 0xE7, 0x05, 0x29, + 0xD9, 0xD3, 0xE1, 0xE7, 0x03, 0x29, 0xD6, 0xD3, 0xDE, 0xE7, 0x00, 0x00, + 0xA4, 0x47, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, + 0x03, 0x29, 0x29, 0xD0, 0x14, 0x29, 0x27, 0xD0, 0x15, 0x29, 0x25, 0xD0, + 0x60, 0x68, 0x82, 0x79, 0x50, 0x1C, 0xC3, 0xB2, 0x19, 0x29, 0x1F, 0xD8, + 0xC8, 0x07, 0x1D, 0xD0, 0x0F, 0x48, 0x01, 0x2B, 0x12, 0xD0, 0x01, 0x29, + 0x18, 0xD0, 0x8B, 0x42, 0x16, 0xD0, 0x0B, 0x46, 0x00, 0x92, 0x02, 0x22, + 0x0B, 0x49, 0xF9, 0xF7, 0x6C, 0xDC, 0x00, 0x21, 0x20, 0x46, 0x00, 0xF0, + 0x75, 0xFF, 0x61, 0x68, 0x00, 0x20, 0x88, 0x71, 0x00, 0x20, 0x38, 0xBD, + 0x0B, 0x46, 0x05, 0x49, 0x00, 0x92, 0x02, 0x22, 0x54, 0x39, 0xF9, 0xF7, + 0x5C, 0xDC, 0xF5, 0xE7, 0x01, 0x20, 0x38, 0xBD, 0x00, 0x38, 0x10, 0x21, + 0x50, 0x47, 0xC0, 0x08, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x21, 0x00, 0xF0, + 0x5D, 0xFF, 0x00, 0x21, 0x20, 0x46, 0x0A, 0xF0, 0x19, 0xFC, 0x00, 0x20, + 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x46, 0x48, 0x78, 0x0C, 0x46, 0x02, 0x28, + 0x0E, 0xD0, 0x00, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x4D, 0xFF, 0x69, 0x68, + 0x00, 0x20, 0x88, 0x71, 0x01, 0x46, 0x23, 0x79, 0x62, 0x78, 0x28, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x09, 0xF0, 0x58, 0xBF, 0x69, 0x68, 0xC8, 0x79, + 0x00, 0x28, 0x01, 0xD0, 0x40, 0x1E, 0xC8, 0x71, 0x70, 0xBD, 0x10, 0xB5, + 0x82, 0x68, 0x00, 0x24, 0x32, 0xF8, 0x08, 0x3F, 0x0B, 0xB1, 0x0E, 0x24, + 0x06, 0xE0, 0x44, 0xF2, 0x05, 0x03, 0x13, 0x80, 0x49, 0x78, 0x00, 0x8E, + 0x03, 0xF0, 0xC0, 0xF8, 0x20, 0x46, 0x10, 0xBD, 0x70, 0xB5, 0x04, 0x46, + 0x00, 0x21, 0x00, 0xF0, 0x25, 0xFF, 0x60, 0x68, 0x00, 0x25, 0x85, 0x71, + 0x21, 0x8E, 0x28, 0x46, 0x03, 0xF0, 0xE4, 0xFE, 0x60, 0x68, 0x05, 0x81, + 0x70, 0xBD, 0x7C, 0xB5, 0x05, 0x46, 0x04, 0x20, 0x14, 0x46, 0x08, 0x2A, + 0x10, 0xD3, 0x48, 0x78, 0x8A, 0x78, 0x0B, 0x79, 0x00, 0xEB, 0x02, 0x20, + 0xCA, 0x78, 0x00, 0x04, 0x02, 0xEB, 0x03, 0x22, 0x00, 0x0C, 0x92, 0xB2, + 0x01, 0xD0, 0x90, 0x42, 0x03, 0xD9, 0x01, 0x21, 0x41, 0xEA, 0x00, 0x40, + 0x7C, 0xBD, 0x4B, 0x79, 0x8E, 0x79, 0xC9, 0x1D, 0xE4, 0x1F, 0xCD, 0xE9, + 0x00, 0x41, 0x03, 0xEB, 0x06, 0x23, 0x01, 0x46, 0x9B, 0xB2, 0x28, 0x46, + 0x0A, 0xF0, 0x9E, 0xFD, 0x7C, 0xBD, 0x0B, 0x46, 0x52, 0x1E, 0x91, 0x08, + 0x04, 0x22, 0x5B, 0x1C, 0x00, 0xF0, 0x4F, 0xB9, 0x30, 0xB4, 0x04, 0x46, + 0x04, 0x20, 0x0B, 0x46, 0x05, 0x2A, 0x10, 0xD1, 0x58, 0x78, 0x99, 0x78, + 0x1A, 0x79, 0x00, 0xEB, 0x01, 0x20, 0x01, 0x04, 0xD8, 0x78, 0x09, 0x0C, + 0x00, 0xEB, 0x02, 0x20, 0x82, 0xB2, 0x01, 0xD0, 0x91, 0x42, 0x04, 0xD9, + 0x01, 0x20, 0x40, 0xEA, 0x01, 0x40, 0x30, 0xBC, 0x70, 0x47, 0x20, 0x46, + 0x30, 0xBC, 0x0A, 0xF0, 0xA9, 0xBD, 0x30, 0xB4, 0x94, 0x1E, 0x4A, 0x78, + 0x01, 0x2A, 0x07, 0xD0, 0x12, 0x22, 0x94, 0xFB, 0xF2, 0xF4, 0x8B, 0x1C, + 0x21, 0x46, 0x30, 0xBC, 0x00, 0xF0, 0x25, 0xB9, 0x04, 0x22, 0xF6, 0xE7, + 0xF8, 0xB5, 0x05, 0x46, 0x03, 0x20, 0x0C, 0x46, 0x16, 0x46, 0x13, 0x46, + 0x00, 0x90, 0x02, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF9, 0xF7, 0xA9, 0xDB, + 0x03, 0x2E, 0x01, 0xD2, 0x04, 0x20, 0xF8, 0xBD, 0x29, 0x8D, 0x28, 0x46, + 0x00, 0xF0, 0x8F, 0xFB, 0x60, 0x78, 0xA1, 0x78, 0x00, 0xEB, 0x01, 0x20, + 0x81, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x02, 0xFE, 0x00, 0x20, 0xF8, 0xBD, + 0xC4, 0x46, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x42, 0x68, 0xD3, 0x79, + 0x00, 0x2B, 0x08, 0xD0, 0x5B, 0x1E, 0xD3, 0x71, 0x4A, 0x78, 0x89, 0x78, + 0x02, 0xEB, 0x01, 0x21, 0x89, 0xB2, 0x00, 0xF0, 0xEF, 0xBD, 0x70, 0x47, + 0x38, 0xB5, 0xD3, 0x1E, 0x4A, 0x78, 0x8C, 0x78, 0x02, 0xEB, 0x04, 0x22, + 0xCC, 0x1C, 0x00, 0x94, 0x09, 0x78, 0x92, 0xB2, 0x1B, 0x29, 0x03, 0xD0, + 0x00, 0x21, 0x0B, 0xF0, 0x51, 0xF8, 0x38, 0xBD, 0x01, 0x21, 0xFA, 0xE7, + 0x7C, 0xB5, 0x01, 0x24, 0x1C, 0x70, 0x4C, 0x78, 0x8E, 0x78, 0x4D, 0x1D, + 0x04, 0xEB, 0x06, 0x24, 0xCE, 0x78, 0x09, 0x79, 0x24, 0x04, 0x06, 0xEB, + 0x01, 0x21, 0x24, 0x0C, 0x89, 0xB2, 0xA2, 0xF1, 0x05, 0x02, 0x06, 0xD0, + 0xCD, 0xE9, 0x00, 0x53, 0x0B, 0x46, 0x21, 0x46, 0x0B, 0xF0, 0x56, 0xF8, + 0x7C, 0xBD, 0x01, 0x20, 0x7C, 0xBD, 0x70, 0xB5, 0x0C, 0x46, 0x16, 0x46, + 0x05, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x5E, 0xFE, 0x69, 0x68, 0x00, 0x20, + 0x72, 0x1F, 0x88, 0x71, 0xE0, 0x78, 0x21, 0x79, 0x63, 0x1D, 0x00, 0xEB, + 0x01, 0x20, 0x81, 0xB2, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x0B, 0xF0, + 0x7B, 0xB8, 0x03, 0x46, 0x04, 0x20, 0x05, 0x2A, 0x0C, 0xD1, 0x48, 0x78, + 0x8A, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x00, 0x04, 0x00, 0x0C, 0x04, 0xD0, + 0x0A, 0x46, 0x02, 0x21, 0x18, 0x46, 0x0B, 0xF0, 0xE3, 0xB9, 0x01, 0x20, + 0x70, 0x47, 0x70, 0xB5, 0x0E, 0x46, 0x15, 0x46, 0x04, 0x46, 0x00, 0x21, + 0x00, 0xF0, 0x36, 0xFE, 0x61, 0x68, 0x00, 0x20, 0x73, 0x1C, 0x88, 0x71, + 0x6A, 0x1E, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x02, 0x21, 0x0B, 0xF0, + 0x7F, 0xBA, 0x38, 0xB5, 0x04, 0x46, 0x04, 0x20, 0x53, 0x1F, 0x02, 0x2B, + 0x01, 0xD0, 0x10, 0x2B, 0x10, 0xD1, 0x48, 0x78, 0x8A, 0x78, 0x0D, 0x79, + 0x00, 0xEB, 0x02, 0x20, 0xCA, 0x78, 0x00, 0x04, 0x02, 0xEB, 0x05, 0x22, + 0x00, 0x0C, 0x92, 0xB2, 0x01, 0xD0, 0x90, 0x42, 0x03, 0xD9, 0x01, 0x21, + 0x41, 0xEA, 0x00, 0x40, 0x38, 0xBD, 0x49, 0x1D, 0x00, 0x91, 0x01, 0x46, + 0x20, 0x46, 0x0B, 0xF0, 0x4B, 0xF8, 0x38, 0xBD, 0x30, 0xB4, 0x13, 0x46, + 0x4A, 0x78, 0x9B, 0x1E, 0xB3, 0xFB, 0xF2, 0xF4, 0x8B, 0x1C, 0x21, 0x46, + 0x30, 0xBC, 0x00, 0xF0, 0x60, 0xB8, 0x38, 0xB5, 0x04, 0x46, 0x04, 0x20, + 0x53, 0x1F, 0x02, 0x2B, 0x01, 0xD0, 0x10, 0x2B, 0x10, 0xD1, 0x48, 0x78, + 0x8A, 0x78, 0x0D, 0x79, 0x00, 0xEB, 0x02, 0x20, 0xCA, 0x78, 0x00, 0x04, + 0x02, 0xEB, 0x05, 0x22, 0x00, 0x0C, 0x92, 0xB2, 0x01, 0xD0, 0x90, 0x42, + 0x03, 0xD9, 0x01, 0x21, 0x41, 0xEA, 0x00, 0x40, 0x38, 0xBD, 0x49, 0x1D, + 0x00, 0x91, 0x01, 0x46, 0x20, 0x46, 0x0B, 0xF0, 0x57, 0xF8, 0x38, 0xBD, + 0xF8, 0xB5, 0x0C, 0x46, 0x16, 0x46, 0x05, 0x46, 0x00, 0x21, 0x00, 0xF0, + 0xD7, 0xFD, 0x69, 0x68, 0x00, 0x20, 0xB6, 0x1E, 0x88, 0x71, 0x62, 0x78, + 0xB6, 0xFB, 0xF2, 0xF0, 0xB6, 0xFB, 0xF2, 0xF1, 0x02, 0xFB, 0x10, 0x63, + 0x0B, 0xB1, 0xD3, 0x1A, 0x49, 0x1C, 0xA4, 0x1C, 0x28, 0x46, 0x00, 0x94, + 0x0B, 0xF0, 0x72, 0xF8, 0xF8, 0xBD, 0x03, 0x46, 0x04, 0x20, 0x03, 0x2A, + 0x0C, 0xD1, 0x48, 0x78, 0x8A, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x00, 0x04, + 0x00, 0x0C, 0x04, 0xD0, 0x0A, 0x46, 0x01, 0x21, 0x18, 0x46, 0x0B, 0xF0, + 0x57, 0xB9, 0x01, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x0E, 0x46, 0x15, 0x46, + 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0xAA, 0xFD, 0x61, 0x68, 0x00, 0x20, + 0x73, 0x1C, 0x88, 0x71, 0x6A, 0x1E, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0x21, 0x0B, 0xF0, 0xF3, 0xB9, 0x2D, 0xE9, 0xF0, 0x41, 0x0F, 0x46, + 0x1D, 0x46, 0x16, 0x46, 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x96, 0xFD, + 0x61, 0x68, 0x00, 0x20, 0x2B, 0x46, 0x88, 0x71, 0x32, 0x46, 0x39, 0x46, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x0A, 0xF0, 0x7D, 0xBC, 0x00, 0x00, + 0x2D, 0xE9, 0xFF, 0x4F, 0x89, 0xB0, 0x91, 0x46, 0x01, 0xEB, 0x09, 0x04, + 0x00, 0x25, 0x4F, 0xF0, 0x01, 0x0B, 0x01, 0x95, 0x8D, 0xF8, 0x08, 0xB0, + 0x20, 0x78, 0x8A, 0x46, 0x80, 0x46, 0x00, 0xF0, 0x40, 0x06, 0x2F, 0x46, + 0x43, 0x46, 0x5A, 0x46, 0x7F, 0x49, 0x80, 0x48, 0xF9, 0xF7, 0x65, 0xDA, + 0x41, 0x46, 0x09, 0x98, 0xFF, 0xF7, 0xD8, 0xFD, 0x00, 0x28, 0x6E, 0xD0, + 0x01, 0xAA, 0x40, 0x46, 0x0C, 0x99, 0xFF, 0xF7, 0x6F, 0xFD, 0x00, 0x28, + 0x01, 0x98, 0x01, 0xD0, 0x18, 0xB1, 0xC1, 0xE0, 0x00, 0x28, 0xF2, 0xD0, + 0xBE, 0xE0, 0x40, 0x46, 0xB8, 0xF1, 0x10, 0x0F, 0x39, 0xD0, 0x0B, 0xDC, + 0xB8, 0xF1, 0x0E, 0x0F, 0x23, 0xD2, 0xDF, 0xE8, 0x08, 0xF0, 0x22, 0x71, + 0x2E, 0x76, 0x46, 0x8E, 0x3A, 0x82, 0x40, 0x88, 0x4C, 0x94, 0x52, 0x9A, + 0x19, 0x28, 0x71, 0xD0, 0x09, 0xDC, 0xA8, 0xF1, 0x11, 0x00, 0x08, 0x28, + 0x13, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x6C, 0x49, 0x90, 0x12, 0x12, 0x50, + 0x94, 0x57, 0x1E, 0x28, 0x55, 0xD0, 0x05, 0xDC, 0x1B, 0x28, 0x02, 0xD0, + 0xB8, 0xF1, 0x1D, 0x0F, 0x05, 0xD1, 0x90, 0xE0, 0x52, 0x28, 0x39, 0xD0, + 0xB8, 0xF1, 0xD2, 0x0F, 0x36, 0xD0, 0x5E, 0x49, 0x5E, 0x48, 0x43, 0x46, + 0x02, 0x22, 0x28, 0x31, 0x80, 0x1E, 0x00, 0x96, 0xF9, 0xF7, 0x1D, 0xDA, + 0x00, 0x2E, 0x2A, 0xD1, 0x8B, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x60, 0xFE, 0x3A, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xF1, 0xFE, 0x34, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xFB, 0xFD, 0x2E, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x11, 0xFF, 0x28, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x1C, 0xFE, 0x22, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x41, 0xFF, 0x1C, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xAF, 0xFE, 0x16, 0xE0, 0x80, 0xE0, 0x02, 0xAB, 0x21, 0x46, + 0x0C, 0x9A, 0x09, 0x98, 0x00, 0xF0, 0x84, 0xF8, 0x0E, 0xE0, 0x02, 0xAB, + 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x6F, 0xFE, 0x07, 0xE0, + 0x21, 0x46, 0x09, 0x98, 0xFF, 0xF7, 0xAF, 0xFD, 0x02, 0xE0, 0x09, 0x98, + 0xFF, 0xF7, 0x84, 0xFD, 0x01, 0x90, 0x43, 0xE0, 0x21, 0x46, 0x09, 0x98, + 0xFF, 0xF7, 0x89, 0xFD, 0x3E, 0xE0, 0x21, 0x46, 0x09, 0x98, 0xFF, 0xF7, + 0x3B, 0xFE, 0x39, 0xE0, 0x2D, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xCA, 0xFE, 0x32, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xD9, 0xFD, 0x2C, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xEA, 0xFE, 0x26, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0xF1, 0xFD, 0x20, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x0B, 0xFF, 0x1A, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, + 0xFF, 0xF7, 0x79, 0xFE, 0x14, 0xE0, 0x09, 0x98, 0x00, 0xF0, 0x66, 0xF8, + 0x10, 0xE0, 0x21, 0x46, 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x47, 0xFE, + 0x0A, 0xE0, 0x09, 0x98, 0xFF, 0xF7, 0x7E, 0xFD, 0x06, 0xE0, 0x21, 0x46, + 0x0C, 0x9A, 0x09, 0x98, 0xFF, 0xF7, 0x10, 0xFE, 0x8D, 0xF8, 0x08, 0x70, + 0x01, 0x98, 0xC0, 0xB2, 0x05, 0x28, 0x02, 0xD0, 0x16, 0xE0, 0x06, 0x20, + 0xB2, 0xE7, 0x09, 0x98, 0x00, 0x8E, 0x17, 0xF0, 0xE3, 0xF8, 0x78, 0xB1, + 0x0C, 0x98, 0xAD, 0xF8, 0x12, 0x90, 0xAD, 0xF8, 0x14, 0x00, 0xAD, 0xF8, + 0x10, 0xB0, 0xCD, 0xF8, 0x18, 0xA0, 0x03, 0xA9, 0x09, 0x98, 0x0B, 0xF0, + 0xA1, 0xFE, 0x01, 0x25, 0x8D, 0xF8, 0x08, 0x70, 0x01, 0x98, 0x30, 0xB1, + 0x2D, 0xB9, 0xC3, 0xB2, 0x02, 0x0C, 0x21, 0x78, 0x09, 0x98, 0x00, 0xF0, + 0xBF, 0xF8, 0x9D, 0xF8, 0x08, 0x00, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0xF0, 0x47, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0xFE, 0xB5, 0x1D, 0x46, + 0xD6, 0x1E, 0x01, 0x22, 0x2A, 0x70, 0x0A, 0x78, 0xCB, 0x1C, 0x52, 0x2A, + 0x03, 0xD0, 0xD2, 0x2A, 0x03, 0xD0, 0x01, 0x24, 0x02, 0xE0, 0x02, 0x24, + 0x00, 0xE0, 0x05, 0x24, 0x4A, 0x78, 0x89, 0x78, 0x02, 0xEB, 0x01, 0x21, + 0x0A, 0x04, 0x12, 0x0C, 0x0C, 0xD0, 0x00, 0x21, 0x8D, 0xE8, 0x2A, 0x00, + 0x33, 0x46, 0x21, 0x46, 0x0B, 0xF0, 0x86, 0xF9, 0x02, 0x2C, 0x01, 0xD0, + 0x05, 0x2C, 0x00, 0xD1, 0x00, 0x20, 0xFE, 0xBD, 0x01, 0x20, 0xF7, 0xE7, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x21, 0x00, 0xF0, 0x47, 0xFC, 0x61, 0x68, + 0x00, 0x20, 0x88, 0x71, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x21, + 0x0B, 0xF0, 0x98, 0xBA, 0x2D, 0xE9, 0xF0, 0x5F, 0x04, 0x46, 0xDD, 0xE9, + 0x0B, 0x98, 0x90, 0xF8, 0x2D, 0x00, 0x9B, 0x46, 0x16, 0x46, 0x0F, 0x46, + 0x00, 0x28, 0x6D, 0xD1, 0xDF, 0xF8, 0xDC, 0xA0, 0x40, 0xF2, 0x29, 0x13, + 0x36, 0x4A, 0xBA, 0xF8, 0x08, 0x00, 0x30, 0x44, 0x81, 0xB2, 0x35, 0x48, + 0x00, 0x78, 0x00, 0xF0, 0xAD, 0xFE, 0x05, 0x00, 0x5E, 0xD0, 0xBA, 0xF8, + 0x08, 0x00, 0x07, 0x2F, 0x28, 0x44, 0x38, 0xD0, 0x0F, 0xDC, 0x4F, 0xF0, + 0x01, 0x0C, 0x09, 0xF0, 0xFF, 0x02, 0x4F, 0xEA, 0x19, 0x21, 0x01, 0x2F, + 0x0F, 0xD0, 0x02, 0x23, 0x02, 0x2F, 0x15, 0xD0, 0x03, 0x2F, 0x1E, 0xD0, + 0x05, 0x2F, 0x06, 0xD1, 0x37, 0xE0, 0x0B, 0x2F, 0x42, 0xD0, 0x0D, 0x2F, + 0x40, 0xD0, 0x11, 0x2F, 0x1A, 0xD0, 0x07, 0x70, 0x26, 0xE0, 0x80, 0xF8, + 0x00, 0xC0, 0x80, 0xF8, 0x01, 0xB0, 0x0A, 0x9B, 0x03, 0x71, 0x82, 0x70, + 0xC1, 0x70, 0x1D, 0xE0, 0x61, 0x68, 0xCA, 0x79, 0x52, 0x1C, 0xCA, 0x71, + 0x03, 0x70, 0x94, 0xF8, 0x28, 0x10, 0x41, 0x70, 0x21, 0x8D, 0x09, 0x0A, + 0x02, 0xE0, 0x03, 0x23, 0x03, 0x70, 0x42, 0x70, 0x81, 0x70, 0x0D, 0xE0, + 0x11, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0xB2, 0x1E, 0x00, 0xF8, 0x01, 0x8B, + 0x03, 0xE0, 0x07, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x1A, 0xE0, 0x0D, 0x99, + 0x2B, 0xF4, 0xE5, 0xF1, 0xBA, 0xF8, 0x08, 0x30, 0x32, 0x46, 0x29, 0x46, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x40, 0xBC, 0x05, 0x21, + 0x01, 0x70, 0xB8, 0xF1, 0x04, 0x0F, 0x04, 0xD0, 0x43, 0x70, 0xB2, 0x1E, + 0x80, 0x1C, 0x0D, 0x99, 0xEA, 0xE7, 0x80, 0xF8, 0x01, 0xC0, 0xF8, 0xE7, + 0x00, 0xF8, 0x01, 0x7B, 0x42, 0x46, 0xE2, 0xE7, 0xBD, 0xE8, 0xF0, 0x9F, + 0x98, 0x77, 0x20, 0x00, 0x3D, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x41, 0x1C, 0x46, 0x15, 0x46, 0x07, 0x46, 0x0E, 0x46, + 0x0B, 0x46, 0x03, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xCD, 0xE9, 0x00, 0x45, + 0xF9, 0xF7, 0xA1, 0xD8, 0x00, 0x20, 0x00, 0x94, 0xCD, 0xE9, 0x01, 0x50, + 0x03, 0x90, 0x33, 0x46, 0x05, 0x22, 0x01, 0x21, 0x38, 0x46, 0xFF, 0xF7, + 0x65, 0xFF, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, 0x28, 0x46, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x90, 0xF8, + 0x2D, 0x00, 0x0F, 0x46, 0x00, 0x24, 0x10, 0xB1, 0x40, 0xF6, 0x0E, 0x44, + 0x1E, 0xE0, 0x11, 0x4E, 0x4F, 0xF0, 0x02, 0x08, 0x40, 0xF2, 0xEF, 0x23, + 0x30, 0x89, 0x0F, 0x4A, 0x80, 0x1C, 0x81, 0xB2, 0x0E, 0x48, 0x00, 0x78, + 0x00, 0xF0, 0x0C, 0xFE, 0x01, 0x00, 0x0F, 0xD0, 0x68, 0x68, 0x18, 0x22, + 0x82, 0x71, 0x30, 0x89, 0x08, 0x44, 0x02, 0x70, 0x47, 0x70, 0x33, 0x89, + 0x42, 0x46, 0x28, 0x46, 0x0B, 0xF0, 0xE1, 0xFB, 0x00, 0x21, 0x28, 0x46, + 0x00, 0xF0, 0x30, 0xFB, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0x98, 0x77, 0x20, 0x00, 0x6F, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x1F, 0xB5, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91, 0x02, 0x91, 0x0B, 0x46, + 0x03, 0x91, 0x01, 0x22, 0x19, 0x21, 0xFF, 0xF7, 0x1F, 0xFF, 0x1F, 0xBD, + 0x3E, 0xB5, 0x1C, 0x46, 0x06, 0x9B, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46, + 0x06, 0x22, 0xE1, 0x1D, 0x00, 0xF0, 0xB2, 0xF9, 0x3E, 0xBD, 0x1F, 0xB5, + 0x51, 0x43, 0x00, 0x22, 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x21, + 0x4A, 0x1C, 0x00, 0x23, 0x07, 0x21, 0xFF, 0xF7, 0x07, 0xFF, 0x1F, 0xBD, + 0x3E, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x00, 0x24, 0x0B, 0x46, 0x04, 0x22, + 0x05, 0x21, 0x02, 0x94, 0x00, 0xF0, 0x9A, 0xF9, 0x3E, 0xBD, 0x1F, 0xB5, + 0x14, 0x46, 0x00, 0x22, 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x24, + 0x61, 0x43, 0x8A, 0x1C, 0x00, 0x23, 0x05, 0x21, 0xFF, 0xF7, 0xEE, 0xFE, + 0x1F, 0xBD, 0x1F, 0xB5, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91, 0x02, 0x91, + 0x0B, 0x46, 0x03, 0x91, 0x03, 0x22, 0x02, 0x21, 0xFF, 0xF7, 0xE2, 0xFE, + 0x1F, 0xBD, 0x1F, 0xB5, 0x00, 0x22, 0xCD, 0xE9, 0x00, 0x21, 0x02, 0x92, + 0x13, 0x46, 0x03, 0x92, 0x03, 0x22, 0x11, 0x46, 0xFF, 0xF7, 0xD6, 0xFE, + 0x1F, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x81, 0xB0, 0x9C, 0x46, + 0xDD, 0xE9, 0x0E, 0xA8, 0x14, 0x00, 0x0E, 0x46, 0x01, 0xD0, 0x01, 0x27, + 0x00, 0xE0, 0x00, 0x27, 0x01, 0x98, 0xD8, 0xF8, 0x00, 0x50, 0x90, 0xF8, + 0x2D, 0x00, 0xED, 0x1C, 0x18, 0xB1, 0x01, 0x20, 0x05, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0x4F, 0xF0, 0xFF, 0x3B, 0x87, 0xB1, 0xBC, 0xF8, 0x00, 0x30, + 0x03, 0x2B, 0x05, 0xD2, 0x01, 0x22, 0x29, 0x49, 0x29, 0x48, 0xF8, 0xF7, + 0xE2, 0xDF, 0x1C, 0xE0, 0xE0, 0x1E, 0x18, 0x44, 0xDB, 0x1E, 0x99, 0xB2, + 0xAC, 0xF8, 0x00, 0x10, 0x11, 0xE0, 0xDF, 0xF8, 0x94, 0x90, 0x4F, 0xF4, + 0x77, 0x73, 0x24, 0x4A, 0xB9, 0xF8, 0x08, 0x00, 0x28, 0x44, 0x81, 0xB2, + 0x22, 0x48, 0x00, 0x78, 0x00, 0xF0, 0x62, 0xFD, 0x04, 0x00, 0x06, 0xD0, + 0xB9, 0xF8, 0x08, 0x10, 0x08, 0x19, 0x89, 0x46, 0x1E, 0xB1, 0x1B, 0x21, + 0x02, 0xE0, 0x58, 0x46, 0xD0, 0xE7, 0x1D, 0x21, 0x01, 0x70, 0x80, 0xF8, + 0x01, 0xA0, 0x4F, 0xEA, 0x1A, 0x21, 0x81, 0x70, 0x8F, 0xB1, 0xB6, 0xB1, + 0x4F, 0xF4, 0x7B, 0x70, 0x00, 0x90, 0x14, 0x4B, 0x15, 0x49, 0x20, 0x46, + 0x01, 0x9A, 0x00, 0xF0, 0x0B, 0xFD, 0x60, 0xB9, 0x0D, 0x49, 0x00, 0x22, + 0x30, 0x31, 0x0D, 0x48, 0xF8, 0xF7, 0xA9, 0xDF, 0x05, 0xE0, 0xD8, 0xF8, + 0x00, 0x20, 0xC0, 0x1C, 0x10, 0x99, 0x2B, 0xF4, 0xB6, 0xF0, 0x4B, 0x46, + 0x2A, 0x46, 0x21, 0x46, 0x01, 0x98, 0x0B, 0xF0, 0x14, 0xFB, 0x1E, 0xB9, + 0x01, 0x21, 0x01, 0x98, 0x00, 0xF0, 0x62, 0xFA, 0x00, 0x20, 0xC8, 0xF8, + 0x00, 0x50, 0xA1, 0xE7, 0x70, 0x46, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, + 0x98, 0x77, 0x20, 0x00, 0xB9, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0xC5, 0xF6, 0x80, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x9C, 0x46, + 0x13, 0x46, 0xDD, 0xE9, 0x06, 0x07, 0x95, 0xF8, 0x2D, 0x20, 0x00, 0x26, + 0x12, 0xB1, 0x40, 0xF6, 0x0E, 0x46, 0x1B, 0xE0, 0x3A, 0x88, 0x54, 0x1D, + 0x3C, 0x80, 0x04, 0x88, 0x16, 0x27, 0x64, 0x1F, 0xA4, 0xB2, 0x04, 0x80, + 0x64, 0x44, 0x52, 0x1D, 0x27, 0x70, 0x63, 0x70, 0x1B, 0x0A, 0xA3, 0x70, + 0xE1, 0x70, 0x09, 0x0A, 0x21, 0x71, 0x03, 0x88, 0x61, 0x46, 0x28, 0x46, + 0x0B, 0xF0, 0xDB, 0xFA, 0x68, 0x68, 0x00, 0x21, 0x87, 0x71, 0x28, 0x46, + 0x00, 0xF0, 0x28, 0xFA, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0x2D, 0xE9, 0xF0, 0x5F, 0x82, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0xDD, 0xF8, + 0x28, 0xB0, 0x99, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x00, 0x28, 0x2D, 0xD1, + 0xDF, 0xF8, 0x5C, 0x80, 0x09, 0xF1, 0x05, 0x05, 0x40, 0xF2, 0x9D, 0x33, + 0xB8, 0xF8, 0x08, 0x00, 0x14, 0x4A, 0x28, 0x44, 0x81, 0xB2, 0x14, 0x48, + 0x00, 0x78, 0x00, 0xF0, 0xD3, 0xFC, 0x04, 0x00, 0x1C, 0xD0, 0xB8, 0xF8, + 0x08, 0x00, 0x17, 0x21, 0x20, 0x44, 0x4A, 0x46, 0x00, 0xF8, 0x01, 0x1B, + 0x39, 0x0A, 0x00, 0xF8, 0x01, 0x7B, 0x00, 0xF8, 0x02, 0x1B, 0x31, 0x0A, + 0x00, 0xF8, 0x01, 0x6C, 0x00, 0xF8, 0x01, 0x1B, 0x59, 0x46, 0x2B, 0xF4, + 0x3C, 0xF0, 0xB8, 0xF8, 0x08, 0x30, 0x2A, 0x46, 0x21, 0x46, 0x50, 0x46, + 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x97, 0xBA, 0xBD, 0xE8, 0xF0, 0x9F, + 0x98, 0x77, 0x20, 0x00, 0xA1, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x3E, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x00, 0x24, 0x0B, 0x46, 0x0C, 0x22, + 0x05, 0x21, 0x02, 0x94, 0x00, 0xF0, 0x7A, 0xF8, 0x3E, 0xBD, 0x3E, 0xB5, + 0x06, 0x9C, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46, 0x10, 0x22, 0x61, 0x1D, + 0x00, 0xF0, 0x70, 0xF8, 0x3E, 0xBD, 0x1F, 0xB5, 0x14, 0x46, 0x00, 0x22, + 0x03, 0x93, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x24, 0x61, 0x43, 0x8A, 0x1C, + 0x00, 0x23, 0x11, 0x21, 0xFF, 0xF7, 0xC4, 0xFD, 0x1F, 0xBD, 0x3E, 0xB5, + 0x1C, 0x46, 0x06, 0x9B, 0x8D, 0xE8, 0x1C, 0x00, 0x0B, 0x46, 0x08, 0x22, + 0x61, 0x1D, 0x00, 0xF0, 0x57, 0xF8, 0x3E, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, + 0x81, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0x9B, 0x46, 0x90, 0x46, 0x00, 0x28, + 0x2E, 0xD1, 0x01, 0xFB, 0x08, 0xF7, 0xB9, 0xF8, 0x2A, 0x00, 0xBC, 0x1C, + 0x25, 0x1A, 0x00, 0x2D, 0x01, 0xDD, 0x64, 0x1B, 0x00, 0xE0, 0x00, 0x25, + 0xDF, 0xF8, 0x48, 0xA0, 0x40, 0xF2, 0x67, 0x33, 0x11, 0x4A, 0xBA, 0xF8, + 0x08, 0x00, 0x20, 0x44, 0x81, 0xB2, 0x10, 0x48, 0x00, 0x78, 0x00, 0xF0, + 0x5D, 0xFC, 0x06, 0x00, 0x14, 0xD0, 0xBA, 0xF8, 0x08, 0x00, 0x09, 0x21, + 0x30, 0x44, 0x7A, 0x1B, 0x00, 0xF8, 0x01, 0x1B, 0x59, 0x46, 0x00, 0xF8, + 0x01, 0x8B, 0x2A, 0xF4, 0xCE, 0xF7, 0xBA, 0xF8, 0x08, 0x30, 0x22, 0x46, + 0x31, 0x46, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, 0x0B, 0xF0, 0x29, 0xBA, + 0xBD, 0xE8, 0xF0, 0x9F, 0x98, 0x77, 0x20, 0x00, 0x87, 0xAB, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x0E, 0xB5, 0x00, 0x22, 0x00, 0x92, 0x01, 0x92, + 0x0B, 0x46, 0x02, 0x92, 0x0A, 0x22, 0x03, 0x21, 0x00, 0xF0, 0x0C, 0xF8, + 0x0E, 0xBD, 0x1F, 0xB5, 0x00, 0x24, 0xCD, 0xE9, 0x02, 0x23, 0x00, 0x94, + 0x01, 0x94, 0x23, 0x46, 0x52, 0x1C, 0xFF, 0xF7, 0x63, 0xFD, 0x1F, 0xBD, + 0x2D, 0xE9, 0xF0, 0x5F, 0x80, 0x46, 0x90, 0xF8, 0x2D, 0x00, 0xDD, 0xF8, + 0x28, 0x90, 0x1F, 0x46, 0x14, 0x46, 0x8B, 0x46, 0x00, 0x26, 0x10, 0xB1, + 0x40, 0xF6, 0x0E, 0x46, 0x5E, 0xE0, 0xDF, 0xF8, 0xC4, 0xA0, 0x40, 0xF2, + 0x93, 0x13, 0x30, 0x4A, 0xBA, 0xF8, 0x08, 0x10, 0x01, 0xEB, 0x0B, 0x00, + 0x81, 0xB2, 0x2E, 0x48, 0x00, 0x78, 0x00, 0xF0, 0x0B, 0xFC, 0x05, 0x00, + 0x4E, 0xD0, 0xD8, 0xF8, 0x04, 0x10, 0xBA, 0xF8, 0x08, 0x00, 0x3A, 0x0A, + 0x8C, 0x71, 0xF9, 0xB2, 0x28, 0x44, 0x09, 0xF0, 0xFF, 0x07, 0x4F, 0xEA, + 0x19, 0x23, 0x0A, 0x2C, 0x32, 0xD0, 0x06, 0xDC, 0x04, 0x2C, 0x29, 0xD0, + 0x06, 0x2C, 0x07, 0xD0, 0x08, 0x2C, 0x2E, 0xD1, 0x19, 0xE0, 0x0C, 0x2C, + 0x22, 0xD0, 0x10, 0x2C, 0x29, 0xD1, 0x14, 0xE0, 0x00, 0xF8, 0x01, 0x4B, + 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, 0x00, 0xF8, 0x01, 0x2B, 0x00, 0xF8, + 0x03, 0x7B, 0x00, 0xF8, 0x02, 0x3C, 0x00, 0xF8, 0x01, 0x1C, 0x28, 0x21, + 0x00, 0xF8, 0x01, 0x1B, 0xDD, 0xE9, 0x0B, 0x12, 0x2A, 0xF4, 0x59, 0xF7, + 0x13, 0xE0, 0x00, 0xF8, 0x01, 0x4B, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0xF8, + 0x02, 0x2B, 0x00, 0xF8, 0x01, 0x7C, 0x00, 0xF8, 0x01, 0x3B, 0xEF, 0xE7, + 0x04, 0x70, 0x41, 0x70, 0x82, 0x70, 0xC7, 0x70, 0x03, 0x71, 0x02, 0xE0, + 0x04, 0x70, 0x41, 0x70, 0x82, 0x70, 0xBA, 0xF8, 0x08, 0x30, 0x5A, 0x46, + 0x29, 0x46, 0x40, 0x46, 0x0B, 0xF0, 0xA1, 0xF9, 0x00, 0x21, 0x40, 0x46, + 0x00, 0xF0, 0xF0, 0xF8, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x9F, 0x00, 0x00, + 0x98, 0x77, 0x20, 0x00, 0x4B, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x05, 0x46, 0xDD, 0xE9, 0x12, 0xA3, + 0x90, 0xF8, 0x2D, 0x00, 0x4F, 0xF0, 0x00, 0x08, 0x10, 0xB1, 0x40, 0xF6, + 0x0E, 0x48, 0x69, 0xE0, 0x1E, 0x88, 0x00, 0x27, 0xF0, 0x1C, 0x18, 0x80, + 0xBA, 0xF8, 0x00, 0x00, 0xF6, 0x1C, 0xC0, 0x1E, 0x80, 0xB2, 0xAA, 0xF8, + 0x00, 0x00, 0x08, 0x9B, 0xC4, 0x18, 0x10, 0x0A, 0x62, 0x70, 0xA0, 0x70, + 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x05, 0xD0, 0x05, 0x29, 0x44, 0xD1, + 0x06, 0xE0, 0x12, 0x20, 0x20, 0x70, 0x40, 0xE0, 0x52, 0x20, 0x20, 0x70, + 0x01, 0x27, 0x2D, 0xE0, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, + 0x03, 0x90, 0xD2, 0x20, 0x20, 0x70, 0xA9, 0x7E, 0x05, 0xF1, 0x13, 0x00, + 0x01, 0x27, 0x04, 0x90, 0x16, 0xF0, 0x46, 0xFF, 0x5F, 0xEA, 0x00, 0x09, + 0x1A, 0xD0, 0xA9, 0x7E, 0x04, 0x98, 0x16, 0xF0, 0x57, 0xFF, 0x04, 0xEB, + 0x06, 0x0B, 0x42, 0x1C, 0xCB, 0xF8, 0x00, 0x00, 0xA9, 0x7E, 0x04, 0x98, + 0x1A, 0xF0, 0x3E, 0xFF, 0x6B, 0x46, 0x32, 0x1D, 0x21, 0x46, 0x48, 0x46, + 0x27, 0xF4, 0x64, 0xF6, 0x02, 0x98, 0xCB, 0xF8, 0x04, 0x00, 0x03, 0x98, + 0xCB, 0xF8, 0x08, 0x00, 0x0C, 0x36, 0x01, 0xE0, 0x40, 0xF6, 0x0F, 0x48, + 0x40, 0xF2, 0xB1, 0x20, 0x00, 0x90, 0x0F, 0x4B, 0x2A, 0x46, 0x0F, 0x49, + 0x08, 0x98, 0x00, 0xF0, 0x13, 0xFB, 0x20, 0xB9, 0x00, 0x22, 0x0D, 0x49, + 0x0D, 0x48, 0xF8, 0xF7, 0xB2, 0xDD, 0xBA, 0xF8, 0x00, 0x30, 0x32, 0x46, + 0x28, 0x46, 0x08, 0x99, 0x0B, 0xF0, 0x23, 0xF9, 0x37, 0xB9, 0x69, 0x68, + 0x20, 0x78, 0x88, 0x71, 0x00, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x6E, 0xF8, + 0x09, 0xB0, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x58, 0xAB, 0x82, 0x00, + 0xC5, 0xF6, 0x80, 0x00, 0x00, 0x46, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, + 0x10, 0xB5, 0x04, 0x46, 0x42, 0x8D, 0x00, 0x8D, 0x88, 0x42, 0x03, 0xD9, + 0x17, 0x29, 0x02, 0xD3, 0x61, 0x85, 0x00, 0xE0, 0x60, 0x85, 0x61, 0x8D, + 0x91, 0x42, 0x03, 0xD1, 0x94, 0xF8, 0x2C, 0x00, 0x00, 0x28, 0x05, 0xD1, + 0x20, 0x8E, 0x02, 0xF0, 0x4E, 0xFA, 0x01, 0x20, 0x84, 0xF8, 0x2C, 0x00, + 0x10, 0xBD, 0x00, 0x00, 0xF8, 0xB5, 0x0E, 0x46, 0x1E, 0x49, 0xC0, 0xEB, + 0xC0, 0x02, 0x02, 0xEB, 0x00, 0x10, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x04, + 0x04, 0xF1, 0x13, 0x01, 0x1A, 0x48, 0xF8, 0xF7, 0x3D, 0xDF, 0x00, 0x90, + 0x33, 0x46, 0x02, 0x22, 0x18, 0x49, 0x19, 0x48, 0xF8, 0xF7, 0x67, 0xDD, + 0x26, 0xB1, 0xA0, 0x68, 0x05, 0x46, 0x44, 0x30, 0x40, 0x35, 0x03, 0xE0, + 0x60, 0x68, 0x05, 0x46, 0x40, 0x1D, 0x20, 0x35, 0x00, 0x28, 0x1C, 0xD0, + 0x01, 0x78, 0x00, 0x29, 0x19, 0xD0, 0x00, 0x27, 0x07, 0x70, 0x01, 0x20, + 0x84, 0xF8, 0x2D, 0x00, 0x2E, 0xB1, 0x40, 0xF6, 0x0D, 0x41, 0x20, 0x46, + 0x09, 0xF0, 0x1A, 0xFD, 0x08, 0xE0, 0x60, 0x68, 0x00, 0x23, 0x01, 0x21, + 0x82, 0x79, 0x20, 0x46, 0x09, 0xF0, 0x68, 0xF8, 0x60, 0x68, 0x87, 0x71, + 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x01, 0xF0, 0xE7, 0xBA, 0xF8, 0xBD, + 0x98, 0x77, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0xCC, 0x45, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0xF8, 0xB5, 0x0F, 0x00, 0x06, 0x46, 0x04, 0xD0, + 0xB4, 0x68, 0x25, 0x46, 0x44, 0x34, 0x40, 0x35, 0x03, 0xE0, 0x74, 0x68, + 0x25, 0x46, 0x64, 0x1D, 0x20, 0x35, 0x00, 0x2C, 0x24, 0xD0, 0x20, 0x78, + 0x00, 0x28, 0x21, 0xD1, 0x06, 0xF1, 0x13, 0x01, 0x10, 0x48, 0xF8, 0xF7, + 0xED, 0xDE, 0x00, 0x90, 0x3B, 0x46, 0x02, 0x22, 0x0E, 0x49, 0x0F, 0x48, + 0xF8, 0xF7, 0x17, 0xDD, 0x00, 0x20, 0x28, 0x60, 0x0D, 0x48, 0x31, 0x78, + 0x00, 0x78, 0x00, 0x06, 0x40, 0xEA, 0x01, 0x42, 0x0B, 0x48, 0x3A, 0x43, + 0x4F, 0xF4, 0x7A, 0x71, 0x90, 0xF8, 0x30, 0x00, 0x10, 0xFB, 0x01, 0xF3, + 0x08, 0xA1, 0x28, 0x46, 0x01, 0xF0, 0x94, 0xFA, 0x01, 0x20, 0x20, 0x70, + 0xF8, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x6C, 0x45, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0x94, 0x77, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x61, 0x74, 0x74, 0x00, 0xF8, 0xB5, 0x0E, 0x00, 0x04, 0xD0, 0x84, 0x68, + 0x25, 0x46, 0x44, 0x34, 0x40, 0x35, 0x03, 0xE0, 0x44, 0x68, 0x25, 0x46, + 0x64, 0x1D, 0x20, 0x35, 0x00, 0x2C, 0x13, 0xD0, 0x21, 0x78, 0x00, 0x29, + 0x10, 0xD0, 0x00, 0xF1, 0x13, 0x01, 0x08, 0x48, 0xF8, 0xF7, 0xAC, 0xDE, + 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF8, 0xF7, + 0xD6, 0xDC, 0x28, 0x46, 0x01, 0xF0, 0x7C, 0xFA, 0x00, 0x20, 0x20, 0x70, + 0xF8, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x98, 0x45, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0x00, 0x21, 0xAF, 0xF3, 0x00, 0x80, 0x2D, 0xE9, + 0xF8, 0x43, 0x05, 0x46, 0x40, 0x78, 0x88, 0x46, 0x00, 0x28, 0x46, 0xD0, + 0x68, 0x7E, 0x05, 0x28, 0x01, 0xD0, 0x03, 0x28, 0x41, 0xD1, 0x00, 0x26, + 0x01, 0x27, 0x03, 0x28, 0x02, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x01, 0xD0, + 0x40, 0xF6, 0x04, 0x46, 0x05, 0xF1, 0x50, 0x09, 0xB8, 0xF1, 0x00, 0x0F, + 0x00, 0xD1, 0x00, 0x27, 0x48, 0x46, 0x03, 0xF4, 0x1C, 0xF4, 0x04, 0x00, + 0x2D, 0xD0, 0x20, 0x79, 0x90, 0xB1, 0x01, 0x28, 0x17, 0xD0, 0x02, 0x28, + 0x20, 0xD1, 0xA6, 0x82, 0x3E, 0xB1, 0x00, 0x96, 0xD4, 0xE9, 0x02, 0x12, + 0xE3, 0x8A, 0x00, 0x20, 0x01, 0xF0, 0x64, 0xFE, 0x16, 0xE0, 0x04, 0xF1, + 0x08, 0x00, 0x08, 0xF0, 0xA7, 0xFD, 0x11, 0xE0, 0xE3, 0x88, 0x29, 0x8E, + 0x02, 0x22, 0x30, 0x46, 0x02, 0xF0, 0xCE, 0xFC, 0x0A, 0xE0, 0xE3, 0x88, + 0x29, 0x8E, 0x05, 0x22, 0x30, 0x46, 0x02, 0xF0, 0xC7, 0xFC, 0x29, 0x8E, + 0x01, 0x22, 0x30, 0x46, 0x05, 0xF0, 0xE9, 0xFA, 0x21, 0x46, 0x05, 0xF1, + 0x44, 0x00, 0x03, 0xF4, 0xD8, 0xF3, 0x00, 0x2F, 0xC8, 0xD1, 0xBD, 0xE8, + 0xF8, 0x83, 0x00, 0x00, 0x06, 0x48, 0x10, 0xB5, 0x41, 0x68, 0x08, 0x78, + 0x08, 0xB1, 0x08, 0x5C, 0x10, 0xBD, 0x00, 0x22, 0x03, 0x49, 0x04, 0x48, + 0xF8, 0xF7, 0x69, 0xDC, 0xFF, 0x20, 0x10, 0xBD, 0xC4, 0x78, 0x20, 0x00, + 0x54, 0x79, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0x48, 0x08, 0xB5, + 0x40, 0x68, 0x03, 0x78, 0x8B, 0x42, 0x07, 0xD2, 0x00, 0x91, 0x02, 0x22, + 0x05, 0x49, 0x06, 0x48, 0xF8, 0xF7, 0x55, 0xDC, 0xFF, 0x20, 0x08, 0xBD, + 0x59, 0x1A, 0x08, 0x44, 0x40, 0x78, 0x08, 0xBD, 0xC4, 0x78, 0x20, 0x00, + 0x14, 0x79, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x10, 0x4D, + 0x03, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x28, 0x46, 0xF8, 0xF7, 0x41, 0xDC, + 0x0D, 0x48, 0x40, 0x68, 0x01, 0x78, 0x49, 0xB1, 0x44, 0x78, 0x09, 0x49, + 0x23, 0x46, 0x01, 0x22, 0x44, 0x31, 0x28, 0x46, 0xF8, 0xF7, 0x35, 0xDC, + 0x20, 0x46, 0x70, 0xBD, 0x04, 0x49, 0x05, 0x48, 0x00, 0x22, 0x20, 0x31, + 0xC0, 0x1E, 0xF8, 0xF7, 0x2C, 0xDC, 0xFF, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0xA8, 0x78, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, + 0xF8, 0xB5, 0x0E, 0x46, 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, + 0x1C, 0x49, 0x1D, 0x48, 0xF8, 0xF7, 0x19, 0xDC, 0x1C, 0x4C, 0x31, 0x46, + 0x28, 0x46, 0x27, 0x78, 0x00, 0xF0, 0x9A, 0xF8, 0xFF, 0x28, 0x05, 0xD0, + 0x31, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0xF0, 0xD6, 0xB8, + 0x61, 0x68, 0x08, 0x78, 0xB8, 0x42, 0x08, 0xD1, 0x11, 0x49, 0x12, 0x48, + 0x00, 0x22, 0x2C, 0x31, 0xC0, 0x1E, 0xF8, 0xF7, 0x00, 0xDC, 0x00, 0x20, + 0xF8, 0xBD, 0x49, 0x1C, 0x46, 0x54, 0x62, 0x68, 0x13, 0x21, 0x10, 0x78, + 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x0B, 0x0C, 0x48, 0xF8, 0xF7, 0x5F, 0xDE, + 0x00, 0x90, 0x60, 0x68, 0x06, 0x49, 0x02, 0x22, 0x03, 0x78, 0x06, 0x48, + 0x54, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0xE9, 0xDB, 0x28, 0x46, 0x61, 0x68, + 0x07, 0xF0, 0xA6, 0xF9, 0x01, 0x20, 0xF8, 0xBD, 0xEC, 0x76, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, + 0x10, 0xB5, 0x03, 0x46, 0x01, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF8, 0xF7, + 0xD4, 0xDB, 0x06, 0x49, 0x00, 0x20, 0x08, 0x70, 0xBD, 0xE8, 0x10, 0x40, + 0x01, 0x20, 0x07, 0xF0, 0x8D, 0xB9, 0x00, 0x00, 0xB8, 0x75, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xCC, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x0F, 0x46, + 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1E, 0x49, 0x1F, 0x48, + 0xF8, 0xF7, 0xBB, 0xDB, 0x1E, 0x4C, 0x1D, 0x4E, 0x60, 0x68, 0xF6, 0x1E, + 0x00, 0x78, 0x38, 0xB1, 0x39, 0x46, 0x28, 0x46, 0x00, 0xF0, 0x38, 0xF8, + 0xFF, 0x28, 0x25, 0xD0, 0x62, 0x68, 0x08, 0xE0, 0x15, 0x49, 0x00, 0x22, + 0x2C, 0x31, 0x22, 0xE0, 0x11, 0x18, 0x40, 0x1C, 0x8B, 0x78, 0x4B, 0x70, + 0xC0, 0xB2, 0x11, 0x78, 0x81, 0x42, 0xF7, 0xD8, 0xC8, 0xB2, 0x40, 0x1E, + 0x02, 0xF8, 0x01, 0x0B, 0x13, 0x21, 0x10, 0x48, 0xF8, 0xF7, 0x05, 0xDE, + 0x00, 0x90, 0x60, 0x68, 0x0A, 0x49, 0x02, 0x22, 0x03, 0x78, 0x0A, 0x48, + 0x60, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0x8F, 0xDB, 0x28, 0x46, 0x61, 0x68, + 0x07, 0xF0, 0x4C, 0xF9, 0x01, 0x20, 0xF8, 0xBD, 0x03, 0x49, 0x00, 0x22, + 0xA0, 0x31, 0x30, 0x46, 0xF8, 0xF7, 0x83, 0xDB, 0x00, 0x20, 0xF8, 0xBD, + 0x1C, 0x76, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, + 0x00, 0x00, 0x50, 0x21, 0x38, 0xB5, 0x0B, 0x4A, 0x03, 0x46, 0x00, 0x20, + 0x52, 0x68, 0x14, 0x78, 0x05, 0xE0, 0x15, 0x18, 0x6D, 0x78, 0x8D, 0x42, + 0x0A, 0xD0, 0x40, 0x1C, 0xC0, 0xB2, 0x84, 0x42, 0xF7, 0xD8, 0x00, 0x91, + 0x02, 0x22, 0x04, 0x49, 0x04, 0x48, 0xF8, 0xF7, 0x64, 0xDB, 0xFF, 0x20, + 0x38, 0xBD, 0x00, 0x00, 0xC4, 0x78, 0x20, 0x00, 0xE0, 0x75, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46, 0x0E, 0x49, 0x01, 0x20, + 0x06, 0xF0, 0x4A, 0xFF, 0x0C, 0x4C, 0x88, 0xB9, 0x23, 0x78, 0x01, 0x22, + 0x0B, 0x49, 0x0C, 0x48, 0xF8, 0xF7, 0x4D, 0xDB, 0x20, 0x78, 0x13, 0x28, + 0x08, 0xD9, 0x08, 0x49, 0x08, 0x48, 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E, + 0xF8, 0xF7, 0x43, 0xDB, 0x00, 0x20, 0x20, 0x70, 0x02, 0x48, 0x08, 0x38, + 0x44, 0x60, 0x05, 0x70, 0x70, 0xBD, 0x00, 0x00, 0xCC, 0x78, 0x20, 0x00, + 0x54, 0x75, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0xF8, 0xB5, 0x0C, 0x46, + 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1D, 0x49, 0x1E, 0x48, + 0xF8, 0xF7, 0x2B, 0xDB, 0x21, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0xAE, 0xFF, + 0xFF, 0x28, 0x25, 0xD0, 0x1A, 0x4D, 0x6A, 0x68, 0x11, 0x78, 0x49, 0x1E, + 0x81, 0x42, 0x06, 0xD1, 0x01, 0x20, 0xF8, 0xBD, 0x11, 0x18, 0x40, 0x1C, + 0x8B, 0x78, 0x4B, 0x70, 0xC0, 0xB2, 0x11, 0x78, 0x81, 0x42, 0xF7, 0xD8, + 0xC8, 0xB2, 0x13, 0x21, 0x14, 0x54, 0x12, 0x48, 0x52, 0x1C, 0xF8, 0xF7, + 0x7A, 0xDD, 0x00, 0x90, 0x68, 0x68, 0x0C, 0x49, 0x02, 0x22, 0x03, 0x78, + 0x0B, 0x48, 0x28, 0x31, 0x40, 0x1E, 0xF8, 0xF7, 0x04, 0xDB, 0x30, 0x46, + 0x69, 0x68, 0x07, 0xF0, 0xC1, 0xF8, 0xDF, 0xE7, 0x05, 0x49, 0x06, 0x48, + 0x33, 0x46, 0x02, 0x22, 0x64, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xF8, 0xF7, + 0xF6, 0xDA, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x00, 0x7C, 0x77, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, + 0xF8, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, + 0x1B, 0x49, 0x1C, 0x48, 0xF8, 0xF7, 0xE1, 0xDA, 0x21, 0x46, 0x30, 0x46, + 0xFF, 0xF7, 0x64, 0xFF, 0xFF, 0x28, 0x21, 0xD0, 0x10, 0xB1, 0x18, 0x4D, + 0x6A, 0x68, 0x06, 0xE0, 0x01, 0x20, 0xF8, 0xBD, 0x11, 0x5C, 0x13, 0x18, + 0x40, 0x1E, 0x59, 0x70, 0xC0, 0xB2, 0x00, 0x28, 0xF8, 0xD1, 0x02, 0xF8, + 0x01, 0x4F, 0x13, 0x21, 0x11, 0x48, 0xF8, 0xF7, 0x34, 0xDD, 0x00, 0x90, + 0x68, 0x68, 0x0C, 0x49, 0x02, 0x22, 0x03, 0x78, 0x0B, 0x48, 0x28, 0x31, + 0x40, 0x1E, 0xF8, 0xF7, 0xBE, 0xDA, 0x30, 0x46, 0x69, 0x68, 0x07, 0xF0, + 0x7B, 0xF8, 0xE1, 0xE7, 0x05, 0x49, 0x06, 0x48, 0x33, 0x46, 0x02, 0x22, + 0x60, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xF8, 0xF7, 0xB0, 0xDA, 0x00, 0x20, + 0xF8, 0xBD, 0x00, 0x00, 0x14, 0x78, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xC4, 0x78, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, 0x2D, 0xE9, 0xFC, 0x41, + 0x05, 0x00, 0x19, 0x4F, 0x08, 0x9E, 0x4F, 0xF0, 0x05, 0x50, 0x01, 0xD0, + 0xAC, 0x07, 0x06, 0xD0, 0x19, 0x46, 0xF8, 0xF7, 0xB2, 0xDC, 0x03, 0x46, + 0x03, 0x22, 0x14, 0x49, 0x16, 0xE0, 0x55, 0xF8, 0x04, 0xCC, 0xA5, 0xF1, + 0x10, 0x04, 0x4F, 0xEA, 0x5C, 0x7C, 0x5F, 0xEA, 0xCC, 0x7C, 0x06, 0xD0, + 0xC4, 0xE9, 0x01, 0x12, 0xE0, 0x68, 0x89, 0xB1, 0x40, 0xF0, 0x80, 0x40, + 0x10, 0xE0, 0x19, 0x46, 0xF8, 0xF7, 0x9B, 0xDC, 0x09, 0x49, 0x03, 0x22, + 0x03, 0x46, 0x3C, 0x31, 0xCD, 0xE9, 0x00, 0x65, 0x38, 0x46, 0xF8, 0xF7, + 0x78, 0xDA, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x20, 0xF0, 0x80, 0x40, + 0xE0, 0x60, 0x01, 0x20, 0xF8, 0xE7, 0x00, 0x00, 0x00, 0x36, 0x10, 0x21, + 0x88, 0x01, 0xC0, 0x08, 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x1D, 0x46, + 0x0C, 0x46, 0x06, 0x46, 0x03, 0xF4, 0xFC, 0xF2, 0x01, 0x46, 0x4F, 0xF0, + 0x05, 0x5B, 0x08, 0x2E, 0x09, 0xD3, 0x03, 0xF4, 0x02, 0xF3, 0x58, 0x46, + 0x07, 0x99, 0xF8, 0xF7, 0x72, 0xDC, 0x03, 0x46, 0x03, 0x22, 0x67, 0x49, + 0x20, 0xE0, 0x67, 0x48, 0x00, 0xEB, 0xC6, 0x03, 0x18, 0x78, 0xC0, 0x07, + 0x0F, 0xD0, 0xD8, 0x88, 0x9A, 0x88, 0x90, 0x42, 0x1A, 0xD3, 0x08, 0x46, + 0x03, 0xF4, 0xED, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x5D, 0xDC, + 0x5D, 0x49, 0x03, 0x22, 0x03, 0x46, 0x6C, 0x31, 0x4B, 0xE0, 0x08, 0x46, + 0x03, 0xF4, 0xE1, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x51, 0xDC, + 0x57, 0x49, 0x03, 0x22, 0x03, 0x46, 0x34, 0x31, 0xCD, 0xE9, 0x00, 0x56, + 0x56, 0x48, 0x3F, 0xE0, 0x84, 0xB1, 0x10, 0x34, 0xA4, 0xB2, 0xE0, 0x06, + 0x03, 0xD0, 0x4F, 0xF6, 0xE0, 0x70, 0x1F, 0x34, 0x04, 0x40, 0x3C, 0xB1, + 0xDF, 0xF8, 0x3C, 0xC1, 0xAC, 0xF1, 0x18, 0x0C, 0xDC, 0xF8, 0x04, 0x00, + 0x84, 0x42, 0x0B, 0xD9, 0x08, 0x46, 0x03, 0xF4, 0xC0, 0xF2, 0x58, 0x46, + 0x07, 0x99, 0xF8, 0xF7, 0x30, 0xDC, 0x47, 0x49, 0x03, 0x22, 0x03, 0x46, + 0xA0, 0x31, 0x1E, 0xE0, 0x45, 0x4A, 0x40, 0x32, 0x10, 0x46, 0x00, 0x68, + 0x01, 0xE0, 0x02, 0x46, 0x38, 0x46, 0xC7, 0x68, 0x27, 0xF0, 0x7F, 0x47, + 0xA7, 0x42, 0x02, 0xD2, 0x07, 0x68, 0x00, 0x2F, 0xF5, 0xD1, 0xDC, 0xF8, + 0x0C, 0x70, 0xE1, 0x46, 0xB8, 0x42, 0x13, 0xD1, 0x08, 0x46, 0x03, 0xF4, + 0xA0, 0xF2, 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0x10, 0xDC, 0x37, 0x49, + 0x03, 0x22, 0x03, 0x46, 0xD8, 0x31, 0xCD, 0xE9, 0x00, 0x54, 0x36, 0x48, + 0xF8, 0xF7, 0xED, 0xD9, 0x00, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0xD0, 0xF8, 0x0C, 0xC0, 0x17, 0x68, 0x2C, 0xF0, 0x7F, 0x4C, 0xAC, 0xEB, + 0x04, 0x0C, 0x07, 0xF1, 0x10, 0x0A, 0xBC, 0xF1, 0x40, 0x0F, 0x19, 0xDB, + 0x27, 0x44, 0xD0, 0xF8, 0x00, 0xC0, 0xC7, 0xF8, 0x00, 0xC0, 0xD0, 0xF8, + 0x0C, 0xC0, 0xAC, 0xEB, 0x04, 0x08, 0xD7, 0xF8, 0x0C, 0xC0, 0x68, 0xF3, + 0x17, 0x0C, 0x2C, 0xF0, 0x60, 0x4C, 0xC7, 0xF8, 0x0C, 0xC0, 0x17, 0x60, + 0xC2, 0x68, 0x64, 0xF3, 0x17, 0x02, 0xC2, 0x60, 0xD9, 0xF8, 0x04, 0x70, + 0x3F, 0x1B, 0x08, 0xE0, 0x07, 0x68, 0x17, 0x60, 0xC2, 0x68, 0xD9, 0xF8, + 0x04, 0xC0, 0x22, 0xF0, 0x7F, 0x47, 0xAC, 0xEB, 0x07, 0x07, 0x00, 0x22, + 0xC9, 0xF8, 0x04, 0x70, 0x02, 0x60, 0x42, 0x60, 0x82, 0x60, 0xC2, 0x68, + 0x22, 0xF0, 0x60, 0x42, 0x02, 0xF1, 0x00, 0x52, 0x66, 0xF3, 0x1C, 0x62, + 0xC2, 0x60, 0xD8, 0x88, 0x40, 0x1C, 0xD8, 0x80, 0xD9, 0xE9, 0x01, 0x03, + 0x98, 0x42, 0x01, 0xD2, 0xC9, 0xF8, 0x08, 0x00, 0x08, 0x46, 0x03, 0xF4, + 0x46, 0xF2, 0x0F, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x07, 0x11, 0xD5, + 0x58, 0x46, 0x07, 0x99, 0xF8, 0xF7, 0xB1, 0xDB, 0xCD, 0xF8, 0x0C, 0xA0, + 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x64, 0x03, 0x46, 0x05, 0x22, 0x08, 0x49, + 0x05, 0x48, 0xF8, 0xF7, 0x8C, 0xD9, 0x30, 0x46, 0x00, 0xF0, 0xD2, 0xFB, + 0x50, 0x46, 0x9A, 0xE7, 0x00, 0x02, 0xC0, 0x08, 0x94, 0x75, 0x20, 0x00, + 0x00, 0x36, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x14, 0x03, 0xC0, 0x08, + 0x2D, 0xE9, 0xF7, 0x4F, 0x4F, 0xF0, 0x00, 0x0A, 0x82, 0xB0, 0x16, 0x46, + 0x05, 0x46, 0x57, 0x46, 0x03, 0xF4, 0x0C, 0xF2, 0x00, 0x90, 0x0D, 0xB1, + 0xA8, 0x07, 0x0B, 0xD0, 0x00, 0x98, 0x03, 0xF4, 0x12, 0xF2, 0x4F, 0xF0, + 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0x81, 0xDB, 0x03, 0x46, 0x03, 0x22, + 0x55, 0x49, 0x53, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x43, 0xFB, 0xC8, 0xB1, + 0xA5, 0xF1, 0x10, 0x04, 0xE0, 0x68, 0xC0, 0xF3, 0x04, 0x61, 0x08, 0x29, + 0x1B, 0xD3, 0x00, 0x98, 0x03, 0xF4, 0xFB, 0xF1, 0x4F, 0xF0, 0x05, 0x50, + 0x03, 0x99, 0xF8, 0xF7, 0x6A, 0xDB, 0x03, 0x46, 0xE0, 0x68, 0x4A, 0x49, + 0xC0, 0xF3, 0x04, 0x60, 0xCD, 0xE9, 0x00, 0x60, 0x03, 0x22, 0x30, 0x31, + 0x47, 0x48, 0x38, 0xE0, 0x00, 0x98, 0x03, 0xF4, 0xE8, 0xF1, 0x05, 0xB0, + 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0xF0, 0x45, 0xBF, 0x41, 0x0F, + 0xCA, 0x07, 0x1D, 0xD0, 0x20, 0xF0, 0x60, 0x40, 0xE0, 0x60, 0x89, 0x46, + 0x88, 0x07, 0x04, 0xD5, 0xD4, 0xE9, 0x01, 0x7A, 0x00, 0x20, 0x60, 0x60, + 0xA0, 0x60, 0x3C, 0x4A, 0xE0, 0x68, 0x53, 0x68, 0x20, 0xF0, 0x7F, 0x41, + 0x19, 0x44, 0x51, 0x60, 0xC0, 0xF3, 0x04, 0x61, 0x02, 0xF1, 0x18, 0x00, + 0x00, 0xEB, 0xC1, 0x00, 0xC1, 0x88, 0x49, 0x1E, 0xC1, 0x80, 0x02, 0xF1, + 0x58, 0x00, 0x15, 0xE0, 0x00, 0x98, 0x03, 0xF4, 0xBE, 0xF1, 0x4F, 0xF0, + 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0x2D, 0xDB, 0x2C, 0x49, 0x03, 0x22, + 0x03, 0x46, 0x64, 0x31, 0xCD, 0xE9, 0x00, 0x65, 0x2A, 0x48, 0xF8, 0xF7, + 0x0A, 0xD9, 0x00, 0x20, 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x08, 0x46, + 0x01, 0x68, 0xA1, 0x42, 0xFB, 0xD3, 0xD0, 0xF8, 0x0C, 0xC0, 0x2C, 0xF0, + 0x7F, 0x43, 0x03, 0xEB, 0x00, 0x08, 0xA0, 0x45, 0x06, 0xD1, 0xE4, 0x68, + 0x23, 0x44, 0x63, 0xF3, 0x17, 0x0C, 0x04, 0x46, 0xC0, 0xF8, 0x0C, 0xC0, + 0xE3, 0x68, 0x23, 0xF0, 0x7F, 0x4B, 0x0B, 0xEB, 0x04, 0x0C, 0x8C, 0x45, + 0x09, 0xD1, 0xD2, 0x68, 0x91, 0x42, 0x2D, 0xD0, 0xC9, 0x68, 0x59, 0x44, + 0x61, 0xF3, 0x17, 0x03, 0xE3, 0x60, 0x01, 0x68, 0x09, 0x68, 0x21, 0x60, + 0xA0, 0x42, 0x00, 0xD0, 0x04, 0x60, 0x00, 0x98, 0x03, 0xF4, 0x81, 0xF1, + 0x5F, 0xEA, 0x89, 0x70, 0x02, 0xD5, 0x0F, 0xB1, 0x50, 0x46, 0xB8, 0x47, + 0x10, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x07, 0x12, 0xD5, 0x4F, 0xF0, + 0x05, 0x50, 0x03, 0x99, 0xF8, 0xF7, 0xE5, 0xDA, 0x08, 0x49, 0xCD, 0xE9, + 0x00, 0x65, 0x03, 0x46, 0x03, 0x22, 0x98, 0x31, 0x06, 0x48, 0xF8, 0xF7, + 0xC2, 0xD8, 0xE0, 0x68, 0xC0, 0xF3, 0x04, 0x60, 0x00, 0xF0, 0x06, 0xFB, + 0x01, 0x20, 0xB1, 0xE7, 0x22, 0x60, 0xD7, 0xE7, 0x58, 0x03, 0xC0, 0x08, + 0x00, 0x36, 0x10, 0x21, 0x7C, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x70, 0xB5, 0x16, 0x4C, 0x00, 0x23, 0x03, 0xEB, 0x83, 0x05, 0x04, 0xEB, + 0x85, 0x05, 0xAD, 0x7C, 0xED, 0x07, 0x0E, 0xD0, 0x5B, 0x1C, 0xDB, 0xB2, + 0x05, 0x2B, 0xF4, 0xD3, 0x05, 0x2B, 0x14, 0xD0, 0x03, 0xEB, 0x83, 0x00, + 0x44, 0xF8, 0x20, 0x10, 0x04, 0xEB, 0x80, 0x00, 0x42, 0x60, 0x01, 0x20, + 0x70, 0xBD, 0x03, 0xEB, 0x83, 0x05, 0x04, 0xEB, 0x85, 0x05, 0x6E, 0x8A, + 0x46, 0xF0, 0x01, 0x06, 0x6E, 0x82, 0x03, 0xF1, 0x10, 0x05, 0x05, 0x70, + 0xE8, 0xE7, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, 0xF8, 0xF7, 0x87, 0xD8, + 0x00, 0xF0, 0x44, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0xD0, 0x74, 0x20, 0x00, + 0xB4, 0x08, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, + 0xA0, 0xF1, 0x10, 0x01, 0x05, 0x29, 0x0A, 0xD3, 0x03, 0x46, 0x01, 0x22, + 0x16, 0x49, 0x17, 0x48, 0xF8, 0xF7, 0x71, 0xD8, 0x00, 0xF0, 0x2E, 0xF8, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0xC8, 0xB2, 0x13, 0x49, 0x00, 0xEB, + 0x80, 0x00, 0x01, 0xEB, 0x80, 0x04, 0x03, 0xF4, 0xFD, 0xF0, 0x07, 0x46, + 0xA0, 0x7C, 0xC0, 0x07, 0x12, 0xD0, 0x00, 0x20, 0x60, 0x82, 0x0D, 0x4E, + 0x20, 0x60, 0x04, 0xF1, 0x08, 0x05, 0x70, 0x36, 0x60, 0x60, 0x06, 0xE0, + 0x28, 0x46, 0x02, 0xF4, 0xC8, 0xF7, 0x01, 0x46, 0x30, 0x46, 0x02, 0xF4, + 0xAE, 0xF7, 0x20, 0x8A, 0x00, 0x28, 0xF5, 0xD1, 0x38, 0x46, 0x03, 0xF4, + 0xF0, 0xF0, 0x01, 0x20, 0xD9, 0xE7, 0x00, 0x00, 0xE4, 0x08, 0xC0, 0x08, + 0x00, 0x36, 0x10, 0x21, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x03, 0xF4, 0xD6, 0xF0, 0x1B, 0x4D, 0x07, 0x46, 0x1C, 0x4E, 0xB5, 0xF8, + 0x9E, 0x00, 0xB5, 0xF8, 0x98, 0x30, 0x35, 0xF8, 0x78, 0x1F, 0x03, 0x22, + 0x59, 0x1A, 0xCD, 0xE9, 0x00, 0x10, 0x16, 0x49, 0x30, 0x46, 0xF8, 0xF7, + 0x2C, 0xD8, 0x6B, 0x8C, 0xA9, 0x89, 0x28, 0x8D, 0x59, 0x1A, 0xCD, 0xE9, + 0x00, 0x10, 0x11, 0x49, 0x03, 0x22, 0x40, 0x31, 0x30, 0x46, 0x78, 0x3D, + 0xF8, 0xF7, 0x1F, 0xD8, 0x00, 0x24, 0x04, 0xEB, 0x84, 0x00, 0x05, 0xEB, + 0x80, 0x00, 0x23, 0x46, 0x01, 0x8A, 0x40, 0x8A, 0xCD, 0xE9, 0x00, 0x01, + 0x08, 0x49, 0x03, 0x22, 0x84, 0x31, 0x30, 0x46, 0xF8, 0xF7, 0x0F, 0xD8, + 0x64, 0x1C, 0xE4, 0xB2, 0x05, 0x2C, 0xEC, 0xD3, 0x38, 0x46, 0x03, 0xF4, + 0xAE, 0xF0, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0xD0, 0x74, 0x20, 0x00, + 0x18, 0x06, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xFC, 0x41, + 0x04, 0x46, 0x1E, 0x46, 0x10, 0x38, 0x1E, 0x4F, 0x88, 0x46, 0x4F, 0xF0, + 0x05, 0x53, 0x05, 0x28, 0x07, 0xD3, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7, + 0x0A, 0xDA, 0x03, 0x46, 0x03, 0x22, 0x19, 0x49, 0x24, 0xE0, 0xC0, 0xB2, + 0x00, 0xEB, 0x80, 0x01, 0x17, 0x48, 0x00, 0xEB, 0x81, 0x05, 0xA8, 0x7C, + 0xC0, 0x07, 0x13, 0xD0, 0x03, 0xF4, 0x7A, 0xF0, 0x06, 0x46, 0x05, 0xF1, + 0x08, 0x00, 0x02, 0xF4, 0x67, 0xF7, 0x04, 0x46, 0x30, 0x46, 0x03, 0xF4, + 0x7E, 0xF0, 0xB4, 0xB1, 0x14, 0x22, 0x21, 0x1D, 0x40, 0x46, 0x2A, 0xF4, + 0x2B, 0xF1, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x11, 0x46, 0x18, 0x46, + 0xF8, 0xF7, 0xE5, 0xD9, 0x07, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31, + 0xCD, 0xE9, 0x00, 0x64, 0x38, 0x46, 0xF7, 0xF7, 0xC2, 0xDF, 0xFF, 0xF7, + 0x7F, 0xFF, 0x00, 0x20, 0xEC, 0xE7, 0x00, 0x00, 0x00, 0x36, 0x10, 0x21, + 0x40, 0x08, 0xC0, 0x08, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x04, 0x46, 0x1E, 0x46, 0x10, 0x38, 0x23, 0x4F, 0x88, 0x46, 0x4F, 0xF0, + 0x05, 0x53, 0x05, 0x28, 0x07, 0xD3, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7, + 0xC2, 0xD9, 0x03, 0x46, 0x03, 0x22, 0x1E, 0x49, 0x2F, 0xE0, 0xC0, 0xB2, + 0x00, 0xEB, 0x80, 0x01, 0x1C, 0x48, 0x00, 0xEB, 0x81, 0x05, 0xA8, 0x7C, + 0xC0, 0x07, 0x1E, 0xD0, 0x03, 0xF4, 0x32, 0xF0, 0x06, 0x46, 0x05, 0xF1, + 0x08, 0x00, 0x02, 0xF4, 0x08, 0xF7, 0x04, 0x46, 0x30, 0x46, 0x03, 0xF4, + 0x36, 0xF0, 0x0C, 0xB3, 0x14, 0x22, 0x21, 0x1D, 0x40, 0x46, 0x2A, 0xF4, + 0xE3, 0xF0, 0x03, 0xF4, 0x21, 0xF0, 0x05, 0x46, 0x0F, 0x48, 0x21, 0x46, + 0x70, 0x30, 0x02, 0xF4, 0xE0, 0xF6, 0x28, 0x46, 0x03, 0xF4, 0x25, 0xF0, + 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x11, 0x46, 0x18, 0x46, 0xF8, 0xF7, + 0x92, 0xD9, 0x07, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31, 0xCD, 0xE9, + 0x00, 0x64, 0x38, 0x46, 0xF7, 0xF7, 0x6F, 0xDF, 0xFF, 0xF7, 0x2C, 0xFF, + 0x00, 0x20, 0xEC, 0xE7, 0x00, 0x36, 0x10, 0x21, 0xCC, 0x07, 0xC0, 0x08, + 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x04, 0x46, 0x00, 0x27, + 0x10, 0x38, 0xDF, 0xF8, 0x28, 0xB1, 0x83, 0xB0, 0x1D, 0x46, 0x4F, 0xF0, + 0x05, 0x5A, 0x05, 0x28, 0x07, 0xD3, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7, + 0x6E, 0xD9, 0x03, 0x46, 0x03, 0x22, 0x44, 0x49, 0x6A, 0xE0, 0xC0, 0xB2, + 0x00, 0xEB, 0x80, 0x01, 0x42, 0x48, 0x00, 0xEB, 0x81, 0x06, 0xB1, 0x7C, + 0xC9, 0x07, 0x47, 0xD0, 0x80, 0x46, 0x02, 0xF4, 0xDD, 0xF7, 0x00, 0x90, + 0x3D, 0x48, 0x70, 0x30, 0x02, 0xF4, 0xB3, 0xF6, 0x81, 0x46, 0x00, 0x98, + 0x02, 0xF4, 0xE1, 0xF7, 0xB9, 0xF1, 0x00, 0x0F, 0x41, 0xD0, 0xB8, 0xF8, + 0x98, 0x00, 0xB8, 0xF8, 0x78, 0x20, 0xB8, 0xF8, 0x9E, 0x10, 0x80, 0x1A, + 0x88, 0x42, 0x01, 0xDD, 0xA8, 0xF8, 0x9E, 0x00, 0x14, 0x22, 0x09, 0xF1, + 0x04, 0x00, 0x04, 0x99, 0x2A, 0xF4, 0x80, 0xF0, 0x02, 0xF4, 0xBE, 0xF7, + 0x00, 0x90, 0x49, 0x46, 0x06, 0xF1, 0x08, 0x00, 0x02, 0xF4, 0x7D, 0xF6, + 0x2B, 0x48, 0x7C, 0x30, 0x02, 0xF4, 0x8F, 0xF6, 0x81, 0x46, 0x00, 0x98, + 0x02, 0xF4, 0xBD, 0xF7, 0xB9, 0xF1, 0x00, 0x0F, 0x26, 0xD0, 0xB8, 0xF8, + 0x9A, 0x00, 0xB8, 0xF8, 0x84, 0x10, 0x44, 0x46, 0x40, 0x1A, 0xB8, 0xF8, + 0xA0, 0x10, 0x88, 0x42, 0x01, 0xDD, 0xA4, 0xF8, 0xA0, 0x00, 0xC9, 0xF8, + 0x04, 0x60, 0x02, 0xF4, 0x9D, 0xF7, 0x05, 0x46, 0xB4, 0xF8, 0x90, 0x00, + 0x28, 0xB3, 0x25, 0xE0, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7, 0x15, 0xD9, + 0x18, 0x49, 0x03, 0x22, 0x03, 0x46, 0x38, 0x31, 0x10, 0xE0, 0x50, 0x46, + 0x05, 0x99, 0xF8, 0xF7, 0x0C, 0xD9, 0x14, 0x49, 0x03, 0x22, 0x03, 0x46, + 0x74, 0x31, 0x07, 0xE0, 0x50, 0x46, 0x05, 0x99, 0xF8, 0xF7, 0x03, 0xD9, + 0x0F, 0x49, 0x03, 0x22, 0x03, 0x46, 0xB4, 0x31, 0xCD, 0xE9, 0x00, 0x54, + 0x58, 0x46, 0xF7, 0xF7, 0xE0, 0xDE, 0xFF, 0xF7, 0x9D, 0xFE, 0x00, 0x20, + 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x01, 0x27, 0x08, 0x48, 0x49, 0x46, + 0x88, 0x30, 0x02, 0xF4, 0x32, 0xF6, 0x28, 0x46, 0x02, 0xF4, 0x77, 0xF7, + 0x0F, 0xB1, 0x00, 0xF0, 0xBB, 0xFB, 0x01, 0x20, 0xEE, 0xE7, 0x00, 0x00, + 0x00, 0x36, 0x10, 0x21, 0xD4, 0x06, 0xC0, 0x08, 0xD0, 0x74, 0x20, 0x00, + 0x01, 0x48, 0x90, 0xF8, 0x95, 0x00, 0x70, 0x47, 0xD0, 0x74, 0x20, 0x00, + 0x70, 0xB5, 0x12, 0x4D, 0x95, 0xF8, 0x95, 0x00, 0x30, 0xB1, 0x00, 0x22, + 0x10, 0x49, 0x11, 0x48, 0xF7, 0xF7, 0xB5, 0xDE, 0x01, 0x20, 0x70, 0xBD, + 0x00, 0xF0, 0x0E, 0xFB, 0x04, 0x00, 0x0B, 0xD0, 0x00, 0xF0, 0xC2, 0xFB, + 0x04, 0x00, 0x07, 0xD0, 0x00, 0xF0, 0xA6, 0xFB, 0x04, 0x00, 0x03, 0xD0, + 0x0D, 0xF0, 0x08, 0xFD, 0x04, 0x00, 0x05, 0xD1, 0x05, 0x49, 0x00, 0x22, + 0x20, 0x31, 0x06, 0x48, 0xF7, 0xF7, 0x9D, 0xDE, 0x85, 0xF8, 0x95, 0x40, + 0x20, 0x46, 0x70, 0xBD, 0xD0, 0x74, 0x20, 0x00, 0x14, 0x00, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x00, 0x36, 0x10, 0x21, 0x7C, 0xB5, 0x36, 0x4D, + 0x36, 0x4C, 0x95, 0xF8, 0x8D, 0x31, 0x53, 0xB1, 0x48, 0x20, 0xCD, 0xE9, + 0x00, 0x40, 0xB5, 0xF8, 0x96, 0x21, 0x01, 0x21, 0x32, 0x48, 0x00, 0xF0, + 0x73, 0xF8, 0x00, 0x28, 0x5A, 0xD0, 0x95, 0xF8, 0x9C, 0x31, 0x73, 0xB1, + 0xB5, 0xF8, 0xA4, 0x01, 0x58, 0xB1, 0x51, 0x21, 0x1E, 0x30, 0x82, 0xB2, + 0xCD, 0xE9, 0x00, 0x41, 0x2A, 0x48, 0x01, 0x21, 0x80, 0x1C, 0x00, 0xF0, + 0x61, 0xF8, 0x00, 0x28, 0x48, 0xD0, 0x95, 0xF8, 0x9A, 0x31, 0x73, 0xB1, + 0xB5, 0xF8, 0xA0, 0x01, 0x58, 0xB1, 0x5B, 0x21, 0x1E, 0x30, 0x82, 0xB2, + 0xCD, 0xE9, 0x00, 0x41, 0x21, 0x48, 0x01, 0x21, 0xC0, 0x1C, 0x00, 0xF0, + 0x4F, 0xF8, 0x00, 0x28, 0x36, 0xD0, 0x95, 0xF8, 0x9B, 0x21, 0x72, 0xB1, + 0xB5, 0xF8, 0xA2, 0x01, 0x58, 0xB1, 0x65, 0x21, 0x1E, 0x30, 0x00, 0x91, + 0x81, 0xB2, 0x19, 0x48, 0x17, 0x4B, 0xC0, 0x1E, 0x80, 0x79, 0x00, 0xF0, + 0xEF, 0xF8, 0x00, 0x28, 0x24, 0xD0, 0x95, 0xF8, 0x9D, 0x31, 0x73, 0xB1, + 0xB5, 0xF8, 0xA6, 0x01, 0x58, 0xB1, 0x6F, 0x21, 0x1E, 0x30, 0x82, 0xB2, + 0xCD, 0xE9, 0x00, 0x41, 0x0F, 0x48, 0x01, 0x21, 0x40, 0x1C, 0x00, 0xF0, + 0x2B, 0xF8, 0x00, 0x28, 0x12, 0xD0, 0x95, 0xF8, 0x9E, 0x31, 0x73, 0xB1, + 0xB5, 0xF8, 0xA8, 0x01, 0x58, 0xB1, 0x79, 0x21, 0x1E, 0x30, 0x82, 0xB2, + 0xCD, 0xE9, 0x00, 0x41, 0x06, 0x48, 0x01, 0x21, 0x00, 0x1D, 0x00, 0xF0, + 0x19, 0xF8, 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xAC, 0xA6, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00, + 0x05, 0x49, 0x0A, 0x69, 0x82, 0x42, 0x04, 0xD8, 0x49, 0x69, 0x81, 0x42, + 0x01, 0xD3, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x7C, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x8B, 0x46, 0xDD, 0xE9, + 0x0C, 0x16, 0x14, 0x00, 0x82, 0x46, 0xDF, 0xF8, 0x94, 0x90, 0x1D, 0x46, + 0x4F, 0xF0, 0x00, 0x02, 0x4F, 0xF0, 0x05, 0x50, 0x24, 0xD0, 0x1D, 0xB3, + 0x00, 0x23, 0x21, 0x4F, 0x9C, 0x46, 0x17, 0xF8, 0x33, 0x80, 0x5F, 0xEA, + 0xC8, 0x78, 0x27, 0xD0, 0x5B, 0x1C, 0xDB, 0xB2, 0x08, 0x2B, 0xF6, 0xD3, + 0x08, 0x2B, 0x26, 0xD0, 0x8A, 0xF8, 0x00, 0x30, 0x10, 0x88, 0x40, 0xF0, + 0x01, 0x00, 0x40, 0xEA, 0x0B, 0x20, 0x10, 0x80, 0x16, 0x48, 0x54, 0x80, + 0x95, 0x80, 0x18, 0x38, 0xA2, 0xF8, 0x06, 0xC0, 0x01, 0x68, 0x10, 0x34, + 0x04, 0xFB, 0x05, 0x11, 0x01, 0x60, 0x01, 0x20, 0xBD, 0xE8, 0xFE, 0x8F, + 0xF7, 0xF7, 0xF3, 0xDF, 0x03, 0x46, 0x00, 0x96, 0x04, 0x22, 0x0E, 0x49, + 0x48, 0x46, 0xCD, 0xE9, 0x01, 0x45, 0xF7, 0xF7, 0xD0, 0xDD, 0x0E, 0xE0, + 0x07, 0xEB, 0xC3, 0x02, 0xA2, 0xF8, 0x00, 0xC0, 0xD6, 0xE7, 0xF7, 0xF7, + 0xE2, 0xDF, 0x07, 0x49, 0x03, 0x46, 0x02, 0x22, 0x44, 0x31, 0x48, 0x46, + 0x00, 0x96, 0xF7, 0xF7, 0xC0, 0xDD, 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x00, + 0x00, 0x36, 0x10, 0x21, 0x94, 0x75, 0x20, 0x00, 0x50, 0x00, 0xC0, 0x08, + 0x2D, 0xE9, 0xFF, 0x41, 0x08, 0x28, 0x02, 0xD3, 0x00, 0x24, 0x08, 0x25, + 0x02, 0xE0, 0x04, 0x46, 0x40, 0x1C, 0xC5, 0xB2, 0x24, 0x48, 0x26, 0x4E, + 0xD0, 0xE9, 0x01, 0x12, 0xCD, 0xE9, 0x00, 0x12, 0x03, 0x68, 0x03, 0x22, + 0x21, 0x49, 0x30, 0x46, 0xF7, 0xF7, 0xA1, 0xDD, 0x02, 0xF4, 0x38, 0xF6, + 0x1D, 0x4F, 0x80, 0x46, 0x18, 0x37, 0x15, 0xE0, 0x37, 0xF8, 0x34, 0x10, + 0xC8, 0x07, 0x0F, 0xD0, 0x07, 0xEB, 0xC4, 0x00, 0xC2, 0x88, 0x83, 0x88, + 0x40, 0x88, 0x00, 0x91, 0x03, 0x92, 0xCD, 0xE9, 0x01, 0x03, 0x16, 0x49, + 0x23, 0x46, 0x05, 0x22, 0x44, 0x31, 0x30, 0x46, 0xF7, 0xF7, 0x87, 0xDD, + 0x64, 0x1C, 0xE4, 0xB2, 0xAC, 0x42, 0xE7, 0xD3, 0x0F, 0x48, 0x58, 0x30, + 0x04, 0x68, 0x12, 0xE0, 0xE1, 0x68, 0x23, 0x68, 0x4A, 0x0F, 0xC1, 0xF3, + 0x04, 0x60, 0x21, 0xF0, 0x7F, 0x41, 0xCD, 0xE9, 0x00, 0x31, 0xCD, 0xE9, + 0x02, 0x02, 0x09, 0x49, 0x23, 0x46, 0x05, 0x22, 0x90, 0x31, 0x30, 0x46, + 0xF7, 0xF7, 0x6D, 0xDD, 0x24, 0x68, 0x00, 0x2C, 0xEA, 0xD1, 0x04, 0xB0, + 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x02, 0xF4, 0x0A, 0xB6, 0x00, 0x00, + 0x7C, 0x75, 0x20, 0x00, 0x20, 0x04, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, + 0x2D, 0xE9, 0xFE, 0x43, 0x04, 0x46, 0xDF, 0xF8, 0x90, 0x80, 0x0A, 0x9F, + 0x16, 0x46, 0x0D, 0x00, 0x4F, 0xF0, 0x05, 0x50, 0x0C, 0xD0, 0x5E, 0xB1, + 0x08, 0x2C, 0x17, 0xD3, 0x19, 0x46, 0xF7, 0xF7, 0x66, 0xDF, 0xCD, 0xE9, + 0x00, 0x74, 0x03, 0x46, 0x03, 0x22, 0x1C, 0x49, 0x40, 0x46, 0x2F, 0xE0, + 0x19, 0x46, 0xF7, 0xF7, 0x5C, 0xDF, 0x00, 0x97, 0x18, 0x49, 0xCD, 0xE9, + 0x01, 0x56, 0x03, 0x46, 0x04, 0x22, 0x44, 0x39, 0x40, 0x46, 0xF7, 0xF7, + 0x38, 0xDD, 0x23, 0xE0, 0x14, 0x49, 0x01, 0xEB, 0xC4, 0x04, 0x21, 0x78, + 0xC9, 0x07, 0x10, 0xD0, 0x60, 0x88, 0xA8, 0x42, 0x00, 0xD2, 0x65, 0x80, + 0xA0, 0x88, 0x30, 0x44, 0xA0, 0x80, 0x0E, 0x48, 0x18, 0x38, 0x10, 0x35, + 0x01, 0x68, 0x05, 0xFB, 0x02, 0x11, 0x01, 0x60, 0x01, 0x20, 0xBD, 0xE8, + 0xFE, 0x83, 0x19, 0x46, 0xF7, 0xF7, 0x37, 0xDF, 0x03, 0x46, 0x20, 0x88, + 0x05, 0x49, 0xCD, 0xE9, 0x00, 0x70, 0x03, 0x22, 0x3C, 0x31, 0x40, 0x46, + 0xF7, 0xF7, 0x13, 0xDD, 0x00, 0x20, 0xEE, 0xE7, 0x00, 0x36, 0x10, 0x21, + 0x10, 0x01, 0xC0, 0x08, 0x94, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x1D, 0x4C, + 0x09, 0xB1, 0x21, 0x60, 0x04, 0xE0, 0x21, 0x68, 0x91, 0x42, 0x01, 0xD9, + 0x89, 0x1A, 0xF8, 0xE7, 0x0D, 0x46, 0xF2, 0x23, 0x18, 0x4A, 0x02, 0xF4, + 0x91, 0xF2, 0x00, 0x28, 0x29, 0xD0, 0x02, 0x46, 0xC1, 0x06, 0x04, 0xD0, + 0x1F, 0x32, 0x22, 0xF0, 0x1F, 0x02, 0x10, 0x1A, 0x2D, 0x1A, 0x11, 0x4B, + 0x00, 0x21, 0x58, 0x33, 0x1A, 0x60, 0xD8, 0x68, 0x00, 0xF0, 0x7F, 0x40, + 0xD8, 0x60, 0x50, 0x19, 0x10, 0x38, 0x20, 0xF0, 0x1F, 0x00, 0xE0, 0x60, + 0x01, 0x60, 0xE1, 0x68, 0xCD, 0x68, 0x05, 0xF0, 0x7F, 0x45, 0xCD, 0x60, + 0x81, 0x1A, 0x10, 0x60, 0xD0, 0x68, 0x61, 0xF3, 0x17, 0x00, 0xD0, 0x60, + 0x20, 0xF0, 0x7F, 0x40, 0x60, 0x60, 0xA0, 0x60, 0x18, 0x68, 0x20, 0x61, + 0xE0, 0x68, 0x60, 0x61, 0x01, 0x20, 0x70, 0xBD, 0x7C, 0x75, 0x20, 0x00, + 0x78, 0xA6, 0x82, 0x00, 0x02, 0x68, 0x82, 0xB1, 0x8A, 0x42, 0x06, 0xD1, + 0x11, 0x68, 0x01, 0x60, 0x71, 0xB9, 0x00, 0x21, 0x41, 0x60, 0x0B, 0xE0, + 0x1A, 0x46, 0x13, 0x68, 0x2B, 0xB1, 0x8B, 0x42, 0xFA, 0xD1, 0x19, 0x68, + 0x11, 0x60, 0x11, 0xB1, 0x02, 0xE0, 0x00, 0x20, 0x70, 0x47, 0x42, 0x60, + 0x01, 0x20, 0x70, 0x47, 0x00, 0x22, 0x0A, 0x60, 0x42, 0x68, 0x12, 0xB1, + 0x11, 0x60, 0x41, 0x60, 0x70, 0x47, 0x01, 0x60, 0xFB, 0xE7, 0x00, 0x21, + 0x01, 0x60, 0x41, 0x60, 0x70, 0x47, 0x03, 0x68, 0x23, 0xB1, 0x41, 0xB1, + 0x08, 0x68, 0x10, 0x60, 0x0A, 0x60, 0x70, 0x47, 0x02, 0x60, 0x42, 0x60, + 0x00, 0x20, 0x10, 0x60, 0x70, 0x47, 0x13, 0x60, 0x02, 0x60, 0x70, 0x47, + 0x1C, 0xB5, 0x08, 0x48, 0x03, 0x22, 0xB0, 0xF8, 0x9C, 0x10, 0xB0, 0xF8, + 0x96, 0x30, 0xB0, 0xF8, 0x6C, 0x00, 0x18, 0x1A, 0xCD, 0xE9, 0x00, 0x01, + 0x03, 0x49, 0x04, 0x48, 0xF7, 0xF7, 0x87, 0xDC, 0x1C, 0xBD, 0x00, 0x00, + 0xD0, 0x74, 0x20, 0x00, 0xF8, 0x04, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, + 0x38, 0xB5, 0x1C, 0x46, 0x0B, 0x46, 0x40, 0xB1, 0x01, 0x68, 0xA1, 0xB1, + 0x14, 0x22, 0x18, 0x46, 0x09, 0x1D, 0x29, 0xF4, 0xCD, 0xF5, 0x01, 0x20, + 0x38, 0xBD, 0x11, 0x46, 0x4F, 0xF0, 0x05, 0x50, 0xF7, 0xF7, 0x87, 0xDE, + 0x03, 0x46, 0x02, 0x22, 0x04, 0x49, 0x05, 0x48, 0x00, 0x94, 0xF7, 0xF7, + 0x66, 0xDC, 0xFF, 0xF7, 0xCD, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00, + 0xE0, 0x05, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x38, 0xB5, 0x1C, 0x46, + 0x0B, 0x46, 0x70, 0xB1, 0x00, 0xF0, 0x70, 0xF8, 0x04, 0x00, 0x18, 0xD0, + 0x14, 0x22, 0x21, 0x1D, 0x18, 0x46, 0x29, 0xF4, 0xA9, 0xF5, 0x21, 0x46, + 0x0A, 0x48, 0x02, 0xF4, 0xAA, 0xF3, 0x01, 0x20, 0x38, 0xBD, 0x11, 0x46, + 0x4F, 0xF0, 0x05, 0x50, 0xF7, 0xF7, 0x5F, 0xDE, 0x03, 0x46, 0x02, 0x22, + 0x05, 0x49, 0x06, 0x48, 0x00, 0x94, 0xF7, 0xF7, 0x3E, 0xDC, 0xFF, 0xF7, + 0xA5, 0xFF, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00, 0x34, 0x75, 0x20, 0x00, + 0xA8, 0x05, 0xC0, 0x08, 0x00, 0x36, 0x10, 0x21, 0x2D, 0xE9, 0xFC, 0x47, + 0xDF, 0xF8, 0x84, 0x80, 0x1E, 0x46, 0x8A, 0x46, 0x05, 0x00, 0x91, 0x46, + 0x4F, 0xF0, 0x05, 0x57, 0x1D, 0xD0, 0x1E, 0x48, 0x02, 0xF4, 0x99, 0xF3, + 0x04, 0x00, 0x24, 0xD0, 0x1B, 0x49, 0x64, 0x39, 0xB1, 0xF8, 0x96, 0x00, + 0xB1, 0xF8, 0x6C, 0x20, 0x80, 0x1A, 0xB1, 0xF8, 0x9C, 0x20, 0x90, 0x42, + 0x01, 0xDD, 0xA1, 0xF8, 0x9C, 0x00, 0x14, 0x22, 0x51, 0x46, 0x20, 0x1D, + 0x29, 0xF4, 0x6A, 0xF5, 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x5A, 0xFF, + 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x87, 0x11, 0x46, 0x38, 0x46, 0xF7, 0xF7, + 0x20, 0xDE, 0x03, 0x46, 0x02, 0x22, 0x0D, 0x49, 0x40, 0x46, 0x00, 0x96, + 0xF7, 0xF7, 0xFF, 0xDB, 0x0C, 0xE0, 0x49, 0x46, 0x38, 0x46, 0xF7, 0xF7, + 0x14, 0xDE, 0x08, 0x49, 0xCD, 0xE9, 0x00, 0x65, 0x03, 0x46, 0x03, 0x22, + 0x38, 0x31, 0x40, 0x46, 0xF7, 0xF7, 0xF1, 0xDB, 0xFF, 0xF7, 0x58, 0xFF, + 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x36, 0x10, 0x21, 0x34, 0x75, 0x20, 0x00, + 0x34, 0x05, 0xC0, 0x08, 0x01, 0x46, 0x00, 0x68, 0x00, 0x28, 0x04, 0xD0, + 0x02, 0x68, 0x0A, 0x60, 0x00, 0x2A, 0x00, 0xD1, 0x4A, 0x60, 0x70, 0x47, + 0x00, 0x68, 0x70, 0x47, 0x01, 0x48, 0xB0, 0xF8, 0x78, 0x00, 0x70, 0x47, + 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x02, 0xF4, 0x6A, 0xF4, + 0x15, 0x4F, 0x04, 0x46, 0x97, 0xF8, 0x94, 0x00, 0x01, 0x28, 0x07, 0xD0, + 0x01, 0x20, 0x87, 0xF8, 0x94, 0x00, 0x07, 0xF1, 0x88, 0x09, 0x07, 0xF1, + 0x7C, 0x08, 0x16, 0xE0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x02, 0xF4, + 0x64, 0xB4, 0x48, 0x46, 0x02, 0xF4, 0x2F, 0xF3, 0x01, 0x46, 0x40, 0x68, + 0xD0, 0xE9, 0x00, 0x56, 0x40, 0x46, 0x02, 0xF4, 0x12, 0xF3, 0x20, 0x46, + 0x02, 0xF4, 0x57, 0xF4, 0x30, 0x46, 0xA8, 0x47, 0x02, 0xF4, 0x46, 0xF4, + 0x04, 0x46, 0xB7, 0xF8, 0x90, 0x00, 0x00, 0x28, 0xE9, 0xD1, 0x87, 0xF8, + 0x94, 0x00, 0xE1, 0xE7, 0xD0, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x3C, 0x4E, 0x3D, 0x4D, 0x4F, 0xF4, 0xE6, 0x73, 0xB6, 0xF8, 0x7A, 0x01, + 0xA5, 0xF8, 0x96, 0x00, 0xB6, 0xF8, 0x7E, 0x11, 0xA5, 0xF8, 0x98, 0x10, + 0xB6, 0xF8, 0x7C, 0x11, 0xA5, 0xF8, 0x9A, 0x10, 0x00, 0xEB, 0x40, 0x00, + 0xC1, 0x00, 0x35, 0x4A, 0x00, 0x20, 0x02, 0xF4, 0x1F, 0xF1, 0x04, 0x1E, + 0x5E, 0xD0, 0x00, 0x27, 0x05, 0xF1, 0x64, 0x08, 0x06, 0xE0, 0x21, 0x46, + 0x18, 0x34, 0x40, 0x46, 0x02, 0xF4, 0xDD, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2, + 0xB5, 0xF8, 0x96, 0x00, 0xB8, 0x42, 0xF4, 0xD8, 0xB5, 0xF8, 0x98, 0x00, + 0x40, 0xF2, 0xD9, 0x13, 0x00, 0xEB, 0x40, 0x00, 0xC1, 0x00, 0x27, 0x4A, + 0x00, 0x20, 0x02, 0xF4, 0x03, 0xF1, 0x04, 0x1E, 0x42, 0xD0, 0x00, 0x27, + 0x05, 0xF1, 0x70, 0x08, 0x06, 0xE0, 0x21, 0x46, 0x18, 0x34, 0x40, 0x46, + 0x02, 0xF4, 0xC1, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2, 0xB5, 0xF8, 0x98, 0x00, + 0xB8, 0x42, 0xF4, 0xD8, 0xB5, 0xF8, 0x9A, 0x00, 0x4F, 0xF4, 0xF3, 0x73, + 0xC1, 0x00, 0x1A, 0x4A, 0x00, 0x20, 0x02, 0xF4, 0xE9, 0xF0, 0x04, 0x1E, + 0x28, 0xD0, 0x00, 0x27, 0x05, 0xF1, 0x7C, 0x08, 0x06, 0xE0, 0x21, 0x46, + 0x08, 0x34, 0x40, 0x46, 0x02, 0xF4, 0xA7, 0xF2, 0x7F, 0x1C, 0xBF, 0xB2, + 0xB5, 0xF8, 0x9A, 0x00, 0xB8, 0x42, 0xF4, 0xD8, 0xB6, 0xF8, 0x80, 0x01, + 0x25, 0xF8, 0xA2, 0x0F, 0xB6, 0xF8, 0x82, 0x11, 0x69, 0x80, 0xCD, 0xE9, + 0x00, 0x01, 0x0A, 0x48, 0x0B, 0x4B, 0x0C, 0x4A, 0x0C, 0xA1, 0xA8, 0x30, + 0x02, 0xF4, 0x8C, 0xF4, 0x0E, 0x49, 0x04, 0x46, 0x09, 0x68, 0x21, 0xB9, + 0x01, 0x22, 0x11, 0x46, 0x0B, 0x48, 0x02, 0xF4, 0xDF, 0xF3, 0x20, 0x46, + 0xBD, 0xE8, 0xFC, 0x81, 0x64, 0x01, 0x20, 0x00, 0xD0, 0x74, 0x20, 0x00, + 0x8B, 0xA6, 0x82, 0x00, 0xAD, 0x08, 0x81, 0x00, 0x21, 0x0B, 0x81, 0x00, + 0x55, 0x70, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6B, 0x54, 0x61, + 0x73, 0x6B, 0x00, 0x00, 0xE4, 0x75, 0x20, 0x00, 0x04, 0x48, 0x00, 0x68, + 0x08, 0xB1, 0x02, 0xF4, 0xFC, 0xB3, 0x00, 0x22, 0x02, 0x49, 0x03, 0x48, + 0xF7, 0xF7, 0x09, 0x9B, 0xE4, 0x75, 0x20, 0x00, 0x10, 0x09, 0xC0, 0x08, + 0x00, 0x36, 0x10, 0x21, 0x10, 0xB5, 0x0C, 0xF0, 0x4D, 0xF9, 0x00, 0x28, + 0x0F, 0xD0, 0x0E, 0xF0, 0x9B, 0xFC, 0x00, 0x28, 0x0B, 0xD0, 0x17, 0xF0, + 0xED, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x09, 0xF0, 0x69, 0xFC, 0x00, 0x28, + 0x03, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0xF0, 0x2B, 0xBE, 0x10, 0xBD, + 0x0D, 0xF0, 0x4E, 0xB9, 0x10, 0xB5, 0x00, 0xF0, 0x11, 0xF8, 0x00, 0x28, + 0x0B, 0xD0, 0xFF, 0xF7, 0x53, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x04, 0x48, + 0xD0, 0xE9, 0x61, 0x12, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x20, 0xFF, 0xF7, + 0xCF, 0xBD, 0x10, 0xBD, 0x64, 0x01, 0x20, 0x00, 0x7C, 0xB5, 0x1A, 0x4C, + 0x1A, 0x4D, 0x94, 0xF8, 0x8F, 0x31, 0x5B, 0xB1, 0xB4, 0xF8, 0x92, 0x21, + 0x42, 0xB1, 0x24, 0x20, 0xCD, 0xE9, 0x00, 0x50, 0x01, 0x21, 0x16, 0x48, + 0xFF, 0xF7, 0xB8, 0xFC, 0x00, 0x28, 0x22, 0xD0, 0x94, 0xF8, 0x8C, 0x31, + 0x63, 0xB1, 0xB4, 0xF8, 0x94, 0x21, 0x4A, 0xB1, 0x2D, 0x20, 0xCD, 0xE9, + 0x00, 0x50, 0x0F, 0x48, 0x01, 0x21, 0x80, 0x1C, 0xFF, 0xF7, 0xA8, 0xFC, + 0x00, 0x28, 0x12, 0xD0, 0xB4, 0xF8, 0x90, 0x01, 0x70, 0xB1, 0x94, 0xF8, + 0x8E, 0x31, 0x5B, 0xB1, 0x37, 0x21, 0x22, 0x30, 0x82, 0xB2, 0xCD, 0xE9, + 0x00, 0x51, 0x06, 0x48, 0x01, 0x21, 0x40, 0x1C, 0xFF, 0xF7, 0x96, 0xFC, + 0x00, 0x28, 0x00, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x64, 0x01, 0x20, 0x00, + 0x9A, 0xA6, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x05, 0x4D, 0x04, 0x46, + 0x4F, 0xF0, 0xFF, 0x36, 0x28, 0x68, 0x10, 0xB1, 0x31, 0x46, 0x02, 0xF4, + 0x6D, 0xF3, 0xA0, 0x47, 0xF8, 0xE7, 0x00, 0x00, 0xE4, 0x75, 0x20, 0x00, + 0x01, 0xB5, 0x86, 0xB0, 0x05, 0xA9, 0x06, 0xA8, 0x02, 0xF4, 0xA8, 0xF4, + 0x00, 0x28, 0x11, 0xD0, 0x4F, 0xF4, 0xC0, 0x60, 0xAD, 0xF8, 0x00, 0x00, + 0x05, 0x99, 0x18, 0x23, 0x08, 0x0E, 0x8D, 0xF8, 0x04, 0x00, 0x0A, 0x0C, + 0x8D, 0xF8, 0x05, 0x20, 0xAD, 0xF8, 0x06, 0x10, 0x02, 0x4A, 0x69, 0x46, + 0xFF, 0xF7, 0x0E, 0xFB, 0x07, 0xB0, 0x00, 0xBD, 0xBD, 0xA6, 0x82, 0x00, + 0x7C, 0xB5, 0x04, 0x00, 0x02, 0xD0, 0x20, 0x68, 0x10, 0xB1, 0x0A, 0xE0, + 0x00, 0x20, 0x7C, 0xBD, 0x06, 0x4D, 0x00, 0x20, 0xCD, 0xE9, 0x00, 0x05, + 0x20, 0x46, 0x02, 0xF4, 0x9C, 0xF4, 0x00, 0x28, 0xF5, 0xD0, 0x20, 0x46, + 0xBD, 0xE8, 0x7C, 0x40, 0x02, 0xF4, 0xB8, 0xB4, 0x3D, 0x0B, 0x81, 0x00, + 0x02, 0xF4, 0xE9, 0xB4, 0x10, 0xB5, 0x8C, 0xB0, 0x08, 0x24, 0x8D, 0xF8, + 0x0B, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, + 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x1B, 0xB1, 0x18, 0x68, + 0x03, 0x90, 0x58, 0x68, 0x01, 0xE0, 0x00, 0x20, 0x03, 0x90, 0x04, 0x90, + 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0xB4, 0xFA, 0x0C, 0xB0, 0x10, 0xBD, + 0x00, 0xB5, 0x0C, 0x49, 0x93, 0xB0, 0x09, 0x7A, 0x00, 0x29, 0x11, 0xD0, + 0x05, 0x21, 0xAD, 0xF8, 0x0A, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0x0C, 0xA8, + 0x0B, 0xF0, 0xFE, 0xFD, 0x0C, 0x98, 0x01, 0x90, 0xBD, 0xF8, 0x34, 0x00, + 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x9A, 0xFA, + 0x13, 0xB0, 0x00, 0xBD, 0xD0, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x12, 0x4A, + 0x12, 0x4B, 0x05, 0x46, 0x00, 0x20, 0xD2, 0x68, 0x93, 0xF8, 0x98, 0x31, + 0x05, 0xE0, 0x02, 0xEB, 0x40, 0x14, 0x26, 0x7D, 0x56, 0xB1, 0x40, 0x1C, + 0x80, 0xB2, 0x83, 0x42, 0xF7, 0xD8, 0x00, 0x24, 0x22, 0x46, 0x0B, 0x49, + 0x0B, 0x48, 0xF7, 0xF7, 0x06, 0xDA, 0x0A, 0xE0, 0x4C, 0xB1, 0x28, 0x68, + 0xC4, 0xF8, 0x16, 0x00, 0xA8, 0x88, 0x60, 0x83, 0x61, 0x75, 0x01, 0x20, + 0x20, 0x75, 0x20, 0x77, 0x60, 0x77, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, + 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xC0, 0x57, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x90, 0xB0, 0x1A, 0x26, 0xDD, 0xE9, + 0x14, 0x54, 0xAD, 0xF8, 0x00, 0x60, 0x00, 0xB9, 0x0E, 0x48, 0x03, 0xB9, + 0x0D, 0x4B, 0x1C, 0x2A, 0x00, 0xD9, 0x1C, 0x22, 0x8D, 0xF8, 0x0A, 0x10, + 0x8D, 0xF8, 0x28, 0x50, 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x29, 0x40, + 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x19, 0x46, + 0x03, 0xA8, 0x29, 0xF4, 0xE4, 0xF2, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, + 0xED, 0xF9, 0x10, 0xB0, 0x70, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00, + 0x10, 0xB5, 0x90, 0xB0, 0x18, 0x24, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0xB9, + 0x08, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0C, 0x30, 0x8D, 0xF8, + 0x0B, 0x20, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0xD2, 0xF9, 0x10, 0xB0, 0x10, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x70, 0xB5, 0x8C, 0xB0, 0x17, 0x26, 0xDD, 0xE9, + 0x10, 0x54, 0xAD, 0xF8, 0x02, 0x60, 0x06, 0x68, 0x01, 0x96, 0x80, 0x88, + 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, + 0x0D, 0xF1, 0x0D, 0x00, 0x1B, 0xB1, 0x19, 0x46, 0x29, 0xF4, 0xAB, 0xF2, + 0x02, 0xE0, 0x11, 0x46, 0x29, 0xF4, 0x26, 0xF3, 0x8D, 0xF8, 0x0C, 0x50, + 0xAD, 0xF8, 0x2A, 0x40, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x04, 0xFA, + 0x0C, 0xB0, 0x70, 0xBD, 0x1C, 0x2A, 0x01, 0xD2, 0x00, 0x20, 0x70, 0x47, + 0x11, 0x44, 0x89, 0xB2, 0xC0, 0xB2, 0x4F, 0xF4, 0xB9, 0x73, 0x01, 0x4A, + 0xFE, 0xF7, 0x12, 0xBF, 0xB8, 0xAD, 0x82, 0x00, 0x40, 0xF2, 0x95, 0x12, + 0x01, 0x49, 0xFE, 0xF7, 0xF9, 0xBF, 0x00, 0x00, 0xC8, 0xAD, 0x82, 0x00, + 0x01, 0x00, 0x4F, 0xF0, 0x00, 0x00, 0x40, 0xF2, 0x05, 0x22, 0x06, 0xD0, + 0x09, 0x7D, 0x0B, 0x29, 0x04, 0xD0, 0x0C, 0x29, 0x03, 0xD0, 0x0D, 0x29, + 0x01, 0xD0, 0x10, 0x46, 0x70, 0x47, 0x4F, 0xF4, 0x3D, 0x70, 0x70, 0x47, + 0x10, 0xB5, 0x00, 0xF0, 0xE1, 0xF8, 0x20, 0xB1, 0x01, 0x7D, 0x0B, 0x29, + 0x03, 0xD0, 0x03, 0x29, 0x01, 0xD0, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x8A, + 0x10, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0xF0, 0xD2, 0xF8, + 0x10, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x07, 0xD0, 0x23, 0x46, 0x01, 0x22, + 0x03, 0x49, 0x04, 0x48, 0xF7, 0xF7, 0x45, 0xD9, 0x00, 0x20, 0x10, 0xBD, + 0x00, 0x8A, 0x10, 0xBD, 0x44, 0x58, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0xFF, 0xF7, 0x76, 0xBA, 0x01, 0x28, 0x03, 0xD0, 0x03, 0x28, 0x01, 0xD0, + 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0xB5, 0x8D, 0xB0, + 0x2C, 0x22, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0xA8, 0x29, 0xF4, 0x84, 0xF2, + 0x68, 0x46, 0x15, 0xF0, 0xD7, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, + 0x8D, 0xB0, 0x2C, 0x22, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0xA8, 0x29, 0xF4, + 0x77, 0xF2, 0x9D, 0xF8, 0x0B, 0x00, 0x01, 0x28, 0x06, 0xD0, 0x07, 0x28, + 0x02, 0xD3, 0x68, 0x46, 0x15, 0xF0, 0x20, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0x22, 0x69, 0x46, 0x04, 0x20, 0x08, 0xF0, 0x6D, 0xF9, 0xF7, 0xE7, + 0x2D, 0xE9, 0xF0, 0x41, 0x15, 0x46, 0x0E, 0x46, 0x00, 0xF0, 0x8A, 0xF8, + 0x07, 0x46, 0xD6, 0xB1, 0xCF, 0xB1, 0x1C, 0x48, 0x40, 0xF2, 0xFF, 0x23, + 0x19, 0x4A, 0x08, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x91, 0xFE, 0x04, 0x1E, + 0x10, 0xD0, 0xC5, 0xB1, 0x17, 0x48, 0x40, 0xF2, 0x07, 0x33, 0x14, 0x4A, + 0x30, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x86, 0xFE, 0x05, 0x00, 0x07, 0xD0, + 0x30, 0x22, 0x31, 0x46, 0x29, 0xF4, 0xFF, 0xF1, 0x0A, 0xE0, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x81, 0x73, 0x88, 0x01, 0x22, 0x0E, 0x49, 0x0F, 0x48, + 0xF7, 0xF7, 0xE1, 0xD8, 0xF5, 0xE7, 0x35, 0x46, 0x0B, 0x49, 0x0C, 0x48, + 0x73, 0x88, 0x01, 0x22, 0x2C, 0x31, 0x80, 0x1C, 0xF7, 0xF7, 0xD7, 0xD8, + 0x00, 0x20, 0xC4, 0xE9, 0x00, 0x05, 0x21, 0x46, 0x38, 0x1D, 0x02, 0xF4, + 0x2E, 0xF0, 0x01, 0x20, 0xE4, 0xE7, 0x00, 0x00, 0xE2, 0xAE, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x02, 0x74, 0x20, 0x00, 0x94, 0x53, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x10, 0x48, 0x85, 0xB0, 0x21, 0x23, + 0x0D, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xFF, 0xF7, 0x03, 0xF9, 0x00, 0x28, + 0x0D, 0xD0, 0xBD, 0xF8, 0x00, 0x00, 0xB0, 0xF5, 0x80, 0x7F, 0x0A, 0xD0, + 0xB0, 0xF5, 0xC0, 0x6F, 0x05, 0xD1, 0xBD, 0xF8, 0x06, 0x10, 0x9D, 0xF8, + 0x05, 0x00, 0x02, 0xF0, 0x23, 0xFB, 0x05, 0xB0, 0x00, 0xBD, 0x03, 0x98, + 0x01, 0xF0, 0x18, 0xF9, 0xF9, 0xE7, 0x00, 0x00, 0x8D, 0xAE, 0x82, 0x00, + 0xCC, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24, + 0x0C, 0x4E, 0x0D, 0x4F, 0x0D, 0xE0, 0xF0, 0x68, 0x00, 0xEB, 0x44, 0x15, + 0x28, 0x7D, 0x30, 0xB1, 0x06, 0x22, 0x41, 0x46, 0x05, 0xF1, 0x16, 0x00, + 0x29, 0xF4, 0x56, 0xF1, 0x40, 0xB1, 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8, + 0x98, 0x01, 0xA0, 0x42, 0xED, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x28, 0x46, 0xFB, 0xE7, 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x70, 0xB5, 0x0E, 0x49, 0x03, 0x46, 0x00, 0x20, 0xCA, 0x68, 0x0D, 0x49, + 0x91, 0xF8, 0x98, 0x41, 0x0A, 0xE0, 0x02, 0xEB, 0x40, 0x11, 0x0D, 0x7D, + 0x25, 0xB1, 0x0D, 0x8A, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, + 0x40, 0x1C, 0x80, 0xB2, 0x84, 0x42, 0xF2, 0xD8, 0x01, 0x22, 0x05, 0x49, + 0x05, 0x48, 0xF7, 0xF7, 0x62, 0xD8, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0xD0, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x58, 0x57, 0xC0, 0x08, + 0x01, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x21, 0x11, + 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x04, 0xF0, 0x6C, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x0F, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x04, 0xF0, 0x5A, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0x8F, 0x72, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x04, 0xF0, 0x4A, 0xF8, + 0x11, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0xDD, 0xE9, + 0x08, 0xA7, 0x04, 0x1D, 0x98, 0x46, 0x91, 0x46, 0x0E, 0x46, 0x38, 0x46, + 0xFF, 0xF7, 0xC8, 0xFE, 0xB9, 0xF1, 0x00, 0x0F, 0x02, 0xD0, 0x4F, 0xF4, + 0x91, 0x71, 0x01, 0xE0, 0x4F, 0xF4, 0x90, 0x71, 0x69, 0x80, 0x27, 0x80, + 0xA4, 0xF8, 0x02, 0x80, 0xA4, 0xF8, 0x04, 0xA0, 0x0C, 0x3E, 0xE6, 0x80, + 0x20, 0xB1, 0x00, 0x21, 0x28, 0x46, 0x04, 0xF0, 0x7F, 0xF8, 0x04, 0xE0, + 0x00, 0x22, 0x29, 0x46, 0x38, 0x46, 0xFF, 0xF7, 0xF3, 0xFE, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x87, 0x2D, 0xE9, 0xF8, 0x43, 0x1D, 0x46, 0xDD, 0xE9, + 0x09, 0x43, 0xDD, 0xF8, 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x5C, 0xB1, + 0x08, 0xB1, 0x12, 0x2B, 0x16, 0xD2, 0x02, 0x22, 0x12, 0x49, 0x13, 0x48, + 0x00, 0x94, 0xF6, 0xF7, 0xEA, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, + 0x08, 0xB1, 0xFF, 0xF7, 0x69, 0xFE, 0x10, 0x48, 0x40, 0xF2, 0x2D, 0x43, + 0x0D, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x71, 0xFD, 0x00, 0x28, + 0xF0, 0xD0, 0x00, 0x23, 0x40, 0xF2, 0x0D, 0x11, 0x01, 0x80, 0x07, 0x81, + 0x46, 0x60, 0x45, 0x81, 0xA0, 0xF8, 0x0C, 0x80, 0xC4, 0x81, 0x03, 0x82, + 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0xEB, 0xBF, 0x00, 0x00, + 0xB0, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x39, 0xAE, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0xF8, 0xB5, 0xDD, 0xE9, 0x06, 0x54, 0x38, 0xB1, + 0x10, 0x2C, 0x05, 0xD3, 0x0E, 0x4E, 0xB6, 0xF8, 0xAE, 0x61, 0x76, 0x1F, + 0x9E, 0x42, 0x08, 0xDA, 0x00, 0x93, 0x23, 0x46, 0x02, 0x22, 0x0B, 0x49, + 0x0B, 0x48, 0xF6, 0xF7, 0xAE, 0xDF, 0x00, 0x20, 0xF8, 0xBD, 0x4F, 0xF4, + 0x8E, 0x76, 0x06, 0x80, 0x81, 0x80, 0x03, 0x21, 0x81, 0x71, 0x02, 0x81, + 0x43, 0x81, 0x85, 0x81, 0xC4, 0x81, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21, + 0x03, 0xF0, 0xBE, 0xBF, 0x64, 0x01, 0x20, 0x00, 0xF4, 0x50, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0xF0, 0xB4, 0x04, 0x46, 0xDD, 0xE9, 0x04, 0x56, + 0x40, 0xF2, 0x1D, 0x10, 0x60, 0x80, 0xA6, 0x80, 0xE5, 0x80, 0x23, 0x81, + 0x62, 0x81, 0x0E, 0x39, 0xA1, 0x81, 0x20, 0x46, 0xF0, 0xBC, 0x00, 0x21, + 0x03, 0xF0, 0xFE, 0xBF, 0x2D, 0xE9, 0xF8, 0x43, 0x1D, 0x46, 0xDD, 0xE9, + 0x09, 0x43, 0xDD, 0xF8, 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x8C, 0xB1, + 0x38, 0xB1, 0x12, 0x2B, 0x05, 0xD3, 0x16, 0x49, 0xB1, 0xF8, 0xAE, 0x11, + 0x49, 0x1E, 0xA1, 0x42, 0x16, 0xDA, 0x02, 0x22, 0x13, 0x49, 0x14, 0x48, + 0x00, 0x94, 0xF6, 0xF7, 0x6C, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, + 0x08, 0xB1, 0xFF, 0xF7, 0xEB, 0xFD, 0x11, 0x48, 0x40, 0xF2, 0xF1, 0x33, + 0x0E, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0xF3, 0xFC, 0x00, 0x28, + 0xF0, 0xD0, 0x00, 0x23, 0x40, 0xF2, 0x09, 0x11, 0x01, 0x80, 0x07, 0x81, + 0x46, 0x60, 0x45, 0x81, 0xA0, 0xF8, 0x0C, 0x80, 0xC4, 0x81, 0x03, 0x82, + 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0x6D, 0xBF, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x74, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0x21, 0xAE, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x07, 0x46, + 0x8D, 0xB0, 0x15, 0x46, 0x0E, 0x46, 0x1C, 0x46, 0x18, 0x46, 0xFF, 0xF7, + 0xE5, 0xFD, 0x4F, 0xF4, 0x84, 0x71, 0xAD, 0xF8, 0x0C, 0x60, 0xAD, 0xF8, + 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x40, 0x02, 0x97, 0xAD, 0xF8, 0x0E, 0x50, + 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xA1, 0xFF, 0x0D, 0xB0, + 0xF0, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x14, 0xFE, + 0xF7, 0xE7, 0x00, 0x00, 0xF0, 0xB5, 0x91, 0xB0, 0x0C, 0x46, 0xDD, 0xE9, + 0x17, 0x51, 0x4F, 0xF4, 0x8B, 0x77, 0x16, 0x9E, 0xAD, 0xF8, 0x00, 0x70, + 0x01, 0xB9, 0x0B, 0x49, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x08, 0x20, + 0xAD, 0xF8, 0x0C, 0x60, 0x8D, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x30, + 0xAD, 0xF8, 0x0E, 0x50, 0x10, 0x22, 0x04, 0xA8, 0x29, 0xF4, 0x17, 0xF0, + 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x20, 0xFF, 0x11, 0xB0, 0xF0, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x5F, 0x99, 0x46, 0xDD, 0xE9, + 0x0E, 0xA6, 0xDD, 0xE9, 0x0C, 0x8B, 0x17, 0x46, 0x0D, 0x46, 0x04, 0x00, + 0x01, 0xD0, 0x02, 0x46, 0x09, 0xE0, 0x1F, 0x48, 0x40, 0xF2, 0xE9, 0x43, + 0x1C, 0x4A, 0x30, 0x21, 0x00, 0x78, 0xFE, 0xF7, 0x7B, 0xFC, 0x02, 0x00, + 0x0B, 0xD0, 0x40, 0xF2, 0x17, 0x10, 0x50, 0x80, 0xA2, 0xF8, 0x04, 0xA0, + 0x97, 0x71, 0x10, 0x1D, 0xA2, 0xF8, 0x08, 0xB0, 0x24, 0xB1, 0x14, 0x2D, + 0x15, 0xD2, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x9F, 0x00, 0x21, 0xC1, 0x80, + 0x01, 0x81, 0x41, 0x81, 0x81, 0x81, 0xC1, 0x81, 0x01, 0x2F, 0x14, 0xD1, + 0xB8, 0xF1, 0x01, 0x0F, 0x11, 0xD1, 0x02, 0x21, 0x01, 0x81, 0x01, 0x21, + 0x81, 0x81, 0x06, 0x74, 0x31, 0x0A, 0x41, 0x74, 0x09, 0xE0, 0xA0, 0xF8, + 0x06, 0x90, 0x0A, 0x99, 0x01, 0x81, 0x0B, 0x99, 0x41, 0x81, 0xA0, 0xF8, + 0x0C, 0x80, 0x14, 0x3D, 0xC5, 0x81, 0x00, 0x21, 0x10, 0x46, 0x03, 0xF0, + 0x2D, 0xFF, 0x00, 0x20, 0xDA, 0xE7, 0x00, 0x00, 0x0E, 0xAF, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x8C, 0xB0, 0x80, 0x46, + 0xDD, 0xE9, 0x15, 0x94, 0x1D, 0x46, 0x17, 0x46, 0x0E, 0x46, 0x20, 0x46, + 0xDD, 0xF8, 0x50, 0xA0, 0xFF, 0xF7, 0x4C, 0xFD, 0x4F, 0xF4, 0x83, 0x71, + 0xAD, 0xF8, 0x02, 0x10, 0xCD, 0xE9, 0x01, 0x67, 0xAD, 0xF8, 0x0C, 0x40, + 0xAD, 0xF8, 0x0E, 0x80, 0xAD, 0xF8, 0x10, 0x90, 0x8D, 0xF8, 0x18, 0x50, + 0xDA, 0xF8, 0x00, 0x20, 0xCD, 0xF8, 0x12, 0x20, 0xBA, 0xF8, 0x04, 0x10, + 0xAD, 0xF8, 0x16, 0x10, 0x30, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, + 0xFD, 0xFE, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x01, 0x22, 0x69, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0x6F, 0xFD, 0xF6, 0xE7, 0x2D, 0xE9, 0xF8, 0x43, + 0x1D, 0x46, 0xDD, 0xE9, 0x09, 0x43, 0xDD, 0xF8, 0x2C, 0x90, 0xDD, 0xF8, + 0x20, 0x80, 0x16, 0x46, 0x0F, 0x46, 0x8C, 0xB1, 0x38, 0xB1, 0x16, 0x2B, + 0x05, 0xD3, 0x17, 0x49, 0xB1, 0xF8, 0xAE, 0x11, 0xC9, 0x1E, 0xA1, 0x42, + 0x16, 0xDA, 0x02, 0x22, 0x14, 0x49, 0x15, 0x48, 0x00, 0x94, 0xF6, 0xF7, + 0x60, 0xDE, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x08, 0xB1, 0xFF, 0xF7, + 0xDF, 0xFC, 0x12, 0x48, 0x40, 0xF2, 0xA6, 0x33, 0x0F, 0x4A, 0x40, 0x21, + 0x00, 0x78, 0xFE, 0xF7, 0xE7, 0xFB, 0x00, 0x28, 0xF0, 0xD0, 0x00, 0x23, + 0x4F, 0xF4, 0x82, 0x71, 0x01, 0x80, 0x85, 0x60, 0xA0, 0xF8, 0x10, 0x80, + 0xC7, 0x81, 0x46, 0x60, 0x44, 0x82, 0x80, 0xF8, 0x0C, 0x90, 0x83, 0x82, + 0xBD, 0xE8, 0xF8, 0x43, 0x00, 0x21, 0x03, 0xF0, 0x5F, 0xBE, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x34, 0x50, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0x07, 0xAE, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x05, 0x15, 0x10, 0x9C, 0xAD, 0xF8, 0x0C, 0x00, 0x01, 0x91, + 0xAD, 0xF8, 0x02, 0x50, 0xAD, 0xF8, 0x10, 0x40, 0xAD, 0xF8, 0x0E, 0x30, + 0x01, 0x21, 0x68, 0x46, 0x02, 0x92, 0x03, 0xF0, 0x99, 0xFE, 0x0D, 0xB0, + 0x30, 0xBD, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x07, 0x14, 0xAD, 0xF8, + 0x00, 0x40, 0xCD, 0xE9, 0x01, 0x12, 0xAD, 0xF8, 0x0E, 0x30, 0xAD, 0xF8, + 0x0C, 0x00, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x2F, 0xFE, 0x10, 0xB0, + 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x05, 0x46, 0xDD, 0xE9, 0x0A, 0xAB, + 0xDD, 0xF8, 0x34, 0x80, 0x04, 0x1D, 0x1F, 0x46, 0x91, 0x46, 0x0E, 0x46, + 0x40, 0x46, 0xFF, 0xF7, 0xAB, 0xFC, 0x01, 0x46, 0x16, 0x2E, 0x02, 0xD2, + 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x9F, 0x48, 0x46, 0xB9, 0xF1, 0x01, 0x0F, + 0x1E, 0xD0, 0x02, 0x28, 0x05, 0xD0, 0x03, 0x28, 0x1D, 0xD0, 0xB9, 0xF1, + 0x05, 0x0F, 0x06, 0xD1, 0x02, 0xE0, 0x4F, 0xF4, 0x88, 0x70, 0x01, 0xE0, + 0x40, 0xF2, 0xB7, 0x10, 0x68, 0x80, 0xA4, 0xF8, 0x00, 0x80, 0x67, 0x60, + 0xA4, 0xF8, 0x08, 0xA0, 0xA4, 0xF8, 0x0A, 0xB0, 0x0C, 0x98, 0xE0, 0x81, + 0x16, 0x3E, 0x26, 0x82, 0x51, 0xB1, 0x00, 0x21, 0x28, 0x46, 0x03, 0xF0, + 0x4F, 0xFE, 0x0A, 0xE0, 0x4F, 0xF4, 0x85, 0x70, 0xEA, 0xE7, 0x4F, 0xF4, + 0x86, 0x70, 0xE7, 0xE7, 0x00, 0x22, 0x29, 0x46, 0x40, 0x46, 0xFF, 0xF7, + 0xBD, 0xFC, 0x00, 0x20, 0xCD, 0xE7, 0x00, 0x00, 0xF8, 0xB5, 0x1D, 0x46, + 0xDD, 0xE9, 0x06, 0x43, 0x38, 0xB1, 0x10, 0x2B, 0x05, 0xD3, 0x0E, 0x4E, + 0xB6, 0xF8, 0xAE, 0x61, 0xF6, 0x1E, 0xA6, 0x42, 0x07, 0xDA, 0x02, 0x22, + 0x0B, 0x49, 0x0C, 0x48, 0x00, 0x94, 0xF6, 0xF7, 0xB4, 0xDD, 0x00, 0x20, + 0xF8, 0xBD, 0x4F, 0xF4, 0x8D, 0x76, 0x06, 0x80, 0x81, 0x80, 0x82, 0x71, + 0x05, 0x81, 0x44, 0x81, 0x00, 0x21, 0x81, 0x81, 0xC3, 0x81, 0xBD, 0xE8, + 0xF8, 0x40, 0x03, 0xF0, 0xC5, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x38, 0x51, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0, + 0x40, 0xF2, 0x0B, 0x14, 0xAD, 0xF8, 0x04, 0x00, 0x02, 0x91, 0xAD, 0xF8, + 0x0C, 0x20, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0E, 0x30, 0x01, 0x21, + 0x68, 0x46, 0x03, 0xF0, 0xAD, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x10, 0xB5, + 0x8C, 0xB0, 0x40, 0xF2, 0x1B, 0x14, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, + 0x04, 0x00, 0x00, 0x24, 0xAD, 0xF8, 0x0C, 0x40, 0x8D, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x0E, 0x40, 0xAD, 0xF8, 0x0A, 0x30, + 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xEC, 0xFD, 0x0C, 0xB0, 0x10, 0xBD, + 0x2D, 0xE9, 0xF0, 0x47, 0x05, 0x46, 0xDD, 0xF8, 0x20, 0x90, 0x04, 0x1D, + 0x98, 0x46, 0x17, 0x46, 0x0E, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0x12, 0xFC, + 0x40, 0xF2, 0x11, 0x11, 0x69, 0x80, 0xA4, 0xF8, 0x00, 0x90, 0x67, 0x60, + 0xA4, 0xF8, 0x08, 0x80, 0x10, 0x3E, 0x66, 0x81, 0x20, 0xB1, 0x00, 0x21, + 0x28, 0x46, 0x03, 0xF0, 0xCF, 0xFD, 0x04, 0xE0, 0x00, 0x22, 0x29, 0x46, + 0x48, 0x46, 0xFF, 0xF7, 0x43, 0xFC, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, + 0x2D, 0xE9, 0xF0, 0x43, 0x87, 0xB0, 0x1D, 0x46, 0x91, 0x46, 0x0F, 0x46, + 0x80, 0x46, 0xFF, 0xF7, 0xA5, 0xFC, 0x04, 0x00, 0x4F, 0xF0, 0x00, 0x06, + 0x06, 0xD1, 0x00, 0x96, 0x68, 0x46, 0x01, 0x96, 0xFF, 0xF7, 0x9C, 0xFC, + 0x04, 0x00, 0x2B, 0xD0, 0x41, 0x46, 0x39, 0x48, 0xF6, 0xF7, 0x04, 0xDF, + 0x03, 0x46, 0x20, 0x7D, 0x00, 0x97, 0xCD, 0xE9, 0x01, 0x40, 0x04, 0x22, + 0x35, 0x49, 0x36, 0x48, 0xF6, 0xF7, 0x2B, 0xDD, 0x27, 0x82, 0xD5, 0xF8, + 0x01, 0x00, 0xC4, 0xF8, 0x16, 0x00, 0xB5, 0xF8, 0x05, 0x00, 0x60, 0x83, + 0xE8, 0x79, 0x60, 0x75, 0x20, 0x46, 0xFF, 0xF7, 0xC7, 0xFA, 0x23, 0x7D, + 0x03, 0x2B, 0x14, 0xD0, 0x08, 0x2B, 0x12, 0xD0, 0x09, 0x2B, 0x2B, 0xD0, + 0x07, 0xB0, 0x29, 0x49, 0xBD, 0xE8, 0xF0, 0x43, 0x28, 0x48, 0x01, 0x22, + 0x48, 0x31, 0x80, 0x1E, 0xF6, 0xF7, 0x0D, 0x9D, 0x07, 0xB0, 0x40, 0x46, + 0xBD, 0xE8, 0xF0, 0x43, 0x13, 0x21, 0x07, 0xF0, 0xE7, 0xBD, 0xE8, 0x89, + 0xA9, 0x89, 0x6A, 0x89, 0x05, 0x96, 0x02, 0x92, 0xCD, 0xE9, 0x03, 0x10, + 0x29, 0x78, 0x28, 0x7A, 0xCD, 0xE9, 0x00, 0x01, 0x62, 0x7D, 0x4B, 0x46, + 0x04, 0xF1, 0x16, 0x01, 0x20, 0x46, 0x02, 0xF0, 0xA3, 0xFA, 0x0B, 0x20, + 0x20, 0x75, 0x20, 0x8A, 0x07, 0xB0, 0x01, 0x21, 0xBD, 0xE8, 0xF0, 0x43, + 0x03, 0xF0, 0x14, 0xBC, 0xE9, 0x89, 0xA8, 0x89, 0x6A, 0x89, 0x03, 0xAB, + 0x02, 0x92, 0x83, 0xE8, 0x43, 0x00, 0x29, 0x78, 0x28, 0x7A, 0xCD, 0xE9, + 0x00, 0x01, 0x62, 0x7D, 0x4B, 0x46, 0x04, 0xF1, 0x16, 0x01, 0x20, 0x46, + 0x02, 0xF0, 0x88, 0xFA, 0x20, 0x8A, 0x01, 0x21, 0x03, 0xF0, 0xFE, 0xFB, + 0x61, 0x8A, 0x20, 0x8A, 0x02, 0xF0, 0x4C, 0xFD, 0x00, 0x22, 0x20, 0x8A, + 0x11, 0x46, 0x06, 0xF0, 0x25, 0xFF, 0x07, 0xB0, 0x20, 0x46, 0xBD, 0xE8, + 0xF0, 0x43, 0x03, 0xF0, 0x91, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0xF0, 0x58, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0xF8, 0xB5, 0x0E, 0x46, + 0x05, 0x46, 0x01, 0x46, 0x14, 0x46, 0x14, 0x48, 0xF6, 0xF7, 0x86, 0xDE, + 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x12, 0x49, 0x12, 0x48, 0xF6, 0xF7, + 0xB0, 0xDC, 0x28, 0x46, 0xFF, 0xF7, 0x0E, 0xFC, 0x38, 0xB1, 0x0E, 0x49, + 0x0E, 0x48, 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E, 0xF6, 0xF7, 0xA5, 0xDC, + 0x0B, 0xE0, 0x31, 0x46, 0x28, 0x46, 0xFF, 0xF7, 0x83, 0xFA, 0x30, 0xB1, + 0x02, 0x21, 0x01, 0x75, 0x04, 0x82, 0xBD, 0xE8, 0xF8, 0x40, 0x02, 0xF0, + 0x8B, 0xBA, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21, 0x07, 0xF0, + 0x72, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x6C, 0x59, 0xC0, 0x08, + 0x03, 0x37, 0x10, 0x21, 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0xFF, 0xF7, + 0xE7, 0xFB, 0x04, 0x00, 0x05, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x68, 0x46, + 0xFF, 0xF7, 0xE0, 0xFB, 0x04, 0x46, 0x31, 0x46, 0x14, 0x48, 0xF6, 0xF7, + 0x49, 0xDE, 0x15, 0x4E, 0xCD, 0xE9, 0x00, 0x54, 0x03, 0x46, 0x03, 0x22, + 0x11, 0x49, 0x30, 0x46, 0xF6, 0xF7, 0x71, 0xDC, 0x00, 0x2C, 0x1A, 0xD0, + 0x0E, 0x49, 0x23, 0x7D, 0x01, 0x22, 0x3C, 0x31, 0x30, 0x46, 0xF6, 0xF7, + 0x68, 0xDC, 0x15, 0xB1, 0x20, 0x46, 0xFF, 0xF7, 0x0D, 0xFA, 0x07, 0x20, + 0x20, 0x75, 0x22, 0x8A, 0x61, 0x7D, 0x2B, 0x46, 0x04, 0xF1, 0x16, 0x00, + 0x02, 0xF0, 0xAE, 0xFA, 0x00, 0x2D, 0x04, 0xD0, 0x20, 0x46, 0xBD, 0xE8, + 0x7C, 0x40, 0x03, 0xF0, 0x1F, 0xBC, 0x7C, 0xBD, 0x00, 0x00, 0x30, 0x21, + 0x88, 0x58, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, + 0x86, 0xB0, 0x0E, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0xA7, 0xFB, 0x04, 0x46, + 0x31, 0x46, 0x30, 0x48, 0xF6, 0xF7, 0x10, 0xDE, 0x30, 0x4E, 0xCD, 0xE9, + 0x00, 0x54, 0x03, 0x46, 0x03, 0x22, 0x2D, 0x49, 0x30, 0x46, 0xF6, 0xF7, + 0x38, 0xDC, 0x00, 0x2C, 0x32, 0xD0, 0x2A, 0x49, 0x23, 0x7D, 0x01, 0x22, + 0x3C, 0x31, 0x30, 0x46, 0xF6, 0xF7, 0x2F, 0xDC, 0x23, 0x7D, 0x98, 0x1E, + 0x0B, 0x28, 0x34, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x06, 0x06, 0x33, 0x33, + 0x33, 0x14, 0x24, 0x33, 0x28, 0x0B, 0x2E, 0x00, 0x20, 0x8A, 0x00, 0x21, + 0x03, 0xF0, 0x48, 0xFB, 0x2E, 0xE0, 0x20, 0x8A, 0x01, 0x21, 0x03, 0xF0, + 0x43, 0xFB, 0x20, 0x8A, 0x29, 0x46, 0x02, 0xF0, 0x91, 0xFC, 0x25, 0xE0, + 0x00, 0x20, 0x0E, 0x21, 0xCD, 0xE9, 0x04, 0x01, 0x02, 0x90, 0x03, 0x90, + 0x00, 0x90, 0x01, 0x90, 0x03, 0x46, 0x62, 0x7D, 0x04, 0xF1, 0x16, 0x01, + 0x20, 0x46, 0x02, 0xF0, 0xB5, 0xF9, 0x15, 0xE0, 0x09, 0x20, 0x20, 0x75, + 0x06, 0xB0, 0x70, 0xBD, 0x20, 0x8A, 0x2A, 0x46, 0x00, 0x21, 0x02, 0xF0, + 0x97, 0xFC, 0x0B, 0xE0, 0x20, 0x8A, 0x00, 0x21, 0x03, 0xF0, 0x20, 0xFB, + 0xF4, 0xE7, 0x0A, 0x49, 0x0A, 0x48, 0x01, 0x22, 0x68, 0x31, 0x80, 0x1E, + 0xF6, 0xF7, 0xEF, 0xDB, 0x00, 0x22, 0x20, 0x8A, 0x11, 0x46, 0x06, 0xF0, + 0x43, 0xFE, 0x06, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x03, 0xF0, + 0xAF, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xC8, 0x59, 0xC0, 0x08, + 0x02, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x15, 0x14, + 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, + 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0A, 0x30, 0x01, 0x21, 0x68, 0x46, + 0x03, 0xF0, 0xEC, 0xFB, 0x10, 0xB0, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, + 0x05, 0x46, 0xDD, 0xE9, 0x09, 0x90, 0x1E, 0x46, 0x17, 0x46, 0x88, 0x46, + 0x2C, 0x1D, 0xDD, 0xF8, 0x20, 0xA0, 0xFF, 0xF7, 0x69, 0xFA, 0x01, 0x00, + 0x06, 0xD0, 0x06, 0x2F, 0x04, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x06, + 0x08, 0x0A, 0x0C, 0x0E, 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x01, 0x20, + 0x06, 0xE0, 0x02, 0x20, 0x04, 0xE0, 0x03, 0x20, 0x02, 0xE0, 0x04, 0x20, + 0x00, 0xE0, 0x05, 0x20, 0x4F, 0xF4, 0x8A, 0x72, 0x6A, 0x80, 0x21, 0x80, + 0xA0, 0x70, 0xA4, 0xF8, 0x04, 0x90, 0xE6, 0x80, 0xA4, 0xF8, 0x08, 0xA0, + 0xA8, 0xF1, 0x10, 0x00, 0x60, 0x81, 0x00, 0x21, 0x28, 0x46, 0x03, 0xF0, + 0x0F, 0xFC, 0x00, 0x20, 0xE1, 0xE7, 0x00, 0x00, 0x70, 0xB5, 0x90, 0xB0, + 0x0C, 0x46, 0xDD, 0xE9, 0x14, 0x51, 0x4F, 0xF4, 0x89, 0x76, 0xAD, 0xF8, + 0x00, 0x60, 0x01, 0xB9, 0x0A, 0x49, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, + 0x08, 0x20, 0x8D, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x30, 0xAD, 0xF8, + 0x0C, 0x50, 0x10, 0x22, 0x0D, 0xF1, 0x0E, 0x00, 0x28, 0xF4, 0x8D, 0xF4, + 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x96, 0xFB, 0x10, 0xB0, 0x70, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x13, 0x13, + 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x30, + 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xDA, 0xFB, + 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46, 0x04, 0x46, + 0xFF, 0xF7, 0x06, 0xFA, 0x4F, 0xF4, 0x87, 0x71, 0xAD, 0xF8, 0x04, 0x40, + 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x06, 0x50, 0x28, 0xB1, 0x01, 0x21, + 0x68, 0x46, 0x03, 0xF0, 0xC5, 0xFB, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22, + 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x38, 0xFA, 0xF7, 0xE7, 0x00, 0xB5, + 0x8D, 0xB0, 0x40, 0xF2, 0x1F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, + 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, + 0xAF, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46, + 0x04, 0x46, 0xFF, 0xF7, 0xDB, 0xF9, 0x40, 0xF2, 0x27, 0x11, 0xAD, 0xF8, + 0x04, 0x40, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0x28, 0xB1, + 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x9A, 0xFB, 0x0D, 0xB0, 0x30, 0xBD, + 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x0D, 0xFA, 0xF7, 0xE7, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x23, 0x13, 0xAD, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x08, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x2A, 0xFB, 0x11, 0xB0, 0x00, 0xBD, + 0x10, 0xB5, 0x8C, 0xB0, 0x4F, 0xF4, 0x92, 0x74, 0xAD, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x07, 0x20, + 0xAD, 0xF8, 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0x6E, 0xFB, + 0x0C, 0xB0, 0x10, 0xBD, 0x70, 0xB5, 0x1C, 0x46, 0x1C, 0x4B, 0x90, 0xB0, + 0xDD, 0xE9, 0x14, 0x56, 0x93, 0xF8, 0xC1, 0x31, 0xB4, 0xEB, 0x83, 0x0F, + 0x08, 0xD9, 0x23, 0x46, 0x01, 0x22, 0x18, 0x49, 0x18, 0x48, 0xF6, 0xF7, + 0xE2, 0xDA, 0x00, 0x20, 0x10, 0xB0, 0x70, 0xBD, 0x4F, 0xF4, 0x93, 0x73, + 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x0B, 0x20, + 0x8D, 0xF8, 0x0C, 0x40, 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, + 0xAD, 0xF8, 0x09, 0x00, 0x7D, 0xB1, 0x74, 0xB1, 0x0E, 0x48, 0x40, 0xF2, + 0x23, 0x33, 0x0C, 0x4A, 0x21, 0x46, 0x00, 0x78, 0xFE, 0xF7, 0x5A, 0xF8, + 0x04, 0x90, 0x00, 0x28, 0xE0, 0xD0, 0x22, 0x46, 0x29, 0x46, 0x28, 0xF4, + 0xD2, 0xF3, 0x8D, 0xF8, 0x14, 0x60, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, + 0xD9, 0xFA, 0xD5, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x00, 0x50, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0xEC, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x30, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x25, 0x15, 0x10, 0x9C, 0x8D, 0xF8, + 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x50, 0x8D, 0xF8, 0x05, 0x20, 0x08, 0x68, + 0xCD, 0xF8, 0x06, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x8D, 0xF8, + 0x0C, 0x30, 0x01, 0x21, 0x68, 0x46, 0x04, 0x94, 0x03, 0xF0, 0x0E, 0xFB, + 0x0D, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0xBD, 0x13, + 0xAD, 0xF8, 0x04, 0x00, 0x02, 0x91, 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, + 0x0C, 0x20, 0x01, 0x21, 0x68, 0x46, 0x03, 0xF0, 0xA5, 0xFA, 0x11, 0xB0, + 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x03, 0x12, 0x01, 0x90, + 0xAD, 0xF8, 0x08, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x03, 0xF0, 0xEE, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x01, 0x88, 0x40, 0xF2, + 0x41, 0x12, 0xA1, 0xF2, 0x41, 0x10, 0x91, 0x42, 0x48, 0xD0, 0x5E, 0xDC, + 0x40, 0xF2, 0x15, 0x12, 0xA1, 0xF2, 0x15, 0x10, 0x91, 0x42, 0x17, 0xD0, + 0x32, 0xDC, 0x1D, 0x29, 0x14, 0xD0, 0x14, 0xDC, 0x13, 0x29, 0x11, 0xD0, + 0x08, 0xDC, 0x01, 0x29, 0x38, 0xD0, 0x0B, 0x29, 0x3F, 0xD0, 0x0D, 0x29, + 0x34, 0xD0, 0x10, 0x29, 0x70, 0xD1, 0xCC, 0xE0, 0x14, 0x29, 0x6E, 0xD0, + 0x18, 0x29, 0x6D, 0xD0, 0x1A, 0x29, 0x6C, 0xD0, 0x1C, 0x29, 0x67, 0xD1, + 0xB7, 0xE0, 0x40, 0xF2, 0x09, 0x12, 0xA1, 0xF2, 0x09, 0x10, 0x91, 0x42, + 0x60, 0xD0, 0x0A, 0xDC, 0x23, 0x29, 0x28, 0xD0, 0xA1, 0xF5, 0x80, 0x71, + 0x01, 0x39, 0x73, 0xD0, 0x03, 0x29, 0x57, 0xD0, 0x06, 0x29, 0x55, 0xD1, + 0xAB, 0xE0, 0x02, 0x28, 0x6D, 0xD0, 0x04, 0x28, 0x50, 0xD0, 0x06, 0x28, + 0x6A, 0xD0, 0x09, 0x28, 0x4C, 0xD1, 0xA4, 0xE0, 0x18, 0x28, 0x0B, 0xD0, + 0x14, 0xDC, 0x0C, 0x28, 0x78, 0xD0, 0x08, 0xDC, 0x01, 0x28, 0x76, 0xD0, + 0x05, 0x28, 0x7C, 0xD0, 0x07, 0x28, 0x7A, 0xD0, 0x09, 0x28, 0x78, 0xD1, + 0x9D, 0xE0, 0x0E, 0x28, 0x39, 0xD0, 0x11, 0x28, 0x7B, 0xD0, 0x13, 0x28, + 0x71, 0xD0, 0x16, 0x28, 0x6F, 0xD1, 0x86, 0xE0, 0x1B, 0x38, 0x0F, 0x28, + 0x6B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x92, 0x7E, 0x6A, 0x8A, 0x6A, 0x80, + 0x6A, 0x92, 0x6A, 0x80, 0x6A, 0x6A, 0x80, 0x6A, 0x76, 0x00, 0x36, 0x28, + 0x77, 0xD0, 0x2E, 0xDC, 0x1B, 0x28, 0x66, 0xD0, 0x14, 0xDC, 0x0F, 0x28, + 0x7B, 0xD0, 0x08, 0xDC, 0x07, 0x28, 0x64, 0xD0, 0x0A, 0x28, 0x70, 0xD0, + 0x0B, 0x28, 0x78, 0xD0, 0x0E, 0x28, 0x50, 0xD1, 0x75, 0xE0, 0x11, 0x28, + 0x4D, 0xD0, 0x14, 0x28, 0x6D, 0xD0, 0x17, 0x28, 0x6B, 0xD0, 0x19, 0x28, + 0x47, 0xD1, 0x6C, 0xE0, 0x2D, 0x28, 0x6A, 0xD0, 0x0C, 0xDC, 0x1D, 0x28, + 0x69, 0xD0, 0x1F, 0x28, 0x53, 0xD0, 0x21, 0x28, 0x61, 0xD0, 0x27, 0x28, + 0x3B, 0xD1, 0x5C, 0xE0, 0x39, 0xE0, 0x58, 0xE0, 0x3B, 0xE0, 0x3C, 0xE0, + 0x2F, 0x28, 0x56, 0xD0, 0x32, 0x28, 0x44, 0xD0, 0x34, 0x28, 0x30, 0xD1, + 0x47, 0xE0, 0x4C, 0x28, 0x4F, 0xD0, 0x17, 0xDC, 0x42, 0x28, 0x42, 0xD0, + 0x0B, 0xDC, 0x38, 0x28, 0x3B, 0xD0, 0x3A, 0x28, 0x4D, 0xD0, 0x3C, 0x28, + 0x33, 0xD0, 0x3E, 0x28, 0x21, 0xD1, 0x36, 0xE0, 0x21, 0xE0, 0x3A, 0xE0, + 0x1E, 0xE0, 0x44, 0x28, 0x35, 0xD0, 0x46, 0x28, 0x35, 0xD0, 0x48, 0x28, + 0x35, 0xD0, 0x4A, 0x28, 0x15, 0xD1, 0x34, 0xE0, 0x5A, 0x28, 0x3A, 0xD0, + 0x0B, 0xDC, 0x4E, 0x28, 0x33, 0xD0, 0x50, 0x28, 0x2F, 0xD0, 0x52, 0x28, + 0x2F, 0xD0, 0x54, 0x28, 0x09, 0xD1, 0x2E, 0xE0, 0x2F, 0xE0, 0x20, 0xE0, + 0x0D, 0xE0, 0x5C, 0x28, 0x2B, 0xD0, 0x79, 0x28, 0x17, 0xD0, 0x7C, 0x28, + 0x1B, 0xD0, 0x3C, 0x20, 0x70, 0x47, 0x18, 0x20, 0x70, 0x47, 0x09, 0x20, + 0x70, 0x47, 0x26, 0x20, 0x70, 0x47, 0x14, 0x20, 0x70, 0x47, 0x05, 0x20, + 0x70, 0x47, 0x0E, 0x20, 0x70, 0x47, 0x0A, 0x20, 0x70, 0x47, 0x11, 0x20, + 0x70, 0x47, 0x28, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x08, 0x20, + 0x70, 0x47, 0x07, 0x20, 0x70, 0x47, 0x1C, 0x20, 0x70, 0x47, 0x0C, 0x20, + 0x70, 0x47, 0x1A, 0x20, 0x70, 0x47, 0x10, 0x20, 0x70, 0x47, 0x06, 0x20, + 0x70, 0x47, 0x03, 0x20, 0x70, 0x47, 0x04, 0x20, 0x70, 0x47, 0x02, 0x20, + 0x70, 0x47, 0x00, 0x00, 0xFF, 0x22, 0x02, 0x70, 0x39, 0xB1, 0x01, 0x29, + 0x07, 0xD0, 0x10, 0x29, 0x0A, 0xD0, 0x11, 0x29, 0x0A, 0xD0, 0x00, 0x20, + 0x70, 0x47, 0x05, 0x49, 0x00, 0xE0, 0x05, 0x49, 0x09, 0x78, 0x01, 0x70, + 0x01, 0x20, 0x70, 0x47, 0x03, 0x49, 0xF9, 0xE7, 0x03, 0x49, 0xF7, 0xE7, + 0x00, 0x74, 0x20, 0x00, 0x01, 0x74, 0x20, 0x00, 0x05, 0x74, 0x20, 0x00, + 0x06, 0x74, 0x20, 0x00, 0x06, 0xF0, 0x70, 0xBE, 0x0A, 0x46, 0x01, 0x46, + 0x01, 0x48, 0x00, 0x78, 0xFE, 0xF7, 0xD0, 0xBF, 0x00, 0x74, 0x20, 0x00, + 0x40, 0x88, 0xB0, 0xF5, 0xA1, 0x7F, 0x7D, 0xD0, 0x58, 0xDC, 0x40, 0xF2, + 0x11, 0x12, 0xA0, 0xF2, 0x11, 0x11, 0x90, 0x42, 0x77, 0xD0, 0x35, 0xDC, + 0x1E, 0x28, 0x75, 0xD0, 0x12, 0xDC, 0xA0, 0xF1, 0x02, 0x00, 0x1A, 0x28, + 0x6F, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0xD9, 0xE8, 0xE8, 0xD9, 0xE8, 0xE8, + 0xE5, 0xE8, 0xE8, 0xE8, 0xD3, 0xE8, 0xE8, 0xE8, 0xE8, 0xE1, 0xD9, 0xE8, + 0xE8, 0xE1, 0xD3, 0xC3, 0xE8, 0xD9, 0xE8, 0xD3, 0xB0, 0xF5, 0x83, 0x7F, + 0x7E, 0xD0, 0x11, 0xDC, 0xB0, 0xF5, 0x80, 0x7F, 0x7B, 0xD0, 0x06, 0xDC, + 0x1F, 0x28, 0x55, 0xD0, 0x20, 0x28, 0x77, 0xD0, 0x24, 0x28, 0x52, 0xD1, + 0xC8, 0xE0, 0xA0, 0xF5, 0x80, 0x70, 0x03, 0x38, 0x4C, 0xD0, 0x02, 0x28, + 0x4B, 0xD1, 0xC1, 0xE0, 0xA0, 0xF5, 0x84, 0x70, 0x07, 0x28, 0x46, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0xAA, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xB6, 0x00, + 0x89, 0x1E, 0x2E, 0x29, 0x3D, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0xAB, 0xB6, + 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0x99, 0xB6, 0xB6, 0xB6, 0xAD, 0xB6, + 0xB6, 0xA5, 0xB6, 0xAB, 0xB3, 0xB6, 0xAD, 0xB6, 0xA1, 0x9B, 0xB6, 0x9D, + 0xB6, 0xAB, 0xAD, 0xB6, 0xB6, 0xAD, 0xB6, 0xAF, 0xB6, 0xAD, 0xB6, 0xAF, + 0xB6, 0xAF, 0x9F, 0xB6, 0xAD, 0xB6, 0xAD, 0xA5, 0xB0, 0xF5, 0xBF, 0x7F, + 0x78, 0xD0, 0x38, 0xDC, 0x40, 0xF2, 0x61, 0x12, 0xA0, 0xF2, 0x61, 0x11, + 0x90, 0x42, 0x72, 0xD0, 0x11, 0xDC, 0xA0, 0xF2, 0x49, 0x10, 0x17, 0x28, + 0x15, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x83, 0x85, 0x8E, 0x8E, 0x83, 0x83, + 0x8E, 0x8E, 0x83, 0x8E, 0x83, 0x8E, 0x8E, 0x79, 0x85, 0x8E, 0x87, 0x8E, + 0x85, 0x8E, 0x87, 0x8E, 0x7D, 0x00, 0x11, 0x29, 0x6E, 0xD0, 0x12, 0xDC, + 0x08, 0x29, 0x75, 0xD0, 0x0A, 0xDC, 0x02, 0xE0, 0x49, 0xE0, 0x77, 0xE0, + 0x66, 0xE0, 0x02, 0x29, 0x6E, 0xD0, 0x04, 0x29, 0x6A, 0xD0, 0x06, 0x29, + 0x71, 0xD1, 0x67, 0xE0, 0x0E, 0x29, 0x67, 0xD0, 0x10, 0x29, 0x6C, 0xD1, + 0x62, 0xE0, 0x13, 0x39, 0x09, 0x29, 0x68, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x5E, 0x67, 0x58, 0x67, 0x58, 0x67, 0x60, 0x67, 0x60, 0x00, 0xB0, 0xF5, + 0xCB, 0x7F, 0x57, 0xD0, 0x14, 0xDC, 0xA0, 0xF5, 0xC0, 0x70, 0x15, 0x28, + 0x59, 0xD2, 0x02, 0xE0, 0x38, 0xE0, 0x3B, 0xE0, 0x34, 0xE0, 0xDF, 0xE8, + 0x00, 0xF0, 0x4D, 0x51, 0x4D, 0x54, 0x43, 0x54, 0x4B, 0x54, 0x4B, 0x54, + 0x4B, 0x54, 0x4D, 0x54, 0x4D, 0x54, 0x4D, 0x54, 0x4B, 0x54, 0x4D, 0x00, + 0xB0, 0xF5, 0xD9, 0x7F, 0x36, 0xD0, 0x15, 0xDC, 0x40, 0xF2, 0xAB, 0x12, + 0xA0, 0xF2, 0xAB, 0x11, 0x90, 0x42, 0x33, 0xD0, 0x09, 0xDC, 0xB0, 0xF5, + 0xCD, 0x7F, 0x31, 0xD0, 0xB0, 0xF5, 0xCE, 0x7F, 0x30, 0xD0, 0xB0, 0xF5, + 0xCF, 0x7F, 0x34, 0xD1, 0x2A, 0xE0, 0x01, 0x29, 0x24, 0xD0, 0x06, 0x29, + 0x2F, 0xD1, 0x1F, 0xE0, 0xA0, 0xF2, 0xB3, 0x10, 0x07, 0x28, 0x2A, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0x24, 0x29, 0x1E, 0x29, 0x29, 0x26, 0x0E, 0x00, + 0x28, 0x20, 0x70, 0x47, 0x0E, 0xE0, 0x19, 0xE0, 0x01, 0x20, 0xFA, 0xE7, + 0x18, 0x20, 0xF8, 0xE7, 0x0E, 0x20, 0xF6, 0xE7, 0x07, 0x20, 0xF4, 0xE7, + 0x1A, 0x20, 0xF2, 0xE7, 0x29, 0x20, 0xF0, 0xE7, 0x0C, 0x20, 0xEE, 0xE7, + 0x14, 0x20, 0xEC, 0xE7, 0x0A, 0x20, 0xEA, 0xE7, 0x08, 0x20, 0xE8, 0xE7, + 0x20, 0x20, 0xE6, 0xE7, 0x06, 0x20, 0xE4, 0xE7, 0x04, 0x20, 0xE2, 0xE7, + 0x02, 0x20, 0xE0, 0xE7, 0x12, 0x20, 0xDE, 0xE7, 0x10, 0x20, 0xDC, 0xE7, + 0xFF, 0xE7, 0x2C, 0x20, 0xD9, 0xE7, 0x00, 0x00, 0x38, 0xB5, 0x0C, 0x46, + 0x01, 0x46, 0x0E, 0x48, 0xF6, 0xF7, 0x20, 0xDA, 0x03, 0x46, 0x02, 0x22, + 0x0C, 0x49, 0x0D, 0x48, 0x00, 0x94, 0xF6, 0xF7, 0x4A, 0xD8, 0x0C, 0x48, + 0x01, 0x78, 0x5C, 0xB1, 0x21, 0xF0, 0x01, 0x01, 0x01, 0x70, 0x20, 0x46, + 0xFE, 0xF7, 0x08, 0xFE, 0x00, 0x2C, 0x06, 0xD1, 0xBD, 0xE8, 0x38, 0x40, + 0x02, 0xF0, 0x32, 0xBB, 0x41, 0xF0, 0x01, 0x01, 0xF2, 0xE7, 0x38, 0xBD, + 0x00, 0x00, 0x30, 0x21, 0xE0, 0x57, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21, + 0xD0, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x47, 0x81, 0x46, 0xDD, 0xE9, + 0x0A, 0x78, 0x9A, 0x46, 0x16, 0x46, 0x08, 0x46, 0xFE, 0xF7, 0xD2, 0xFE, + 0x05, 0x00, 0x1A, 0xD0, 0xF0, 0x19, 0x81, 0xB2, 0x0E, 0x48, 0x40, 0xF2, + 0x9E, 0x23, 0x0C, 0x4A, 0x00, 0x78, 0xFD, 0xF7, 0xAF, 0xFD, 0x04, 0x00, + 0x0F, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x04, 0xD0, 0xA0, 0x19, 0x3A, 0x46, + 0x41, 0x46, 0x28, 0xF4, 0x24, 0xF1, 0xCD, 0xE9, 0x00, 0x95, 0xBA, 0xB2, + 0x53, 0x46, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0x71, 0xF8, 0xBD, 0xE8, + 0xFC, 0x87, 0x00, 0x00, 0xEB, 0xAF, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x83, 0x46, 0xDD, 0xE9, 0x11, 0x09, + 0xDD, 0xE9, 0x13, 0x87, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0xDD, 0xF8, + 0x40, 0xA0, 0xFE, 0xF7, 0x9F, 0xFE, 0xB8, 0xB1, 0x04, 0x2E, 0x01, 0xD0, + 0x01, 0x22, 0x00, 0xE0, 0x02, 0x22, 0x00, 0x26, 0xCD, 0xE9, 0x04, 0x06, + 0xA1, 0xB2, 0x01, 0xAE, 0x00, 0x91, 0xBB, 0xB2, 0x1F, 0xFA, 0x88, 0xF0, + 0x86, 0xE8, 0x09, 0x04, 0x1F, 0xFA, 0x89, 0xF3, 0xA9, 0xB2, 0x58, 0x46, + 0xFF, 0xF7, 0xE0, 0xF8, 0x00, 0x28, 0x08, 0xD0, 0x07, 0xB0, 0x58, 0x46, + 0xBD, 0xE8, 0xF0, 0x4F, 0x40, 0xF2, 0x25, 0x32, 0x02, 0x49, 0xFD, 0xF7, + 0x53, 0xBE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x0B, 0xB0, 0x82, 0x00, + 0xF8, 0xB5, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x06, 0x9C, 0xFE, 0xF7, + 0x71, 0xFE, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46, 0x00, 0x94, 0xFF, 0xF7, + 0x8B, 0xF9, 0xF8, 0xBD, 0x70, 0xB5, 0x06, 0x46, 0x1D, 0x46, 0x14, 0x46, + 0x08, 0x46, 0xFE, 0xF7, 0x63, 0xFE, 0x01, 0x21, 0x01, 0x2C, 0x04, 0xD0, + 0x02, 0x2C, 0x04, 0xD0, 0x05, 0x2C, 0x09, 0xD1, 0x03, 0xE0, 0x38, 0xB1, + 0x02, 0xE0, 0x02, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x33, 0x46, 0x2A, 0x46, + 0xFF, 0xF7, 0x1B, 0xFA, 0x01, 0x20, 0x70, 0xBD, 0x00, 0xB5, 0x8B, 0xB0, + 0xC1, 0x79, 0x8D, 0xF8, 0x07, 0x10, 0x01, 0x68, 0x00, 0x91, 0x81, 0x88, + 0xAD, 0xF8, 0x04, 0x10, 0x81, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0x00, 0x21, + 0xAD, 0xF8, 0x08, 0x10, 0x00, 0x7A, 0x69, 0x46, 0xFE, 0xF7, 0x69, 0xFE, + 0x0B, 0xB0, 0x00, 0xBD, 0x70, 0xB5, 0x05, 0x00, 0x05, 0xF1, 0x04, 0x00, + 0x4F, 0xF0, 0x01, 0x04, 0x77, 0xD0, 0x2B, 0x88, 0x40, 0xF2, 0x4B, 0x16, + 0x1A, 0x46, 0xA3, 0xF2, 0x4B, 0x11, 0xB3, 0x42, 0x70, 0xD0, 0x74, 0xDC, + 0x40, 0xF2, 0x15, 0x16, 0xA3, 0xF2, 0x15, 0x11, 0xB3, 0x42, 0x6B, 0xD0, + 0x36, 0xDC, 0x21, 0x2B, 0x69, 0xD0, 0x18, 0xDC, 0x14, 0x2B, 0x67, 0xD0, + 0x0C, 0xDC, 0x0D, 0x2B, 0x76, 0xD0, 0x04, 0xDC, 0x01, 0x2B, 0x74, 0xD0, + 0x0B, 0x2B, 0x73, 0xD1, 0xF5, 0xE0, 0x10, 0x2B, 0x71, 0xD0, 0x13, 0x2B, + 0x6E, 0xD1, 0xFF, 0xE0, 0x18, 0x2B, 0x6D, 0xD0, 0x1A, 0x2B, 0x6C, 0xD0, + 0x1C, 0x2B, 0x6B, 0xD0, 0x1D, 0x2B, 0x65, 0xD1, 0x0B, 0xE1, 0x40, 0xF2, + 0x09, 0x16, 0xA3, 0xF2, 0x09, 0x11, 0xB3, 0x42, 0x71, 0xD0, 0x0A, 0xDC, + 0x23, 0x2B, 0x6F, 0xD0, 0xA3, 0xF5, 0x80, 0x73, 0x01, 0x3B, 0x6C, 0xD0, + 0x03, 0x2B, 0x6B, 0xD0, 0x06, 0x2B, 0x53, 0xD1, 0xC5, 0xE0, 0x02, 0x29, + 0x67, 0xD0, 0x04, 0x29, 0x72, 0xD0, 0x06, 0x29, 0x71, 0xD0, 0x09, 0x29, + 0x4A, 0xD1, 0x2A, 0xE1, 0x1B, 0x29, 0x50, 0xD0, 0x18, 0xDC, 0x0E, 0x29, + 0x6A, 0xD0, 0x0C, 0xDC, 0x07, 0x29, 0x04, 0xD0, 0x04, 0xDC, 0x01, 0x29, + 0x7D, 0xD0, 0x05, 0x29, 0x3C, 0xD1, 0x28, 0xE1, 0x09, 0x29, 0x79, 0xD0, + 0x0C, 0x29, 0x37, 0xD1, 0x27, 0xE1, 0x11, 0x29, 0x75, 0xD0, 0x13, 0x29, + 0x74, 0xD0, 0x16, 0x29, 0x73, 0xD0, 0x18, 0x29, 0x2E, 0xD1, 0xE5, 0xE0, + 0x24, 0x29, 0x6F, 0xD0, 0x08, 0xDC, 0x1C, 0x29, 0x6D, 0xD0, 0x1E, 0x29, + 0x6C, 0xD0, 0x20, 0x29, 0x6B, 0xD0, 0x22, 0x29, 0x22, 0xD1, 0x30, 0xE1, + 0x27, 0x29, 0x67, 0xD0, 0x29, 0x29, 0x6F, 0xD0, 0x2C, 0x29, 0x6E, 0xD0, + 0x33, 0x29, 0x19, 0xD1, 0x4D, 0xE1, 0x90, 0xE0, 0x4E, 0xE1, 0x02, 0xE0, + 0xF9, 0xE0, 0xBF, 0xE0, 0xA7, 0xE0, 0x30, 0x29, 0x70, 0xD0, 0x3F, 0xDC, + 0x17, 0x29, 0x6E, 0xD0, 0x24, 0xDC, 0x0D, 0x29, 0x6C, 0xD0, 0x13, 0xDC, + 0x05, 0x29, 0x6A, 0xD0, 0x0B, 0xDC, 0x01, 0x29, 0x68, 0xD0, 0x04, 0x29, + 0x6F, 0xD1, 0x3F, 0xE1, 0x86, 0xE0, 0x7E, 0xE0, 0x6B, 0xE0, 0x8B, 0xE0, + 0x94, 0xE0, 0x9C, 0xE0, 0x9E, 0xE0, 0x07, 0x29, 0x73, 0xD0, 0x0A, 0x29, + 0x63, 0xD1, 0x68, 0xE0, 0x0F, 0x29, 0x6F, 0xD0, 0x11, 0x29, 0x6E, 0xD0, + 0x13, 0x29, 0x6D, 0xD0, 0x15, 0x29, 0x5A, 0xD1, 0x0E, 0xE1, 0xB7, 0xE0, + 0x99, 0xE0, 0xE6, 0xE0, 0xAB, 0xE0, 0xB7, 0xE0, 0x25, 0x29, 0x6F, 0xD0, + 0x0B, 0xDC, 0x19, 0x29, 0x6D, 0xD0, 0x1B, 0x29, 0x6C, 0xD0, 0x1D, 0x29, + 0x6B, 0xD0, 0x23, 0x29, 0x49, 0xD1, 0x43, 0xE1, 0xAE, 0xE0, 0xB2, 0xE0, + 0xCD, 0xE0, 0x28, 0x29, 0x71, 0xD0, 0x2A, 0x29, 0x70, 0xD0, 0x2C, 0x29, + 0x6F, 0xD0, 0x2E, 0x29, 0x3D, 0xD1, 0x2B, 0xE1, 0x46, 0x29, 0x6B, 0xD0, + 0x20, 0xDC, 0x3C, 0x29, 0x69, 0xD0, 0x12, 0xDC, 0x32, 0x29, 0x67, 0xD0, + 0x34, 0x29, 0x6F, 0xD0, 0x38, 0x29, 0x6E, 0xD0, 0x3A, 0x29, 0x2E, 0xD1, + 0x49, 0xE1, 0xA8, 0xE0, 0x9B, 0xE0, 0xB6, 0xE0, 0xD1, 0xE0, 0xBB, 0xE0, + 0xCC, 0xE0, 0xBC, 0xE0, 0xBE, 0xE0, 0xC0, 0xE0, 0xE2, 0xE0, 0x3E, 0x29, + 0x6F, 0xD0, 0x40, 0x29, 0x6E, 0xD0, 0x42, 0x29, 0x6D, 0xD0, 0x44, 0x29, + 0x1B, 0xD1, 0x18, 0xE1, 0xDB, 0xE0, 0xC4, 0xE0, 0x52, 0x29, 0x67, 0xD0, + 0x0D, 0xDC, 0x48, 0x29, 0x6F, 0xD0, 0x4A, 0x29, 0x6E, 0xD0, 0x4E, 0x29, + 0x6D, 0xD0, 0x50, 0x29, 0x0D, 0xD1, 0x19, 0xE1, 0xFD, 0xE0, 0xC3, 0xE0, + 0xE4, 0xE0, 0xDC, 0xE0, 0xD5, 0xE0, 0x69, 0x29, 0x70, 0xD0, 0x6F, 0x29, + 0x48, 0xD0, 0x71, 0x29, 0x49, 0xD0, 0x72, 0x29, 0x51, 0xD0, 0x13, 0x46, + 0x01, 0x22, 0x93, 0x49, 0x93, 0x48, 0xF5, 0xF7, 0x82, 0xDE, 0x41, 0xF2, + 0x16, 0x52, 0x92, 0x49, 0x28, 0x46, 0xFD, 0xF7, 0xFF, 0xFC, 0x20, 0x46, + 0x70, 0xBD, 0xC7, 0xE0, 0xCE, 0xE0, 0x9D, 0xE0, 0x9F, 0xE0, 0x28, 0x46, + 0x01, 0xF0, 0x9E, 0xF8, 0xEF, 0xE7, 0x01, 0xF0, 0x98, 0xF8, 0xEC, 0xE7, + 0x28, 0x46, 0x01, 0xF0, 0x17, 0xF9, 0xE8, 0xE7, 0xD9, 0xE0, 0x9C, 0xE0, + 0x7E, 0xE0, 0xA3, 0xE0, 0x28, 0x46, 0x01, 0xF0, 0x4E, 0xF8, 0xE0, 0xE7, + 0x01, 0xF0, 0x73, 0xF8, 0xDD, 0xE7, 0x01, 0xF0, 0x79, 0xF8, 0xDA, 0xE7, + 0xFF, 0xF7, 0xB8, 0xFE, 0xD7, 0xE7, 0xB6, 0xE0, 0xB8, 0xE0, 0xBA, 0xE0, + 0xCE, 0xE0, 0xEB, 0xE0, 0xAE, 0xE0, 0x00, 0xF0, 0x9A, 0xFB, 0xCE, 0xE7, + 0x01, 0xF0, 0xF2, 0xF8, 0xCB, 0xE7, 0x00, 0xF0, 0xC1, 0xFB, 0xC8, 0xE7, + 0xB6, 0xE0, 0xD6, 0xE0, 0x01, 0xF0, 0xB7, 0xF8, 0xC3, 0xE7, 0x01, 0xF0, + 0x69, 0xF8, 0xC0, 0xE7, 0x00, 0xF0, 0x85, 0xFB, 0xBD, 0xE7, 0x01, 0xF0, + 0xE5, 0xF8, 0xBA, 0xE7, 0x00, 0xF0, 0xB8, 0xFD, 0xB7, 0xE7, 0xC9, 0xE0, + 0xC2, 0xE0, 0xBE, 0xE0, 0xCF, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x6E, 0xFB, + 0x02, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x00, 0xFA, 0x04, 0x00, 0xAA, 0xD1, + 0xAF, 0xE7, 0xA6, 0xE0, 0xA8, 0xE0, 0xAA, 0xE0, 0x28, 0x46, 0x00, 0xF0, + 0x59, 0xF9, 0xF5, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x38, 0xFA, 0x9E, 0xE7, + 0x28, 0x46, 0x00, 0xF0, 0x38, 0xF9, 0xED, 0xE7, 0xB8, 0xE0, 0x28, 0x46, + 0x00, 0xF0, 0x08, 0xF9, 0x95, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x16, 0xF9, + 0x91, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xAD, 0xFA, 0x8D, 0xE7, 0x28, 0x46, + 0x00, 0xF0, 0x96, 0xFA, 0x89, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x70, 0xF9, + 0x85, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x2E, 0xFA, 0xD4, 0xE7, 0x28, 0x46, + 0x00, 0xF0, 0xE1, 0xF8, 0x7D, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xD1, 0xFA, + 0x79, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0xE6, 0xFA, 0x75, 0xE7, 0x01, 0xF0, + 0x4B, 0xF8, 0x72, 0xE7, 0x00, 0xF0, 0xFE, 0xFB, 0x6F, 0xE7, 0x00, 0xF0, + 0x9A, 0xFB, 0x6C, 0xE7, 0x00, 0xF0, 0x70, 0xFB, 0x69, 0xE7, 0x00, 0xF0, + 0x63, 0xFB, 0x66, 0xE7, 0x00, 0xF0, 0x79, 0xFE, 0x63, 0xE7, 0x00, 0xF0, + 0x06, 0xFF, 0x60, 0xE7, 0x00, 0xF0, 0xEF, 0xFE, 0x5D, 0xE7, 0x28, 0x46, + 0x00, 0xF0, 0x7E, 0xFC, 0x59, 0xE7, 0x00, 0xF0, 0xBD, 0xFB, 0x56, 0xE7, + 0x00, 0xF0, 0x1D, 0xFF, 0x53, 0xE7, 0x00, 0xF0, 0x81, 0xFE, 0x50, 0xE7, + 0x00, 0x78, 0x09, 0xF0, 0xF1, 0xFC, 0x4C, 0xE7, 0x00, 0xF0, 0x90, 0xFF, + 0x49, 0xE7, 0x09, 0xF0, 0x1C, 0xFF, 0x46, 0xE7, 0x00, 0xF0, 0x38, 0xFE, + 0x43, 0xE7, 0x00, 0xF0, 0xBB, 0xFB, 0x40, 0xE7, 0x0B, 0xF0, 0x40, 0xFB, + 0x3D, 0xE7, 0x00, 0xF0, 0xAD, 0xFC, 0x3A, 0xE7, 0x00, 0xF0, 0x98, 0xFC, + 0x37, 0xE7, 0x00, 0xF0, 0x1F, 0xFD, 0x34, 0xE7, 0x00, 0xF0, 0x0D, 0xFD, + 0x31, 0xE7, 0x00, 0xF0, 0xE1, 0xFD, 0x2E, 0xE7, 0x28, 0x46, 0x00, 0xF0, + 0xD0, 0xFC, 0x7D, 0xE7, 0x28, 0x46, 0x00, 0xF0, 0x29, 0xFE, 0x26, 0xE7, + 0x28, 0x46, 0x00, 0xF0, 0xB2, 0xFC, 0x22, 0xE7, 0x00, 0xF0, 0x73, 0xFB, + 0x1F, 0xE7, 0x00, 0xF0, 0xE9, 0xFD, 0x1C, 0xE7, 0x00, 0xF0, 0x72, 0xFE, + 0x19, 0xE7, 0x00, 0xF0, 0x5F, 0xFE, 0x16, 0xE7, 0x00, 0xF0, 0xC9, 0xFE, + 0x13, 0xE7, 0x00, 0xF0, 0x46, 0xFF, 0x10, 0xE7, 0x00, 0xF0, 0x2F, 0xFF, + 0x0D, 0xE7, 0x00, 0xF0, 0xE2, 0xFE, 0x0A, 0xE7, 0x00, 0xF0, 0x53, 0xFF, + 0x07, 0xE7, 0x00, 0xF0, 0xF3, 0xFE, 0x04, 0xE7, 0x00, 0xF0, 0x01, 0xFF, + 0x01, 0xE7, 0x00, 0xF0, 0x4D, 0xFD, 0xFE, 0xE6, 0x00, 0xF0, 0x4F, 0xFD, + 0xFB, 0xE6, 0x00, 0xF0, 0x79, 0xFE, 0xF8, 0xE6, 0x00, 0xF0, 0x4F, 0xFF, + 0xF5, 0xE6, 0x00, 0xF0, 0x93, 0xFD, 0xF2, 0xE6, 0x00, 0xF0, 0x7D, 0xFD, + 0xEF, 0xE6, 0x00, 0xF0, 0xB1, 0xFE, 0xEC, 0xE6, 0x00, 0xF0, 0x4B, 0xFD, + 0xE9, 0xE6, 0x00, 0xF0, 0x55, 0xFD, 0xE6, 0xE6, 0x00, 0xF0, 0x3D, 0xFD, + 0xE3, 0xE6, 0x00, 0xF0, 0xA9, 0xFD, 0xE0, 0xE6, 0x00, 0xF0, 0x1A, 0xFD, + 0xDD, 0xE6, 0x00, 0x00, 0xB4, 0x56, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0xD7, 0xAF, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x08, 0x46, 0xFE, 0xF7, + 0x01, 0xFC, 0x00, 0x28, 0x04, 0xD0, 0x21, 0x46, 0xBD, 0xE8, 0x10, 0x40, + 0x01, 0xF0, 0x1A, 0xBC, 0x10, 0xBD, 0x70, 0xB5, 0x05, 0x46, 0x14, 0x46, + 0x08, 0x46, 0xFE, 0xF7, 0xF3, 0xFB, 0x00, 0x28, 0x15, 0xD0, 0x02, 0x2C, + 0x07, 0xD0, 0x03, 0x2C, 0x09, 0xD0, 0x04, 0x2C, 0x09, 0xD0, 0x05, 0x2C, + 0x03, 0xD0, 0x01, 0x21, 0x06, 0xE0, 0x02, 0x21, 0x04, 0xE0, 0x05, 0x21, + 0x02, 0xE0, 0x03, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x2A, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0xFF, 0xF7, 0xBD, 0xB9, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, + 0x08, 0x46, 0xFE, 0xF7, 0xD5, 0xFB, 0x00, 0x28, 0x04, 0xD0, 0x21, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0xDD, 0xB9, 0x10, 0xBD, 0x10, 0xB5, + 0x80, 0x88, 0xFE, 0xF7, 0x9F, 0xFC, 0x00, 0x28, 0x07, 0xD0, 0x01, 0x7D, + 0x0B, 0x29, 0x04, 0xD1, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, + 0x8B, 0xBA, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, + 0x8F, 0xFC, 0x00, 0x28, 0x09, 0xD0, 0x01, 0x7D, 0x0B, 0x29, 0x06, 0xD1, + 0xA2, 0x88, 0x61, 0x88, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, + 0x78, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, + 0x7D, 0xFC, 0x58, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x02, 0xD0, 0x40, 0xF6, + 0x04, 0x41, 0x07, 0xE0, 0xA1, 0x78, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, + 0x06, 0xF0, 0x74, 0xBE, 0x40, 0xF6, 0x07, 0x41, 0x20, 0x88, 0xBD, 0xE8, + 0x10, 0x40, 0xFF, 0xF7, 0xA2, 0xB9, 0xF8, 0xB5, 0x05, 0x46, 0x04, 0x1D, + 0x00, 0x26, 0x00, 0x89, 0xFE, 0xF7, 0x62, 0xFC, 0x10, 0xB1, 0x01, 0x7D, + 0x0B, 0x29, 0x02, 0xD0, 0x01, 0x26, 0x30, 0x46, 0xF8, 0xBD, 0x62, 0x89, + 0x0A, 0xB9, 0x01, 0x26, 0x00, 0x25, 0x00, 0x95, 0xA3, 0x89, 0xE1, 0x88, + 0x00, 0x8A, 0x06, 0xF0, 0xF3, 0xFB, 0xF2, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, + 0x05, 0x46, 0x04, 0x1D, 0x00, 0x27, 0x00, 0x89, 0xFE, 0xF7, 0x48, 0xFC, + 0x06, 0x00, 0x02, 0xD0, 0x30, 0x7D, 0x0B, 0x28, 0x03, 0xD0, 0x01, 0x27, + 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0xA0, 0x89, 0x61, 0x89, 0x09, 0xB1, + 0xBD, 0xB1, 0x0B, 0xE0, 0x0D, 0x48, 0x01, 0x27, 0x40, 0xF6, 0x19, 0x43, + 0x0A, 0x4A, 0x1C, 0x21, 0x00, 0x78, 0xFD, 0xF7, 0x43, 0xFA, 0x05, 0x00, + 0x0B, 0xD0, 0x1C, 0x20, 0x21, 0x68, 0x80, 0x1F, 0x29, 0x60, 0xA8, 0x80, + 0x2B, 0x46, 0x62, 0x89, 0xE1, 0x88, 0x30, 0x8A, 0x06, 0xF0, 0x2A, 0xFA, + 0xE0, 0xE7, 0x01, 0x20, 0xDF, 0xE7, 0x00, 0x00, 0x96, 0xAF, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x1D, 0x87, 0xB0, 0x80, 0x88, + 0xFE, 0xF7, 0x16, 0xFC, 0x00, 0x25, 0x01, 0x22, 0x40, 0xF6, 0x07, 0x41, + 0x18, 0xB1, 0x03, 0x7D, 0x0B, 0x2B, 0x04, 0xD0, 0xC9, 0x1E, 0xA0, 0x78, + 0x01, 0x28, 0x2F, 0xD0, 0x04, 0xE0, 0xA3, 0x78, 0x01, 0x2B, 0x10, 0xD0, + 0x02, 0x2B, 0x14, 0xD0, 0x20, 0x88, 0xCD, 0xE9, 0x04, 0x05, 0xCD, 0xE9, + 0x02, 0x51, 0x00, 0x95, 0x01, 0x95, 0xA2, 0x78, 0x00, 0x23, 0x00, 0x21, + 0x08, 0x46, 0xFE, 0xF7, 0x79, 0xFD, 0x07, 0xB0, 0x30, 0xBD, 0xA1, 0x88, + 0x09, 0xB1, 0x02, 0x21, 0x02, 0xE0, 0x01, 0x21, 0x00, 0xE0, 0x04, 0x21, + 0x00, 0x8A, 0x04, 0x29, 0xAD, 0xF8, 0x00, 0x00, 0x18, 0xD0, 0xA0, 0x88, + 0x70, 0xB3, 0x02, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8, + 0x04, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x68, 0x46, 0x06, 0xF0, + 0xF7, 0xF9, 0xE2, 0xE7, 0xE0, 0x88, 0x23, 0x88, 0x00, 0x95, 0xCD, 0xE9, + 0x04, 0x30, 0xCD, 0xE9, 0x02, 0x21, 0x01, 0x95, 0x00, 0x23, 0xD4, 0xE7, + 0x04, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x04, 0x00, + 0x20, 0x89, 0xAD, 0xF8, 0x06, 0x00, 0x60, 0x89, 0x30, 0xB1, 0x10, 0x20, + 0xAD, 0xF8, 0x08, 0x00, 0x60, 0x89, 0xAD, 0xF8, 0x0C, 0x00, 0xDF, 0xE7, + 0x80, 0x20, 0x0C, 0x34, 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x94, 0xD9, 0xE7, + 0xAD, 0xF8, 0x02, 0x20, 0xE0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xD3, 0xE7, + 0x2D, 0xE9, 0xFF, 0x41, 0x06, 0x46, 0x04, 0x1D, 0x00, 0x27, 0xC0, 0x89, + 0xFE, 0xF7, 0xAA, 0xFB, 0x05, 0x00, 0x28, 0xD0, 0x28, 0x7D, 0x0B, 0x28, + 0x02, 0xD0, 0x40, 0xF6, 0x04, 0x40, 0x24, 0xE0, 0x20, 0x8A, 0xE1, 0x89, + 0x09, 0xB1, 0xD6, 0xB1, 0x0B, 0xE0, 0x16, 0x48, 0x01, 0x27, 0x40, 0xF6, + 0xDC, 0x33, 0x13, 0x4A, 0x1C, 0x21, 0x00, 0x78, 0xFD, 0xF7, 0xA6, 0xF9, + 0x06, 0x00, 0x0E, 0xD0, 0x1C, 0x20, 0xE2, 0x89, 0x21, 0x7A, 0xA3, 0x89, + 0xCD, 0xE9, 0x00, 0x32, 0xCD, 0xE9, 0x02, 0x01, 0xD4, 0xE9, 0x00, 0x32, + 0x29, 0x8A, 0x30, 0x46, 0x06, 0xF0, 0xF2, 0xF9, 0x0D, 0xE0, 0x01, 0x20, + 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x40, 0xF6, 0x07, 0x40, 0x00, 0x90, + 0xD4, 0xE9, 0x00, 0x12, 0xA3, 0x89, 0x60, 0x89, 0xFE, 0xF7, 0xC0, 0xFD, + 0x01, 0x27, 0x38, 0x46, 0xF0, 0xE7, 0x00, 0x00, 0x75, 0xAF, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x70, 0x47, 0x38, 0xB5, 0x04, 0x1D, 0x80, 0x88, + 0xFE, 0xF7, 0x68, 0xFB, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D, 0x0B, 0x29, + 0x07, 0xD1, 0x00, 0x21, 0x00, 0x91, 0x00, 0x23, 0x21, 0x89, 0x00, 0x8A, + 0x1A, 0x46, 0x06, 0xF0, 0xFD, 0xFA, 0x38, 0xBD, 0x2D, 0xE9, 0xFC, 0x41, + 0x07, 0x46, 0x04, 0x1D, 0x01, 0x25, 0x80, 0x88, 0xFE, 0xF7, 0x52, 0xFB, + 0x06, 0x46, 0xA0, 0x78, 0x01, 0x28, 0x0A, 0xD0, 0x02, 0x28, 0x0F, 0xD0, + 0x03, 0x28, 0x0F, 0xD0, 0x04, 0x28, 0x0F, 0xD0, 0x00, 0x22, 0x1A, 0x49, + 0x1A, 0x48, 0xF5, 0xF7, 0xC0, 0xDB, 0xC6, 0xB1, 0x30, 0x7D, 0x0B, 0x28, + 0x08, 0xD0, 0x40, 0xF6, 0x04, 0x43, 0x14, 0xE0, 0x02, 0x25, 0xF6, 0xE7, + 0x03, 0x25, 0xF4, 0xE7, 0x05, 0x25, 0xF2, 0xE7, 0x60, 0x89, 0x29, 0x46, + 0x00, 0x1F, 0x78, 0x80, 0x20, 0x89, 0x38, 0x80, 0x00, 0x97, 0xE3, 0x88, + 0xA2, 0x88, 0x30, 0x8A, 0x06, 0xF0, 0xE8, 0xFA, 0x14, 0xE0, 0x40, 0xF6, + 0x07, 0x43, 0xA1, 0x78, 0x03, 0x29, 0x06, 0xD0, 0xA2, 0x88, 0x20, 0x88, + 0xFE, 0xF7, 0x13, 0xFE, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x20, 0x88, + 0x18, 0x21, 0xCD, 0xE9, 0x00, 0x30, 0x00, 0x23, 0x1A, 0x46, 0x38, 0x46, + 0xFE, 0xF7, 0xFA, 0xFB, 0x00, 0x20, 0xF2, 0xE7, 0xE8, 0x54, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, + 0xFE, 0xF7, 0xE6, 0xFA, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D, 0x0B, 0x29, + 0x07, 0xD1, 0x00, 0x8A, 0x23, 0x46, 0x2A, 0x46, 0x31, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0xFF, 0xF7, 0x71, 0xB8, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x1D, + 0x80, 0x88, 0xFE, 0xF7, 0xF5, 0xFA, 0x00, 0x28, 0x0A, 0xD0, 0x01, 0x7D, + 0x0B, 0x29, 0x07, 0xD1, 0xE3, 0x88, 0xA2, 0x88, 0xA1, 0x78, 0x00, 0x8A, + 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x66, 0xBC, 0x10, 0xBD, 0x1F, 0xB5, + 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, 0xE2, 0xFA, 0x40, 0xF6, 0x07, 0x42, + 0x30, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0xA1, 0x78, 0x04, 0xD0, 0x20, 0x88, + 0xD2, 0x1E, 0x11, 0xE0, 0xA1, 0x78, 0x0E, 0xE0, 0x69, 0xB1, 0x00, 0x8A, + 0xAD, 0xF8, 0x00, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xA0, 0x88, 0xAD, 0xF8, + 0x04, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x02, 0x29, 0x14, 0xD1, + 0x05, 0xE0, 0x20, 0x88, 0x04, 0xB0, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, + 0xCD, 0xBF, 0x20, 0x89, 0x30, 0xB1, 0x10, 0x20, 0xAD, 0xF8, 0x08, 0x00, + 0x20, 0x89, 0xAD, 0xF8, 0x0C, 0x00, 0x04, 0xE0, 0x80, 0x20, 0x0A, 0x34, + 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x94, 0x68, 0x46, 0x06, 0xF0, 0x71, 0xFC, + 0x1F, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x80, 0x88, 0xFE, 0xF7, 0xAA, 0xFA, + 0x10, 0xB1, 0x01, 0x7D, 0x0B, 0x29, 0x07, 0xD0, 0x20, 0x88, 0x04, 0x23, + 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x46, 0xFF, 0xF7, 0x14, 0xB8, + 0x41, 0x7D, 0x23, 0x79, 0x62, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x16, 0x30, + 0x15, 0xF0, 0xC4, 0xBD, 0x10, 0xB5, 0x04, 0x1D, 0x00, 0x20, 0x21, 0x78, + 0x8C, 0xB0, 0x01, 0x22, 0x40, 0xF6, 0x08, 0x43, 0x11, 0xB1, 0x01, 0x29, + 0x30, 0xD1, 0x1A, 0xE0, 0x21, 0x7C, 0x01, 0xB1, 0x18, 0x46, 0xAD, 0xF8, + 0x00, 0x00, 0x8D, 0xF8, 0x0B, 0x20, 0x20, 0x7A, 0x69, 0x46, 0x80, 0x08, + 0xAD, 0xF8, 0x0C, 0x00, 0xD4, 0xF8, 0x01, 0x00, 0x01, 0x90, 0xB4, 0xF8, + 0x05, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x79, 0x8D, 0xF8, 0x0A, 0x00, + 0x02, 0x20, 0xE2, 0x68, 0x06, 0xF0, 0x4C, 0xFB, 0x14, 0xE0, 0x21, 0x7C, + 0x01, 0xB1, 0x18, 0x46, 0x00, 0x21, 0x8D, 0xF8, 0x07, 0x20, 0xAD, 0xF8, + 0x08, 0x10, 0xD4, 0xF8, 0x01, 0x10, 0x00, 0x91, 0xB4, 0xF8, 0x05, 0x10, + 0xAD, 0xF8, 0x04, 0x10, 0xE1, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0x69, 0x46, + 0xFE, 0xF7, 0xB1, 0xF9, 0xE0, 0x68, 0x00, 0x28, 0x0A, 0xD0, 0x21, 0x7A, + 0x00, 0x29, 0x07, 0xD0, 0x0C, 0xB0, 0x40, 0xF6, 0xF4, 0x52, 0xBD, 0xE8, + 0x10, 0x40, 0x02, 0x49, 0xFD, 0xF7, 0x4C, 0xB9, 0x0C, 0xB0, 0x10, 0xBD, + 0xB5, 0xAF, 0x82, 0x00, 0x10, 0xB5, 0x83, 0x88, 0x82, 0x89, 0x81, 0x68, + 0x18, 0x46, 0x07, 0xF0, 0x9B, 0xFA, 0x01, 0x20, 0x10, 0xBD, 0xC2, 0x79, + 0x81, 0x79, 0x15, 0xF0, 0xFF, 0xBC, 0x30, 0xB5, 0x04, 0x46, 0x90, 0xF8, + 0x24, 0x00, 0x8B, 0xB0, 0x11, 0x38, 0x05, 0x28, 0x22, 0xD8, 0xA0, 0x79, + 0x8D, 0xF8, 0x06, 0x00, 0x94, 0xF8, 0x24, 0x00, 0x8D, 0xF8, 0x07, 0x00, + 0xE0, 0x79, 0x00, 0x25, 0x00, 0xB1, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00, + 0x20, 0x68, 0x00, 0x90, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE2, 0x79, + 0x04, 0xF1, 0x08, 0x01, 0x03, 0xA8, 0x27, 0xF4, 0xAC, 0xF3, 0x94, 0xF8, + 0x25, 0x00, 0x18, 0xB1, 0x01, 0x28, 0x01, 0xD0, 0x40, 0xF6, 0x08, 0x45, + 0x69, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0x5A, 0xF9, 0x0B, 0xB0, 0x30, 0xBD, + 0xC2, 0x79, 0x81, 0x79, 0x15, 0xF0, 0x00, 0xBD, 0x01, 0x78, 0x02, 0x23, + 0x01, 0x29, 0x00, 0xD1, 0x03, 0x23, 0x41, 0x78, 0x42, 0x68, 0x18, 0x46, + 0x06, 0xF0, 0xAC, 0xBC, 0x1F, 0xB5, 0x04, 0x46, 0x80, 0x7B, 0xFE, 0xF7, + 0x3D, 0xF9, 0x8D, 0xF8, 0x0E, 0x00, 0xA0, 0x68, 0x02, 0x90, 0xA0, 0x89, + 0xAD, 0xF8, 0x0C, 0x00, 0x20, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x78, + 0x8D, 0xF8, 0x01, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE0, 0x88, + 0xAD, 0xF8, 0x06, 0x00, 0x60, 0x78, 0x8D, 0xF8, 0x02, 0x00, 0xE0, 0x7B, + 0x8D, 0xF8, 0x0F, 0x00, 0xE0, 0x7B, 0x01, 0xF0, 0xCB, 0xFF, 0x6A, 0x46, + 0x10, 0x21, 0x01, 0x20, 0x06, 0xF0, 0x86, 0xFC, 0x1F, 0xBD, 0x00, 0x78, + 0x20, 0xB1, 0x01, 0x28, 0x06, 0xD0, 0x04, 0x21, 0x00, 0xF0, 0x44, 0xBF, + 0x00, 0x22, 0x11, 0x46, 0x05, 0x20, 0x02, 0xE0, 0x00, 0x22, 0x11, 0x46, + 0x04, 0x20, 0x06, 0xF0, 0x75, 0xBC, 0x06, 0x28, 0x12, 0xD2, 0xDF, 0xE8, + 0x00, 0xF0, 0x11, 0x03, 0x07, 0x09, 0x0C, 0x0E, 0x4F, 0xF4, 0x9A, 0x70, + 0x02, 0xF0, 0x4F, 0xBA, 0x00, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x00, 0xF0, + 0xE5, 0xBE, 0x01, 0x20, 0x00, 0xE0, 0x00, 0x20, 0x00, 0xF0, 0x26, 0xBF, + 0x70, 0x47, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x78, 0x20, 0xB1, 0xBD, 0xE8, + 0x10, 0x40, 0x00, 0x20, 0x17, 0xF0, 0xEA, 0xBA, 0x60, 0x1C, 0x17, 0xF0, + 0xE7, 0xFA, 0x62, 0x1C, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x46, + 0x00, 0xF0, 0x38, 0xBF, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, + 0x9B, 0xF9, 0x00, 0x28, 0x0B, 0xD0, 0xA1, 0x78, 0x01, 0x29, 0x06, 0xD0, + 0x4F, 0xF4, 0x40, 0x61, 0x00, 0x8A, 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, + 0x13, 0xBD, 0x00, 0x21, 0xF8, 0xE7, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, + 0x00, 0x88, 0xFE, 0xF7, 0x87, 0xF9, 0x28, 0xB1, 0x00, 0x8A, 0x21, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x3A, 0xBD, 0x20, 0x88, 0xBD, 0xE8, + 0x10, 0x40, 0x40, 0xF6, 0x07, 0x41, 0x01, 0xF0, 0xC3, 0xB8, 0x00, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x05, 0x46, 0xFE, 0xF7, 0x50, 0xF9, + 0x43, 0x4E, 0x44, 0x4F, 0x04, 0x00, 0x14, 0xD0, 0x23, 0x7D, 0x01, 0x22, + 0x42, 0x49, 0x78, 0x1C, 0xF5, 0xF7, 0xE5, 0xD9, 0x23, 0x7D, 0x07, 0xF1, + 0x02, 0x08, 0x02, 0x2B, 0x24, 0xD0, 0x04, 0x2B, 0x42, 0xD0, 0x01, 0x22, + 0x06, 0xB0, 0x78, 0x1E, 0xBD, 0xE8, 0xF0, 0x41, 0x3B, 0x49, 0xF5, 0xF7, + 0xD6, 0x99, 0x29, 0x46, 0x30, 0x46, 0xF5, 0xF7, 0xA1, 0xDB, 0x37, 0x49, + 0x03, 0x46, 0x01, 0x22, 0x3C, 0x39, 0x38, 0x46, 0xF5, 0xF7, 0xCB, 0xD9, + 0x00, 0x20, 0x07, 0x21, 0xCD, 0xE9, 0x04, 0x01, 0x02, 0x90, 0x03, 0x90, + 0x00, 0x90, 0x03, 0x46, 0x02, 0x46, 0x29, 0x46, 0x01, 0x90, 0x00, 0xF0, + 0x6D, 0xFF, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0xA8, 0x79, 0x01, 0x28, + 0x0A, 0xD0, 0x04, 0xF1, 0x16, 0x01, 0x0D, 0x46, 0x30, 0x46, 0xF5, 0xF7, + 0x81, 0xDB, 0x27, 0x49, 0x01, 0x22, 0x03, 0x46, 0x70, 0x31, 0x26, 0xE0, + 0x03, 0x20, 0x20, 0x75, 0x04, 0xF1, 0x16, 0x01, 0x0C, 0x46, 0x30, 0x46, + 0xF5, 0xF7, 0x74, 0xDB, 0x20, 0x49, 0x03, 0x46, 0x01, 0x22, 0x34, 0x31, + 0x40, 0x46, 0xF5, 0xF7, 0x9E, 0xD9, 0x01, 0x21, 0x20, 0x46, 0x2D, 0xE0, + 0x60, 0x8A, 0x1C, 0x49, 0x00, 0x90, 0x02, 0x22, 0x80, 0x39, 0x38, 0x46, + 0xF5, 0xF7, 0x93, 0xD9, 0xA8, 0x79, 0x01, 0x28, 0x1F, 0xD0, 0x04, 0xF1, + 0x16, 0x01, 0x0D, 0x46, 0x30, 0x46, 0xF5, 0xF7, 0x59, 0xDB, 0x14, 0x49, + 0x01, 0x22, 0x03, 0x46, 0x3C, 0x39, 0x40, 0x46, 0xF5, 0xF7, 0x83, 0xD9, + 0x20, 0x8A, 0x00, 0x21, 0x02, 0xF0, 0xA8, 0xF8, 0x00, 0x21, 0x28, 0x46, + 0x06, 0xF0, 0x5B, 0xF9, 0x00, 0x22, 0x20, 0x8A, 0x11, 0x46, 0x05, 0xF0, + 0xCF, 0xFB, 0x06, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0x02, 0xF0, + 0x3B, 0xB9, 0x01, 0x21, 0x04, 0xF1, 0x16, 0x00, 0x06, 0xB0, 0xBD, 0xE8, + 0xF0, 0x41, 0x06, 0xF0, 0x48, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0x01, 0x37, 0x10, 0x21, 0x4C, 0x55, 0xC0, 0x08, 0x78, 0x56, 0xC0, 0x08, + 0x70, 0xB5, 0x04, 0x1D, 0x40, 0x1D, 0xFE, 0xF7, 0xBB, 0xF8, 0x01, 0x46, + 0xE0, 0x79, 0x01, 0x28, 0x06, 0xD0, 0x03, 0x28, 0x04, 0xD0, 0x00, 0x20, + 0xE0, 0x71, 0x19, 0xB1, 0x05, 0x23, 0x1E, 0xE0, 0x01, 0x20, 0xF9, 0xE7, + 0xC1, 0xB2, 0x60, 0x1C, 0xFD, 0xF7, 0x2C, 0xFF, 0xB0, 0xB1, 0x06, 0x21, + 0x01, 0x75, 0x61, 0x89, 0x69, 0xB1, 0x0D, 0x4B, 0x02, 0x8A, 0x4F, 0xF4, + 0x80, 0x35, 0x1B, 0x78, 0x01, 0xEB, 0x81, 0x01, 0x45, 0xEA, 0x03, 0x63, + 0x1A, 0x43, 0x4B, 0x00, 0x08, 0xA1, 0xFD, 0xF7, 0xC7, 0xFE, 0x20, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x06, 0xF0, 0x21, 0xB9, 0x03, 0x23, 0x00, 0x22, + 0xE1, 0x79, 0x60, 0x1C, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x7C, 0xBF, + 0xCC, 0x77, 0x20, 0x00, 0x62, 0x74, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x38, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0xA1, 0xF8, 0xFD, 0xF7, + 0xA9, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xA0, 0x7A, 0x00, 0x90, 0x23, 0x89, + 0xE2, 0x88, 0xA1, 0x88, 0x60, 0x88, 0x0D, 0xF0, 0xA1, 0xF9, 0x38, 0xBD, + 0x38, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0x8F, 0xF8, 0x05, 0x00, + 0x09, 0xD0, 0xFD, 0xF7, 0x95, 0xFF, 0x02, 0x00, 0x08, 0xD0, 0x28, 0x8A, + 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x21, 0x00, 0xF0, 0x26, 0xBD, 0x20, 0x88, + 0x04, 0x22, 0xF7, 0xE7, 0x20, 0x89, 0x00, 0x90, 0xE3, 0x88, 0xA2, 0x88, + 0x61, 0x88, 0x28, 0x8A, 0x0D, 0xF0, 0xBC, 0xF9, 0x38, 0xBD, 0x10, 0xB5, + 0x04, 0x1D, 0x80, 0x79, 0x08, 0xB1, 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22, + 0x21, 0x88, 0x00, 0x20, 0x0D, 0xF0, 0x84, 0xF8, 0x00, 0x28, 0x20, 0x88, + 0x04, 0xD0, 0x00, 0x21, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x96, 0xB8, + 0x03, 0x21, 0xF9, 0xE7, 0x70, 0x47, 0xF0, 0xB5, 0x06, 0x46, 0x04, 0x1D, + 0x85, 0xB0, 0x01, 0x27, 0x80, 0x88, 0xFE, 0xF7, 0x59, 0xF8, 0xFD, 0xF7, + 0x61, 0xFF, 0x05, 0x00, 0x03, 0x96, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, + 0x38, 0x46, 0xAD, 0xF8, 0x04, 0x00, 0x60, 0x88, 0xAD, 0xF8, 0x0A, 0x00, + 0xA0, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x06, 0xD1, 0x68, 0x46, 0x0D, 0xF0, + 0xDD, 0xF8, 0x00, 0xB9, 0x05, 0x25, 0x00, 0x27, 0x25, 0xB1, 0x61, 0x88, + 0x20, 0x88, 0x2A, 0x46, 0x01, 0xF0, 0xE2, 0xF8, 0x05, 0xB0, 0x38, 0x46, + 0xF0, 0xBD, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x50, 0xFF, + 0x00, 0x28, 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0xF0, 0xD2, 0xB8, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, + 0xFE, 0xF7, 0x26, 0xF8, 0xFD, 0xF7, 0x2E, 0xFF, 0x00, 0x28, 0x04, 0xD1, + 0x60, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x0D, 0xF0, 0x1D, 0xB9, 0x10, 0xBD, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0x17, 0xF8, 0xFD, 0xF7, + 0x1F, 0xFF, 0x02, 0x00, 0x04, 0xD1, 0x60, 0x88, 0x0D, 0xF0, 0xC8, 0xF9, + 0x02, 0x00, 0x05, 0xD0, 0x60, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x21, + 0x00, 0xF0, 0xE5, 0xBC, 0x10, 0xBD, 0x70, 0x47, 0x70, 0xB5, 0x05, 0x46, + 0x00, 0x88, 0xFE, 0xF7, 0x01, 0xF8, 0x04, 0x00, 0x06, 0xD0, 0x20, 0x7D, + 0x06, 0x28, 0x0D, 0xD0, 0xA9, 0x78, 0x06, 0x29, 0x06, 0xD1, 0x17, 0xE0, + 0x2B, 0x88, 0x01, 0x22, 0x13, 0x49, 0x14, 0x48, 0xF5, 0xF7, 0x6F, 0xD8, + 0x00, 0x22, 0x28, 0x88, 0x04, 0x21, 0x1B, 0xE0, 0x0F, 0x49, 0x10, 0x48, + 0x2B, 0x88, 0x01, 0x22, 0x48, 0x31, 0x80, 0x1C, 0xF5, 0xF7, 0x63, 0xD8, + 0x0A, 0x20, 0x20, 0x75, 0x20, 0x46, 0xFD, 0xF7, 0x07, 0xFE, 0x03, 0xE0, + 0x0C, 0x28, 0x08, 0xD0, 0x0C, 0x20, 0x20, 0x75, 0x04, 0xF1, 0x16, 0x00, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21, 0x06, 0xF0, 0x33, 0xB9, 0x20, 0x8A, + 0x00, 0x22, 0x05, 0x21, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xE6, 0xB8, + 0x58, 0x54, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x10, 0x21, + 0x01, 0x20, 0x08, 0xF0, 0x6D, 0xFC, 0x20, 0xB1, 0xBD, 0xE8, 0x10, 0x40, + 0x00, 0x20, 0x09, 0xF0, 0xF9, 0xBA, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0x21, + 0x40, 0xF2, 0xB5, 0x10, 0x02, 0xF0, 0x49, 0xB8, 0x82, 0x78, 0x41, 0x78, + 0x00, 0x78, 0x08, 0xF0, 0x7C, 0xBE, 0xC3, 0x78, 0x82, 0x78, 0x41, 0x78, + 0x00, 0x78, 0x08, 0xF0, 0x84, 0xBE, 0x01, 0x46, 0x02, 0x20, 0x0A, 0x78, + 0x01, 0x2A, 0x00, 0xD1, 0x03, 0x20, 0x06, 0xF0, 0xCB, 0xBB, 0x01, 0x46, + 0x00, 0x78, 0x20, 0xB1, 0x01, 0x28, 0x04, 0xD0, 0x04, 0x21, 0x01, 0xF0, + 0x83, 0xB9, 0x05, 0x20, 0x00, 0xE0, 0x04, 0x20, 0x06, 0xF0, 0xBE, 0xBB, + 0x01, 0x46, 0x01, 0x20, 0x06, 0xF0, 0xBA, 0xBB, 0x0B, 0x46, 0x06, 0x28, + 0x16, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x15, 0x03, 0x07, 0x0A, 0x0E, 0x11, + 0x11, 0x46, 0x18, 0x46, 0x01, 0xF0, 0xBC, 0xB9, 0x19, 0x46, 0x00, 0x20, + 0x01, 0xE0, 0x19, 0x46, 0x01, 0x20, 0x01, 0xF0, 0x39, 0xB9, 0x19, 0x46, + 0x01, 0x20, 0x01, 0xE0, 0x19, 0x46, 0x00, 0x20, 0x01, 0xF0, 0x60, 0xB9, + 0x70, 0x47, 0x10, 0xB5, 0x04, 0x78, 0x82, 0x78, 0x41, 0x78, 0x03, 0x1D, + 0x20, 0x46, 0x09, 0xF0, 0x71, 0xF8, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, + 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC6, 0x70, 0x01, 0xF0, + 0xF8, 0xBF, 0x10, 0xBD, 0x10, 0xB5, 0x83, 0x88, 0x42, 0x88, 0x41, 0x78, + 0x00, 0x78, 0x09, 0xF0, 0x49, 0xF8, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, + 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC7, 0x70, 0x01, 0xF0, + 0xE6, 0xBF, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7, + 0x4F, 0xFF, 0xFD, 0xF7, 0x57, 0xFE, 0x02, 0x00, 0x05, 0xD1, 0xA1, 0x88, + 0x60, 0x88, 0x0D, 0xF0, 0xD5, 0xF8, 0x02, 0x00, 0x05, 0xD0, 0x61, 0x88, + 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x19, 0xBD, 0x10, 0xBD, + 0x41, 0x78, 0x00, 0x78, 0x06, 0xF0, 0x0E, 0xBC, 0x70, 0xB5, 0x04, 0x46, + 0x00, 0x78, 0x00, 0x25, 0x28, 0xB1, 0x01, 0x28, 0x06, 0xD0, 0x02, 0x28, + 0x0D, 0xD0, 0x04, 0x25, 0x12, 0xE0, 0x08, 0xF0, 0x56, 0xFD, 0x0C, 0xE0, + 0x60, 0x78, 0x04, 0xF1, 0x18, 0x03, 0x04, 0xF1, 0x08, 0x02, 0xA1, 0x1C, + 0x08, 0xF0, 0x24, 0xFD, 0x03, 0xE0, 0x60, 0x78, 0xA1, 0x1C, 0x08, 0xF0, + 0xC7, 0xFE, 0x38, 0xB1, 0x00, 0x2D, 0x08, 0xD0, 0x20, 0x78, 0x29, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x14, 0xBB, 0x4F, 0xF4, 0xB4, 0x75, + 0xF6, 0xE7, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0xC0, 0x79, 0xFF, 0x28, + 0x01, 0xD0, 0xFD, 0xF7, 0x4D, 0xFE, 0x02, 0x46, 0x20, 0x78, 0x61, 0x1C, + 0xBD, 0xE8, 0x10, 0x40, 0x06, 0xF0, 0x08, 0xBC, 0x1C, 0xB5, 0x81, 0x88, + 0xAD, 0xF8, 0x04, 0x10, 0x81, 0x79, 0x8D, 0xF8, 0x00, 0x10, 0xC1, 0x79, + 0x8D, 0xF8, 0x01, 0x10, 0x00, 0x7A, 0x8D, 0xF8, 0x02, 0x00, 0x68, 0x46, + 0x12, 0xF0, 0xC4, 0xFD, 0x01, 0xF0, 0x4C, 0xFB, 0x1C, 0xBD, 0x10, 0xB5, + 0x08, 0xF0, 0x65, 0xFE, 0x00, 0x28, 0x06, 0xD1, 0xBD, 0xE8, 0x10, 0x40, + 0x00, 0x21, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x59, 0xBB, 0x10, 0xBD, + 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x09, 0xFE, 0x00, 0x28, + 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, + 0x69, 0xBB, 0x70, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7, + 0xD1, 0xFE, 0x60, 0xB1, 0x00, 0x8A, 0x08, 0xF0, 0x48, 0xFE, 0x00, 0x28, + 0x0B, 0xD1, 0x20, 0x88, 0x00, 0x22, 0x4F, 0xF4, 0xB4, 0x71, 0xBD, 0xE8, + 0x10, 0x40, 0x01, 0xF0, 0x55, 0xBB, 0x00, 0x22, 0x20, 0x88, 0x04, 0x21, + 0xF7, 0xE7, 0x10, 0xBD, 0x1C, 0xB5, 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46, + 0x08, 0xF0, 0x38, 0xFE, 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90, + 0x69, 0x46, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x71, 0xFB, 0x1C, 0xBD, + 0x1C, 0xB5, 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46, 0x08, 0xF0, 0x2E, 0xFE, + 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x69, 0x46, 0x4F, 0xF4, + 0xB4, 0x70, 0x01, 0xF0, 0x8D, 0xFB, 0x1C, 0xBD, 0x7C, 0xB5, 0x14, 0x46, + 0x0D, 0x46, 0xCD, 0xE9, 0x00, 0x54, 0x06, 0x46, 0x03, 0x46, 0x03, 0x22, + 0x05, 0x49, 0x06, 0x48, 0xF4, 0xF7, 0x0F, 0xDF, 0x30, 0x46, 0xFD, 0xF7, + 0x8F, 0xFE, 0x00, 0x28, 0x01, 0xD0, 0x05, 0x77, 0x44, 0x77, 0x7C, 0xBD, + 0x64, 0x5A, 0xC0, 0x08, 0x02, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x08, 0xF0, + 0x14, 0xFE, 0x00, 0x28, 0x07, 0xD1, 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, + 0x11, 0x46, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x87, 0xBB, 0x10, 0xBD, + 0x00, 0x78, 0x08, 0xF0, 0x13, 0xBE, 0x08, 0xB5, 0x81, 0x79, 0x00, 0x91, + 0xC3, 0x79, 0x82, 0x88, 0x41, 0x88, 0x00, 0x78, 0x08, 0xF0, 0xFC, 0xFF, + 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x08, 0x40, 0x4F, 0xF4, 0xB4, 0x71, + 0x4F, 0xF4, 0x9D, 0x70, 0x01, 0xF0, 0xF3, 0xBE, 0x08, 0xBD, 0x10, 0xB5, + 0x41, 0x78, 0x00, 0x78, 0x08, 0xF0, 0xE0, 0xFF, 0x00, 0x28, 0x07, 0xD1, + 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0x9C, 0x70, + 0x01, 0xF0, 0xE3, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0x00, 0x78, 0x08, 0xF0, + 0xFB, 0xFD, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, + 0xB4, 0x71, 0x4F, 0xF4, 0xBD, 0x70, 0x01, 0xF0, 0xD4, 0xBE, 0x10, 0xBD, + 0x02, 0x78, 0x41, 0x1C, 0x10, 0x46, 0x0A, 0xF0, 0x13, 0xBC, 0x10, 0xB5, + 0x08, 0xF0, 0x72, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, + 0x4F, 0xF4, 0xB4, 0x71, 0x40, 0xF2, 0x5D, 0x10, 0x01, 0xF0, 0xC1, 0xBE, + 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFD, 0xF7, 0x2A, 0xFE, + 0x48, 0xB1, 0xA2, 0x88, 0x61, 0x88, 0x00, 0x8A, 0x08, 0xF0, 0x3A, 0xFE, + 0x00, 0x28, 0x08, 0xD1, 0x4F, 0xF4, 0xB4, 0x70, 0x00, 0xE0, 0x04, 0x20, + 0x21, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x5A, 0xBC, 0x10, 0xBD, + 0x10, 0xB5, 0x82, 0x78, 0x41, 0x78, 0x00, 0x78, 0x08, 0xF0, 0x3F, 0xFE, + 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, + 0x4F, 0xF4, 0xC8, 0x70, 0x01, 0xF0, 0x99, 0xBE, 0x10, 0xBD, 0x38, 0xB5, + 0x04, 0x46, 0x40, 0x79, 0x00, 0x90, 0x23, 0x79, 0xE2, 0x78, 0xA1, 0x78, + 0x20, 0x88, 0x08, 0xF0, 0x47, 0xFF, 0x00, 0x28, 0x06, 0xD1, 0x21, 0x88, + 0xBD, 0xE8, 0x38, 0x40, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x81, 0xBC, + 0x38, 0xBD, 0x70, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFD, 0xF7, 0x18, 0xFD, + 0x00, 0x28, 0x05, 0xD0, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0xF0, 0x73, 0xBC, 0x70, 0xBD, 0x10, 0xB5, 0x03, 0x78, 0xC2, 0x79, + 0x41, 0x1C, 0x18, 0x46, 0x08, 0xF0, 0x41, 0xFF, 0x00, 0x28, 0x07, 0xD1, + 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xC0, 0x70, + 0x01, 0xF0, 0x65, 0xBE, 0x10, 0xBD, 0x0A, 0xF0, 0xCD, 0xBB, 0x10, 0xB5, + 0x00, 0x88, 0x08, 0xF0, 0x4C, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, + 0x10, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xBE, 0x70, 0x01, 0xF0, + 0x54, 0xBE, 0x10, 0xBD, 0x08, 0xF0, 0x8F, 0xBF, 0x82, 0x78, 0x41, 0x78, + 0x00, 0x78, 0x08, 0xF0, 0x8E, 0xBF, 0x10, 0xB5, 0x41, 0x88, 0x00, 0x88, + 0x08, 0xF0, 0xAB, 0xFF, 0x00, 0x28, 0x05, 0xD1, 0xBD, 0xE8, 0x10, 0x40, + 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xF0, 0x0E, 0xBD, 0x10, 0xBD, 0x10, 0xB5, + 0x90, 0xF9, 0x01, 0x10, 0x90, 0xF9, 0x00, 0x00, 0x89, 0xB2, 0x80, 0xB2, + 0x08, 0xF0, 0x87, 0xFF, 0x00, 0x28, 0x07, 0xD1, 0xBD, 0xE8, 0x10, 0x40, + 0x4F, 0xF4, 0xB4, 0x71, 0x4F, 0xF4, 0xCE, 0x70, 0x01, 0xF0, 0x2B, 0xBE, + 0x10, 0xBD, 0x08, 0xB5, 0xC1, 0x88, 0x00, 0x1D, 0x89, 0x0A, 0x1C, 0xD1, + 0x01, 0x79, 0x04, 0x29, 0x19, 0xD8, 0x00, 0x21, 0x00, 0x91, 0x02, 0x78, + 0x9D, 0xF8, 0x03, 0x10, 0x62, 0xF3, 0x04, 0x11, 0x8D, 0xF8, 0x03, 0x10, + 0x42, 0x88, 0xAD, 0xF8, 0x00, 0x20, 0x02, 0x79, 0x62, 0xF3, 0x02, 0x01, + 0x8D, 0xF8, 0x03, 0x10, 0x40, 0x79, 0x60, 0xF3, 0xC3, 0x01, 0x8D, 0xF8, + 0x03, 0x10, 0x68, 0x46, 0x12, 0xF0, 0x26, 0xFC, 0x08, 0xBD, 0x04, 0x21, + 0xBD, 0xE8, 0x08, 0x40, 0x11, 0x20, 0x01, 0xF0, 0x02, 0xBE, 0xC1, 0x79, + 0x01, 0x29, 0x01, 0xD0, 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22, 0x81, 0x79, + 0x15, 0xF0, 0xA6, 0xBA, 0x01, 0x7B, 0x83, 0x68, 0x01, 0x29, 0x01, 0xD0, + 0x01, 0x22, 0x00, 0xE0, 0x00, 0x22, 0x81, 0x79, 0x15, 0xF0, 0xB6, 0xBA, + 0x81, 0x79, 0x0A, 0xF0, 0x9B, 0xB9, 0x81, 0x79, 0x0A, 0xF0, 0xE8, 0xB9, + 0x10, 0xB5, 0x8C, 0xB0, 0x02, 0x21, 0xAD, 0xF8, 0x02, 0x10, 0x11, 0x4C, + 0x4F, 0xF0, 0x01, 0x11, 0x01, 0x91, 0x21, 0x7A, 0x00, 0x1D, 0x41, 0xB1, + 0x03, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x3B, 0xFE, 0x0C, 0xB0, 0x10, 0xBD, 0x01, 0x21, 0x21, 0x72, 0x00, 0x68, + 0x60, 0x60, 0x00, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x68, 0x46, 0x01, 0xF0, + 0x2F, 0xFE, 0x20, 0x78, 0xC0, 0x07, 0xF0, 0xD0, 0x00, 0x20, 0xFD, 0xF7, + 0x77, 0xFB, 0x01, 0xF0, 0xA5, 0xF8, 0xEA, 0xE7, 0xD0, 0x77, 0x20, 0x00, + 0x08, 0xB5, 0x81, 0x7D, 0x01, 0x29, 0x01, 0xD0, 0x01, 0x21, 0x00, 0xE0, + 0x00, 0x21, 0x00, 0x91, 0xC1, 0x7D, 0x00, 0x23, 0x82, 0x1D, 0x15, 0xF0, + 0x77, 0xFB, 0x08, 0xBD, 0x1C, 0xB5, 0x14, 0x68, 0x00, 0x94, 0x92, 0x88, + 0xAD, 0xF8, 0x04, 0x20, 0x8D, 0xF8, 0x06, 0x30, 0x6B, 0x46, 0x09, 0x22, + 0xFD, 0xF7, 0x3C, 0xFB, 0x1C, 0xBD, 0x00, 0x78, 0x01, 0x28, 0x03, 0xD0, + 0x02, 0x21, 0x22, 0x20, 0x01, 0xF0, 0x9D, 0xBD, 0x0A, 0xF0, 0xB4, 0xB9, + 0xF8, 0xB5, 0x13, 0x4D, 0x04, 0x46, 0x0E, 0x46, 0x0B, 0x46, 0x00, 0x90, + 0x02, 0x22, 0x0F, 0x49, 0x28, 0x46, 0xF4, 0xF7, 0x7C, 0xDD, 0x01, 0x2C, + 0x17, 0xD1, 0x30, 0x46, 0xFD, 0xF7, 0xFA, 0xFC, 0x04, 0x00, 0x12, 0xD0, + 0xFD, 0xF7, 0x1C, 0xFB, 0x08, 0x49, 0x23, 0x7D, 0x01, 0x22, 0x34, 0x31, + 0x28, 0x46, 0xF4, 0xF7, 0x6C, 0xDD, 0x20, 0x7D, 0x07, 0x28, 0x06, 0xD1, + 0x04, 0xF1, 0x16, 0x00, 0xBD, 0xE8, 0xF8, 0x40, 0x00, 0x21, 0x05, 0xF0, + 0x43, 0xBE, 0xF8, 0xBD, 0xE8, 0x56, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21, + 0xC2, 0x79, 0x81, 0x79, 0x16, 0xF0, 0xD6, 0xBE, 0xC2, 0x79, 0x81, 0x79, + 0x16, 0xF0, 0x28, 0xBF, 0x38, 0xB5, 0x04, 0x1D, 0x82, 0x79, 0x80, 0x88, + 0xE1, 0x1C, 0x08, 0xF0, 0x96, 0xFF, 0x00, 0x28, 0x06, 0xD1, 0x00, 0x90, + 0x21, 0x88, 0x03, 0x46, 0x4F, 0xF4, 0xB4, 0x72, 0x00, 0xF0, 0x02, 0xF8, + 0x38, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x07, 0x46, 0x1D, 0x46, + 0x17, 0x48, 0x8A, 0x46, 0x91, 0x46, 0x05, 0xF1, 0x0A, 0x01, 0x40, 0xF2, + 0x0D, 0x23, 0x13, 0x4A, 0x88, 0x46, 0x00, 0x78, 0x08, 0x9E, 0xFC, 0xF7, + 0xC7, 0xFA, 0x04, 0x00, 0x15, 0xD0, 0x20, 0x1D, 0x0E, 0x21, 0x61, 0x80, + 0xA4, 0xF8, 0x04, 0xA0, 0xA4, 0xF8, 0x06, 0x90, 0x27, 0x72, 0x65, 0x72, + 0x2E, 0xB1, 0x25, 0xB1, 0x2A, 0x46, 0x31, 0x46, 0x80, 0x1D, 0x26, 0xF4, + 0x34, 0xF6, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x21, 0x01, 0xF0, + 0x93, 0xBD, 0x43, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x01, 0x22, 0x04, 0x49, + 0x04, 0x48, 0xF4, 0xF7, 0x12, 0x9D, 0x00, 0x00, 0xB2, 0xAE, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0xF0, 0x52, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0x70, 0xB5, 0x06, 0x46, 0x12, 0x48, 0x0C, 0x46, 0x40, 0xF2, 0x2D, 0x23, + 0x0F, 0x4A, 0x49, 0x1D, 0x00, 0x78, 0xFC, 0xF7, 0x93, 0xFA, 0x88, 0xB1, + 0x03, 0x1D, 0x0F, 0x21, 0x41, 0x80, 0x05, 0x46, 0x04, 0x71, 0x2E, 0xB1, + 0x24, 0xB1, 0x22, 0x46, 0x31, 0x46, 0x58, 0x1C, 0x26, 0xF4, 0x05, 0xF6, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21, 0x01, 0xF0, 0x64, 0xBD, + 0x63, 0x1D, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, + 0xF4, 0xF7, 0xE3, 0x9C, 0xCA, 0xAE, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x2C, 0x53, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, + 0x03, 0x46, 0x8C, 0xB0, 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xF4, 0xF7, + 0xD2, 0xDC, 0x20, 0x21, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x04, 0x40, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x42, 0xFD, 0x0C, 0xB0, 0x10, 0xBD, + 0x68, 0x53, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x0D, 0x48, 0x10, 0xB5, + 0x90, 0xF8, 0x98, 0x01, 0x48, 0xB1, 0x41, 0x01, 0x3C, 0x23, 0x0B, 0x4A, + 0x00, 0x20, 0xFF, 0xF7, 0x4D, 0xDA, 0x0A, 0x49, 0x00, 0x28, 0xC8, 0x60, + 0x0B, 0xD0, 0x08, 0x4A, 0x08, 0x49, 0x10, 0x1F, 0xFC, 0xF7, 0xFE, 0xFB, + 0x00, 0x28, 0x04, 0xD0, 0x04, 0x48, 0x14, 0x30, 0xFF, 0xF7, 0x02, 0xDC, + 0x01, 0x20, 0x10, 0xBD, 0x64, 0x01, 0x20, 0x00, 0x98, 0xAE, 0x82, 0x00, + 0xD0, 0x77, 0x20, 0x00, 0xD1, 0x0E, 0x81, 0x00, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xDD, 0x73, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, 0x08, 0x48, + 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, + 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0xAB, 0xFC, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00, + 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0xB9, 0x12, 0xAD, 0xF8, 0x02, 0x20, + 0x02, 0x68, 0x01, 0x92, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, + 0x0A, 0x10, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xED, 0xFC, 0x0D, 0xB0, + 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x19, 0x23, 0xAD, 0xF8, 0x02, 0x30, + 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, + 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0xD9, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x1F, 0x23, + 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8, + 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x20, 0x8D, 0xF8, 0x0B, 0x10, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0xC5, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x1D, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, + 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x68, + 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x01, 0xF0, 0x56, 0xFC, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, + 0x00, 0xB5, 0x8D, 0xB0, 0x1E, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x0B, 0x68, + 0xCD, 0xF8, 0x06, 0x30, 0x89, 0x88, 0xAD, 0xF8, 0x0A, 0x10, 0xAD, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x0C, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x97, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x8D, 0xB0, + 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x12, 0x9F, 0xFD, 0xF7, 0xB2, 0xFA, + 0x00, 0x28, 0x16, 0xD0, 0xAD, 0xF8, 0x04, 0x70, 0xAD, 0xF8, 0x06, 0x00, + 0x4F, 0xF4, 0xAB, 0x71, 0x09, 0x48, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, + 0x08, 0x60, 0xAD, 0xF8, 0x0A, 0x50, 0xAD, 0xF8, 0x0C, 0x40, 0x90, 0xF8, + 0x9B, 0x01, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x73, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x30, 0xB5, 0x8D, 0xB0, 0x0D, 0x46, 0x04, 0x46, 0xFD, 0xF7, 0x8E, 0xFA, + 0x4F, 0xF4, 0xA5, 0x71, 0xAD, 0xF8, 0x04, 0x40, 0xAD, 0xF8, 0x02, 0x10, + 0xAD, 0xF8, 0x06, 0x50, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x5B, 0xFC, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, + 0xFD, 0xF7, 0xCE, 0xFA, 0xF7, 0xE7, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46, + 0x0D, 0x46, 0xFD, 0xF7, 0x73, 0xFA, 0x00, 0x28, 0x0D, 0xD0, 0x40, 0xF2, + 0x49, 0x11, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, + 0x06, 0x50, 0xAD, 0xF8, 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x3D, 0xFC, 0x0D, 0xB0, 0x30, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46, + 0x0D, 0x46, 0xFD, 0xF7, 0x3F, 0xFB, 0x00, 0x28, 0x17, 0xD0, 0x03, 0x7D, + 0x0B, 0x2B, 0x03, 0xD0, 0x0C, 0x2B, 0x01, 0xD0, 0x03, 0x2B, 0x10, 0xD1, + 0x00, 0x8A, 0x00, 0x28, 0x0D, 0xD0, 0x4F, 0xF4, 0xA7, 0x71, 0xAD, 0xF8, + 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8, + 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x1B, 0xFC, 0x0D, 0xB0, + 0x30, 0xBD, 0x30, 0xB5, 0x8D, 0xB0, 0x14, 0x46, 0x0D, 0x46, 0xFD, 0xF7, + 0x39, 0xFA, 0x00, 0x28, 0x0D, 0xD0, 0x40, 0xF2, 0x4D, 0x11, 0xAD, 0xF8, + 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8, + 0x08, 0x40, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x03, 0xFC, 0x0D, 0xB0, + 0x30, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x90, 0xB0, 0x15, 0x46, 0x06, 0x46, + 0x0C, 0x46, 0x1F, 0x29, 0x06, 0xD9, 0x0B, 0x46, 0x01, 0x22, 0x12, 0x49, + 0x12, 0x48, 0xF4, 0xF7, 0x7A, 0xDB, 0x1F, 0x24, 0x40, 0xF2, 0x35, 0x10, + 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x04, 0x60, 0x00, 0x20, 0x8D, 0xF8, + 0x05, 0x40, 0x02, 0x90, 0x74, 0xB1, 0x0D, 0x48, 0x40, 0xF2, 0x56, 0x53, + 0x0A, 0x4A, 0x21, 0x46, 0x00, 0x78, 0xFC, 0xF7, 0xFB, 0xF8, 0x02, 0x90, + 0x00, 0x28, 0x07, 0xD0, 0x22, 0x46, 0x29, 0x46, 0x26, 0xF4, 0x73, 0xF4, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x7C, 0xFB, 0x10, 0xB0, 0x70, 0xBD, + 0x74, 0x51, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x57, 0xAE, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x9B, 0x72, + 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xBC, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, + 0xF0, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x33, 0x1C, 0xDD, 0xE9, 0x17, 0x46, + 0x16, 0x9F, 0x19, 0x9D, 0xAD, 0xF8, 0x00, 0xC0, 0x04, 0xB9, 0x0D, 0x4C, + 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x08, 0x20, + 0x8D, 0xF8, 0x12, 0x60, 0xAD, 0xF8, 0x0A, 0x30, 0x8D, 0xF8, 0x13, 0x70, + 0x8D, 0xF8, 0x06, 0x50, 0x20, 0x68, 0x03, 0x90, 0xA0, 0x88, 0xAD, 0xF8, + 0x10, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x3F, 0xFB, 0x11, 0xB0, + 0xF0, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x31, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x2E, 0xFB, 0x11, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x99, 0x72, 0x8D, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x01, 0xF0, 0x76, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0, + 0x40, 0xF2, 0xB1, 0x14, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x0A, 0x30, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x62, 0xFB, 0x0C, 0xB0, 0x10, 0xBD, + 0x16, 0xF0, 0x44, 0xBB, 0x10, 0xB5, 0x8C, 0xB0, 0x4F, 0xF4, 0xBF, 0x74, + 0xAD, 0xF8, 0x04, 0x00, 0x13, 0x00, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, + 0x06, 0x10, 0x05, 0xD0, 0x10, 0x22, 0x19, 0x46, 0x0D, 0xF1, 0x07, 0x00, + 0x26, 0xF4, 0xE7, 0xF3, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x48, 0xFB, + 0x0C, 0xB0, 0x10, 0xBD, 0x16, 0xF0, 0x60, 0xBB, 0x10, 0xB5, 0x00, 0x28, + 0x02, 0xDA, 0x20, 0xF0, 0x00, 0x40, 0x01, 0xE0, 0x4F, 0xF0, 0xFF, 0x30, + 0x12, 0xF0, 0x2E, 0xF9, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x01, 0x20, + 0x10, 0xBD, 0x12, 0xF0, 0x41, 0xB9, 0x12, 0xF0, 0x45, 0xB9, 0x04, 0xF0, + 0x55, 0xBC, 0x00, 0x00, 0x7C, 0xB5, 0x0D, 0x46, 0xFD, 0xF7, 0x12, 0xFA, + 0x04, 0x00, 0x06, 0xD1, 0x00, 0x90, 0x01, 0x90, 0x68, 0x46, 0xFD, 0xF7, + 0x0B, 0xFA, 0x04, 0x00, 0x0B, 0xD0, 0x23, 0x7D, 0x01, 0x22, 0x05, 0x49, + 0x05, 0x48, 0xF4, 0xF7, 0xA2, 0xDA, 0x20, 0x7D, 0x04, 0x28, 0x01, 0xD0, + 0x08, 0x20, 0x20, 0x75, 0x25, 0x82, 0x7C, 0xBD, 0x10, 0x58, 0xC0, 0x08, + 0x02, 0x37, 0x10, 0x21, 0x70, 0xB5, 0x07, 0x4C, 0x40, 0xF2, 0x36, 0x45, + 0x20, 0x46, 0xFF, 0xF7, 0x04, 0xDA, 0x00, 0x28, 0x04, 0xD0, 0x2A, 0x46, + 0x03, 0x49, 0xFC, 0xF7, 0x0D, 0xF9, 0xF5, 0xE7, 0x70, 0xBD, 0x00, 0x00, + 0xE4, 0x77, 0x20, 0x00, 0x8E, 0xB0, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x7D, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x70, 0xB1, 0x00, 0x21, + 0x8D, 0xF8, 0x04, 0x10, 0x01, 0x46, 0x10, 0x22, 0x0D, 0xF1, 0x05, 0x00, + 0x26, 0xF4, 0x87, 0xF3, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x90, 0xFA, + 0x11, 0xB0, 0x00, 0xBD, 0x01, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0xF5, 0xE7, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x2B, 0x12, 0xAD, 0xF8, 0x00, 0x20, + 0x00, 0xB9, 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, + 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x77, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x8A, 0xAD, 0x82, 0x00, + 0x2D, 0xE9, 0xF0, 0x43, 0x8D, 0xB0, 0x04, 0x00, 0xDD, 0xE9, 0x18, 0x95, + 0xDD, 0xE9, 0x14, 0xC7, 0xDD, 0xE9, 0x16, 0x60, 0x4F, 0xF4, 0x96, 0x78, + 0xAD, 0xF8, 0x02, 0x80, 0x0F, 0xD0, 0xB4, 0xF8, 0x10, 0x80, 0xAD, 0xF8, + 0x06, 0x80, 0x94, 0xF8, 0x1C, 0x80, 0x8D, 0xF8, 0x1A, 0x80, 0x94, 0xF8, + 0x1D, 0x80, 0x8D, 0xF8, 0x1B, 0x80, 0x94, 0xF8, 0x1E, 0x80, 0x8D, 0xF8, + 0x1C, 0x80, 0xAD, 0xF8, 0x08, 0x30, 0xAD, 0xF8, 0x04, 0x50, 0x8D, 0xF8, + 0x0A, 0xC0, 0xAD, 0xF8, 0x14, 0x60, 0x8D, 0xF8, 0x0B, 0x70, 0x8D, 0xF8, + 0x0C, 0x20, 0xAD, 0xF8, 0x16, 0x00, 0xAD, 0xF8, 0x18, 0x90, 0x08, 0x68, + 0xCD, 0xF8, 0x0D, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x11, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0x91, 0xFA, 0x00, 0x2D, 0x05, 0xD1, 0x00, 0x2C, + 0x03, 0xD0, 0x20, 0x8A, 0x01, 0x21, 0x01, 0xF0, 0x39, 0xF9, 0x0D, 0xB0, + 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x95, 0x71, + 0xAD, 0xF8, 0x02, 0x10, 0x41, 0x7D, 0x8D, 0xF8, 0x0A, 0x10, 0xD0, 0xF8, + 0x16, 0x10, 0x01, 0x91, 0x40, 0x8B, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0x73, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5, + 0x8C, 0xB0, 0x4F, 0xF4, 0xA1, 0x74, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, + 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, + 0x0A, 0x30, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x5F, 0xFA, 0x0C, 0xB0, + 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x91, 0xB0, 0x0D, 0x00, 0xDD, 0xE9, + 0x17, 0x71, 0x4F, 0xF4, 0x94, 0x7C, 0x16, 0x9E, 0x4F, 0xF0, 0x01, 0x04, + 0xAD, 0xF8, 0x00, 0xC0, 0x8D, 0xF8, 0x04, 0x00, 0x00, 0xD1, 0x12, 0x4D, + 0x8D, 0xF8, 0x0C, 0x30, 0x8D, 0xF8, 0x0B, 0x20, 0xAD, 0xF8, 0x0E, 0x70, + 0x2A, 0x68, 0xCD, 0xF8, 0x05, 0x20, 0xAA, 0x88, 0xAD, 0xF8, 0x09, 0x20, + 0x8D, 0xF8, 0x0D, 0x60, 0x06, 0xF0, 0x07, 0x02, 0x38, 0xB1, 0x00, 0x24, + 0x03, 0xE0, 0x64, 0x1C, 0x50, 0x1E, 0xE4, 0xB2, 0x02, 0x40, 0x00, 0x2A, + 0xF9, 0xD1, 0x22, 0x01, 0x04, 0xA8, 0x26, 0xF4, 0xCA, 0xF2, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0xD3, 0xF9, 0x11, 0xB0, 0xF0, 0xBD, 0x00, 0x00, + 0x8A, 0xAD, 0x82, 0x00, 0x10, 0xB5, 0x8C, 0xB0, 0x40, 0xF2, 0x29, 0x14, + 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, 0x0E, 0x30, + 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, + 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x11, 0xFA, 0x0C, 0xB0, + 0x10, 0xBD, 0x2D, 0xE9, 0xF8, 0x43, 0x1F, 0x46, 0xDD, 0xE9, 0x08, 0x64, + 0x90, 0x46, 0x0D, 0x46, 0xFD, 0xF7, 0x10, 0xF9, 0x00, 0x28, 0x11, 0xD0, + 0x01, 0x2D, 0x08, 0xD0, 0x00, 0x8A, 0x01, 0xB0, 0x23, 0x46, 0x32, 0x46, + 0x41, 0x46, 0xBD, 0xE8, 0xF0, 0x43, 0xFF, 0xF7, 0x88, 0xBF, 0x00, 0x94, + 0x00, 0x8A, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x00, 0xF0, 0x12, 0xF8, + 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x41, 0x12, + 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x8A, 0xF9, 0x11, 0xB0, 0x00, 0xBD, + 0x30, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xA0, 0x75, 0x10, 0x9C, 0xAD, 0xF8, + 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, + 0x02, 0x50, 0xAD, 0xF8, 0x0A, 0x30, 0xAD, 0xF8, 0x0C, 0x40, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0xCB, 0xF9, 0x0D, 0xB0, 0x30, 0xBD, 0xF0, 0xB5, + 0x91, 0xB0, 0x16, 0xAC, 0x94, 0xE8, 0xE0, 0x00, 0xAD, 0xF8, 0x04, 0x00, + 0x4F, 0xF4, 0x9F, 0x74, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x08, 0x20, + 0xAD, 0xF8, 0x0C, 0x50, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, 0x0A, 0x30, + 0xAD, 0xF8, 0x0E, 0x60, 0xAD, 0xF8, 0x10, 0x70, 0x01, 0x21, 0x68, 0x46, + 0x01, 0xF0, 0x56, 0xF9, 0x11, 0xB0, 0xF0, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x3F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x9E, 0xF9, + 0x0D, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0, 0x0C, 0x46, 0xFC, 0xF7, + 0xBD, 0xFF, 0x00, 0x28, 0x0B, 0xD0, 0x40, 0xF2, 0x57, 0x11, 0xAD, 0xF8, + 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x40, 0x01, 0x21, + 0x68, 0x46, 0x01, 0xF0, 0x89, 0xF9, 0x0C, 0xB0, 0x10, 0xBD, 0x00, 0x00, + 0x70, 0xB5, 0x1C, 0x46, 0x13, 0x4B, 0x92, 0xB0, 0xDD, 0xE9, 0x16, 0x65, + 0xB3, 0xF8, 0xA6, 0x31, 0x93, 0x42, 0x09, 0xD2, 0x00, 0x93, 0x13, 0x46, + 0x02, 0x22, 0x0F, 0x49, 0x0F, 0x48, 0xF4, 0xF7, 0xFC, 0xD8, 0x00, 0x20, + 0x12, 0xB0, 0x70, 0xBD, 0xAD, 0xF8, 0x08, 0x00, 0x40, 0xF2, 0x4B, 0x13, + 0xAD, 0xF8, 0x0A, 0x10, 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x10, 0x60, + 0xAD, 0xF8, 0x04, 0x30, 0xAD, 0xF8, 0x0E, 0x40, 0xAD, 0xF8, 0x12, 0x50, + 0x01, 0x21, 0x01, 0xA8, 0x01, 0xF0, 0x06, 0xF9, 0xE8, 0xE7, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xF4, 0x51, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, + 0x30, 0xB5, 0x1C, 0x46, 0x11, 0x4B, 0x91, 0xB0, 0xB3, 0xF8, 0xA6, 0x31, + 0x14, 0x9D, 0x93, 0x42, 0x09, 0xD2, 0x00, 0x93, 0x13, 0x46, 0x02, 0x22, + 0x0D, 0x49, 0x0E, 0x48, 0xF4, 0xF7, 0xCD, 0xD8, 0x00, 0x20, 0x11, 0xB0, + 0x30, 0xBD, 0xAD, 0xF8, 0x08, 0x00, 0x4F, 0xF4, 0xA4, 0x73, 0xAD, 0xF8, + 0x0A, 0x10, 0xAD, 0xF8, 0x0C, 0x20, 0xAD, 0xF8, 0x04, 0x30, 0xAD, 0xF8, + 0x0E, 0x40, 0xAD, 0xF8, 0x10, 0x50, 0x01, 0x21, 0x01, 0xA8, 0x01, 0xF0, + 0xD9, 0xF8, 0xEA, 0xE7, 0x64, 0x01, 0x20, 0x00, 0xB4, 0x51, 0xC0, 0x08, + 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x55, 0x13, + 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30, + 0x8D, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xC2, 0xF8, + 0x11, 0xB0, 0x00, 0xBD, 0x38, 0xB5, 0x04, 0x9C, 0x13, 0xB1, 0x08, 0xB1, + 0x0C, 0x2C, 0x08, 0xD2, 0x00, 0x93, 0x23, 0x46, 0x02, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF4, 0xF7, 0x92, 0xD8, 0x00, 0x20, 0x38, 0xBD, 0x4F, 0xF4, + 0xA9, 0x75, 0x05, 0x80, 0x81, 0x80, 0xC2, 0x80, 0x03, 0x81, 0x44, 0x81, + 0xBD, 0xE8, 0x38, 0x40, 0x00, 0x21, 0x01, 0xF0, 0xA5, 0xB8, 0x00, 0x00, + 0x34, 0x52, 0xC0, 0x08, 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x4F, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x92, 0xF8, + 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xA6, 0x72, + 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x82, 0xF8, 0x11, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xAD, 0x72, 0xAD, 0xF8, 0x00, 0x20, + 0xFF, 0x28, 0x02, 0xD9, 0x00, 0x20, 0x11, 0xB0, 0x00, 0xBD, 0xAD, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x6D, 0xF8, 0xF4, 0xE7, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x5B, 0x12, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0xB6, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, + 0x10, 0xB5, 0x90, 0xB0, 0x4F, 0xF4, 0xAC, 0x74, 0xAD, 0xF8, 0x00, 0x40, + 0xFF, 0x28, 0x02, 0xD9, 0x00, 0x20, 0x10, 0xB0, 0x10, 0xBD, 0xAD, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0x8D, 0xF8, 0x07, 0x20, 0x8D, 0xF8, + 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, 0x45, 0xF8, 0xF0, 0xE7, + 0x10, 0xB5, 0x0C, 0x46, 0xFC, 0xF7, 0xA2, 0xFF, 0x00, 0x28, 0x00, 0xD0, + 0x84, 0x77, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x1E, 0x46, 0x15, 0x46, + 0x0F, 0x46, 0x14, 0x1D, 0xDD, 0xF8, 0x18, 0x80, 0xFC, 0xF7, 0xB0, 0xFE, + 0x00, 0x28, 0x0E, 0xD0, 0x4F, 0xF4, 0xAA, 0x71, 0x69, 0x80, 0x20, 0x80, + 0x67, 0x80, 0x0C, 0x3E, 0xA4, 0xF8, 0x04, 0x80, 0xE6, 0x80, 0x28, 0x46, + 0xBD, 0xE8, 0xF0, 0x41, 0x00, 0x21, 0x01, 0xF0, 0x79, 0xB8, 0xBD, 0xE8, + 0xF0, 0x81, 0x2D, 0xE9, 0xF0, 0x41, 0x8C, 0xB0, 0x1C, 0x46, 0x15, 0x46, + 0x0E, 0x46, 0x07, 0x46, 0xDD, 0xF8, 0x48, 0x80, 0xFC, 0xF7, 0xA0, 0xFE, + 0x4F, 0xF4, 0xB9, 0x71, 0xAD, 0xF8, 0x04, 0x70, 0xAD, 0xF8, 0x08, 0x50, + 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x06, 0x60, 0xAD, 0xF8, 0x0A, 0x40, + 0xAD, 0xF8, 0x0C, 0x80, 0x30, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x01, 0xF0, + 0x59, 0xF8, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x22, 0x69, 0x46, + 0x38, 0x46, 0xFC, 0xF7, 0xCB, 0xFE, 0xF6, 0xE7, 0x00, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x53, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x01, 0xF0, 0x40, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, + 0x07, 0x46, 0x16, 0x48, 0xDD, 0xE9, 0x08, 0x98, 0x1C, 0x46, 0x15, 0x46, + 0x0E, 0x46, 0x40, 0xF2, 0x34, 0x73, 0x11, 0x4A, 0x14, 0x21, 0x00, 0x78, + 0xFB, 0xF7, 0x4A, 0xFD, 0x00, 0x28, 0x18, 0xD0, 0x40, 0xF2, 0x81, 0x11, + 0x41, 0x80, 0x86, 0x72, 0x87, 0x74, 0x80, 0xF8, 0x13, 0x80, 0x44, 0x74, + 0x29, 0x68, 0x41, 0x60, 0xA9, 0x88, 0x01, 0x81, 0xD9, 0xF8, 0x00, 0x20, + 0xC0, 0xF8, 0x0B, 0x20, 0xB9, 0xF8, 0x04, 0x10, 0xA0, 0xF8, 0x0F, 0x10, + 0xBD, 0xE8, 0xF0, 0x47, 0x00, 0x21, 0x01, 0xF0, 0x13, 0xB8, 0xBD, 0xE8, + 0xF0, 0x87, 0x00, 0x00, 0x26, 0xAF, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0x98, 0x71, 0xAD, 0xF8, 0x00, 0x10, + 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xFF, + 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x2F, 0x12, + 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xF0, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x2D, 0x12, 0xAD, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x88, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x4F, 0xF4, 0x97, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xCE, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xDA, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x6A, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x92, 0xB0, + 0x04, 0x46, 0x0C, 0xA8, 0x08, 0xF0, 0x14, 0xFB, 0xAD, 0xF8, 0x04, 0x40, + 0xBD, 0xF8, 0x44, 0x00, 0xAD, 0xF8, 0x06, 0x00, 0x40, 0xF2, 0xB5, 0x11, + 0x9D, 0xF8, 0x40, 0x00, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x08, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xFF, 0x12, 0xB0, 0x10, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x93, 0x13, 0x8D, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x3E, 0xFF, 0x11, 0xB0, 0x00, 0xBD, + 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x95, 0x14, 0x8D, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x40, + 0x8D, 0xF8, 0x07, 0x30, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x2A, 0xFF, + 0x10, 0xB0, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x43, 0x91, 0xB0, 0x1D, 0x46, + 0xDD, 0xE9, 0x18, 0x49, 0x16, 0x46, 0x0F, 0x46, 0x80, 0x46, 0xFB, 0x2C, + 0x06, 0xD9, 0x23, 0x46, 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xF3, 0xF7, + 0xF6, 0xDE, 0xFB, 0x24, 0x40, 0xF2, 0x87, 0x10, 0x8D, 0xF8, 0x04, 0x80, + 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x05, 0x70, 0x8D, 0xF8, 0x06, 0x60, + 0x00, 0x20, 0x8D, 0xF8, 0x07, 0x50, 0x8D, 0xF8, 0x08, 0x40, 0x03, 0x90, + 0x74, 0xB1, 0x0E, 0x48, 0x40, 0xF6, 0x49, 0x03, 0x0B, 0x4A, 0x21, 0x46, + 0x00, 0x78, 0xFB, 0xF7, 0x71, 0xFC, 0x03, 0x90, 0x00, 0x28, 0x07, 0xD0, + 0x22, 0x46, 0x49, 0x46, 0x25, 0xF4, 0xE9, 0xF7, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xF2, 0xFE, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0x00, + 0x74, 0x52, 0xC0, 0x08, 0x01, 0x37, 0x10, 0x21, 0x70, 0xAE, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC4, 0x72, + 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x30, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x13, 0x46, 0x04, 0x29, 0x02, 0xD9, 0x00, 0x20, + 0x11, 0xB0, 0x00, 0xBD, 0x40, 0xF2, 0x89, 0x12, 0x8D, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x05, 0x10, 0x39, 0xB1, 0x01, 0xEB, + 0x41, 0x00, 0x42, 0x00, 0x19, 0x46, 0x0D, 0xF1, 0x06, 0x00, 0x25, 0xF4, + 0xB0, 0xF7, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xB9, 0xFE, 0xE7, 0xE7, + 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC5, 0x72, 0x8D, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x02, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F, + 0x91, 0xB0, 0x40, 0xF2, 0x85, 0x18, 0xDD, 0xE9, 0x1E, 0xEB, 0xDD, 0xE9, + 0x1C, 0x64, 0xDD, 0xE9, 0x20, 0x95, 0xDD, 0xE9, 0x1A, 0xC7, 0xDD, 0xF8, + 0x8C, 0xA0, 0xAD, 0xF8, 0x00, 0x80, 0x04, 0xB9, 0x14, 0x4C, 0x8D, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x10, 0xC0, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8, + 0x11, 0x70, 0xCD, 0xE9, 0x02, 0x23, 0x8D, 0xF8, 0x12, 0x60, 0x20, 0x68, + 0xCD, 0xF8, 0x13, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x17, 0x00, 0x8D, 0xF8, + 0x19, 0xE0, 0x8D, 0xF8, 0x1C, 0x50, 0x22, 0x98, 0x8D, 0xF8, 0x1A, 0xB0, + 0x8D, 0xF8, 0x1D, 0x00, 0x8D, 0xF8, 0x1B, 0x90, 0x8D, 0xF8, 0x1E, 0xA0, + 0x24, 0x98, 0x8D, 0xF8, 0x1F, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x6F, 0xFE, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x8A, 0xAD, 0x82, 0x00, + 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC3, 0x72, 0x8D, 0xF8, 0x04, 0x10, + 0xAD, 0xF8, 0x06, 0x00, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xB4, 0xFE, 0x0D, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, + 0x2B, 0x4E, 0x9A, 0x46, 0x17, 0x46, 0x88, 0x46, 0x81, 0x46, 0x40, 0xF2, + 0x91, 0x73, 0x27, 0x4A, 0x24, 0x21, 0x30, 0x78, 0xDD, 0xF8, 0x40, 0xB0, + 0x12, 0x9D, 0xFB, 0xF7, 0xBD, 0xFB, 0x04, 0x00, 0x41, 0xD0, 0x4F, 0xF4, + 0xD6, 0x70, 0x60, 0x80, 0xA4, 0xF8, 0x04, 0x90, 0x84, 0xF8, 0x06, 0x80, + 0xE7, 0x71, 0xDA, 0xF8, 0x00, 0x10, 0xA1, 0x60, 0xBA, 0xF8, 0x04, 0x00, + 0xA0, 0x81, 0x0A, 0x98, 0xA0, 0x73, 0x0B, 0x98, 0xE0, 0x73, 0x0C, 0x98, + 0x20, 0x74, 0x0D, 0x98, 0x60, 0x74, 0x0E, 0x98, 0xA0, 0x74, 0x0F, 0x98, + 0xA0, 0x82, 0x84, 0xF8, 0x16, 0xB0, 0x11, 0x98, 0x01, 0x68, 0xC4, 0xF8, + 0x17, 0x10, 0x80, 0x88, 0xA4, 0xF8, 0x1B, 0x00, 0x65, 0x77, 0x00, 0x20, + 0x20, 0x62, 0x65, 0xB1, 0x40, 0xF2, 0xA9, 0x73, 0x0D, 0x4A, 0x29, 0x46, + 0x30, 0x78, 0xFB, 0xF7, 0x8D, 0xFB, 0x20, 0x62, 0x48, 0xB1, 0x2A, 0x46, + 0x13, 0x99, 0x25, 0xF4, 0x06, 0xF7, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, + 0x00, 0x21, 0x00, 0xF0, 0x65, 0xBE, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, + 0x40, 0xF2, 0xAD, 0x72, 0x02, 0x49, 0xFB, 0xF7, 0x67, 0xBC, 0xBD, 0xE8, + 0xF0, 0x9F, 0x00, 0x00, 0x3E, 0xAF, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00, + 0x70, 0xB5, 0x04, 0x46, 0x0F, 0x48, 0x0D, 0x46, 0x40, 0x69, 0x05, 0xE0, + 0x01, 0x79, 0xA1, 0x42, 0x01, 0xD1, 0x45, 0x71, 0x70, 0xBD, 0x00, 0x68, + 0x00, 0x28, 0xF7, 0xD1, 0x0B, 0x48, 0x40, 0xF2, 0x0B, 0x43, 0x09, 0x4A, + 0x10, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x5C, 0xFB, 0x01, 0x00, 0xF1, 0xD0, + 0x0C, 0x71, 0x4D, 0x71, 0x00, 0x20, 0x88, 0x81, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0x48, 0x14, 0x30, 0xFE, 0xF7, 0x19, 0x9D, 0xD0, 0x77, 0x20, 0x00, + 0x4A, 0xB0, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, + 0x14, 0x48, 0x0D, 0x46, 0x40, 0x69, 0x09, 0xE0, 0x01, 0x79, 0xA1, 0x42, + 0x05, 0xD1, 0x29, 0x68, 0xC0, 0xF8, 0x06, 0x10, 0xA9, 0x88, 0x41, 0x81, + 0x70, 0xBD, 0x00, 0x68, 0x00, 0x28, 0xF3, 0xD1, 0x0E, 0x48, 0x40, 0xF2, + 0xEB, 0x33, 0x0C, 0x4A, 0x10, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x30, 0xFB, + 0x01, 0x00, 0xF1, 0xD0, 0x0C, 0x71, 0x01, 0x20, 0x48, 0x71, 0x28, 0x68, + 0xC1, 0xF8, 0x06, 0x00, 0xA8, 0x88, 0x48, 0x81, 0x00, 0x20, 0x88, 0x81, + 0xBD, 0xE8, 0x70, 0x40, 0x01, 0x48, 0x14, 0x30, 0xFE, 0xF7, 0xE7, 0x9C, + 0xD0, 0x77, 0x20, 0x00, 0x25, 0xB0, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x8B, 0x14, 0x8D, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x20, 0x02, 0xF0, 0x05, 0x00, + 0xAD, 0xF8, 0x00, 0x40, 0x00, 0x22, 0x03, 0xE0, 0x52, 0x1C, 0x41, 0x1E, + 0xD2, 0xB2, 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1, 0x02, 0xEB, 0x42, 0x00, + 0x42, 0x00, 0x19, 0x46, 0x02, 0xA8, 0x25, 0xF4, 0x7A, 0xF6, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x83, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0xB5, + 0x8D, 0xB0, 0x4F, 0xF4, 0xC6, 0x71, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, + 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xCD, 0xFD, 0x0D, 0xB0, + 0x00, 0xBD, 0x10, 0xB5, 0x90, 0xB0, 0x40, 0xF2, 0x8D, 0x14, 0x8D, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x40, 0xAD, 0xF8, + 0x06, 0x20, 0xAD, 0xF8, 0x08, 0x30, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x61, 0xFD, 0x10, 0xB0, 0x10, 0xBD, 0x11, 0xF0, 0xC5, 0xBD, 0x00, 0x00, + 0x01, 0x48, 0x00, 0x7C, 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, + 0x01, 0x48, 0x40, 0x7C, 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, + 0x10, 0xB5, 0x08, 0x4A, 0x00, 0x24, 0x52, 0x69, 0x07, 0xE0, 0x93, 0x89, + 0x83, 0x42, 0x03, 0xD1, 0x50, 0x79, 0x08, 0x70, 0x01, 0x24, 0x02, 0xE0, + 0x12, 0x68, 0x00, 0x2A, 0xF5, 0xD1, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00, + 0xD0, 0x77, 0x20, 0x00, 0x01, 0x46, 0x07, 0x48, 0x00, 0x23, 0x40, 0x69, + 0x05, 0xE0, 0x82, 0x89, 0x8A, 0x42, 0x01, 0xD1, 0x83, 0x1D, 0x02, 0xE0, + 0x00, 0x68, 0x00, 0x28, 0xF7, 0xD1, 0x18, 0x46, 0x70, 0x47, 0x00, 0x00, + 0xD0, 0x77, 0x20, 0x00, 0x00, 0xB5, 0x93, 0xB0, 0x40, 0xF2, 0xB3, 0x10, + 0xAD, 0xF8, 0x02, 0x00, 0x0C, 0xA8, 0x08, 0xF0, 0xD3, 0xF8, 0xDD, 0xF8, + 0x36, 0x00, 0x01, 0x90, 0xDD, 0xF8, 0x3A, 0x00, 0x02, 0x90, 0x11, 0x48, + 0x01, 0x21, 0x00, 0x78, 0xAD, 0xF8, 0x0C, 0x00, 0x1C, 0x20, 0xAD, 0xF8, + 0x0E, 0x00, 0x0E, 0x48, 0x90, 0xF8, 0xAB, 0x01, 0x8D, 0xF8, 0x10, 0x00, + 0x9D, 0xF8, 0x3F, 0x00, 0x8D, 0xF8, 0x11, 0x00, 0x9D, 0xF8, 0x3E, 0x00, + 0x8D, 0xF8, 0x12, 0x00, 0x9D, 0xF8, 0x41, 0x00, 0x8D, 0xF8, 0x13, 0x00, + 0x9D, 0xF8, 0x42, 0x00, 0x8D, 0xF8, 0x14, 0x00, 0x68, 0x46, 0x00, 0xF0, + 0x53, 0xFD, 0x13, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x06, 0x74, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x9D, 0x12, + 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xE6, 0xFC, 0x11, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xCF, 0x72, 0x8D, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x2E, 0xFD, 0x0D, 0xB0, 0x00, 0xBD, 0x30, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x73, 0x14, 0x14, 0x9D, 0xAD, 0xF8, 0x00, 0x40, 0x8D, 0xF8, + 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0x00, 0x24, 0x32, 0xB1, 0x10, 0x68, + 0xCD, 0xF8, 0x06, 0x00, 0x90, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x03, 0xE0, + 0xCD, 0xF8, 0x06, 0x40, 0xAD, 0xF8, 0x0A, 0x40, 0x2B, 0xB1, 0x10, 0x22, + 0x19, 0x46, 0x03, 0xA8, 0x25, 0xF4, 0xA9, 0xF5, 0x03, 0xE0, 0x03, 0x94, + 0x04, 0x94, 0x05, 0x94, 0x06, 0x94, 0x2D, 0xB1, 0x10, 0x22, 0x29, 0x46, + 0x07, 0xA8, 0x25, 0xF4, 0x9E, 0xF5, 0x03, 0xE0, 0x07, 0x94, 0x08, 0x94, + 0x09, 0x94, 0x0A, 0x94, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA2, 0xFC, + 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBA, 0x72, + 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xEA, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0x9E, 0x73, 0xAD, 0xF8, 0x00, 0x30, + 0x01, 0xB9, 0x08, 0x49, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x0B, 0x20, + 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x7A, 0xFC, 0x11, 0xB0, 0x00, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x3D, 0x12, + 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xC0, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, + 0xF0, 0xB5, 0x07, 0x46, 0x8D, 0xB0, 0x1D, 0x46, 0x16, 0x46, 0x0C, 0x46, + 0x08, 0x46, 0xFC, 0xF7, 0xE9, 0xFA, 0x40, 0xF2, 0xAB, 0x11, 0xAD, 0xF8, + 0x04, 0x70, 0x8D, 0xF8, 0x08, 0x60, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, + 0x06, 0x40, 0x8D, 0xF8, 0x09, 0x50, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xA4, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0x01, 0x22, 0x69, 0x46, + 0x20, 0x46, 0xFC, 0xF7, 0x17, 0xFB, 0xF7, 0xE7, 0x00, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x59, 0x11, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x90, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xB3, 0x70, 0xAD, 0xF8, 0x00, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x2C, 0xFC, 0x11, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x67, 0x12, 0xAD, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x74, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xAF, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x0E, 0xFC, 0x11, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0x5F, 0x13, 0xAD, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x06, 0x10, 0x2A, 0xB1, 0x21, 0xB9, + 0x10, 0x68, 0x02, 0x90, 0x10, 0x79, 0x8D, 0xF8, 0x0C, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x4F, 0xFC, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x77, 0x12, 0xAD, 0xF8, 0x00, 0x20, + 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x06, 0x49, 0x08, 0x68, 0xCD, 0xF8, + 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xE0, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, + 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBC, 0x72, 0xAD, 0xF8, 0x02, 0x20, + 0xAD, 0xF8, 0x04, 0x00, 0x08, 0x68, 0xCD, 0xF8, 0x06, 0x00, 0x88, 0x88, + 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x22, 0xFC, + 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x75, 0x12, + 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x06, 0x49, + 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xB4, 0xFB, 0x11, 0xB0, 0x00, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xBB, 0x72, + 0xAD, 0xF8, 0x02, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x08, 0x68, 0xCD, 0xF8, + 0x06, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xF6, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x99, 0x10, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x92, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x4F, 0xF4, 0xCD, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x07, 0x10, + 0xAD, 0xF8, 0x02, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xD8, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xB0, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x72, 0xFB, 0x11, 0xB0, 0x00, 0xBD, + 0x70, 0xB5, 0x8C, 0xB0, 0x0E, 0x46, 0x05, 0x46, 0x07, 0xF0, 0x3C, 0xFF, + 0x04, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0xF2, 0xF9, 0x4F, 0xF4, 0xDB, 0x71, + 0xAD, 0xF8, 0x06, 0x50, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x60, + 0x1C, 0xB1, 0x21, 0x68, 0x02, 0x91, 0x61, 0x68, 0x03, 0x91, 0x28, 0xB1, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xAC, 0xFB, 0x0C, 0xB0, 0x70, 0xBD, + 0x01, 0x22, 0x69, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0x1F, 0xFA, 0xF7, 0xE7, + 0x0C, 0x49, 0x10, 0xB5, 0x4C, 0x69, 0x03, 0xE0, 0x21, 0x79, 0x81, 0x42, + 0x03, 0xD0, 0x24, 0x68, 0x00, 0x2C, 0xF9, 0xD1, 0x10, 0xBD, 0x00, 0x2C, + 0xFC, 0xD0, 0x06, 0x48, 0x21, 0x46, 0x14, 0x30, 0xFE, 0xF7, 0xC3, 0xDA, + 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x40, 0xF2, 0x29, 0x42, 0x02, 0x49, + 0xFB, 0xF7, 0x94, 0xB9, 0xD0, 0x77, 0x20, 0x00, 0x73, 0xB0, 0x82, 0x00, + 0x30, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x39, 0x15, 0x8D, 0xF8, 0x04, 0x00, + 0x14, 0x9C, 0xAD, 0xF8, 0x08, 0x20, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8, + 0x0A, 0x30, 0xAD, 0xF8, 0x00, 0x50, 0x8D, 0xF8, 0x0B, 0x40, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x19, 0xFB, 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5, + 0x91, 0xB0, 0x40, 0xF2, 0x37, 0x12, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, + 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x09, 0xFB, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x06, 0x46, + 0x0E, 0x48, 0x14, 0x46, 0x0D, 0x46, 0x40, 0xF6, 0x1B, 0x03, 0x0B, 0x4A, + 0x0C, 0x21, 0x00, 0x78, 0xFB, 0xF7, 0x6E, 0xF8, 0x00, 0x28, 0x0E, 0xD0, + 0x4F, 0xF4, 0xD9, 0x71, 0x41, 0x80, 0x06, 0x71, 0x45, 0x71, 0x21, 0x68, + 0xC0, 0xF8, 0x06, 0x10, 0xA1, 0x88, 0x41, 0x81, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0x21, 0x00, 0xF0, 0x41, 0xBB, 0x70, 0xBD, 0x5A, 0xAF, 0x82, 0x00, + 0x03, 0x74, 0x20, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x9C, 0x71, + 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x30, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xA8, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xC6, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x51, 0x13, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, + 0xAD, 0xF8, 0x02, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x0C, 0xFB, 0x0D, 0xB0, 0x00, 0xBD, 0x01, 0x49, 0x08, 0x74, + 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, 0x00, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x83, 0x12, 0xAD, 0xF8, 0x00, 0x20, 0x00, 0x28, 0x0B, 0xD0, + 0x8D, 0xF8, 0x04, 0x10, 0x01, 0x68, 0xCD, 0xF8, 0x05, 0x10, 0x80, 0x88, + 0xAD, 0xF8, 0x09, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x98, 0xFA, + 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0xC2, 0x73, + 0xAD, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x30, + 0x10, 0x68, 0xCD, 0xF8, 0x07, 0x00, 0x90, 0x88, 0xAD, 0xF8, 0x0B, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xDA, 0xFA, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xAE, 0x71, 0xAD, 0xF8, 0x00, 0x10, + 0x01, 0x68, 0x01, 0x91, 0x00, 0x79, 0x8D, 0xF8, 0x08, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x71, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, + 0x91, 0xB0, 0x4F, 0xF4, 0xB8, 0x73, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, + 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x20, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x5F, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x30, 0xB5, + 0x05, 0x46, 0x8D, 0xB0, 0x0C, 0x46, 0x08, 0x46, 0xFC, 0xF7, 0xE2, 0xF8, + 0x40, 0xF2, 0x71, 0x11, 0xAD, 0xF8, 0x04, 0x50, 0xAD, 0xF8, 0x02, 0x10, + 0xAD, 0xF8, 0x06, 0x40, 0x28, 0xB1, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0xA1, 0xFA, 0x0D, 0xB0, 0x30, 0xBD, 0x01, 0x22, 0x69, 0x46, 0x20, 0x46, + 0xFC, 0xF7, 0x14, 0xF9, 0xF7, 0xE7, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, + 0x8F, 0x13, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, + 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x31, 0xFA, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x01, 0x49, 0x48, 0x74, + 0x70, 0x47, 0x00, 0x00, 0xD0, 0x77, 0x20, 0x00, 0x30, 0xB5, 0x91, 0xB0, + 0x40, 0xF2, 0x91, 0x15, 0xAD, 0xF8, 0x04, 0x00, 0x14, 0x9C, 0x8D, 0xF8, + 0x06, 0x10, 0x8D, 0xF8, 0x08, 0x30, 0xAD, 0xF8, 0x00, 0x50, 0x8D, 0xF8, + 0x07, 0x20, 0x8D, 0xF8, 0x09, 0x40, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x13, 0xFA, 0x11, 0xB0, 0x30, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, + 0xC9, 0x72, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, + 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x5B, 0xFA, 0x0D, 0xB0, + 0x00, 0xBD, 0x00, 0x00, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x7F, 0x13, + 0xAD, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0xB9, 0x07, 0x49, + 0x08, 0x68, 0xCD, 0xF8, 0x05, 0x00, 0x88, 0x88, 0xAD, 0xF8, 0x09, 0x00, + 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xEA, 0xF9, + 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x91, 0xB0, + 0x4F, 0xF4, 0xB4, 0x71, 0xAD, 0xF8, 0x00, 0x10, 0x00, 0x28, 0x08, 0xD0, + 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0xD5, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, + 0x91, 0xB0, 0x40, 0xF2, 0x79, 0x11, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, + 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xC7, 0xF9, 0x11, 0xB0, + 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x7B, 0x11, 0xAD, 0xF8, + 0x00, 0x10, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0xB9, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x2D, 0xE9, 0xF0, 0x43, 0x80, 0x46, + 0x8D, 0xB0, 0x17, 0x46, 0x0E, 0x46, 0x08, 0x46, 0xFC, 0xF7, 0x10, 0xF9, + 0x04, 0x00, 0x4F, 0xF4, 0xDC, 0x70, 0xAD, 0xF8, 0x02, 0x00, 0x19, 0xD0, + 0x20, 0x7D, 0x0B, 0x28, 0x16, 0xD1, 0x04, 0xF1, 0x16, 0x00, 0x61, 0x7D, + 0x81, 0x46, 0x11, 0xF0, 0x0D, 0xFB, 0x05, 0x46, 0x61, 0x7D, 0x48, 0x46, + 0x11, 0xF0, 0xF6, 0xFA, 0xAD, 0xF8, 0x04, 0x60, 0x8D, 0xF8, 0x08, 0x70, + 0xCD, 0xE9, 0x03, 0x05, 0xAD, 0xF8, 0x06, 0x80, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xE6, 0xF9, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x00, 0xB5, + 0x91, 0xB0, 0x4F, 0xF4, 0xB2, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x81, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, + 0x8D, 0xB0, 0x40, 0xF2, 0x65, 0x12, 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, + 0x06, 0x10, 0xAD, 0xF8, 0x02, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0xC9, 0xF9, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, + 0xB1, 0x73, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, + 0x00, 0x30, 0x8D, 0xF8, 0x06, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x5F, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x05, 0x4A, 0x52, 0x69, + 0x05, 0xE0, 0x13, 0x79, 0x83, 0x42, 0x01, 0xD1, 0x91, 0x81, 0x70, 0x47, + 0x12, 0x68, 0x00, 0x2A, 0xF7, 0xD1, 0x70, 0x47, 0xD0, 0x77, 0x20, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xB7, 0x72, 0xAD, 0xF8, 0x04, 0x00, + 0xAD, 0xF8, 0x06, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x40, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x40, 0xF2, 0x6F, 0x11, 0xAD, 0xF8, 0x02, 0x10, 0xAD, 0xF8, 0x04, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x8A, 0xF9, 0x0D, 0xB0, 0x00, 0xBD, + 0x00, 0xB5, 0x91, 0xB0, 0x40, 0xF2, 0x9B, 0x12, 0x8D, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x00, 0x20, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x22, 0xF9, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x90, 0xB0, + 0x10, 0x24, 0x8D, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x06, 0x10, 0x8D, 0xF8, + 0x08, 0x20, 0xAD, 0xF8, 0x00, 0x40, 0x8D, 0xF8, 0x09, 0x30, 0x01, 0x21, + 0x68, 0x46, 0x00, 0xF0, 0x0F, 0xF9, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0xB5, + 0x8D, 0xB0, 0x12, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, + 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, + 0x0B, 0x20, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x53, 0xF9, 0x0D, 0xB0, + 0x00, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x0F, 0x46, 0x04, 0x46, + 0xFC, 0xF7, 0x54, 0xF8, 0x05, 0x00, 0x07, 0xD0, 0xDF, 0xF8, 0x60, 0x80, + 0x40, 0xF2, 0x36, 0x39, 0x40, 0xF2, 0x39, 0x3A, 0x6C, 0x68, 0x21, 0xE0, + 0x23, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x13, 0x48, 0x01, 0x22, 0x13, 0x49, + 0x80, 0x1E, 0xF3, 0xF7, 0xBE, 0x98, 0x66, 0x68, 0x10, 0x49, 0x01, 0x22, + 0x73, 0x88, 0x40, 0x31, 0x40, 0x46, 0xF3, 0xF7, 0xB6, 0xD8, 0x27, 0xB1, + 0x00, 0x21, 0x30, 0x46, 0x00, 0xF0, 0x2A, 0xF9, 0x04, 0xE0, 0x4A, 0x46, + 0x0A, 0x49, 0x30, 0x46, 0xFA, 0xF7, 0x2E, 0xFF, 0x52, 0x46, 0x08, 0x49, + 0x20, 0x46, 0xFA, 0xF7, 0x29, 0xFF, 0x24, 0x68, 0x00, 0x2C, 0xE4, 0xD1, + 0x28, 0x1D, 0xBD, 0xE8, 0xF0, 0x47, 0xFD, 0xF7, 0xF7, 0x9F, 0x00, 0x00, + 0x02, 0x37, 0x10, 0x21, 0xE8, 0x53, 0xC0, 0x08, 0xF4, 0xAE, 0x82, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x23, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, + 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xA8, 0xF8, 0x11, 0xB0, 0x00, 0xBD, + 0x70, 0xB5, 0x8C, 0xB0, 0x24, 0x26, 0xDD, 0xE9, 0x10, 0x45, 0xAD, 0xF8, + 0x0C, 0x00, 0xAD, 0xF8, 0x10, 0x40, 0xAD, 0xF8, 0x02, 0x60, 0x8D, 0xF8, + 0x0A, 0x20, 0x8D, 0xF8, 0x0E, 0x30, 0xAD, 0xF8, 0x12, 0x50, 0x08, 0x68, + 0x01, 0x90, 0x88, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0xE4, 0xF8, 0x0C, 0xB0, 0x70, 0xBD, 0x00, 0xB5, 0x91, 0xB0, + 0x0B, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, + 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, + 0x00, 0xF0, 0x7A, 0xF8, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, 0x8C, 0xB0, + 0x0C, 0x24, 0xAD, 0xF8, 0x0C, 0x00, 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, + 0x0A, 0x20, 0x8D, 0xF8, 0x0E, 0x30, 0x08, 0x68, 0x01, 0x90, 0x88, 0x88, + 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0xBC, 0xF8, + 0x0C, 0xB0, 0x10, 0xBD, 0x00, 0xB5, 0x91, 0xB0, 0x01, 0x21, 0x01, 0x90, + 0xAD, 0xF8, 0x00, 0x10, 0x68, 0x46, 0x00, 0xF0, 0x59, 0xF8, 0x11, 0xB0, + 0x00, 0xBD, 0x00, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0x23, 0x7D, + 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xF3, 0xF7, 0x2C, 0xD8, 0x20, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0x20, 0x21, 0x25, 0xF4, 0xDB, 0xB1, 0x10, 0xBD, + 0x98, 0x57, 0xC0, 0x08, 0x03, 0x37, 0x10, 0x21, 0x10, 0xB5, 0x90, 0xB0, + 0x14, 0x46, 0x40, 0xF2, 0x01, 0x12, 0xAD, 0xF8, 0x00, 0x20, 0x00, 0xB9, + 0x0B, 0x48, 0x04, 0xB9, 0x0A, 0x4C, 0x8D, 0xF8, 0x1B, 0x10, 0x8D, 0xF8, + 0x1A, 0x30, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, + 0x10, 0x22, 0x21, 0x46, 0x0D, 0xF1, 0x0A, 0x00, 0x25, 0xF4, 0x1B, 0xF1, + 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, 0x24, 0xF8, 0x10, 0xB0, 0x10, 0xBD, + 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x4F, 0xF4, 0x80, 0x72, + 0xAD, 0xF8, 0x02, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, + 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x67, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, 0xAD, 0xF8, + 0x02, 0x00, 0xAD, 0xF8, 0x04, 0x10, 0x01, 0x21, 0x68, 0x46, 0x00, 0xF0, + 0x5B, 0xF8, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x87, 0xB0, + 0x0C, 0x46, 0x05, 0x46, 0xFB, 0xF7, 0x14, 0xF9, 0xC8, 0xB1, 0x28, 0x46, + 0xFC, 0xF7, 0x62, 0xFD, 0x03, 0x1D, 0x02, 0x22, 0x1F, 0x49, 0x20, 0x48, + 0x00, 0x95, 0xF2, 0xF7, 0xCE, 0xDF, 0xBC, 0xB1, 0x1F, 0x48, 0x4F, 0xF4, + 0xA8, 0x73, 0x1D, 0x4A, 0x40, 0x21, 0x00, 0x78, 0xFA, 0xF7, 0x5A, 0xFD, + 0x04, 0x00, 0x0A, 0xD0, 0x40, 0x22, 0x29, 0x46, 0x25, 0xF4, 0x18, 0xF1, + 0x09, 0xE0, 0x15, 0x49, 0x00, 0x22, 0x2C, 0x39, 0x17, 0x48, 0xF2, 0xF7, + 0xB8, 0xDF, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD, 0x2C, 0x46, 0x4F, 0xF4, + 0x80, 0x70, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00, + 0x00, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x40, 0x20, 0xAD, 0xF8, 0x0C, 0x00, + 0x0E, 0x48, 0x04, 0x94, 0x4F, 0xF4, 0xB1, 0x73, 0x09, 0x4A, 0x01, 0xA9, + 0x00, 0x78, 0xFB, 0xF7, 0x39, 0xF8, 0x08, 0xB1, 0x01, 0x20, 0xE3, 0xE7, + 0x4F, 0xF4, 0xB2, 0x72, 0x04, 0x49, 0x04, 0x98, 0xFA, 0xF7, 0x18, 0xFE, + 0xDB, 0xE7, 0x00, 0x00, 0xFC, 0x4F, 0xC0, 0x08, 0x03, 0x3E, 0x11, 0x21, + 0xAA, 0xAD, 0x82, 0x00, 0x02, 0x74, 0x20, 0x00, 0x00, 0x37, 0x10, 0x21, + 0xCC, 0x77, 0x20, 0x00, 0xF8, 0xB5, 0x1B, 0x4E, 0x04, 0x46, 0x0D, 0x46, + 0x30, 0x7A, 0x36, 0x1D, 0xC8, 0xB1, 0x20, 0x46, 0xFC, 0xF7, 0x26, 0xFE, + 0x03, 0x1D, 0x02, 0x22, 0x16, 0x49, 0x17, 0x48, 0x00, 0x94, 0xF2, 0xF7, + 0x76, 0xDF, 0xB5, 0xB1, 0x16, 0x48, 0x4F, 0xF4, 0xD8, 0x73, 0x14, 0x4A, + 0x30, 0x21, 0x00, 0x78, 0xFA, 0xF7, 0x02, 0xFD, 0x05, 0x1E, 0x12, 0xD0, + 0x30, 0x22, 0x21, 0x46, 0x25, 0xF4, 0xC0, 0xF0, 0x08, 0xE0, 0x0C, 0x49, + 0x63, 0x88, 0x01, 0x22, 0x38, 0x39, 0x0E, 0x48, 0xF2, 0xF7, 0x5F, 0xDF, + 0x0C, 0xE0, 0x25, 0x46, 0x31, 0x68, 0x19, 0xB1, 0x28, 0x46, 0x88, 0x47, + 0x01, 0x20, 0xF8, 0xBD, 0x4F, 0xF4, 0xE3, 0x72, 0x05, 0x49, 0x28, 0x46, + 0xFA, 0xF7, 0xD4, 0xFD, 0x00, 0x20, 0xF8, 0xBD, 0xD0, 0x77, 0x20, 0x00, + 0xEC, 0x52, 0xC0, 0x08, 0x03, 0x3E, 0x12, 0x21, 0xA2, 0xAE, 0x82, 0x00, + 0x02, 0x74, 0x20, 0x00, 0x00, 0x37, 0x10, 0x21, 0x00, 0xB5, 0x91, 0xB0, + 0x21, 0x21, 0xAD, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x04, 0x00, 0x01, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0x59, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x10, 0xB5, + 0x04, 0x00, 0x01, 0xD1, 0x05, 0xF0, 0x50, 0xFC, 0x21, 0x46, 0xBD, 0xE8, + 0x10, 0x40, 0x22, 0x20, 0xFF, 0xF7, 0x3F, 0xBF, 0x00, 0xB5, 0x91, 0xB0, + 0x1C, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, 0x07, 0x48, 0x8D, 0xF8, + 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, + 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, 0xFF, 0xF7, 0x38, 0xFF, + 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, + 0x1B, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, + 0xAD, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x0A, 0x10, 0x03, 0x92, 0x01, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0x7B, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x4F, 0xF4, 0xDE, 0x73, 0xAD, 0xF8, 0x00, 0x30, + 0x00, 0xB9, 0x08, 0x48, 0x8D, 0xF8, 0x0B, 0x20, 0x8D, 0xF8, 0x0A, 0x10, + 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0x0B, 0xFF, 0x11, 0xB0, 0x00, 0xBD, 0x00, 0x00, + 0x8A, 0xAD, 0x82, 0x00, 0x00, 0xB5, 0x8D, 0xB0, 0x40, 0xF2, 0xBB, 0x13, + 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, 0xAD, 0xF8, + 0x08, 0x00, 0x03, 0x91, 0x8D, 0xF8, 0x0A, 0x20, 0x01, 0x21, 0x68, 0x46, + 0xFF, 0xF7, 0x4C, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0xB5, 0x8D, 0xB0, + 0x16, 0x23, 0xAD, 0xF8, 0x02, 0x30, 0x03, 0x68, 0x01, 0x93, 0x80, 0x88, + 0xAD, 0xF8, 0x08, 0x00, 0x03, 0x91, 0x8D, 0xF8, 0x0A, 0x20, 0x01, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0x39, 0xFF, 0x0D, 0xB0, 0x00, 0xBD, 0x00, 0x00, + 0x00, 0xB5, 0x91, 0xB0, 0x13, 0x23, 0xAD, 0xF8, 0x00, 0x30, 0x00, 0xB9, + 0x07, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x20, 0x01, 0x68, + 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, 0x68, 0x46, + 0xFF, 0xF7, 0xCA, 0xFE, 0x11, 0xB0, 0x00, 0xBD, 0x8A, 0xAD, 0x82, 0x00, + 0x10, 0xB5, 0x90, 0xB0, 0x14, 0x24, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0xB9, + 0x08, 0x48, 0x8D, 0xF8, 0x0A, 0x10, 0x03, 0x92, 0x8D, 0xF8, 0x10, 0x30, + 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x21, + 0x68, 0x46, 0xFF, 0xF7, 0xB1, 0xFE, 0x10, 0xB0, 0x10, 0xBD, 0x00, 0x00, + 0x8A, 0xAD, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x10, 0x48, + 0x17, 0x46, 0x0D, 0x46, 0x4F, 0xF4, 0xE1, 0x73, 0x0C, 0x4A, 0xC9, 0x1D, + 0x00, 0x78, 0xFA, 0xF7, 0x13, 0xFC, 0x00, 0x28, 0x10, 0xD0, 0x04, 0x46, + 0x0D, 0x20, 0x20, 0x80, 0xA6, 0x80, 0xA5, 0x71, 0x25, 0xB1, 0x2A, 0x46, + 0x39, 0x46, 0xE0, 0x1D, 0x24, 0xF4, 0x85, 0xF7, 0x20, 0x46, 0xBD, 0xE8, + 0xF0, 0x41, 0x00, 0x21, 0xFF, 0xF7, 0x8C, 0xBE, 0xBD, 0xE8, 0xF0, 0x81, + 0xD8, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41, + 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0xA8, 0xFA, + 0x68, 0xB1, 0x00, 0x20, 0x03, 0x94, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x05, + 0x33, 0x46, 0x09, 0x22, 0x04, 0x21, 0x38, 0x46, 0x01, 0xF0, 0xF4, 0xF8, + 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, 0xFA, 0xE7, 0x00, 0x00, + 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x04, 0x46, + 0x00, 0xF0, 0x8E, 0xFA, 0xA0, 0xB1, 0x0B, 0x4A, 0x04, 0xEB, 0x84, 0x01, + 0x00, 0x20, 0x92, 0x68, 0x3B, 0x46, 0x02, 0xEB, 0xC1, 0x01, 0x05, 0x22, + 0x48, 0x71, 0x03, 0x95, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x06, 0x03, 0x21, + 0x20, 0x46, 0x01, 0xF0, 0xD3, 0xF8, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, + 0x02, 0x20, 0xFA, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0xFF, 0x29, 0x00, 0xD1, 0x00, 0x21, 0x00, 0xF0, 0x6C, 0xFA, + 0x70, 0xB1, 0x00, 0x20, 0x01, 0xAE, 0x01, 0x21, 0x4F, 0xF6, 0xFF, 0x72, + 0x00, 0x90, 0x86, 0xE8, 0x07, 0x00, 0x2B, 0x46, 0x0A, 0x46, 0x20, 0x46, + 0x01, 0xF0, 0xB6, 0xF8, 0x04, 0xB0, 0x70, 0xBD, 0x02, 0x20, 0xFB, 0xE7, + 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x0A, 0x48, 0x0E, 0xF0, 0x60, 0xFA, + 0x58, 0xB1, 0x09, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB, + 0x00, 0x10, 0x00, 0x8A, 0xFB, 0xF7, 0xA8, 0xFD, 0x18, 0xB1, 0x00, 0x20, + 0x10, 0xBD, 0x02, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x00, 0x00, + 0x8D, 0xB2, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF3, 0x4F, + 0xDF, 0xF8, 0xC0, 0xA0, 0x2E, 0x49, 0x00, 0xEB, 0x80, 0x09, 0xDA, 0xF8, + 0x08, 0x30, 0x0A, 0x88, 0x03, 0xEB, 0xC9, 0x04, 0x03, 0x26, 0x21, 0x8C, + 0xE3, 0x8B, 0x00, 0xEB, 0x40, 0x08, 0xC9, 0x1A, 0x29, 0x4B, 0x0D, 0x04, + 0x83, 0xB0, 0x19, 0x68, 0x2D, 0x0C, 0x01, 0xEB, 0x08, 0x10, 0x2F, 0xD0, + 0x40, 0x8A, 0x9B, 0x46, 0x40, 0x1F, 0xA8, 0x42, 0x00, 0xDA, 0x85, 0xB2, + 0x52, 0x1D, 0x96, 0xB2, 0x31, 0x46, 0x28, 0x46, 0xFC, 0xF7, 0x6E, 0xFC, + 0x07, 0x00, 0x33, 0xD0, 0xE1, 0x8B, 0x60, 0x6A, 0x2A, 0x46, 0x01, 0x44, + 0xB8, 0x19, 0x24, 0xF4, 0xD8, 0xF6, 0xE0, 0x8B, 0xCD, 0xE9, 0x00, 0x06, + 0xDB, 0xF8, 0x00, 0x10, 0xA2, 0x8B, 0x01, 0xEB, 0x08, 0x10, 0x2B, 0x46, + 0x01, 0x8A, 0x38, 0x46, 0xFB, 0xF7, 0xF6, 0xFD, 0x88, 0xB1, 0xE0, 0x8B, + 0x00, 0x26, 0x28, 0x44, 0xE0, 0x83, 0x04, 0x98, 0xE0, 0x70, 0xDA, 0xF8, + 0x08, 0x10, 0x01, 0x22, 0x01, 0xEB, 0xC9, 0x00, 0x02, 0x71, 0x0D, 0xE0, + 0x00, 0x8A, 0x01, 0x21, 0xFB, 0xF7, 0x6E, 0xFD, 0x08, 0xE0, 0x07, 0x26, + 0x38, 0x46, 0xFB, 0xF7, 0x25, 0xFC, 0x0A, 0x49, 0x00, 0x22, 0x0A, 0x48, + 0xF2, 0xF7, 0x9B, 0xDD, 0x05, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, + 0x05, 0x49, 0x08, 0x26, 0x00, 0x22, 0x38, 0x31, 0xF3, 0xE7, 0x00, 0x00, + 0x46, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00, + 0x4C, 0x64, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0xFE, 0xB5, 0x15, 0x46, + 0x0E, 0x46, 0x04, 0x46, 0x00, 0xF0, 0xCC, 0xF9, 0xD0, 0xB1, 0x00, 0x22, + 0x11, 0x49, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92, 0x09, 0x68, 0x04, 0xEB, + 0x44, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x2B, 0x46, 0x00, 0x8A, 0x01, 0x21, + 0xFB, 0xF7, 0x52, 0xFE, 0x60, 0xB1, 0x0B, 0x48, 0x04, 0xEB, 0x84, 0x01, + 0x00, 0x25, 0x80, 0x68, 0x00, 0xEB, 0xC1, 0x00, 0x01, 0x21, 0x86, 0x70, + 0x01, 0x71, 0x07, 0xE0, 0x02, 0x20, 0xFE, 0xBD, 0x07, 0x25, 0x00, 0x22, + 0x04, 0x49, 0x05, 0x48, 0xF2, 0xF7, 0x5D, 0xDD, 0x28, 0x46, 0xFE, 0xBD, + 0x64, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xF0, 0x63, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F, 0x1C, 0x46, 0xDD, 0xE9, + 0x0C, 0xA9, 0x17, 0x46, 0x0E, 0x46, 0x05, 0x46, 0x4F, 0xF0, 0x02, 0x08, + 0x00, 0xF0, 0x92, 0xF9, 0x08, 0xB1, 0x1F, 0xB1, 0x03, 0xE0, 0x40, 0x46, + 0xBD, 0xE8, 0xFE, 0x8F, 0x01, 0x27, 0x0C, 0xB9, 0x4F, 0xF6, 0xFF, 0x74, + 0x11, 0x49, 0xCD, 0xE9, 0x00, 0x4A, 0xCD, 0xF8, 0x08, 0x90, 0x09, 0x68, + 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x3B, 0x46, 0x00, 0x8A, + 0x00, 0x22, 0x02, 0x21, 0xFB, 0xF7, 0x0E, 0xFE, 0x50, 0xB1, 0x0A, 0x48, + 0x05, 0xEB, 0x85, 0x01, 0x00, 0x24, 0x80, 0x68, 0x00, 0xEB, 0xC1, 0x00, + 0x01, 0x21, 0x86, 0x70, 0x01, 0x71, 0x05, 0xE0, 0x07, 0x24, 0x00, 0x22, + 0x04, 0x49, 0x05, 0x48, 0xF2, 0xF7, 0x1B, 0xDD, 0x20, 0x46, 0xD5, 0xE7, + 0x64, 0x78, 0x20, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x18, 0x64, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x83, 0x46, + 0x15, 0x46, 0x4F, 0xF0, 0x03, 0x09, 0x59, 0x46, 0x5E, 0x48, 0x10, 0x9C, + 0x0E, 0xF0, 0x5C, 0xF9, 0x40, 0xB1, 0x5D, 0x48, 0x0B, 0xEB, 0x8B, 0x06, + 0x01, 0x2D, 0x07, 0xD0, 0x5B, 0x49, 0x09, 0x78, 0xD9, 0xB1, 0x09, 0xE0, + 0x02, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x81, 0x68, 0x01, 0xEB, + 0xC6, 0x01, 0x09, 0x79, 0x01, 0x29, 0x09, 0xD0, 0x82, 0x46, 0x80, 0x68, + 0x54, 0x49, 0x00, 0xEB, 0xC6, 0x07, 0x0B, 0xEB, 0x4B, 0x08, 0x04, 0x2D, + 0x0F, 0xD0, 0x15, 0xE0, 0x5B, 0x46, 0x01, 0x22, 0x50, 0x49, 0x51, 0x48, + 0xF2, 0xF7, 0xE1, 0xDC, 0xE4, 0xE7, 0x4E, 0x49, 0x00, 0x22, 0x2C, 0x31, + 0x4D, 0x48, 0xF2, 0xF7, 0xDA, 0xDC, 0x06, 0x20, 0xDD, 0xE7, 0x0A, 0x68, + 0x02, 0xEB, 0x08, 0x10, 0x40, 0x8A, 0x0F, 0x38, 0xA0, 0x42, 0x0B, 0xDB, + 0x45, 0x49, 0x09, 0x68, 0x01, 0xEB, 0x08, 0x10, 0x40, 0x8A, 0xC0, 0x1E, + 0xA0, 0x42, 0x23, 0xDA, 0x4F, 0xF4, 0x00, 0x71, 0x8C, 0x42, 0x01, 0xD9, + 0x09, 0x20, 0xC8, 0xE7, 0x01, 0x2D, 0x01, 0xD0, 0x48, 0x46, 0xC4, 0xE7, + 0x40, 0xF2, 0xC1, 0x23, 0x38, 0x4A, 0x00, 0x20, 0xFD, 0xF7, 0x4E, 0xDA, + 0x78, 0x62, 0x78, 0xB1, 0x22, 0x46, 0x11, 0x99, 0x24, 0xF4, 0xC7, 0xF5, + 0x3C, 0x84, 0x00, 0x20, 0xF8, 0x83, 0x06, 0x98, 0xB8, 0x83, 0x04, 0x99, + 0x07, 0xB0, 0x58, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0xFF, 0xF7, 0xB4, 0xBE, + 0x08, 0x20, 0xAA, 0xE7, 0x32, 0x48, 0x01, 0x88, 0x32, 0x48, 0xC9, 0x1C, + 0x89, 0xB2, 0x00, 0x88, 0x89, 0x46, 0x04, 0x2D, 0x2A, 0xD0, 0x0A, 0x46, + 0x21, 0x46, 0xFB, 0xF7, 0x0F, 0xFB, 0x07, 0x00, 0x44, 0xD0, 0x07, 0xEB, + 0x09, 0x00, 0x22, 0x46, 0x11, 0x99, 0x24, 0xF4, 0xA4, 0xF5, 0x25, 0x49, + 0xCD, 0xE9, 0x00, 0x49, 0x09, 0x68, 0x2A, 0x46, 0x01, 0xEB, 0x08, 0x10, + 0x06, 0x9B, 0x01, 0x8A, 0x38, 0x46, 0xFB, 0xF7, 0xBD, 0xFE, 0x28, 0xB3, + 0x00, 0x24, 0x02, 0x2D, 0x13, 0xD0, 0x04, 0x2D, 0x11, 0xD0, 0xDA, 0xF8, + 0x08, 0x00, 0x01, 0x21, 0x00, 0xEB, 0xC6, 0x00, 0x01, 0x71, 0xDA, 0xF8, + 0x08, 0x10, 0x04, 0x98, 0x01, 0xEB, 0xC6, 0x01, 0xC8, 0x70, 0x1D, 0xE0, + 0x04, 0xF1, 0x0C, 0x01, 0x89, 0xB2, 0x4A, 0x46, 0xD1, 0xE7, 0x12, 0x49, + 0x5B, 0x46, 0x02, 0x22, 0x08, 0x78, 0x40, 0x1E, 0xC0, 0xB2, 0x08, 0x70, + 0x00, 0x90, 0x10, 0x49, 0x10, 0x48, 0x5C, 0x31, 0xC0, 0x1C, 0xF2, 0xF7, + 0x5E, 0xDC, 0xE4, 0xE7, 0x07, 0x24, 0x38, 0x46, 0xFB, 0xF7, 0xDE, 0xFA, + 0x0A, 0x49, 0x00, 0x22, 0x90, 0x31, 0x0A, 0x48, 0xF2, 0xF7, 0x53, 0xDC, + 0x20, 0x46, 0x56, 0xE7, 0x06, 0x49, 0x08, 0x24, 0x00, 0x22, 0xBC, 0x31, + 0xF5, 0xE7, 0x00, 0x00, 0x7B, 0xB2, 0x82, 0x00, 0xA0, 0x78, 0x20, 0x00, + 0x60, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00, 0xC0, 0x64, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x46, 0x78, 0x20, 0x00, 0x44, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46, 0x88, 0x46, 0x07, 0x46, + 0x0A, 0x9C, 0x00, 0xF0, 0x7D, 0xF8, 0xC8, 0xB1, 0x0D, 0x48, 0x07, 0xEB, + 0x87, 0x02, 0x02, 0x21, 0x80, 0x68, 0x00, 0xEB, 0xC2, 0x00, 0x10, 0x22, + 0x41, 0x71, 0x21, 0x46, 0x80, 0x1D, 0x24, 0xF4, 0x38, 0xF5, 0x00, 0x20, + 0x03, 0x95, 0x8D, 0xE8, 0x51, 0x00, 0x43, 0x46, 0x05, 0x22, 0x03, 0x21, + 0x38, 0x46, 0x00, 0xF0, 0xBD, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, + 0x02, 0x20, 0xFA, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41, + 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0x57, 0xF8, 0x80, 0xB1, + 0x01, 0x20, 0x4F, 0xF6, 0xFF, 0x74, 0x00, 0x21, 0xCD, 0xE9, 0x00, 0x15, + 0xCD, 0xE9, 0x02, 0x04, 0x02, 0x46, 0x33, 0x46, 0x02, 0x21, 0x38, 0x46, + 0x00, 0xF0, 0xA0, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, + 0xFA, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x41, 0x1D, 0x46, 0x16, 0x46, + 0x88, 0x46, 0x07, 0x46, 0x0A, 0x9C, 0x00, 0xF0, 0x39, 0xF8, 0xB0, 0xB1, + 0x0C, 0x48, 0x07, 0xEB, 0x87, 0x02, 0x01, 0x21, 0x80, 0x68, 0x43, 0x46, + 0x00, 0xEB, 0xC2, 0x00, 0x05, 0x22, 0x41, 0x71, 0xC4, 0x82, 0x00, 0x20, + 0xCD, 0xE9, 0x00, 0x40, 0xCD, 0xE9, 0x02, 0x65, 0x03, 0x21, 0x38, 0x46, + 0x00, 0xF0, 0x7C, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, + 0xFA, 0xE7, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41, + 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0xF0, 0x15, 0xF8, 0x80, 0xB1, + 0x4F, 0xF6, 0xFF, 0x70, 0x01, 0x24, 0x03, 0x90, 0x00, 0x21, 0x00, 0x95, + 0xCD, 0xE9, 0x01, 0x14, 0x33, 0x46, 0x22, 0x46, 0x02, 0x21, 0x38, 0x46, + 0x00, 0xF0, 0x5E, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, + 0xFA, 0xE7, 0x00, 0x00, 0x38, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, + 0x11, 0x48, 0x0E, 0xF0, 0x05, 0xF8, 0x00, 0x28, 0x13, 0xD0, 0x10, 0x49, + 0x10, 0x48, 0x4A, 0x78, 0x95, 0x42, 0x05, 0xD3, 0x2B, 0x46, 0x01, 0x22, + 0x0E, 0x49, 0xF2, 0xF7, 0xA2, 0xDB, 0x10, 0xE0, 0x89, 0x68, 0x04, 0xEB, + 0x84, 0x02, 0x01, 0xEB, 0xC2, 0x01, 0x09, 0x79, 0x01, 0x29, 0x01, 0xD0, + 0x01, 0x20, 0x38, 0xBD, 0x07, 0x49, 0x23, 0x46, 0x02, 0x22, 0x2C, 0x31, + 0x00, 0x95, 0xF2, 0xF7, 0x90, 0xDB, 0x00, 0x20, 0x38, 0xBD, 0x00, 0x00, + 0x68, 0xB2, 0x82, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21, + 0x1C, 0x63, 0xC0, 0x08, 0x08, 0x49, 0x10, 0xB5, 0x4A, 0x78, 0x90, 0x42, + 0x03, 0xD2, 0xC9, 0x68, 0x01, 0xEB, 0xC0, 0x00, 0x10, 0xBD, 0x03, 0x46, + 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xF2, 0xF7, 0x76, 0xDB, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xE8, 0x62, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46, + 0x15, 0x46, 0x0A, 0x48, 0x0D, 0xF0, 0xBC, 0xFF, 0x00, 0x28, 0x0D, 0xD0, + 0x08, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x0A, 0x68, 0x02, 0xEB, 0x00, 0x12, + 0x52, 0x6A, 0x32, 0x60, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8C, + 0x28, 0x80, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x00, 0xED, 0xB2, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x29, 0x49, 0x10, 0xB5, 0x09, 0x78, 0x01, 0x24, + 0x29, 0xB3, 0x43, 0x88, 0x40, 0xF2, 0x1F, 0x12, 0xA3, 0xF2, 0x1F, 0x11, + 0x93, 0x42, 0x41, 0xD0, 0x12, 0xDC, 0x40, 0xF2, 0x17, 0x12, 0xA3, 0xF2, + 0x17, 0x11, 0x93, 0x42, 0x20, 0xD0, 0x06, 0xDC, 0xA3, 0xF5, 0x80, 0x73, + 0x13, 0x3B, 0x13, 0xD0, 0x01, 0x2B, 0x36, 0xD1, 0x14, 0xE0, 0x04, 0x29, + 0x21, 0xD0, 0x06, 0x29, 0x31, 0xD1, 0x29, 0xE0, 0x01, 0x29, 0x20, 0xD0, + 0x03, 0x29, 0x1E, 0xD0, 0x0F, 0x29, 0x01, 0xD0, 0x10, 0x29, 0x28, 0xD1, + 0x80, 0x88, 0x00, 0xF0, 0x2B, 0xF8, 0x24, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0x17, 0xFD, 0x20, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x95, 0xFA, 0x1C, 0xE0, + 0x81, 0x79, 0x00, 0xF1, 0x04, 0x00, 0x02, 0x29, 0x02, 0xD0, 0x00, 0xF0, + 0x49, 0xF8, 0x14, 0xE0, 0x00, 0xF0, 0xA2, 0xF9, 0x11, 0xE0, 0x00, 0x1D, + 0x00, 0xF0, 0x3A, 0xFA, 0x0D, 0xE0, 0x02, 0x46, 0x01, 0x1D, 0x18, 0x46, + 0x00, 0xF0, 0x12, 0xF9, 0x04, 0x46, 0x06, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0x6F, 0xF9, 0x02, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xD5, 0xF8, 0x20, 0x46, + 0x10, 0xBD, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0D, 0xF0, + 0xEB, 0xFF, 0x00, 0x28, 0x24, 0xD0, 0x13, 0x4E, 0xC5, 0x78, 0xB0, 0x68, + 0x05, 0xEB, 0x85, 0x04, 0x00, 0xEB, 0xC4, 0x00, 0x40, 0x6A, 0x30, 0xB1, + 0xFD, 0xF7, 0xDD, 0xD8, 0xB1, 0x68, 0x00, 0x20, 0x01, 0xEB, 0xC4, 0x01, + 0x48, 0x62, 0xB0, 0x68, 0x28, 0x21, 0x00, 0xEB, 0xC4, 0x00, 0x24, 0xF4, + 0x93, 0xF4, 0x00, 0x24, 0x09, 0xE0, 0xF0, 0x68, 0x00, 0xEB, 0xC4, 0x00, + 0x40, 0x68, 0x41, 0x69, 0x09, 0xB1, 0x28, 0x46, 0x88, 0x47, 0x64, 0x1C, + 0xE4, 0xB2, 0x70, 0x78, 0x84, 0x42, 0xF2, 0xD3, 0x70, 0xBD, 0x00, 0x00, + 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x04, 0x46, 0x00, 0x88, + 0x0D, 0xF0, 0xBA, 0xFF, 0x07, 0x00, 0x5D, 0xD0, 0x49, 0x49, 0x97, 0xF8, + 0x03, 0xB0, 0x89, 0x68, 0x0B, 0xEB, 0x8B, 0x00, 0x01, 0xEB, 0xC0, 0x05, + 0xA8, 0x78, 0xFF, 0xF7, 0x33, 0xFF, 0x80, 0x46, 0xA1, 0x88, 0x04, 0xF1, + 0x10, 0x00, 0x39, 0xB1, 0x21, 0x89, 0x00, 0x22, 0x00, 0x29, 0x69, 0xD0, + 0xA1, 0x89, 0x01, 0x29, 0x5E, 0xD0, 0x65, 0xE0, 0x21, 0x89, 0x00, 0x29, + 0x70, 0xD0, 0xE1, 0x89, 0x66, 0x89, 0x01, 0xEB, 0x00, 0x09, 0xA1, 0x89, + 0xE0, 0x88, 0x09, 0xEB, 0x41, 0x0A, 0x4F, 0xF4, 0x00, 0x71, 0xA8, 0xB1, + 0x28, 0x8C, 0x82, 0x19, 0x8A, 0x42, 0x35, 0xD8, 0x69, 0x6A, 0x32, 0x46, + 0x08, 0x44, 0x51, 0x46, 0x24, 0xF4, 0xA7, 0xF3, 0x28, 0x8C, 0x30, 0x44, + 0x80, 0xB2, 0x28, 0x84, 0x79, 0x8A, 0x49, 0x1E, 0xB1, 0x42, 0x14, 0xD0, + 0x06, 0x46, 0xD5, 0xF8, 0x24, 0xA0, 0x27, 0xE0, 0x78, 0x8A, 0x40, 0x1E, + 0xB0, 0x42, 0x23, 0xD1, 0x40, 0xF2, 0xF9, 0x53, 0x29, 0x4A, 0x00, 0x20, + 0xFD, 0xF7, 0x12, 0xD8, 0x68, 0x62, 0xD8, 0xB1, 0x32, 0x46, 0x51, 0x46, + 0x24, 0xF4, 0x8B, 0xF3, 0x2E, 0x84, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, + 0x02, 0x90, 0x23, 0x49, 0x0B, 0xEB, 0x4B, 0x00, 0xB9, 0xF8, 0x00, 0x30, + 0x09, 0x68, 0x2A, 0x8C, 0x01, 0xEB, 0x00, 0x10, 0x01, 0x21, 0x00, 0x8A, + 0xFB, 0xF7, 0x46, 0xFB, 0xBD, 0xE8, 0xFE, 0x8F, 0x40, 0xF6, 0x11, 0x40, + 0xA0, 0x80, 0x00, 0x26, 0x00, 0x20, 0x28, 0x71, 0xB8, 0xF1, 0x00, 0x0F, + 0x22, 0xD0, 0xD8, 0xF8, 0x04, 0x00, 0x87, 0x68, 0x3F, 0xB1, 0xCD, 0xF8, + 0x00, 0xA0, 0xB9, 0xF8, 0x00, 0x20, 0xA1, 0x88, 0x33, 0x46, 0x58, 0x46, + 0xB8, 0x47, 0x15, 0xE0, 0xE1, 0x89, 0x0A, 0x5C, 0x04, 0xF1, 0x11, 0x00, + 0x08, 0x5C, 0x02, 0xEB, 0x00, 0x20, 0x82, 0xB2, 0x00, 0x20, 0x28, 0x71, + 0xB8, 0xF1, 0x00, 0x0F, 0x08, 0xD0, 0xD8, 0xF8, 0x04, 0x10, 0x8E, 0x68, + 0x26, 0xB1, 0x00, 0x90, 0xA1, 0x88, 0x00, 0x23, 0x58, 0x46, 0xB0, 0x47, + 0x68, 0x6A, 0x00, 0x28, 0xCE, 0xD0, 0xFD, 0xF7, 0x26, 0xD8, 0x00, 0x20, + 0x68, 0x62, 0xC9, 0xE7, 0xA0, 0x78, 0x20, 0x00, 0xCA, 0xB2, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x05, 0x46, 0x00, 0x88, 0x0D, 0xF0, + 0x19, 0xFF, 0x00, 0x28, 0x27, 0xD0, 0x14, 0x49, 0xC6, 0x78, 0x89, 0x68, + 0x06, 0xEB, 0x86, 0x00, 0x01, 0xEB, 0xC0, 0x04, 0xE0, 0x78, 0xFF, 0xF7, + 0x93, 0xFE, 0x69, 0x88, 0x21, 0xB9, 0xE1, 0x8B, 0x11, 0xB9, 0x40, 0xF6, + 0x11, 0x41, 0x69, 0x80, 0x00, 0x27, 0x27, 0x71, 0x68, 0xB1, 0x40, 0x68, + 0xD0, 0xF8, 0x0C, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x07, 0xD0, 0x08, 0x48, + 0x01, 0x21, 0x00, 0x78, 0x00, 0x90, 0x6B, 0x88, 0xA2, 0x8B, 0x30, 0x46, + 0xE0, 0x47, 0x60, 0x6A, 0x00, 0x28, 0x02, 0xD0, 0xFC, 0xF7, 0xEF, 0xDF, + 0x67, 0x62, 0xF8, 0xBD, 0xA0, 0x78, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x5F, 0x14, 0x46, 0xB0, 0xF5, 0x91, 0x7F, 0x1B, 0xD0, + 0x00, 0x26, 0x88, 0x88, 0x01, 0x90, 0x48, 0x88, 0x02, 0x90, 0xCA, 0x88, + 0x01, 0xF1, 0x08, 0x00, 0x02, 0xEB, 0x00, 0x08, 0x08, 0x88, 0x00, 0x27, + 0x4F, 0xF0, 0x01, 0x09, 0x03, 0x90, 0x0D, 0xF0, 0xD3, 0xFE, 0x88, 0xB3, + 0x90, 0xF8, 0x03, 0xB0, 0xA8, 0xEB, 0x04, 0x01, 0x44, 0x62, 0x41, 0x84, + 0x00, 0x24, 0xDF, 0xF8, 0x78, 0xA0, 0x21, 0xE0, 0x01, 0x26, 0xE2, 0xE7, + 0xDA, 0xF8, 0x0C, 0x00, 0x00, 0xEB, 0xC4, 0x00, 0x40, 0x68, 0x05, 0x69, + 0xB5, 0xB1, 0xCD, 0xF8, 0x00, 0x80, 0xDD, 0xE9, 0x01, 0x32, 0x31, 0x46, + 0x58, 0x46, 0xA8, 0x47, 0x05, 0x46, 0xA0, 0xF5, 0x50, 0x60, 0x01, 0x38, + 0x05, 0xD1, 0x00, 0x22, 0x12, 0x49, 0x13, 0x48, 0xF2, 0xF7, 0xB9, 0xD9, + 0x01, 0x27, 0x1E, 0xB1, 0xA5, 0xF5, 0x50, 0x60, 0x05, 0x38, 0x08, 0xD0, + 0x64, 0x1C, 0xE4, 0xB2, 0x9A, 0xF8, 0x01, 0x10, 0x8C, 0x42, 0xDB, 0xD3, + 0x3E, 0x43, 0x09, 0xD0, 0x0B, 0xE0, 0x09, 0x49, 0x00, 0x22, 0x2C, 0x31, + 0x08, 0x48, 0xF2, 0xF7, 0xA4, 0xD9, 0x4F, 0xF0, 0x00, 0x09, 0xF3, 0xE7, + 0x03, 0x98, 0xFB, 0xF7, 0x47, 0xF9, 0x04, 0xB0, 0x48, 0x46, 0xBD, 0xE8, + 0xF0, 0x9F, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0x6C, 0x69, 0xC0, 0x08, + 0x03, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x00, 0x88, 0x0D, 0xF0, + 0x83, 0xFE, 0x00, 0x28, 0x0E, 0xD0, 0xC4, 0x78, 0x68, 0x88, 0x0C, 0x4E, + 0x58, 0xB1, 0x28, 0x88, 0x00, 0x21, 0xFB, 0xF7, 0x4D, 0xF9, 0xB2, 0x68, + 0x04, 0xEB, 0x84, 0x01, 0x02, 0xEB, 0xC1, 0x01, 0x00, 0x20, 0xC8, 0x83, + 0x70, 0xBD, 0xB1, 0x68, 0x04, 0xEB, 0x84, 0x00, 0x01, 0xEB, 0xC0, 0x00, + 0xC1, 0x78, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0x7E, 0xBB, + 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x5F, 0x04, 0x46, 0x00, 0x88, + 0x0D, 0xF0, 0x5E, 0xFE, 0x5F, 0xEA, 0x00, 0x0B, 0x23, 0xD0, 0x9B, 0xF8, + 0x03, 0x00, 0x45, 0x4E, 0x00, 0xEB, 0x80, 0x05, 0xCD, 0xE9, 0x02, 0x50, + 0xB0, 0x68, 0x00, 0xEB, 0xC5, 0x00, 0x80, 0x78, 0xFF, 0xF7, 0xD4, 0xFD, + 0x80, 0x46, 0xB0, 0x68, 0xA1, 0x88, 0x00, 0xEB, 0xC5, 0x0A, 0x91, 0xB1, + 0x00, 0x21, 0x8A, 0xF8, 0x04, 0x10, 0xB8, 0xF1, 0x00, 0x0F, 0x0A, 0xD0, + 0xD8, 0xF8, 0x04, 0x00, 0x85, 0x68, 0x00, 0x2D, 0x05, 0xD0, 0x00, 0x91, + 0x00, 0x23, 0xA1, 0x88, 0x1A, 0x46, 0x03, 0x98, 0xA8, 0x47, 0xBD, 0xE8, + 0xFF, 0x9F, 0x21, 0x89, 0x00, 0x29, 0xFA, 0xD0, 0x65, 0x89, 0xA0, 0x89, + 0xAA, 0x1C, 0x42, 0x43, 0x51, 0x1A, 0x89, 0xB2, 0x01, 0x91, 0xE2, 0x89, + 0x04, 0xF1, 0x10, 0x01, 0x57, 0x18, 0x07, 0xEB, 0x40, 0x09, 0x00, 0x26, + 0x4F, 0xE0, 0x01, 0x99, 0x29, 0xB1, 0x41, 0x1E, 0xB1, 0x42, 0x02, 0xD1, + 0x01, 0x99, 0x69, 0x1A, 0x8D, 0xB2, 0x01, 0x28, 0x29, 0xD1, 0xBB, 0xF8, + 0x12, 0x00, 0x00, 0x1F, 0xA8, 0x42, 0x24, 0xD1, 0x40, 0xF2, 0x99, 0x53, + 0x22, 0x4A, 0x4F, 0xF4, 0x00, 0x71, 0x00, 0x20, 0xFC, 0xF7, 0xAC, 0xDE, + 0xCA, 0xF8, 0x24, 0x00, 0xC8, 0xB1, 0x2A, 0x46, 0x49, 0x46, 0xDA, 0xF8, + 0x24, 0x00, 0x24, 0xF4, 0x22, 0xF2, 0xAA, 0xF8, 0x20, 0x50, 0x00, 0x20, + 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x19, 0x49, 0x03, 0x98, 0x3B, 0x88, + 0x09, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x2A, 0x46, + 0x00, 0x8A, 0x01, 0x21, 0xFB, 0xF7, 0xDC, 0xF9, 0xB7, 0xE7, 0x10, 0x4A, + 0x02, 0x99, 0x00, 0x20, 0x92, 0x68, 0xB8, 0xF1, 0x00, 0x0F, 0x02, 0xEB, + 0xC1, 0x01, 0x08, 0x71, 0x0D, 0xD0, 0xD8, 0xF8, 0x04, 0x00, 0xD0, 0xF8, + 0x08, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x06, 0xD0, 0xCD, 0xF8, 0x00, 0x90, + 0x3A, 0x88, 0xA1, 0x88, 0x2B, 0x46, 0x03, 0x98, 0xE0, 0x47, 0x76, 0x1C, + 0xA9, 0x44, 0xF6, 0xB2, 0xBF, 0x1C, 0xA0, 0x89, 0xB0, 0x42, 0xAC, 0xD8, + 0x97, 0xE7, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, 0xA5, 0xB2, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0x00, 0x88, + 0x0D, 0xF0, 0xC2, 0xFD, 0x1E, 0x4E, 0x30, 0xB3, 0xDF, 0xF8, 0x78, 0x90, + 0xC7, 0x78, 0xD9, 0xF8, 0x08, 0x10, 0x07, 0xEB, 0x87, 0x08, 0x01, 0xEB, + 0xC8, 0x00, 0xC0, 0x78, 0xFF, 0xF7, 0x3A, 0xFD, 0x05, 0x46, 0xA0, 0x78, + 0x02, 0x28, 0x1F, 0xD0, 0x04, 0x28, 0x1D, 0xD0, 0xD9, 0xF8, 0x08, 0x10, + 0x00, 0x22, 0x01, 0xEB, 0xC8, 0x00, 0x02, 0x71, 0x00, 0x2D, 0x0A, 0xD0, + 0x68, 0x68, 0xC5, 0x68, 0x00, 0x2D, 0x06, 0xD0, 0x30, 0x78, 0x00, 0x90, + 0xE3, 0x88, 0xA2, 0x88, 0xA1, 0x78, 0x38, 0x46, 0xA8, 0x47, 0xBD, 0xE8, + 0xF8, 0x83, 0xA0, 0x78, 0x02, 0x28, 0x01, 0xD0, 0x04, 0x28, 0xF8, 0xD1, + 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0xF4, 0xE7, 0x30, 0x78, 0x3B, 0x46, + 0x40, 0x1C, 0xC0, 0xB2, 0x30, 0x70, 0x00, 0x90, 0x02, 0x22, 0x04, 0x49, + 0x04, 0x48, 0xF2, 0xF7, 0x90, 0xD8, 0xDB, 0xE7, 0x60, 0x78, 0x20, 0x00, + 0xA0, 0x78, 0x20, 0x00, 0x28, 0x69, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x4F, 0x8D, 0xB0, 0x4F, 0xF0, 0x00, 0x0A, 0x04, 0x46, + 0xCD, 0xF8, 0x2C, 0xA0, 0x00, 0x88, 0x0D, 0xF0, 0x71, 0xFD, 0x00, 0x28, + 0x78, 0xD0, 0xC0, 0x78, 0xDF, 0xF8, 0x40, 0xB4, 0x00, 0xEB, 0x80, 0x01, + 0x0A, 0x90, 0xDB, 0xF8, 0x08, 0x00, 0x00, 0xEB, 0xC1, 0x06, 0x70, 0x78, + 0xFF, 0xF7, 0xE8, 0xFC, 0x05, 0x46, 0xA0, 0x88, 0x00, 0x28, 0x68, 0xD1, + 0xA1, 0x78, 0x00, 0x27, 0x04, 0xF1, 0x0C, 0x00, 0x06, 0x29, 0x3D, 0xD2, + 0xDF, 0xE8, 0x01, 0xF0, 0x3C, 0x03, 0x7A, 0xFD, 0xFC, 0x9E, 0x21, 0x89, + 0x06, 0x29, 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, + 0x2C, 0xD0, 0x68, 0xE0, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00, + 0xCD, 0xE9, 0x00, 0x01, 0xB8, 0xF8, 0x00, 0x30, 0x03, 0x22, 0xFB, 0x49, + 0xFB, 0x48, 0xF2, 0xF7, 0x48, 0xD8, 0xB8, 0xF8, 0x02, 0x70, 0x3D, 0xB1, + 0x68, 0x68, 0x43, 0x68, 0x23, 0xB1, 0x00, 0x21, 0x42, 0x46, 0x0A, 0x98, + 0x98, 0x47, 0x0E, 0xE0, 0xDB, 0xF8, 0x04, 0x30, 0x5B, 0xB1, 0x01, 0x20, + 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x6A, 0x46, + 0xCD, 0xF8, 0x08, 0x80, 0xFF, 0x20, 0x0A, 0x99, 0x98, 0x47, 0x09, 0xF1, + 0x01, 0x00, 0x08, 0xF1, 0x06, 0x08, 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46, + 0x49, 0x45, 0xCF, 0xD8, 0x97, 0xE1, 0x10, 0x22, 0x08, 0xF1, 0x04, 0x01, + 0x06, 0xA8, 0x24, 0xF4, 0x32, 0xF1, 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00, + 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0x32, 0xB8, 0xF8, 0x02, 0x00, + 0x00, 0x90, 0xDF, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x06, 0x22, 0x38, 0x31, + 0xDD, 0x48, 0xF2, 0xF7, 0x0C, 0xD8, 0xB8, 0xF8, 0x02, 0x70, 0x4D, 0xB1, + 0x68, 0x68, 0x43, 0x68, 0x33, 0xB1, 0x01, 0x21, 0x42, 0x46, 0x0A, 0x98, + 0x98, 0x47, 0x0F, 0xE0, 0xEF, 0xE1, 0x82, 0xE1, 0xDB, 0xF8, 0x04, 0x30, + 0x53, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x04, 0x00, + 0x6A, 0x46, 0xCD, 0xF8, 0x08, 0x80, 0xFF, 0x20, 0x0A, 0x99, 0x98, 0x47, + 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x14, 0x08, 0xC0, 0xB2, 0xE1, 0x88, + 0x81, 0x46, 0x49, 0x45, 0xC3, 0xD8, 0x5A, 0xE1, 0x61, 0x89, 0x01, 0xEB, + 0x00, 0x08, 0x00, 0x20, 0x19, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0x00, 0x90, + 0xC4, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x02, 0x22, 0x7C, 0x31, 0xC3, 0x48, + 0xF1, 0xF7, 0xD7, 0xDF, 0xB8, 0xF8, 0x02, 0x70, 0x35, 0xB1, 0x68, 0x68, + 0x43, 0x68, 0x1B, 0xB1, 0x02, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, + 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x04, 0x08, 0xC0, 0xB2, 0xE1, 0x88, + 0x81, 0x46, 0x49, 0x45, 0xE1, 0xD8, 0x36, 0xE1, 0x21, 0x89, 0x08, 0x29, + 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x1F, 0xD0, + 0x63, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0xB8, 0xF8, 0x06, 0x20, 0xB8, 0xF8, + 0x04, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0xAE, 0x49, 0xB8, 0xF8, 0x00, 0x30, + 0x04, 0x22, 0xA0, 0x31, 0xAC, 0x48, 0xF1, 0xF7, 0xAA, 0xDF, 0xB8, 0xF8, + 0x00, 0x70, 0x35, 0xB1, 0x68, 0x68, 0x43, 0x68, 0x1B, 0xB1, 0x07, 0x21, + 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, + 0x08, 0x08, 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xDC, 0xD8, + 0x09, 0xE1, 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01, 0x06, 0xA8, 0x24, 0xF4, + 0xA4, 0xF0, 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x32, + 0xCD, 0xE9, 0x04, 0x10, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00, + 0xCD, 0xE9, 0x00, 0x01, 0x96, 0x49, 0x97, 0x4F, 0xB8, 0xF8, 0x00, 0x30, + 0x07, 0x22, 0xE8, 0x31, 0x38, 0x46, 0xF1, 0xF7, 0x7A, 0xDF, 0x00, 0x20, + 0x08, 0xEB, 0x00, 0x01, 0x89, 0x79, 0x19, 0xB9, 0x40, 0x1C, 0xC0, 0xB2, + 0x10, 0x28, 0xF7, 0xD3, 0x10, 0x28, 0x06, 0xD1, 0xB8, 0xF8, 0x02, 0x30, + 0x01, 0x22, 0x8D, 0x49, 0x38, 0x46, 0xF1, 0xF7, 0x68, 0xDF, 0xB8, 0xF8, + 0x00, 0x70, 0x01, 0xE0, 0x88, 0xE0, 0x11, 0xE0, 0x35, 0xB1, 0x68, 0x68, + 0x43, 0x68, 0x1B, 0xB1, 0x08, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, + 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x16, 0x08, 0xC0, 0xB2, 0xE1, 0x88, + 0x81, 0x46, 0x49, 0x45, 0xBB, 0xD8, 0xC4, 0xE0, 0x21, 0x89, 0x08, 0x29, + 0x61, 0x89, 0x01, 0xEB, 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x28, 0xD0, + 0x65, 0xE0, 0xB8, 0xF8, 0x02, 0x00, 0xB8, 0xF8, 0x06, 0x20, 0xB8, 0xF8, + 0x04, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0x77, 0x49, 0xB8, 0xF8, 0x00, 0x30, + 0x04, 0x22, 0x38, 0x31, 0x73, 0x48, 0xF1, 0xF7, 0x38, 0xDF, 0xB8, 0xF8, + 0x04, 0x70, 0x70, 0x79, 0xC0, 0xB1, 0x01, 0x28, 0x0C, 0xD1, 0xF1, 0x8A, + 0xB8, 0xF8, 0x06, 0x00, 0x81, 0x42, 0x07, 0xD1, 0x09, 0x21, 0x2D, 0xB1, + 0x68, 0x68, 0x43, 0x68, 0x13, 0xB1, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, + 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x08, 0x08, 0xC0, 0xB2, 0xE1, 0x88, + 0x81, 0x46, 0x49, 0x45, 0xD3, 0xD8, 0x8E, 0xE0, 0x03, 0x21, 0xEC, 0xE7, + 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01, 0x06, 0xA8, 0x24, 0xF4, 0x27, 0xF0, + 0x06, 0xAF, 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x32, 0xCD, 0xE9, + 0x04, 0x10, 0xB8, 0xF8, 0x04, 0x10, 0xB8, 0xF8, 0x02, 0x00, 0xCD, 0xE9, + 0x00, 0x01, 0x5A, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x07, 0x22, 0x94, 0x31, + 0x56, 0x48, 0xF1, 0xF7, 0xFE, 0xDE, 0xB8, 0xF8, 0x04, 0x70, 0x70, 0x79, + 0xE0, 0xB1, 0x02, 0x28, 0x10, 0xD1, 0x10, 0x22, 0x08, 0xF1, 0x06, 0x01, + 0xB0, 0x1D, 0x23, 0xF4, 0xBB, 0xF7, 0x48, 0xB9, 0x70, 0x79, 0x88, 0xB1, + 0x0A, 0x21, 0x2D, 0xB1, 0x68, 0x68, 0x43, 0x68, 0x13, 0xB1, 0x42, 0x46, + 0x0A, 0x98, 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x16, 0x08, + 0xC0, 0xB2, 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xC4, 0xD8, 0x50, 0xE0, + 0x04, 0x21, 0xEC, 0xE7, 0x21, 0x89, 0x04, 0x29, 0x61, 0x89, 0x01, 0xEB, + 0x00, 0x08, 0x4F, 0xF0, 0x00, 0x00, 0x19, 0xD0, 0x41, 0xE0, 0xB8, 0xF8, + 0x02, 0x00, 0x00, 0x90, 0xB8, 0xF8, 0x00, 0x30, 0x02, 0x22, 0x3E, 0x49, + 0x3B, 0x48, 0xF1, 0xF7, 0xC8, 0xDE, 0xB8, 0xF8, 0x00, 0x70, 0x35, 0xB1, + 0x68, 0x68, 0x43, 0x68, 0x1B, 0xB1, 0x05, 0x21, 0x42, 0x46, 0x0A, 0x98, + 0x98, 0x47, 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x04, 0x08, 0xC0, 0xB2, + 0xE1, 0x88, 0x81, 0x46, 0x49, 0x45, 0xE2, 0xD8, 0x27, 0xE0, 0x10, 0x22, + 0x08, 0xF1, 0x02, 0x01, 0x06, 0xA8, 0x23, 0xF4, 0xC2, 0xF7, 0x06, 0xAF, + 0x97, 0xE8, 0x0F, 0x00, 0xCD, 0xE9, 0x02, 0x10, 0xCD, 0xE9, 0x00, 0x32, + 0x2B, 0x49, 0xB8, 0xF8, 0x00, 0x30, 0x05, 0x22, 0x30, 0x31, 0x27, 0x48, + 0xF1, 0xF7, 0x9F, 0xDE, 0xB8, 0xF8, 0x00, 0x70, 0x35, 0xB1, 0x68, 0x68, + 0x43, 0x68, 0x1B, 0xB1, 0x06, 0x21, 0x42, 0x46, 0x0A, 0x98, 0x98, 0x47, + 0x09, 0xF1, 0x01, 0x00, 0x08, 0xF1, 0x12, 0x08, 0xC0, 0xB2, 0xE1, 0x88, + 0x81, 0x46, 0x49, 0x45, 0xD7, 0xD8, 0x78, 0x1C, 0x30, 0x83, 0x1F, 0xB1, + 0x70, 0x8B, 0xB8, 0x42, 0x09, 0xD9, 0x0D, 0xE0, 0x01, 0x20, 0x0B, 0x90, + 0x19, 0x49, 0x17, 0x48, 0x00, 0x22, 0x70, 0x31, 0x80, 0x1E, 0xF1, 0xF7, + 0x7C, 0xDE, 0x00, 0x20, 0x30, 0x83, 0x70, 0x83, 0x4F, 0xF0, 0x01, 0x0A, + 0x73, 0x8B, 0x32, 0x8B, 0xA1, 0x78, 0x20, 0x88, 0xFB, 0xF7, 0x94, 0xFA, + 0xBA, 0xF1, 0x00, 0x0F, 0x5D, 0xD0, 0x33, 0x78, 0x01, 0x2B, 0x1D, 0xD0, + 0x03, 0x2B, 0x1D, 0xD0, 0x05, 0x2B, 0x1D, 0xD0, 0x09, 0x2B, 0x27, 0xD0, + 0x0A, 0x49, 0x08, 0x48, 0x01, 0x22, 0xAC, 0x31, 0x80, 0x1E, 0xF1, 0xF7, + 0x5E, 0xDE, 0xA0, 0x88, 0xA0, 0xF5, 0x80, 0x61, 0x0A, 0x39, 0x1D, 0xD0, + 0xF0, 0xB9, 0x1B, 0xE0, 0xA0, 0x78, 0x20, 0x00, 0xA8, 0x65, 0xC0, 0x08, + 0x02, 0x33, 0x10, 0x21, 0xE8, 0x66, 0xC0, 0x08, 0xE8, 0x67, 0xC0, 0x08, + 0x02, 0x20, 0x07, 0xE0, 0x04, 0x20, 0x05, 0xE0, 0x70, 0x79, 0x01, 0x28, + 0x04, 0xD0, 0x02, 0x28, 0x04, 0xD0, 0x06, 0x20, 0x30, 0x70, 0xE2, 0xE7, + 0x07, 0x20, 0xFB, 0xE7, 0x08, 0x20, 0xF9, 0xE7, 0x0A, 0x20, 0xF7, 0xE7, + 0x0B, 0x98, 0x38, 0xB1, 0x0B, 0x20, 0x30, 0x70, 0xA3, 0x88, 0x01, 0x22, + 0x13, 0x49, 0x14, 0x48, 0xF1, 0xF7, 0x31, 0xDE, 0x11, 0x49, 0x12, 0x48, + 0x33, 0x78, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1C, 0xF1, 0xF7, 0x29, 0xDE, + 0x00, 0x20, 0x30, 0x71, 0x45, 0xB1, 0x69, 0x68, 0x0A, 0x68, 0x2A, 0xB1, + 0x31, 0x78, 0x0A, 0x98, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, 0x10, 0x47, + 0xDB, 0xF8, 0x04, 0x30, 0x00, 0x2B, 0x08, 0xD0, 0x8D, 0xF8, 0x00, 0x00, + 0x30, 0x78, 0x8D, 0xF8, 0x04, 0x00, 0x6A, 0x46, 0xFF, 0x20, 0x0A, 0x99, + 0x98, 0x47, 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xC8, 0x68, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0xFE, 0xB5, 0x81, 0x88, 0x00, 0x29, 0x2D, 0xD0, + 0x00, 0x88, 0x0D, 0xF0, 0xF7, 0xFA, 0x00, 0x28, 0x28, 0xD0, 0x15, 0x4D, + 0xC6, 0x78, 0x00, 0x27, 0xA8, 0x68, 0x06, 0xEB, 0x86, 0x04, 0x00, 0xEB, + 0xC4, 0x01, 0x0B, 0x22, 0x0F, 0x71, 0x00, 0xF8, 0x34, 0x20, 0x48, 0x78, + 0xFF, 0xF7, 0x6C, 0xFA, 0x50, 0xB1, 0x40, 0x68, 0x02, 0x68, 0x3A, 0xB1, + 0xA8, 0x68, 0x10, 0xF8, 0x34, 0x10, 0x03, 0xB0, 0x30, 0x46, 0xBD, 0xE8, + 0xF0, 0x40, 0x10, 0x47, 0x6B, 0x68, 0x00, 0x2B, 0x0A, 0xD0, 0x8D, 0xF8, + 0x00, 0x70, 0xA8, 0x68, 0x6A, 0x46, 0x31, 0x46, 0x10, 0xF8, 0x34, 0x00, + 0x8D, 0xF8, 0x04, 0x00, 0xFF, 0x20, 0x98, 0x47, 0xFE, 0xBD, 0x00, 0x00, + 0xA0, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x10, 0x48, 0x00, 0x78, + 0x00, 0xEB, 0x80, 0x00, 0xC5, 0x00, 0xFA, 0xF7, 0x8D, 0xFC, 0x90, 0xB1, + 0x4E, 0x23, 0x0D, 0x4A, 0x29, 0x46, 0x00, 0x20, 0xFC, 0xF7, 0x58, 0xDB, + 0x0B, 0x4D, 0x00, 0x28, 0xA8, 0x60, 0x07, 0xD0, 0xE1, 0x00, 0x2C, 0x70, + 0x55, 0x23, 0x07, 0x4A, 0x00, 0x20, 0xFC, 0xF7, 0x4D, 0xDB, 0xE8, 0x60, + 0x70, 0xBD, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xF1, 0xF7, 0xAF, 0x9D, 0x61, 0x78, 0x20, 0x00, 0x5C, 0xB2, 0x82, 0x00, + 0xA0, 0x78, 0x20, 0x00, 0x68, 0x62, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x01, 0x49, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 0xA0, 0x78, 0x20, 0x00, + 0x38, 0xB5, 0x10, 0x4A, 0x53, 0x78, 0x03, 0x70, 0x53, 0x78, 0x14, 0x78, + 0xA3, 0x42, 0x07, 0xD3, 0x02, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0x00, 0x94, + 0xF1, 0xF7, 0x91, 0xDD, 0x00, 0x20, 0x38, 0xBD, 0xD4, 0x68, 0x01, 0x25, + 0x04, 0xF8, 0x33, 0x50, 0x53, 0x78, 0x00, 0x78, 0x04, 0xEB, 0xC3, 0x03, + 0x58, 0x70, 0x50, 0x78, 0x04, 0xEB, 0xC0, 0x00, 0x41, 0x60, 0x50, 0x78, + 0x40, 0x1C, 0x50, 0x70, 0x28, 0x46, 0x38, 0xBD, 0xA0, 0x78, 0x20, 0x00, + 0x90, 0x62, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41, + 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0xFF, 0xF7, 0xBA, 0xF9, + 0x68, 0xB1, 0x00, 0x20, 0x03, 0x94, 0x00, 0x90, 0xCD, 0xE9, 0x01, 0x05, + 0x33, 0x46, 0x03, 0x22, 0x05, 0x21, 0x38, 0x46, 0x00, 0xF0, 0x06, 0xF8, + 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x02, 0x20, 0xFA, 0xE7, 0x00, 0x00, + 0x2D, 0xE9, 0xFC, 0x5F, 0x99, 0x46, 0xDD, 0xE9, 0x0E, 0x58, 0xDD, 0xE9, + 0x0C, 0xAB, 0x16, 0x46, 0x0C, 0x46, 0x07, 0x46, 0x0B, 0x46, 0x01, 0x22, + 0x17, 0x49, 0x18, 0x48, 0xF1, 0xF7, 0x4D, 0xDD, 0x17, 0x49, 0xCD, 0xE9, + 0x00, 0xAB, 0x07, 0xEB, 0x47, 0x00, 0x09, 0x68, 0x43, 0x46, 0x01, 0xEB, + 0x00, 0x10, 0x2A, 0x46, 0x00, 0x8A, 0x21, 0x46, 0xFB, 0xF7, 0xAC, 0xF9, + 0x80, 0xB1, 0x11, 0x49, 0x07, 0xEB, 0x87, 0x00, 0x00, 0x24, 0x89, 0x68, + 0x01, 0xF8, 0x30, 0x60, 0x01, 0xEB, 0xC0, 0x01, 0x01, 0x20, 0x0D, 0x83, + 0xA1, 0xF8, 0x1A, 0x80, 0x81, 0xF8, 0x01, 0x90, 0x08, 0x71, 0x07, 0xE0, + 0x05, 0x49, 0x06, 0x48, 0x07, 0x24, 0x00, 0x22, 0x34, 0x31, 0xC0, 0x1E, + 0xF1, 0xF7, 0x25, 0xDD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x9F, 0x00, 0x00, + 0x84, 0x63, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21, 0x64, 0x78, 0x20, 0x00, + 0xA0, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x07, 0x46, 0x13, 0x48, + 0x0C, 0x46, 0x1D, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x16, 0x46, 0x49, 0x06, + 0x02, 0xD4, 0x02, 0x20, 0xBD, 0xE8, 0xFC, 0x81, 0x90, 0xF8, 0xCB, 0x01, + 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF6, 0xE7, 0xCD, 0xE9, + 0x00, 0x65, 0x23, 0x46, 0x03, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, + 0xFC, 0xDC, 0x00, 0x94, 0x08, 0x4C, 0x33, 0x46, 0x20, 0x8A, 0xA1, 0x89, + 0xE2, 0x89, 0x08, 0x44, 0x28, 0x44, 0x81, 0xB2, 0x38, 0x46, 0x07, 0xF0, + 0xBE, 0xFB, 0xE1, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x10, 0x7D, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46, + 0x00, 0x20, 0x01, 0x90, 0x10, 0x48, 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, + 0x01, 0xD4, 0x02, 0x20, 0x1C, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, + 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x1C, 0xBD, 0x23, 0x46, 0x01, 0x22, + 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0xCF, 0xDC, 0x09, 0x48, 0x00, 0x94, + 0x04, 0x23, 0x01, 0x8A, 0x02, 0x89, 0x11, 0x44, 0x14, 0x31, 0xC2, 0x89, + 0x89, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x91, 0xFB, 0x1C, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xE0, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x01, 0x90, + 0x10, 0x48, 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20, + 0x1C, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, + 0x01, 0x20, 0x1C, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, + 0xF1, 0xF7, 0xA1, 0xDC, 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, + 0x42, 0x89, 0x11, 0x44, 0x14, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x01, 0xA8, + 0x07, 0xF0, 0x63, 0xFB, 0x1C, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xA4, 0x7C, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0x1C, 0xB5, 0x04, 0x46, 0x00, 0x20, 0x01, 0x90, 0x10, 0x48, 0x90, 0xF8, + 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4, 0x02, 0x20, 0x1C, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x1C, 0xBD, + 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x73, 0xDC, + 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, 0xC2, 0x88, 0x11, 0x44, + 0x14, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x35, 0xFB, + 0x1C, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x74, 0x7B, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x30, 0xB5, 0x24, 0x4C, + 0x24, 0x4A, 0x87, 0xB0, 0x14, 0x20, 0x20, 0x80, 0xB2, 0xF8, 0xC2, 0x11, + 0x1C, 0x20, 0x8B, 0x07, 0x01, 0xD5, 0x60, 0x80, 0x3C, 0x20, 0x4B, 0x07, + 0x01, 0xD5, 0xA0, 0x80, 0x20, 0x30, 0x0B, 0x07, 0x01, 0xD5, 0xE0, 0x80, + 0x18, 0x30, 0xCB, 0x06, 0x01, 0xD5, 0x20, 0x81, 0x18, 0x30, 0x8B, 0x06, + 0x01, 0xD5, 0x60, 0x81, 0x18, 0x30, 0x49, 0x06, 0x06, 0xD5, 0x92, 0xF8, + 0xC1, 0x11, 0x04, 0x23, 0x03, 0xEB, 0x81, 0x01, 0xA0, 0x81, 0x08, 0x44, + 0x14, 0x38, 0x83, 0xB2, 0xE3, 0x81, 0x50, 0x20, 0x20, 0x82, 0x92, 0xF8, + 0xCB, 0x11, 0x11, 0x4D, 0xCD, 0xE9, 0x00, 0x01, 0x03, 0x22, 0x0E, 0x49, + 0x28, 0x46, 0xF1, 0xF7, 0x28, 0xDC, 0xE0, 0x88, 0x0D, 0xF1, 0x08, 0x0C, + 0xA3, 0x89, 0x62, 0x89, 0x21, 0x89, 0x8C, 0xE8, 0x0F, 0x00, 0xA1, 0x88, + 0x60, 0x88, 0xCD, 0xE9, 0x00, 0x01, 0x06, 0x49, 0x23, 0x88, 0x07, 0x22, + 0x60, 0x31, 0x28, 0x46, 0xF1, 0xF7, 0x15, 0xDC, 0x07, 0xB0, 0x30, 0xBD, + 0xE0, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xB8, 0x7D, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x0C, 0x46, 0x03, 0x46, 0x01, 0x22, + 0x06, 0x49, 0x07, 0x48, 0xF1, 0xF7, 0x03, 0xDC, 0x00, 0x20, 0x02, 0x46, + 0x00, 0x90, 0x05, 0x48, 0x14, 0x23, 0x01, 0x8A, 0x20, 0x46, 0x07, 0xF0, + 0xB5, 0xFA, 0x38, 0xBD, 0x34, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x05, 0x46, 0x18, 0x48, 0x0C, 0x46, + 0x04, 0x22, 0x90, 0xF8, 0xC1, 0x11, 0x02, 0xEB, 0x81, 0x01, 0xCE, 0xB2, + 0x90, 0xF8, 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, + 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, + 0xF8, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xF1, 0xF7, + 0xD6, 0xDB, 0x20, 0x46, 0x00, 0xF0, 0x5A, 0xF9, 0x00, 0x1D, 0xC3, 0xB2, + 0x04, 0x2B, 0x01, 0xD0, 0xB3, 0x42, 0x02, 0xD9, 0x00, 0x20, 0x28, 0x70, + 0xE4, 0xE7, 0x08, 0x48, 0x00, 0x94, 0x01, 0x8A, 0x82, 0x89, 0x11, 0x44, + 0xC2, 0x89, 0x89, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x7B, 0xFA, 0xF8, 0xBD, + 0x64, 0x01, 0x20, 0x00, 0x40, 0x7D, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46, + 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD, + 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, + 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, + 0xA0, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x11, 0x89, + 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x50, 0xFA, + 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x5C, 0x7C, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, + 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x07, 0x01, 0xD4, + 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, + 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF1, 0xF7, 0x74, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x20, 0x23, + 0x10, 0x8A, 0x51, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, + 0x07, 0xF0, 0x24, 0xFA, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xE8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0x38, 0xB5, 0x05, 0x46, 0x0D, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xCB, 0x01, + 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x0B, 0x46, + 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0x4E, 0xDB, 0x09, 0x4A, + 0x00, 0x94, 0x08, 0x23, 0x10, 0x8A, 0x11, 0x88, 0xD2, 0x89, 0x08, 0x44, + 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0xFE, 0xF9, 0x38, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xA8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46, + 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD, + 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, + 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, + 0x22, 0xDB, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x51, 0x89, + 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0xD2, 0xF9, + 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0xC8, 0x7C, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, + 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4, + 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, + 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF1, 0xF7, 0xF6, 0xDA, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, + 0x10, 0x8A, 0xD1, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, + 0x07, 0xF0, 0xA6, 0xF9, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x98, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, + 0x49, 0x07, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, + 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, + 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0xCA, 0xDA, 0x09, 0x4A, + 0x00, 0x94, 0x20, 0x23, 0x10, 0x8A, 0x91, 0x88, 0xD2, 0x89, 0x08, 0x44, + 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x7A, 0xF9, 0x38, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x2C, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, + 0x06, 0x48, 0xF1, 0xF7, 0xAE, 0xDA, 0x00, 0x21, 0x0A, 0x46, 0x00, 0x91, + 0x04, 0x23, 0x28, 0x21, 0x20, 0x46, 0x07, 0xF0, 0x61, 0xF9, 0x38, 0xBD, + 0xC4, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, + 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, 0x9A, 0xDA, 0x00, 0x21, + 0x0A, 0x46, 0x00, 0x91, 0x10, 0x23, 0x2C, 0x21, 0x20, 0x46, 0x07, 0xF0, + 0x4D, 0xF9, 0x38, 0xBD, 0xF8, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, + 0x86, 0xDA, 0x00, 0x21, 0x28, 0x23, 0x0A, 0x46, 0x20, 0x46, 0x00, 0x91, + 0x07, 0xF0, 0x3A, 0xF9, 0x38, 0xBD, 0x00, 0x00, 0x90, 0x79, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x17, 0x48, 0x90, 0xF8, + 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x7C, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0x7C, 0xBD, + 0x11, 0x4A, 0x00, 0x94, 0x04, 0x23, 0x10, 0x8A, 0x91, 0x89, 0xD2, 0x89, + 0x08, 0x44, 0x81, 0xB2, 0x01, 0xA8, 0x07, 0xF0, 0x19, 0xF9, 0x0D, 0x4D, + 0x38, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x0C, 0x49, 0x28, 0x46, 0xF1, 0xF7, + 0x56, 0xDA, 0x00, 0x20, 0x7C, 0xBD, 0x9D, 0xF8, 0x04, 0x00, 0x08, 0x49, + 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x2C, 0x39, 0x28, 0x46, 0xF1, 0xF7, + 0x4A, 0xDA, 0x9D, 0xF8, 0x04, 0x00, 0x7C, 0xBD, 0x64, 0x01, 0x20, 0x00, + 0xE0, 0x78, 0x20, 0x00, 0x03, 0x35, 0x10, 0x21, 0x88, 0x7D, 0xC0, 0x08, + 0x38, 0xB5, 0x0C, 0x46, 0x03, 0x46, 0x01, 0x22, 0x06, 0x49, 0x07, 0x48, + 0xF1, 0xF7, 0x37, 0xDA, 0x00, 0x20, 0x02, 0x46, 0x00, 0x90, 0x05, 0x48, + 0x14, 0x23, 0x01, 0x8A, 0x20, 0x46, 0x07, 0xF0, 0xFC, 0xF8, 0x38, 0xBD, + 0x10, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0xF8, 0xB5, 0x06, 0x46, 0x11, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8, + 0xC2, 0x11, 0x49, 0x06, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD, + 0x23, 0x46, 0x02, 0x22, 0x09, 0x49, 0x0A, 0x48, 0x00, 0x95, 0xF1, 0xF7, + 0x0E, 0xDA, 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0xA1, 0x89, + 0xE2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x07, 0xF0, 0xD1, 0xF8, + 0xF8, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0xEC, 0x7C, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, + 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x01, 0xD4, + 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, + 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF1, 0xF7, 0xE2, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, + 0x10, 0x8A, 0x11, 0x89, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, + 0x07, 0xF0, 0xA5, 0xF8, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xBC, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8, + 0xC2, 0x11, 0x89, 0x07, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD, + 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0xB5, 0xD9, + 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0x61, 0x88, 0xE2, 0x89, + 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x07, 0xF0, 0x78, 0xF8, 0xF8, 0xBD, + 0x64, 0x01, 0x20, 0x00, 0xC8, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x0D, 0x46, + 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA8, 0x42, 0x01, 0xDA, 0x01, 0x20, + 0x3E, 0xBD, 0x21, 0x46, 0x0D, 0x48, 0xF1, 0xF7, 0x61, 0xDB, 0xA2, 0x79, + 0xE1, 0x79, 0xCD, 0xE9, 0x00, 0x02, 0x02, 0x91, 0x2B, 0x46, 0x04, 0x22, + 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x87, 0xD9, 0x09, 0x48, 0x00, 0x95, + 0x08, 0x23, 0x01, 0x8A, 0x02, 0x88, 0x11, 0x44, 0xC2, 0x89, 0x89, 0xB2, + 0x20, 0x46, 0x07, 0xF0, 0x4A, 0xF8, 0x3E, 0xBD, 0x64, 0x01, 0x20, 0x00, + 0x00, 0x00, 0x30, 0x21, 0x58, 0x7A, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, 0x10, 0x48, 0x0C, 0x46, + 0x90, 0xF8, 0xC2, 0x11, 0x89, 0x06, 0x01, 0xD4, 0x02, 0x20, 0x38, 0xBD, + 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, + 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF1, 0xF7, + 0x5A, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, 0x10, 0x8A, 0x51, 0x89, + 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, 0x07, 0xF0, 0x1D, 0xF8, + 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x80, 0x7C, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x05, 0x46, + 0x10, 0x48, 0x0C, 0x46, 0x90, 0xF8, 0xC2, 0x11, 0x09, 0x07, 0x01, 0xD4, + 0x02, 0x20, 0x38, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, + 0x01, 0xDA, 0x01, 0x20, 0x38, 0xBD, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF1, 0xF7, 0x2E, 0xD9, 0x09, 0x4A, 0x00, 0x94, 0x18, 0x23, + 0x10, 0x8A, 0xD1, 0x88, 0xD2, 0x89, 0x08, 0x44, 0x81, 0xB2, 0x28, 0x46, + 0x06, 0xF0, 0xF1, 0xFF, 0x38, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x50, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0C, 0x46, 0x15, 0x46, 0x90, 0xF8, + 0xC2, 0x11, 0x49, 0x07, 0x01, 0xD4, 0x02, 0x20, 0xF8, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF8, 0xBD, + 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xF1, 0xF7, 0x01, 0xD9, + 0x00, 0x94, 0x08, 0x4C, 0x2B, 0x46, 0x20, 0x8A, 0xA1, 0x88, 0xE2, 0x89, + 0x08, 0x44, 0x81, 0xB2, 0x30, 0x46, 0x06, 0xF0, 0xC4, 0xFF, 0xF8, 0xBD, + 0x64, 0x01, 0x20, 0x00, 0x08, 0x7B, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xE0, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, + 0x06, 0x48, 0xF1, 0xF7, 0xE6, 0xD8, 0x00, 0x21, 0x0A, 0x46, 0x00, 0x91, + 0x04, 0x23, 0x28, 0x21, 0x20, 0x46, 0x06, 0xF0, 0xAC, 0xFF, 0x38, 0xBD, + 0xA8, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, + 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, 0xD2, 0xD8, 0x00, 0x21, + 0x0A, 0x46, 0x00, 0x91, 0x10, 0x23, 0x2C, 0x21, 0x20, 0x46, 0x06, 0xF0, + 0x98, 0xFF, 0x38, 0xBD, 0xE0, 0x79, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0x38, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x06, 0x49, 0x06, 0x48, 0xF1, 0xF7, + 0xBE, 0xD8, 0x00, 0x21, 0x28, 0x23, 0x0A, 0x46, 0x20, 0x46, 0x00, 0x91, + 0x06, 0xF0, 0x85, 0xFF, 0x38, 0xBD, 0x00, 0x00, 0x78, 0x79, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x13, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x82, 0xB0, + 0x90, 0xF8, 0xC2, 0x11, 0xC9, 0x06, 0x02, 0xD4, 0x02, 0x20, 0x04, 0xB0, + 0x10, 0xBD, 0x90, 0xF8, 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, + 0x01, 0x20, 0xF6, 0xE7, 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, + 0xF1, 0xF7, 0x99, 0xD8, 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, + 0x02, 0x89, 0x11, 0x44, 0x10, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x03, 0xA8, + 0x06, 0xF0, 0x5B, 0xFF, 0xE3, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x04, 0x7C, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, + 0x13, 0xB5, 0x04, 0x46, 0x11, 0x48, 0x82, 0xB0, 0x90, 0xF8, 0xC2, 0x11, + 0x89, 0x06, 0x02, 0xD4, 0x02, 0x20, 0x04, 0xB0, 0x10, 0xBD, 0x90, 0xF8, + 0xCB, 0x01, 0x40, 0x1E, 0xA0, 0x42, 0x01, 0xDA, 0x01, 0x20, 0xF6, 0xE7, + 0x23, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, 0xF1, 0xF7, 0x6B, 0xD8, + 0x09, 0x48, 0x00, 0x94, 0x04, 0x23, 0x01, 0x8A, 0x42, 0x89, 0x11, 0x44, + 0x10, 0x31, 0xC2, 0x89, 0x89, 0xB2, 0x03, 0xA8, 0x06, 0xF0, 0x2D, 0xFF, + 0xE3, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x30, 0x7C, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xE0, 0x78, 0x20, 0x00, 0x31, 0xB5, 0x82, 0xB0, + 0x01, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x13, 0x4C, 0x3E, 0x20, 0x00, 0x90, + 0x10, 0x4B, 0x00, 0x22, 0x02, 0xA9, 0xE0, 0x68, 0xFB, 0xF7, 0x00, 0xDF, + 0x0F, 0x4D, 0x78, 0xB1, 0x43, 0x20, 0x00, 0x90, 0x0B, 0x4B, 0x00, 0x22, + 0x01, 0xA9, 0x20, 0x69, 0xFB, 0xF7, 0xF6, 0xDE, 0x00, 0x28, 0x04, 0xD1, + 0x00, 0x22, 0x0A, 0x49, 0x28, 0x46, 0xF1, 0xF7, 0x36, 0xD8, 0x3E, 0xBD, + 0x07, 0x49, 0x00, 0x22, 0x2C, 0x39, 0x28, 0x46, 0xF1, 0xF7, 0x2F, 0xD8, + 0x02, 0x98, 0xF9, 0xF7, 0xB1, 0xFE, 0x3E, 0xBD, 0xA8, 0xB0, 0x82, 0x00, + 0xF0, 0x77, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0xDC, 0x5A, 0xC0, 0x08, + 0x10, 0xB5, 0xF9, 0xF7, 0xA5, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0xC1, 0x88, 0x00, 0x29, 0x06, 0xD1, 0x04, 0x49, + 0x02, 0x68, 0x4A, 0x61, 0x80, 0x88, 0x08, 0x83, 0x00, 0xF0, 0xE0, 0xBC, + 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x03, 0x46, + 0xA0, 0xF5, 0x00, 0x75, 0x00, 0x24, 0x15, 0x48, 0x15, 0x4A, 0x06, 0x2D, + 0x1D, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x1C, 0x12, 0x14, 0x17, 0x1A, + 0x12, 0x4A, 0x12, 0x78, 0xD2, 0x07, 0x04, 0xD0, 0x42, 0x69, 0x0A, 0x60, + 0x00, 0x8B, 0x88, 0x80, 0x15, 0xE0, 0x0F, 0x48, 0x50, 0xF8, 0x33, 0x2F, + 0x0A, 0x60, 0x80, 0x88, 0xF7, 0xE7, 0x10, 0x78, 0x03, 0xE0, 0x50, 0x88, + 0x08, 0x80, 0x0A, 0xE0, 0x50, 0x78, 0x08, 0x70, 0x07, 0xE0, 0x00, 0x78, + 0xFB, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xF0, 0xF7, + 0xE0, 0xDF, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, + 0x4A, 0x74, 0x20, 0x00, 0x38, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x60, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0xC0, 0x88, 0x00, 0x28, + 0x01, 0xD1, 0x00, 0xF0, 0x31, 0xBA, 0x70, 0x47, 0x41, 0x88, 0x05, 0x29, + 0x06, 0xD0, 0x0E, 0x29, 0x07, 0xD0, 0x0F, 0x29, 0x08, 0xD1, 0x00, 0x1D, + 0x00, 0xF0, 0xDC, 0xB9, 0x00, 0x1D, 0xFF, 0xF7, 0xA3, 0xBF, 0x00, 0x1D, + 0x00, 0xF0, 0xB2, 0xB9, 0x70, 0x47, 0x00, 0x00, 0x7F, 0xB5, 0x10, 0x4D, + 0x04, 0x46, 0x28, 0x69, 0x00, 0x28, 0x19, 0xD0, 0x20, 0x88, 0x0C, 0xF0, + 0xA5, 0xFC, 0x00, 0x28, 0x14, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, + 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, 0x20, 0x89, 0xAD, 0xF8, 0x08, 0x00, + 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, + 0xCD, 0xF8, 0x0C, 0xD0, 0x2A, 0x69, 0x03, 0xA9, 0x14, 0x20, 0x90, 0x47, + 0x7F, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x0C, 0x49, 0x10, 0xB5, + 0x09, 0x78, 0xC9, 0x07, 0x12, 0xD1, 0x81, 0x78, 0x61, 0xB1, 0xC1, 0x1C, + 0x10, 0x22, 0x09, 0x48, 0x23, 0xF4, 0x9D, 0xF0, 0x08, 0x48, 0x90, 0xF8, + 0x78, 0x01, 0x00, 0x06, 0x02, 0xD5, 0x05, 0x48, 0xFF, 0xF7, 0xA8, 0xFE, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xE2, 0xB9, 0x10, 0xBD, 0x00, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x09, 0x49, 0x10, 0xB5, 0x09, 0x78, 0xC9, 0x07, 0x0D, 0xD1, 0x03, 0x88, + 0x3B, 0xB1, 0x01, 0x22, 0x06, 0x49, 0x07, 0x48, 0xF0, 0xF7, 0x69, 0xDF, + 0x03, 0x49, 0x00, 0x20, 0x48, 0x72, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, + 0xC7, 0xB9, 0x10, 0xBD, 0x38, 0x78, 0x20, 0x00, 0x94, 0x5E, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x05, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, + 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x73, 0x20, + 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5, + 0x0A, 0x68, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, + 0x69, 0x46, 0x74, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, + 0x09, 0x49, 0x02, 0x89, 0x09, 0x4B, 0x8A, 0x81, 0x42, 0x89, 0xCA, 0x81, + 0x02, 0x7B, 0x1A, 0x70, 0x42, 0x7B, 0x4A, 0x71, 0x06, 0x4A, 0xC3, 0x7B, + 0x13, 0x70, 0x03, 0x7C, 0x53, 0x70, 0x02, 0x68, 0x0A, 0x62, 0x40, 0x68, + 0x48, 0x62, 0x70, 0x47, 0x38, 0x78, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00, + 0x50, 0x74, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x69, 0x00, 0x2A, + 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x01, 0x20, 0x90, 0x47, 0x08, 0xBD, + 0x38, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x0E, 0x4D, 0x04, 0x46, 0x28, 0x69, + 0x00, 0x28, 0x15, 0xD0, 0x20, 0x88, 0x0C, 0xF0, 0x05, 0xFC, 0x00, 0x28, + 0x10, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x60, 0x88, 0xAD, 0xF8, + 0x02, 0x00, 0x60, 0x68, 0x01, 0x90, 0x20, 0x7A, 0x8D, 0xF8, 0x08, 0x00, + 0xCD, 0xF8, 0x0C, 0xD0, 0x2A, 0x69, 0x03, 0xA9, 0x11, 0x20, 0x90, 0x47, + 0x7F, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5, + 0x0A, 0x68, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, + 0x69, 0x46, 0x70, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, + 0x7C, 0xB5, 0x0B, 0x4D, 0x04, 0x46, 0x28, 0x69, 0x00, 0x28, 0x10, 0xD0, + 0x60, 0x88, 0x0C, 0xF0, 0xD7, 0xFB, 0x00, 0x28, 0x0B, 0xD0, 0xC0, 0x78, + 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xCD, 0xF8, + 0x04, 0xD0, 0x2A, 0x69, 0x01, 0xA9, 0x13, 0x20, 0x90, 0x47, 0x7C, 0xBD, + 0x38, 0x78, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x69, 0x00, 0x2A, + 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x03, 0x20, 0x90, 0x47, 0x08, 0xBD, + 0x38, 0x78, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, + 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x72, 0x20, 0x90, 0x47, 0x08, 0xBD, + 0x48, 0x78, 0x20, 0x00, 0x05, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, + 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x71, 0x20, + 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x88, + 0xA1, 0xF5, 0x7D, 0x42, 0x80, 0x3A, 0x2F, 0xD1, 0x81, 0x79, 0x03, 0x29, + 0x2D, 0xD0, 0x0B, 0xDC, 0xD1, 0xB1, 0x01, 0x29, 0x11, 0xD0, 0x02, 0x29, + 0x26, 0xD1, 0x40, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90, + 0x18, 0x20, 0x24, 0xE0, 0x09, 0x29, 0x12, 0xD0, 0x0C, 0x29, 0x1B, 0xD1, + 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x1A, 0x20, 0x1B, 0xE0, 0x40, 0x88, + 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x12, 0x20, 0x14, 0xE0, + 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x42, 0x20, 0x0F, 0xE0, 0x0B, 0x49, + 0x09, 0x78, 0xC9, 0x07, 0x04, 0xD0, 0x40, 0x88, 0xAD, 0xF8, 0x00, 0x00, + 0xA2, 0x20, 0x06, 0xE0, 0x00, 0xF0, 0xDA, 0xF8, 0x1C, 0xBD, 0x40, 0x88, + 0xAD, 0xF8, 0x00, 0x00, 0xA3, 0x20, 0x03, 0x49, 0x0A, 0x69, 0x00, 0x2A, + 0xF6, 0xD0, 0x69, 0x46, 0x90, 0x47, 0x1C, 0xBD, 0x38, 0x78, 0x20, 0x00, + 0x1C, 0xB5, 0x01, 0x28, 0x1A, 0xD1, 0x13, 0x4C, 0x6C, 0x20, 0x00, 0x90, + 0x10, 0x4B, 0x00, 0x22, 0x01, 0xA9, 0xE0, 0x68, 0xFB, 0xF7, 0x44, 0xDD, + 0x00, 0x28, 0x0F, 0xD0, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0xA2, 0x68, + 0x5A, 0xB1, 0x69, 0x46, 0x01, 0x98, 0x90, 0x47, 0x38, 0xB1, 0x9D, 0xF8, + 0x00, 0x00, 0x00, 0x28, 0x02, 0xD0, 0x01, 0x98, 0xF9, 0xF7, 0xCE, 0xFC, + 0x1C, 0xBD, 0x01, 0x98, 0xFF, 0xF7, 0x7A, 0xFE, 0x01, 0x98, 0x0B, 0xF0, + 0x0D, 0xFF, 0x8D, 0xF8, 0x00, 0x00, 0xF0, 0xE7, 0xCB, 0xB0, 0x82, 0x00, + 0xF0, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x4D, 0x04, 0x46, 0x28, 0x69, + 0x00, 0x28, 0x14, 0xD0, 0xA1, 0x79, 0x20, 0x46, 0x0C, 0xF0, 0xEE, 0xFA, + 0x00, 0x28, 0x0E, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x89, + 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x7A, 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8, + 0x04, 0xD0, 0x2A, 0x69, 0x01, 0xA9, 0x10, 0x20, 0x90, 0x47, 0x7C, 0xBD, + 0x38, 0x78, 0x20, 0x00, 0x08, 0x49, 0x08, 0xB5, 0x09, 0x78, 0xC9, 0x07, + 0x08, 0xD0, 0x06, 0x49, 0x0A, 0x69, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90, + 0x69, 0x46, 0x02, 0x20, 0x90, 0x47, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40, + 0x00, 0xF0, 0x70, 0xB8, 0x38, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x88, + 0xA1, 0xF5, 0x7D, 0x42, 0x82, 0x3A, 0x12, 0xD1, 0x81, 0x79, 0x89, 0xB1, + 0x01, 0x29, 0x0E, 0xD1, 0x41, 0x88, 0xAD, 0xF8, 0x04, 0x10, 0xC0, 0x79, + 0x8D, 0xF8, 0x06, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x01, 0x20, 0x07, 0x49, + 0x4A, 0x68, 0x00, 0x2A, 0x01, 0xD0, 0x69, 0x46, 0x90, 0x47, 0x1C, 0xBD, + 0x40, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, 0x00, 0x90, 0x00, 0x20, + 0xF1, 0xE7, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x01, 0x46, 0x05, 0x48, + 0x08, 0xB5, 0x42, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x91, 0x04, 0x20, + 0x69, 0x46, 0x90, 0x47, 0x08, 0xBD, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, + 0x09, 0x49, 0x08, 0xB5, 0x09, 0x78, 0xC9, 0x07, 0x0A, 0xD0, 0x07, 0x49, + 0x0A, 0x69, 0x00, 0x2A, 0x05, 0xD0, 0x00, 0x88, 0xAD, 0xF8, 0x00, 0x00, + 0x69, 0x46, 0x04, 0x20, 0x90, 0x47, 0x08, 0xBD, 0xBD, 0xE8, 0x08, 0x40, + 0x00, 0xF0, 0x28, 0xB8, 0x38, 0x78, 0x20, 0x00, 0x0F, 0x48, 0x10, 0xB5, + 0x00, 0x78, 0xA0, 0xB1, 0x0E, 0x48, 0x00, 0x24, 0x90, 0xF8, 0x78, 0x01, + 0x00, 0x06, 0x10, 0xD5, 0x0C, 0x48, 0xFF, 0xF7, 0x13, 0xFB, 0x60, 0xB9, + 0x0A, 0x49, 0x00, 0x20, 0x0A, 0x5C, 0x1A, 0xB9, 0x40, 0x1C, 0xC0, 0xB2, + 0x10, 0x28, 0xF9, 0xD3, 0x10, 0x28, 0x00, 0xD1, 0x0C, 0xB1, 0x05, 0x48, + 0x00, 0xE0, 0x00, 0x20, 0xBD, 0xE8, 0x10, 0x40, 0xFC, 0xF7, 0x1E, 0xBB, + 0x0F, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00, + 0x7C, 0xB5, 0x48, 0x4D, 0x00, 0x24, 0x01, 0x22, 0x2B, 0x89, 0x47, 0x49, + 0x47, 0x48, 0xF0, 0xF7, 0x92, 0xDD, 0x28, 0x89, 0x41, 0x07, 0x05, 0xD5, + 0xFF, 0xF7, 0xCC, 0xFF, 0x28, 0x89, 0x20, 0xF0, 0x04, 0x00, 0x7D, 0xE0, + 0x01, 0x07, 0x0E, 0xD5, 0x40, 0x21, 0x00, 0x20, 0x09, 0xF0, 0xBE, 0xFF, + 0x20, 0xB1, 0x3F, 0x48, 0x00, 0x88, 0xFD, 0xF7, 0xDA, 0xFB, 0x00, 0xE0, + 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0, 0x08, 0x00, 0x55, 0xE0, 0x3B, 0x4B, + 0x01, 0x06, 0x4F, 0xF0, 0x00, 0x06, 0x0D, 0xD5, 0x10, 0x21, 0x01, 0x20, + 0x09, 0xF0, 0xAA, 0xFF, 0x10, 0xB1, 0xFC, 0xF7, 0x19, 0xFE, 0x01, 0xE0, + 0x5E, 0x72, 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0, 0x80, 0x00, 0x42, 0xE0, + 0x81, 0x05, 0x07, 0xD5, 0xE9, 0x88, 0xA8, 0x88, 0xFD, 0xF7, 0x32, 0xFC, + 0x28, 0x89, 0x20, 0xF4, 0x00, 0x70, 0x4F, 0xE0, 0x81, 0x06, 0x07, 0xD5, + 0x2B, 0x48, 0x14, 0x30, 0xFD, 0xF7, 0x90, 0xFB, 0x28, 0x89, 0x20, 0xF0, + 0x20, 0x00, 0x45, 0xE0, 0xC1, 0x07, 0x1B, 0xD0, 0x8D, 0xF8, 0x00, 0x60, + 0x69, 0x46, 0x40, 0xF2, 0x12, 0x20, 0x01, 0x96, 0x09, 0xF0, 0x14, 0xFA, + 0x01, 0xA9, 0x40, 0xF2, 0x11, 0x20, 0x09, 0xF0, 0x0F, 0xFA, 0x9D, 0xF8, + 0x00, 0x00, 0x00, 0x28, 0x01, 0x98, 0x02, 0xD0, 0x40, 0xF0, 0x00, 0x40, + 0x01, 0x90, 0xFC, 0xF7, 0x6D, 0xFA, 0x28, 0x89, 0x20, 0xF0, 0x01, 0x00, + 0x28, 0x81, 0x98, 0xE7, 0x41, 0x06, 0x12, 0xD5, 0x01, 0x21, 0x08, 0x46, + 0x09, 0xF0, 0x68, 0xFF, 0x28, 0xB1, 0x1A, 0x7A, 0xD9, 0x79, 0x98, 0x79, + 0xFD, 0xF7, 0x07, 0xFB, 0x00, 0xE0, 0x01, 0x24, 0x28, 0x89, 0x20, 0xF0, + 0x40, 0x00, 0x28, 0x81, 0x00, 0x2C, 0x84, 0xD1, 0x7C, 0xBD, 0xC1, 0x05, + 0x06, 0xD5, 0xA8, 0x78, 0x0D, 0xF0, 0xAE, 0xFC, 0x28, 0x89, 0x20, 0xF4, + 0x80, 0x70, 0x09, 0xE0, 0x80, 0x07, 0xF3, 0xD5, 0x0E, 0xF0, 0x40, 0xF9, + 0x08, 0xB9, 0x00, 0xF0, 0x2F, 0xFA, 0x28, 0x89, 0x20, 0xF0, 0x02, 0x00, + 0x28, 0x81, 0x7C, 0xBD, 0x50, 0x74, 0x20, 0x00, 0x70, 0x5E, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x86, 0x74, 0x20, 0x00, 0x38, 0x78, 0x20, 0x00, + 0x08, 0xB5, 0x01, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x01, 0x46, 0x6A, 0x46, + 0x4F, 0xF6, 0x82, 0x50, 0xFD, 0xF7, 0x6A, 0xFE, 0x08, 0xB1, 0x00, 0x20, + 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0x01, 0x49, 0x48, 0x60, + 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x01, 0x49, 0x88, 0x60, + 0x70, 0x47, 0x00, 0x00, 0xF0, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x41, + 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46, + 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0xD5, 0xDC, + 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x05, 0x20, 0x66, 0xF3, + 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8, + 0x03, 0x94, 0x00, 0xF0, 0xD1, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, + 0xC4, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41, + 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46, + 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0xB1, 0xDC, + 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x03, 0x20, 0x66, 0xF3, + 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8, + 0x03, 0x94, 0x00, 0xF0, 0xAD, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, + 0xAC, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41, + 0x15, 0x46, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x65, 0x07, 0x46, 0x03, 0x46, + 0x00, 0x24, 0x03, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xF0, 0xF7, 0x8D, 0xDC, + 0xAD, 0xF8, 0x08, 0x40, 0x67, 0xF3, 0x07, 0x04, 0x02, 0x20, 0x66, 0xF3, + 0x0F, 0x24, 0xAD, 0xF8, 0x0A, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x02, 0xA8, + 0x03, 0x94, 0x00, 0xF0, 0x89, 0xF8, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, + 0x60, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, + 0x15, 0x48, 0x03, 0x78, 0x40, 0x1E, 0x03, 0xF0, 0x01, 0x01, 0x02, 0x78, + 0x02, 0xF0, 0x01, 0x00, 0x81, 0x42, 0x0F, 0xD1, 0xC3, 0xF3, 0x81, 0x00, + 0xC2, 0xF3, 0x81, 0x01, 0x88, 0x42, 0x09, 0xD1, 0xC3, 0xF3, 0x01, 0x10, + 0xC2, 0xF3, 0x01, 0x11, 0x88, 0x42, 0x03, 0xD1, 0x98, 0x09, 0xB0, 0xEB, + 0x92, 0x1F, 0x0F, 0xD0, 0x08, 0x4D, 0x8D, 0xF8, 0x00, 0x20, 0x6D, 0x1E, + 0x01, 0x94, 0x03, 0x22, 0x06, 0x49, 0x07, 0x48, 0xF0, 0xF7, 0x51, 0xDC, + 0x21, 0x46, 0x28, 0x68, 0x00, 0xF0, 0x0A, 0xF8, 0x28, 0x78, 0x68, 0x70, + 0x7C, 0xBD, 0x00, 0x00, 0x39, 0x78, 0x20, 0x00, 0x30, 0x5E, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0xFE, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0x03, 0x46, + 0x00, 0x91, 0x00, 0x24, 0x02, 0x22, 0x09, 0x49, 0x09, 0x48, 0xF0, 0xF7, + 0x38, 0xDC, 0xAD, 0xF8, 0x04, 0x40, 0x01, 0x20, 0x66, 0xF3, 0x07, 0x04, + 0xAD, 0xF8, 0x06, 0x00, 0x65, 0xF3, 0x1F, 0x44, 0x01, 0xA8, 0x02, 0x94, + 0x00, 0xF0, 0x36, 0xF8, 0xFE, 0xBD, 0x00, 0x00, 0x2C, 0x84, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0x1C, 0xB5, 0x03, 0x78, 0x00, 0x21, 0x01, 0x2B, + 0x0D, 0xD1, 0xAD, 0xF8, 0x00, 0x10, 0x0B, 0x22, 0xAD, 0xF8, 0x02, 0x20, + 0x02, 0x79, 0x62, 0xF3, 0x07, 0x01, 0x42, 0x79, 0x40, 0x88, 0x62, 0xF3, + 0x0F, 0x21, 0x60, 0xF3, 0x1F, 0x41, 0x68, 0x46, 0x01, 0x91, 0x00, 0xF0, + 0x19, 0xF8, 0x1C, 0xBD, 0x7C, 0xB5, 0x05, 0x46, 0x00, 0x24, 0x22, 0x46, + 0x07, 0x49, 0x08, 0x48, 0xF0, 0xF7, 0x05, 0xDC, 0xAD, 0xF8, 0x00, 0x40, + 0x0A, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46, + 0x01, 0x94, 0x00, 0xF0, 0x05, 0xF8, 0x7C, 0xBD, 0x08, 0x86, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x17, 0x48, 0x00, 0x78, + 0x18, 0xB3, 0x02, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x16, 0x4E, 0x30, 0x20, + 0x00, 0x90, 0x14, 0x4B, 0x00, 0x22, 0x21, 0x46, 0x70, 0x68, 0xFB, 0xF7, + 0x9D, 0xDA, 0x13, 0x4D, 0x80, 0xB1, 0x34, 0x20, 0x00, 0x90, 0x0F, 0x4B, + 0x00, 0x22, 0x01, 0xA9, 0x30, 0x68, 0xFB, 0xF7, 0x93, 0xDA, 0x00, 0x28, + 0x05, 0xD1, 0x63, 0x88, 0x0D, 0x49, 0x01, 0x22, 0x28, 0x46, 0xF0, 0xF7, + 0xD2, 0xDB, 0x7C, 0xBD, 0x0A, 0x49, 0x01, 0x22, 0x63, 0x88, 0x30, 0x39, + 0xF6, 0xE7, 0x09, 0x48, 0x02, 0x68, 0x00, 0x2A, 0xF5, 0xD0, 0x69, 0x46, + 0xB0, 0x20, 0x00, 0x94, 0x90, 0x47, 0x7C, 0xBD, 0x53, 0x74, 0x20, 0x00, + 0x92, 0xB5, 0x82, 0x00, 0x68, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, + 0xFC, 0x83, 0xC0, 0x08, 0x48, 0x78, 0x20, 0x00, 0xFE, 0xB5, 0x0D, 0x46, + 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x00, 0x24, 0x02, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xF0, 0xF7, 0xAC, 0xDB, 0xAD, 0xF8, 0x04, 0x40, 0x04, 0x20, + 0x66, 0xF3, 0x07, 0x04, 0xAD, 0xF8, 0x06, 0x00, 0x65, 0xF3, 0x1F, 0x44, + 0x01, 0xA8, 0x02, 0x94, 0xFF, 0xF7, 0xAA, 0xFF, 0xFE, 0xBD, 0x00, 0x00, + 0xF4, 0x84, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46, + 0x00, 0x24, 0x22, 0x46, 0x07, 0x49, 0x08, 0x48, 0xF0, 0xF7, 0x91, 0xDB, + 0xAD, 0xF8, 0x00, 0x40, 0x08, 0x20, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3, + 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x91, 0xFF, 0x7C, 0xBD, + 0xA8, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46, + 0x03, 0x46, 0x00, 0x24, 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xF0, 0xF7, + 0x78, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x06, 0x20, 0xAD, 0xF8, 0x02, 0x00, + 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x78, 0xFF, + 0x7C, 0xBD, 0x00, 0x00, 0x2C, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, + 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0x00, 0x24, 0x22, 0x46, 0x09, 0x49, + 0x09, 0x48, 0xF0, 0xF7, 0x5E, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x07, 0x20, + 0x66, 0xF3, 0x07, 0x04, 0xAD, 0xF8, 0x02, 0x00, 0x65, 0xF3, 0x0F, 0x24, + 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x5C, 0xFF, 0x7C, 0xBD, 0x00, 0x00, + 0x88, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46, + 0x03, 0x46, 0x00, 0x24, 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xF0, 0xF7, + 0x42, 0xDB, 0xAD, 0xF8, 0x00, 0x40, 0x09, 0x20, 0xAD, 0xF8, 0x02, 0x00, + 0x65, 0xF3, 0x07, 0x04, 0x68, 0x46, 0x01, 0x94, 0xFF, 0xF7, 0x42, 0xFF, + 0x7C, 0xBD, 0x00, 0x00, 0x58, 0x85, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, + 0x09, 0x48, 0x10, 0xB5, 0x00, 0x78, 0x08, 0xB1, 0x01, 0x23, 0x00, 0xE0, + 0x00, 0x23, 0x07, 0x49, 0x08, 0x78, 0x00, 0xB1, 0x01, 0x20, 0x4A, 0x78, + 0x49, 0x88, 0xFD, 0xF7, 0x23, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0xF0, 0x77, 0x20, 0x00, 0x4A, 0x74, 0x20, 0x00, + 0x70, 0xB5, 0x03, 0x46, 0x00, 0x24, 0xA0, 0xF5, 0x00, 0x70, 0x16, 0x4D, + 0x02, 0x38, 0x06, 0xD0, 0x01, 0x28, 0x12, 0xD0, 0x02, 0x28, 0x15, 0xD0, + 0x03, 0x28, 0x07, 0xD1, 0x19, 0xE0, 0x01, 0x29, 0x04, 0xD1, 0x11, 0x78, + 0x01, 0x29, 0x01, 0xD8, 0x29, 0x70, 0x19, 0xE0, 0x03, 0x24, 0x01, 0x22, + 0x0D, 0x49, 0x0E, 0x48, 0xF0, 0xF7, 0xFD, 0xDA, 0x12, 0xE0, 0x02, 0x29, + 0xF6, 0xD1, 0x10, 0x88, 0x68, 0x80, 0x0D, 0xE0, 0x01, 0x29, 0xF1, 0xD1, + 0x11, 0x78, 0x04, 0x29, 0xEE, 0xD8, 0x69, 0x70, 0x06, 0xE0, 0x01, 0x29, + 0xEA, 0xD1, 0x11, 0x78, 0x01, 0x29, 0xE7, 0xD8, 0x04, 0x48, 0x01, 0x70, + 0x20, 0x46, 0x70, 0xBD, 0x4A, 0x74, 0x20, 0x00, 0x38, 0x5B, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0xF0, 0x77, 0x20, 0x00, 0x03, 0x48, 0x01, 0x78, + 0x41, 0xF0, 0x01, 0x01, 0x01, 0x70, 0x00, 0x20, 0xFF, 0xF7, 0x60, 0xBE, + 0x38, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x04, 0x46, + 0xF9, 0xF7, 0x92, 0xF9, 0x98, 0xB1, 0x31, 0x46, 0x20, 0x46, 0x0B, 0xF0, + 0xEF, 0xF8, 0x57, 0x20, 0x00, 0x90, 0x0A, 0x4B, 0x04, 0x22, 0x29, 0x46, + 0x09, 0x48, 0xFB, 0xF7, 0x03, 0xD9, 0x08, 0x48, 0x0C, 0x38, 0x04, 0x61, + 0xBD, 0xE8, 0xF8, 0x40, 0x06, 0x48, 0xFD, 0xF7, 0x79, 0xBA, 0x00, 0x22, + 0x05, 0x49, 0x06, 0x48, 0xF0, 0xF7, 0xB5, 0xDA, 0x00, 0x20, 0xF8, 0xBD, + 0xB8, 0xB0, 0x82, 0x00, 0xFC, 0x77, 0x20, 0x00, 0xAD, 0x6F, 0x81, 0x00, + 0x08, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0xB5, 0x00, 0x21, + 0x8D, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21, + 0x4F, 0xF6, 0x82, 0x50, 0xFD, 0xF7, 0x12, 0xFC, 0x08, 0xB1, 0x00, 0x20, + 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0xF8, 0xB5, 0x00, 0x26, + 0xDD, 0xE9, 0x06, 0x47, 0x15, 0x46, 0x26, 0x80, 0x03, 0x46, 0x00, 0x92, + 0x02, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xF0, 0xF7, 0x8A, 0xDA, 0x06, 0x2D, + 0x05, 0xD0, 0x08, 0x2D, 0x09, 0xD0, 0x40, 0xF2, 0x0A, 0x46, 0x30, 0x46, + 0xF8, 0xBD, 0x08, 0x48, 0x38, 0x60, 0x22, 0xF4, 0x73, 0xF3, 0x40, 0x1C, + 0x03, 0xE0, 0x05, 0x48, 0x0E, 0x38, 0x38, 0x60, 0x02, 0x20, 0x20, 0x80, + 0xF1, 0xE7, 0x00, 0x00, 0x1C, 0x7F, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, + 0x04, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x86, 0xB0, 0x17, 0x46, + 0xDD, 0xE9, 0x0E, 0x46, 0xCD, 0xE9, 0x00, 0x74, 0x8A, 0x46, 0x81, 0x46, + 0x03, 0x46, 0x00, 0x25, 0x03, 0x22, 0x28, 0x49, 0x28, 0x48, 0xF0, 0xF7, + 0x5E, 0xDA, 0x03, 0x20, 0xDF, 0xF8, 0x9C, 0x80, 0x40, 0xF2, 0x0D, 0x41, + 0x06, 0x2F, 0x06, 0xD0, 0x08, 0x2F, 0x27, 0xD0, 0xCD, 0x1E, 0x06, 0xB0, + 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x2C, 0x3A, 0xD8, 0xC6, 0xB3, + 0x8D, 0xF8, 0x08, 0x00, 0x01, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8, + 0x09, 0x90, 0xAD, 0xF8, 0x0E, 0x40, 0x04, 0x96, 0xD8, 0xF8, 0x04, 0x20, + 0x22, 0xB1, 0x02, 0xA9, 0x50, 0x46, 0x90, 0x47, 0x05, 0x00, 0xE6, 0xD1, + 0x27, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x15, 0x48, 0x22, 0x46, 0x31, 0x46, + 0x10, 0x30, 0x22, 0xF4, 0x46, 0xF3, 0x12, 0x49, 0x00, 0x20, 0x10, 0x31, + 0x08, 0x55, 0xD8, 0xE7, 0x02, 0x2C, 0x17, 0xD1, 0xAE, 0xB1, 0x8D, 0xF8, + 0x08, 0x00, 0x02, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8, 0x09, 0x90, + 0xAD, 0xF8, 0x0E, 0x00, 0x04, 0x96, 0xD8, 0xF8, 0x04, 0x20, 0x22, 0xB1, + 0x02, 0xA9, 0x50, 0x46, 0x90, 0x47, 0x05, 0x00, 0xC3, 0xD1, 0x30, 0x88, + 0xA8, 0xF8, 0x02, 0x00, 0xBF, 0xE7, 0xFF, 0xE7, 0x0D, 0x46, 0xBC, 0xE7, + 0x54, 0x7F, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, 0xF4, 0x78, 0x20, 0x00, + 0x3E, 0xB5, 0x0C, 0x46, 0x8D, 0xF8, 0x01, 0x00, 0x01, 0x20, 0x8D, 0xF8, + 0x00, 0x00, 0x03, 0x2A, 0x0D, 0xD1, 0x98, 0x07, 0x01, 0xD5, 0x03, 0x20, + 0x00, 0xE0, 0x04, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x03, 0x48, 0x42, 0x68, + 0x00, 0x2A, 0x02, 0xD0, 0x69, 0x46, 0x20, 0x46, 0x90, 0x47, 0x3E, 0xBD, + 0xF4, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x16, 0x46, 0x0C, 0x46, + 0x03, 0x46, 0x01, 0x25, 0x02, 0x21, 0x0A, 0x22, 0x22, 0x48, 0x05, 0x2B, + 0x37, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x0F, 0x18, 0x1F, 0x29, 0x00, + 0x28, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x22, 0x46, 0x31, 0x46, 0x1D, 0x48, + 0x22, 0xF4, 0xED, 0xF2, 0x1B, 0x49, 0x00, 0x20, 0x08, 0x55, 0x2E, 0xE0, + 0x02, 0x2C, 0x21, 0xD1, 0x18, 0x49, 0x30, 0x88, 0x0E, 0x39, 0x08, 0x70, + 0x00, 0x0A, 0x48, 0x70, 0x25, 0xE0, 0x01, 0x2C, 0x18, 0xD1, 0x14, 0x49, + 0x30, 0x78, 0x10, 0x39, 0x08, 0x70, 0x1E, 0xE0, 0x01, 0x2C, 0x11, 0xD1, + 0x33, 0x78, 0x01, 0x2B, 0x0E, 0xD8, 0x01, 0xD1, 0x42, 0x70, 0x16, 0xE0, + 0x41, 0x70, 0x14, 0xE0, 0x01, 0x2C, 0x07, 0xD1, 0x33, 0x78, 0x01, 0x2B, + 0x04, 0xD8, 0x01, 0xD1, 0x02, 0x70, 0x0C, 0xE0, 0x01, 0x70, 0x0A, 0xE0, + 0x4F, 0xF0, 0x00, 0x05, 0x07, 0xE0, 0x4F, 0xF0, 0x00, 0x05, 0x4F, 0xF0, + 0x01, 0x02, 0x05, 0x49, 0x05, 0x48, 0xF0, 0xF7, 0xA6, 0xD9, 0x28, 0x46, + 0xBD, 0xE8, 0xF0, 0x81, 0x83, 0x74, 0x20, 0x00, 0x04, 0x79, 0x20, 0x00, + 0xF0, 0x7E, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x10, 0xB5, 0x07, 0x4C, + 0x20, 0x70, 0x00, 0x0A, 0x60, 0x70, 0xA1, 0x70, 0x08, 0x0A, 0x21, 0x46, + 0xC8, 0x70, 0x22, 0x71, 0x10, 0x0A, 0x48, 0x71, 0xA3, 0x71, 0x18, 0x0A, + 0xC8, 0x71, 0x10, 0xBD, 0xFC, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x0F, 0x48, + 0x4F, 0xF4, 0xD2, 0x72, 0x90, 0xF8, 0xB0, 0x01, 0xC0, 0x07, 0x01, 0xD1, + 0x4F, 0xF4, 0xB6, 0x72, 0x0B, 0x48, 0xD0, 0xE9, 0x0A, 0x13, 0xCD, 0xE9, + 0x00, 0x13, 0xA0, 0xF5, 0xC0, 0x71, 0x43, 0x6A, 0x08, 0x48, 0x0D, 0xF0, + 0x22, 0xF9, 0x08, 0xB1, 0x01, 0x20, 0x1C, 0xBD, 0x00, 0x22, 0x06, 0x49, + 0x06, 0x48, 0xF0, 0xF7, 0x6C, 0xD9, 0x00, 0x20, 0x1C, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x60, 0xB5, 0x82, 0x00, 0xF5, 0x78, 0x20, 0x00, + 0x98, 0x7F, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, + 0x23, 0x4D, 0x24, 0x49, 0x00, 0x24, 0x23, 0x46, 0x20, 0x46, 0x49, 0x68, + 0x95, 0xF8, 0x98, 0x21, 0x09, 0xE0, 0xC0, 0xEB, 0xC0, 0x04, 0x04, 0xEB, + 0x00, 0x14, 0x01, 0xEB, 0x84, 0x04, 0x66, 0x78, 0x26, 0xB1, 0x40, 0x1C, + 0xC0, 0xB2, 0x82, 0x42, 0xF3, 0xD8, 0x53, 0xB3, 0x4C, 0x21, 0x04, 0xF1, + 0x10, 0x00, 0x22, 0xF4, 0xF7, 0xF2, 0x01, 0x20, 0x60, 0x70, 0xB5, 0xF8, + 0xAE, 0x01, 0x20, 0x85, 0x17, 0x20, 0x60, 0x85, 0x00, 0x20, 0x60, 0x76, + 0x60, 0x68, 0x20, 0x21, 0x00, 0x1D, 0x22, 0xF4, 0xE9, 0xF2, 0xA0, 0x68, + 0x44, 0x21, 0x00, 0x1D, 0x22, 0xF4, 0xE4, 0xF2, 0x00, 0x26, 0x04, 0xF1, + 0x44, 0x08, 0xE7, 0x68, 0x06, 0xE0, 0x39, 0x46, 0x40, 0x46, 0xFB, 0xF7, + 0x84, 0xD8, 0x76, 0x1C, 0xF6, 0xB2, 0x20, 0x37, 0x95, 0xF8, 0xAB, 0x01, + 0xB0, 0x42, 0xF4, 0xD8, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x22, + 0x04, 0x49, 0x05, 0x48, 0xF0, 0xF7, 0x17, 0xD9, 0x00, 0x20, 0xF6, 0xE7, + 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x3C, 0x4E, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x1B, 0x48, 0x00, 0x23, 0x19, 0x4C, + 0x02, 0x21, 0x90, 0xF8, 0xAD, 0x01, 0x07, 0xE0, 0x62, 0x68, 0x03, 0xEB, + 0x43, 0x05, 0x01, 0xEB, 0x85, 0x05, 0x52, 0x5B, 0x4A, 0xB1, 0x5B, 0x1C, + 0x98, 0x42, 0xF5, 0xDC, 0x00, 0x22, 0x13, 0x49, 0x13, 0x48, 0xF0, 0xF7, + 0xF6, 0xD8, 0x00, 0x20, 0x70, 0xBD, 0x60, 0x68, 0x03, 0xEB, 0x43, 0x05, + 0x00, 0xEB, 0x85, 0x00, 0x00, 0x22, 0x02, 0x60, 0x42, 0x60, 0x82, 0x60, + 0x60, 0x68, 0x01, 0xEB, 0x85, 0x01, 0x20, 0xF8, 0x25, 0x30, 0x62, 0x68, + 0x01, 0x20, 0x50, 0x52, 0x02, 0x46, 0x07, 0x49, 0x07, 0x48, 0x24, 0x39, + 0xC0, 0x1C, 0xF0, 0xF7, 0xDC, 0xD8, 0x60, 0x68, 0x00, 0xEB, 0x85, 0x00, + 0x70, 0xBD, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xD8, 0x4E, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x30, 0xB5, 0x05, 0x46, + 0x88, 0x78, 0xCA, 0x78, 0x01, 0x24, 0x00, 0xEB, 0x02, 0x20, 0x0A, 0x78, + 0x80, 0xB2, 0xD3, 0x07, 0x4F, 0xF4, 0x20, 0x52, 0x03, 0xD1, 0x90, 0x42, + 0x01, 0xD1, 0x08, 0x46, 0x04, 0xE0, 0x00, 0x23, 0x29, 0x46, 0x58, 0x1E, + 0x00, 0xF0, 0xCE, 0xFD, 0x18, 0xB1, 0x00, 0x88, 0x00, 0x05, 0x00, 0xD4, + 0x00, 0x24, 0x20, 0x46, 0x30, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x16, 0x46, + 0x0A, 0x46, 0x05, 0x46, 0x1F, 0x46, 0x00, 0x24, 0x31, 0x46, 0x10, 0x46, + 0xFF, 0xF7, 0xD8, 0xFF, 0xF0, 0xB1, 0x22, 0x4A, 0xB0, 0x69, 0x4F, 0xB1, + 0x04, 0x21, 0x01, 0xEA, 0x10, 0x11, 0x02, 0xEA, 0x10, 0x10, 0x51, 0xEA, + 0x00, 0x02, 0x07, 0xD1, 0x03, 0x24, 0x34, 0xE0, 0x00, 0xF0, 0x04, 0x01, + 0x10, 0x40, 0x51, 0xEA, 0x00, 0x02, 0x09, 0xD0, 0x02, 0x28, 0x10, 0xD0, + 0x03, 0x28, 0x13, 0xD0, 0x08, 0x28, 0x07, 0xD0, 0xB0, 0xF5, 0x80, 0x3F, + 0x15, 0xD1, 0x10, 0xE0, 0x02, 0x24, 0x22, 0xE0, 0x80, 0x24, 0x20, 0xE0, + 0x68, 0x79, 0x40, 0x07, 0x0D, 0xD4, 0x0F, 0x24, 0x1B, 0xE0, 0x68, 0x79, + 0xC0, 0x07, 0x08, 0xD1, 0x05, 0x24, 0x16, 0xE0, 0x68, 0x79, 0x80, 0x07, + 0x01, 0xE0, 0x68, 0x79, 0x00, 0x07, 0x00, 0x28, 0xF6, 0xDA, 0x30, 0x8B, + 0xC0, 0xF3, 0x03, 0x30, 0x00, 0x28, 0x00, 0xDD, 0x40, 0x1C, 0xAA, 0x79, + 0x82, 0x42, 0x01, 0xDA, 0x0C, 0x24, 0x04, 0xE0, 0x19, 0xB1, 0x30, 0x78, + 0x40, 0x07, 0x00, 0xD4, 0x08, 0x24, 0x20, 0x46, 0xF0, 0xBD, 0x00, 0x00, + 0x0B, 0x00, 0x01, 0x00, 0x42, 0xF6, 0x03, 0x01, 0x00, 0xF0, 0x14, 0xB8, + 0x42, 0xF6, 0x02, 0x11, 0x00, 0xF0, 0x10, 0xB8, 0x10, 0xB5, 0x04, 0x46, + 0x4F, 0xF4, 0x20, 0x51, 0x00, 0xF0, 0x0A, 0xF8, 0x30, 0xB9, 0x42, 0xF6, + 0x01, 0x01, 0x20, 0x46, 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x28, 0x00, 0xD0, + 0x01, 0x20, 0x10, 0xBD, 0x82, 0x78, 0xC3, 0x78, 0x00, 0x78, 0x02, 0xEB, + 0x03, 0x22, 0x92, 0xB2, 0xC0, 0x07, 0x03, 0xD1, 0x8A, 0x42, 0x01, 0xD1, + 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xFF, 0x41, + 0x17, 0x46, 0xDD, 0xE9, 0x0A, 0x4C, 0x01, 0x22, 0x8C, 0xF8, 0x00, 0x20, + 0x1D, 0x88, 0x6A, 0x07, 0x0A, 0xD5, 0x62, 0x8A, 0x03, 0x92, 0xA3, 0x8A, + 0xA6, 0x68, 0x04, 0xF1, 0x14, 0x02, 0x9D, 0x19, 0x00, 0x23, 0x8C, 0xF8, + 0x00, 0x30, 0x08, 0xE0, 0x00, 0x26, 0x32, 0x46, 0xAD, 0x07, 0x01, 0xD5, + 0x1D, 0x1D, 0x00, 0xE0, 0x5D, 0x69, 0x5B, 0x8A, 0x03, 0x93, 0x03, 0xAB, + 0x00, 0x97, 0xCD, 0xE9, 0x01, 0x35, 0x01, 0x29, 0x00, 0xD0, 0x00, 0x21, + 0x13, 0x46, 0x32, 0x46, 0xF7, 0xF7, 0x0A, 0xF8, 0x00, 0x2E, 0x01, 0xD0, + 0x03, 0x99, 0x61, 0x82, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x7C, 0xB5, + 0x0C, 0x46, 0x45, 0x68, 0x49, 0x88, 0xAD, 0x1D, 0x44, 0xF2, 0x02, 0x06, + 0x01, 0x29, 0x06, 0xD0, 0x02, 0x29, 0x0D, 0xD0, 0x04, 0x29, 0x17, 0xD0, + 0x40, 0xF6, 0x02, 0x40, 0x7C, 0xBD, 0xA1, 0x88, 0xF7, 0xF7, 0x4C, 0xF9, + 0x00, 0x28, 0xF9, 0xD1, 0xA1, 0x88, 0xE9, 0x80, 0x00, 0x21, 0x08, 0xE0, + 0xE2, 0x88, 0xA1, 0x88, 0xF7, 0xF7, 0xD4, 0xF8, 0x00, 0x28, 0xEF, 0xD1, + 0xA1, 0x88, 0xE9, 0x80, 0xE1, 0x88, 0x29, 0x81, 0x6E, 0x80, 0x0E, 0xE0, + 0x21, 0x89, 0x10, 0x29, 0x0E, 0xD0, 0xE1, 0x68, 0x10, 0x23, 0x00, 0x91, + 0xE2, 0x88, 0xA1, 0x88, 0xF7, 0xF7, 0xE5, 0xF8, 0x00, 0x28, 0xDD, 0xD1, + 0x44, 0xF2, 0x01, 0x01, 0x69, 0x80, 0x61, 0x88, 0xA9, 0x80, 0x7C, 0xBD, + 0xA1, 0x89, 0x8D, 0xF8, 0x04, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x05, 0x10, + 0x01, 0xA9, 0x02, 0x23, 0xE9, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, + 0x47, 0x48, 0x87, 0xB0, 0x99, 0x46, 0x00, 0x78, 0xDD, 0xE9, 0x16, 0x47, + 0x40, 0x1C, 0x20, 0xF0, 0x01, 0x00, 0x00, 0x1F, 0xDD, 0xF8, 0x54, 0xA0, + 0x4F, 0xF0, 0x00, 0x0B, 0x06, 0x90, 0x0A, 0x28, 0x7A, 0xD3, 0x48, 0x44, + 0x57, 0x45, 0x01, 0xD0, 0x00, 0xEB, 0x44, 0x00, 0x81, 0xB2, 0x3E, 0x48, + 0x4F, 0xF4, 0x72, 0x73, 0x3B, 0x4A, 0x00, 0x78, 0xF7, 0xF7, 0x3C, 0xFD, + 0x05, 0x90, 0x00, 0x28, 0x6A, 0xD0, 0xB9, 0xF1, 0x00, 0x0F, 0x4E, 0xD0, + 0xDD, 0xE9, 0x05, 0x01, 0x45, 0x18, 0x50, 0x46, 0x57, 0x45, 0x2C, 0xD1, + 0x74, 0xB1, 0x14, 0x99, 0x4F, 0xF0, 0x00, 0x08, 0x09, 0xEB, 0x01, 0x00, + 0x90, 0xFB, 0xF4, 0xF6, 0xB6, 0x1E, 0x05, 0xEB, 0x44, 0x00, 0x00, 0x90, + 0x60, 0x1E, 0xB3, 0x46, 0x01, 0x90, 0x19, 0xE0, 0x40, 0xF6, 0x07, 0x40, + 0x07, 0x90, 0x3F, 0xE0, 0x3A, 0xF8, 0x02, 0x0B, 0x25, 0xF8, 0x02, 0x0B, + 0x14, 0x98, 0x20, 0xB1, 0x01, 0x99, 0x88, 0x45, 0x01, 0xD1, 0x14, 0x98, + 0x36, 0x1A, 0x32, 0x46, 0x51, 0x46, 0x00, 0x98, 0x22, 0xF4, 0x8B, 0xF0, + 0x00, 0x98, 0xB2, 0x44, 0x30, 0x44, 0x08, 0xF1, 0x01, 0x08, 0x00, 0x90, + 0xA0, 0x45, 0xE7, 0xDB, 0x18, 0xE0, 0x1C, 0xB1, 0x99, 0xFB, 0xF4, 0xFB, + 0x00, 0x20, 0x0A, 0xE0, 0x01, 0x46, 0x4A, 0x46, 0x28, 0x46, 0x22, 0xF4, + 0x78, 0xF0, 0x1B, 0xE0, 0x37, 0xF8, 0x02, 0x1B, 0x25, 0xF8, 0x02, 0x1B, + 0x40, 0x1C, 0xA0, 0x42, 0xF8, 0xDB, 0x4A, 0x46, 0x51, 0x46, 0x28, 0x46, + 0x22, 0xF4, 0x6B, 0xF0, 0x09, 0xEB, 0x44, 0x09, 0xB9, 0xF1, 0x00, 0x0F, + 0x0A, 0xD1, 0x01, 0x2C, 0x08, 0xD1, 0xDD, 0xE9, 0x05, 0x01, 0x08, 0x44, + 0x39, 0x88, 0x01, 0x80, 0x4F, 0xF0, 0x02, 0x09, 0x4F, 0xF0, 0x00, 0x0B, + 0x18, 0x99, 0x08, 0x9A, 0xCD, 0xE9, 0x01, 0x21, 0xCD, 0xE9, 0x03, 0xB4, + 0x07, 0x98, 0x00, 0x90, 0xDD, 0xE9, 0x05, 0x02, 0x4B, 0x46, 0x09, 0x99, + 0xF9, 0xF7, 0x38, 0xFF, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, + 0x48, 0x74, 0x20, 0x00, 0xA3, 0xAC, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x4F, 0x1F, 0x4A, 0x4F, 0xF0, 0x00, 0x0C, 0x1D, 0x4D, + 0x61, 0x46, 0x4F, 0xF0, 0x04, 0x0A, 0x4F, 0xF0, 0x02, 0x0B, 0x08, 0x26, + 0x6F, 0xF0, 0x1B, 0x07, 0x92, 0xF8, 0xAD, 0x91, 0x27, 0xE0, 0x6B, 0x68, + 0x01, 0xEB, 0x41, 0x02, 0x0B, 0xEB, 0x82, 0x04, 0x1C, 0x5B, 0xFC, 0xB1, + 0x0A, 0xEB, 0x82, 0x04, 0x06, 0xEB, 0x82, 0x08, 0x33, 0xF8, 0x08, 0x80, + 0x1C, 0x59, 0xC8, 0xEB, 0xC8, 0x08, 0x07, 0xEB, 0x88, 0x08, 0xA0, 0x44, + 0x84, 0x42, 0x11, 0xD8, 0x40, 0x45, 0x0F, 0xD8, 0x01, 0xEB, 0x41, 0x05, + 0x0A, 0xEB, 0x85, 0x01, 0x59, 0x58, 0x40, 0x1A, 0x1C, 0x21, 0xB0, 0xFB, + 0xF1, 0xF0, 0x0A, 0x21, 0x01, 0xEB, 0x82, 0x01, 0x59, 0x5A, 0x00, 0xEB, + 0x01, 0x0C, 0x02, 0xE0, 0x49, 0x1C, 0x89, 0x45, 0xD5, 0xDC, 0x1F, 0xFA, + 0x8C, 0xF0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x08, 0xB5, 0x82, 0x89, 0x01, 0x68, 0x00, 0x92, + 0xC3, 0x89, 0x42, 0x68, 0x00, 0x8A, 0xF9, 0xF7, 0x17, 0xFF, 0x08, 0xBD, + 0x2D, 0xE9, 0xFC, 0x41, 0x05, 0x46, 0x00, 0x24, 0x08, 0x98, 0x1F, 0x46, + 0x16, 0x46, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x01, 0xD0, 0x05, 0x29, + 0x00, 0xD1, 0x01, 0x24, 0x03, 0x1D, 0x82, 0x1D, 0x01, 0x29, 0x09, 0xD0, + 0x02, 0x29, 0x07, 0xD0, 0x03, 0x29, 0x15, 0xD0, 0x05, 0x29, 0x03, 0xD0, + 0x40, 0xF6, 0x02, 0x40, 0xBD, 0xE8, 0xFC, 0x81, 0xCD, 0xE9, 0x00, 0x23, + 0x03, 0x68, 0x32, 0x46, 0x28, 0x46, 0xF7, 0xF7, 0xA3, 0xF8, 0x04, 0x43, + 0xF4, 0xD1, 0x6A, 0x68, 0x44, 0xF2, 0x03, 0x01, 0x11, 0x81, 0x69, 0x68, + 0x4E, 0x81, 0xED, 0xE7, 0xCD, 0xE9, 0x00, 0x23, 0x03, 0x68, 0x32, 0x46, + 0x39, 0x46, 0x28, 0x46, 0xF6, 0xF7, 0x26, 0xFF, 0x00, 0x28, 0xE3, 0xD1, + 0x6A, 0x68, 0x44, 0xF2, 0x04, 0x01, 0x11, 0x81, 0xDE, 0xE7, 0x02, 0x46, + 0x10, 0xF4, 0x7F, 0x41, 0x4F, 0xF0, 0x0E, 0x00, 0x4F, 0xF4, 0x80, 0x63, + 0x01, 0xD0, 0x99, 0x42, 0x05, 0xD1, 0xD0, 0xB2, 0xA0, 0xF1, 0x12, 0x01, + 0x6E, 0x29, 0x00, 0xD2, 0x0E, 0x20, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x43, + 0x05, 0x46, 0x00, 0x20, 0x04, 0x46, 0x15, 0x4F, 0x06, 0x46, 0xDF, 0xF8, + 0x54, 0x90, 0x1F, 0xE0, 0xBB, 0x69, 0x9B, 0x68, 0x03, 0xEB, 0xC4, 0x03, + 0x93, 0xF8, 0x00, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x15, 0xD0, 0xB3, 0xF8, + 0x02, 0xC0, 0xB1, 0xF8, 0x30, 0x80, 0xC4, 0x45, 0x0F, 0xD1, 0x40, 0x1C, + 0x15, 0xB1, 0x02, 0x2D, 0x0B, 0xD1, 0x03, 0xE0, 0x1E, 0x70, 0x5E, 0x70, + 0xDE, 0x80, 0x06, 0xE0, 0xB3, 0xF8, 0x04, 0xC0, 0x22, 0xF8, 0x02, 0xCB, + 0xDB, 0x88, 0x22, 0xF8, 0x02, 0x3B, 0x64, 0x1C, 0x99, 0xF8, 0xAC, 0x31, + 0xA3, 0x42, 0xDB, 0xDC, 0xBD, 0xE8, 0xF0, 0x83, 0x98, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x01, 0x49, 0x88, 0x72, 0x70, 0x47, 0x00, 0x00, + 0x98, 0x77, 0x20, 0x00, 0x41, 0x76, 0x70, 0x47, 0x00, 0x78, 0x52, 0x28, + 0x07, 0xD0, 0x00, 0xF0, 0x3F, 0x00, 0x1B, 0x28, 0x03, 0xD0, 0x02, 0x28, + 0x01, 0xD0, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0xF0, 0xB5, + 0x06, 0x46, 0x0D, 0x46, 0x01, 0x24, 0x08, 0x46, 0x01, 0xF0, 0x48, 0xFE, + 0x07, 0x00, 0x1D, 0xD0, 0x02, 0x46, 0x01, 0x23, 0x29, 0x46, 0x30, 0x46, + 0xFF, 0xF7, 0x8C, 0xFD, 0x04, 0x00, 0x15, 0xD1, 0x38, 0x46, 0xFF, 0xF7, + 0xDD, 0xFD, 0x08, 0xB1, 0x80, 0x24, 0x0F, 0xE0, 0xA7, 0xF1, 0x1C, 0x00, + 0x05, 0x46, 0xFF, 0xF7, 0xD1, 0xFD, 0x48, 0xB1, 0x28, 0x78, 0x80, 0x07, + 0x01, 0xD5, 0x28, 0x79, 0x01, 0xE0, 0x68, 0x69, 0x00, 0x78, 0x00, 0x07, + 0x00, 0xD4, 0x03, 0x24, 0x20, 0x46, 0xF0, 0xBD, 0x70, 0xB5, 0x06, 0x46, + 0x0D, 0x46, 0x01, 0x24, 0x08, 0x46, 0x01, 0xF0, 0x1F, 0xFE, 0x30, 0xB1, + 0x02, 0x46, 0x00, 0x23, 0x29, 0x46, 0x30, 0x46, 0xFF, 0xF7, 0x64, 0xFD, + 0x04, 0x46, 0x20, 0x46, 0x70, 0xBD, 0x70, 0xB5, 0x00, 0x25, 0x10, 0xB1, + 0x09, 0xB1, 0x00, 0x22, 0x1D, 0xE0, 0x40, 0xF6, 0x07, 0x40, 0x70, 0xBD, + 0x04, 0x88, 0xE3, 0x07, 0x14, 0xD1, 0x83, 0x78, 0xC6, 0x78, 0x03, 0xEB, + 0x06, 0x23, 0x9B, 0xB2, 0xA3, 0xF6, 0x02, 0x13, 0xB3, 0xF5, 0x00, 0x53, + 0x0A, 0xD0, 0x03, 0x2B, 0x08, 0xD0, 0xA3, 0x07, 0x06, 0xD5, 0x03, 0x7E, + 0x13, 0xF0, 0x70, 0x0F, 0x02, 0xD0, 0x40, 0xF6, 0x05, 0x45, 0x04, 0xE0, + 0x1D, 0xB9, 0x1C, 0x30, 0x52, 0x1C, 0x8A, 0x42, 0xE2, 0xDB, 0x28, 0x46, + 0x70, 0xBD, 0xF0, 0xB5, 0x8D, 0xB0, 0x05, 0x46, 0x00, 0x20, 0x0A, 0x90, + 0x0B, 0x90, 0x0C, 0x46, 0xCF, 0x79, 0x01, 0x21, 0x28, 0x46, 0xFF, 0xF7, + 0x83, 0xFF, 0x06, 0x22, 0x0A, 0xA9, 0x05, 0xF1, 0x13, 0x00, 0x21, 0xF4, + 0xA1, 0xF6, 0x08, 0xB1, 0x00, 0x26, 0x00, 0xE0, 0x01, 0x26, 0x55, 0xF8, + 0x13, 0x0F, 0x08, 0x90, 0xA8, 0x88, 0xAD, 0xF8, 0x24, 0x00, 0x20, 0x7A, + 0xFC, 0xF7, 0xBE, 0xFB, 0x20, 0x78, 0x60, 0xB1, 0x04, 0xF1, 0x0C, 0x01, + 0x60, 0x7A, 0xCD, 0xE9, 0x00, 0x01, 0x21, 0x7A, 0x08, 0xAB, 0x3A, 0x46, + 0x30, 0x46, 0x03, 0xF0, 0x28, 0xFC, 0x0D, 0xB0, 0xF0, 0xBD, 0xA0, 0x8A, + 0x04, 0xAD, 0x63, 0x8B, 0x22, 0x8B, 0xE1, 0x8A, 0x85, 0xE8, 0x0F, 0x00, + 0x63, 0x8A, 0x22, 0x8A, 0x21, 0x7A, 0x08, 0xA8, 0x8D, 0xE8, 0x0F, 0x00, + 0xE1, 0x89, 0xA0, 0x89, 0x3B, 0x46, 0x32, 0x46, 0x03, 0xF0, 0x8F, 0xFB, + 0xE9, 0xE7, 0x00, 0x00, 0xF8, 0xB5, 0x16, 0x46, 0x04, 0x46, 0x0D, 0x46, + 0x0B, 0x46, 0x00, 0x90, 0x02, 0x22, 0x09, 0x49, 0x09, 0x48, 0xEF, 0xF7, + 0x9C, 0xDD, 0x20, 0x46, 0x00, 0xF0, 0x64, 0xF9, 0x00, 0x28, 0x07, 0xD0, + 0x01, 0xB0, 0x32, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0x23, + 0x02, 0xF0, 0xDC, 0xB8, 0xF8, 0xBD, 0x00, 0x00, 0x98, 0x49, 0xC0, 0x08, + 0x03, 0x38, 0x10, 0x21, 0x7C, 0xB5, 0x05, 0x46, 0x19, 0xB1, 0x88, 0x88, + 0xCE, 0x88, 0x4C, 0x88, 0x03, 0xE0, 0x52, 0xB1, 0x50, 0x88, 0x96, 0x88, + 0x14, 0x88, 0x28, 0x21, 0x03, 0x2C, 0x09, 0xD0, 0x05, 0x2C, 0x05, 0xD0, + 0x04, 0x2C, 0x17, 0xD0, 0x09, 0xE0, 0x40, 0xF6, 0x07, 0x40, 0x7C, 0xBD, + 0x02, 0x22, 0x00, 0xE0, 0x03, 0x22, 0x8D, 0xF8, 0x04, 0x20, 0x8D, 0xF8, + 0x05, 0x10, 0x01, 0xA9, 0x00, 0x91, 0x01, 0x46, 0x02, 0x23, 0x32, 0x46, + 0x28, 0x46, 0xF6, 0xF7, 0x70, 0xFE, 0x00, 0x28, 0xED, 0xD1, 0x69, 0x68, + 0x0C, 0x81, 0x7C, 0xBD, 0x01, 0x46, 0x32, 0x46, 0x28, 0x46, 0xF6, 0xF7, + 0x23, 0xFD, 0xF4, 0xE7, 0x2D, 0xE9, 0xFC, 0x5F, 0x82, 0x46, 0x09, 0xB1, + 0x4E, 0x88, 0x01, 0xE0, 0xD2, 0xB1, 0x16, 0x88, 0xDA, 0xF8, 0x04, 0x40, + 0x4F, 0xF0, 0x00, 0x0B, 0xA4, 0x1D, 0x01, 0x2E, 0x16, 0xD0, 0x89, 0xB3, + 0x31, 0xF8, 0x04, 0x8F, 0x88, 0x88, 0xB1, 0xF8, 0x02, 0x90, 0x10, 0x28, + 0x21, 0xD0, 0x8D, 0x68, 0x10, 0x27, 0x88, 0x88, 0xE0, 0x80, 0x3A, 0x46, + 0x29, 0x46, 0x04, 0xF1, 0x08, 0x00, 0x21, 0xF4, 0x4C, 0xF6, 0x29, 0xE0, + 0x40, 0xF6, 0x07, 0x40, 0xBD, 0xE8, 0xFC, 0x9F, 0x11, 0xB1, 0x88, 0x88, + 0xCA, 0x88, 0x01, 0xE0, 0x50, 0x88, 0x92, 0x88, 0x8D, 0xF8, 0x04, 0xB0, + 0x28, 0x21, 0x8D, 0xF8, 0x05, 0x10, 0x02, 0x21, 0x00, 0x91, 0x01, 0x46, + 0x01, 0xAB, 0x50, 0x46, 0xF6, 0xF7, 0x15, 0xFE, 0x19, 0xE0, 0x08, 0x89, + 0x8D, 0xF8, 0x04, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x05, 0x00, 0x01, 0xAD, + 0x02, 0x27, 0xD6, 0xE7, 0xFF, 0xE7, 0xD0, 0x88, 0xB2, 0xF8, 0x02, 0x80, + 0xB2, 0xF8, 0x04, 0x90, 0x95, 0x68, 0x10, 0x28, 0x0D, 0xD0, 0x10, 0x27, + 0x3B, 0x46, 0x4A, 0x46, 0x41, 0x46, 0x50, 0x46, 0x00, 0x95, 0xF6, 0xF7, + 0xB7, 0xFC, 0x00, 0x28, 0xCE, 0xD1, 0xA4, 0xF8, 0x04, 0xB0, 0x66, 0x80, + 0xCA, 0xE7, 0x02, 0x27, 0xF0, 0xE7, 0x00, 0x00, 0x00, 0xB5, 0x0E, 0x48, + 0x85, 0xB0, 0x25, 0x23, 0x0B, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xF7, 0xF7, + 0x3D, 0xFD, 0x00, 0x28, 0x0E, 0xD0, 0xBD, 0xF8, 0x00, 0x00, 0xB0, 0xF5, + 0xC0, 0x6F, 0x09, 0xD1, 0xBD, 0xF8, 0x06, 0x00, 0x08, 0xB1, 0x01, 0x21, + 0x00, 0xE0, 0x00, 0x21, 0x9D, 0xF8, 0x05, 0x00, 0xF6, 0xF7, 0x66, 0xFF, + 0x05, 0xB0, 0x00, 0xBD, 0xCD, 0xAB, 0x82, 0x00, 0x94, 0x77, 0x20, 0x00, + 0x70, 0xB5, 0x86, 0xB0, 0x04, 0x46, 0x11, 0xB1, 0x40, 0xF6, 0x0D, 0x40, + 0x01, 0xE0, 0x43, 0xF4, 0x80, 0x60, 0x00, 0x25, 0x0C, 0x2A, 0x11, 0xD0, + 0x08, 0xDC, 0x04, 0x2A, 0x0E, 0xD0, 0x06, 0x2A, 0x0C, 0xD0, 0x08, 0x2A, + 0x0A, 0xD0, 0x0A, 0x2A, 0x45, 0xD1, 0x07, 0xE0, 0x10, 0x2A, 0x05, 0xD0, + 0x12, 0x2A, 0x03, 0xD0, 0x16, 0x2A, 0x01, 0xD0, 0x18, 0x2A, 0x3C, 0xD1, + 0x61, 0x68, 0x0A, 0x89, 0x0A, 0xB3, 0x6F, 0xF4, 0x80, 0x43, 0x13, 0x44, + 0x05, 0x2B, 0x04, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x0B, 0x0B, 0x21, 0x27, + 0x30, 0x00, 0x00, 0x95, 0x01, 0x95, 0x02, 0x95, 0x21, 0x8E, 0x00, 0x23, + 0x02, 0xF0, 0x8C, 0xFD, 0x27, 0xE0, 0x4A, 0x89, 0x04, 0x2A, 0x0D, 0xD0, + 0x03, 0x2A, 0x0B, 0xD0, 0x01, 0x23, 0xCD, 0xE9, 0x01, 0x53, 0x0C, 0x31, + 0xCD, 0xE9, 0x03, 0x15, 0x00, 0x95, 0x21, 0x8E, 0x00, 0x23, 0xFF, 0xF7, + 0xD3, 0xFC, 0x16, 0xE0, 0x01, 0x95, 0x02, 0x95, 0x03, 0x95, 0x04, 0x95, + 0xF4, 0xE7, 0x4B, 0x89, 0x21, 0x8E, 0x01, 0x22, 0xF9, 0xF7, 0xD2, 0xFC, + 0x0B, 0xE0, 0x08, 0x4A, 0x00, 0x95, 0x01, 0x95, 0x21, 0x8E, 0x00, 0x23, + 0x12, 0x78, 0xF9, 0xF7, 0x57, 0xFC, 0x02, 0xE0, 0x21, 0x8E, 0xF9, 0xF7, + 0x55, 0xFF, 0x60, 0x68, 0x05, 0x81, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00, + 0x48, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xF6, 0xF7, 0xE8, 0xFB, + 0x00, 0x28, 0x03, 0xD1, 0x62, 0x68, 0x44, 0xF2, 0x05, 0x01, 0x11, 0x81, + 0x10, 0xBD, 0x70, 0xB5, 0x84, 0x68, 0x15, 0x46, 0x61, 0xB1, 0x08, 0x46, + 0xFF, 0xF7, 0xC3, 0xFD, 0x03, 0x00, 0x07, 0xD0, 0x2A, 0x46, 0x18, 0x21, + 0x20, 0x68, 0xF6, 0xF7, 0xB3, 0xFB, 0x00, 0x20, 0x20, 0x81, 0x70, 0xBD, + 0x20, 0x68, 0xF6, 0xF7, 0x01, 0xFC, 0xF8, 0xE7, 0x2D, 0xE9, 0xF0, 0x41, + 0x80, 0x46, 0x00, 0x24, 0x0E, 0x4D, 0x0F, 0x4E, 0x11, 0xE0, 0xC4, 0xEB, + 0xC4, 0x01, 0x68, 0x68, 0x01, 0xEB, 0x04, 0x11, 0x00, 0xEB, 0x81, 0x07, + 0x78, 0x78, 0x30, 0xB1, 0x06, 0x22, 0x41, 0x46, 0x07, 0xF1, 0x13, 0x00, + 0x21, 0xF4, 0x0E, 0xF5, 0x40, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x96, 0xF8, + 0x98, 0x01, 0xA0, 0x42, 0xE9, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x38, 0x46, 0xFB, 0xE7, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x70, 0xB5, 0x10, 0x49, 0x03, 0x46, 0x00, 0x20, 0x4A, 0x68, 0x0F, 0x49, + 0x91, 0xF8, 0x98, 0x41, 0x0E, 0xE0, 0xC0, 0xEB, 0xC0, 0x01, 0x01, 0xEB, + 0x00, 0x11, 0x02, 0xEB, 0x81, 0x01, 0x4D, 0x78, 0x25, 0xB1, 0x0D, 0x8E, + 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, + 0x84, 0x42, 0xEE, 0xD8, 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xEF, 0xF7, + 0x16, 0xDC, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x7C, 0x4E, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, + 0x38, 0xB5, 0x04, 0x46, 0x03, 0x78, 0x01, 0x22, 0x19, 0x49, 0x1A, 0x48, + 0xEF, 0xF7, 0x03, 0xDC, 0x01, 0x21, 0x20, 0x46, 0xF6, 0xF7, 0x39, 0xFF, + 0xA0, 0x68, 0x00, 0x25, 0xB0, 0xB1, 0x00, 0x6B, 0x30, 0xB1, 0x4F, 0xF4, + 0x53, 0x72, 0x14, 0x49, 0xF7, 0xF7, 0x78, 0xFA, 0xA0, 0x68, 0x05, 0x63, + 0xA0, 0x68, 0x05, 0x81, 0xA0, 0x68, 0xC0, 0x79, 0x40, 0xB1, 0x23, 0x46, + 0x00, 0x22, 0x01, 0x21, 0x03, 0x20, 0x00, 0x95, 0x02, 0xF0, 0x54, 0xFC, + 0xA0, 0x68, 0xC5, 0x71, 0x01, 0x21, 0x20, 0x46, 0x00, 0xF0, 0x14, 0xF8, + 0x00, 0x20, 0x60, 0x76, 0x94, 0xF8, 0x2E, 0x00, 0x00, 0x28, 0x05, 0xD1, + 0x00, 0x22, 0x21, 0x46, 0x10, 0x46, 0xFF, 0xF7, 0x41, 0xFD, 0x65, 0x70, + 0x38, 0xBD, 0x00, 0x00, 0x60, 0x4E, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, + 0x09, 0xAD, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xC0, 0x69, 0x00, 0x28, + 0x0B, 0xD0, 0x41, 0xB1, 0x94, 0xF8, 0x20, 0x10, 0xC9, 0x07, 0x04, 0xD0, + 0x40, 0xF6, 0x99, 0x02, 0x02, 0x49, 0xF7, 0xF7, 0x41, 0xFA, 0x00, 0x20, + 0xE0, 0x61, 0x10, 0xBD, 0x19, 0xAD, 0x82, 0x00, 0x01, 0x46, 0x00, 0x20, + 0x0A, 0x88, 0x93, 0x07, 0x01, 0xD5, 0x08, 0x1D, 0x70, 0x47, 0x52, 0x07, + 0xFC, 0xD4, 0x48, 0x69, 0x70, 0x47, 0x00, 0x00, 0xF8, 0xB5, 0x16, 0x46, + 0x00, 0x25, 0x40, 0xB9, 0x6B, 0x46, 0x42, 0xF6, 0x02, 0x12, 0x01, 0x20, + 0x00, 0xF0, 0xB8, 0xF8, 0xC8, 0xB1, 0xBD, 0xF8, 0x00, 0x10, 0xB1, 0xB1, + 0x0C, 0x48, 0x00, 0x23, 0x82, 0x69, 0x0C, 0x48, 0x90, 0xF8, 0xAC, 0x01, + 0x0D, 0xE0, 0x94, 0x68, 0x04, 0xEB, 0xC3, 0x04, 0x27, 0x78, 0x3F, 0xB1, + 0xA7, 0x88, 0x8F, 0x42, 0x04, 0xD1, 0x67, 0x88, 0xB7, 0x42, 0x01, 0xD1, + 0xE5, 0x88, 0x02, 0xE0, 0x5B, 0x1C, 0x98, 0x42, 0xEF, 0xDC, 0x28, 0x46, + 0xF8, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xF0, 0xB5, 0x0D, 0x4B, 0x00, 0x22, 0x9D, 0x69, 0x0C, 0x4B, 0x93, 0xF8, + 0xAC, 0x41, 0x0E, 0xE0, 0xAB, 0x68, 0x03, 0xEB, 0xC2, 0x03, 0x1E, 0x78, + 0x46, 0xB1, 0x9E, 0x88, 0x8E, 0x42, 0x05, 0xD1, 0x5E, 0x88, 0x07, 0x8E, + 0xBE, 0x42, 0x01, 0xD1, 0x58, 0x78, 0xF0, 0xBD, 0x52, 0x1C, 0x94, 0x42, + 0xEE, 0xDC, 0x4F, 0xF0, 0xFF, 0x30, 0xF0, 0xBD, 0x98, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x81, 0x78, 0xC2, 0x78, 0x01, 0xEB, 0x02, 0x21, + 0x89, 0xB2, 0xA1, 0xF5, 0x20, 0x52, 0x03, 0x3A, 0x02, 0xD0, 0x4F, 0xF0, + 0xFF, 0x30, 0x70, 0x47, 0x01, 0x78, 0x89, 0x07, 0x01, 0xD5, 0x00, 0x79, + 0x70, 0x47, 0x40, 0x69, 0x00, 0x78, 0x70, 0x47, 0x2D, 0xE9, 0xF0, 0x4F, + 0x2B, 0x4F, 0x15, 0x46, 0x00, 0x24, 0xD7, 0xF8, 0x18, 0xC0, 0x2A, 0x4F, + 0x9B, 0x46, 0x02, 0x46, 0x6F, 0xF0, 0x01, 0x0A, 0x56, 0x46, 0x20, 0x46, + 0x23, 0x46, 0x4F, 0xF0, 0xFF, 0x39, 0x97, 0xF8, 0xAD, 0x71, 0x15, 0xE0, + 0xDC, 0xF8, 0x04, 0x40, 0x03, 0xEB, 0x43, 0x08, 0x04, 0xEB, 0x88, 0x04, + 0xB4, 0xF8, 0x02, 0x80, 0xB8, 0xF1, 0x00, 0x0F, 0x09, 0xD0, 0xD4, 0xF8, + 0x04, 0x80, 0x88, 0x45, 0x05, 0xD1, 0x02, 0xB3, 0xA8, 0x42, 0x01, 0xD1, + 0x4E, 0x46, 0x04, 0xE0, 0x40, 0x1C, 0x5B, 0x1C, 0x9F, 0x42, 0xE7, 0xDC, + 0x02, 0xB1, 0x00, 0x25, 0x56, 0x45, 0x25, 0xDD, 0x20, 0x89, 0x40, 0x1E, + 0xA8, 0x42, 0x21, 0xDD, 0x60, 0x68, 0xC5, 0xEB, 0xC5, 0x01, 0x00, 0xEB, + 0x81, 0x07, 0x38, 0x46, 0xFF, 0xF7, 0xBA, 0xFA, 0xC0, 0xB1, 0x60, 0x89, + 0x07, 0xF1, 0x1C, 0x06, 0x28, 0x44, 0xAB, 0xF8, 0x00, 0x00, 0x6D, 0x1C, + 0x07, 0xE0, 0x4E, 0x46, 0xE8, 0xE7, 0x30, 0x46, 0xFF, 0xF7, 0xAC, 0xFA, + 0x20, 0xB9, 0x6D, 0x1C, 0x1C, 0x36, 0x20, 0x89, 0xA8, 0x42, 0xF6, 0xDC, + 0x60, 0x89, 0x6D, 0x1E, 0x09, 0x99, 0x28, 0x44, 0x00, 0x26, 0x08, 0x80, + 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x00, 0x28, 0x00, 0xD0, 0x40, 0x89, 0x70, 0x47, + 0x2D, 0xE9, 0xF0, 0x4F, 0x07, 0x46, 0x99, 0x46, 0x16, 0x46, 0x88, 0x46, + 0x00, 0x24, 0x01, 0x20, 0x01, 0xF0, 0xEA, 0xFA, 0x2A, 0x49, 0x91, 0xF8, + 0xAD, 0x11, 0x81, 0x42, 0x4C, 0xDD, 0x29, 0x49, 0x00, 0xEB, 0x40, 0x00, + 0x89, 0x69, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x05, 0x68, 0x88, 0x98, 0xB3, + 0x41, 0x46, 0x00, 0x20, 0x01, 0xF0, 0xD8, 0xFA, 0xB5, 0xF8, 0x08, 0x80, + 0x80, 0x45, 0x3B, 0xDD, 0xD5, 0xF8, 0x04, 0xC0, 0xC0, 0xEB, 0xC0, 0x01, + 0x1C, 0xEB, 0x81, 0x04, 0x34, 0xD0, 0x00, 0x2F, 0x32, 0xD0, 0x02, 0xDD, + 0x4F, 0xF0, 0x01, 0x02, 0x01, 0xE0, 0x4F, 0xF0, 0xFF, 0x32, 0x10, 0x44, + 0x4F, 0xF4, 0x20, 0x57, 0x42, 0xF6, 0x01, 0x0A, 0x42, 0xF6, 0x03, 0x0B, + 0x20, 0xE0, 0xC0, 0xEB, 0xC0, 0x01, 0x0C, 0xEB, 0x81, 0x04, 0x21, 0x78, + 0xC9, 0x07, 0x18, 0xD1, 0xA1, 0x78, 0xE3, 0x78, 0x01, 0xEB, 0x03, 0x21, + 0x89, 0xB2, 0xB1, 0x42, 0x07, 0xD1, 0xB9, 0xF1, 0x00, 0x0F, 0x13, 0xD0, + 0x69, 0x89, 0x08, 0x44, 0xA9, 0xF8, 0x00, 0x00, 0x0E, 0xE0, 0xB9, 0x42, + 0x05, 0xD0, 0x51, 0x45, 0x03, 0xD0, 0xBE, 0x42, 0x03, 0xD0, 0x59, 0x45, + 0x01, 0xD1, 0x00, 0x24, 0x04, 0xE0, 0x10, 0x44, 0x00, 0x28, 0x01, 0xDB, + 0x80, 0x45, 0xDA, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x1F, 0xB5, 0xFF, 0xF7, + 0x4F, 0xFE, 0x00, 0x28, 0x09, 0xD0, 0x00, 0x21, 0x00, 0x91, 0x01, 0x91, + 0x02, 0x91, 0x0B, 0x46, 0x03, 0x91, 0x01, 0x22, 0x1E, 0x21, 0xF6, 0xF7, + 0x47, 0xF9, 0x1F, 0xBD, 0x70, 0xB5, 0x1C, 0x46, 0x15, 0x46, 0x0E, 0x46, + 0xFF, 0xF7, 0x3C, 0xFE, 0x20, 0xB1, 0x23, 0x46, 0x2A, 0x46, 0x31, 0x46, + 0x01, 0xF0, 0xAE, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x40, 0xF2, + 0x8A, 0x22, 0x01, 0x49, 0xF7, 0xF7, 0xE6, 0xB8, 0x56, 0xAC, 0x82, 0x00, + 0x30, 0xB5, 0x04, 0x46, 0x40, 0x88, 0x85, 0xB0, 0x04, 0x28, 0x04, 0xD1, + 0x20, 0x89, 0x80, 0x28, 0x01, 0xD1, 0xE0, 0x68, 0x40, 0xB1, 0x20, 0x88, + 0xFF, 0xF7, 0x1E, 0xFE, 0x02, 0x00, 0x2A, 0xD0, 0x50, 0x7E, 0x05, 0x28, + 0x06, 0xD1, 0x02, 0xE0, 0x40, 0xF6, 0x01, 0x40, 0x25, 0xE0, 0x50, 0x68, + 0x80, 0x79, 0x10, 0xB1, 0x40, 0xF6, 0x04, 0x40, 0x1F, 0xE0, 0x61, 0x88, + 0x40, 0xF6, 0x07, 0x40, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, 0x02, 0xD0, + 0x04, 0x29, 0x16, 0xD1, 0x02, 0xE0, 0xA1, 0x88, 0x99, 0xB1, 0x07, 0xE0, + 0xA1, 0x88, 0x81, 0xB1, 0xE1, 0x88, 0x00, 0x23, 0x49, 0xB1, 0x00, 0x21, + 0x8B, 0x42, 0x0A, 0xD8, 0x21, 0x46, 0x10, 0x46, 0xFF, 0xF7, 0x23, 0xFA, + 0x28, 0xB9, 0x05, 0xB0, 0x30, 0xBD, 0x01, 0x21, 0xF4, 0xE7, 0x40, 0xF6, + 0x08, 0x40, 0x00, 0x23, 0x62, 0x88, 0x19, 0x46, 0x01, 0x2A, 0x01, 0xD0, + 0x02, 0x2A, 0x01, 0xD1, 0x01, 0x23, 0x21, 0x1D, 0x00, 0x25, 0xCD, 0xE9, + 0x01, 0x53, 0xCD, 0xE9, 0x03, 0x15, 0x00, 0x95, 0x21, 0x88, 0x2B, 0x46, + 0xFF, 0xF7, 0x4A, 0xFA, 0xE5, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, + 0x8F, 0xB0, 0x1F, 0x46, 0x1C, 0xAB, 0x00, 0x26, 0x93, 0xE8, 0x03, 0x40, + 0x01, 0x23, 0x06, 0x96, 0x8D, 0xF8, 0x34, 0x30, 0xC0, 0xEB, 0xC0, 0x0C, + 0x6F, 0xF0, 0x1B, 0x08, 0x7B, 0x68, 0x08, 0xEB, 0x8C, 0x0C, 0x03, 0xEB, + 0x0C, 0x08, 0x7B, 0x89, 0x82, 0x46, 0x03, 0x44, 0x9B, 0xB2, 0x05, 0x93, + 0xCD, 0xE9, 0x07, 0x72, 0xAD, 0xF8, 0x2A, 0x00, 0xAD, 0xF8, 0x2E, 0x10, + 0x0F, 0x98, 0x09, 0x90, 0x10, 0x98, 0xAD, 0xF8, 0x2C, 0x00, 0xAD, 0xF8, + 0x30, 0xE0, 0xB7, 0xF8, 0x08, 0xC0, 0x00, 0x97, 0xCD, 0xE9, 0x01, 0xA3, + 0xCD, 0xE9, 0x03, 0xCE, 0x13, 0x46, 0x75, 0x1E, 0x40, 0xF6, 0x05, 0x44, + 0x0D, 0xF1, 0x1C, 0x0B, 0xB1, 0x46, 0x06, 0x22, 0x79, 0x49, 0x7A, 0x48, + 0xEF, 0xF7, 0xD5, 0xD9, 0x39, 0x89, 0x51, 0x45, 0x01, 0xDC, 0xA4, 0x1C, + 0x3D, 0xE0, 0x40, 0x46, 0xFF, 0xF7, 0x6C, 0xFE, 0x06, 0x90, 0x00, 0x28, + 0x37, 0xDB, 0x34, 0xDD, 0x10, 0xF0, 0x30, 0x0F, 0x31, 0xD0, 0x4F, 0xF0, + 0x00, 0x04, 0x08, 0xF1, 0x1C, 0x08, 0x10, 0x98, 0xFF, 0xF7, 0x8A, 0xFD, + 0x06, 0x00, 0x2A, 0xD0, 0x70, 0x7E, 0x05, 0x28, 0x27, 0xD1, 0x32, 0x8E, + 0x00, 0x20, 0x05, 0x99, 0xFF, 0xF7, 0x08, 0xFE, 0x05, 0x00, 0x20, 0xD4, + 0xD8, 0xF8, 0x18, 0x00, 0x40, 0xF6, 0x0F, 0x42, 0xC0, 0xF3, 0x01, 0x21, + 0x02, 0x29, 0x02, 0xD0, 0x03, 0x29, 0x0A, 0xD1, 0x04, 0xE0, 0xB1, 0x68, + 0x49, 0x79, 0xC9, 0x07, 0x04, 0xD0, 0x04, 0xE0, 0xB1, 0x68, 0x49, 0x79, + 0x89, 0x07, 0x00, 0xD4, 0x14, 0x46, 0x00, 0x0A, 0x00, 0x07, 0x08, 0xD5, + 0xB0, 0x68, 0x40, 0x79, 0x40, 0x07, 0x04, 0xD4, 0x4F, 0xF4, 0x41, 0x64, + 0x01, 0xE0, 0x40, 0xF6, 0x09, 0x44, 0x58, 0x48, 0x90, 0xF8, 0xB0, 0x01, + 0x80, 0x07, 0x10, 0xD5, 0x00, 0x2D, 0x0E, 0xDB, 0x06, 0x98, 0xC0, 0xF3, + 0x01, 0x10, 0x03, 0x28, 0x10, 0xD0, 0x06, 0x98, 0x80, 0x06, 0x01, 0xD5, + 0x02, 0x25, 0x16, 0xE0, 0x06, 0x98, 0xC0, 0x06, 0x01, 0xD5, 0x01, 0x25, + 0x0D, 0xE0, 0x03, 0x2D, 0x04, 0xD0, 0x01, 0x2D, 0x09, 0xD0, 0x02, 0x2D, + 0x0B, 0xD0, 0x0E, 0xE0, 0x1F, 0x98, 0x02, 0x28, 0x01, 0xD0, 0x01, 0x25, + 0x09, 0xE0, 0x02, 0x25, 0x07, 0xE0, 0x1F, 0x98, 0x02, 0x28, 0x03, 0xD0, + 0x03, 0xE0, 0x1F, 0x98, 0x01, 0x28, 0x00, 0xD1, 0x00, 0x25, 0x94, 0xBB, + 0x45, 0xB1, 0x40, 0xF6, 0x04, 0x41, 0xCF, 0x1E, 0x02, 0x2D, 0x06, 0xD0, + 0x00, 0x2D, 0x0C, 0xDA, 0x0C, 0x46, 0x4D, 0xE0, 0x40, 0xF6, 0x0A, 0x44, + 0x4A, 0xE0, 0xB0, 0x68, 0x40, 0xF6, 0x0C, 0x44, 0x90, 0xF8, 0x34, 0x00, + 0x00, 0x28, 0xF3, 0xD1, 0x10, 0xE0, 0x06, 0xF1, 0x44, 0x00, 0xFA, 0xF7, + 0xC0, 0xD8, 0x5F, 0xEA, 0x00, 0x09, 0x17, 0xD0, 0x02, 0x21, 0x89, 0xF8, + 0x04, 0x10, 0x09, 0xF1, 0x08, 0x00, 0x83, 0x46, 0x18, 0x22, 0x07, 0xA9, + 0x21, 0xF4, 0x98, 0xF2, 0x0D, 0xA9, 0xCD, 0xE9, 0x00, 0xB1, 0xA9, 0xB2, + 0x43, 0x46, 0x30, 0x46, 0x05, 0x9A, 0xFF, 0xF7, 0xFD, 0xF8, 0x00, 0x28, + 0x0C, 0xDA, 0x3C, 0x46, 0x0D, 0xE0, 0x23, 0xE0, 0x25, 0x49, 0x4F, 0xF0, + 0x00, 0x02, 0x01, 0xF1, 0x78, 0x01, 0x26, 0x48, 0xEF, 0xF7, 0x29, 0xD9, + 0x3C, 0x46, 0x19, 0xE0, 0x06, 0xDD, 0x40, 0xF6, 0x0E, 0x44, 0x4F, 0xF0, + 0x01, 0x00, 0x8D, 0xF8, 0x34, 0x00, 0x11, 0xE0, 0x02, 0x2D, 0x0E, 0xD1, + 0xB1, 0x68, 0x01, 0x20, 0x81, 0xF8, 0x34, 0x00, 0xB1, 0x68, 0xA1, 0xF8, + 0x36, 0xA0, 0xB1, 0x68, 0xDB, 0xF8, 0x04, 0x00, 0xC8, 0x63, 0xB1, 0x68, + 0xDB, 0xF8, 0x00, 0x00, 0x88, 0x63, 0x04, 0xB3, 0x13, 0x49, 0x23, 0x46, + 0x01, 0x22, 0xAC, 0x31, 0x14, 0x48, 0xEF, 0xF7, 0x06, 0xD9, 0x58, 0x46, + 0xAB, 0xF8, 0x0C, 0x40, 0xFF, 0xF7, 0x16, 0xFA, 0xB9, 0xF1, 0x00, 0x00, + 0x04, 0xD0, 0x01, 0x46, 0x06, 0xF1, 0x44, 0x00, 0xFA, 0xF7, 0x57, 0xD8, + 0x9D, 0xF8, 0x34, 0x00, 0x00, 0x28, 0x05, 0xD0, 0x40, 0xF2, 0x79, 0x22, + 0x0A, 0x49, 0x0F, 0x98, 0xF6, 0xF7, 0x72, 0xFF, 0x13, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0xB9, 0xF1, 0x00, 0x00, 0xEF, 0xD0, 0x01, 0x46, 0x06, 0xF1, + 0x50, 0x00, 0xE9, 0xE7, 0x58, 0x4B, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, + 0x64, 0x01, 0x20, 0x00, 0x00, 0x38, 0x10, 0x21, 0x3A, 0xAC, 0x82, 0x00, + 0xF8, 0xB5, 0x1D, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x06, 0x9C, 0xFF, 0xF7, + 0x9F, 0xFC, 0x28, 0xB1, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46, 0x00, 0x94, + 0x02, 0xF0, 0x6E, 0xFC, 0x00, 0x2C, 0x07, 0xD0, 0x20, 0x46, 0xBD, 0xE8, + 0xF8, 0x40, 0x40, 0xF2, 0x9B, 0x22, 0x02, 0x49, 0xF6, 0xF7, 0x46, 0xBF, + 0xF8, 0xBD, 0x00, 0x00, 0x70, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, + 0x9A, 0x46, 0x91, 0x46, 0x0E, 0x46, 0x83, 0x46, 0x00, 0x25, 0xDD, 0xF8, + 0x30, 0x80, 0xFF, 0xF7, 0x7F, 0xFC, 0x04, 0x00, 0x57, 0xD0, 0x60, 0x7E, + 0x01, 0xAF, 0x05, 0x28, 0x06, 0xD1, 0x02, 0x2E, 0x0D, 0xD0, 0x05, 0x2E, + 0x05, 0xD0, 0x60, 0x68, 0x80, 0x79, 0x40, 0xB1, 0x40, 0xF6, 0x04, 0x40, + 0x4B, 0xE0, 0xA1, 0x7E, 0x04, 0xF1, 0x13, 0x00, 0x0D, 0xF0, 0x04, 0xFA, + 0xB0, 0xB1, 0x40, 0xF6, 0x07, 0x40, 0xB9, 0xF1, 0x00, 0x0F, 0x40, 0xD0, + 0xAD, 0xF8, 0x08, 0xA0, 0xCD, 0xF8, 0x04, 0x80, 0xB8, 0xF8, 0x02, 0x10, + 0x09, 0x1D, 0xAD, 0xF8, 0x0A, 0x10, 0x01, 0x2E, 0x1D, 0xD0, 0x02, 0x2E, + 0x07, 0xD0, 0x03, 0x2E, 0x19, 0xD0, 0x05, 0x2E, 0x31, 0xD1, 0x02, 0xE0, + 0x40, 0xF6, 0x0F, 0x40, 0x2D, 0xE0, 0x04, 0xF1, 0x44, 0x00, 0xF9, 0xF7, + 0xF4, 0xDF, 0x05, 0x00, 0x17, 0xD0, 0x02, 0x2E, 0x01, 0xD0, 0x01, 0x20, + 0x00, 0xE0, 0x00, 0x20, 0x28, 0x71, 0xA5, 0xF8, 0x06, 0x90, 0xDD, 0xE9, + 0x01, 0x01, 0x05, 0xF1, 0x08, 0x07, 0xC7, 0xE9, 0x00, 0x01, 0x00, 0x97, + 0xB8, 0xF8, 0x00, 0x30, 0x4A, 0x46, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0x87, 0xF9, 0x18, 0xB1, 0x0D, 0xE0, 0x40, 0xF6, 0x01, 0x40, 0x0A, 0xE0, + 0x00, 0x2D, 0x04, 0xD0, 0x29, 0x46, 0x04, 0xF1, 0x50, 0x00, 0xF9, 0xF7, + 0xBA, 0xDF, 0xBD, 0xE8, 0xFE, 0x8F, 0x40, 0xF6, 0x08, 0x40, 0x03, 0x2E, + 0x13, 0xD0, 0x4B, 0x46, 0x32, 0x46, 0x59, 0x46, 0xF9, 0xF7, 0x94, 0xF8, + 0x25, 0xB1, 0x29, 0x46, 0x04, 0xF1, 0x44, 0x00, 0xF9, 0xF7, 0xA9, 0xDF, + 0x03, 0xB0, 0x40, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x40, 0xF2, 0x91, 0x52, + 0x06, 0x49, 0xF6, 0xF7, 0xC5, 0xBE, 0x00, 0x21, 0x00, 0x91, 0x0B, 0x46, + 0x01, 0x91, 0x04, 0x49, 0x0A, 0x78, 0x59, 0x46, 0xF9, 0xF7, 0x0A, 0xF8, + 0xE6, 0xE7, 0x00, 0x00, 0xB7, 0xAC, 0x82, 0x00, 0x48, 0x74, 0x20, 0x00, + 0x3E, 0xB5, 0x84, 0x68, 0x00, 0x22, 0x84, 0xF8, 0x34, 0x20, 0x02, 0x8E, + 0x20, 0x68, 0x02, 0x92, 0x00, 0xF1, 0x13, 0x03, 0xCD, 0xE9, 0x00, 0x31, + 0xD4, 0xE9, 0x0E, 0x12, 0x83, 0x7E, 0xE0, 0x8E, 0xF8, 0xF7, 0x74, 0xF9, + 0x3E, 0xBD, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0xC1, 0xFB, 0x00, 0x28, + 0x08, 0xD0, 0x0C, 0xB1, 0x00, 0x21, 0x00, 0xE0, 0x04, 0x21, 0x81, 0x74, + 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0xBA, 0xBA, 0x10, 0xBD, 0x70, 0xB5, + 0x04, 0x46, 0x40, 0xF6, 0x01, 0x45, 0xFE, 0xF7, 0xAB, 0xFE, 0x70, 0xB1, + 0xD4, 0xF8, 0x01, 0x10, 0xC0, 0xF8, 0x13, 0x10, 0xB4, 0xF8, 0x05, 0x10, + 0xA0, 0xF8, 0x17, 0x10, 0xE1, 0x79, 0x81, 0x76, 0x21, 0x46, 0x01, 0xF0, + 0xBD, 0xFA, 0x00, 0x28, 0x05, 0xD1, 0x29, 0x46, 0x60, 0x1C, 0xBD, 0xE8, + 0x70, 0x40, 0xF8, 0xF7, 0x69, 0xBB, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, + 0x02, 0x46, 0x0C, 0x46, 0xC8, 0x68, 0xC9, 0x88, 0x46, 0x18, 0x10, 0x46, + 0xFF, 0xF7, 0xB4, 0xFB, 0x1F, 0x4F, 0x05, 0x00, 0x35, 0xD0, 0xE8, 0x7E, + 0x00, 0xBB, 0x30, 0x46, 0xFF, 0xF7, 0x88, 0xF9, 0x90, 0xF0, 0x01, 0x0F, + 0x1A, 0xD1, 0xE8, 0x69, 0x28, 0xB1, 0x1A, 0x49, 0x00, 0x22, 0x38, 0x46, + 0xEE, 0xF7, 0xD7, 0xDF, 0x1D, 0xE0, 0xE8, 0x7E, 0x80, 0xB9, 0x30, 0x78, + 0x03, 0x28, 0x0D, 0xD0, 0x21, 0x46, 0x28, 0x46, 0x01, 0xF0, 0xF4, 0xFC, + 0x33, 0x78, 0xBD, 0xE8, 0xF0, 0x41, 0x11, 0x49, 0x0F, 0x48, 0x01, 0x22, + 0x3C, 0x39, 0x40, 0x1C, 0xEE, 0xF7, 0xC3, 0x9F, 0x0E, 0x49, 0xE0, 0x68, + 0x08, 0x60, 0xE3, 0x88, 0x22, 0x89, 0x28, 0x46, 0xE1, 0x68, 0x01, 0xF0, + 0x21, 0xFB, 0x00, 0x28, 0x0B, 0xD0, 0xE0, 0x68, 0xBD, 0xE8, 0xF0, 0x41, + 0x4F, 0xF4, 0xC3, 0x72, 0x07, 0x49, 0xF6, 0xF7, 0x33, 0xBE, 0x04, 0x49, + 0x00, 0x22, 0x2C, 0x31, 0xD1, 0xE7, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0x00, 0x38, 0x10, 0x21, 0x04, 0x4A, 0xC0, 0x08, 0x98, 0x77, 0x20, 0x00, + 0xE2, 0xAB, 0x82, 0x00, 0x2D, 0xE9, 0xFE, 0x43, 0x3C, 0x4F, 0x3D, 0x4E, + 0x90, 0x46, 0x0C, 0x46, 0x02, 0x28, 0x10, 0xD0, 0x21, 0x1D, 0x38, 0x46, + 0xEF, 0xF7, 0x64, 0xD9, 0xA1, 0x89, 0xE2, 0x7A, 0x00, 0x92, 0xCD, 0xE9, + 0x01, 0x01, 0x23, 0x88, 0x04, 0x22, 0x36, 0x49, 0x30, 0x46, 0xEE, 0xF7, + 0x8A, 0xDF, 0xBD, 0xE8, 0xFE, 0x83, 0x20, 0x1D, 0xFF, 0xF7, 0x2A, 0xFB, + 0x05, 0x46, 0x21, 0x1D, 0x38, 0x46, 0xEF, 0xF7, 0x4F, 0xD9, 0xA1, 0x89, + 0xE2, 0x7A, 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x01, 0x2C, 0x49, 0x23, 0x88, + 0x04, 0x22, 0xC4, 0x39, 0x30, 0x46, 0xEE, 0xF7, 0x74, 0xDF, 0x28, 0x4E, + 0xF6, 0x1E, 0x85, 0xB1, 0x27, 0x49, 0x6B, 0x7E, 0x01, 0x22, 0x40, 0x39, + 0xB0, 0x1C, 0xEE, 0xF7, 0x6A, 0xDF, 0x00, 0x20, 0x85, 0xF8, 0x2E, 0x00, + 0x20, 0x88, 0x58, 0xB1, 0xA5, 0xB3, 0x28, 0x46, 0x02, 0xF0, 0x1E, 0xFA, + 0x25, 0xE0, 0x1F, 0x49, 0x00, 0x22, 0x68, 0x39, 0x30, 0x46, 0xEE, 0xF7, + 0x5A, 0xDF, 0xF1, 0xE7, 0x15, 0xB1, 0x28, 0x46, 0x02, 0xF0, 0x12, 0xFA, + 0xE0, 0x7A, 0x01, 0x28, 0x15, 0xD1, 0x00, 0x2D, 0xC5, 0xD0, 0x46, 0x46, + 0xA2, 0x89, 0x43, 0x46, 0x00, 0x21, 0x28, 0x46, 0x01, 0xF0, 0x0E, 0xFF, + 0x00, 0x27, 0x07, 0xE0, 0x73, 0x88, 0x32, 0x88, 0x00, 0x21, 0x28, 0x46, + 0x02, 0xF0, 0x98, 0xF9, 0x36, 0x1D, 0x7F, 0x1C, 0xA0, 0x89, 0xB8, 0x42, + 0xF4, 0xDC, 0x00, 0x2D, 0xAF, 0xD0, 0xE8, 0x69, 0x00, 0x28, 0xAC, 0xD0, + 0xE8, 0x7E, 0x00, 0x28, 0xA9, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0xFE, 0x43, + 0x01, 0xF0, 0xBA, 0xBA, 0x03, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x43, + 0x04, 0x49, 0x00, 0x22, 0x14, 0x39, 0xEE, 0xF7, 0x26, 0x9F, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0x03, 0x38, 0x10, 0x21, 0x44, 0x4D, 0xC0, 0x08, + 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x01, 0x46, 0x0A, 0x48, 0xEF, 0xF7, + 0xE7, 0xD8, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x08, 0x49, 0x09, 0x48, + 0xEE, 0xF7, 0x11, 0xDF, 0x28, 0x46, 0xFF, 0xF7, 0xB3, 0xFA, 0x00, 0x28, + 0x04, 0xD0, 0x21, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x01, 0xF0, 0x2A, 0xBA, + 0x38, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x64, 0x49, 0xC0, 0x08, + 0x03, 0x38, 0x10, 0x21, 0xFE, 0xB5, 0x1D, 0x46, 0x14, 0x46, 0x0E, 0x46, + 0xFF, 0xF7, 0xC4, 0xFA, 0x00, 0x28, 0x16, 0xD0, 0x54, 0xEA, 0x05, 0x01, + 0x13, 0xD0, 0x41, 0x68, 0x31, 0xF8, 0x0A, 0x2F, 0xA2, 0xF5, 0x7F, 0x43, + 0xFF, 0x3B, 0x01, 0xD0, 0x64, 0xB1, 0x0F, 0xE0, 0x00, 0x21, 0x00, 0x91, + 0x01, 0x91, 0x02, 0x91, 0x01, 0x8E, 0x00, 0x23, 0x32, 0x46, 0x40, 0xF2, + 0x0A, 0x40, 0x01, 0xF0, 0xC1, 0xFF, 0xFE, 0xBD, 0x52, 0x1C, 0x14, 0x04, + 0x24, 0x0C, 0xFA, 0xD0, 0xAC, 0x42, 0xF8, 0xD8, 0xAD, 0xF8, 0x00, 0x60, + 0xAD, 0xF8, 0x02, 0x40, 0xAD, 0xF8, 0x04, 0x50, 0x4A, 0x88, 0x09, 0x1D, + 0xAD, 0xF8, 0x06, 0x20, 0x02, 0x91, 0x06, 0x2E, 0xEB, 0xD2, 0xDF, 0xE8, + 0x06, 0xF0, 0x03, 0x04, 0x04, 0x09, 0x09, 0x09, 0xE5, 0xE7, 0x6A, 0x46, + 0x00, 0x21, 0xFF, 0xF7, 0x69, 0xF9, 0xFE, 0xBD, 0x6A, 0x46, 0x00, 0x21, + 0xFF, 0xF7, 0x34, 0xF9, 0xFE, 0xBD, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, + 0xFF, 0xF7, 0x82, 0xFA, 0x03, 0x00, 0x03, 0xD0, 0x58, 0x7E, 0x05, 0x28, + 0x06, 0xD1, 0x02, 0xE0, 0x40, 0xF6, 0x08, 0x40, 0x1F, 0xE0, 0x58, 0x68, + 0x80, 0x79, 0x10, 0xB1, 0x40, 0xF6, 0x04, 0x40, 0x19, 0xE0, 0xA1, 0x88, + 0x40, 0xF6, 0x07, 0x40, 0xA9, 0xB1, 0xE2, 0x88, 0x91, 0x42, 0x12, 0xD8, + 0x61, 0x88, 0x06, 0x29, 0x0F, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x0E, 0x03, + 0x03, 0x09, 0x09, 0x09, 0x00, 0x22, 0x21, 0x46, 0x18, 0x46, 0xFF, 0xF7, + 0x3B, 0xF9, 0x04, 0xE0, 0x00, 0x22, 0x21, 0x46, 0x18, 0x46, 0xFF, 0xF7, + 0x05, 0xF9, 0x62, 0x88, 0x21, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF9, 0xF7, + 0x3C, 0xB9, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFF, 0xF7, 0x4E, 0xFA, + 0x00, 0x28, 0x05, 0xD0, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0xFF, 0xF7, 0x0B, 0xBA, 0x70, 0xBD, 0x00, 0x00, 0x38, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0xFF, 0xF7, 0x3F, 0xFA, 0xD8, 0xB1, 0x43, 0x7E, 0x05, 0x2B, + 0x02, 0xD1, 0x41, 0x68, 0x89, 0x79, 0x51, 0xB1, 0x40, 0x68, 0x02, 0x22, + 0x0D, 0x49, 0x80, 0x79, 0x00, 0x90, 0x0D, 0x48, 0xEE, 0xF7, 0x65, 0xDE, + 0x40, 0xF6, 0x04, 0x40, 0x0C, 0xE0, 0x25, 0xB1, 0x01, 0x2D, 0x02, 0xD0, + 0x40, 0xF6, 0x07, 0x40, 0x06, 0xE0, 0x29, 0x46, 0xFF, 0xF7, 0xDE, 0xF9, + 0x10, 0xB9, 0x38, 0xBD, 0x40, 0xF6, 0x08, 0x40, 0x21, 0x46, 0xBD, 0xE8, + 0x38, 0x40, 0xF9, 0xF7, 0x23, 0xB9, 0x00, 0x00, 0x34, 0x4C, 0xC0, 0x08, + 0x00, 0x38, 0x10, 0x21, 0xF0, 0xB5, 0x87, 0xB0, 0x0C, 0x46, 0x05, 0x46, + 0xDD, 0xE9, 0x0C, 0x61, 0x10, 0x20, 0x4F, 0xF4, 0x20, 0x57, 0xBB, 0x42, + 0x03, 0xD0, 0x42, 0xF6, 0x01, 0x0C, 0x63, 0x45, 0x19, 0xD1, 0x02, 0x20, + 0xAD, 0xF8, 0x00, 0x00, 0xBB, 0x42, 0x01, 0xD1, 0x01, 0x20, 0x00, 0xE0, + 0x00, 0x20, 0x8D, 0xF8, 0x02, 0x00, 0x01, 0x20, 0x01, 0x90, 0x09, 0x48, + 0xAD, 0xF8, 0x08, 0x40, 0xCD, 0xE9, 0x04, 0x10, 0xAD, 0xF8, 0x0A, 0x20, + 0x03, 0x96, 0x69, 0x46, 0x28, 0x46, 0x00, 0xF0, 0x0B, 0xFC, 0x00, 0x28, + 0x02, 0xD0, 0x80, 0xB2, 0x40, 0xEA, 0x04, 0x40, 0x07, 0xB0, 0xF0, 0xBD, + 0xCF, 0xEF, 0x80, 0x00, 0x10, 0xB5, 0x86, 0xB0, 0x4F, 0xF4, 0x80, 0x43, + 0xAD, 0xF8, 0x00, 0x30, 0xAD, 0xF8, 0x08, 0x10, 0x00, 0x23, 0x07, 0x49, + 0x8D, 0xF8, 0x02, 0x30, 0xCD, 0xE9, 0x04, 0x31, 0x02, 0x24, 0x01, 0x94, + 0xAD, 0xF8, 0x0A, 0x20, 0x03, 0x93, 0x69, 0x46, 0x00, 0xF0, 0xEC, 0xFB, + 0x06, 0xB0, 0x10, 0xBD, 0xFF, 0xEF, 0x80, 0x00, 0xFE, 0xB5, 0x44, 0x68, + 0x15, 0x46, 0x00, 0x26, 0x34, 0xF8, 0x08, 0x2F, 0xAD, 0xB2, 0x24, 0xF8, + 0x02, 0x69, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x34, 0x8B, 0xB2, 0x01, 0x8E, + 0x30, 0x46, 0x01, 0xF0, 0xD1, 0xFE, 0xFE, 0xBD, 0x2D, 0xE9, 0xFC, 0x41, + 0x1C, 0x46, 0x16, 0x46, 0x0F, 0x46, 0x08, 0x9D, 0xFF, 0xF7, 0xB2, 0xF9, + 0x00, 0x28, 0x11, 0xD0, 0xC7, 0x86, 0x06, 0x87, 0x44, 0x87, 0x85, 0x87, + 0x00, 0x21, 0xC1, 0x87, 0xA0, 0xF8, 0x40, 0x10, 0x01, 0x21, 0x80, 0xF8, + 0x32, 0x10, 0xCD, 0xE9, 0x00, 0x45, 0x00, 0x8E, 0x33, 0x46, 0x3A, 0x46, + 0xFA, 0xF7, 0x3D, 0xFC, 0xBD, 0xE8, 0xFC, 0x81, 0x2D, 0xE9, 0xFF, 0x41, + 0x2E, 0x4E, 0x05, 0x46, 0x90, 0x46, 0xB0, 0x89, 0x00, 0x24, 0x60, 0xB1, + 0x02, 0x2D, 0x01, 0xD0, 0x03, 0x2D, 0x05, 0xD1, 0x40, 0xF2, 0x35, 0x62, + 0x29, 0x49, 0x40, 0x46, 0xF6, 0xF7, 0x42, 0xFC, 0x40, 0xF6, 0x04, 0x41, + 0x37, 0xE0, 0xB5, 0x81, 0x06, 0x2D, 0x3E, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, + 0x3D, 0x03, 0x12, 0x1C, 0x2A, 0x39, 0x11, 0x46, 0x97, 0x78, 0x53, 0x78, + 0x88, 0x7B, 0x08, 0x32, 0x8D, 0xE8, 0x8D, 0x00, 0xCB, 0x7B, 0x0A, 0x78, + 0xC9, 0x88, 0xB8, 0xF8, 0x04, 0x00, 0x02, 0xF0, 0x0A, 0xFD, 0x19, 0xE0, + 0x0A, 0x46, 0x41, 0x46, 0x42, 0xF2, 0x08, 0x00, 0x02, 0xF0, 0xE8, 0xFC, + 0x07, 0x46, 0x40, 0xF2, 0x4E, 0x62, 0x08, 0xE0, 0x0A, 0x46, 0x41, 0x46, + 0x42, 0xF2, 0x09, 0x00, 0x02, 0xF0, 0xDE, 0xFC, 0x07, 0x46, 0x40, 0xF2, + 0x53, 0x62, 0x11, 0x49, 0x40, 0x46, 0xF6, 0xF7, 0x11, 0xFC, 0x02, 0xE0, + 0x01, 0x20, 0x0D, 0xE0, 0x07, 0x46, 0x8F, 0xB1, 0x00, 0x2C, 0x12, 0xD0, + 0x00, 0x20, 0xB0, 0x81, 0x21, 0x46, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x41, 0xF9, 0xF7, 0x38, 0xBB, 0x00, 0x20, 0x02, 0xF0, 0xB2, 0xFC, + 0xEE, 0xE7, 0x40, 0xF6, 0x07, 0x44, 0xEF, 0xE7, 0x4F, 0xF4, 0xB4, 0x74, + 0xEC, 0xE7, 0xBD, 0xE8, 0xFF, 0x81, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0xD2, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFC, 0x5F, 0x82, 0x46, 0xDD, 0xE9, + 0x0D, 0x86, 0x99, 0x46, 0x17, 0x46, 0x0D, 0x46, 0x40, 0x46, 0xDD, 0xF8, + 0x3C, 0xB0, 0xFF, 0xF7, 0x05, 0xF9, 0x04, 0x46, 0xB5, 0xF5, 0x9E, 0x7F, + 0x05, 0xD0, 0x54, 0xEA, 0x07, 0x00, 0x4F, 0xF0, 0x00, 0x07, 0x07, 0xD0, + 0x0C, 0xE0, 0x29, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x4F, 0xF4, 0xC1, 0x70, + 0xFB, 0xF7, 0x63, 0xBD, 0x00, 0x97, 0x68, 0x46, 0x01, 0x97, 0xFF, 0xF7, + 0xEF, 0xF8, 0x04, 0x46, 0x54, 0xEA, 0x05, 0x00, 0x0C, 0xD0, 0x00, 0x2C, + 0x43, 0xD0, 0xAD, 0xB1, 0x04, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xE4, 0xFE, + 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x01, 0xF0, 0x56, 0xB8, + 0xFE, 0xF7, 0xD8, 0xFB, 0x04, 0x00, 0xF0, 0xD1, 0x02, 0xB0, 0x00, 0x22, + 0xBD, 0xE8, 0xF0, 0x5F, 0x19, 0x49, 0x1A, 0x48, 0xEE, 0xF7, 0x2D, 0x9D, + 0xA4, 0xF8, 0x30, 0xA0, 0x0C, 0x98, 0xA0, 0x76, 0xD8, 0xF8, 0x00, 0x10, + 0xC4, 0xF8, 0x13, 0x10, 0xB8, 0xF8, 0x04, 0x00, 0xA4, 0xF8, 0x17, 0x00, + 0x84, 0xF8, 0x34, 0x90, 0xE6, 0x86, 0x26, 0x87, 0xA4, 0xF8, 0x3A, 0xB0, + 0x10, 0x98, 0xA0, 0x87, 0xE7, 0x87, 0xA4, 0xF8, 0x40, 0x70, 0x94, 0xF8, + 0x2F, 0x00, 0x48, 0xB1, 0x05, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xB4, 0xFE, + 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x5F, 0x00, 0x21, 0x00, 0xF0, 0xDE, 0xBF, + 0x02, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xAA, 0xFE, 0x20, 0x46, 0xBD, 0xE8, + 0xFC, 0x5F, 0x00, 0xF0, 0xBC, 0xBF, 0xBD, 0xE8, 0xFC, 0x9F, 0x00, 0x00, + 0x8C, 0x48, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x1F, 0xB5, 0x0C, 0x46, + 0xFF, 0xF7, 0xC0, 0xF8, 0x00, 0x28, 0x15, 0xD0, 0x0C, 0xB1, 0x01, 0x21, + 0x00, 0xE0, 0x00, 0x21, 0x90, 0xF8, 0x32, 0x20, 0x00, 0x2A, 0x0D, 0xD0, + 0xB0, 0xF8, 0x40, 0x20, 0xC3, 0x8F, 0x84, 0x8F, 0x00, 0x94, 0x03, 0x91, + 0xCD, 0xE9, 0x01, 0x32, 0x43, 0x8F, 0x02, 0x8F, 0xC1, 0x8E, 0x00, 0x8E, + 0x06, 0xF0, 0x76, 0xFE, 0x1F, 0xBD, 0x7C, 0xB5, 0x1D, 0x46, 0x14, 0x46, + 0x06, 0x9E, 0xFF, 0xF7, 0xA1, 0xF8, 0x00, 0x28, 0x0F, 0xD0, 0xC4, 0x86, + 0x04, 0x87, 0x45, 0x87, 0x86, 0x87, 0x00, 0x21, 0xC1, 0x87, 0xA0, 0xF8, + 0x40, 0x10, 0xCD, 0xE9, 0x00, 0x56, 0x23, 0x46, 0x00, 0x8E, 0x1A, 0x46, + 0x02, 0x21, 0xFA, 0xF7, 0x2E, 0xFB, 0x7C, 0xBD, 0x70, 0xB5, 0x0D, 0x46, + 0x06, 0x46, 0xFF, 0xF7, 0x89, 0xF8, 0x04, 0x00, 0x0A, 0xD0, 0x20, 0x8E, + 0x29, 0x46, 0x06, 0xF0, 0x00, 0xFE, 0x01, 0x00, 0x0B, 0xD0, 0x20, 0x8E, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x08, 0xB8, 0x31, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x40, 0xF6, 0x06, 0x40, 0xF8, 0xF7, 0x51, 0xBF, 0x70, 0xBD, + 0x70, 0xB5, 0x0D, 0x46, 0xFF, 0xF7, 0x70, 0xF8, 0x04, 0x00, 0x09, 0xD0, + 0x94, 0xF8, 0x32, 0x00, 0x18, 0xB9, 0x21, 0x8E, 0x28, 0x46, 0xF8, 0xF7, + 0x43, 0xFF, 0x00, 0x20, 0x84, 0xF8, 0x32, 0x00, 0x70, 0xBD, 0x00, 0x00, + 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x01, 0x46, 0x0C, 0x48, 0xEE, 0xF7, + 0x5F, 0xDE, 0x03, 0x46, 0x02, 0x22, 0x0B, 0x49, 0x0B, 0x48, 0x00, 0x94, + 0xEE, 0xF7, 0x89, 0xDC, 0x28, 0x46, 0xFF, 0xF7, 0x2B, 0xF8, 0x05, 0x00, + 0x09, 0xD0, 0x14, 0xB9, 0x02, 0x21, 0xFE, 0xF7, 0x25, 0xFE, 0x21, 0x46, + 0x28, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, 0x40, 0xBF, 0x38, 0xBD, + 0x00, 0x00, 0x30, 0x21, 0xD0, 0x48, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, + 0x70, 0xB5, 0x0D, 0x46, 0xFF, 0xF7, 0x3A, 0xF8, 0x04, 0x00, 0x13, 0xD0, + 0xA0, 0x7C, 0x38, 0xB1, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0x23, 0x00, 0x22, 0x00, 0xF0, 0xB0, 0xBF, 0x29, 0x46, 0x20, 0x46, + 0x00, 0xF0, 0x7C, 0xFF, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x04, 0x21, + 0xFE, 0xF7, 0xFE, 0xBD, 0x70, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x06, 0x46, 0x47, 0x48, 0x8C, 0xB0, 0x00, 0x25, 0x82, 0x89, 0x40, 0xF6, + 0x04, 0x44, 0x62, 0xB1, 0x02, 0x2E, 0x01, 0xD0, 0x03, 0x2E, 0x05, 0xD1, + 0x88, 0x68, 0x40, 0xF2, 0x7F, 0x62, 0x41, 0x49, 0xF6, 0xF7, 0xC6, 0xFA, + 0x00, 0x22, 0x21, 0x46, 0x5E, 0xE0, 0x80, 0x46, 0x86, 0x81, 0x06, 0x2E, + 0x6C, 0xD2, 0xDF, 0xE8, 0x06, 0xF0, 0x6B, 0x03, 0x2D, 0x3E, 0x5F, 0x64, + 0x98, 0xF8, 0x0F, 0x20, 0x40, 0x46, 0x00, 0x2A, 0xEE, 0xD1, 0x01, 0x22, + 0xC2, 0x73, 0x0A, 0x78, 0x02, 0x74, 0x4A, 0x7B, 0x88, 0xF8, 0x11, 0x20, + 0x08, 0x7E, 0x07, 0xAF, 0xCC, 0x7E, 0x8B, 0x7E, 0x4A, 0x7E, 0x87, 0xE8, + 0x1D, 0x00, 0x03, 0xAF, 0xCC, 0x7D, 0x8B, 0x7D, 0x4A, 0x7D, 0x01, 0xF1, + 0x0F, 0x00, 0x87, 0xE8, 0x1D, 0x00, 0x08, 0x7B, 0x8B, 0x7B, 0x4A, 0x7B, + 0x8D, 0xE8, 0x0D, 0x00, 0xD1, 0xE9, 0x01, 0x23, 0x48, 0x88, 0x0C, 0x78, + 0x01, 0x46, 0x20, 0x46, 0x02, 0xF0, 0x2F, 0xFC, 0x04, 0x46, 0x23, 0xE0, + 0x0F, 0x46, 0x89, 0x68, 0x38, 0x79, 0xCD, 0xE9, 0x00, 0x01, 0xFB, 0x78, + 0xBA, 0x78, 0x79, 0x78, 0x42, 0xF2, 0x37, 0x00, 0x02, 0xF0, 0x04, 0xFC, + 0x04, 0x46, 0x40, 0xF2, 0xA9, 0x62, 0xB8, 0x68, 0x0F, 0xE0, 0x0F, 0x46, + 0x89, 0x68, 0x38, 0x79, 0xCD, 0xE9, 0x00, 0x01, 0xFB, 0x78, 0xBA, 0x78, + 0x79, 0x78, 0x42, 0xF2, 0x38, 0x00, 0x02, 0xF0, 0xF3, 0xFB, 0x04, 0x46, + 0xB8, 0x68, 0x40, 0xF2, 0xB3, 0x62, 0x14, 0x49, 0xF6, 0xF7, 0x6C, 0xFA, + 0xDC, 0xB1, 0x00, 0x2D, 0x1C, 0xD0, 0x00, 0x21, 0xA8, 0xF8, 0x0C, 0x10, + 0x0A, 0x46, 0x29, 0x46, 0x0C, 0xB0, 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x41, + 0xF9, 0xF7, 0xCA, 0xBB, 0x48, 0x78, 0x8A, 0x1C, 0x01, 0x46, 0x01, 0x20, + 0x03, 0xE0, 0x48, 0x78, 0x8A, 0x1C, 0x01, 0x46, 0x00, 0x20, 0x02, 0xF0, + 0xA9, 0xFB, 0xBF, 0xE7, 0x40, 0xF6, 0x07, 0x45, 0xE5, 0xE7, 0x4F, 0xF4, + 0xB4, 0x75, 0xE2, 0xE7, 0x0C, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0x98, 0x77, 0x20, 0x00, 0xE9, 0xAC, 0x82, 0x00, 0x70, 0xB5, 0x05, 0x46, + 0x09, 0x48, 0x00, 0x21, 0xC4, 0x7B, 0xC1, 0x73, 0x14, 0xB1, 0x02, 0x2C, + 0x04, 0xD0, 0x05, 0xE0, 0x00, 0x7C, 0xFB, 0xF7, 0x89, 0xF8, 0x01, 0xE0, + 0xFA, 0xF7, 0x1A, 0xF9, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0xFA, 0xF7, 0xE8, 0xBE, 0x98, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x11, 0x4E, + 0x05, 0x46, 0x00, 0x24, 0xF0, 0x7B, 0x08, 0xB1, 0x05, 0x21, 0x12, 0xE0, + 0xF5, 0x73, 0x31, 0x74, 0x1D, 0xB1, 0x02, 0x2D, 0x04, 0xD0, 0x04, 0x24, + 0x08, 0xE0, 0x02, 0xF0, 0x40, 0xF9, 0x02, 0xE0, 0x08, 0x46, 0x02, 0xF0, + 0xBA, 0xFA, 0x48, 0xB1, 0x00, 0x2C, 0x0A, 0xD0, 0x00, 0x20, 0xF0, 0x73, + 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFA, 0xF7, 0xC6, 0xBE, + 0x4F, 0xF4, 0xB4, 0x74, 0xF4, 0xE7, 0x70, 0xBD, 0x98, 0x77, 0x20, 0x00, + 0x03, 0x4A, 0x01, 0x46, 0x00, 0x23, 0x90, 0x7B, 0x93, 0x73, 0xFA, 0xF7, + 0x27, 0xBF, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x70, 0xB5, 0x14, 0x4E, + 0x05, 0x46, 0x00, 0x24, 0xB0, 0x7B, 0x08, 0xB1, 0x05, 0x21, 0x17, 0xE0, + 0xB5, 0x73, 0x6D, 0xB1, 0x01, 0x2D, 0x03, 0xD0, 0x02, 0x2D, 0x04, 0xD0, + 0x04, 0x24, 0x0C, 0xE0, 0x42, 0xF2, 0x11, 0x00, 0x01, 0xE0, 0x42, 0xF2, + 0x12, 0x00, 0x02, 0xF0, 0x45, 0xFA, 0x01, 0xE0, 0x02, 0xF0, 0x0F, 0xF9, + 0x48, 0xB1, 0x00, 0x2C, 0x0A, 0xD0, 0x00, 0x20, 0xB0, 0x73, 0x21, 0x46, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFA, 0xF7, 0xFF, 0xBE, 0x4F, 0xF4, + 0xB4, 0x74, 0xF4, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x4C, 0x01, 0x46, 0xA0, 0x89, 0xF9, 0xF7, 0x01, 0xF9, + 0x00, 0x20, 0xA0, 0x81, 0x10, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x0B, 0x4C, 0x06, 0x46, 0x00, 0x25, 0xA0, 0x89, + 0x0F, 0x46, 0x01, 0x28, 0x08, 0xD1, 0xE0, 0x7B, 0x01, 0x28, 0x04, 0xD1, + 0x1E, 0xB9, 0x61, 0x7C, 0x20, 0x7C, 0xFA, 0xF7, 0x53, 0xFD, 0xE5, 0x73, + 0xA0, 0x89, 0x3A, 0x46, 0x31, 0x46, 0xF9, 0xF7, 0x19, 0xFB, 0xA5, 0x81, + 0xBD, 0xE8, 0xF0, 0x81, 0x98, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x46, + 0x00, 0x8E, 0x9B, 0xB2, 0x06, 0x99, 0xCD, 0xE9, 0x00, 0x30, 0x0A, 0x4C, + 0x13, 0x46, 0x2A, 0x46, 0x20, 0x68, 0x09, 0x1A, 0x89, 0xB2, 0xF7, 0xF7, + 0xEF, 0xFA, 0x00, 0x28, 0x08, 0xD0, 0x20, 0x68, 0x02, 0xB0, 0x40, 0xF6, + 0x2A, 0x32, 0xBD, 0xE8, 0x70, 0x40, 0x03, 0x49, 0xF6, 0xF7, 0x8E, 0xB9, + 0x7C, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x33, 0xAD, 0x82, 0x00, + 0x2D, 0xE9, 0xF8, 0x4F, 0x0F, 0x46, 0xDD, 0xE9, 0x0A, 0xA8, 0x84, 0x68, + 0x01, 0x21, 0x06, 0x46, 0x88, 0xF8, 0x00, 0x10, 0x34, 0xF8, 0x08, 0x0F, + 0x99, 0x46, 0x93, 0x46, 0x08, 0xB1, 0x0E, 0x25, 0x05, 0xE0, 0x39, 0x46, + 0xB0, 0x68, 0xFE, 0xF7, 0xA4, 0xFC, 0x05, 0x00, 0x05, 0xD0, 0xA8, 0xB2, + 0x40, 0xEA, 0x07, 0x45, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x8F, 0x44, 0xF2, + 0x04, 0x00, 0x20, 0x80, 0x39, 0x46, 0x01, 0x20, 0x00, 0xF0, 0xEA, 0xFA, + 0x0B, 0x49, 0x00, 0xEB, 0x40, 0x00, 0x4B, 0x46, 0x89, 0x69, 0x5A, 0x46, + 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00, 0x60, 0x60, 0x27, 0x81, 0x00, 0x27, + 0xA7, 0x81, 0xA4, 0xF8, 0x0A, 0x90, 0xCD, 0xF8, 0x00, 0xA0, 0x03, 0x21, + 0xB0, 0x68, 0x01, 0xF0, 0x61, 0xFA, 0x88, 0xF8, 0x00, 0x70, 0xDD, 0xE7, + 0x98, 0x77, 0x20, 0x00, 0x7C, 0xB5, 0x0D, 0x46, 0xCD, 0xE9, 0x00, 0x23, + 0x04, 0x46, 0x01, 0x8E, 0x05, 0x48, 0x2B, 0x46, 0x02, 0x78, 0x00, 0x20, + 0xF8, 0xF7, 0x8C, 0xFA, 0x61, 0x68, 0x00, 0x20, 0x08, 0x81, 0x01, 0x20, + 0x7C, 0xBD, 0x00, 0x00, 0x48, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x87, 0xB0, + 0x0C, 0x46, 0x05, 0x46, 0x04, 0x20, 0x0A, 0x99, 0x02, 0x2B, 0x28, 0xD1, + 0x08, 0x78, 0x49, 0x78, 0x4F, 0xF4, 0x20, 0x53, 0x00, 0xEB, 0x01, 0x20, + 0x80, 0xB2, 0x98, 0x42, 0x02, 0xD0, 0x59, 0x1C, 0x88, 0x42, 0x1B, 0xD1, + 0x01, 0x21, 0xAD, 0xF8, 0x00, 0x10, 0x98, 0x42, 0x01, 0xD1, 0x01, 0x20, + 0x00, 0xE0, 0x00, 0x20, 0x8D, 0xF8, 0x02, 0x00, 0x02, 0x20, 0x01, 0x90, + 0x00, 0x20, 0x03, 0x90, 0x04, 0x90, 0x09, 0x48, 0xAD, 0xF8, 0x08, 0x40, + 0x05, 0x90, 0xAD, 0xF8, 0x0A, 0x20, 0x69, 0x46, 0x28, 0x46, 0x00, 0xF0, + 0x6D, 0xF8, 0x10, 0xB9, 0x07, 0xB0, 0x30, 0xBD, 0x10, 0x20, 0x80, 0xB2, + 0x40, 0xEA, 0x04, 0x40, 0xF8, 0xE7, 0x00, 0x00, 0x53, 0xF2, 0x80, 0x00, + 0xF0, 0xB5, 0x87, 0xB0, 0x0E, 0x46, 0x0C, 0x9D, 0x44, 0xF2, 0x01, 0x04, + 0x02, 0x2B, 0x11, 0xD1, 0x29, 0x78, 0x6F, 0x78, 0x01, 0xEB, 0x07, 0x21, + 0x89, 0xB2, 0xA1, 0xF6, 0x02, 0x01, 0xB1, 0xF5, 0x00, 0x51, 0x02, 0xD0, + 0x01, 0x29, 0x05, 0xD1, 0x01, 0xE0, 0x05, 0x24, 0x00, 0xE0, 0x03, 0x24, + 0x00, 0x23, 0x1D, 0x46, 0xAD, 0xF8, 0x00, 0x40, 0x00, 0x21, 0x8D, 0xF8, + 0x02, 0x10, 0x02, 0x21, 0x01, 0x91, 0x09, 0x49, 0xAD, 0xF8, 0x08, 0x60, + 0xCD, 0xE9, 0x04, 0x51, 0xAD, 0xF8, 0x0A, 0x20, 0x03, 0x93, 0x69, 0x46, + 0x00, 0xF0, 0x36, 0xF8, 0x00, 0x28, 0x02, 0xD0, 0x80, 0xB2, 0x40, 0xEA, + 0x06, 0x40, 0x07, 0xB0, 0xF0, 0xBD, 0x00, 0x00, 0x85, 0xF2, 0x80, 0x00, + 0xF0, 0xB5, 0x44, 0x68, 0x85, 0xB0, 0x16, 0x46, 0x22, 0x89, 0x0A, 0x9F, + 0x00, 0x25, 0xA4, 0x1D, 0x05, 0x2A, 0x11, 0xD0, 0x6F, 0xF4, 0x80, 0x4C, + 0x12, 0xEB, 0x0C, 0x0F, 0x0F, 0xD1, 0xCD, 0xE9, 0x01, 0x71, 0x00, 0x93, + 0xCD, 0xE9, 0x03, 0x75, 0x71, 0x43, 0xCB, 0x1A, 0x01, 0x8E, 0xA2, 0x88, + 0x00, 0x20, 0xFE, 0xF7, 0x63, 0xFA, 0x0C, 0xE0, 0x06, 0x2E, 0x00, 0xD1, + 0x01, 0x21, 0x65, 0x80, 0xB3, 0xB2, 0xCD, 0xE9, 0x00, 0x37, 0x02, 0x94, + 0x8B, 0xB2, 0x01, 0x8E, 0x28, 0x46, 0x01, 0xF0, 0xFD, 0xFA, 0x65, 0x80, + 0x05, 0xB0, 0xF0, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F, 0x0C, 0x46, 0x85, 0x68, + 0x09, 0x88, 0x00, 0x27, 0x44, 0xF2, 0x01, 0x08, 0x08, 0x35, 0x89, 0xB0, + 0x81, 0x46, 0x41, 0x45, 0x0D, 0xD1, 0x20, 0x69, 0x01, 0x78, 0x40, 0x78, + 0x01, 0xEB, 0x00, 0x20, 0xE1, 0x68, 0x80, 0xB2, 0x02, 0x29, 0x04, 0xD1, + 0xA0, 0xF5, 0x24, 0x51, 0x02, 0x39, 0x00, 0xD1, 0x01, 0x27, 0xB9, 0xF8, + 0x2A, 0x00, 0x61, 0x68, 0x40, 0xF6, 0x9B, 0x33, 0x40, 0x1A, 0x81, 0xB2, + 0x07, 0x90, 0x51, 0x48, 0x4F, 0x4A, 0x00, 0x78, 0xF5, 0xF7, 0x86, 0xFF, + 0x4F, 0x49, 0x00, 0x28, 0xC8, 0x62, 0x7C, 0xD0, 0x07, 0x98, 0x28, 0x84, + 0x8A, 0x46, 0xC8, 0x6A, 0x08, 0xA9, 0xCD, 0xE9, 0x03, 0x10, 0x4F, 0xF0, + 0xFF, 0x32, 0x07, 0xAB, 0xCD, 0xE9, 0x05, 0x32, 0xD4, 0xE9, 0x03, 0x12, + 0x60, 0x89, 0x4F, 0xF0, 0x00, 0x0B, 0x8D, 0xE8, 0x07, 0x00, 0xA2, 0x78, + 0x21, 0x88, 0x04, 0xF1, 0x08, 0x03, 0xD9, 0xF8, 0x08, 0x00, 0x00, 0xF0, + 0x03, 0xFF, 0x06, 0x46, 0x07, 0x98, 0x00, 0x28, 0x34, 0xDA, 0x40, 0x42, + 0x07, 0x90, 0xA5, 0xF8, 0x00, 0x80, 0x07, 0x99, 0x69, 0x84, 0xD8, 0x46, + 0xA5, 0xF8, 0x24, 0x80, 0x08, 0x98, 0x40, 0x1E, 0x48, 0x43, 0x80, 0x1C, + 0xE8, 0x84, 0x29, 0x8C, 0x08, 0x1A, 0x28, 0x84, 0xA5, 0xF8, 0x0C, 0x80, + 0x21, 0x89, 0x01, 0x20, 0x00, 0xF0, 0xC0, 0xF9, 0xDA, 0xF8, 0x18, 0x10, + 0x00, 0xEB, 0x40, 0x00, 0x57, 0x46, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00, + 0x68, 0x60, 0x20, 0x89, 0x28, 0x81, 0x60, 0x89, 0x68, 0x81, 0xA0, 0x89, + 0xE8, 0x81, 0xE2, 0x68, 0x22, 0xB1, 0x05, 0xF1, 0x10, 0x00, 0x21, 0x69, + 0x20, 0xF4, 0xB5, 0xF2, 0xF8, 0x6A, 0xA8, 0x62, 0x48, 0x46, 0xC7, 0xF8, + 0x2C, 0x80, 0x01, 0xF0, 0x1F, 0xF9, 0x37, 0xE0, 0x08, 0x98, 0x00, 0x28, + 0x29, 0xDD, 0xCF, 0xB1, 0x00, 0x27, 0xDA, 0xF8, 0x2C, 0x50, 0x12, 0xE0, + 0x28, 0x78, 0x69, 0x78, 0x05, 0xF1, 0x02, 0x08, 0x00, 0xEB, 0x01, 0x20, + 0x81, 0xB2, 0xB9, 0xF8, 0x30, 0x20, 0x01, 0x20, 0xFE, 0xF7, 0xD8, 0xFD, + 0x01, 0x0A, 0x88, 0xF8, 0x00, 0x00, 0x2D, 0x1D, 0x88, 0xF8, 0x01, 0x10, + 0x7F, 0x1C, 0x08, 0x98, 0x87, 0x42, 0xE9, 0xDB, 0x5B, 0xEA, 0x06, 0x00, + 0x06, 0xD1, 0xDD, 0xE9, 0x07, 0x21, 0x65, 0x69, 0xDA, 0xF8, 0x2C, 0x30, + 0x48, 0x46, 0xA8, 0x47, 0x00, 0xE0, 0x16, 0xE0, 0xBB, 0xF1, 0x00, 0x0F, + 0x0A, 0xD1, 0xDA, 0xF8, 0x2C, 0x00, 0x55, 0x46, 0x30, 0xB1, 0x40, 0xF6, + 0xE7, 0x32, 0x08, 0x49, 0xF5, 0xF7, 0xE6, 0xFF, 0x00, 0x20, 0xE8, 0x62, + 0x1E, 0xB1, 0x21, 0x89, 0xB0, 0xB2, 0x40, 0xEA, 0x01, 0x46, 0x09, 0xB0, + 0x30, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, 0x11, 0x26, 0xF5, 0xE7, 0x00, 0x00, + 0x4A, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x2D, 0xE9, 0xF7, 0x4F, 0x84, 0xB0, 0x07, 0x46, 0x84, 0x68, 0x05, 0x98, + 0x4F, 0xF0, 0x00, 0x0A, 0x08, 0x34, 0x55, 0x46, 0x02, 0x28, 0x08, 0xD0, + 0x04, 0x28, 0x7D, 0xD0, 0x50, 0x78, 0x91, 0x78, 0x00, 0xEB, 0x01, 0x20, + 0x1F, 0xFA, 0x80, 0xF8, 0x09, 0xE0, 0x50, 0x78, 0x91, 0x78, 0x00, 0xEB, + 0x01, 0x20, 0x1F, 0xFA, 0x80, 0xF8, 0xD0, 0x78, 0x11, 0x79, 0x00, 0xEB, + 0x01, 0x2A, 0x20, 0x88, 0x08, 0xB1, 0x0E, 0x25, 0x7F, 0xE0, 0x78, 0x8D, + 0x40, 0xF6, 0xFC, 0x43, 0x40, 0x1E, 0x81, 0xB2, 0x01, 0x90, 0x41, 0x48, + 0x3F, 0x4A, 0x00, 0x78, 0xF5, 0xF7, 0xB6, 0xFE, 0x3F, 0x49, 0x00, 0x28, + 0xC8, 0x62, 0x73, 0xD0, 0x01, 0x20, 0x02, 0x90, 0x4F, 0xF0, 0x00, 0x0B, + 0x01, 0x98, 0x20, 0x84, 0x5E, 0x46, 0x89, 0x46, 0x01, 0xA8, 0x00, 0x90, + 0xD9, 0xF8, 0x2C, 0x30, 0x52, 0x46, 0x41, 0x46, 0xB8, 0x68, 0x00, 0xF0, + 0xC7, 0xFC, 0x05, 0x00, 0x40, 0xD1, 0x01, 0x98, 0x00, 0x28, 0x39, 0xDA, + 0x41, 0x1C, 0x02, 0xD0, 0x80, 0x1C, 0x27, 0xD0, 0x34, 0xE0, 0x05, 0x98, + 0x4F, 0xF0, 0x01, 0x0B, 0x02, 0x28, 0x02, 0xD0, 0x44, 0xF2, 0x02, 0x00, + 0x01, 0xE0, 0x44, 0xF2, 0x06, 0x00, 0x20, 0x80, 0x00, 0x20, 0x60, 0x84, + 0xA4, 0xF8, 0x0C, 0xA0, 0xA4, 0xF8, 0x08, 0x80, 0x41, 0x46, 0x01, 0x20, + 0x00, 0xF0, 0xF6, 0xF8, 0xD9, 0xF8, 0x18, 0x20, 0x00, 0xEB, 0x40, 0x01, + 0x38, 0x46, 0x52, 0x68, 0x02, 0xEB, 0x81, 0x01, 0x61, 0x60, 0xD9, 0xF8, + 0x2C, 0x10, 0xA1, 0x62, 0x00, 0x21, 0xC9, 0xF8, 0x2C, 0x10, 0x01, 0xF0, + 0x61, 0xF8, 0x0D, 0xE0, 0x3A, 0x8E, 0x41, 0x46, 0x01, 0x20, 0xFE, 0xF7, + 0x29, 0xFD, 0xD9, 0xF8, 0x2C, 0x20, 0x10, 0x70, 0xD9, 0xF8, 0x2C, 0x10, + 0x00, 0x0A, 0x48, 0x70, 0x02, 0x20, 0x01, 0x90, 0x02, 0x98, 0x76, 0x1C, + 0x86, 0x42, 0xB3, 0xDB, 0x5B, 0xEA, 0x05, 0x00, 0x0D, 0xD1, 0x05, 0x98, + 0x02, 0x28, 0x00, 0xE0, 0x18, 0xE0, 0xD9, 0xF8, 0x2C, 0x30, 0x01, 0x9A, + 0x01, 0xD0, 0x0B, 0x21, 0x00, 0xE0, 0x0D, 0x21, 0x38, 0x46, 0xF5, 0xF7, + 0x1A, 0xFA, 0xD9, 0xF8, 0x2C, 0x00, 0x4C, 0x46, 0x30, 0xB1, 0x40, 0xF6, + 0x46, 0x52, 0x06, 0x49, 0xF5, 0xF7, 0x32, 0xFF, 0x00, 0x20, 0xE0, 0x62, + 0x15, 0xB1, 0xA8, 0xB2, 0x40, 0xEA, 0x08, 0x45, 0x07, 0xB0, 0x28, 0x46, + 0xBD, 0xE8, 0xF0, 0x8F, 0x64, 0xAD, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x98, 0x77, 0x20, 0x00, 0xF0, 0xB5, 0x00, 0x27, 0x44, 0x68, 0x85, 0xB0, + 0xA4, 0x1D, 0x3E, 0x46, 0x3D, 0x46, 0x01, 0x29, 0x04, 0xD0, 0x02, 0x29, + 0x01, 0xD0, 0x00, 0x22, 0x02, 0xE0, 0x27, 0x89, 0x01, 0x26, 0xA5, 0x1D, + 0xCD, 0xE9, 0x02, 0x65, 0x00, 0x25, 0xCD, 0xE9, 0x00, 0x53, 0x04, 0x97, + 0xA6, 0x88, 0x01, 0x8E, 0x13, 0x46, 0x32, 0x46, 0x28, 0x46, 0xFE, 0xF7, + 0xBB, 0xF8, 0x65, 0x80, 0x05, 0xB0, 0xF0, 0xBD, 0x2D, 0xE9, 0xFF, 0x41, + 0x05, 0x46, 0xDD, 0xE9, 0x0A, 0x46, 0x1F, 0x46, 0x88, 0x46, 0x27, 0x48, + 0xEE, 0xF7, 0x44, 0xDA, 0x03, 0x97, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x64, + 0x03, 0x46, 0x05, 0x22, 0x23, 0x49, 0x24, 0x48, 0xEE, 0xF7, 0x6B, 0xD8, + 0x00, 0x2F, 0x12, 0xD1, 0x40, 0x46, 0xFE, 0xF7, 0x0B, 0xFC, 0x00, 0x28, + 0x0D, 0xD0, 0x80, 0x68, 0x00, 0x28, 0x0A, 0xD0, 0x00, 0x21, 0xED, 0x1E, + 0x06, 0x2D, 0x06, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x0C, 0x2D, 0x07, + 0x05, 0x28, 0x41, 0x71, 0x81, 0x71, 0xBD, 0xE8, 0xFF, 0x81, 0x41, 0x79, + 0x41, 0xF0, 0x04, 0x01, 0x41, 0x71, 0x86, 0x71, 0x84, 0xB1, 0x04, 0x2C, + 0x0E, 0xD0, 0x05, 0x2C, 0x10, 0xD0, 0x07, 0x2C, 0x01, 0xD0, 0x08, 0x2C, + 0xEF, 0xD1, 0x41, 0x79, 0x08, 0x2C, 0x41, 0xF0, 0x09, 0x01, 0x41, 0x71, + 0xE9, 0xD1, 0x41, 0xF0, 0x02, 0x01, 0x07, 0xE0, 0x41, 0x79, 0x41, 0xF0, + 0x01, 0x01, 0x03, 0xE0, 0x41, 0x79, 0x41, 0xF0, 0x01, 0x01, 0xF4, 0xE7, + 0x41, 0x71, 0xDC, 0xE7, 0x42, 0x79, 0x22, 0xF0, 0x04, 0x02, 0x42, 0x71, + 0x81, 0x71, 0x41, 0x79, 0x21, 0xF0, 0x03, 0x01, 0xF4, 0xE7, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0xA0, 0x4D, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x47, 0x0F, 0x46, 0x80, 0x46, 0x01, 0x46, 0x91, 0x46, + 0x00, 0x24, 0x40, 0xF6, 0x01, 0x46, 0x38, 0x46, 0xFE, 0xF7, 0x05, 0xFA, + 0x05, 0x00, 0x11, 0xD1, 0xFD, 0xF7, 0x06, 0xFF, 0x04, 0x00, 0x0C, 0xD0, + 0x67, 0x60, 0xA4, 0xF8, 0x08, 0x80, 0xA4, 0xF8, 0x0A, 0x90, 0x20, 0x46, + 0x00, 0xF0, 0x54, 0xFA, 0x20, 0xB9, 0xB5, 0x1D, 0x00, 0x20, 0x60, 0x80, + 0x00, 0xE0, 0x35, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, + 0xF7, 0xF7, 0x7B, 0xBD, 0x00, 0x23, 0x01, 0x46, 0x1A, 0x46, 0x18, 0x46, + 0xFE, 0xF7, 0x0C, 0xBD, 0xF0, 0xB5, 0x19, 0x4A, 0x17, 0x4E, 0x00, 0x23, + 0x92, 0xF8, 0xAD, 0x51, 0xA6, 0xF1, 0x1C, 0x02, 0x92, 0xF8, 0x31, 0x70, + 0x1A, 0xE0, 0x72, 0x68, 0x03, 0xEB, 0x43, 0x04, 0x02, 0xEB, 0x84, 0x02, + 0x54, 0x88, 0x94, 0xB1, 0x54, 0x89, 0x27, 0xB1, 0x8C, 0x42, 0x08, 0xD9, + 0x0D, 0xE0, 0x20, 0xB9, 0x11, 0xE0, 0x8C, 0x42, 0x03, 0xD3, 0x00, 0x28, + 0x00, 0xD0, 0x10, 0x88, 0xF0, 0xBD, 0xB2, 0xF8, 0x08, 0xC0, 0x64, 0x44, + 0x64, 0x1E, 0x8C, 0x42, 0xF1, 0xDA, 0x5B, 0x1C, 0x9D, 0x42, 0xE2, 0xDC, + 0x20, 0xB1, 0x28, 0x46, 0xF0, 0xBD, 0x50, 0x89, 0x08, 0x1A, 0xF0, 0xBD, + 0x4F, 0xF0, 0xFF, 0x30, 0xF0, 0xBD, 0x00, 0x00, 0xB4, 0x77, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, 0x8F, 0xB0, 0x89, 0x46, + 0x1A, 0x99, 0x06, 0x46, 0x00, 0x27, 0x85, 0x68, 0x01, 0x20, 0x08, 0x70, + 0x35, 0xF8, 0x08, 0x0F, 0x98, 0x46, 0x92, 0x46, 0x40, 0xB1, 0xB9, 0xF1, + 0x02, 0x0F, 0x04, 0xD0, 0xB9, 0xF1, 0x05, 0x0F, 0x01, 0xD0, 0x0E, 0x24, + 0xD4, 0xE0, 0x01, 0x27, 0x09, 0xF0, 0xFF, 0x00, 0x00, 0x90, 0xCD, 0xF8, + 0x30, 0x80, 0x0C, 0xAB, 0xB0, 0x68, 0x51, 0x46, 0x19, 0x9A, 0x01, 0xF0, + 0x73, 0xFA, 0x04, 0x00, 0x73, 0xD1, 0x0D, 0x90, 0x0C, 0x98, 0xA3, 0x46, + 0x00, 0x28, 0x03, 0xDA, 0x41, 0x1C, 0x02, 0xD0, 0x80, 0x1C, 0x40, 0xD0, + 0xCF, 0xE0, 0x27, 0xB1, 0x2C, 0x22, 0x29, 0x46, 0x01, 0xA8, 0x20, 0xF4, + 0xE5, 0xF0, 0x48, 0x46, 0xB9, 0xF1, 0x01, 0x0F, 0x0D, 0xD0, 0x02, 0x28, + 0x03, 0xD0, 0xB9, 0xF1, 0x05, 0x0F, 0x0D, 0xD1, 0x02, 0xE0, 0xA5, 0xF8, + 0x00, 0xB0, 0x09, 0xE0, 0xA5, 0xF8, 0x00, 0xB0, 0xA8, 0xF1, 0x0C, 0x08, + 0x04, 0xE0, 0x44, 0xF2, 0x03, 0x00, 0x28, 0x80, 0x01, 0x20, 0x0D, 0x90, + 0x51, 0x46, 0x01, 0x20, 0xFF, 0xF7, 0x7A, 0xFF, 0x00, 0xEB, 0x40, 0x01, + 0x66, 0x48, 0x42, 0x46, 0x80, 0x69, 0x40, 0x68, 0x00, 0xEB, 0x81, 0x00, + 0x68, 0x60, 0xA5, 0xF8, 0x08, 0xA0, 0xA5, 0xF8, 0x0C, 0xB0, 0x19, 0x98, + 0x00, 0x90, 0xB0, 0x68, 0x49, 0x46, 0x18, 0x9B, 0x00, 0xF0, 0xF2, 0xFE, + 0x1A, 0x99, 0x00, 0x2F, 0x81, 0xF8, 0x00, 0xB0, 0x04, 0xD0, 0x2C, 0x22, + 0x01, 0xA9, 0x28, 0x46, 0x20, 0xF4, 0xAC, 0xF0, 0x8C, 0xE0, 0x19, 0x98, + 0xB8, 0xF1, 0x02, 0x0F, 0x01, 0x78, 0x40, 0x78, 0x01, 0xEB, 0x00, 0x20, + 0x87, 0xB2, 0x0A, 0xD0, 0xB8, 0xF1, 0x01, 0x0F, 0x06, 0xD0, 0xCD, 0xF8, + 0x30, 0xB0, 0xB8, 0xF1, 0x02, 0x0F, 0x7E, 0xD9, 0x0D, 0x24, 0x63, 0xE0, + 0xFF, 0xB2, 0x00, 0x23, 0x42, 0xF6, 0x03, 0x02, 0x51, 0x46, 0x58, 0x1E, + 0xFE, 0xF7, 0x4C, 0xFC, 0xF0, 0xB3, 0xFE, 0xF7, 0xD3, 0xFB, 0xB9, 0x08, + 0x07, 0xD1, 0xC1, 0x06, 0x01, 0xD4, 0xF9, 0x07, 0x03, 0xD1, 0x80, 0x06, + 0x04, 0xD4, 0xB8, 0x07, 0x02, 0xD5, 0xC0, 0x24, 0x4C, 0xE0, 0x4D, 0xE0, + 0x3B, 0x46, 0x52, 0x46, 0x01, 0x21, 0x30, 0x46, 0x01, 0xF0, 0x78, 0xF9, + 0x00, 0x28, 0x02, 0xDA, 0x4F, 0xF0, 0x11, 0x04, 0x2A, 0xE0, 0x04, 0xDD, + 0xB1, 0x68, 0x4F, 0xF0, 0x01, 0x00, 0xC8, 0x71, 0x18, 0xE0, 0x51, 0x46, + 0x4F, 0xF0, 0x00, 0x00, 0xFF, 0xF7, 0x1A, 0xFF, 0x1F, 0xFA, 0x80, 0xF8, + 0x51, 0x46, 0x01, 0x20, 0xFF, 0xF7, 0x14, 0xFF, 0x34, 0x49, 0x80, 0xB2, + 0x00, 0xEB, 0x40, 0x00, 0x09, 0x6A, 0x01, 0xEB, 0x80, 0x00, 0x41, 0x68, + 0xC8, 0xEB, 0xC8, 0x00, 0x11, 0xF8, 0x20, 0x00, 0x80, 0x06, 0x0B, 0xD5, + 0xAD, 0xF8, 0x00, 0xA0, 0xAD, 0xF8, 0x02, 0x70, 0x6B, 0x46, 0x00, 0xE0, + 0x19, 0xE0, 0x01, 0x22, 0x11, 0x46, 0x30, 0x46, 0x00, 0xF0, 0xB6, 0xFE, + 0x28, 0x48, 0x90, 0xF8, 0xB0, 0x01, 0x40, 0x07, 0x0D, 0xD4, 0xB0, 0x68, + 0xC0, 0x79, 0x50, 0xB1, 0x5F, 0x46, 0x33, 0x46, 0x00, 0x22, 0x01, 0x21, + 0x03, 0x20, 0xCD, 0xF8, 0x00, 0xB0, 0x00, 0xF0, 0x4D, 0xFF, 0xB0, 0x68, + 0xC7, 0x71, 0xBC, 0xB1, 0x00, 0xE0, 0x0E, 0x24, 0xA5, 0xF8, 0x00, 0xB0, + 0xB9, 0xF1, 0x05, 0x0F, 0x25, 0xD0, 0x54, 0xB1, 0xCD, 0xE9, 0x00, 0x4A, + 0x4B, 0x46, 0x03, 0x22, 0x19, 0x49, 0x1A, 0x48, 0xED, 0xF7, 0xCD, 0xDE, + 0xA0, 0xB2, 0x40, 0xEA, 0x0A, 0x44, 0x0F, 0xB0, 0x20, 0x46, 0xBD, 0xE8, + 0xF0, 0x8F, 0x02, 0xE0, 0x0D, 0x98, 0x00, 0x28, 0xE8, 0xD1, 0xB9, 0xF1, + 0x01, 0x0F, 0xE5, 0xD1, 0xCD, 0xF8, 0x00, 0xB0, 0xCD, 0xF8, 0x04, 0xB0, + 0xCD, 0xF8, 0x08, 0xB0, 0x00, 0x23, 0x01, 0x22, 0x13, 0x21, 0x30, 0x46, + 0xCD, 0xF8, 0x0C, 0xB0, 0xF4, 0xF7, 0x80, 0xFD, 0xE5, 0xE7, 0x31, 0x8E, + 0x34, 0xB1, 0xA0, 0xB2, 0x40, 0xF4, 0x80, 0x60, 0x00, 0x22, 0xFA, 0xF7, + 0x12, 0xFD, 0xD1, 0xE7, 0x00, 0x22, 0x10, 0x46, 0xFA, 0xF7, 0x0D, 0xFD, + 0xD7, 0xE7, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x90, 0x4F, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, + 0x40, 0x68, 0x0A, 0x46, 0x21, 0x8E, 0x43, 0x89, 0x00, 0x20, 0xF7, 0xF7, + 0xD3, 0xFE, 0x62, 0x68, 0x00, 0x21, 0x11, 0x81, 0x10, 0xBD, 0x00, 0x00, + 0x2D, 0xE9, 0xF0, 0x47, 0x65, 0x4A, 0x66, 0x49, 0x10, 0x1F, 0xF5, 0xF7, + 0xD3, 0xFD, 0x00, 0x28, 0x7D, 0xD0, 0x62, 0x4F, 0x1C, 0x20, 0x63, 0x4E, + 0x38, 0x81, 0x07, 0xF1, 0x1C, 0x05, 0xBD, 0x61, 0x96, 0xF8, 0x78, 0x01, + 0x80, 0x07, 0x01, 0xD5, 0x00, 0x20, 0x00, 0xE0, 0x01, 0x20, 0x87, 0xF8, + 0x31, 0x00, 0x96, 0xF8, 0x98, 0x01, 0x5C, 0x21, 0x10, 0xFB, 0x01, 0xF1, + 0x53, 0x23, 0x5A, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xFD, 0xDB, 0x78, 0x60, + 0x18, 0xB9, 0x96, 0xF8, 0x98, 0x01, 0x00, 0x28, 0x7E, 0xD1, 0x96, 0xF8, + 0x98, 0x01, 0xA8, 0x46, 0x00, 0xEB, 0xC0, 0x00, 0x81, 0x00, 0x5B, 0x23, + 0x51, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xEC, 0xDB, 0xC8, 0xF8, 0x0C, 0x00, + 0x18, 0xB9, 0x96, 0xF8, 0x98, 0x01, 0x00, 0x28, 0x6C, 0xD1, 0x96, 0xF8, + 0x98, 0x01, 0x63, 0x23, 0x00, 0xEB, 0xC0, 0x00, 0xC1, 0x00, 0x49, 0x4A, + 0x00, 0x20, 0xF8, 0xF7, 0xDB, 0xDB, 0x28, 0x60, 0x10, 0xB9, 0x96, 0xF8, + 0x98, 0x01, 0xE8, 0xBB, 0x96, 0xF8, 0xAD, 0x01, 0x6A, 0x23, 0x00, 0xEB, + 0x40, 0x00, 0x81, 0x00, 0x41, 0x4A, 0x00, 0x20, 0xF8, 0xF7, 0xCC, 0xDB, + 0x68, 0x60, 0x10, 0xB9, 0x96, 0xF8, 0xAD, 0x01, 0x70, 0xBB, 0x96, 0xF8, + 0xAC, 0x01, 0x71, 0x23, 0xC1, 0x00, 0x3B, 0x4A, 0x00, 0x20, 0xF8, 0xF7, + 0xBF, 0xDB, 0xA8, 0x60, 0x10, 0xB9, 0x96, 0xF8, 0xAC, 0x01, 0x08, 0xBB, + 0x00, 0x24, 0xB1, 0x46, 0x43, 0xE0, 0xC4, 0xEB, 0xC4, 0x01, 0x78, 0x68, + 0x01, 0xEB, 0x04, 0x16, 0x4F, 0xF0, 0x08, 0x0C, 0x00, 0xF8, 0x26, 0x40, + 0x29, 0x68, 0x7A, 0x68, 0x04, 0xEB, 0xC4, 0x00, 0x0C, 0xEB, 0x86, 0x0C, + 0x01, 0xEB, 0xC0, 0x01, 0x42, 0xF8, 0x0C, 0x10, 0x79, 0x68, 0x2A, 0x68, + 0x01, 0xEB, 0x86, 0x01, 0x42, 0xF8, 0x30, 0x10, 0xD8, 0xF8, 0x0C, 0x10, + 0x01, 0xEB, 0x80, 0x01, 0x01, 0xE0, 0x20, 0xE0, 0x1E, 0xE0, 0x4F, 0xF0, + 0x04, 0x0C, 0x7A, 0x68, 0x0C, 0xEB, 0x86, 0x0C, 0x84, 0x23, 0x42, 0xF8, + 0x0C, 0x10, 0x79, 0x68, 0x01, 0xEB, 0x86, 0x02, 0xD8, 0xF8, 0x0C, 0x10, + 0x41, 0xF8, 0x20, 0x20, 0x99, 0xF8, 0xAB, 0x01, 0x1C, 0x4A, 0x41, 0x01, + 0x00, 0x20, 0xF8, 0xF7, 0x81, 0xDB, 0x0C, 0x21, 0x7A, 0x68, 0x01, 0xEB, + 0x86, 0x01, 0x50, 0x50, 0x28, 0xB9, 0x99, 0xF8, 0xAB, 0x01, 0x10, 0xB1, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x64, 0x1C, 0xE4, 0xB2, 0x99, 0xF8, + 0x98, 0x01, 0x4B, 0x46, 0xA0, 0x42, 0xB6, 0xD8, 0x93, 0xF8, 0xAD, 0x01, + 0x1C, 0x46, 0x00, 0xEB, 0x40, 0x00, 0x81, 0x00, 0x68, 0x68, 0x1F, 0xF4, + 0x85, 0xF7, 0x00, 0x20, 0x06, 0xE0, 0x69, 0x68, 0x00, 0xEB, 0x40, 0x02, + 0x21, 0xF8, 0x22, 0x00, 0x40, 0x1C, 0xC0, 0xB2, 0x94, 0xF8, 0xAD, 0x11, + 0x81, 0x42, 0xF4, 0xD8, 0x1E, 0x20, 0x87, 0xF8, 0x30, 0x00, 0x01, 0x20, + 0xDB, 0xE7, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x5D, 0x86, 0x81, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xD8, 0xAB, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x29, 0x49, 0x29, 0x4A, 0x01, 0x24, 0x91, 0xF8, 0x78, 0x11, 0x28, 0x4E, + 0x92, 0xF8, 0xAD, 0x51, 0x4F, 0xF0, 0x00, 0x03, 0x89, 0x07, 0x1A, 0x46, + 0x11, 0xD5, 0x33, 0xE0, 0x71, 0x68, 0x02, 0xEB, 0x42, 0x07, 0x01, 0xEB, + 0x87, 0x01, 0x81, 0x42, 0x08, 0xD0, 0x4F, 0x88, 0x37, 0xB1, 0x4F, 0x89, + 0x09, 0x89, 0x39, 0x44, 0x49, 0x1E, 0x99, 0x42, 0x00, 0xDD, 0x8B, 0xB2, + 0x52, 0x1C, 0x95, 0x42, 0xEC, 0xDC, 0x41, 0x89, 0x03, 0xF1, 0x01, 0x03, + 0x19, 0xB1, 0x99, 0x42, 0x03, 0xD2, 0x00, 0x24, 0x20, 0xE0, 0x43, 0x81, + 0x1E, 0xE0, 0x15, 0x4A, 0x00, 0x21, 0x1C, 0x3A, 0x82, 0xF8, 0x31, 0x10, + 0x18, 0xE0, 0x71, 0x68, 0x02, 0xEB, 0x42, 0x07, 0x01, 0xEB, 0x87, 0x01, + 0x81, 0x42, 0x08, 0xD0, 0x4F, 0x88, 0x37, 0xB1, 0x4F, 0x89, 0x09, 0x89, + 0x39, 0x44, 0x49, 0x1E, 0x99, 0x42, 0x00, 0xDD, 0x8B, 0xB2, 0x52, 0x1C, + 0x95, 0x42, 0xEC, 0xD8, 0x01, 0x21, 0x13, 0xB1, 0x19, 0x09, 0x09, 0x01, + 0x10, 0x31, 0x41, 0x81, 0x43, 0x89, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, + 0xED, 0xF7, 0x63, 0xDD, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xB4, 0x77, 0x20, 0x00, 0xFC, 0x4E, 0xC0, 0x08, + 0x03, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x05, 0x21, + 0xFD, 0xF7, 0xF6, 0xFE, 0x2C, 0xB1, 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0xF0, 0x6D, 0xB8, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0x21, 0x00, 0xF0, 0x19, 0xB8, 0x02, 0x8E, 0x81, 0x7E, 0x13, 0x30, + 0xF7, 0xF7, 0x80, 0xB8, 0x01, 0x22, 0x80, 0xF8, 0x2F, 0x20, 0xFD, 0xF7, + 0x50, 0xBF, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x13, 0x30, 0xF7, 0xF7, + 0xA9, 0xF8, 0x00, 0x2C, 0x04, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0xFE, 0xF7, 0x22, 0xB9, 0x70, 0xBD, 0x00, 0x00, 0x7F, 0xB5, 0x04, 0x46, + 0x00, 0xF1, 0x13, 0x05, 0x00, 0x29, 0x23, 0xDD, 0x94, 0xF8, 0x34, 0x00, + 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x7E, 0x8D, 0xF8, 0x07, 0x00, 0x1B, 0x48, + 0x6B, 0x46, 0x90, 0xF8, 0xAB, 0x01, 0x8D, 0xF8, 0x08, 0x00, 0xE0, 0x8E, + 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8F, 0xAD, 0xF8, 0x0C, 0x00, 0xA0, 0x8F, + 0xAD, 0xF8, 0x0E, 0x00, 0xD4, 0xF8, 0x13, 0x00, 0xCD, 0xF8, 0x01, 0x00, + 0xB4, 0xF8, 0x17, 0x00, 0xAD, 0xF8, 0x05, 0x00, 0x62, 0x8D, 0x21, 0x8E, + 0x28, 0x46, 0xF6, 0xF7, 0xB5, 0xFF, 0x7F, 0xBD, 0x94, 0xF8, 0x2F, 0x00, + 0x10, 0xB9, 0x0C, 0x48, 0x80, 0x7A, 0x28, 0xB1, 0x20, 0x8D, 0x17, 0x28, + 0x02, 0xD3, 0x20, 0x46, 0xF4, 0xF7, 0xD7, 0xFC, 0x21, 0x8E, 0x28, 0x46, + 0xF9, 0xF7, 0x3C, 0xFA, 0x00, 0x20, 0x02, 0x46, 0x01, 0x21, 0x00, 0x90, + 0x23, 0x46, 0x08, 0x46, 0x00, 0xF0, 0x56, 0xFD, 0x7F, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x98, 0x77, 0x20, 0x00, 0x0A, 0x46, 0x00, 0xF1, + 0x13, 0x01, 0x10, 0x46, 0xF7, 0xF7, 0x90, 0xB8, 0x70, 0xB5, 0x13, 0x4D, + 0x04, 0x46, 0x43, 0x7E, 0x01, 0x22, 0x10, 0x49, 0x28, 0x46, 0xED, 0xF7, + 0xD4, 0xDC, 0x60, 0x7E, 0x05, 0x28, 0x0D, 0xD0, 0x03, 0x28, 0x15, 0xD0, + 0x04, 0x28, 0x13, 0xD0, 0x0A, 0x49, 0x00, 0x22, 0x28, 0x31, 0x28, 0x46, + 0xED, 0xF7, 0xC7, 0xDC, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xF0, 0xBA, + 0x03, 0x21, 0x20, 0x46, 0xFD, 0xF7, 0x64, 0xFE, 0x20, 0x8E, 0xBD, 0xE8, + 0x70, 0x40, 0x13, 0x21, 0x01, 0xF0, 0x26, 0xBA, 0x70, 0xBD, 0x00, 0x00, + 0x10, 0x49, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, 0x70, 0xB5, 0x1C, 0x46, + 0x0B, 0x46, 0x05, 0x46, 0x32, 0xB1, 0x05, 0xF1, 0x13, 0x01, 0x18, 0x46, + 0xF7, 0xF7, 0x5C, 0xF8, 0x00, 0x2C, 0x0C, 0xD0, 0x00, 0x21, 0x28, 0x46, + 0xF4, 0xF7, 0xB0, 0xFF, 0x01, 0x21, 0x28, 0x46, 0xF4, 0xF7, 0xAC, 0xFF, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x8F, 0xB8, 0x70, 0xBD, + 0x70, 0xB5, 0x15, 0x46, 0x1C, 0x46, 0x01, 0x22, 0x48, 0xB1, 0x43, 0x7E, + 0x03, 0x2B, 0x06, 0xD0, 0x04, 0x2B, 0x04, 0xD0, 0xE2, 0xB2, 0x2B, 0x46, + 0xF4, 0xF7, 0x0E, 0xFA, 0x02, 0x46, 0x10, 0x46, 0x70, 0xBD, 0x92, 0xB2, + 0x00, 0xF0, 0xB4, 0xBE, 0x10, 0xB5, 0xFE, 0xF7, 0x4D, 0xF8, 0x00, 0x28, + 0x09, 0xD0, 0xC1, 0x69, 0x00, 0x29, 0x06, 0xD0, 0xC1, 0x7E, 0x00, 0x29, + 0x03, 0xD0, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x01, 0xB8, 0x10, 0xBD, + 0x10, 0xB5, 0xC1, 0x69, 0x04, 0x46, 0x00, 0x29, 0x0C, 0xD0, 0x07, 0x48, + 0x62, 0x8C, 0xA3, 0x8C, 0x01, 0x60, 0x20, 0x46, 0xFF, 0xF7, 0xD0, 0xFF, + 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFE, 0xF7, 0x96, 0xB8, + 0x10, 0xBD, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0x30, 0xB5, 0x55, 0x89, + 0x5C, 0x1E, 0x2C, 0x44, 0xA4, 0xB2, 0x68, 0xB1, 0x10, 0x89, 0x98, 0x42, + 0x0A, 0xD1, 0x07, 0x48, 0x13, 0x88, 0x90, 0xF8, 0xAD, 0x01, 0x40, 0x1E, + 0x83, 0x42, 0x01, 0xDA, 0xD0, 0x89, 0x08, 0xB9, 0x4F, 0xF6, 0xFF, 0x74, + 0x0C, 0x70, 0x20, 0x0A, 0x48, 0x70, 0x30, 0xBD, 0x64, 0x01, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x4F, 0x8B, 0xB0, 0x98, 0x46, 0xDD, 0xF8, 0x60, 0xA0, + 0x15, 0x46, 0x0F, 0x46, 0xDA, 0xF8, 0x00, 0x00, 0x07, 0x90, 0x01, 0x24, + 0x08, 0x46, 0xFF, 0xF7, 0x39, 0xFC, 0x06, 0x00, 0x6B, 0xD0, 0x02, 0x46, + 0x00, 0x23, 0x39, 0x46, 0x0B, 0x98, 0xFD, 0xF7, 0x7D, 0xFB, 0x04, 0x00, + 0x63, 0xD1, 0x30, 0x46, 0xFD, 0xF7, 0xCE, 0xFB, 0x10, 0xB1, 0xA0, 0x1E, + 0x07, 0x90, 0x5C, 0xE0, 0x30, 0x46, 0xFD, 0xF7, 0xC3, 0xFB, 0x4F, 0xF0, + 0x00, 0x0B, 0x4F, 0xF0, 0xFF, 0x39, 0x28, 0xB3, 0xCD, 0xE9, 0x00, 0x7B, + 0x02, 0xA9, 0xAD, 0xF8, 0x20, 0x70, 0x09, 0xAB, 0x58, 0x46, 0x81, 0xE8, + 0x09, 0x01, 0x07, 0xAA, 0xCD, 0xE9, 0x05, 0x29, 0x08, 0xAB, 0x00, 0x22, + 0x03, 0x21, 0x0B, 0x98, 0x00, 0xF0, 0x3C, 0xF9, 0x04, 0x00, 0x40, 0xD1, + 0x07, 0x98, 0x40, 0x1B, 0x80, 0x1E, 0x07, 0x90, 0x28, 0xD4, 0x00, 0x20, + 0x06, 0xE0, 0x42, 0x19, 0x02, 0xEB, 0x08, 0x01, 0x8A, 0x78, 0x08, 0xF8, + 0x00, 0x20, 0x40, 0x1C, 0x07, 0x99, 0x88, 0x42, 0xF5, 0xDB, 0x2E, 0xE0, + 0x77, 0x8A, 0x8F, 0xB9, 0x30, 0x88, 0x41, 0x07, 0x0C, 0xD4, 0x01, 0x07, + 0x0A, 0xD5, 0x80, 0x07, 0x01, 0xD5, 0x30, 0x1D, 0x00, 0xE0, 0x70, 0x69, + 0x1F, 0xF4, 0xDE, 0xF4, 0x80, 0xB2, 0x40, 0x1C, 0x87, 0xB2, 0x01, 0xE0, + 0xCD, 0xF8, 0x1C, 0x90, 0x07, 0x98, 0x40, 0x1C, 0x17, 0xD0, 0xBD, 0x42, + 0x05, 0xDB, 0xCD, 0xF8, 0x1C, 0xB0, 0x12, 0xDD, 0x4F, 0xF0, 0x07, 0x04, + 0x0F, 0xE0, 0x30, 0x46, 0xFE, 0xF7, 0x1C, 0xF8, 0x90, 0xB1, 0x07, 0x9A, + 0x79, 0x1B, 0x91, 0x42, 0x00, 0xDA, 0x07, 0x91, 0x07, 0x9A, 0x00, 0x2A, + 0x03, 0xDD, 0x41, 0x19, 0x40, 0x46, 0x1F, 0xF4, 0xDC, 0xF4, 0x07, 0x99, + 0xCA, 0xF8, 0x00, 0x10, 0x0F, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, + 0xCD, 0xF8, 0x1C, 0x90, 0xF5, 0xE7, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x86, 0x68, 0x8A, 0xB0, 0x15, 0x46, 0x00, 0x27, 0x06, 0xF1, 0x0C, 0x04, + 0x6F, 0xF4, 0x80, 0x48, 0x79, 0xB1, 0x08, 0x46, 0xFD, 0xF7, 0x09, 0xFD, + 0x03, 0x00, 0x7D, 0xD0, 0x31, 0x89, 0xA2, 0x88, 0x11, 0xEB, 0x08, 0x00, + 0x79, 0xD0, 0x01, 0x28, 0x78, 0xD0, 0x05, 0x28, 0x77, 0xD0, 0x00, 0x21, + 0xA5, 0xE0, 0x98, 0x88, 0x9B, 0x1D, 0xC1, 0x18, 0x33, 0x89, 0x00, 0x22, + 0x13, 0xEB, 0x08, 0x00, 0x1C, 0xD0, 0x01, 0x28, 0x02, 0xD0, 0x05, 0x28, + 0x34, 0xD1, 0x0A, 0xE0, 0xA0, 0x8B, 0xA8, 0x42, 0x01, 0xD2, 0x07, 0x90, + 0x00, 0xE0, 0x07, 0x95, 0x0B, 0x46, 0x30, 0x68, 0x0B, 0x21, 0x07, 0x9A, + 0x09, 0xE0, 0xA0, 0x8B, 0xA8, 0x42, 0x01, 0xD2, 0x07, 0x90, 0x00, 0xE0, + 0x07, 0x95, 0x0B, 0x46, 0x30, 0x68, 0x0D, 0x21, 0x07, 0x9A, 0xF4, 0xF7, + 0xE0, 0xFC, 0x85, 0xE0, 0x20, 0x8C, 0x30, 0xB1, 0xA8, 0x42, 0x00, 0xD0, + 0x01, 0x22, 0xE0, 0x8B, 0x02, 0x28, 0x02, 0xD0, 0x07, 0xE0, 0x25, 0x84, + 0xF9, 0xE7, 0xA0, 0x8B, 0xA8, 0x42, 0x00, 0xD2, 0x05, 0x46, 0xA8, 0x1C, + 0xE0, 0x83, 0x2A, 0xB1, 0x60, 0x8C, 0x80, 0x1E, 0x60, 0x84, 0xE0, 0x88, + 0xA0, 0x80, 0x13, 0xE0, 0x80, 0xB2, 0x80, 0x1E, 0xA8, 0x42, 0x01, 0xD0, + 0x0E, 0x23, 0xB1, 0xE7, 0x62, 0x8C, 0x60, 0x6A, 0x10, 0x44, 0x2A, 0x46, + 0x1F, 0xF4, 0x6D, 0xF4, 0x60, 0x8C, 0x28, 0x44, 0x60, 0x84, 0xA0, 0x8B, + 0x40, 0x1B, 0x80, 0xB2, 0xA0, 0x83, 0x07, 0x90, 0xA0, 0x88, 0xE1, 0x88, + 0x88, 0x42, 0x46, 0xD2, 0x40, 0x1C, 0xA0, 0x80, 0x63, 0x8C, 0x60, 0x6A, + 0x07, 0xAA, 0x18, 0x44, 0xCD, 0xE9, 0x04, 0x02, 0x08, 0xAB, 0x4F, 0xF0, + 0xFF, 0x31, 0x03, 0x93, 0x06, 0x91, 0xE0, 0x88, 0x04, 0xF1, 0x0C, 0x02, + 0x61, 0x89, 0x8D, 0xE8, 0x07, 0x00, 0x31, 0x89, 0x23, 0x1D, 0x00, 0x22, + 0x30, 0x46, 0x00, 0xF0, 0x65, 0xF8, 0x07, 0x98, 0x00, 0x28, 0x1C, 0xDA, + 0xA0, 0x8B, 0x03, 0xE0, 0x34, 0xE0, 0x2F, 0xE0, 0x2A, 0xE0, 0x2B, 0xE0, + 0x80, 0x1E, 0xA0, 0x83, 0x60, 0x8C, 0x80, 0x1C, 0x60, 0x84, 0xA1, 0x88, + 0x01, 0x20, 0xFF, 0xF7, 0x2B, 0xFB, 0x1B, 0x49, 0x00, 0xEB, 0x40, 0x00, + 0x89, 0x69, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x00, 0x20, 0x60, 0x30, 0x68, + 0x00, 0xF0, 0x9C, 0xFA, 0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x60, 0x8C, + 0xE1, 0x8B, 0xB0, 0xFB, 0xF1, 0xF0, 0x08, 0x99, 0x08, 0x44, 0x08, 0x90, + 0xE2, 0x8B, 0x63, 0x6A, 0x30, 0x68, 0x08, 0x99, 0xF4, 0xF7, 0x1E, 0xFC, + 0x0E, 0xE0, 0x60, 0x8C, 0xE1, 0x8B, 0xB0, 0xFB, 0xF1, 0xF0, 0xF2, 0xE7, + 0x0A, 0x21, 0x02, 0xE0, 0x0C, 0x21, 0x00, 0xE0, 0x08, 0x21, 0x30, 0x68, + 0xF4, 0xF7, 0x4A, 0xFA, 0x00, 0x2F, 0xDF, 0xD1, 0x00, 0x25, 0x35, 0x81, + 0x60, 0x6A, 0x00, 0x28, 0xDA, 0xD0, 0x40, 0xF6, 0x3B, 0x72, 0x03, 0x49, + 0xF5, 0xF7, 0x70, 0xF9, 0x65, 0x62, 0xD3, 0xE7, 0x98, 0x77, 0x20, 0x00, + 0x79, 0xAD, 0x82, 0x00, 0x01, 0x49, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, + 0xF4, 0x78, 0x20, 0x00, 0x02, 0x48, 0x00, 0x21, 0x81, 0x81, 0x81, 0x73, + 0x70, 0x47, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, 0xCA, 0x68, 0xC2, 0x61, + 0x0A, 0x89, 0x42, 0x84, 0xCA, 0x88, 0x82, 0x84, 0x89, 0x88, 0x01, 0x84, + 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x89, 0xB0, 0x4F, 0xF0, + 0xFF, 0x30, 0x05, 0x90, 0x00, 0x20, 0xDD, 0xE9, 0x1A, 0x59, 0x19, 0x99, + 0x1C, 0x9E, 0x02, 0x90, 0x04, 0x90, 0x83, 0x46, 0x82, 0x46, 0x08, 0x60, + 0x0C, 0x98, 0x01, 0x88, 0x01, 0x20, 0xFF, 0xF7, 0xC3, 0xFA, 0x03, 0x90, + 0x0C, 0x98, 0x01, 0x88, 0x00, 0x20, 0xFF, 0xF7, 0xBD, 0xFA, 0xFE, 0x49, + 0x91, 0xF8, 0xAD, 0x21, 0x03, 0x99, 0x8A, 0x42, 0x03, 0xDC, 0x0A, 0x20, + 0x0D, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xFA, 0x49, 0x89, 0x69, 0x4A, 0x68, + 0x03, 0x99, 0x01, 0xEB, 0x41, 0x01, 0x02, 0xEB, 0x81, 0x08, 0xB8, 0xF8, + 0x02, 0x10, 0x00, 0x29, 0x7D, 0xD0, 0xB8, 0xF8, 0x0A, 0x20, 0x16, 0x99, + 0x8A, 0x42, 0x78, 0xD8, 0xD8, 0xF8, 0x04, 0x10, 0xC0, 0xEB, 0xC0, 0x02, + 0x01, 0xEB, 0x82, 0x04, 0x07, 0x46, 0xD6, 0xE1, 0x05, 0x98, 0x00, 0x28, + 0x01, 0xDB, 0x40, 0x1C, 0x05, 0x90, 0x22, 0x88, 0xD0, 0x07, 0x0C, 0xD0, + 0x00, 0x20, 0x00, 0x90, 0x0A, 0x98, 0x05, 0x28, 0x7E, 0xD0, 0x0C, 0xDC, + 0x01, 0x28, 0x14, 0xD0, 0x02, 0x28, 0x12, 0xD0, 0x03, 0x28, 0x0D, 0xD1, + 0xEB, 0xE0, 0xA0, 0x78, 0xE1, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2, + 0xED, 0xE7, 0xB0, 0xF5, 0x80, 0x4F, 0xF5, 0xD0, 0x6F, 0xF4, 0x80, 0x41, + 0xC8, 0x42, 0x6A, 0xD0, 0x4F, 0xF0, 0x01, 0x0B, 0xBB, 0xE1, 0x00, 0x98, + 0xB0, 0xF5, 0x20, 0x5F, 0x03, 0xD0, 0x42, 0xF6, 0x01, 0x01, 0x88, 0x42, + 0x16, 0xD1, 0x02, 0x98, 0x68, 0xB1, 0x3B, 0x46, 0x42, 0x46, 0xA9, 0x1C, + 0x0B, 0x98, 0xFF, 0xF7, 0xFD, 0xFD, 0x00, 0x20, 0x02, 0x90, 0xD9, 0xF8, + 0x00, 0x00, 0x35, 0x44, 0x81, 0x1B, 0xC9, 0xF8, 0x00, 0x10, 0x0B, 0x98, + 0x00, 0x28, 0x00, 0x98, 0x03, 0xD0, 0xB0, 0xF5, 0x20, 0x5F, 0x04, 0xD0, + 0x68, 0xE1, 0x42, 0xF6, 0x01, 0x01, 0x88, 0x42, 0xFA, 0xD1, 0x0A, 0x98, + 0x01, 0x28, 0x04, 0xD0, 0x20, 0x78, 0x80, 0x07, 0x28, 0xD5, 0x21, 0x1D, + 0x27, 0xE0, 0x00, 0x2E, 0x02, 0xDA, 0x66, 0x8A, 0x36, 0x1D, 0x04, 0xE0, + 0x60, 0x8A, 0xB1, 0xB2, 0x00, 0x1D, 0x81, 0x42, 0x15, 0xD1, 0xD9, 0xF8, + 0x00, 0x00, 0xB0, 0x42, 0x11, 0xDB, 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1, + 0x01, 0x0A, 0x38, 0x44, 0x28, 0x70, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44, + 0x00, 0x0A, 0x68, 0x70, 0x01, 0x20, 0x02, 0x90, 0x20, 0x78, 0x80, 0x07, + 0x02, 0xD5, 0x21, 0x1D, 0x01, 0xE0, 0x89, 0xE1, 0x61, 0x69, 0x62, 0x8A, + 0x28, 0x1D, 0x1F, 0xF4, 0x2E, 0xF3, 0x35, 0xE1, 0x61, 0x69, 0xDD, 0xE9, + 0x17, 0x20, 0x1F, 0xF4, 0xDD, 0xF2, 0x00, 0x28, 0x74, 0xD1, 0x00, 0x2E, + 0x00, 0xDA, 0x04, 0x26, 0xD9, 0xF8, 0x00, 0x00, 0xB0, 0x42, 0xD7, 0xDB, + 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x38, 0x44, 0x01, 0xE0, + 0x09, 0xE0, 0xC3, 0xE0, 0x28, 0x70, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44, + 0x00, 0x0A, 0x68, 0x70, 0x01, 0x20, 0x02, 0x90, 0x16, 0xE1, 0x00, 0x98, + 0xA0, 0xF5, 0x20, 0x51, 0x02, 0x39, 0xA7, 0xD1, 0x8C, 0x46, 0x61, 0x69, + 0x00, 0x29, 0xA3, 0xD0, 0x50, 0x06, 0x04, 0xD5, 0x4F, 0xF0, 0x01, 0x0C, + 0x08, 0x46, 0x01, 0x91, 0x05, 0xE0, 0x60, 0x8A, 0xC0, 0xEB, 0xC0, 0x00, + 0x01, 0xEB, 0x80, 0x00, 0x01, 0x90, 0x40, 0x8A, 0x10, 0x28, 0x04, 0xD0, + 0x08, 0x20, 0x00, 0x2E, 0x03, 0xDA, 0x06, 0x46, 0x04, 0xE0, 0x06, 0x20, + 0xF9, 0xE7, 0x86, 0x42, 0x7F, 0xF4, 0x68, 0xAF, 0xD9, 0xF8, 0x00, 0x00, + 0xB0, 0x42, 0xFF, 0xF6, 0x63, 0xAF, 0x07, 0xA8, 0x00, 0x90, 0x62, 0x8A, + 0x06, 0xAB, 0x60, 0x46, 0xFD, 0xF7, 0x7E, 0xFE, 0x00, 0x28, 0xEF, 0xD1, + 0x98, 0xF8, 0x0A, 0x00, 0x38, 0x44, 0x05, 0xF8, 0x01, 0x0B, 0xB8, 0xF8, + 0x0A, 0x00, 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0xBD, 0xF8, + 0x18, 0x00, 0x05, 0xF8, 0x01, 0x0B, 0xBD, 0xF8, 0x18, 0x00, 0x00, 0x0A, + 0x05, 0xF8, 0x03, 0x0B, 0xBD, 0xF8, 0x1C, 0x00, 0x05, 0xF8, 0x02, 0x0C, + 0xBD, 0xF8, 0x1C, 0x00, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0C, 0x08, 0x2E, + 0x11, 0xD1, 0x01, 0x98, 0x00, 0x78, 0x80, 0x07, 0x01, 0x98, 0x08, 0xD5, + 0x00, 0x79, 0x05, 0xF8, 0x01, 0x0B, 0x01, 0x98, 0x40, 0x79, 0x05, 0xF8, + 0x01, 0x0B, 0x04, 0xE0, 0xDF, 0xE0, 0x40, 0x69, 0x00, 0x88, 0x25, 0xF8, + 0x02, 0x0B, 0xD9, 0xF8, 0x00, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x81, 0x1B, + 0xC9, 0xF8, 0x00, 0x10, 0xAC, 0xE0, 0x00, 0x98, 0xA0, 0xF5, 0x20, 0x51, + 0x03, 0x39, 0x03, 0xD0, 0x0A, 0x98, 0xB0, 0xF5, 0x80, 0x4F, 0x4D, 0xD1, + 0x0A, 0x98, 0x03, 0x28, 0x08, 0xD0, 0x21, 0x46, 0x02, 0x20, 0x0A, 0x78, + 0xD2, 0x07, 0x07, 0xD0, 0x10, 0x22, 0x10, 0x30, 0x00, 0x92, 0x06, 0xE0, + 0x04, 0xF1, 0x1C, 0x01, 0x05, 0x20, 0xF4, 0xE7, 0x02, 0x22, 0x80, 0x1C, + 0x00, 0x92, 0x00, 0x2E, 0x01, 0xDA, 0x06, 0x46, 0x01, 0xE0, 0x86, 0x42, + 0x94, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0xB0, 0x42, 0x95, 0xDB, 0x98, 0xF8, + 0x0A, 0x00, 0x38, 0x44, 0x05, 0xF8, 0x01, 0x0B, 0xB8, 0xF8, 0x0A, 0x00, + 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0x0A, 0x98, 0x03, 0x28, + 0x14, 0xD1, 0x20, 0x78, 0x80, 0x07, 0x01, 0xD5, 0x20, 0x79, 0x01, 0xE0, + 0x60, 0x69, 0x00, 0x78, 0x05, 0xF8, 0x01, 0x0B, 0x98, 0xF8, 0x0A, 0x20, + 0x78, 0x1C, 0x02, 0x44, 0x05, 0xF8, 0x01, 0x2B, 0xB8, 0xF8, 0x0A, 0x20, + 0x10, 0x44, 0x00, 0x0A, 0x05, 0xF8, 0x01, 0x0B, 0x28, 0x46, 0x89, 0x1C, + 0x00, 0x9A, 0x1F, 0xF4, 0x56, 0xF2, 0x00, 0x98, 0x05, 0x44, 0xA6, 0xE7, + 0x00, 0x98, 0x00, 0x28, 0x17, 0x98, 0x02, 0xD0, 0x02, 0x28, 0x02, 0xD0, + 0x54, 0xE0, 0x10, 0x28, 0x52, 0xD1, 0x02, 0x46, 0xA1, 0x1C, 0x18, 0x98, + 0x1F, 0xF4, 0xFA, 0xF1, 0xF0, 0xBB, 0xB8, 0xF8, 0x0A, 0x00, 0x00, 0x23, + 0x38, 0x44, 0x81, 0xB2, 0x22, 0x46, 0x09, 0x98, 0xFD, 0xF7, 0x76, 0xF8, + 0x04, 0x90, 0x00, 0x28, 0xB4, 0xD1, 0x20, 0x46, 0xFD, 0xF7, 0x68, 0xFD, + 0x01, 0x90, 0x38, 0xB1, 0x20, 0x78, 0x00, 0x07, 0x04, 0xD5, 0x01, 0x98, + 0x1F, 0xF4, 0x0E, 0xF2, 0x40, 0x1C, 0x00, 0xE0, 0x60, 0x8A, 0x00, 0x90, + 0x80, 0x1C, 0x00, 0x2E, 0x01, 0xDA, 0x06, 0x46, 0x01, 0xE0, 0x86, 0x42, + 0x9E, 0xD1, 0xD9, 0xF8, 0x00, 0x00, 0x02, 0x28, 0x7F, 0xF6, 0x9A, 0xAE, + 0x98, 0xF8, 0x0A, 0x00, 0x0A, 0xF1, 0x01, 0x0A, 0x38, 0x44, 0x05, 0xF8, + 0x01, 0x0B, 0xB8, 0xF8, 0x0A, 0x00, 0x38, 0x44, 0x00, 0x0A, 0x05, 0xF8, + 0x01, 0x0B, 0x01, 0x98, 0xD0, 0xB1, 0xD9, 0xF8, 0x00, 0x00, 0x00, 0x9A, + 0x81, 0x1E, 0x91, 0x42, 0x01, 0xDA, 0x06, 0x46, 0x00, 0x91, 0x00, 0xE0, + 0x0C, 0xE0, 0xDD, 0xE9, 0x00, 0x21, 0x28, 0x46, 0x1F, 0xF4, 0xFF, 0xF1, + 0x00, 0x98, 0xD9, 0xF8, 0x00, 0x10, 0x05, 0x44, 0x08, 0x1A, 0x80, 0x1E, + 0xC9, 0xF8, 0x00, 0x00, 0xBB, 0xF1, 0x00, 0x0F, 0x2F, 0xD1, 0x06, 0xE0, + 0xB8, 0xF8, 0x0A, 0x00, 0x0C, 0x99, 0x38, 0x44, 0x76, 0x42, 0x08, 0x80, + 0x68, 0xE6, 0x05, 0x98, 0x01, 0x28, 0x04, 0xDB, 0x02, 0x98, 0xE8, 0xB3, + 0xAA, 0xF1, 0x01, 0x0A, 0x3F, 0xE0, 0x01, 0x20, 0x16, 0x99, 0xFF, 0xF7, + 0xD5, 0xF8, 0x03, 0x99, 0x88, 0x42, 0x0C, 0xD1, 0x00, 0x20, 0x16, 0x99, + 0xFF, 0xF7, 0xCE, 0xF8, 0xB8, 0x42, 0x06, 0xD1, 0x00, 0x20, 0x05, 0x90, + 0x0A, 0x98, 0x01, 0x28, 0x01, 0xD0, 0x02, 0x28, 0xE2, 0xD1, 0x1C, 0x34, + 0x7F, 0x1C, 0xB8, 0xF8, 0x08, 0x00, 0x03, 0xE0, 0x64, 0x01, 0x20, 0x00, + 0x98, 0x77, 0x20, 0x00, 0xB8, 0x42, 0x3F, 0xF7, 0x1F, 0xAE, 0x02, 0x98, + 0x68, 0xB1, 0x3B, 0x46, 0x42, 0x46, 0xA9, 0x1C, 0x0B, 0x98, 0xFF, 0xF7, + 0x49, 0xFC, 0x00, 0x20, 0x02, 0x90, 0xD9, 0xF8, 0x00, 0x00, 0x35, 0x44, + 0x81, 0x1B, 0xC9, 0xF8, 0x00, 0x10, 0xBB, 0xF1, 0x00, 0x0F, 0x0C, 0xD1, + 0x0F, 0x48, 0x03, 0x99, 0x90, 0xF8, 0xAD, 0x01, 0x40, 0x1E, 0x88, 0x42, + 0x05, 0xDD, 0x00, 0xE0, 0x03, 0xE0, 0x48, 0x1C, 0x03, 0x90, 0x00, 0x20, + 0xE5, 0xE5, 0x19, 0x99, 0xBA, 0xF1, 0x00, 0x0F, 0xC1, 0xF8, 0x00, 0xA0, + 0x02, 0xDD, 0xC9, 0xF8, 0x00, 0x60, 0x06, 0xE0, 0x00, 0x21, 0xC9, 0xF8, + 0x00, 0x10, 0x04, 0x98, 0x08, 0xB9, 0x0A, 0x20, 0x04, 0x90, 0x04, 0x98, + 0xD0, 0xE5, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x84, 0x68, + 0x05, 0x46, 0x00, 0x20, 0x21, 0x8A, 0xFF, 0xF7, 0x7D, 0xF8, 0x81, 0xB2, + 0x2B, 0x8E, 0xA2, 0x8A, 0xE0, 0x68, 0xBD, 0xE8, 0x70, 0x40, 0xF6, 0xF7, + 0x2B, 0xB9, 0x00, 0x00, 0x2D, 0xE9, 0xFF, 0x47, 0x88, 0x46, 0x05, 0x46, + 0x00, 0xF1, 0x0C, 0x04, 0x01, 0x8A, 0x1E, 0x46, 0x17, 0x46, 0x00, 0x20, + 0xDD, 0xF8, 0x30, 0x90, 0xFF, 0xF7, 0x66, 0xF8, 0x29, 0x68, 0x80, 0xB2, + 0xBA, 0xB2, 0x09, 0x8E, 0x03, 0x91, 0x8D, 0xE8, 0x45, 0x00, 0x23, 0x68, + 0x0A, 0x4C, 0x42, 0x46, 0x20, 0x68, 0xA9, 0xEB, 0x00, 0x01, 0x89, 0xB2, + 0xF6, 0xF7, 0x41, 0xFA, 0x00, 0x28, 0x08, 0xD0, 0x20, 0x68, 0x04, 0xB0, + 0x4F, 0xF4, 0xAB, 0x72, 0xBD, 0xE8, 0xF0, 0x47, 0x03, 0x49, 0xF4, 0xF7, + 0xC5, 0xBE, 0xBD, 0xE8, 0xFF, 0x87, 0x00, 0x00, 0x98, 0x77, 0x20, 0x00, + 0x21, 0xAC, 0x82, 0x00, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x1C, 0x46, + 0x92, 0x46, 0x88, 0xE0, 0x03, 0x46, 0x01, 0x22, 0x48, 0x49, 0x49, 0x48, + 0xED, 0xF7, 0x2F, 0xD8, 0x48, 0x4D, 0x4F, 0xF0, 0x00, 0x0B, 0xD3, 0x23, + 0x29, 0x78, 0x47, 0x4A, 0x01, 0xEB, 0x8A, 0x00, 0x81, 0xB2, 0x46, 0x48, + 0x00, 0x78, 0xF4, 0xF7, 0xB7, 0xFD, 0x01, 0x90, 0x00, 0x28, 0x76, 0xD0, + 0x29, 0x46, 0x00, 0x26, 0x09, 0x78, 0x77, 0x1E, 0x00, 0xEB, 0x01, 0x09, + 0xB0, 0x46, 0x4A, 0xE0, 0x21, 0x88, 0x00, 0x20, 0xFF, 0xF7, 0x1C, 0xF8, + 0x80, 0xB2, 0x00, 0x90, 0x21, 0x88, 0x01, 0x20, 0xFF, 0xF7, 0x16, 0xF8, + 0x85, 0xB2, 0x3A, 0x48, 0x90, 0xF8, 0xAD, 0x01, 0xA8, 0x42, 0x37, 0xD9, + 0x21, 0x88, 0x03, 0x98, 0xFD, 0xF7, 0x82, 0xFC, 0x00, 0x28, 0x00, 0xDA, + 0x00, 0x20, 0x04, 0x99, 0x88, 0x43, 0xC0, 0x07, 0x2C, 0xD1, 0x33, 0x48, + 0x05, 0xEB, 0x45, 0x01, 0x00, 0x6A, 0x00, 0xEB, 0x81, 0x0B, 0x00, 0x98, + 0xDB, 0xF8, 0x04, 0x10, 0xC0, 0xEB, 0xC0, 0x00, 0x11, 0xF8, 0x20, 0x00, + 0xC0, 0x06, 0x17, 0xD5, 0x00, 0x2F, 0x01, 0xDA, 0x2F, 0x46, 0x08, 0xE0, + 0xAF, 0x42, 0x06, 0xD0, 0x28, 0x48, 0x07, 0xEB, 0x47, 0x01, 0x00, 0x6A, + 0x00, 0xEB, 0x81, 0x0B, 0x15, 0xE0, 0x00, 0x98, 0xA9, 0xF8, 0x00, 0x00, + 0x09, 0xF1, 0x02, 0x00, 0x61, 0x88, 0x20, 0xF8, 0x02, 0x1B, 0x81, 0x46, + 0x76, 0x1C, 0x05, 0xE0, 0x19, 0x49, 0x00, 0x22, 0x20, 0x31, 0x19, 0x48, + 0xEC, 0xF7, 0xCF, 0xDF, 0x08, 0xF1, 0x01, 0x08, 0x24, 0x1D, 0xD0, 0x45, + 0xB2, 0xDB, 0xAA, 0xEB, 0x08, 0x0A, 0x00, 0x2E, 0x20, 0xDD, 0x12, 0x49, + 0x12, 0x48, 0x5B, 0x46, 0x02, 0x22, 0x58, 0x31, 0x40, 0x1C, 0x00, 0x96, + 0xEC, 0xF7, 0xBD, 0xDF, 0x03, 0x98, 0xB3, 0xB2, 0x5A, 0x46, 0x00, 0x8E, + 0x00, 0x90, 0x0D, 0x48, 0x01, 0x78, 0x01, 0x98, 0xF6, 0xF7, 0x42, 0xFA, + 0x28, 0xB1, 0x4F, 0xF4, 0x8F, 0x72, 0x0A, 0x49, 0x01, 0x98, 0xF4, 0xF7, + 0x2F, 0xFE, 0xBA, 0xF1, 0x00, 0x00, 0x3F, 0xF7, 0x73, 0xAF, 0x07, 0xB0, + 0xBD, 0xE8, 0xF0, 0x8F, 0x4F, 0xF4, 0x91, 0x72, 0xF1, 0xE7, 0x00, 0x00, + 0xC4, 0x4A, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x48, 0x74, 0x20, 0x00, + 0x0E, 0xAC, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x98, 0x77, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x1F, 0x46, 0x01, 0x29, + 0x2A, 0xD1, 0x00, 0x24, 0x07, 0xF1, 0x13, 0x01, 0x88, 0x46, 0x01, 0x28, + 0x26, 0xD0, 0x2E, 0x4D, 0x57, 0x23, 0x2E, 0x4A, 0x95, 0xF8, 0xC1, 0x01, + 0x81, 0x00, 0x2D, 0x48, 0x00, 0x78, 0xF4, 0xF7, 0x13, 0xFD, 0x06, 0x00, + 0x18, 0xD0, 0x74, 0x80, 0x00, 0x22, 0x39, 0x46, 0x01, 0x20, 0xFD, 0xF7, + 0xE1, 0xF8, 0x95, 0xF8, 0xC1, 0x11, 0x04, 0x46, 0xA1, 0x42, 0x17, 0xDA, + 0x41, 0x46, 0x25, 0x48, 0xED, 0xF7, 0x3C, 0xD9, 0x03, 0x46, 0x95, 0xF8, + 0xC1, 0x01, 0x03, 0x22, 0xCD, 0xE9, 0x00, 0x40, 0x21, 0x49, 0x22, 0x48, + 0xEC, 0xF7, 0x63, 0xDF, 0xBD, 0xE8, 0xFC, 0x81, 0x01, 0x20, 0x87, 0xF8, + 0x2E, 0x00, 0x00, 0x94, 0x00, 0x23, 0xBA, 0x7E, 0x18, 0x46, 0x29, 0xE0, + 0x00, 0x2C, 0x04, 0xDD, 0x32, 0x46, 0x39, 0x46, 0x02, 0x20, 0xFD, 0xF7, + 0xBD, 0xF8, 0xA5, 0xB2, 0x00, 0x2C, 0x12, 0xDD, 0x00, 0x22, 0x30, 0x46, + 0x31, 0x46, 0x0C, 0xE0, 0x43, 0x88, 0x2B, 0xB1, 0x88, 0x42, 0x01, 0xD0, + 0x03, 0x68, 0x0B, 0x60, 0x09, 0x1D, 0x01, 0xE0, 0x6D, 0x1E, 0xAD, 0xB2, + 0x52, 0x1C, 0x92, 0xB2, 0x00, 0x1D, 0xA2, 0x42, 0xF0, 0xDB, 0x2D, 0xB9, + 0x8F, 0x22, 0x08, 0x49, 0x30, 0x46, 0xF4, 0xF7, 0xB9, 0xFD, 0x00, 0x26, + 0xA8, 0x06, 0x03, 0x0E, 0x00, 0x96, 0xBA, 0x7E, 0x41, 0x46, 0x01, 0x20, + 0xF6, 0xF7, 0x80, 0xFC, 0xC8, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xF7, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, + 0x70, 0x4A, 0xC0, 0x08, 0x00, 0x38, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, + 0x85, 0xB0, 0x4F, 0xF0, 0x00, 0x07, 0xDD, 0xE9, 0x12, 0x84, 0x5F, 0xEA, + 0x03, 0x0B, 0xB9, 0x46, 0x0D, 0xD0, 0x07, 0x98, 0x02, 0x28, 0x0D, 0xD0, + 0x03, 0x28, 0x10, 0xD0, 0x04, 0x28, 0x15, 0xD0, 0x05, 0x28, 0x40, 0x46, + 0x08, 0xD0, 0x06, 0x28, 0x15, 0xD0, 0x14, 0x20, 0x13, 0xE0, 0x00, 0x20, + 0x00, 0x90, 0x11, 0xE0, 0x04, 0x20, 0x0E, 0xE0, 0x08, 0x28, 0x0C, 0xD0, + 0x02, 0xE0, 0xB8, 0xF1, 0x07, 0x0F, 0x01, 0xD0, 0x16, 0x20, 0x06, 0xE0, + 0x08, 0x20, 0x04, 0xE0, 0x40, 0x46, 0xB8, 0xF1, 0x04, 0x0F, 0x00, 0xD0, + 0x12, 0x20, 0x00, 0x90, 0x8C, 0x49, 0x40, 0xF2, 0x15, 0x33, 0x8C, 0x4A, + 0x09, 0x78, 0x49, 0x1C, 0x21, 0xF0, 0x01, 0x0A, 0x0B, 0xFB, 0x00, 0xA0, + 0x81, 0xB2, 0x89, 0x48, 0x00, 0x78, 0xF4, 0xF7, 0x77, 0xFC, 0x03, 0x90, + 0x00, 0x28, 0x7B, 0xD0, 0x00, 0xEB, 0x0A, 0x05, 0x00, 0x26, 0xD7, 0xE0, + 0x02, 0x28, 0x3B, 0xD0, 0x03, 0x28, 0x7F, 0xD0, 0x04, 0x28, 0x73, 0xD0, + 0x05, 0x28, 0x48, 0xD0, 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1, 0x06, 0x0F, + 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x21, 0x16, 0xD0, 0x06, 0xEB, + 0x86, 0x00, 0x25, 0xF8, 0x20, 0x10, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, + 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x05, 0xEB, 0x80, 0x01, + 0x00, 0x20, 0x4F, 0x80, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, + 0x1A, 0x71, 0x10, 0x28, 0xF8, 0xD3, 0xAE, 0xE0, 0x06, 0xEB, 0x46, 0x00, + 0x25, 0xF8, 0x10, 0x10, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB, 0x40, 0x00, + 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x47, 0x80, + 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, + 0x81, 0x80, 0x98, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, + 0x00, 0xEB, 0x01, 0x20, 0x25, 0xF8, 0x26, 0x00, 0x14, 0xF8, 0x01, 0x0B, + 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2, 0x05, 0xEB, + 0x86, 0x00, 0x47, 0x80, 0x85, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1, + 0x08, 0x0F, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x1F, 0xFA, + 0x80, 0xF9, 0x1E, 0xD0, 0x06, 0xEB, 0x46, 0x00, 0x00, 0xEB, 0xC6, 0x00, + 0x25, 0xF8, 0x10, 0x90, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB, 0x40, 0x00, + 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x41, 0x80, 0x14, 0xF8, + 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x81, 0x80, + 0x10, 0x21, 0x80, 0x1D, 0x1E, 0xF4, 0xF8, 0xF7, 0x10, 0x34, 0x5E, 0xE0, + 0x86, 0xE0, 0x09, 0xE0, 0x43, 0xE0, 0x25, 0xF8, 0x36, 0x90, 0x14, 0xF8, + 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x21, 0x28, 0xE0, + 0x14, 0xF8, 0x01, 0x0B, 0xB8, 0xF1, 0x07, 0x0F, 0x14, 0xF8, 0x01, 0x1B, + 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2, 0x1A, 0xD0, 0x06, 0xEB, 0x46, 0x00, + 0x00, 0xEB, 0xC6, 0x00, 0x05, 0xEB, 0x40, 0x01, 0x25, 0xF8, 0x10, 0x70, + 0x14, 0xF8, 0x01, 0x2B, 0x4A, 0x80, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, + 0x01, 0x2B, 0x00, 0xEB, 0x02, 0x20, 0x88, 0x80, 0x00, 0x20, 0x0B, 0x18, + 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x9A, 0x71, 0x10, 0x28, 0xF8, 0xD3, + 0x2D, 0xE0, 0x25, 0xF8, 0x36, 0x70, 0x14, 0xF8, 0x01, 0x1B, 0x05, 0xEB, + 0xC6, 0x00, 0x41, 0x80, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, 0x01, 0x2B, + 0x01, 0xEB, 0x02, 0x21, 0x81, 0x80, 0x14, 0xF8, 0x01, 0x1B, 0x14, 0xF8, + 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0xC1, 0x80, 0x17, 0xE0, 0x14, 0xF8, + 0x01, 0x0B, 0xB8, 0xF1, 0x04, 0x0F, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, + 0x01, 0x20, 0x87, 0xB2, 0x15, 0xD0, 0x06, 0xEB, 0xC6, 0x01, 0x00, 0x20, + 0x25, 0xF8, 0x11, 0x70, 0x05, 0xEB, 0x41, 0x03, 0x03, 0x44, 0x14, 0xF8, + 0x01, 0x2B, 0x40, 0x1C, 0x9A, 0x70, 0x10, 0x28, 0xF6, 0xD3, 0x76, 0x1C, + 0x07, 0x98, 0x5E, 0x45, 0xFF, 0xF6, 0x24, 0xAF, 0x05, 0x28, 0x0C, 0xD0, + 0x0C, 0xE0, 0x25, 0xF8, 0x26, 0x70, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, + 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x05, 0xEB, 0x86, 0x01, 0x48, 0x80, + 0xEB, 0xE7, 0x4F, 0x46, 0x14, 0x98, 0x00, 0xB1, 0x87, 0x80, 0xDD, 0xE9, + 0x05, 0x01, 0xCD, 0xE9, 0x01, 0x01, 0x51, 0x46, 0x5B, 0x46, 0x07, 0x9A, + 0x03, 0x98, 0xF6, 0xF7, 0x19, 0xFA, 0x28, 0xB1, 0x40, 0xF2, 0x93, 0x32, + 0x04, 0x49, 0x03, 0x98, 0xF4, 0xF7, 0x5E, 0xFC, 0x09, 0xB0, 0x38, 0x46, + 0xBD, 0xE8, 0xF0, 0x8F, 0x48, 0x74, 0x20, 0x00, 0x8B, 0xAC, 0x82, 0x00, + 0x04, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x87, 0xB0, 0x04, 0x46, 0x1E, 0x46, + 0x00, 0x8E, 0x0F, 0x46, 0x15, 0x46, 0x13, 0x46, 0x00, 0x90, 0x02, 0x22, + 0x0C, 0x49, 0x0D, 0x48, 0xEC, 0xF7, 0xC3, 0xDD, 0x4F, 0xF4, 0xA0, 0x60, + 0xAD, 0xF8, 0x04, 0x00, 0xAD, 0xF8, 0x0A, 0x60, 0x01, 0x20, 0xAD, 0xF8, + 0x08, 0x00, 0xAD, 0xF8, 0x0C, 0x50, 0x04, 0x20, 0x04, 0x97, 0xAD, 0xF8, + 0x0E, 0x00, 0x20, 0x8E, 0x05, 0x90, 0x01, 0xA8, 0x04, 0xF0, 0xCA, 0xFD, + 0x07, 0xB0, 0xF0, 0xBD, 0x60, 0x48, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, + 0x2D, 0xE9, 0xFC, 0x47, 0x00, 0x24, 0x8A, 0x46, 0x05, 0x46, 0x99, 0x46, + 0x16, 0x46, 0x27, 0x46, 0xA0, 0x46, 0x11, 0x46, 0x01, 0x20, 0xFE, 0xF7, + 0xA5, 0xFD, 0x28, 0x49, 0x91, 0xF8, 0xAD, 0x21, 0x90, 0x42, 0x2B, 0xDA, + 0x26, 0x4A, 0x00, 0x20, 0x91, 0xF8, 0xAC, 0x11, 0x92, 0x69, 0x0F, 0xE0, + 0x93, 0x68, 0x03, 0xEB, 0xC0, 0x04, 0x23, 0x78, 0x63, 0xB1, 0xA3, 0x88, + 0xB3, 0x42, 0x06, 0xD1, 0x63, 0x88, 0xB5, 0xF8, 0x30, 0xC0, 0x63, 0x45, + 0x01, 0xD1, 0x27, 0x46, 0x02, 0xE0, 0x40, 0x1C, 0x81, 0x42, 0xED, 0xDC, + 0x2F, 0xB9, 0x81, 0x42, 0x2C, 0xDD, 0x01, 0x20, 0x20, 0x70, 0x80, 0x46, + 0x44, 0xB3, 0xBA, 0xF1, 0x00, 0x0F, 0x06, 0xD0, 0xE8, 0x7E, 0x50, 0xB9, + 0x60, 0x78, 0x40, 0xF0, 0x01, 0x00, 0x60, 0x70, 0x05, 0xE0, 0x60, 0x78, + 0xC0, 0x07, 0x02, 0xD0, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x87, 0x01, 0x27, + 0xB8, 0xF1, 0x00, 0x0F, 0x03, 0xD0, 0x28, 0x8E, 0x60, 0x80, 0xA6, 0x80, + 0x03, 0xE0, 0xE1, 0x88, 0x49, 0x45, 0x00, 0xD1, 0x00, 0x27, 0xA4, 0xF8, + 0x06, 0x90, 0x61, 0x78, 0x03, 0x22, 0xCD, 0xE9, 0x00, 0x91, 0x63, 0x88, + 0x06, 0x49, 0x07, 0x48, 0xEC, 0xF7, 0x51, 0xDD, 0x38, 0x46, 0xE4, 0xE7, + 0x4F, 0xF0, 0xFF, 0x30, 0xE1, 0xE7, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x98, 0x77, 0x20, 0x00, 0xFC, 0x4D, 0xC0, 0x08, 0x03, 0x38, 0x10, 0x21, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x08, 0x49, 0x08, 0x48, 0xEC, 0xF7, + 0x3C, 0xDD, 0xE0, 0x7E, 0x00, 0x28, 0x07, 0xD1, 0x01, 0x20, 0xE0, 0x76, + 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x06, 0xB8, + 0x10, 0xBD, 0x00, 0x00, 0x58, 0x4A, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, + 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x07, 0x46, 0x08, 0x98, 0x93, 0x46, + 0x89, 0x46, 0x04, 0x68, 0x12, 0x9E, 0x01, 0x25, 0x08, 0x46, 0xFE, 0xF7, + 0x21, 0xFD, 0x5F, 0xEA, 0x00, 0x08, 0x0C, 0xD0, 0x02, 0x46, 0x01, 0x23, + 0x49, 0x46, 0x38, 0x46, 0xFC, 0xF7, 0x64, 0xFC, 0x05, 0x00, 0x04, 0xD1, + 0x40, 0x46, 0xFC, 0xF7, 0xB5, 0xFC, 0x08, 0xB1, 0xAC, 0x1E, 0xA1, 0xE0, + 0xA8, 0xF1, 0x1C, 0x00, 0x81, 0x46, 0xFC, 0xF7, 0xA9, 0xFC, 0x00, 0x28, + 0x7E, 0xD0, 0x99, 0xF8, 0x00, 0x10, 0x89, 0x07, 0x02, 0xD5, 0x99, 0xF8, + 0x04, 0x00, 0x02, 0xE0, 0xD9, 0xF8, 0x14, 0x00, 0x00, 0x78, 0x02, 0x2E, + 0x04, 0xD0, 0x05, 0x2E, 0x04, 0xD0, 0x01, 0x2E, 0x05, 0xD0, 0x08, 0xE0, + 0x40, 0x07, 0x03, 0xE0, 0x40, 0x06, 0x03, 0xD5, 0x05, 0xE0, 0x00, 0x07, + 0x00, 0x28, 0x6C, 0xDB, 0x03, 0x25, 0x05, 0x2E, 0x61, 0xD1, 0x0B, 0xEB, + 0x04, 0x00, 0x82, 0x46, 0x10, 0xF8, 0x0C, 0x1D, 0x42, 0x78, 0x01, 0xEB, + 0x02, 0x21, 0x82, 0x78, 0x1A, 0xF8, 0x09, 0x0C, 0x12, 0x04, 0x02, 0xEB, + 0x00, 0x60, 0x0E, 0x18, 0x33, 0x46, 0x01, 0x22, 0x39, 0x49, 0x3A, 0x48, + 0xEC, 0xF7, 0xD5, 0xDC, 0x38, 0x68, 0x81, 0x7E, 0x13, 0x30, 0x0A, 0xF0, + 0x54, 0xFE, 0x5F, 0xEA, 0x00, 0x09, 0x4A, 0xD0, 0x02, 0x46, 0x10, 0x21, + 0x34, 0x48, 0xEC, 0xF7, 0x34, 0xDF, 0x31, 0x49, 0x03, 0x46, 0x01, 0x22, + 0x20, 0x31, 0x30, 0x48, 0xEC, 0xF7, 0xC1, 0xDC, 0x01, 0xAB, 0x62, 0x1F, + 0xAB, 0xF1, 0x03, 0x01, 0x48, 0x46, 0x1B, 0xF4, 0x53, 0xF5, 0xAA, 0xF1, + 0x08, 0x01, 0x03, 0xA8, 0x89, 0x46, 0x08, 0x22, 0x82, 0x46, 0x1E, 0xF4, + 0x7B, 0xF5, 0xB0, 0xB1, 0x27, 0x4E, 0x52, 0x46, 0x08, 0x21, 0x30, 0x46, + 0xEC, 0xF7, 0x17, 0xDF, 0x05, 0x46, 0x4A, 0x46, 0x08, 0x21, 0x30, 0x46, + 0xEC, 0xF7, 0x11, 0xDF, 0x03, 0x46, 0x1F, 0x49, 0x1F, 0x48, 0x02, 0x22, + 0x40, 0x31, 0x80, 0x1E, 0x00, 0x95, 0xEC, 0xF7, 0x9C, 0xDC, 0xC2, 0x25, + 0x2E, 0xE0, 0x38, 0x68, 0x81, 0x7E, 0x13, 0x30, 0x0A, 0xF0, 0x24, 0xFE, + 0x86, 0x42, 0x03, 0xD2, 0x80, 0x1B, 0x10, 0xF5, 0x80, 0x7F, 0x0A, 0xD9, + 0x38, 0x68, 0x72, 0x1C, 0x81, 0x7E, 0x13, 0x30, 0x0E, 0xF0, 0xFE, 0xFD, + 0x0C, 0x3C, 0x00, 0xE0, 0x05, 0xE0, 0x25, 0xB1, 0x18, 0xE0, 0xC1, 0x25, + 0x16, 0xE0, 0x05, 0x25, 0x14, 0xE0, 0x40, 0x46, 0xFD, 0xF7, 0xC4, 0xF8, + 0xB8, 0xF8, 0x12, 0x10, 0x29, 0xB1, 0x20, 0xB1, 0xA1, 0x42, 0x05, 0xDA, + 0x00, 0x24, 0x0D, 0x25, 0x08, 0xE0, 0x4F, 0xF0, 0xFF, 0x34, 0x05, 0xE0, + 0x00, 0x2C, 0x03, 0xDD, 0x22, 0x46, 0x59, 0x46, 0x1E, 0xF4, 0x7F, 0xF5, + 0x08, 0x98, 0x04, 0x60, 0x09, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x8F, + 0x24, 0x4F, 0xC0, 0x08, 0x02, 0x38, 0x10, 0x21, 0x00, 0x00, 0x50, 0x21, + 0x2D, 0xE9, 0xFF, 0x47, 0x84, 0x68, 0xDD, 0xF8, 0x30, 0x90, 0x1F, 0x46, + 0x92, 0x46, 0x80, 0x46, 0x04, 0xF1, 0x0C, 0x05, 0x00, 0x26, 0x59, 0xB1, + 0x08, 0x46, 0xFC, 0xF7, 0xAA, 0xFD, 0x03, 0x00, 0x06, 0xD0, 0x20, 0x89, + 0x00, 0x1F, 0xB0, 0xF5, 0x80, 0x4F, 0x1B, 0xD0, 0x12, 0x21, 0x1A, 0xE0, + 0x21, 0x89, 0x09, 0xEB, 0x07, 0x00, 0x09, 0x1F, 0xB1, 0xF5, 0x80, 0x4F, + 0x0A, 0xD0, 0x00, 0x96, 0x01, 0x96, 0x02, 0x96, 0x00, 0x23, 0x01, 0x22, + 0x13, 0x21, 0x40, 0x46, 0x03, 0x96, 0xF3, 0xF7, 0x05, 0xFB, 0x0C, 0xE0, + 0x00, 0x90, 0xEA, 0x88, 0xA9, 0x88, 0x53, 0x46, 0x20, 0x68, 0xF3, 0xF7, + 0xD5, 0xFC, 0x04, 0xE0, 0x16, 0x21, 0xAA, 0x88, 0x20, 0x68, 0xF3, 0xF7, + 0x79, 0xFB, 0x26, 0x81, 0xBD, 0xE8, 0xFF, 0x87, 0x0E, 0xB5, 0x02, 0xAB, + 0x8D, 0xF8, 0x08, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x09, 0x10, 0x8D, 0xF8, + 0x0A, 0x20, 0x11, 0x0A, 0x8D, 0xF8, 0x0B, 0x10, 0x00, 0x22, 0x04, 0x21, + 0xCD, 0xE9, 0x00, 0x12, 0x02, 0x49, 0x02, 0x22, 0x49, 0x78, 0x0A, 0xF0, + 0x7D, 0xF8, 0x0E, 0xBD, 0xF4, 0x78, 0x20, 0x00, 0xF0, 0xB5, 0x19, 0x4D, + 0x19, 0x4A, 0x06, 0x46, 0xB5, 0xF8, 0x46, 0x30, 0x92, 0xF8, 0x98, 0x41, + 0x00, 0x20, 0xA3, 0x42, 0x00, 0xD3, 0xF0, 0xBD, 0x13, 0x4B, 0x00, 0x22, + 0x1B, 0x6B, 0x05, 0xE0, 0x03, 0xEB, 0x42, 0x17, 0x3F, 0x78, 0xE7, 0xB1, + 0x52, 0x1C, 0x92, 0xB2, 0x94, 0x42, 0xF7, 0xD8, 0x00, 0x28, 0xF0, 0xD0, + 0x01, 0x22, 0x02, 0x70, 0x41, 0x70, 0x4F, 0xF6, 0xFF, 0x71, 0x41, 0x80, + 0xFF, 0x21, 0x81, 0x72, 0x00, 0x21, 0x01, 0x75, 0x32, 0x68, 0x42, 0x60, + 0xB2, 0x88, 0x02, 0x81, 0xC0, 0xF8, 0x16, 0x10, 0xC0, 0xF8, 0x1A, 0x10, + 0x35, 0xF8, 0x46, 0x1F, 0x49, 0x1C, 0x29, 0x80, 0xF0, 0xBD, 0x03, 0xEB, + 0x42, 0x10, 0xE3, 0xE7, 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x03, 0x4A, 0x10, 0x44, 0x90, 0xF8, 0x48, 0x00, 0x08, 0x40, 0x00, 0xD0, + 0x01, 0x20, 0x70, 0x47, 0xF0, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x14, 0x46, + 0x0D, 0x46, 0x00, 0xF0, 0x45, 0xFF, 0x00, 0x28, 0x04, 0xD0, 0x28, 0x44, + 0x80, 0x7D, 0x20, 0x40, 0x00, 0xD0, 0x01, 0x20, 0x70, 0xBD, 0x06, 0x22, + 0x02, 0xF0, 0x22, 0xB8, 0x7C, 0xB5, 0x6B, 0x46, 0x00, 0x24, 0x0D, 0x5D, + 0x64, 0x1C, 0x03, 0xF8, 0x01, 0x5B, 0x06, 0x2C, 0xF9, 0xD3, 0x03, 0xF8, + 0x01, 0x2B, 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46, 0x02, 0xF0, + 0x11, 0xF8, 0x7C, 0xBD, 0x2D, 0xE9, 0xFF, 0x5F, 0xDF, 0xF8, 0x10, 0x82, + 0x10, 0xF8, 0x01, 0x2B, 0xDF, 0xF8, 0x0C, 0xA2, 0x88, 0xF8, 0x04, 0x20, + 0x10, 0xF8, 0x01, 0x2B, 0x0F, 0x46, 0x10, 0xF8, 0x01, 0x3B, 0x04, 0x46, + 0x02, 0xEB, 0x03, 0x22, 0x98, 0xF8, 0x01, 0x00, 0x95, 0xB2, 0x40, 0xB9, + 0xA5, 0xF5, 0x40, 0x60, 0x03, 0x38, 0x04, 0xD0, 0x2B, 0x46, 0x01, 0x22, + 0x79, 0x49, 0x50, 0x46, 0xE7, 0xE0, 0x04, 0x2F, 0x02, 0xD3, 0x14, 0xF8, + 0x01, 0x6B, 0x00, 0xE0, 0x00, 0x26, 0x30, 0x46, 0x00, 0xF0, 0xD8, 0xFE, + 0x83, 0x46, 0x41, 0xF2, 0x03, 0x01, 0xDF, 0xF8, 0xC4, 0x91, 0x68, 0x1A, + 0xA9, 0xF1, 0x01, 0x09, 0x8D, 0x42, 0x5E, 0xD0, 0x0D, 0xDC, 0x00, 0x2D, + 0x22, 0xD0, 0xA5, 0xF5, 0x40, 0x60, 0x01, 0x38, 0x06, 0xD0, 0xB0, 0xF5, + 0x80, 0x6F, 0x1D, 0xD0, 0xA0, 0xF5, 0x80, 0x60, 0x01, 0x38, 0x08, 0xD1, + 0x83, 0xE0, 0x02, 0x28, 0x60, 0xD0, 0x06, 0x28, 0x3A, 0xD0, 0xA0, 0xF5, + 0x80, 0x60, 0x02, 0x38, 0x79, 0xD0, 0x3F, 0x20, 0xB0, 0xEB, 0x95, 0x2F, + 0x76, 0xD1, 0x04, 0x2F, 0x01, 0xD3, 0x3F, 0x1F, 0xBF, 0xB2, 0xFB, 0xB2, + 0x5A, 0x46, 0x29, 0x46, 0x01, 0x20, 0x00, 0x94, 0xF7, 0xF7, 0x0E, 0xFE, + 0xBD, 0xE8, 0xFF, 0x9F, 0x98, 0xF8, 0x00, 0x00, 0x41, 0x46, 0x02, 0x28, + 0xF8, 0xD1, 0x00, 0x2E, 0xF6, 0xD1, 0x23, 0x78, 0x4B, 0x71, 0x60, 0x78, + 0xA2, 0x78, 0x66, 0x79, 0x00, 0xEB, 0x02, 0x20, 0x82, 0xB2, 0x20, 0x79, + 0xE5, 0x78, 0x00, 0xEB, 0x06, 0x20, 0x80, 0xB2, 0xA8, 0xF8, 0x06, 0x00, + 0xA1, 0x79, 0xE4, 0x79, 0xCD, 0xE9, 0x00, 0x25, 0x01, 0xEB, 0x04, 0x21, + 0x89, 0xB2, 0xCD, 0xE9, 0x02, 0x01, 0x4B, 0x49, 0x05, 0x22, 0x34, 0x31, + 0x48, 0x46, 0xEC, 0xF7, 0x2A, 0xDB, 0x58, 0xE0, 0x98, 0xF8, 0x00, 0x00, + 0x41, 0x46, 0x02, 0x28, 0xD2, 0xD1, 0x00, 0x2E, 0xD0, 0xD1, 0x00, 0x20, + 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x83, 0xF8, 0x20, 0x20, + 0x06, 0x28, 0xF7, 0xD3, 0x47, 0xE0, 0x98, 0xF8, 0x00, 0x00, 0x02, 0x28, + 0xC2, 0xD1, 0x00, 0x2E, 0xC0, 0xD1, 0x22, 0x46, 0x08, 0x21, 0x3C, 0x48, + 0xEC, 0xF7, 0x79, 0xDD, 0x39, 0x49, 0x03, 0x46, 0x01, 0x22, 0x90, 0x31, + 0x48, 0x46, 0xEC, 0xF7, 0x06, 0xDB, 0x34, 0xE0, 0x98, 0xF8, 0x00, 0x00, + 0x41, 0x46, 0x02, 0x28, 0xAE, 0xD1, 0x00, 0x2E, 0xAC, 0xD1, 0x20, 0x78, + 0x62, 0x78, 0x00, 0xEB, 0x02, 0x20, 0x83, 0xB2, 0xA1, 0xF8, 0x44, 0x30, + 0xE0, 0x78, 0x22, 0x79, 0x00, 0xEB, 0x02, 0x20, 0x80, 0xB2, 0xA1, 0xF8, + 0x42, 0x00, 0xA8, 0xF8, 0x40, 0x00, 0x2A, 0x49, 0x00, 0x90, 0x02, 0x22, + 0xB8, 0x31, 0x50, 0x46, 0xEC, 0xF7, 0xE7, 0xDA, 0x15, 0xE0, 0x18, 0xE0, + 0x31, 0xE0, 0x98, 0xF8, 0x00, 0x10, 0x40, 0x46, 0x02, 0x29, 0x8D, 0xD1, + 0x00, 0x2E, 0x8B, 0xD1, 0x41, 0x78, 0x00, 0x29, 0x88, 0xD0, 0xA5, 0xF5, + 0x40, 0x61, 0x01, 0x39, 0x05, 0xD1, 0xC1, 0x78, 0x01, 0x29, 0x02, 0xD1, + 0x10, 0x21, 0x88, 0xF8, 0x01, 0x10, 0xBD, 0xE8, 0xFF, 0x5F, 0x01, 0xF0, + 0xAF, 0xBF, 0x20, 0x78, 0x61, 0x78, 0xA4, 0x78, 0x00, 0xEB, 0x01, 0x20, + 0x85, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x42, 0xFE, 0x40, 0xB1, 0x42, 0x78, + 0x01, 0x1D, 0x04, 0xB0, 0x63, 0xB2, 0x58, 0x46, 0xBD, 0xE8, 0xF0, 0x5F, + 0xF9, 0xF7, 0x62, 0xBA, 0x0F, 0x49, 0x0E, 0x48, 0x01, 0x22, 0xEC, 0x31, + 0x2B, 0x46, 0xC0, 0x1E, 0x0F, 0xE0, 0x08, 0x20, 0xB0, 0xEB, 0x95, 0x2F, + 0x07, 0xD1, 0x04, 0xB0, 0x22, 0x46, 0x59, 0x46, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x5F, 0x01, 0xF0, 0xC5, 0xB9, 0x08, 0x49, 0x2B, 0x46, 0x01, 0x22, + 0x48, 0x46, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x5F, 0xEC, 0xF7, 0x9D, 0x9A, + 0xF0, 0x75, 0x20, 0x00, 0x03, 0x3C, 0x10, 0x21, 0x98, 0x0A, 0xC0, 0x08, + 0x00, 0x00, 0x50, 0x21, 0xC0, 0x0B, 0xC0, 0x08, 0x38, 0xB5, 0x0C, 0x46, + 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x05, 0x49, 0x06, 0x48, + 0xEC, 0xF7, 0x89, 0xDA, 0x22, 0x46, 0x29, 0x46, 0xBD, 0xE8, 0x38, 0x40, + 0x40, 0xF2, 0x06, 0x40, 0x00, 0xF0, 0xA1, 0xBC, 0x88, 0x09, 0xC0, 0x08, + 0x02, 0x3C, 0x10, 0x21, 0x30, 0xB5, 0x8B, 0xB0, 0x0D, 0xF1, 0x01, 0x04, + 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x0D, 0x5C, 0x40, 0x1C, 0x04, 0xF8, + 0x01, 0x5B, 0x06, 0x28, 0xF9, 0xD3, 0x00, 0x20, 0x11, 0x5C, 0x40, 0x1C, + 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28, 0xF9, 0xD3, 0x00, 0x20, 0x19, 0x5C, + 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28, 0xF9, 0xD3, 0x68, 0x46, + 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x27, 0x00, 0x01, 0xF0, + 0xC1, 0xFE, 0x0B, 0xB0, 0x30, 0xBD, 0x42, 0xF2, 0x3D, 0x00, 0x00, 0xF0, + 0xD2, 0xBB, 0x42, 0xF2, 0x29, 0x00, 0x00, 0xF0, 0xCE, 0xBB, 0x42, 0xF2, + 0x10, 0x00, 0x00, 0xF0, 0xCA, 0xBB, 0x2D, 0xE9, 0xFF, 0x41, 0x0A, 0xAC, + 0x94, 0xE8, 0xE0, 0x00, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, + 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x03, 0x00, + 0x8D, 0xF8, 0x04, 0x20, 0x10, 0x0A, 0x8D, 0xF8, 0x05, 0x00, 0x8D, 0xF8, + 0x06, 0x30, 0x18, 0x0A, 0x8D, 0xF8, 0x07, 0x00, 0x8D, 0xF8, 0x08, 0x50, + 0x28, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x6C, 0x46, 0x8D, 0xF8, 0x0A, 0x60, + 0x30, 0x0A, 0xE0, 0x72, 0x27, 0x73, 0x38, 0x0A, 0x60, 0x73, 0x68, 0x46, + 0x0E, 0x34, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x13, 0x00, + 0x01, 0xF0, 0x84, 0xFE, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x2D, 0xE9, + 0xF0, 0x4F, 0x87, 0xB0, 0x9A, 0x46, 0xDD, 0xE9, 0x14, 0x65, 0x8D, 0xF8, + 0x00, 0x00, 0x00, 0x0A, 0xDD, 0xE9, 0x10, 0x8B, 0x8D, 0xF8, 0x01, 0x00, + 0x91, 0x46, 0xDD, 0xE9, 0x16, 0x43, 0xDD, 0xE9, 0x12, 0xC7, 0x8D, 0xF8, + 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x90, + 0x8D, 0xF8, 0x05, 0xA0, 0x00, 0x20, 0x0D, 0xF1, 0x06, 0x02, 0x18, 0xF8, + 0x00, 0x10, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF8, 0xD3, + 0x82, 0xF8, 0x00, 0xB0, 0x82, 0xF8, 0x01, 0xC0, 0x4F, 0xEA, 0x1C, 0x20, + 0x90, 0x70, 0xD7, 0x70, 0x38, 0x0A, 0x10, 0x71, 0x56, 0x71, 0x30, 0x0A, + 0x90, 0x71, 0xD5, 0x71, 0x28, 0x0A, 0x10, 0x72, 0x54, 0x72, 0x20, 0x0A, + 0x90, 0x72, 0xD3, 0x72, 0x18, 0x0A, 0x10, 0x73, 0x68, 0x46, 0x0D, 0x32, + 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x0D, 0x00, 0x01, 0xF0, + 0x3D, 0xFE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x42, 0xF2, 0x0E, 0x00, + 0x00, 0xF0, 0x4D, 0xBB, 0x10, 0xB5, 0x88, 0xB0, 0x6A, 0x46, 0x00, 0x23, + 0xC4, 0x5C, 0x5B, 0x1C, 0x02, 0xF8, 0x01, 0x4B, 0x10, 0x2B, 0xF9, 0xD3, + 0x00, 0x20, 0x0B, 0x5C, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x3B, 0x10, 0x28, + 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, + 0x17, 0x00, 0x01, 0xF0, 0x1D, 0xFE, 0x08, 0xB0, 0x10, 0xBD, 0x08, 0xB5, + 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, + 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x33, 0x00, 0x01, 0xF0, 0x0E, 0xFE, + 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, + 0x8D, 0xF8, 0x02, 0x20, 0x8D, 0xF8, 0x03, 0x30, 0x04, 0x22, 0x69, 0x46, + 0x42, 0xF2, 0x34, 0x00, 0x01, 0xF0, 0xFE, 0xFD, 0x08, 0xBD, 0x70, 0xB5, + 0x90, 0xB0, 0x0D, 0xF1, 0x03, 0x04, 0xDD, 0xE9, 0x14, 0x65, 0x8D, 0xF8, + 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x00, 0x20, + 0x19, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF9, 0xD3, + 0x04, 0xF8, 0x01, 0x6B, 0x06, 0xF0, 0x07, 0x00, 0x00, 0x22, 0x03, 0xE0, + 0x52, 0x1C, 0x41, 0x1E, 0xD2, 0xB2, 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1, + 0x00, 0x21, 0x2C, 0xE0, 0x05, 0xEB, 0x01, 0x10, 0x49, 0x1C, 0x03, 0x78, + 0x23, 0x70, 0x03, 0x88, 0xC9, 0xB2, 0x1B, 0x0A, 0x63, 0x70, 0x83, 0x78, + 0xA3, 0x70, 0x43, 0x88, 0x1B, 0x0A, 0xE3, 0x70, 0x03, 0x79, 0x23, 0x71, + 0x83, 0x88, 0x1B, 0x0A, 0x63, 0x71, 0x83, 0x79, 0xA3, 0x71, 0xC3, 0x88, + 0x1B, 0x0A, 0xE3, 0x71, 0x03, 0x7A, 0x23, 0x72, 0x03, 0x89, 0x1B, 0x0A, + 0x63, 0x72, 0x83, 0x7A, 0xA3, 0x72, 0x43, 0x89, 0x1B, 0x0A, 0xE3, 0x72, + 0x03, 0x7B, 0x23, 0x73, 0x83, 0x89, 0x1B, 0x0A, 0x63, 0x73, 0x83, 0x7B, + 0xA3, 0x73, 0xC0, 0x89, 0x00, 0x0A, 0xE0, 0x73, 0x10, 0x34, 0x91, 0x42, + 0xD0, 0xD3, 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, + 0x43, 0x00, 0x01, 0xF0, 0xA5, 0xFD, 0x10, 0xB0, 0x70, 0xBD, 0x01, 0x46, + 0x42, 0xF2, 0x1B, 0x00, 0x00, 0xF0, 0x3C, 0xBB, 0x00, 0xB5, 0x85, 0xB0, + 0x0D, 0xF1, 0x02, 0x02, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, + 0x01, 0x00, 0x00, 0x20, 0x0B, 0x5C, 0x40, 0x1C, 0x02, 0xF8, 0x01, 0x3B, + 0x10, 0x28, 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, + 0x42, 0xF2, 0x1A, 0x00, 0x01, 0xF0, 0x86, 0xFD, 0x05, 0xB0, 0x00, 0xBD, + 0x1C, 0xB5, 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8, 0x00, 0x20, 0x00, 0x22, + 0x8C, 0x5C, 0x52, 0x1C, 0x03, 0xF8, 0x01, 0x4B, 0x06, 0x2A, 0xF9, 0xD3, + 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46, 0x01, 0xF0, 0x72, 0xFD, + 0x1C, 0xBD, 0x42, 0xF2, 0x18, 0x00, 0x00, 0xF0, 0x84, 0xBA, 0x42, 0xF2, + 0x07, 0x00, 0x00, 0xF0, 0x80, 0xBA, 0x01, 0x46, 0x42, 0xF2, 0x15, 0x00, + 0x00, 0xF0, 0x02, 0xBB, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x2C, 0x00, + 0x00, 0xF0, 0x24, 0xBB, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x2B, 0x00, + 0x00, 0xF0, 0x1E, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x30, 0x00, 0x00, 0xF0, + 0xF1, 0xBA, 0x42, 0xF2, 0x4C, 0x00, 0x00, 0xF0, 0x66, 0xBA, 0x01, 0x46, + 0x42, 0xF2, 0x16, 0x00, 0x00, 0xF0, 0xE8, 0xBA, 0x42, 0xF2, 0x4B, 0x00, + 0x00, 0xF0, 0x5D, 0xBA, 0x01, 0x46, 0x42, 0xF2, 0x1D, 0x00, 0x00, 0xF0, + 0x1A, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x3C, 0x00, 0x00, 0xF0, 0x15, 0xBB, + 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x28, 0x00, 0x00, 0xF0, 0xFC, 0xBA, + 0x01, 0x46, 0x42, 0xF2, 0x2D, 0x00, 0x00, 0xF0, 0x0A, 0xBB, 0x00, 0x00, + 0x07, 0x4B, 0x93, 0xF8, 0x60, 0x20, 0x10, 0xB1, 0x42, 0xF0, 0x01, 0x01, + 0x01, 0xE0, 0x22, 0xF0, 0x01, 0x01, 0x83, 0xF8, 0x60, 0x10, 0x01, 0x46, + 0x42, 0xF2, 0x0A, 0x00, 0x00, 0xF0, 0xF9, 0xBA, 0xF0, 0x75, 0x20, 0x00, + 0x70, 0xB5, 0x88, 0xB0, 0x0D, 0x46, 0x06, 0x46, 0x14, 0x46, 0x20, 0x21, + 0x68, 0x46, 0x1E, 0xF4, 0x63, 0xF2, 0x68, 0x46, 0x1F, 0x2C, 0x00, 0xD9, + 0x1F, 0x24, 0x8D, 0xF8, 0x00, 0x40, 0x22, 0x46, 0x29, 0x46, 0x40, 0x1C, + 0x1E, 0xF4, 0xB7, 0xF1, 0x20, 0x22, 0x69, 0x46, 0x30, 0x46, 0x01, 0xF0, + 0x05, 0xFD, 0x08, 0xB0, 0x70, 0xBD, 0x2D, 0xE9, 0xFF, 0x41, 0x0D, 0xF1, + 0x07, 0x04, 0xDD, 0xE9, 0x0B, 0x57, 0xDD, 0xF8, 0x28, 0xC0, 0x8D, 0xF8, + 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, + 0x08, 0x0A, 0x8D, 0xF8, 0x04, 0x20, 0x0D, 0x9E, 0x8D, 0xF8, 0x03, 0x00, + 0x8D, 0xF8, 0x05, 0x30, 0x8D, 0xF8, 0x06, 0xC0, 0x00, 0x20, 0x29, 0x5C, + 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28, 0xF9, 0xD3, 0x04, 0xF8, + 0x01, 0x7B, 0x68, 0x46, 0x04, 0xF8, 0x01, 0x6B, 0x20, 0x1A, 0xC2, 0xB2, + 0x69, 0x46, 0x42, 0xF2, 0x06, 0x00, 0x01, 0xF0, 0xD7, 0xFC, 0x04, 0xB0, + 0xBD, 0xE8, 0xF0, 0x81, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x35, 0x00, + 0x00, 0xF0, 0x94, 0xBA, 0x1C, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, + 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, + 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x20, 0x10, 0x0A, 0x8D, 0xF8, 0x05, 0x00, + 0x06, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x22, 0x00, 0x01, 0xF0, 0xB8, 0xFC, + 0x1C, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, + 0x8D, 0xF8, 0x02, 0x20, 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x31, 0x00, + 0x01, 0xF0, 0xAA, 0xFC, 0x08, 0xBD, 0x1C, 0xB5, 0xFF, 0x20, 0x8D, 0xF8, + 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x00, 0x7F, 0x20, 0x8D, 0xF8, 0x02, 0x00, + 0x00, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x8D, 0xF8, 0x05, 0x00, 0x8D, 0xF8, + 0x06, 0x00, 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x07, 0x00, 0x08, 0x22, + 0x69, 0x46, 0x42, 0xF2, 0x01, 0x00, 0x01, 0xF0, 0x8F, 0xFC, 0x1C, 0xBD, + 0x30, 0xB5, 0xC1, 0xB0, 0x0D, 0xF1, 0x02, 0x03, 0x8D, 0xF8, 0x00, 0x00, + 0x8D, 0xF8, 0x01, 0x10, 0x00, 0x20, 0x13, 0xE0, 0x00, 0xEB, 0x40, 0x04, + 0x12, 0xF8, 0x14, 0x50, 0x02, 0xEB, 0x44, 0x04, 0x03, 0xF8, 0x01, 0x5B, + 0xA5, 0x78, 0x03, 0xF8, 0x01, 0x5B, 0x65, 0x88, 0x2D, 0x0A, 0x03, 0xF8, + 0x02, 0x5B, 0x24, 0x79, 0x40, 0x1C, 0x03, 0xF8, 0x01, 0x4C, 0xC0, 0xB2, + 0x88, 0x42, 0xE9, 0xD3, 0x68, 0x46, 0x18, 0x1A, 0xC2, 0xB2, 0x69, 0x46, + 0x42, 0xF2, 0x39, 0x00, 0x01, 0xF0, 0x66, 0xFC, 0x41, 0xB0, 0x30, 0xBD, + 0x70, 0xB5, 0xC0, 0xB0, 0x01, 0xAC, 0x8D, 0xF8, 0x00, 0x10, 0xDD, 0xE9, + 0x44, 0x56, 0x8D, 0xF8, 0x01, 0x20, 0x8D, 0xF8, 0x02, 0x30, 0x8D, 0xF8, + 0x03, 0x50, 0x00, 0x21, 0x03, 0xE0, 0x72, 0x5C, 0x04, 0xF8, 0x01, 0x2B, + 0x49, 0x1C, 0xA9, 0x42, 0xF9, 0xD3, 0x69, 0x46, 0x61, 0x1A, 0xCA, 0xB2, + 0x69, 0x46, 0x01, 0xF0, 0x49, 0xFC, 0x40, 0xB0, 0x70, 0xBD, 0x2D, 0xE9, + 0xF0, 0x4F, 0x87, 0xB0, 0x6C, 0x46, 0xDD, 0xE9, 0x14, 0xEC, 0x19, 0x9E, + 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x08, 0x0A, 0xDD, 0xE9, + 0x10, 0x9A, 0x8D, 0xF8, 0x02, 0x00, 0x10, 0x0A, 0x8D, 0xF8, 0x04, 0x00, + 0x10, 0x0C, 0x8D, 0xF8, 0x05, 0x00, 0xDD, 0xE9, 0x16, 0x7B, 0x8D, 0xF8, + 0x06, 0x30, 0x18, 0x0A, 0x8D, 0xF8, 0x07, 0x00, 0xDD, 0xE9, 0x12, 0x85, + 0x18, 0x0C, 0x8D, 0xF8, 0x08, 0x00, 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8, + 0x09, 0x90, 0x04, 0xF8, 0x0A, 0xAF, 0x00, 0x20, 0x84, 0xF8, 0x01, 0x80, + 0xA4, 0x1C, 0x29, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x06, 0x28, + 0xF9, 0xD3, 0x04, 0xF8, 0x01, 0xEB, 0x69, 0x46, 0x04, 0xF8, 0x01, 0xCB, + 0x04, 0xF8, 0x01, 0x7B, 0x04, 0xF8, 0x03, 0xBB, 0x18, 0x98, 0x04, 0xF8, + 0x02, 0x0C, 0x04, 0xF8, 0x01, 0x6C, 0x1A, 0x98, 0x04, 0xF8, 0x01, 0x0B, + 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x42, 0xF2, 0x36, 0x00, 0x01, 0xF0, + 0xFD, 0xFB, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0xB5, 0x8D, 0xF8, + 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x10, 0x0A, + 0x8D, 0xF8, 0x03, 0x00, 0x8D, 0xF8, 0x04, 0x30, 0x18, 0x0A, 0x8D, 0xF8, + 0x05, 0x00, 0x06, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x42, 0x00, 0x01, 0xF0, + 0xE5, 0xFB, 0x1C, 0xBD, 0x7F, 0xB5, 0x0D, 0xF1, 0x03, 0x04, 0x8D, 0xF8, + 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x02, 0xF0, + 0x05, 0x00, 0x00, 0x22, 0x03, 0xE0, 0x52, 0x1C, 0x41, 0x1E, 0xD2, 0xB2, + 0x08, 0x40, 0x00, 0x28, 0xF9, 0xD1, 0x17, 0xE0, 0x00, 0xEB, 0x40, 0x01, + 0x13, 0xF8, 0x11, 0x50, 0x03, 0xEB, 0x41, 0x01, 0x04, 0xF8, 0x01, 0x5B, + 0x8D, 0x78, 0x04, 0xF8, 0x01, 0x5B, 0x4D, 0x88, 0x2D, 0x0A, 0x04, 0xF8, + 0x02, 0x5B, 0x0D, 0x79, 0x04, 0xF8, 0x01, 0x5C, 0x89, 0x88, 0x09, 0x0A, + 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0xC0, 0xB2, 0x90, 0x42, 0xE5, 0xD3, + 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, 0x41, 0x00, + 0x01, 0xF0, 0xAE, 0xFB, 0x04, 0xB0, 0x70, 0xBD, 0x1C, 0xB5, 0x6A, 0x46, + 0x00, 0x21, 0x43, 0x5C, 0x49, 0x1C, 0x02, 0xF8, 0x01, 0x3B, 0x05, 0x29, + 0xF9, 0xD3, 0x68, 0x46, 0x10, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, + 0x14, 0x00, 0x01, 0xF0, 0x9B, 0xFB, 0x1C, 0xBD, 0x1C, 0xB5, 0x8D, 0xF8, + 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00, 0x04, 0x9C, 0x8D, 0xF8, + 0x02, 0x10, 0x8D, 0xF8, 0x04, 0x30, 0x8D, 0xF8, 0x05, 0x40, 0x20, 0x0A, + 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8, 0x06, 0x00, 0x07, 0x22, 0x69, 0x46, + 0x42, 0xF2, 0x32, 0x00, 0x01, 0xF0, 0x82, 0xFB, 0x1C, 0xBD, 0x1C, 0xB5, + 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x5C, + 0x40, 0x1C, 0x03, 0xF8, 0x01, 0x4B, 0x06, 0x28, 0xF9, 0xD3, 0x03, 0xF8, + 0x01, 0x2B, 0x68, 0x46, 0x18, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, + 0x4E, 0x00, 0x01, 0xF0, 0x6B, 0xFB, 0x1C, 0xBD, 0x01, 0x46, 0x42, 0xF2, + 0x05, 0x00, 0xFF, 0xF7, 0x40, 0xBB, 0x01, 0x46, 0x42, 0xF2, 0x2E, 0x00, + 0x00, 0xF0, 0xFE, 0xB8, 0x08, 0xB5, 0x02, 0x22, 0x8D, 0xF8, 0x00, 0x00, + 0x8D, 0xF8, 0x01, 0x10, 0x69, 0x46, 0x42, 0xF2, 0x0C, 0x00, 0x01, 0xF0, + 0x55, 0xFB, 0x08, 0xBD, 0x1C, 0xB5, 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, + 0x01, 0x10, 0x08, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x10, 0x0A, 0x8D, 0xF8, + 0x04, 0x00, 0x04, 0x9C, 0x8D, 0xF8, 0x03, 0x20, 0x8D, 0xF8, 0x05, 0x30, + 0x8D, 0xF8, 0x06, 0x40, 0x07, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x0B, 0x00, + 0x01, 0xF0, 0x3C, 0xFB, 0x1C, 0xBD, 0x30, 0xB5, 0x87, 0xB0, 0x0D, 0xF1, + 0x02, 0x04, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x01, 0x00, + 0x00, 0x20, 0x0D, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x5B, 0x08, 0x28, + 0xF9, 0xD3, 0x04, 0xF8, 0x01, 0x2B, 0x10, 0x0A, 0x04, 0xF8, 0x01, 0x0B, + 0x00, 0x20, 0x19, 0x5C, 0x40, 0x1C, 0x04, 0xF8, 0x01, 0x1B, 0x10, 0x28, + 0xF9, 0xD3, 0x68, 0x46, 0x20, 0x1A, 0xC2, 0xB2, 0x69, 0x46, 0x42, 0xF2, + 0x19, 0x00, 0x01, 0xF0, 0x17, 0xFB, 0x07, 0xB0, 0x30, 0xBD, 0x42, 0xF2, + 0x1F, 0x00, 0x00, 0xF0, 0x28, 0xB8, 0x08, 0xB5, 0x00, 0x23, 0x00, 0x93, + 0x8D, 0xF8, 0x00, 0x00, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, + 0x03, 0x22, 0x69, 0x46, 0x42, 0xF2, 0x1E, 0x00, 0x01, 0xF0, 0x02, 0xFB, + 0x08, 0xBD, 0x08, 0xB5, 0x04, 0x22, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x0A, + 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x08, 0x0A, 0x8D, 0xF8, + 0x03, 0x00, 0x69, 0x46, 0x42, 0xF2, 0x4D, 0x00, 0x01, 0xF0, 0xF0, 0xFA, + 0x08, 0xBD, 0x0A, 0x46, 0x01, 0x46, 0x42, 0xF2, 0x24, 0x00, 0x00, 0xF0, + 0x92, 0xB8, 0x00, 0x22, 0x11, 0x46, 0x01, 0xF0, 0xE5, 0xBA, 0x1C, 0xB5, + 0x01, 0x78, 0x8D, 0xF8, 0x00, 0x10, 0x41, 0x78, 0x8D, 0xF8, 0x01, 0x10, + 0x81, 0x78, 0x8D, 0xF8, 0x02, 0x10, 0xC1, 0x78, 0x8D, 0xF8, 0x03, 0x10, + 0x01, 0x79, 0x8D, 0xF8, 0x04, 0x10, 0x41, 0x79, 0x8D, 0xF8, 0x05, 0x10, + 0x81, 0x79, 0x8D, 0xF8, 0x06, 0x10, 0xC0, 0x79, 0x8D, 0xF8, 0x07, 0x00, + 0x08, 0x22, 0x69, 0x46, 0x40, 0xF6, 0x01, 0x40, 0x01, 0xF0, 0xC6, 0xFA, + 0x1C, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x2C, 0x4F, 0x01, 0x78, + 0x42, 0x78, 0x3A, 0x71, 0x82, 0x78, 0xC0, 0x78, 0x02, 0xEB, 0x00, 0x20, + 0x84, 0xB2, 0x08, 0x46, 0x00, 0xF0, 0xA6, 0xF9, 0x06, 0x46, 0x78, 0x78, + 0x28, 0xB9, 0x24, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x24, 0x49, 0x25, 0x48, + 0x3E, 0xE0, 0xF8, 0x8C, 0x00, 0x25, 0xA0, 0x42, 0x00, 0xD1, 0xFD, 0x84, + 0x00, 0x2C, 0x10, 0xD0, 0xA4, 0xF5, 0x80, 0x60, 0x06, 0x38, 0x0E, 0xD0, + 0x17, 0x28, 0x11, 0xD0, 0x3F, 0x20, 0xB0, 0xEB, 0x94, 0x2F, 0x1D, 0xD1, + 0x00, 0x23, 0x32, 0x46, 0x21, 0x46, 0x18, 0x46, 0x00, 0x95, 0xF7, 0xF7, + 0xEB, 0xF8, 0xBD, 0xE8, 0xFC, 0x81, 0xF8, 0x8D, 0x00, 0xF0, 0xA8, 0xF9, + 0xA0, 0xB9, 0xF8, 0xE7, 0xF8, 0x8D, 0x00, 0xF0, 0xA3, 0xF9, 0x00, 0x28, + 0xF3, 0xD0, 0x00, 0x2E, 0xF1, 0xD0, 0x00, 0x95, 0x01, 0x95, 0x42, 0x78, + 0x01, 0x1D, 0x00, 0x23, 0x30, 0x46, 0xF8, 0xF7, 0x93, 0xFD, 0xE8, 0xE7, + 0x08, 0x20, 0xB0, 0xEB, 0x94, 0x2F, 0x05, 0xD1, 0x31, 0x46, 0x20, 0x46, + 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0xF0, 0xFE, 0xBE, 0x06, 0x49, 0x07, 0x48, + 0x01, 0x22, 0x3C, 0x31, 0x23, 0x46, 0x40, 0x1C, 0x02, 0xB0, 0xBD, 0xE8, + 0xF0, 0x41, 0xEB, 0xF7, 0x02, 0x9E, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, + 0xF4, 0x09, 0xC0, 0x08, 0x01, 0x3C, 0x10, 0x21, 0x08, 0xB5, 0x02, 0x22, + 0x8D, 0xF8, 0x00, 0x10, 0x09, 0x0A, 0x8D, 0xF8, 0x01, 0x10, 0x69, 0x46, + 0x01, 0xF0, 0x58, 0xFA, 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x10, + 0x09, 0x0A, 0x8D, 0xF8, 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x11, 0x0A, + 0x8D, 0xF8, 0x03, 0x10, 0x04, 0x22, 0x69, 0x46, 0x01, 0xF0, 0x48, 0xFA, + 0x08, 0xBD, 0x08, 0xB5, 0x8D, 0xF8, 0x00, 0x10, 0x09, 0x0A, 0x8D, 0xF8, + 0x01, 0x10, 0x8D, 0xF8, 0x02, 0x20, 0x03, 0x22, 0x69, 0x46, 0x01, 0xF0, + 0x3B, 0xFA, 0x08, 0xBD, 0x1C, 0xB5, 0x0D, 0xF1, 0x01, 0x03, 0x8D, 0xF8, + 0x00, 0x10, 0x00, 0x21, 0x54, 0x5C, 0x49, 0x1C, 0x03, 0xF8, 0x01, 0x4B, + 0x06, 0x29, 0xF9, 0xD3, 0x69, 0x46, 0x59, 0x1A, 0xCA, 0xB2, 0x69, 0x46, + 0x01, 0xF0, 0x28, 0xFA, 0x1C, 0xBD, 0x08, 0xB5, 0x01, 0x22, 0x8D, 0xF8, + 0x00, 0x10, 0x69, 0x46, 0x01, 0xF0, 0x20, 0xFA, 0x08, 0xBD, 0x01, 0xF0, + 0x1D, 0xBA, 0x00, 0x00, 0x7C, 0xB5, 0x41, 0x78, 0x82, 0x78, 0xC6, 0x78, + 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x28, 0x46, 0x00, 0xF0, 0x2A, 0xF9, + 0x04, 0x00, 0x0E, 0xD0, 0x28, 0x46, 0x09, 0xF0, 0xDD, 0xFC, 0xA0, 0xB3, + 0x00, 0x22, 0x1F, 0x49, 0x1F, 0x48, 0xEB, 0xF7, 0xA0, 0xDD, 0x20, 0x7D, + 0x40, 0xF0, 0x10, 0x00, 0x20, 0x75, 0x66, 0x75, 0x7C, 0xBD, 0x1C, 0x4C, + 0x2B, 0x46, 0x03, 0x22, 0x14, 0xF8, 0x60, 0x0F, 0xC0, 0xF3, 0xC0, 0x00, + 0x61, 0x88, 0xCD, 0xE9, 0x00, 0x10, 0x15, 0x49, 0x15, 0x48, 0x6C, 0x39, + 0x40, 0x1E, 0xEB, 0xF7, 0x8A, 0xDD, 0x14, 0xF8, 0x60, 0x09, 0x01, 0x07, + 0xEA, 0xD5, 0xB4, 0xF8, 0x62, 0x10, 0xA9, 0x42, 0xE6, 0xD1, 0x20, 0xF0, + 0x08, 0x00, 0x84, 0xF8, 0x60, 0x00, 0x00, 0x21, 0xA4, 0xF8, 0x62, 0x10, + 0x80, 0x07, 0xDD, 0xD5, 0x01, 0x20, 0xFF, 0xF7, 0xAD, 0xFC, 0x14, 0xF8, + 0x60, 0x0F, 0x40, 0xF0, 0x04, 0x00, 0x20, 0x70, 0x7C, 0xBD, 0xFF, 0xE7, + 0x31, 0x46, 0x28, 0x46, 0x01, 0xF0, 0x29, 0xF8, 0x20, 0x1D, 0xBD, 0xE8, + 0x7C, 0x40, 0x00, 0xF0, 0xFF, 0xB8, 0x00, 0x00, 0x5C, 0x0C, 0xC0, 0x08, + 0x01, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x10, 0xB5, 0x0A, 0x48, + 0x86, 0xB0, 0x0D, 0xF1, 0x04, 0x0C, 0x01, 0x8F, 0xC4, 0x8F, 0x83, 0x8F, + 0x42, 0x8F, 0x8C, 0xE8, 0x1E, 0x00, 0xC1, 0x8E, 0x00, 0x91, 0x83, 0x8E, + 0x06, 0x22, 0x04, 0x49, 0x04, 0x48, 0xEB, 0xF7, 0x4C, 0xDD, 0x06, 0xB0, + 0x10, 0xBD, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0xD0, 0x11, 0xC0, 0x08, + 0x03, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x20, 0xB1, 0x01, 0x28, 0x02, 0xD0, + 0x40, 0xF4, 0x80, 0x70, 0x1D, 0xE0, 0x15, 0x4C, 0x15, 0x4E, 0x4F, 0xF0, + 0x80, 0x45, 0xA0, 0x78, 0x01, 0x22, 0x00, 0xF0, 0x03, 0x03, 0x13, 0x49, + 0x30, 0x46, 0xEB, 0xF7, 0x30, 0xDD, 0xA0, 0x78, 0x10, 0xF0, 0x03, 0x01, + 0x05, 0xEB, 0xB0, 0x00, 0x4F, 0xEA, 0xB0, 0x70, 0xA0, 0x70, 0x0C, 0xD0, + 0x01, 0x29, 0x0D, 0xD0, 0x03, 0x29, 0xEA, 0xD1, 0xC0, 0xB2, 0x40, 0xF0, + 0x04, 0x00, 0xA0, 0x70, 0x00, 0x20, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7, + 0xD3, 0xBD, 0x42, 0xF2, 0x3A, 0x00, 0x01, 0xE0, 0x42, 0xF2, 0x3B, 0x00, + 0xBD, 0xE8, 0x70, 0x40, 0xFF, 0xF7, 0x8F, 0xBE, 0xF0, 0x75, 0x20, 0x00, + 0x03, 0x3C, 0x10, 0x21, 0x44, 0x09, 0xC0, 0x08, 0x70, 0xB5, 0x41, 0x78, + 0x82, 0x78, 0x04, 0x78, 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0xC6, 0x78, + 0x28, 0x46, 0x00, 0xF0, 0x7F, 0xF8, 0x00, 0x28, 0x09, 0xD0, 0x20, 0x46, + 0x00, 0xF0, 0x52, 0xF8, 0x02, 0x46, 0x31, 0x46, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x0A, 0xF0, 0x13, 0xBC, 0x70, 0xBD, 0x70, 0xB5, 0x04, 0x78, + 0x41, 0x78, 0x80, 0x78, 0x01, 0xEB, 0x00, 0x20, 0x85, 0xB2, 0x28, 0x46, + 0x00, 0xF0, 0x68, 0xF8, 0x00, 0x28, 0x05, 0xD0, 0x21, 0x46, 0x28, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x0A, 0xF0, 0x88, 0xB9, 0x70, 0xBD, 0x00, 0x00, + 0x00, 0xB5, 0x17, 0x48, 0x85, 0xB0, 0x40, 0xF2, 0x9E, 0x23, 0x14, 0x4A, + 0x69, 0x46, 0x00, 0x78, 0xF3, 0xF7, 0x1E, 0xFD, 0x88, 0xB1, 0xBD, 0xF8, + 0x00, 0x30, 0x18, 0x46, 0xB3, 0xF5, 0x00, 0x7F, 0x17, 0xD0, 0xA3, 0xF5, + 0x00, 0x73, 0x01, 0x3B, 0x0F, 0xD0, 0x01, 0x2B, 0x09, 0xD0, 0x03, 0x46, + 0x01, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xEB, 0xF7, 0xC2, 0xDC, 0x01, 0xF0, + 0x63, 0xFA, 0x05, 0xB0, 0x00, 0xBD, 0x68, 0x46, 0x00, 0xF0, 0x9D, 0xF9, + 0xF7, 0xE7, 0x68, 0x46, 0x00, 0xF0, 0xB6, 0xF9, 0xF3, 0xE7, 0x68, 0x46, + 0x00, 0xF0, 0xD8, 0xF9, 0xEF, 0xE7, 0x00, 0x00, 0x54, 0xA7, 0x82, 0x00, + 0xEC, 0x75, 0x20, 0x00, 0x60, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, + 0x00, 0x28, 0x01, 0xD0, 0x40, 0xF4, 0x80, 0x70, 0x70, 0x47, 0x00, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24, 0x0C, 0x4E, 0x0D, 0x4F, + 0x0C, 0xE0, 0x30, 0x6B, 0x00, 0xEB, 0x44, 0x15, 0x28, 0x78, 0x28, 0xB1, + 0x06, 0x22, 0x41, 0x46, 0x28, 0x1D, 0x1D, 0xF4, 0x5B, 0xF5, 0x40, 0xB1, + 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xEE, 0xD8, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x28, 0x46, 0xFB, 0xE7, 0x00, 0x00, + 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46, + 0x09, 0x48, 0x00, 0x21, 0x02, 0x6B, 0x09, 0x48, 0x90, 0xF8, 0x98, 0x31, + 0x08, 0xE0, 0x02, 0xEB, 0x41, 0x10, 0x05, 0x78, 0x15, 0xB1, 0x45, 0x88, + 0xA5, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0x89, 0xB2, 0x8B, 0x42, 0xF4, 0xD8, + 0x00, 0x20, 0x30, 0xBD, 0xF0, 0x75, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x30, 0xB5, 0x87, 0xB0, 0x05, 0x46, 0xFF, 0xF7, 0xBF, 0xFF, 0x04, 0x46, + 0x29, 0x46, 0x14, 0x48, 0xEB, 0xF7, 0x2C, 0xDE, 0x03, 0x46, 0x02, 0x22, + 0x12, 0x49, 0x13, 0x48, 0x00, 0x94, 0xEB, 0xF7, 0x56, 0xDC, 0x00, 0x2C, + 0x19, 0xD0, 0x04, 0xF1, 0x0C, 0x05, 0x55, 0x23, 0x0F, 0x4A, 0x01, 0xA9, + 0x28, 0x46, 0xF3, 0xF7, 0xEF, 0xFF, 0x48, 0xB1, 0xBD, 0xF8, 0x08, 0x00, + 0xC0, 0x07, 0xF4, 0xD0, 0x59, 0x22, 0x0A, 0x49, 0x04, 0x98, 0xF3, 0xF7, + 0xC5, 0xFA, 0xEE, 0xE7, 0x08, 0x49, 0x00, 0x20, 0x20, 0x70, 0x31, 0xF8, + 0x46, 0x0F, 0x40, 0x1E, 0x08, 0x80, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0x48, 0x12, 0xC0, 0x08, 0x02, 0x3C, 0x10, 0x21, + 0x67, 0xA7, 0x82, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x0E, 0x49, 0x0A, 0x6A, + 0x02, 0x60, 0x8A, 0x8C, 0x82, 0x80, 0x8A, 0x6C, 0xC0, 0xF8, 0x06, 0x20, + 0xCA, 0x6C, 0xC0, 0xF8, 0x0A, 0x20, 0x91, 0xF8, 0x50, 0x20, 0xC2, 0x73, + 0x91, 0xF8, 0x51, 0x20, 0x82, 0x73, 0xB1, 0xF8, 0x56, 0x20, 0x82, 0x82, + 0x91, 0xF8, 0x52, 0x20, 0x02, 0x74, 0x91, 0xF8, 0x53, 0x20, 0x42, 0x74, + 0x91, 0xF8, 0x54, 0x10, 0x81, 0x74, 0x70, 0x47, 0xF0, 0x75, 0x20, 0x00, + 0x10, 0xB5, 0xFF, 0xF7, 0x89, 0xFF, 0x00, 0x28, 0x00, 0xD0, 0x16, 0x30, + 0x10, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x2E, 0x48, + 0xDF, 0xF8, 0xB8, 0x90, 0x85, 0xB0, 0x40, 0x78, 0xB8, 0xB3, 0xE1, 0x88, + 0xE0, 0x68, 0x45, 0x18, 0x15, 0xF8, 0x01, 0x0B, 0x15, 0xF8, 0x01, 0x1B, + 0x00, 0xEB, 0x01, 0x20, 0x15, 0xF8, 0x01, 0x1B, 0xC0, 0xF3, 0x01, 0x38, + 0x15, 0xF8, 0x01, 0x2B, 0xC0, 0xF3, 0x0B, 0x07, 0x01, 0xEB, 0x02, 0x21, + 0x8E, 0xB2, 0x38, 0x46, 0xFF, 0xF7, 0x64, 0xFF, 0x68, 0xB3, 0x4F, 0xF4, + 0x40, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0xE0, 0x68, 0x03, 0x90, 0xA0, 0x89, + 0xAD, 0xF8, 0x08, 0x60, 0x28, 0x1A, 0xAD, 0xF8, 0x06, 0x00, 0xB8, 0xF1, + 0x01, 0x0F, 0x1C, 0xD0, 0x08, 0x20, 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8, + 0x04, 0x00, 0x18, 0x48, 0xAD, 0xF8, 0x0A, 0x70, 0x68, 0x23, 0x15, 0x4A, + 0x69, 0x46, 0x00, 0x78, 0xF3, 0xF7, 0x62, 0xFC, 0x05, 0xB0, 0xBD, 0xE8, + 0xF0, 0x83, 0xFF, 0xE7, 0x00, 0x22, 0x12, 0x49, 0x48, 0x46, 0xEB, 0xF7, + 0xBE, 0xDB, 0x20, 0x79, 0xC0, 0x07, 0xF3, 0xD0, 0x4C, 0x22, 0xE0, 0x68, + 0x0D, 0xE0, 0x10, 0x20, 0xE1, 0xE7, 0x0C, 0x49, 0x3B, 0x46, 0x01, 0x22, + 0x34, 0x31, 0x48, 0x46, 0xEB, 0xF7, 0xAF, 0xDB, 0x20, 0x79, 0xC0, 0x07, + 0xE4, 0xD0, 0xE0, 0x68, 0x70, 0x22, 0x04, 0x49, 0xF3, 0xF7, 0x2A, 0xFA, + 0xDE, 0xE7, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x01, 0x3C, 0x10, 0x21, + 0xE6, 0xA6, 0x82, 0x00, 0x64, 0x76, 0x20, 0x00, 0x74, 0x0F, 0xC0, 0x08, + 0xC1, 0x68, 0xC0, 0x88, 0x22, 0x4A, 0x08, 0x44, 0x10, 0xF8, 0x01, 0x3B, + 0x52, 0x78, 0x10, 0xF8, 0x01, 0x1B, 0x3A, 0xB9, 0x0E, 0x2B, 0x05, 0xD0, + 0x0F, 0x2B, 0x03, 0xD0, 0x01, 0x22, 0x1D, 0x49, 0x1D, 0x48, 0x1C, 0xE0, + 0x10, 0x2B, 0x26, 0xD0, 0x0C, 0xDC, 0x0C, 0x2B, 0x1F, 0xD0, 0x04, 0xDC, + 0x05, 0x2B, 0x1A, 0xD0, 0x08, 0x2B, 0x0D, 0xD1, 0x20, 0xE0, 0x0E, 0x2B, + 0x11, 0xD0, 0x0F, 0x2B, 0x08, 0xD1, 0x10, 0xE0, 0x13, 0x2B, 0x14, 0xD0, + 0x30, 0x2B, 0x19, 0xD0, 0x3E, 0x2B, 0x19, 0xD0, 0xFF, 0x2B, 0x1A, 0xD0, + 0x0F, 0x49, 0x10, 0x48, 0x01, 0x22, 0x38, 0x31, 0x40, 0x1E, 0xEB, 0xF7, + 0x6A, 0x9B, 0xFE, 0xF7, 0xBF, 0xBF, 0xFF, 0xF7, 0x09, 0xBD, 0xFF, 0xF7, + 0xAF, 0xBD, 0x00, 0xF0, 0x41, 0xBF, 0x00, 0xF0, 0xF9, 0xBE, 0x00, 0x78, + 0xF6, 0xF7, 0x82, 0xBE, 0xFF, 0xF7, 0x50, 0xBE, 0xFF, 0xF7, 0x66, 0xBE, + 0x89, 0x1C, 0x00, 0xF0, 0x09, 0xB8, 0xF6, 0xF7, 0x4B, 0xBE, 0x00, 0x00, + 0xF0, 0x75, 0x20, 0x00, 0xD8, 0x0F, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, + 0x10, 0xF8, 0x01, 0x1B, 0x15, 0x29, 0x29, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x28, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x28, 0x15, 0x28, 0x28, 0x0B, 0x17, + 0x19, 0x1F, 0x28, 0x28, 0x28, 0x21, 0x1B, 0x1D, 0x26, 0x00, 0x00, 0xF0, + 0x89, 0xBC, 0x00, 0xF0, 0xE1, 0xB9, 0x00, 0xF0, 0x87, 0xBD, 0x00, 0xF0, + 0x97, 0xBE, 0x00, 0xF0, 0x69, 0xBE, 0x00, 0xF0, 0xA2, 0xBD, 0x00, 0xF0, + 0xBF, 0xBD, 0x00, 0xF0, 0x7C, 0xBE, 0x00, 0xF0, 0x27, 0xBA, 0x00, 0xF0, + 0xAE, 0xBE, 0x00, 0xF0, 0xFB, 0xBD, 0x00, 0x21, 0x4F, 0xF4, 0xD8, 0x70, + 0xF8, 0xF7, 0x35, 0xBB, 0x00, 0xF0, 0x35, 0xBA, 0x70, 0x47, 0x10, 0xB5, + 0x04, 0x46, 0xC1, 0x68, 0xC0, 0x88, 0x01, 0x44, 0x40, 0x1C, 0xE0, 0x80, + 0x20, 0x89, 0x40, 0x1E, 0x20, 0x81, 0x08, 0x78, 0x02, 0x28, 0x09, 0xD0, + 0x04, 0x28, 0x0C, 0xD1, 0x20, 0x46, 0xFF, 0xF7, 0x71, 0xFF, 0x20, 0x69, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x10, 0xB9, 0x20, 0x46, 0xBD, 0xE8, + 0x10, 0x40, 0xFF, 0xF7, 0xFD, 0xBE, 0x10, 0xBD, 0x38, 0xB5, 0xC1, 0x68, + 0x09, 0x78, 0x02, 0x29, 0x07, 0xD1, 0x0C, 0x49, 0x31, 0xF8, 0x3E, 0x2F, + 0x52, 0x1C, 0x0A, 0x80, 0x4A, 0x88, 0x52, 0x1C, 0x4A, 0x80, 0xC3, 0x68, + 0x02, 0x22, 0x08, 0x49, 0x53, 0xF8, 0x04, 0x4C, 0x07, 0x48, 0x00, 0x94, + 0xEB, 0xF7, 0xEB, 0xDA, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x40, 0xF2, + 0x2B, 0x12, 0x04, 0x49, 0xF3, 0xF7, 0x66, 0xB9, 0xF0, 0x75, 0x20, 0x00, + 0x40, 0x10, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF9, 0xA6, 0x82, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0xC3, 0x88, 0x28, 0x4F, 0x04, 0x46, 0x10, 0x2B, + 0x0B, 0xD2, 0x01, 0x22, 0x26, 0x49, 0x38, 0x46, 0xEB, 0xF7, 0xCF, 0xDA, + 0x20, 0x79, 0xC0, 0x07, 0x42, 0xD0, 0x40, 0xF2, 0x3B, 0x12, 0xE0, 0x68, + 0x23, 0xE0, 0x60, 0x89, 0xC0, 0xF3, 0x0B, 0x05, 0x28, 0x46, 0xFF, 0xF7, + 0x41, 0xFE, 0x06, 0x00, 0x0E, 0xD0, 0x21, 0x89, 0x48, 0x1D, 0x20, 0x81, + 0xE0, 0x88, 0x40, 0x1F, 0x80, 0xB2, 0xE0, 0x80, 0xE2, 0x68, 0x10, 0x44, + 0xA2, 0x88, 0xD3, 0x06, 0x14, 0xD5, 0x45, 0xF4, 0x80, 0x55, 0x15, 0xE0, + 0x15, 0x49, 0x2B, 0x46, 0x01, 0x22, 0x30, 0x31, 0x38, 0x46, 0xEB, 0xF7, + 0xAA, 0xDA, 0x20, 0x79, 0xC0, 0x07, 0x1D, 0xD0, 0xE0, 0x68, 0x40, 0xF2, + 0x49, 0x12, 0xBD, 0xE8, 0xF0, 0x41, 0x0F, 0x49, 0xF3, 0xF7, 0x22, 0xB9, + 0x52, 0x06, 0x01, 0xD5, 0x45, 0xF4, 0x00, 0x55, 0x02, 0x22, 0x02, 0x70, + 0x45, 0x70, 0x2A, 0x0A, 0x82, 0x70, 0xC1, 0x70, 0x09, 0x0A, 0x01, 0x71, + 0x21, 0x46, 0x06, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF0, 0x41, 0x4F, 0xF4, + 0xB4, 0x73, 0x04, 0x4A, 0xF3, 0xF7, 0x56, 0xBE, 0xBD, 0xE8, 0xF0, 0x81, + 0x00, 0x3C, 0x10, 0x21, 0x6C, 0x10, 0xC0, 0x08, 0x13, 0xA7, 0x82, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x1E, 0x46, 0x14, 0x46, 0x00, 0x91, + 0xCD, 0xE9, 0x01, 0x46, 0x0F, 0x46, 0x80, 0x46, 0x03, 0x46, 0x01, 0x25, + 0x04, 0x22, 0x38, 0x49, 0x38, 0x48, 0xEB, 0xF7, 0x70, 0xDA, 0x43, 0x46, + 0xDF, 0xF8, 0xDC, 0x80, 0x02, 0x22, 0x08, 0xF1, 0x04, 0x01, 0x01, 0xF1, + 0x20, 0x00, 0x05, 0x2B, 0x5E, 0xD2, 0xDF, 0xE8, 0x03, 0xF0, 0x4D, 0x5D, + 0x03, 0x37, 0x49, 0x00, 0x08, 0x8F, 0x00, 0x25, 0x40, 0x1C, 0x08, 0x87, + 0x23, 0x78, 0x02, 0x2B, 0x09, 0xD0, 0x04, 0x2B, 0x09, 0xD0, 0x2A, 0x49, + 0x2A, 0x48, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xEB, 0xF7, 0x51, 0xDA, + 0x1E, 0xE0, 0x4D, 0x89, 0x62, 0x55, 0x76, 0x1B, 0x62, 0x19, 0xB1, 0xB2, + 0x26, 0x48, 0xEB, 0xF7, 0x6F, 0xDB, 0x40, 0xF2, 0x02, 0x20, 0xAD, 0xF8, + 0x00, 0x00, 0xAD, 0xF8, 0x06, 0x50, 0x01, 0x20, 0x03, 0x94, 0xAD, 0xF8, + 0x08, 0x60, 0xAD, 0xF8, 0x04, 0x00, 0x04, 0x94, 0x40, 0xF2, 0xAB, 0x13, + 0x1E, 0x4A, 0x69, 0x46, 0x98, 0xF8, 0x00, 0x00, 0xF3, 0xF7, 0xCE, 0xFA, + 0x05, 0x00, 0x29, 0xD1, 0x20, 0x46, 0x00, 0xF0, 0x37, 0xF8, 0x25, 0xE0, + 0x40, 0xF2, 0x01, 0x20, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0xC8, 0x8E, + 0x4F, 0xF4, 0xDF, 0x73, 0x40, 0x1C, 0xC8, 0x86, 0x13, 0x4A, 0x69, 0x46, + 0x98, 0xF8, 0x00, 0x00, 0xF3, 0xF7, 0xB8, 0xFA, 0x05, 0x46, 0x13, 0xE0, + 0x97, 0xB9, 0x4F, 0xF4, 0xB3, 0x71, 0x0D, 0xE0, 0x57, 0xB1, 0x0A, 0x70, + 0x00, 0x20, 0x48, 0x70, 0xC8, 0x78, 0x01, 0x28, 0x01, 0xD1, 0x07, 0x20, + 0x48, 0x70, 0x00, 0xF0, 0xEF, 0xFE, 0x03, 0xE0, 0x40, 0xF2, 0x65, 0x11, + 0xF5, 0xF7, 0xB0, 0xF9, 0x06, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81, + 0xD0, 0x10, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xEC, 0x75, 0x20, 0x00, + 0x00, 0x3D, 0x28, 0x21, 0x2D, 0xA7, 0x82, 0x00, 0xF9, 0xF7, 0xA9, 0x9E, + 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, + 0xEB, 0xF7, 0xEF, 0xD9, 0x09, 0x4A, 0x0A, 0x48, 0x51, 0x8F, 0x49, 0x1C, + 0x51, 0x87, 0x00, 0x78, 0x00, 0x28, 0x20, 0x46, 0x01, 0xD0, 0x07, 0x49, + 0x00, 0xE0, 0x07, 0x49, 0x09, 0x68, 0xBD, 0xE8, 0x10, 0x40, 0x08, 0x47, + 0xDC, 0x09, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, + 0xE8, 0x75, 0x20, 0x00, 0x74, 0x05, 0x20, 0x00, 0x78, 0x05, 0x20, 0x00, + 0xF9, 0xF7, 0x71, 0x9E, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x03, 0x46, + 0x00, 0x91, 0x02, 0x22, 0x07, 0x49, 0x08, 0x48, 0xEB, 0xF7, 0xC7, 0xD9, + 0x07, 0x49, 0x08, 0x4A, 0x88, 0x8E, 0x40, 0x1C, 0x88, 0x86, 0x12, 0x68, + 0x01, 0xB0, 0x21, 0x46, 0x28, 0x46, 0xBD, 0xE8, 0x30, 0x40, 0x10, 0x47, + 0xBC, 0x09, 0xC0, 0x08, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, + 0x70, 0x05, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, 0x28, 0x4A, 0x29, 0x49, + 0x10, 0x1F, 0xF3, 0xF7, 0xFB, 0xF8, 0x00, 0x28, 0x48, 0xD0, 0x25, 0x48, + 0x10, 0x30, 0xF3, 0xF7, 0xFC, 0xFC, 0x23, 0x48, 0x18, 0x30, 0xF3, 0xF7, + 0xF8, 0xFC, 0x21, 0x4D, 0x00, 0x26, 0x07, 0x20, 0x2E, 0x70, 0x28, 0x72, + 0x13, 0x20, 0x68, 0x81, 0x0B, 0x20, 0xA8, 0x81, 0xEE, 0x84, 0x7F, 0x20, + 0x85, 0xF8, 0x53, 0x00, 0x85, 0xF8, 0x54, 0x00, 0x05, 0xF1, 0x64, 0x00, + 0xF3, 0xF7, 0xE5, 0xFC, 0x19, 0x4F, 0x85, 0xF8, 0x72, 0x60, 0x97, 0xF8, + 0x98, 0x01, 0x30, 0xB3, 0x41, 0x01, 0x40, 0xF2, 0xE1, 0x23, 0x16, 0x4A, + 0x00, 0x20, 0xF5, 0xF7, 0x17, 0xDF, 0x28, 0x63, 0x00, 0x28, 0x1D, 0xD0, + 0x00, 0x24, 0x4F, 0xF0, 0xFF, 0x08, 0x4F, 0xF0, 0x0A, 0x09, 0x4F, 0xF0, + 0x0C, 0x0A, 0x10, 0xE0, 0x28, 0x6B, 0x09, 0xEB, 0x44, 0x11, 0x00, 0xEB, + 0x44, 0x10, 0x06, 0x70, 0x2A, 0x6B, 0x0A, 0xEB, 0x44, 0x10, 0x02, 0xF8, + 0x01, 0x80, 0x29, 0x6B, 0x08, 0x44, 0xF3, 0xF7, 0xBE, 0xFC, 0x64, 0x1C, + 0xA4, 0xB2, 0x97, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xEA, 0xD8, 0x01, 0x20, + 0xBD, 0xE8, 0xF0, 0x87, 0xF0, 0x75, 0x20, 0x00, 0x99, 0xC6, 0x81, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x5E, 0xA7, 0x82, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x10, 0xF8, 0x01, 0x8B, 0x06, 0x46, 0x00, 0x25, 0x40, 0xE0, 0x23, 0x48, + 0x40, 0xF2, 0x54, 0x53, 0x20, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xF2, 0xF7, + 0xDD, 0xFE, 0x04, 0x00, 0x1E, 0xD0, 0x40, 0xF2, 0x3B, 0x10, 0x60, 0x80, + 0x70, 0x1C, 0x37, 0x78, 0x10, 0xF8, 0x01, 0x3B, 0x00, 0x21, 0x6A, 0x46, + 0x10, 0xF8, 0x01, 0x6B, 0x56, 0x54, 0x49, 0x1C, 0x06, 0x29, 0xF9, 0xD3, + 0x10, 0xF8, 0x01, 0x2B, 0x86, 0x18, 0x1F, 0x2A, 0x0C, 0xD9, 0x00, 0x22, + 0x14, 0x49, 0x15, 0x48, 0xEB, 0xF7, 0x2D, 0xD9, 0x40, 0xF2, 0x65, 0x52, + 0x0F, 0x49, 0x20, 0x46, 0xF2, 0xF7, 0xAA, 0xFF, 0xBD, 0xE8, 0xFC, 0x81, + 0x16, 0xF8, 0x01, 0x1B, 0xA3, 0x72, 0xE7, 0x72, 0x21, 0x73, 0x62, 0x73, + 0x00, 0x99, 0x61, 0x60, 0xBD, 0xF8, 0x04, 0x10, 0x21, 0x81, 0x01, 0x46, + 0x04, 0xF1, 0x0E, 0x00, 0x1D, 0xF4, 0x29, 0xF2, 0x00, 0x21, 0x20, 0x46, + 0xF8, 0xF7, 0x8A, 0xF9, 0x6D, 0x1C, 0xED, 0xB2, 0x45, 0x45, 0xBC, 0xD3, + 0xE4, 0xE7, 0x00, 0x00, 0xD0, 0xA6, 0x82, 0x00, 0x03, 0x74, 0x20, 0x00, + 0x10, 0x0F, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, + 0x81, 0x78, 0xC2, 0x78, 0x04, 0x78, 0x46, 0x78, 0x01, 0xEB, 0x02, 0x21, + 0x07, 0x79, 0x8D, 0xB2, 0x1C, 0xB9, 0x29, 0x46, 0x30, 0x46, 0xF7, 0xF7, + 0xB9, 0xFF, 0x20, 0x46, 0xFF, 0xF7, 0x48, 0xFC, 0x3B, 0x46, 0x2A, 0x46, + 0x31, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0xEF, 0xBD, 0x01, 0x78, + 0x42, 0x78, 0x01, 0xEB, 0x02, 0x21, 0x8A, 0xB2, 0x81, 0x78, 0x10, 0x46, + 0xF7, 0xF7, 0xBE, 0xB8, 0x2D, 0xE9, 0xFC, 0x41, 0x0C, 0x46, 0x6F, 0xF4, + 0x00, 0x51, 0x00, 0xEB, 0x01, 0x0C, 0xE3, 0x49, 0x00, 0x27, 0xE0, 0x4B, + 0xE0, 0x4E, 0x08, 0x78, 0x01, 0xF1, 0x5A, 0x05, 0xBC, 0xF1, 0x4E, 0x0F, + 0x7E, 0xD2, 0xDF, 0xE8, 0x0C, 0xF0, 0x92, 0x57, 0x27, 0x94, 0xFC, 0xA9, + 0x8A, 0xA9, 0xA9, 0x96, 0xFB, 0xFA, 0x94, 0x94, 0x82, 0xF9, 0xF9, 0xF9, + 0xF8, 0xF7, 0xF6, 0x94, 0xF5, 0xF4, 0x94, 0x94, 0x94, 0x3E, 0xF3, 0xF2, + 0xF1, 0x94, 0x94, 0xF0, 0x94, 0xEF, 0x94, 0x94, 0xEE, 0xED, 0xEC, 0xEB, + 0xEA, 0xE9, 0xE8, 0xE7, 0x94, 0xE6, 0xE5, 0x94, 0xE4, 0xE3, 0xD1, 0xC8, + 0xCB, 0xCB, 0xCB, 0xB7, 0xBF, 0xE2, 0xE2, 0x94, 0x94, 0x94, 0xE1, 0xE0, + 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0xAE, 0x94, 0x94, 0xDF, + 0x02, 0x28, 0x6A, 0xD1, 0x00, 0x2C, 0x2A, 0xD1, 0x00, 0x20, 0x0D, 0x18, + 0x12, 0xF8, 0x01, 0x4B, 0x40, 0x1C, 0x85, 0xF8, 0x48, 0x40, 0x08, 0x28, + 0xF7, 0xD3, 0xC3, 0x4A, 0x08, 0x21, 0x48, 0x32, 0x18, 0x46, 0xEB, 0xF7, + 0x00, 0xDB, 0x03, 0x46, 0x01, 0x22, 0xC0, 0x49, 0x14, 0xE0, 0x02, 0x28, + 0x53, 0xD1, 0x00, 0x2C, 0xE7, 0xD1, 0x00, 0x20, 0x69, 0x46, 0x12, 0xF8, + 0x01, 0x4B, 0x0C, 0x54, 0x40, 0x1C, 0x08, 0x28, 0xF9, 0xD3, 0x0A, 0x46, + 0x08, 0x21, 0x18, 0x46, 0xEB, 0xF7, 0xEB, 0xDA, 0xB6, 0x49, 0x01, 0x22, + 0x03, 0x46, 0x30, 0x31, 0x30, 0x46, 0xEB, 0xF7, 0x78, 0xD8, 0x16, 0xE1, + 0x02, 0x28, 0x3A, 0xD1, 0x00, 0x2C, 0x25, 0xD1, 0x10, 0x78, 0x53, 0x78, + 0x94, 0x78, 0x00, 0xEB, 0x03, 0x20, 0x05, 0x04, 0x2D, 0x0C, 0x06, 0xD0, + 0x2C, 0xB1, 0xA1, 0xF8, 0x44, 0x50, 0xA1, 0xF8, 0x42, 0x40, 0xA1, 0xF8, + 0x40, 0x40, 0xA9, 0x49, 0xA6, 0x48, 0x2B, 0x46, 0x02, 0x22, 0x5C, 0x31, + 0x40, 0x1C, 0x00, 0x94, 0xEB, 0xF7, 0x5B, 0xD8, 0x0D, 0xB1, 0x00, 0x2C, + 0x0A, 0xD1, 0xA3, 0x49, 0xA0, 0x48, 0x02, 0x22, 0x90, 0x31, 0x2B, 0x46, + 0x80, 0x1E, 0x00, 0xE0, 0x15, 0xE0, 0x00, 0x94, 0xEB, 0xF7, 0x4D, 0xD8, + 0xEB, 0xE0, 0x02, 0x28, 0x0F, 0xD1, 0x00, 0x2C, 0x02, 0xD1, 0x10, 0x78, + 0x81, 0xF8, 0x50, 0x00, 0xE3, 0xE0, 0x02, 0x28, 0x51, 0xD0, 0x11, 0x78, + 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x33, 0xBC, 0x02, 0x28, + 0x49, 0xD0, 0xBD, 0xE8, 0xFC, 0x81, 0x91, 0xF8, 0x60, 0x00, 0x42, 0x07, + 0x04, 0xD5, 0x20, 0xF0, 0x04, 0x00, 0x81, 0xF8, 0x60, 0x00, 0xF4, 0xE7, + 0x44, 0xB9, 0xC2, 0x07, 0x02, 0xD0, 0x40, 0xF0, 0x02, 0x00, 0x01, 0xE0, + 0x20, 0xF0, 0x02, 0x00, 0x81, 0xF8, 0x60, 0x00, 0x20, 0x46, 0xBD, 0xE8, + 0xFC, 0x41, 0xFC, 0xF7, 0xD3, 0xBC, 0x02, 0x28, 0xE3, 0xD1, 0x64, 0xBB, + 0x10, 0x78, 0x01, 0xF8, 0x53, 0x0F, 0x50, 0x78, 0x48, 0x70, 0xB6, 0xE0, + 0x54, 0xB9, 0x10, 0x78, 0x52, 0x78, 0x00, 0xEB, 0x02, 0x20, 0xA1, 0xF8, + 0x56, 0x00, 0x03, 0xE0, 0x14, 0xB9, 0x10, 0x78, 0x81, 0xF8, 0x52, 0x00, + 0xE0, 0xB2, 0xBD, 0xE8, 0xFC, 0x41, 0xFF, 0xF7, 0xC3, 0xBA, 0x10, 0x78, + 0x41, 0xB2, 0x00, 0xE0, 0x00, 0x21, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, + 0xFC, 0xF7, 0xBC, 0xBC, 0x0E, 0x46, 0x2A, 0x46, 0x06, 0xF8, 0x58, 0x7F, + 0x20, 0x46, 0x71, 0x78, 0x0D, 0xF0, 0x46, 0xF8, 0x71, 0x78, 0x2A, 0x46, + 0x20, 0x46, 0x02, 0xB0, 0x1E, 0xE0, 0x8E, 0xE0, 0xB1, 0xE0, 0x28, 0xE0, + 0x23, 0xE0, 0x1D, 0xE0, 0xB5, 0xE0, 0xB0, 0xE0, 0xC9, 0xE0, 0xB6, 0xE0, + 0xA5, 0xE0, 0xA0, 0xE0, 0x99, 0xE0, 0x92, 0xE0, 0x7A, 0xE0, 0x8A, 0xE0, + 0x86, 0xE0, 0x82, 0xE0, 0x71, 0xE0, 0x66, 0xE0, 0x5B, 0xE0, 0x56, 0xE0, + 0x51, 0xE0, 0x41, 0xE0, 0x3B, 0xE0, 0x2D, 0xE0, 0x23, 0xE0, 0x1C, 0xE0, + 0x25, 0xE0, 0x16, 0xE0, 0x11, 0xE0, 0x3E, 0xE0, 0xBD, 0xE8, 0xF0, 0x41, + 0xF7, 0xF7, 0x58, 0xBD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xFC, 0xF7, + 0x07, 0xBC, 0x21, 0x46, 0x4F, 0xF4, 0xC6, 0x70, 0xA8, 0xE0, 0x21, 0x46, + 0x4F, 0xF4, 0xC7, 0x70, 0xA4, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0x9D, 0x70, + 0xA0, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0x9C, 0x70, 0x9C, 0xE0, 0x21, 0x46, + 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0x20, 0xFC, 0xF7, 0x09, 0xBB, 0x21, 0x46, + 0x40, 0xF2, 0x5D, 0x10, 0x92, 0xE0, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, + 0xFC, 0xF7, 0x26, 0xBC, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8, 0x01, 0x1B, + 0x02, 0xB0, 0x00, 0xEB, 0x01, 0x20, 0x21, 0x46, 0xBD, 0xE8, 0xF0, 0x41, + 0x80, 0xB2, 0xF6, 0xF7, 0x3B, 0xB8, 0x10, 0x46, 0xBD, 0xE8, 0xFC, 0x41, + 0x09, 0xF0, 0x12, 0xBF, 0x10, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0x0A, 0xF0, + 0x77, 0xB8, 0x81, 0xF8, 0x58, 0x70, 0x29, 0x46, 0x20, 0x46, 0x0D, 0xF0, + 0x2F, 0xF8, 0x21, 0x46, 0x40, 0xF2, 0x69, 0x10, 0x6C, 0xE0, 0x21, 0x46, + 0x40, 0xF2, 0x61, 0x10, 0x68, 0xE0, 0x21, 0x46, 0x40, 0xF2, 0x63, 0x10, + 0x64, 0xE0, 0x10, 0x78, 0x51, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x81, 0xB2, + 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x18, 0xBE, 0x10, 0x78, + 0x51, 0x78, 0x00, 0xEB, 0x01, 0x20, 0x81, 0xB2, 0x20, 0x46, 0xBD, 0xE8, + 0xFC, 0x41, 0xF7, 0xF7, 0x30, 0xBD, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, + 0xF7, 0xF7, 0x4A, 0xBE, 0x02, 0x28, 0x7F, 0xF4, 0x34, 0xAF, 0x14, 0xB9, + 0x10, 0x78, 0x81, 0xF8, 0x51, 0x00, 0xBD, 0xE8, 0xFC, 0x41, 0x00, 0xF0, + 0x3F, 0xBC, 0x21, 0x46, 0x01, 0x20, 0x04, 0xE0, 0x21, 0x46, 0x02, 0x20, + 0x01, 0xE0, 0x21, 0x46, 0x00, 0x20, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, + 0xD1, 0xBA, 0x11, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, + 0xBB, 0xBB, 0x11, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, + 0x89, 0xBB, 0x21, 0x46, 0x4F, 0xF4, 0xBD, 0x70, 0x24, 0xE0, 0x21, 0x46, + 0x4F, 0xF4, 0xBE, 0x70, 0x20, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0xC0, 0x70, + 0x1C, 0xE0, 0x21, 0x46, 0x4F, 0xF4, 0xCA, 0x70, 0x18, 0xE0, 0x21, 0x46, + 0x4F, 0xF4, 0xCB, 0x70, 0x14, 0xE0, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8, + 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2, 0x34, 0xB1, 0x01, 0x21, + 0x0A, 0x46, 0x02, 0xB0, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0x06, 0xB8, + 0x11, 0x78, 0x52, 0x78, 0xF7, 0xE7, 0x21, 0x46, 0x4F, 0xF4, 0xC8, 0x70, + 0xBD, 0xE8, 0xFC, 0x41, 0xF7, 0xF7, 0x2B, 0xBF, 0x00, 0x00, 0x50, 0x21, + 0x02, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x4C, 0x0D, 0xC0, 0x08, + 0xF8, 0xB5, 0x0C, 0x46, 0x06, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, + 0x28, 0x49, 0x29, 0x48, 0xEA, 0xF7, 0x05, 0xDF, 0x42, 0xF2, 0x19, 0x02, + 0xB1, 0x1A, 0x27, 0x4D, 0x96, 0x42, 0x29, 0xD0, 0x08, 0xDC, 0xA6, 0xF5, + 0x00, 0x50, 0x0D, 0x38, 0x13, 0xD0, 0x06, 0x28, 0x1C, 0xD0, 0x09, 0x28, + 0x04, 0xD1, 0x2B, 0xE0, 0x19, 0x29, 0x34, 0xD0, 0x2A, 0x29, 0x0A, 0xD0, + 0x01, 0xB0, 0x33, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x1A, 0x49, 0x1B, 0x48, + 0x01, 0x22, 0x78, 0x31, 0x40, 0x1E, 0xEA, 0xF7, 0xE6, 0x9E, 0x14, 0xB1, + 0x00, 0x20, 0x85, 0xF8, 0x72, 0x00, 0x21, 0x46, 0xBD, 0xE8, 0xF8, 0x40, + 0x15, 0x48, 0x28, 0x30, 0xFC, 0xF7, 0x44, 0xBA, 0xE8, 0x8D, 0x21, 0x46, + 0xBD, 0xE8, 0xF8, 0x40, 0xFC, 0xF7, 0x2C, 0xBA, 0x00, 0x2C, 0x1A, 0xD0, + 0xE0, 0xB2, 0xFF, 0xF7, 0x27, 0xFA, 0x02, 0x46, 0xE8, 0x8D, 0xBD, 0xE8, + 0xF8, 0x40, 0x00, 0x21, 0x09, 0xF0, 0xE8, 0xBD, 0x00, 0x2C, 0x0E, 0xD0, + 0xBD, 0xE8, 0xF8, 0x40, 0x06, 0x49, 0x07, 0x48, 0x00, 0x22, 0x38, 0x31, + 0x80, 0x1E, 0xEA, 0xF7, 0xBE, 0x9E, 0xE8, 0x8D, 0x21, 0x46, 0xBD, 0xE8, + 0xF8, 0x40, 0xF6, 0xF7, 0x48, 0xB8, 0xF8, 0xBD, 0x14, 0x0E, 0xC0, 0x08, + 0x02, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x93, 0xB0, 0x4F, 0xF0, 0x00, 0x0A, 0x89, 0x46, 0x04, 0x46, 0x55, 0x46, + 0xCD, 0xF8, 0x44, 0xA0, 0xCD, 0xF8, 0x48, 0xA0, 0x24, 0x21, 0x06, 0xA8, + 0xCD, 0xF8, 0x00, 0xA0, 0x1D, 0xF4, 0x54, 0xF0, 0x8D, 0xF8, 0x14, 0x50, + 0x14, 0xF8, 0x01, 0x1B, 0x0D, 0xF1, 0x3C, 0x0B, 0x14, 0xF8, 0x01, 0x0B, + 0x14, 0xF8, 0x02, 0x2B, 0x00, 0xEB, 0x02, 0x20, 0x14, 0xF8, 0x01, 0x5C, + 0x87, 0xB2, 0x14, 0xF8, 0x01, 0x8B, 0x00, 0x20, 0x14, 0xF8, 0x01, 0x3B, + 0x0B, 0xF8, 0x00, 0x30, 0x40, 0x1C, 0x06, 0x28, 0xF8, 0xD3, 0x08, 0x46, + 0xFF, 0xF7, 0xDA, 0xF9, 0x06, 0x46, 0xB9, 0xF1, 0x0A, 0x0F, 0x0E, 0xD0, + 0xCD, 0xF8, 0x27, 0xA0, 0xAD, 0xF8, 0x2B, 0xA0, 0xCD, 0xF8, 0x2D, 0xA0, + 0xAD, 0xF8, 0x31, 0xA0, 0xDF, 0xF8, 0x7C, 0x91, 0x99, 0xF8, 0x72, 0x00, + 0x18, 0xB3, 0x95, 0xB1, 0x21, 0xE0, 0x00, 0x20, 0x06, 0xA9, 0x0B, 0x18, + 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0xDA, 0x73, 0x06, 0x28, 0xF8, 0xD3, + 0x00, 0x20, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, 0x5A, 0x75, + 0x06, 0x28, 0xF8, 0xD3, 0xE6, 0xE7, 0x53, 0x48, 0x06, 0x22, 0x6C, 0x30, + 0x0F, 0xA9, 0x01, 0x90, 0x1C, 0xF4, 0x20, 0xF7, 0x28, 0xB1, 0x06, 0x22, + 0x11, 0xA9, 0x01, 0x98, 0x1C, 0xF4, 0x1A, 0xF7, 0x08, 0xB9, 0x89, 0xF8, + 0x72, 0xA0, 0x16, 0xB1, 0x3C, 0x2E, 0x65, 0xD0, 0x6A, 0xE0, 0x0F, 0xA8, + 0xFF, 0xF7, 0xA4, 0xF9, 0xA8, 0xB1, 0x0F, 0xAA, 0x06, 0x21, 0x47, 0x48, + 0xEB, 0xF7, 0xAD, 0xD8, 0x00, 0x90, 0x3B, 0x46, 0x02, 0x22, 0x45, 0x49, + 0x45, 0x48, 0xEA, 0xF7, 0x3A, 0xDE, 0x48, 0x46, 0x10, 0xF8, 0x60, 0x1F, + 0x41, 0xF0, 0x08, 0x01, 0x01, 0x70, 0xA9, 0xF8, 0x62, 0x70, 0x13, 0x21, + 0x0B, 0xE0, 0x41, 0x46, 0x0F, 0xA8, 0xFE, 0xF7, 0x1F, 0xFA, 0x28, 0xB1, + 0x85, 0x72, 0x47, 0x80, 0x4D, 0xB1, 0x01, 0x2D, 0x0A, 0xD0, 0x15, 0xE0, + 0x14, 0x21, 0x38, 0x46, 0xFE, 0xF7, 0x8E, 0xFB, 0x13, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0xF7, 0xF7, 0xE7, 0xF8, 0x09, 0xE0, 0x05, 0xA9, 0x38, 0x46, + 0xF7, 0xF7, 0xE8, 0xF8, 0x10, 0xB1, 0x01, 0x20, 0x00, 0x90, 0x03, 0xE0, + 0xF7, 0xF7, 0xD6, 0xF8, 0x8D, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x18, 0x50, + 0x9D, 0xF8, 0x14, 0x00, 0x8D, 0xF8, 0x19, 0x00, 0x8D, 0xF8, 0x20, 0x80, + 0x0F, 0x98, 0xCD, 0xF8, 0x1A, 0x00, 0xBD, 0xF8, 0x40, 0x00, 0xAD, 0xF8, + 0x1E, 0x00, 0x0F, 0x99, 0xCD, 0xF8, 0x21, 0x10, 0xAD, 0xF8, 0x25, 0x00, + 0x20, 0x78, 0x61, 0x78, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x34, 0x00, + 0xA0, 0x78, 0xE1, 0x78, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x36, 0x00, + 0x20, 0x79, 0x61, 0x79, 0x00, 0xEB, 0x01, 0x20, 0xAD, 0xF8, 0x38, 0x00, + 0xA0, 0x79, 0x8D, 0xF8, 0x3A, 0x00, 0x05, 0xE0, 0x99, 0xF8, 0x60, 0x10, + 0x21, 0xF0, 0x02, 0x01, 0x89, 0xF8, 0x60, 0x10, 0xF3, 0xB2, 0x2A, 0x46, + 0x39, 0x46, 0x0F, 0xA8, 0x01, 0xF0, 0x42, 0xFC, 0x06, 0xAB, 0x39, 0x46, + 0x30, 0x46, 0x00, 0x9A, 0x09, 0xF0, 0x1E, 0xFC, 0xBD, 0xF8, 0x38, 0x00, + 0xBD, 0xF8, 0x36, 0x10, 0xBD, 0xF8, 0x34, 0x20, 0xCD, 0xF8, 0x00, 0x80, + 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0xB2, 0x9D, 0xF8, 0x19, 0x30, + 0x2A, 0x46, 0x31, 0x46, 0x38, 0x46, 0xFC, 0xF7, 0x53, 0xF8, 0x00, 0x2E, + 0x9C, 0xD1, 0x38, 0x46, 0xFE, 0xF7, 0xCA, 0xFC, 0x38, 0x46, 0xFE, 0xF7, + 0xD0, 0xFC, 0x95, 0xE7, 0xF0, 0x75, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, + 0xC0, 0x0E, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0xF8, 0xB5, 0x42, 0x78, + 0x83, 0x78, 0x01, 0x78, 0x02, 0xEB, 0x03, 0x22, 0x96, 0xB2, 0xC2, 0x78, + 0x03, 0x79, 0x02, 0xEB, 0x03, 0x22, 0x95, 0xB2, 0x42, 0x79, 0x83, 0x79, + 0x02, 0xEB, 0x03, 0x22, 0x94, 0xB2, 0xC2, 0x79, 0x00, 0x7A, 0x02, 0xEB, + 0x00, 0x20, 0x87, 0xB2, 0x08, 0x46, 0xFF, 0xF7, 0xED, 0xF8, 0x01, 0x46, + 0x23, 0x46, 0x2A, 0x46, 0x30, 0x46, 0x00, 0x97, 0xFC, 0xF7, 0xB3, 0xF8, + 0xF8, 0xBD, 0x38, 0xB5, 0x01, 0x78, 0x42, 0x78, 0x43, 0x79, 0x01, 0xEB, + 0x02, 0x21, 0x8C, 0xB2, 0x81, 0x78, 0xC2, 0x78, 0xC5, 0x79, 0x01, 0xEB, + 0x02, 0x21, 0x02, 0x79, 0x89, 0xB2, 0x02, 0xEB, 0x03, 0x22, 0x83, 0x79, + 0x92, 0xB2, 0x03, 0xEB, 0x05, 0x23, 0x05, 0x7A, 0x40, 0x7A, 0x9B, 0xB2, + 0x05, 0xEB, 0x00, 0x20, 0x80, 0xB2, 0x00, 0x90, 0x20, 0x46, 0xF6, 0xF7, + 0x72, 0xFD, 0x38, 0xBD, 0xF0, 0xB5, 0x87, 0xB0, 0x10, 0xF8, 0x01, 0x6B, + 0x04, 0x46, 0x00, 0x25, 0x04, 0xAF, 0x20, 0xE0, 0x14, 0xF8, 0x01, 0x0B, + 0x00, 0x22, 0x14, 0xF8, 0x01, 0x1B, 0x02, 0xAB, 0x14, 0xF8, 0x01, 0xCB, + 0x03, 0xF8, 0x02, 0xC0, 0x52, 0x1C, 0x06, 0x2A, 0xF8, 0xD3, 0x14, 0xF8, + 0x01, 0x3B, 0x00, 0x22, 0x14, 0xF8, 0x01, 0xCB, 0x07, 0xF8, 0x02, 0xC0, + 0x52, 0x1C, 0x06, 0x2A, 0xF8, 0xD3, 0x14, 0xF8, 0x01, 0x2B, 0x52, 0xB2, + 0xCD, 0xE9, 0x00, 0x72, 0x02, 0xAA, 0xF6, 0xF7, 0x83, 0xFD, 0x6D, 0x1C, + 0xED, 0xB2, 0xB5, 0x42, 0xDC, 0xD3, 0x07, 0xB0, 0xF0, 0xBD, 0x70, 0xB5, + 0x04, 0x46, 0x0D, 0x46, 0x08, 0x46, 0xFF, 0xF7, 0x93, 0xF8, 0x01, 0x46, + 0x20, 0x46, 0x01, 0xF0, 0x09, 0xFB, 0x20, 0x46, 0x09, 0xF0, 0x30, 0xFC, + 0x28, 0x46, 0xFF, 0xF7, 0x89, 0xF8, 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0xFC, 0xF7, 0xB9, 0xB8, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x91, 0xB0, 0x10, 0xF8, 0x01, 0x1B, 0x04, 0x46, 0x00, 0x25, 0x0E, 0xAE, + 0x0D, 0x91, 0x4F, 0xE0, 0x14, 0xF8, 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, + 0x00, 0xEB, 0x01, 0x20, 0xC0, 0xF3, 0x41, 0x1E, 0x00, 0xF0, 0x1F, 0x00, + 0x0C, 0x90, 0x14, 0xF8, 0x01, 0xBB, 0x00, 0x20, 0x0A, 0xA9, 0x14, 0xF8, + 0x01, 0x2B, 0x0A, 0x54, 0x40, 0x1C, 0x06, 0x28, 0xF9, 0xD3, 0x14, 0xF8, + 0x01, 0xAB, 0x14, 0xF8, 0x01, 0x9B, 0x14, 0xF8, 0x02, 0x8B, 0x14, 0xF9, + 0x01, 0x7C, 0x14, 0xF9, 0x04, 0x3B, 0x14, 0xF8, 0x03, 0x0C, 0x14, 0xF8, + 0x02, 0x1C, 0x00, 0xEB, 0x01, 0x20, 0x82, 0xB2, 0x14, 0xF8, 0x01, 0x1C, + 0x00, 0x20, 0x14, 0xF8, 0x01, 0xCB, 0x06, 0xF8, 0x00, 0xC0, 0x40, 0x1C, + 0x06, 0x28, 0xF8, 0xD3, 0x14, 0xF8, 0x01, 0x0B, 0xA4, 0x46, 0x04, 0x44, + 0xE5, 0x28, 0x07, 0xD9, 0x00, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xEA, 0xF7, + 0xE6, 0xDC, 0x11, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xCD, 0xE9, 0x04, 0x32, + 0xCD, 0xE9, 0x06, 0x16, 0xCD, 0xE9, 0x08, 0x0C, 0xCD, 0xE9, 0x02, 0x87, + 0xCD, 0xE9, 0x00, 0xA9, 0x0A, 0xAB, 0x5A, 0x46, 0x71, 0x46, 0x0C, 0x98, + 0xF6, 0xF7, 0x9A, 0xFE, 0x6D, 0x1C, 0xED, 0xB2, 0x0D, 0x98, 0x85, 0x42, + 0xAC, 0xD3, 0xE6, 0xE7, 0x40, 0x0F, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, + 0x1C, 0xB5, 0x10, 0xF8, 0x01, 0x1B, 0x6B, 0x46, 0x10, 0xF8, 0x01, 0x2B, + 0x01, 0xEB, 0x02, 0x21, 0x8A, 0xB2, 0x00, 0x21, 0x10, 0xF8, 0x01, 0x4B, + 0x5C, 0x54, 0x49, 0x1C, 0x08, 0x29, 0xF9, 0xD3, 0x01, 0x78, 0x40, 0x78, + 0x01, 0xEB, 0x00, 0x20, 0x80, 0xB2, 0x19, 0x46, 0x09, 0xF0, 0x32, 0xFD, + 0x1C, 0xBD, 0x70, 0xB5, 0x42, 0x78, 0x83, 0x78, 0x01, 0x78, 0x02, 0xEB, + 0x03, 0x22, 0xC5, 0x78, 0x06, 0x79, 0x94, 0xB2, 0x08, 0x46, 0xFE, 0xF7, + 0xFB, 0xFF, 0x33, 0x46, 0x2A, 0x46, 0x21, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0xF7, 0xF7, 0x58, 0xB8, 0x70, 0xB5, 0x10, 0xF8, 0x01, 0x5B, 0x10, 0xF8, + 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x04, 0x46, 0x01, 0xEB, 0x02, 0x21, + 0x8E, 0xB2, 0x30, 0x46, 0xFF, 0xF7, 0x0E, 0xF8, 0x01, 0x00, 0x11, 0xD0, + 0x3D, 0xB9, 0x00, 0x20, 0x0B, 0x18, 0x14, 0xF8, 0x01, 0x2B, 0x40, 0x1C, + 0x9A, 0x75, 0x08, 0x28, 0xF8, 0xD3, 0x28, 0x46, 0xFE, 0xF7, 0xD8, 0xFF, + 0x01, 0x46, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7, 0x2C, 0xB9, + 0x70, 0xBD, 0x7C, 0xB5, 0x10, 0xF8, 0x01, 0x4B, 0x00, 0x22, 0x10, 0xF8, + 0x01, 0x1B, 0x6B, 0x46, 0x10, 0xF8, 0x01, 0x5B, 0x9D, 0x54, 0x52, 0x1C, + 0x06, 0x2A, 0xF9, 0xD3, 0x1A, 0x46, 0x20, 0x46, 0xF7, 0xF7, 0x84, 0xF9, + 0x7C, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x10, 0xF8, 0x01, 0x5B, + 0x04, 0x46, 0xDF, 0xF8, 0x40, 0x80, 0x18, 0xE0, 0x14, 0xF8, 0x01, 0x0B, + 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x86, 0xB2, 0x14, 0xF8, + 0x01, 0x0B, 0x14, 0xF8, 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x87, 0xB2, + 0x30, 0x46, 0xFE, 0xF7, 0xCD, 0xFF, 0xCD, 0xE9, 0x00, 0x70, 0x33, 0x46, + 0x03, 0x22, 0x05, 0x49, 0x40, 0x46, 0xEA, 0xF7, 0x46, 0xDC, 0x6D, 0x1E, + 0xED, 0xB2, 0xE3, 0xD2, 0xBD, 0xE8, 0xFC, 0x81, 0x02, 0x3C, 0x10, 0x21, + 0xFC, 0x0C, 0xC0, 0x08, 0x7C, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFE, 0xF7, + 0x95, 0xFF, 0x48, 0xB1, 0x41, 0x88, 0x40, 0xF2, 0x1D, 0x40, 0xFE, 0xF7, + 0x37, 0xFE, 0x00, 0x28, 0x0C, 0xD1, 0x4F, 0xF4, 0xB4, 0x70, 0x01, 0xE0, + 0x4F, 0xF4, 0x89, 0x70, 0x00, 0x21, 0x00, 0x91, 0x0B, 0x46, 0x01, 0x91, + 0x22, 0x46, 0x29, 0x46, 0xF7, 0xF7, 0x9E, 0xFB, 0x7C, 0xBD, 0x00, 0x00, + 0x2D, 0xE9, 0xFC, 0x47, 0x41, 0x78, 0x82, 0x78, 0x90, 0xF8, 0x00, 0x90, + 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x01, 0x79, 0x42, 0x79, 0x90, 0xF8, + 0x03, 0x80, 0x01, 0xEB, 0x02, 0x21, 0x8C, 0xB2, 0x81, 0x79, 0xC0, 0x79, + 0x01, 0xEB, 0x00, 0x20, 0x87, 0xB2, 0x28, 0x46, 0xFE, 0xF7, 0x88, 0xFF, + 0x06, 0x00, 0x0B, 0xD0, 0x48, 0x46, 0xFE, 0xF7, 0x5B, 0xFF, 0xCD, 0xE9, + 0x00, 0x47, 0x72, 0x78, 0x43, 0x46, 0x31, 0x1D, 0xF7, 0xF7, 0x78, 0xFB, + 0xBD, 0xE8, 0xFC, 0x87, 0x02, 0xB0, 0x2B, 0x46, 0xBD, 0xE8, 0xF0, 0x47, + 0x01, 0x22, 0x02, 0x49, 0x02, 0x48, 0xEA, 0xF7, 0xF2, 0x9B, 0x00, 0x00, + 0x8C, 0x0C, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46, + 0x05, 0x46, 0xFE, 0xF7, 0x45, 0xFF, 0x48, 0xB1, 0x41, 0x88, 0x41, 0xF2, + 0x05, 0x40, 0xFE, 0xF7, 0xE7, 0xFD, 0x00, 0x28, 0x0B, 0xD1, 0x4F, 0xF4, + 0xB4, 0x70, 0x01, 0xE0, 0x4F, 0xF4, 0x89, 0x70, 0x22, 0x46, 0x29, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x23, 0xF7, 0xF7, 0x7D, 0xBB, 0x70, 0xBD, + 0x08, 0x49, 0x10, 0xB5, 0x01, 0x20, 0xC8, 0x70, 0x07, 0x48, 0xFF, 0xF7, + 0xF9, 0xF9, 0x00, 0x28, 0x06, 0xD1, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x22, + 0x04, 0x49, 0x05, 0x48, 0xEA, 0xF7, 0xC3, 0x9B, 0x10, 0xBD, 0x00, 0x00, + 0xF0, 0x75, 0x20, 0x00, 0x55, 0xCB, 0x81, 0x00, 0xAC, 0x11, 0xC0, 0x08, + 0x00, 0x3C, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0xFE, 0xF7, 0x34, 0xFF, + 0x04, 0x00, 0x14, 0xD0, 0x20, 0x7D, 0xC0, 0x06, 0x11, 0xD5, 0x00, 0x22, + 0x08, 0x49, 0x09, 0x48, 0xEA, 0xF7, 0xAB, 0xDB, 0x20, 0x7D, 0x20, 0xF0, + 0x10, 0x00, 0x20, 0x75, 0x61, 0x7D, 0x28, 0x46, 0xFF, 0xF7, 0x61, 0xFE, + 0x20, 0x1D, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x37, 0xBF, 0x70, 0xBD, + 0x68, 0x09, 0xC0, 0x08, 0x01, 0x3C, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x47, + 0xDF, 0xF8, 0xE4, 0x80, 0x05, 0x46, 0x8A, 0x46, 0x98, 0xF8, 0x08, 0x00, + 0x17, 0x1D, 0xC1, 0x19, 0x37, 0x48, 0x16, 0x46, 0x86, 0xB0, 0x4F, 0xF4, + 0x8E, 0x73, 0x34, 0x4A, 0x00, 0x78, 0xF2, 0xF7, 0x1B, 0xF9, 0x04, 0x00, + 0x33, 0xD0, 0x98, 0xF8, 0x08, 0x00, 0x4F, 0xF0, 0x01, 0x09, 0x20, 0x44, + 0x29, 0x0A, 0x00, 0xF8, 0x01, 0x9B, 0x00, 0xF8, 0x01, 0x5B, 0x00, 0xF8, + 0x02, 0x1B, 0xBA, 0xF1, 0x00, 0x01, 0x00, 0xF8, 0x01, 0x6C, 0x03, 0xD0, + 0x16, 0xB1, 0x32, 0x46, 0x1C, 0xF4, 0x83, 0xF4, 0x4F, 0xF4, 0x00, 0x70, + 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0x98, 0xF8, 0x08, 0x00, 0xAD, 0xF8, + 0x06, 0x00, 0x42, 0xF2, 0x16, 0x01, 0x68, 0x1A, 0xAD, 0xF8, 0x04, 0x90, + 0xAD, 0xF8, 0x08, 0x70, 0x8D, 0x42, 0x24, 0xD0, 0x0F, 0xDC, 0xA5, 0xF5, + 0x80, 0x65, 0x1D, 0x3D, 0x1F, 0xD0, 0x05, 0xF5, 0x82, 0x65, 0xB5, 0xF5, + 0x00, 0x55, 0x13, 0xD0, 0x06, 0x2D, 0x0A, 0xD1, 0x17, 0xE0, 0x00, 0x20, + 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x03, 0x28, 0x11, 0xD0, 0x1C, 0x28, + 0x0F, 0xD0, 0x2D, 0x28, 0x06, 0xD0, 0x11, 0x48, 0x40, 0xF2, 0x4F, 0x13, + 0x10, 0x4A, 0x69, 0x46, 0x10, 0x30, 0x0C, 0xE0, 0x0D, 0x48, 0x4F, 0xF4, + 0x9D, 0x73, 0x0D, 0x4A, 0x69, 0x46, 0x64, 0x30, 0x05, 0xE0, 0x0A, 0x48, + 0x40, 0xF2, 0x4B, 0x13, 0x09, 0x4A, 0x69, 0x46, 0x18, 0x30, 0xF2, 0xF7, + 0xFD, 0xFE, 0x05, 0x00, 0x05, 0xD1, 0x40, 0xF2, 0x55, 0x12, 0x05, 0x49, + 0x20, 0x46, 0xF2, 0xF7, 0xAB, 0xF9, 0x00, 0xF0, 0xC9, 0xF8, 0x28, 0x46, + 0xD4, 0xE7, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x75, 0xA7, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x7C, 0xB5, 0x35, 0x4D, 0x35, 0x4C, 0x01, 0x22, + 0x35, 0x49, 0x63, 0x78, 0x28, 0x46, 0xEA, 0xF7, 0x14, 0xDB, 0x61, 0x78, + 0x48, 0x1C, 0x60, 0x70, 0x12, 0x29, 0xF4, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, + 0x09, 0x09, 0x0A, 0x0D, 0x10, 0x13, 0x16, 0x19, 0x25, 0x28, 0x2B, 0x2E, + 0x31, 0x09, 0x09, 0x37, 0x3B, 0x3F, 0xE8, 0xE7, 0x41, 0xF2, 0x09, 0x00, + 0x25, 0xE0, 0x41, 0xF2, 0x02, 0x00, 0x22, 0xE0, 0x41, 0xF2, 0x05, 0x00, + 0x1F, 0xE0, 0x41, 0xF2, 0x01, 0x00, 0x1C, 0xE0, 0x41, 0xF2, 0x03, 0x00, + 0x19, 0xE0, 0x60, 0x79, 0x06, 0x28, 0xD6, 0xD3, 0x22, 0xA0, 0xD0, 0xE9, + 0x00, 0x10, 0xCD, 0xE9, 0x00, 0x10, 0x68, 0x46, 0xFE, 0xF7, 0x6B, 0xFC, + 0x7C, 0xBD, 0x42, 0xF2, 0x03, 0x00, 0x0A, 0xE0, 0x42, 0xF2, 0x1C, 0x00, + 0x07, 0xE0, 0x42, 0xF2, 0x02, 0x00, 0x04, 0xE0, 0x42, 0xF2, 0x0F, 0x00, + 0x01, 0xE0, 0x42, 0xF2, 0x2A, 0x00, 0xBD, 0xE8, 0x7C, 0x40, 0xFE, 0xF7, + 0x54, 0xBC, 0xBD, 0xE8, 0x7C, 0x40, 0xFE, 0xF7, 0xEF, 0xB9, 0xBD, 0xE8, + 0x7C, 0x40, 0xFE, 0xF7, 0x8C, 0xBA, 0xE0, 0x78, 0x03, 0x25, 0x01, 0x28, + 0x10, 0xD0, 0x0D, 0x48, 0x00, 0x21, 0x20, 0x30, 0x06, 0x46, 0xF4, 0xF7, + 0x6D, 0xFA, 0xB4, 0xF8, 0x44, 0x10, 0x00, 0x20, 0x02, 0xF0, 0xEC, 0xF9, + 0x25, 0x70, 0x30, 0x46, 0xBD, 0xE8, 0x7C, 0x40, 0x08, 0xF0, 0x36, 0xB9, + 0x25, 0x70, 0x00, 0x20, 0xE0, 0x70, 0xBD, 0xE8, 0x7C, 0x40, 0xF7, 0xF7, + 0x7C, 0xBB, 0x00, 0x00, 0x03, 0x3C, 0x10, 0x21, 0xF0, 0x75, 0x20, 0x00, + 0x6C, 0x12, 0xC0, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, + 0x70, 0xB5, 0x11, 0x4D, 0x06, 0x46, 0x0C, 0x46, 0x95, 0xF8, 0x58, 0x00, + 0x28, 0xB1, 0x0A, 0x46, 0x31, 0x46, 0x4F, 0xF4, 0x86, 0x70, 0xF7, 0xF7, + 0x25, 0xF8, 0x21, 0x46, 0x30, 0x46, 0xFE, 0xF7, 0x29, 0xFA, 0x48, 0xB1, + 0x02, 0x20, 0x05, 0xF8, 0x58, 0x0F, 0x6E, 0x70, 0x20, 0x68, 0xC5, 0xF8, + 0x02, 0x00, 0xA0, 0x88, 0xE8, 0x80, 0x70, 0xBD, 0x22, 0x46, 0x31, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x4F, 0xF4, 0xB4, 0x70, 0xF7, 0xF7, 0x0E, 0xB8, + 0xF0, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x10, 0x4C, 0x05, 0x46, 0x40, 0xF2, + 0x69, 0x16, 0x94, 0xF8, 0x58, 0x00, 0x20, 0xB1, 0x4F, 0xF4, 0x86, 0x71, + 0x30, 0x46, 0xF7, 0xF7, 0x88, 0xFA, 0x28, 0x46, 0xFE, 0xF7, 0x6E, 0xFB, + 0x40, 0xB1, 0x01, 0x20, 0x04, 0xF8, 0x58, 0x0F, 0x28, 0x68, 0xC4, 0xF8, + 0x02, 0x00, 0xA8, 0x88, 0xE0, 0x80, 0x70, 0xBD, 0x30, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x4F, 0xF4, 0xB4, 0x71, 0xF7, 0xF7, 0x74, 0xBA, 0x00, 0x00, + 0xF0, 0x75, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x5B, 0x4C, 0x86, 0xB0, + 0x04, 0xF1, 0x10, 0x08, 0x42, 0xF2, 0x0D, 0x06, 0x42, 0xF2, 0x43, 0x05, + 0x80, 0xE0, 0xE0, 0x8C, 0x10, 0xB1, 0x40, 0xF2, 0x19, 0x23, 0x16, 0xE0, + 0x94, 0xF8, 0x72, 0x00, 0x40, 0xB9, 0x53, 0x48, 0x40, 0xF2, 0x21, 0x23, + 0x52, 0x4A, 0x69, 0x46, 0x64, 0x30, 0xF2, 0xF7, 0xE5, 0xFD, 0x80, 0xB9, + 0x4E, 0x48, 0x4F, 0xF4, 0x09, 0x73, 0x4E, 0x4A, 0x69, 0x46, 0x18, 0x30, + 0xF2, 0xF7, 0xDC, 0xFD, 0x38, 0xB9, 0x40, 0xF2, 0x26, 0x23, 0x4A, 0x4A, + 0x69, 0x46, 0x40, 0x46, 0xF2, 0xF7, 0xD4, 0xFD, 0x90, 0xB3, 0xBD, 0xF8, + 0x00, 0x00, 0xB0, 0xF5, 0x00, 0x7F, 0x59, 0xD1, 0xBD, 0xF8, 0x06, 0x10, + 0x03, 0x98, 0x42, 0x18, 0x12, 0xF8, 0x01, 0x0F, 0x51, 0x78, 0x92, 0x1C, + 0x00, 0xEB, 0x01, 0x20, 0x80, 0xB2, 0xA0, 0xF5, 0x40, 0x61, 0x35, 0x39, + 0x02, 0xD0, 0x21, 0x79, 0x49, 0x1E, 0x21, 0x71, 0xB0, 0x42, 0x0B, 0xD1, + 0x00, 0x21, 0xE0, 0x84, 0xD2, 0x1D, 0x67, 0x18, 0x12, 0xF8, 0x01, 0x3B, + 0x49, 0x1C, 0x87, 0xF8, 0x28, 0x30, 0x06, 0x29, 0xF7, 0xD3, 0x28, 0xE0, + 0xA8, 0x42, 0x0C, 0xD1, 0x00, 0x21, 0xE0, 0x84, 0x12, 0x1D, 0x67, 0x18, + 0x12, 0xF8, 0x01, 0x3B, 0x49, 0x1C, 0x87, 0xF8, 0x28, 0x30, 0x06, 0x29, + 0xF7, 0xD3, 0x1A, 0xE0, 0x2E, 0xE0, 0xA0, 0xF5, 0x80, 0x61, 0x1D, 0x39, + 0x0F, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x13, 0x39, 0x0B, 0xD0, 0xA0, 0xF5, + 0x00, 0x51, 0x16, 0x39, 0x07, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x32, 0x39, + 0x03, 0xD0, 0xA0, 0xF5, 0x00, 0x51, 0x19, 0x39, 0x05, 0xD1, 0xE0, 0x84, + 0x51, 0x78, 0x92, 0x78, 0x01, 0xEB, 0x02, 0x21, 0xE1, 0x85, 0xB0, 0x42, + 0x01, 0xD0, 0xA8, 0x42, 0x09, 0xD1, 0x01, 0x20, 0x84, 0xF8, 0x72, 0x00, + 0x1B, 0x48, 0x00, 0x1F, 0xC1, 0x6A, 0x01, 0x67, 0x01, 0x8E, 0xA0, 0xF8, + 0x74, 0x10, 0x68, 0x46, 0x00, 0xF0, 0x4E, 0xF8, 0x20, 0x79, 0x00, 0x28, + 0x7F, 0xF4, 0x7B, 0xAF, 0xB4, 0xF8, 0x46, 0x00, 0x00, 0x28, 0x21, 0xD0, + 0x00, 0x25, 0x40, 0xF2, 0x86, 0x28, 0x13, 0x4F, 0x26, 0x6B, 0x17, 0xE0, + 0x06, 0xEB, 0x45, 0x10, 0x01, 0x78, 0x89, 0xB1, 0xB4, 0xF8, 0x40, 0x10, + 0x71, 0xB1, 0x43, 0x46, 0x0C, 0x4A, 0x69, 0x46, 0x0C, 0x30, 0xF2, 0xF7, + 0x59, 0xFD, 0x38, 0xB1, 0x68, 0x46, 0x00, 0xF0, 0x2F, 0xF8, 0xB4, 0xF8, + 0x40, 0x00, 0x40, 0x1E, 0xA4, 0xF8, 0x40, 0x00, 0x6D, 0x1C, 0xED, 0xB2, + 0x97, 0xF8, 0x98, 0x01, 0xA8, 0x42, 0xE3, 0xD8, 0x06, 0xB0, 0xBD, 0xE8, + 0xF0, 0x81, 0x00, 0x00, 0xF0, 0x75, 0x20, 0x00, 0x47, 0xA7, 0x82, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x08, 0x48, 0x10, 0xB5, 0x01, 0x21, 0x01, 0x70, + 0x01, 0x71, 0x07, 0x48, 0xFE, 0xF7, 0xC2, 0xFF, 0x08, 0xB1, 0x01, 0x20, + 0x10, 0xBD, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, 0xEA, 0xF7, 0x8D, 0xD9, + 0x00, 0x20, 0x10, 0xBD, 0xF0, 0x75, 0x20, 0x00, 0x55, 0xCB, 0x81, 0x00, + 0x88, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, + 0xC0, 0x68, 0xE1, 0x88, 0x45, 0x18, 0x21, 0x89, 0x2A, 0x46, 0x16, 0x48, + 0xEA, 0xF7, 0xA0, 0xDA, 0x28, 0x78, 0x02, 0x28, 0x04, 0xD1, 0x05, 0xF8, + 0x08, 0x0D, 0x20, 0x89, 0x08, 0x30, 0x20, 0x81, 0xE0, 0x68, 0x45, 0xF8, + 0x04, 0x0C, 0x28, 0x78, 0x02, 0x28, 0x03, 0xD1, 0x0E, 0x48, 0x81, 0x8F, + 0x49, 0x1C, 0x81, 0x87, 0x21, 0x89, 0x28, 0x46, 0xFE, 0xF7, 0x92, 0xFF, + 0x00, 0x28, 0x0F, 0xD1, 0x20, 0x89, 0x00, 0x90, 0x2B, 0x78, 0x02, 0x22, + 0x08, 0x49, 0x09, 0x48, 0xEA, 0xF7, 0x59, 0xD9, 0xE0, 0x68, 0xBD, 0xE8, + 0x38, 0x40, 0x40, 0xF2, 0x01, 0x22, 0x06, 0x49, 0xF1, 0xF7, 0xD4, 0xBF, + 0x38, 0xBD, 0x00, 0x00, 0x00, 0x3D, 0x20, 0x21, 0xF0, 0x75, 0x20, 0x00, + 0x2C, 0x11, 0xC0, 0x08, 0x00, 0x3C, 0x10, 0x21, 0x3D, 0xA7, 0x82, 0x00, + 0x70, 0xB5, 0x06, 0x46, 0x04, 0x98, 0x1D, 0x46, 0x00, 0xFB, 0x02, 0x10, + 0x81, 0xB2, 0x1A, 0x46, 0x30, 0x46, 0xEE, 0xF7, 0x0D, 0xDD, 0x04, 0x00, + 0x03, 0xD0, 0x29, 0x46, 0x30, 0x46, 0x1C, 0xF4, 0xC7, 0xF2, 0x20, 0x46, + 0x70, 0xBD, 0x30, 0xB4, 0x02, 0x9C, 0x04, 0xFB, 0x02, 0x11, 0x30, 0xBC, + 0x89, 0xB2, 0x1A, 0x46, 0xEE, 0xF7, 0x9D, 0x9C, 0x70, 0xB5, 0x05, 0x46, + 0x17, 0x4A, 0x18, 0x4C, 0x00, 0x20, 0x01, 0x46, 0x12, 0x68, 0x04, 0x23, + 0x94, 0xF8, 0x98, 0x41, 0x07, 0xE0, 0x01, 0xEB, 0x01, 0x16, 0x03, 0xEB, + 0x86, 0x06, 0x96, 0x5D, 0xDE, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x8C, 0x42, + 0xF5, 0xD8, 0x00, 0x28, 0x14, 0xD0, 0x01, 0x21, 0x01, 0x71, 0x4F, 0xF6, + 0xFF, 0x71, 0x41, 0x80, 0x00, 0x21, 0x01, 0x80, 0x81, 0x62, 0xC1, 0x85, + 0x01, 0x86, 0x41, 0x71, 0x81, 0x71, 0x41, 0x63, 0x01, 0x64, 0x2A, 0x68, + 0xC2, 0x60, 0xAA, 0x88, 0x02, 0x82, 0x17, 0x22, 0x42, 0x81, 0x01, 0x72, + 0x70, 0xBD, 0x01, 0xEB, 0x01, 0x10, 0x02, 0xEB, 0x80, 0x00, 0xE2, 0xE7, + 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0xFE, 0xB5, 0x04, 0x46, + 0x0D, 0x46, 0x00, 0x7F, 0xA1, 0x89, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95, + 0x60, 0x68, 0x16, 0x46, 0x04, 0x22, 0x43, 0x88, 0x26, 0x49, 0x27, 0x48, + 0xEA, 0xF7, 0xE3, 0xD8, 0x23, 0x7F, 0x08, 0x2B, 0x3D, 0xD2, 0xDF, 0xE8, + 0x03, 0xF0, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x3C, 0x2C, 0x34, 0x03, 0xB0, + 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, + 0x3D, 0xB8, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, + 0xF0, 0x40, 0x00, 0xF0, 0x0D, 0xB9, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, 0xD1, 0xB9, 0x03, 0xB0, + 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, + 0xBB, 0xB8, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, + 0xF0, 0x40, 0x00, 0xF0, 0x3F, 0xB9, 0x03, 0xB0, 0x32, 0x46, 0x29, 0x46, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, 0x57, 0xB8, 0x03, 0xB0, + 0x32, 0x46, 0x29, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x00, 0xF0, + 0x7D, 0xB9, 0x04, 0x49, 0x04, 0x48, 0x02, 0x22, 0x44, 0x31, 0xC0, 0x1E, + 0x00, 0x95, 0xEA, 0xF7, 0x9A, 0xD8, 0xFE, 0xBD, 0x58, 0x1D, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46, + 0x0B, 0x46, 0x01, 0x22, 0x1B, 0x49, 0x1C, 0x48, 0xEA, 0xF7, 0x8B, 0xD8, + 0x05, 0x2C, 0x15, 0xD0, 0x09, 0xDC, 0x01, 0x2C, 0x17, 0xD0, 0x03, 0x2C, + 0x1A, 0xD0, 0x04, 0x2C, 0x28, 0xD1, 0x01, 0x20, 0x28, 0x77, 0x01, 0x46, + 0x1F, 0xE0, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C, 0x13, 0xD0, 0xF9, 0x2C, + 0x16, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0xF9, 0x3C, 0x1A, 0xD1, 0x0C, 0xE0, + 0x00, 0x21, 0x28, 0x46, 0x02, 0xF0, 0x03, 0xF8, 0x07, 0xE0, 0x31, 0x88, + 0x28, 0x46, 0x01, 0xF0, 0xD3, 0xFF, 0x02, 0xE0, 0x28, 0x46, 0x01, 0xF0, + 0x53, 0xFB, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x76, 0xBA, + 0x02, 0x20, 0x28, 0x77, 0x00, 0x21, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0xF0, 0xB4, 0xBF, 0x70, 0xBD, 0x00, 0x00, 0x34, 0x1C, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46, + 0x0B, 0x46, 0x01, 0x22, 0x24, 0x49, 0x25, 0x48, 0xEA, 0xF7, 0x49, 0xD8, + 0x40, 0xF2, 0x07, 0x12, 0x07, 0x21, 0xA4, 0xF2, 0x07, 0x10, 0x94, 0x42, + 0x20, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x30, 0xD0, 0x03, 0x2C, 0x33, 0xD0, + 0x05, 0x2C, 0x35, 0xD1, 0x29, 0x77, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0xF0, 0xFC, 0xBA, 0xB0, 0xF5, 0x80, 0x7F, 0x17, 0xD0, 0xA0, 0xF5, + 0x80, 0x70, 0xF9, 0x38, 0x28, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x28, 0x46, + 0x01, 0xF0, 0xB7, 0xFF, 0x28, 0x46, 0x01, 0xF0, 0xED, 0xFA, 0x28, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x36, 0xBA, 0x34, 0x88, 0x29, 0x77, + 0x28, 0x46, 0x01, 0xF0, 0xE3, 0xFA, 0x21, 0x46, 0x0C, 0xE0, 0x05, 0xF1, + 0x08, 0x00, 0x01, 0xF0, 0x6F, 0xFF, 0x00, 0x20, 0x28, 0x77, 0x01, 0x46, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0x9C, 0xBF, 0x31, 0x88, + 0x28, 0x46, 0x01, 0xF0, 0x98, 0xFF, 0xE2, 0xE7, 0x28, 0x46, 0x01, 0xF0, + 0xF3, 0xFA, 0xDE, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x08, 0x1D, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46, + 0x0B, 0x46, 0x01, 0x22, 0x1B, 0x49, 0x1C, 0x48, 0xE9, 0xF7, 0xF5, 0xDF, + 0x05, 0x2C, 0x23, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x27, 0xD0, 0x03, 0x2C, + 0x2A, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0xD8, 0xFA, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0xF0, 0xFB, 0xB9, 0xA4, 0xF5, 0x80, 0x74, 0x01, 0x3C, + 0x06, 0xD0, 0x02, 0x2C, 0x1C, 0xD1, 0x31, 0x88, 0x68, 0x68, 0x01, 0xF0, + 0xEF, 0xFB, 0xEF, 0xE7, 0x06, 0x20, 0x28, 0x77, 0x00, 0x21, 0x28, 0x46, + 0x01, 0xF0, 0x62, 0xFC, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x21, + 0x01, 0xF0, 0x38, 0xBF, 0x07, 0x20, 0x28, 0x77, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x01, 0xF0, 0x8F, 0xBA, 0x31, 0x88, 0x28, 0x46, 0x01, 0xF0, + 0x52, 0xFF, 0xD7, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0xAC, 0x1C, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x15, 0x46, 0x06, 0x46, 0x0C, 0x46, + 0x0B, 0x46, 0x01, 0x22, 0x1F, 0x49, 0x20, 0x48, 0xE9, 0xF7, 0xB3, 0xDF, + 0x06, 0x2C, 0x22, 0xD0, 0x0A, 0xDC, 0x01, 0x2C, 0x2C, 0xD0, 0x03, 0x2C, + 0x2F, 0xD0, 0x05, 0x2C, 0x31, 0xD1, 0x00, 0x21, 0x30, 0x46, 0x01, 0xF0, + 0x3A, 0xFF, 0x11, 0xE0, 0x07, 0x2C, 0x1E, 0xD0, 0xA4, 0xF5, 0x80, 0x74, + 0x07, 0x3C, 0x1D, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0xF9, 0x3C, 0x22, 0xD1, + 0x40, 0xF2, 0xF6, 0x21, 0x30, 0x46, 0x01, 0xF0, 0xFF, 0xFE, 0x30, 0x46, + 0x01, 0xF0, 0x5A, 0xFA, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, + 0xA3, 0xB9, 0x70, 0x7F, 0x01, 0x28, 0x12, 0xD1, 0x04, 0x20, 0x30, 0x77, + 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x01, 0xF0, 0xC9, 0xBB, 0x70, 0x7F, + 0x01, 0x28, 0x08, 0xD1, 0x29, 0x88, 0x30, 0x46, 0x01, 0xF0, 0xE6, 0xFE, + 0xE8, 0xE7, 0x30, 0x46, 0x01, 0xF0, 0x66, 0xFA, 0xE4, 0xE7, 0x70, 0xBD, + 0x54, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x15, 0x46, + 0x06, 0x46, 0x0C, 0x46, 0x0B, 0x46, 0x01, 0x22, 0x21, 0x49, 0x22, 0x48, + 0xE9, 0xF7, 0x69, 0xDF, 0x40, 0xF2, 0x01, 0x20, 0xA4, 0xF2, 0x01, 0x21, + 0x84, 0x42, 0x29, 0xD0, 0x0A, 0xDC, 0x01, 0x2C, 0x2E, 0xD0, 0x03, 0x2C, + 0x2E, 0xD0, 0x05, 0x2C, 0x14, 0xD0, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C, + 0x2C, 0xD1, 0x25, 0xE0, 0x01, 0x29, 0x29, 0xD0, 0x02, 0x29, 0x21, 0xD0, + 0xFF, 0x29, 0x25, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x30, 0x46, 0x01, 0xF0, + 0xB5, 0xFE, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x5C, 0xB9, + 0xF0, 0x89, 0x30, 0xB1, 0x07, 0x20, 0x30, 0x77, 0x30, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x01, 0xF0, 0x05, 0xBA, 0x00, 0x21, 0x30, 0x46, 0x01, 0xF0, + 0xCE, 0xFE, 0xEC, 0xE7, 0x06, 0x20, 0x30, 0x77, 0x30, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0x21, 0x01, 0xF0, 0x9A, 0xBE, 0x29, 0x88, 0xDF, 0xE7, + 0x30, 0x46, 0x01, 0xF0, 0x19, 0xFA, 0xDE, 0xE7, 0x70, 0xBD, 0x00, 0x00, + 0xD8, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, + 0x05, 0x46, 0x0C, 0x46, 0x0B, 0x46, 0x01, 0x22, 0x14, 0x49, 0x15, 0x48, + 0xE9, 0xF7, 0x1B, 0xDF, 0x40, 0xF2, 0x07, 0x20, 0xA4, 0xF2, 0x07, 0x21, + 0x84, 0x42, 0x13, 0xD0, 0x0B, 0xDC, 0x01, 0x2C, 0x15, 0xD0, 0x03, 0x2C, + 0x18, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0xFA, 0xF9, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0xF0, 0x1D, 0xB9, 0x01, 0x29, 0x07, 0xD0, 0xF9, 0x29, + 0x0C, 0xD1, 0x40, 0xF2, 0xF6, 0x21, 0x05, 0xE0, 0x28, 0x46, 0x01, 0xF0, + 0xEB, 0xF9, 0x00, 0x21, 0x00, 0xE0, 0x31, 0x88, 0x28, 0x46, 0x01, 0xF0, + 0x8C, 0xFE, 0xE9, 0xE7, 0x70, 0xBD, 0x00, 0x00, 0x28, 0x1D, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x16, 0x46, 0x05, 0x46, 0x0C, 0x46, + 0x0B, 0x46, 0x01, 0x22, 0x20, 0x49, 0x21, 0x48, 0xE9, 0xF7, 0xE7, 0xDE, + 0x07, 0x2C, 0x2A, 0xD0, 0x11, 0xDC, 0x01, 0x2C, 0x32, 0xD0, 0x03, 0x2C, + 0x1C, 0xD0, 0x05, 0x2C, 0x1E, 0xD0, 0x06, 0x2C, 0x31, 0xD1, 0x68, 0x7F, + 0x02, 0x28, 0x2E, 0xD1, 0x03, 0x20, 0x28, 0x77, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x01, 0xF0, 0x55, 0xBE, 0xA4, 0xF5, 0x80, 0x74, 0x07, 0x3C, + 0x1E, 0xD0, 0xB4, 0xF5, 0x80, 0x7F, 0x07, 0xD0, 0xA4, 0xF5, 0x80, 0x74, + 0xF9, 0x3C, 0x1C, 0xD1, 0x28, 0x46, 0x01, 0xF0, 0x8B, 0xF9, 0x13, 0xE0, + 0x28, 0x46, 0x01, 0xF0, 0xAD, 0xF9, 0x0F, 0xE0, 0x00, 0x21, 0x28, 0x46, + 0x01, 0xF0, 0x4F, 0xFE, 0x0A, 0xE0, 0x68, 0x7F, 0x02, 0x28, 0x0C, 0xD1, + 0x31, 0x88, 0x11, 0xB1, 0xC8, 0xB2, 0x30, 0x38, 0x81, 0xB2, 0x68, 0x68, + 0x01, 0xF0, 0xC2, 0xFA, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, + 0xBF, 0xB8, 0x70, 0xBD, 0x80, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x00, 0x22, 0x21, 0xB1, 0x01, 0x29, 0x08, 0xD0, 0x03, 0x29, 0x1A, 0xD1, + 0x0B, 0xE0, 0xC0, 0xB1, 0x16, 0x28, 0x16, 0xD0, 0xC0, 0x07, 0x13, 0xD0, + 0x13, 0xE0, 0x90, 0xB1, 0x16, 0x28, 0x10, 0xD0, 0xC0, 0x07, 0x0D, 0xD1, + 0x0D, 0xE0, 0x01, 0x28, 0x0A, 0xD0, 0x12, 0x28, 0x08, 0xD0, 0x13, 0x28, + 0x06, 0xD0, 0x06, 0x28, 0x04, 0xD0, 0x07, 0x28, 0x02, 0xD0, 0x14, 0x38, + 0x02, 0x28, 0x00, 0xD8, 0x01, 0x22, 0x10, 0x46, 0x70, 0x47, 0x00, 0x21, + 0x04, 0x28, 0x03, 0xD0, 0x05, 0x28, 0x01, 0xD0, 0x06, 0x28, 0x00, 0xD1, + 0x01, 0x21, 0x08, 0x46, 0x70, 0x47, 0x30, 0xB5, 0x84, 0x1F, 0x40, 0xF6, + 0x7A, 0x45, 0xAC, 0x42, 0x0F, 0xD8, 0x06, 0x29, 0x0D, 0xD3, 0xAC, 0x1D, + 0xA1, 0x42, 0x0A, 0xD8, 0x81, 0x42, 0x08, 0xD3, 0xB2, 0xF5, 0xFA, 0x7F, + 0x05, 0xD2, 0x0A, 0x2B, 0x03, 0xD3, 0xA3, 0x42, 0x01, 0xD8, 0x00, 0x20, + 0x30, 0xBD, 0x40, 0xF2, 0x05, 0x20, 0x30, 0xBD, 0x13, 0xB5, 0x04, 0x46, + 0x83, 0x89, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, 0xE9, 0xF7, 0x57, 0xDE, + 0x01, 0xAA, 0x40, 0xF2, 0x07, 0x11, 0x20, 0x46, 0xFF, 0xF7, 0x5E, 0xFD, + 0x1C, 0xBD, 0x00, 0x00, 0x18, 0x1C, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x07, 0x46, 0x2A, 0x4D, 0x2A, 0x48, 0x0E, 0x46, + 0x69, 0x7E, 0x90, 0xF8, 0x99, 0x21, 0x00, 0x24, 0x91, 0x42, 0x02, 0xD3, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x24, 0x49, 0x00, 0x20, 0x34, 0x23, + 0x89, 0x68, 0x0C, 0xE0, 0x00, 0xEB, 0x40, 0x0C, 0x0C, 0xEB, 0x00, 0x1C, + 0x03, 0xEB, 0x8C, 0x0C, 0x11, 0xF8, 0x0C, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, + 0x2A, 0xD0, 0x40, 0x1C, 0xC0, 0xB2, 0x82, 0x42, 0xF0, 0xD8, 0x1C, 0xB3, + 0x4C, 0x21, 0x20, 0x46, 0x1B, 0xF4, 0xD8, 0xF7, 0x00, 0xF0, 0x9A, 0xF9, + 0xA0, 0x81, 0x20, 0xB3, 0x04, 0xF1, 0x20, 0x00, 0xF2, 0xF7, 0x71, 0xF9, + 0x00, 0x20, 0x67, 0x60, 0xA0, 0x62, 0x20, 0x77, 0x60, 0x77, 0xE6, 0x81, + 0x4F, 0xF4, 0x28, 0x71, 0x21, 0x82, 0x61, 0x82, 0xA0, 0x60, 0x68, 0x7E, + 0x40, 0x1C, 0x68, 0x76, 0x01, 0x20, 0x84, 0xF8, 0x34, 0x00, 0x60, 0x68, + 0x01, 0x88, 0x49, 0x1C, 0x01, 0x80, 0x20, 0x46, 0x01, 0xF0, 0x04, 0xF8, + 0x20, 0x46, 0xC2, 0xE7, 0x00, 0xEB, 0x40, 0x02, 0x02, 0xEB, 0x00, 0x10, + 0x01, 0xEB, 0x80, 0x04, 0xD1, 0xE7, 0x00, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xE9, 0xF7, 0xF5, 0xDD, 0xB4, 0xE7, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xE8, 0x1B, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0x01, 0x46, 0x86, 0xB0, 0x20, 0x48, + 0xF4, 0xF7, 0x8D, 0xDD, 0x00, 0x28, 0x37, 0xD0, 0x60, 0x68, 0x01, 0x88, + 0x49, 0x1E, 0x01, 0x80, 0x04, 0xF1, 0x08, 0x00, 0x01, 0xF0, 0x32, 0xFD, + 0xA0, 0x6B, 0x00, 0x25, 0x28, 0xB1, 0x4F, 0xF4, 0x98, 0x72, 0x18, 0x49, + 0xF1, 0xF7, 0x54, 0xFC, 0xA5, 0x63, 0xE5, 0x87, 0xA4, 0xF8, 0x40, 0x50, + 0xA0, 0x6A, 0x28, 0xB1, 0x40, 0xF2, 0x39, 0x12, 0x12, 0x49, 0xF1, 0xF7, + 0x49, 0xFC, 0xA5, 0x62, 0x40, 0xF2, 0x3F, 0x17, 0x40, 0xF2, 0x3D, 0x18, + 0x04, 0xF1, 0x20, 0x06, 0x43, 0x46, 0x0D, 0x4A, 0x69, 0x46, 0x30, 0x46, + 0xF2, 0xF7, 0x5C, 0xF9, 0x28, 0xB1, 0x3A, 0x46, 0x09, 0x49, 0x03, 0x98, + 0xF1, 0xF7, 0x36, 0xFC, 0xF2, 0xE7, 0x06, 0x49, 0x25, 0x77, 0x0C, 0x39, + 0x84, 0xF8, 0x34, 0x50, 0x48, 0x7E, 0x40, 0x1E, 0x48, 0x76, 0x01, 0x20, + 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x74, 0x76, 0x20, 0x00, + 0x59, 0xA8, 0x82, 0x00, 0x00, 0xB5, 0x13, 0x48, 0x85, 0xB0, 0x4F, 0xF4, + 0xAC, 0x63, 0x10, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xF1, 0xF7, 0xE0, 0xFD, + 0x00, 0x28, 0x0C, 0xD0, 0xBD, 0xF8, 0x00, 0x30, 0xB3, 0xF5, 0x40, 0x7F, + 0x09, 0xD0, 0xB3, 0xF5, 0xC0, 0x6F, 0x0A, 0xD0, 0x01, 0x22, 0x0A, 0x49, + 0x0A, 0x48, 0xE9, 0xF7, 0x88, 0xDD, 0x05, 0xB0, 0x00, 0xBD, 0x68, 0x46, + 0x00, 0xF0, 0x28, 0xF9, 0xF9, 0xE7, 0xBD, 0xF8, 0x06, 0x10, 0x9D, 0xF8, + 0x05, 0x00, 0x00, 0xF0, 0x2B, 0xFE, 0xF2, 0xE7, 0x34, 0xA8, 0x82, 0x00, + 0x64, 0x76, 0x20, 0x00, 0xA0, 0x1B, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x80, 0x46, 0x00, 0x24, 0x0D, 0x4E, 0x0E, 0x4F, + 0x0F, 0xE0, 0x30, 0x68, 0x04, 0xEB, 0x04, 0x11, 0x00, 0xEB, 0x81, 0x05, + 0x28, 0x79, 0x30, 0xB1, 0x06, 0x22, 0x05, 0xF1, 0x0C, 0x01, 0x40, 0x46, + 0x1B, 0xF4, 0x28, 0xF6, 0x40, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x97, 0xF8, + 0x98, 0x01, 0xA0, 0x42, 0xEB, 0xD8, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x28, 0x46, 0xFB, 0xE7, 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x02, 0x46, 0x30, 0xB5, 0x09, 0x48, 0x00, 0x21, 0x03, 0x68, 0x09, 0x48, + 0x90, 0xF8, 0x98, 0x41, 0x08, 0xE0, 0x01, 0xEB, 0x01, 0x10, 0x03, 0xEB, + 0x80, 0x00, 0x45, 0x88, 0x95, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, + 0x8C, 0x42, 0xF4, 0xD8, 0x00, 0x20, 0x30, 0xBD, 0x68, 0x76, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x02, 0x46, 0x06, 0x48, 0xC0, 0x68, 0x06, 0xE0, + 0x43, 0x68, 0x93, 0x42, 0x02, 0xD1, 0x83, 0x7F, 0x8B, 0x42, 0x02, 0xD0, + 0x00, 0x68, 0x00, 0x28, 0xF6, 0xD1, 0x70, 0x47, 0x68, 0x76, 0x20, 0x00, + 0x01, 0x46, 0x05, 0x48, 0xC0, 0x68, 0x03, 0xE0, 0x82, 0x89, 0x8A, 0x42, + 0x02, 0xD0, 0x00, 0x68, 0x00, 0x28, 0xF9, 0xD1, 0x70, 0x47, 0x00, 0x00, + 0x68, 0x76, 0x20, 0x00, 0x02, 0x46, 0x06, 0x48, 0xC0, 0x68, 0x06, 0xE0, + 0x43, 0x68, 0x93, 0x42, 0x02, 0xD1, 0xC3, 0x89, 0x8B, 0x42, 0x02, 0xD0, + 0x00, 0x68, 0x00, 0x28, 0xF6, 0xD1, 0x70, 0x47, 0x68, 0x76, 0x20, 0x00, + 0x02, 0x46, 0x30, 0xB5, 0x08, 0x48, 0x00, 0x21, 0x43, 0x68, 0x08, 0x48, + 0x90, 0xF8, 0xCA, 0x41, 0x06, 0xE0, 0x03, 0xEB, 0x81, 0x00, 0x05, 0x88, + 0x95, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, 0x8C, 0x42, 0xF6, 0xD8, + 0x00, 0x20, 0x30, 0xBD, 0x68, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xE9, 0xF7, 0xE7, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, + 0xF5, 0xBF, 0x00, 0x00, 0xDC, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x70, 0xB5, 0x04, 0x46, 0x00, 0xF1, 0x0C, 0x01, 0x86, 0xB0, 0x24, 0x48, + 0xE9, 0xF7, 0xA4, 0xDE, 0x03, 0x46, 0x01, 0x22, 0x22, 0x49, 0x23, 0x48, + 0xE9, 0xF7, 0xCF, 0xDC, 0x4F, 0xF6, 0xFF, 0x70, 0x60, 0x80, 0x00, 0x25, + 0x25, 0x71, 0x25, 0x80, 0x60, 0x6B, 0x20, 0xB1, 0x72, 0x22, 0x1E, 0x49, + 0xF1, 0xF7, 0x46, 0xFB, 0x65, 0x63, 0x04, 0xF1, 0x1C, 0x06, 0x76, 0x23, + 0x1A, 0x4A, 0x69, 0x46, 0x30, 0x46, 0xF2, 0xF7, 0x5D, 0xF8, 0x58, 0xB1, + 0x78, 0x22, 0x17, 0x49, 0x03, 0x98, 0xF1, 0xF7, 0x37, 0xFB, 0xF2, 0xE7, + 0x7D, 0x22, 0x14, 0x49, 0x03, 0x98, 0xF1, 0xF7, 0x31, 0xFB, 0x01, 0xE0, + 0x04, 0xF1, 0x14, 0x06, 0x7B, 0x23, 0x10, 0x4A, 0x69, 0x46, 0x30, 0x46, + 0xF2, 0xF7, 0x48, 0xF8, 0x00, 0x28, 0xEF, 0xD1, 0xE0, 0x8D, 0x30, 0xB1, + 0x82, 0x22, 0x0B, 0x49, 0xA0, 0x6A, 0xF1, 0xF7, 0x1F, 0xFB, 0xA5, 0x62, + 0xE5, 0x85, 0xA0, 0x79, 0x00, 0x28, 0x04, 0xD0, 0x04, 0xF1, 0x40, 0x00, + 0x01, 0xF0, 0xEC, 0xFB, 0xA5, 0x71, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0xC8, 0x1B, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x47, 0xA8, 0x82, 0x00, 0x10, 0xB5, 0x7F, 0x24, 0x40, 0x23, 0x18, 0x46, + 0xFF, 0xF7, 0x5C, 0xFF, 0x28, 0xB1, 0x5B, 0x1C, 0x9B, 0xB2, 0xA3, 0x42, + 0xF7, 0xD3, 0x00, 0x20, 0x10, 0xBD, 0x18, 0x46, 0x10, 0xBD, 0x41, 0x79, + 0x49, 0x1C, 0x11, 0xF0, 0xFF, 0x01, 0x41, 0x71, 0x01, 0xD1, 0x01, 0x21, + 0x41, 0x71, 0xC8, 0xB2, 0x70, 0x47, 0x00, 0x00, 0x48, 0x68, 0x10, 0xF8, + 0x01, 0x2B, 0x10, 0xF8, 0x01, 0x3B, 0x48, 0x60, 0x02, 0xEB, 0x03, 0x22, + 0x93, 0xB2, 0x01, 0x22, 0x01, 0x49, 0x02, 0x48, 0xE9, 0xF7, 0x5F, 0x9C, + 0xBC, 0x17, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F, + 0x05, 0x46, 0x85, 0xB0, 0x40, 0x89, 0xFF, 0xF7, 0x05, 0xFF, 0xDF, 0xF8, + 0x30, 0xB3, 0x04, 0x00, 0x21, 0xD0, 0x28, 0x79, 0x2E, 0x89, 0x00, 0x07, + 0xE0, 0x8D, 0x4F, 0xF0, 0x00, 0x09, 0x31, 0xD5, 0x50, 0xB1, 0x00, 0x22, + 0xC6, 0x49, 0x58, 0x46, 0xE9, 0xF7, 0x43, 0xDC, 0x40, 0xF2, 0x4D, 0x42, + 0xC4, 0x49, 0xA0, 0x6A, 0xF1, 0xF7, 0xC0, 0xFA, 0x04, 0x2E, 0x17, 0xD2, + 0xC0, 0x49, 0x00, 0x22, 0x38, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x35, 0xDC, + 0xE8, 0x68, 0x40, 0xF2, 0x54, 0x42, 0xBD, 0x49, 0xF1, 0xF7, 0xB2, 0xFA, + 0x4D, 0xE1, 0xBA, 0x49, 0x6B, 0x89, 0x01, 0x22, 0x34, 0x39, 0x58, 0x46, + 0xE9, 0xF7, 0x27, 0xDC, 0x4F, 0xF4, 0x88, 0x62, 0xE8, 0x68, 0xF0, 0xE7, + 0xE8, 0x68, 0xA0, 0x62, 0xE8, 0x88, 0xA0, 0x85, 0xE6, 0x85, 0xA4, 0xF8, + 0x30, 0x90, 0xA8, 0x88, 0x20, 0xF0, 0x01, 0x00, 0xA8, 0x80, 0x47, 0xE0, + 0xF0, 0xB1, 0x23, 0x8E, 0x19, 0x1A, 0xB1, 0x42, 0x24, 0xDA, 0x30, 0x44, + 0xAB, 0x49, 0x00, 0x90, 0x02, 0x22, 0x94, 0x31, 0x58, 0x46, 0xE9, 0xF7, + 0x0A, 0xDC, 0x40, 0xF2, 0x6F, 0x42, 0xA8, 0x49, 0xE8, 0x68, 0xF1, 0xF7, + 0x87, 0xFA, 0x4F, 0xF4, 0x8E, 0x62, 0xA5, 0x49, 0xA0, 0x6A, 0xF1, 0xF7, + 0x81, 0xFA, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0xC4, 0xF8, + 0x28, 0x90, 0x16, 0xE1, 0x9E, 0x49, 0x00, 0x22, 0x68, 0x31, 0x58, 0x46, + 0xE9, 0xF7, 0xF1, 0xDB, 0x40, 0xF2, 0x66, 0x42, 0xE8, 0x68, 0xBA, 0xE7, + 0xEA, 0x88, 0xE9, 0x68, 0xA3, 0x8D, 0x11, 0x44, 0xA2, 0x6A, 0x1A, 0x44, + 0x10, 0x44, 0x32, 0x46, 0x1B, 0xF4, 0xF7, 0xF4, 0xE0, 0x8D, 0x40, 0xF2, + 0x7D, 0x42, 0x30, 0x44, 0xE0, 0x85, 0x93, 0x49, 0xE8, 0x68, 0xF1, 0xF7, + 0x5D, 0xFA, 0xE0, 0x8D, 0x8F, 0x49, 0xCD, 0xE9, 0x00, 0x60, 0x8D, 0x48, + 0x23, 0x8E, 0x03, 0x22, 0xD0, 0x31, 0xC0, 0x1C, 0xE9, 0xF7, 0xCF, 0xDB, + 0xA1, 0x8D, 0xA0, 0x6A, 0x08, 0x44, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, + 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, 0x10, 0xF8, 0x01, 0x1B, + 0x10, 0xF8, 0x01, 0x2B, 0x01, 0xEB, 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF8, + 0x21, 0x8E, 0x00, 0x29, 0x7D, 0xD1, 0x41, 0x46, 0xB8, 0xF1, 0x05, 0x0F, + 0x1F, 0xD1, 0x17, 0x2F, 0x1D, 0xD9, 0x90, 0xF8, 0x01, 0x80, 0x17, 0x26, + 0x3B, 0x46, 0x01, 0x22, 0x7C, 0x49, 0x58, 0x46, 0xE9, 0xF7, 0xAB, 0xDB, + 0x40, 0xF2, 0x94, 0x42, 0x78, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0x28, 0xFA, + 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0xC4, 0xF8, 0x28, 0x90, + 0x84, 0xF8, 0x07, 0x80, 0x00, 0x23, 0x32, 0x46, 0x01, 0x21, 0x20, 0x46, + 0x00, 0xF0, 0x20, 0xFE, 0xB5, 0xE0, 0x08, 0x46, 0xFF, 0xF7, 0x11, 0xFD, + 0xC0, 0xBB, 0x40, 0x46, 0xFF, 0xF7, 0x6A, 0xFE, 0x60, 0x62, 0x18, 0xB1, + 0x81, 0x6B, 0x80, 0x8A, 0xA1, 0xB1, 0x14, 0xE0, 0x69, 0x49, 0x43, 0x46, + 0x01, 0x22, 0x38, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x82, 0xDB, 0x40, 0xF2, + 0xAB, 0x42, 0x64, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0xFF, 0xF9, 0xC4, 0xF8, + 0x28, 0x90, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0x94, 0xE0, + 0x80, 0x1C, 0xB8, 0x42, 0x19, 0xD2, 0x5E, 0x49, 0x3B, 0x46, 0x01, 0x22, + 0x64, 0x31, 0x58, 0x46, 0xE9, 0xF7, 0x6B, 0xDB, 0x40, 0xF2, 0xBC, 0x42, + 0x58, 0x49, 0xE8, 0x68, 0xF1, 0xF7, 0xE8, 0xF9, 0xC4, 0xF8, 0x28, 0x90, + 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, 0x40, 0xF2, 0xF1, 0x21, + 0x60, 0x6A, 0xFF, 0xF7, 0xFB, 0xFC, 0x78, 0xE0, 0xFF, 0xE7, 0x39, 0x1D, + 0x88, 0xB2, 0x20, 0x86, 0xB0, 0x42, 0x3B, 0xD9, 0x4F, 0x4A, 0xDF, 0xF8, + 0x40, 0xA1, 0x92, 0xF8, 0x00, 0xC0, 0x9A, 0xF8, 0x78, 0x21, 0x52, 0x06, + 0x03, 0xD5, 0xBA, 0xF8, 0xA8, 0x21, 0x90, 0x42, 0x2E, 0xD9, 0xA0, 0x8D, + 0x40, 0xF2, 0xDF, 0x43, 0x00, 0x1F, 0xA0, 0x85, 0x08, 0x44, 0x81, 0xB2, + 0x43, 0x4A, 0x60, 0x46, 0x00, 0xE0, 0x25, 0xE0, 0xF1, 0xF7, 0xCE, 0xF8, + 0xA0, 0x62, 0xE8, 0xB3, 0xEA, 0x88, 0xE9, 0x68, 0x11, 0x44, 0xA2, 0x8D, + 0x10, 0x44, 0x32, 0x46, 0x1B, 0xF4, 0x43, 0xF4, 0xBA, 0xF8, 0x78, 0x01, + 0xC0, 0x04, 0x4F, 0xD5, 0xA8, 0x88, 0x39, 0x4B, 0x20, 0xF0, 0x01, 0x00, + 0xA8, 0x80, 0x40, 0xF2, 0xEA, 0x40, 0x00, 0x90, 0xEA, 0x68, 0x39, 0x49, + 0xA0, 0x6A, 0xF1, 0xF7, 0x79, 0xF8, 0x28, 0xB9, 0xE8, 0x68, 0x40, 0xF2, + 0xED, 0x42, 0x31, 0x49, 0xF1, 0xF7, 0x9A, 0xF9, 0x20, 0x8E, 0xC0, 0xB3, + 0xE0, 0x8D, 0x21, 0x8E, 0x88, 0x42, 0x53, 0xD1, 0xA4, 0xF8, 0x2E, 0x90, + 0xA4, 0xF8, 0x30, 0x90, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0xA0, 0x6A, + 0x03, 0x90, 0xA0, 0x8D, 0x4D, 0x46, 0x00, 0x1D, 0xAD, 0xF8, 0x06, 0x00, + 0xAD, 0xF8, 0x08, 0x70, 0x40, 0x46, 0xB8, 0xF1, 0x05, 0x0F, 0x2D, 0xD0, + 0xB8, 0xF1, 0x04, 0x0F, 0x2F, 0xD0, 0x00, 0xE0, 0x20, 0xE0, 0xB8, 0xF1, + 0x06, 0x0F, 0x2A, 0xD0, 0x60, 0x6A, 0x03, 0x7F, 0x06, 0x2B, 0x2C, 0xD0, + 0x05, 0x2B, 0x2A, 0xD0, 0x1C, 0x49, 0x01, 0x22, 0x98, 0x31, 0x58, 0x46, + 0xE9, 0xF7, 0xE9, 0xDA, 0x40, 0xF2, 0x34, 0x52, 0x17, 0x49, 0xA0, 0x6A, + 0xF1, 0xF7, 0x66, 0xF9, 0xE5, 0x85, 0x25, 0x86, 0xA5, 0x62, 0x00, 0x20, + 0x05, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1D, 0xE0, 0x40, 0xF2, 0xF2, 0x42, + 0xE8, 0x68, 0xBC, 0xE7, 0xA4, 0xF8, 0x2E, 0x90, 0xA4, 0xF8, 0x30, 0x90, + 0x40, 0xF2, 0xFB, 0x42, 0xE8, 0x68, 0x9C, 0xE6, 0x69, 0x46, 0x20, 0x46, + 0x00, 0xF0, 0x32, 0xFB, 0x0B, 0xE0, 0x01, 0x46, 0x6A, 0x46, 0x20, 0x46, + 0x00, 0xF0, 0x46, 0xF9, 0x05, 0xE0, 0x81, 0x89, 0xAD, 0xF8, 0x0A, 0x10, + 0x69, 0x46, 0x00, 0xF0, 0x5F, 0xF9, 0xA5, 0x62, 0x01, 0x20, 0xDB, 0xE7, + 0x00, 0x3B, 0x10, 0x21, 0xC8, 0x19, 0xC0, 0x08, 0x20, 0xA8, 0x82, 0x00, + 0xD8, 0x1A, 0xC0, 0x08, 0x04, 0x74, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x59, 0xF5, 0x81, 0x00, 0xF8, 0xB5, 0x07, 0x46, 0x48, 0x68, 0x0C, 0x46, + 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, + 0x02, 0x21, 0x8E, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x33, 0x46, 0x10, 0xF8, + 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x02, 0x22, + 0x10, 0x49, 0x11, 0x48, 0x00, 0x95, 0xE9, 0xF7, 0x92, 0xDA, 0x60, 0x78, + 0xF8, 0x71, 0x30, 0x46, 0xFF, 0xF7, 0x68, 0xFD, 0x58, 0xB1, 0xC1, 0x89, + 0xA9, 0x42, 0x11, 0xD1, 0x61, 0x78, 0xC1, 0x77, 0xBD, 0xE8, 0xF8, 0x40, + 0x00, 0x22, 0x40, 0xF2, 0x07, 0x21, 0xFF, 0xF7, 0x8D, 0xB9, 0x01, 0xB0, + 0x2B, 0x46, 0x32, 0x46, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x40, 0x02, 0x21, + 0x00, 0xF0, 0x00, 0xBD, 0xF8, 0xBD, 0x00, 0x00, 0xDC, 0x16, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0xF8, 0xB5, 0x4A, 0x68, 0x0C, 0x46, 0x12, 0xF8, + 0x01, 0x0B, 0x12, 0xF8, 0x01, 0x1B, 0x62, 0x60, 0x00, 0xEB, 0x01, 0x20, + 0x85, 0xB2, 0x12, 0xF8, 0x01, 0x0B, 0x2B, 0x46, 0x12, 0xF8, 0x01, 0x1B, + 0x62, 0x60, 0x00, 0xEB, 0x01, 0x20, 0x86, 0xB2, 0x02, 0x22, 0x14, 0x49, + 0x14, 0x48, 0x00, 0x96, 0xE9, 0xF7, 0x57, 0xDA, 0x30, 0x46, 0xFF, 0xF7, + 0x2F, 0xFD, 0x11, 0x4B, 0xDB, 0x1E, 0x30, 0xB1, 0xC1, 0x89, 0xA9, 0x42, + 0x07, 0xD0, 0x0D, 0x49, 0x00, 0x22, 0x58, 0x31, 0x0B, 0xE0, 0x0B, 0x49, + 0x00, 0x22, 0x34, 0x31, 0x07, 0xE0, 0x81, 0x7F, 0x62, 0x78, 0x91, 0x42, + 0x4F, 0xF0, 0x00, 0x02, 0x06, 0xD0, 0x06, 0x49, 0x84, 0x31, 0x18, 0x46, + 0xBD, 0xE8, 0xF8, 0x40, 0xE9, 0xF7, 0x39, 0x9A, 0xBD, 0xE8, 0xF8, 0x40, + 0x4F, 0xF4, 0x02, 0x71, 0xFF, 0xF7, 0x40, 0xB9, 0x10, 0x17, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x03, 0x46, + 0x00, 0x91, 0x02, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xE9, 0xF7, 0x25, 0xDA, + 0x28, 0x46, 0xFF, 0xF7, 0xD3, 0xFC, 0x00, 0x28, 0x0D, 0xD0, 0x01, 0x88, + 0x39, 0xB1, 0x04, 0x21, 0x01, 0x71, 0x22, 0x46, 0xBD, 0xE8, 0x38, 0x40, + 0x05, 0x49, 0x00, 0xF0, 0x1D, 0xBC, 0xBD, 0xE8, 0x38, 0x40, 0xFF, 0xF7, + 0x35, 0xBD, 0x38, 0xBD, 0xF4, 0x18, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x89, 0xF3, 0x81, 0x00, 0x2D, 0xE9, 0xF8, 0x4F, 0x82, 0x46, 0x48, 0x68, + 0x0C, 0x46, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, + 0x01, 0xEB, 0x02, 0x21, 0x8D, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x2B, 0x46, + 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8F, 0xB2, + 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, + 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF9, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, + 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8E, 0xB2, 0x10, 0xF8, + 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, + 0x1F, 0xFA, 0x81, 0xF8, 0x02, 0x22, 0x1E, 0x49, 0x1E, 0x48, 0x00, 0x97, + 0xE9, 0xF7, 0xD5, 0xD9, 0x61, 0x78, 0x8A, 0xF8, 0x07, 0x10, 0x28, 0x46, + 0xFF, 0xF7, 0xC8, 0xFC, 0x10, 0xB1, 0x0D, 0xB1, 0xFF, 0x2D, 0x01, 0xD9, + 0x02, 0x21, 0x1D, 0xE0, 0x39, 0x46, 0x50, 0x46, 0xFF, 0xF7, 0xAE, 0xFC, + 0x08, 0xB1, 0x0A, 0x21, 0x16, 0xE0, 0x39, 0x46, 0x50, 0x46, 0xFF, 0xF7, + 0x73, 0xFB, 0x80, 0xB1, 0x05, 0x83, 0x02, 0x21, 0x41, 0x77, 0x61, 0x78, + 0xC1, 0x77, 0x0F, 0x49, 0xA0, 0xF8, 0x12, 0x90, 0xA0, 0xF8, 0x46, 0x80, + 0xB1, 0xF8, 0xA4, 0x11, 0x89, 0x1E, 0xB1, 0x42, 0x07, 0xDA, 0xC1, 0x82, + 0x06, 0xE0, 0x04, 0x21, 0x50, 0x46, 0xBD, 0xE8, 0xF8, 0x4F, 0x00, 0xF0, + 0xB9, 0xBD, 0xC6, 0x82, 0xBD, 0xE8, 0xF8, 0x4F, 0x00, 0x22, 0x4F, 0xF4, + 0x00, 0x71, 0xFF, 0xF7, 0xAB, 0xB8, 0x00, 0x00, 0x58, 0x1F, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, + 0x0C, 0x46, 0x06, 0x46, 0x00, 0x2B, 0x0A, 0xD1, 0xFF, 0xF7, 0x1C, 0xFC, + 0x18, 0xB9, 0x30, 0x46, 0xFF, 0xF7, 0x62, 0xF8, 0x20, 0xB1, 0x44, 0x80, + 0x05, 0x72, 0x03, 0x21, 0x01, 0x71, 0x70, 0xBD, 0x20, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x14, 0x21, 0xFC, 0xF7, 0xEC, 0xBE, 0x10, 0xB5, 0x14, 0x46, + 0x04, 0x29, 0x12, 0xD0, 0x06, 0x29, 0x05, 0xD0, 0x20, 0x79, 0xC0, 0x07, + 0x13, 0xD0, 0xD0, 0x68, 0x5B, 0x22, 0x05, 0xE0, 0x40, 0x88, 0x11, 0x46, + 0x09, 0xF0, 0xC4, 0xFA, 0xE0, 0x68, 0x6C, 0x22, 0xBD, 0xE8, 0x10, 0x40, + 0x04, 0x49, 0xF0, 0xF7, 0xEB, 0xBF, 0x40, 0x88, 0xBD, 0xE8, 0x10, 0x40, + 0x11, 0x46, 0xFA, 0xF7, 0x6F, 0xB9, 0x10, 0xBD, 0x6A, 0xA8, 0x82, 0x00, + 0x2D, 0xE9, 0xF8, 0x43, 0x04, 0x46, 0xB0, 0xF8, 0x44, 0x00, 0x00, 0x90, + 0x0D, 0x46, 0xA3, 0x89, 0x02, 0x22, 0x57, 0x49, 0x57, 0x48, 0xE9, 0xF7, + 0x52, 0xD9, 0xB4, 0xF8, 0x44, 0x00, 0xD0, 0xB1, 0x40, 0x1E, 0xA4, 0xF8, + 0x44, 0x00, 0xDF, 0xF8, 0x4C, 0xC1, 0x2F, 0x89, 0xA1, 0x6B, 0xAC, 0xF1, + 0x03, 0x0C, 0x40, 0xF2, 0xF1, 0x28, 0x89, 0xB1, 0xE2, 0x8F, 0xB4, 0xF8, + 0x40, 0x30, 0xD0, 0x19, 0x98, 0x42, 0x52, 0xD9, 0x4A, 0x49, 0x02, 0x22, + 0x60, 0x31, 0x00, 0x90, 0x60, 0x46, 0xE9, 0xF7, 0x36, 0xD9, 0x46, 0x46, + 0x3D, 0xE0, 0x40, 0xF2, 0xF2, 0x26, 0x3A, 0xE0, 0xE9, 0x88, 0xE8, 0x68, + 0x42, 0x5C, 0x01, 0x44, 0x49, 0x78, 0x02, 0xEB, 0x01, 0x21, 0x8E, 0xB2, + 0x21, 0x8A, 0xB1, 0x42, 0x05, 0xD2, 0x00, 0x91, 0x3E, 0x49, 0x02, 0x22, + 0x33, 0x46, 0x2C, 0x31, 0xE6, 0xE7, 0xBF, 0x1E, 0xBE, 0x42, 0x07, 0xD1, + 0xA0, 0x63, 0xE8, 0x88, 0x80, 0x1C, 0xA0, 0x87, 0xA4, 0xF8, 0x40, 0x60, + 0xE7, 0x87, 0x3E, 0xE0, 0x06, 0xF1, 0x1C, 0x00, 0x81, 0xB2, 0x38, 0x48, + 0x40, 0xF2, 0x16, 0x43, 0x35, 0x4A, 0x00, 0x78, 0xF0, 0xF7, 0xA0, 0xFE, + 0xA0, 0x63, 0x80, 0xB1, 0x1C, 0x21, 0xA1, 0x87, 0xA4, 0xF8, 0x40, 0x60, + 0xBA, 0xB2, 0xE2, 0x87, 0xEB, 0x88, 0xE9, 0x68, 0x1C, 0x30, 0x19, 0x44, + 0x89, 0x1C, 0x1B, 0xF4, 0x10, 0xF2, 0x40, 0xF2, 0x25, 0x42, 0xE8, 0x68, + 0x1E, 0xE0, 0x4F, 0xF4, 0x01, 0x76, 0x4F, 0xF4, 0x8B, 0x62, 0x28, 0x49, + 0xE8, 0x68, 0xF0, 0xF7, 0x73, 0xFF, 0x31, 0x46, 0x20, 0x46, 0xBD, 0xE8, + 0xF8, 0x43, 0xFF, 0xF7, 0x8B, 0xBA, 0xEB, 0x88, 0xE8, 0x68, 0x18, 0x44, + 0xA3, 0x8F, 0x19, 0x44, 0x8B, 0x18, 0x01, 0x46, 0x3A, 0x46, 0x18, 0x46, + 0x1B, 0xF4, 0xF3, 0xF1, 0xE0, 0x8F, 0x40, 0xF2, 0x37, 0x42, 0x38, 0x44, + 0xE0, 0x87, 0xE8, 0x68, 0x1A, 0x49, 0xF0, 0xF7, 0x59, 0xFF, 0xE0, 0x8F, + 0xB4, 0xF8, 0x40, 0x10, 0x88, 0x42, 0x0C, 0xD1, 0x00, 0x90, 0x60, 0x68, + 0xA3, 0x8F, 0xA1, 0x89, 0x40, 0x88, 0xA2, 0x6B, 0xF5, 0xF7, 0xAE, 0xF8, + 0x00, 0x20, 0xA0, 0x63, 0xA4, 0xF8, 0x40, 0x00, 0xE0, 0x87, 0xB4, 0xF8, + 0x4A, 0x10, 0xB4, 0xF8, 0x44, 0x00, 0x71, 0xB1, 0x88, 0x42, 0x0A, 0xD1, + 0xB4, 0xF8, 0x48, 0x10, 0x08, 0x1A, 0x81, 0xB2, 0x20, 0x46, 0x00, 0xF0, + 0x89, 0xFD, 0xB4, 0xF8, 0x48, 0x00, 0xA4, 0xF8, 0x44, 0x00, 0xBD, 0xE8, + 0xF8, 0x83, 0x00, 0x28, 0xFB, 0xD1, 0x60, 0x68, 0xA1, 0x89, 0x40, 0x88, + 0xBD, 0xE8, 0xF8, 0x43, 0xF4, 0xF7, 0x84, 0xBF, 0xDC, 0x21, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0xC0, 0xA8, 0x82, 0x00, 0x04, 0x74, 0x20, 0x00, + 0x2D, 0xE9, 0xFE, 0x43, 0x05, 0x46, 0x48, 0x68, 0x0C, 0x46, 0x10, 0xF8, + 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, + 0x1F, 0xFA, 0x81, 0xF9, 0x10, 0xF8, 0x01, 0x1B, 0x4B, 0x46, 0x10, 0xF8, + 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x1F, 0xFA, 0x81, 0xF8, + 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, 0x60, 0x60, 0x01, 0xEB, + 0x02, 0x21, 0x8F, 0xB2, 0x10, 0xF8, 0x01, 0x1B, 0x10, 0xF8, 0x01, 0x2B, + 0x60, 0x60, 0x01, 0xEB, 0x02, 0x21, 0x8E, 0xB2, 0xCD, 0xF8, 0x00, 0x80, + 0xCD, 0xE9, 0x01, 0x76, 0x04, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE9, 0xF7, + 0x6E, 0xD8, 0x60, 0x78, 0xE8, 0x71, 0x28, 0x7A, 0x40, 0xB1, 0x03, 0xB0, + 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x43, 0x00, 0x23, 0x1A, 0x46, 0x19, 0x46, + 0x00, 0xF0, 0xEA, 0xBA, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46, 0x48, 0x46, + 0xFF, 0xF7, 0xE3, 0xF9, 0x80, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x08, 0x00, + 0x00, 0x21, 0x02, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x8D, 0xF8, 0x09, 0x10, + 0x02, 0xAB, 0x13, 0x22, 0x29, 0x46, 0x00, 0x20, 0x00, 0xF0, 0xE6, 0xFE, + 0xBD, 0xE8, 0xFE, 0x83, 0x00, 0x96, 0x68, 0x88, 0x3B, 0x46, 0x42, 0x46, + 0x49, 0x46, 0xFA, 0xF7, 0x53, 0xFA, 0xF5, 0xE7, 0xF4, 0x1D, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46, 0x48, 0x68, 0x00, 0x25, + 0x10, 0xF8, 0x01, 0x2B, 0x10, 0xF8, 0x01, 0x3B, 0x48, 0x60, 0x02, 0xEB, + 0x03, 0x22, 0x96, 0xB2, 0x33, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48, + 0xE9, 0xF7, 0x2B, 0xD8, 0x20, 0x7A, 0x01, 0x28, 0x11, 0xD1, 0x01, 0x2E, + 0x02, 0xD0, 0x02, 0x2E, 0x03, 0xD0, 0x04, 0xE0, 0x40, 0xF2, 0x41, 0x25, + 0x01, 0xE0, 0x40, 0xF2, 0x42, 0x25, 0x04, 0xF1, 0x40, 0x00, 0x00, 0xF0, + 0x73, 0xFF, 0x60, 0x88, 0x29, 0x46, 0xFA, 0xF7, 0x6D, 0xFB, 0x00, 0x20, + 0xA0, 0x71, 0x70, 0xBD, 0xCC, 0x1D, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x37, 0xB5, 0x84, 0xB0, 0x04, 0x46, 0x9D, 0xF8, 0x14, 0x00, 0xBD, 0xF8, + 0x16, 0x20, 0x9D, 0xF8, 0x15, 0x10, 0x8D, 0xE8, 0x07, 0x00, 0x63, 0x88, + 0x04, 0x22, 0x32, 0x49, 0x32, 0x48, 0xE8, 0xF7, 0xFE, 0xDF, 0x31, 0x4D, + 0x9D, 0xF8, 0x15, 0x00, 0xED, 0x1E, 0x98, 0xB1, 0x9D, 0xF8, 0x14, 0x00, + 0x03, 0x21, 0xFF, 0xF7, 0x4F, 0xF9, 0xD8, 0xB1, 0x9D, 0xF8, 0x14, 0x10, + 0x13, 0x29, 0x3D, 0xD0, 0x10, 0xDC, 0x01, 0x29, 0x26, 0xD0, 0x06, 0x29, + 0x29, 0xD0, 0x07, 0x29, 0x2C, 0xD0, 0x12, 0x29, 0x0E, 0xD1, 0x2E, 0xE0, + 0x23, 0x49, 0x00, 0x22, 0x44, 0x31, 0x28, 0x46, 0xE8, 0xF7, 0xDF, 0xDF, + 0x07, 0xB0, 0x30, 0xBD, 0x14, 0x29, 0x2E, 0xD0, 0x15, 0x29, 0x31, 0xD0, + 0x16, 0x29, 0x34, 0xD0, 0x1C, 0x49, 0x9D, 0xF8, 0x14, 0x30, 0x01, 0x22, + 0x70, 0x31, 0x28, 0x46, 0xE8, 0xF7, 0xCF, 0xDF, 0x9D, 0xF8, 0x15, 0x00, + 0x00, 0x23, 0xE0, 0x71, 0x1A, 0x46, 0x19, 0x46, 0x20, 0x46, 0x00, 0xF0, + 0x4F, 0xFA, 0xE5, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x54, 0xFB, + 0xE0, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x0F, 0xFD, 0xDB, 0xE7, + 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, 0x46, 0xFD, 0xD6, 0xE7, 0x05, 0xA9, + 0x20, 0x46, 0xFF, 0xF7, 0x13, 0xFF, 0xD1, 0xE7, 0x05, 0xA9, 0x20, 0x46, + 0xFF, 0xF7, 0x70, 0xFF, 0xCC, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0xFF, 0xF7, + 0x9D, 0xFD, 0xC7, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0x00, 0xF0, 0x9C, 0xF8, + 0xC2, 0xE7, 0x05, 0xA9, 0x20, 0x46, 0x00, 0xF0, 0xFF, 0xF8, 0xBD, 0xE7, + 0xE0, 0x17, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43, + 0x81, 0x46, 0x0F, 0x46, 0xC8, 0x68, 0xC9, 0x88, 0xDF, 0xF8, 0x74, 0x80, + 0x44, 0x18, 0x38, 0x89, 0x05, 0x19, 0x2A, 0xE0, 0x20, 0x1D, 0xA8, 0x42, + 0x05, 0xD9, 0x00, 0x22, 0x19, 0x49, 0x40, 0x46, 0xE8, 0xF7, 0x85, 0xDF, + 0x23, 0xE0, 0x20, 0x78, 0x62, 0x1C, 0x60, 0xF3, 0x07, 0x06, 0x12, 0xF8, + 0x01, 0x0B, 0x60, 0xF3, 0x0F, 0x26, 0x12, 0xF8, 0x01, 0x0B, 0x12, 0xF8, + 0x01, 0x1B, 0x00, 0xEB, 0x01, 0x20, 0x83, 0xB2, 0xA8, 0x1A, 0x63, 0xF3, + 0x1F, 0x46, 0x83, 0x42, 0x08, 0xDD, 0xA8, 0x1A, 0x0C, 0x49, 0x00, 0x90, + 0x02, 0x22, 0x34, 0x31, 0x40, 0x46, 0xE8, 0xF7, 0x68, 0xDF, 0x06, 0xE0, + 0x9C, 0x18, 0x31, 0x46, 0x48, 0x46, 0xFF, 0xF7, 0x53, 0xFF, 0xAC, 0x42, + 0xD2, 0xD3, 0xF8, 0x68, 0xBD, 0xE8, 0xF8, 0x43, 0x40, 0xF2, 0xCD, 0x32, + 0x03, 0x49, 0xF0, 0xF7, 0xDB, 0xBD, 0x00, 0x00, 0x01, 0x3B, 0x10, 0x21, + 0x80, 0x18, 0xC0, 0x08, 0xF6, 0xA7, 0x82, 0x00, 0x3E, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x1F, 0x49, 0x20, 0x48, + 0xE8, 0xF7, 0x47, 0xDF, 0x81, 0x2C, 0x26, 0xD0, 0x82, 0x2C, 0x0A, 0xD0, + 0x03, 0xB0, 0x23, 0x46, 0x1A, 0x49, 0x1B, 0x48, 0xBD, 0xE8, 0x30, 0x40, + 0x01, 0x22, 0x38, 0x31, 0x80, 0x1E, 0xE8, 0xF7, 0x38, 0x9F, 0x28, 0x46, + 0xFF, 0xF7, 0xE6, 0xF9, 0x04, 0x00, 0x13, 0xD0, 0x04, 0xF1, 0x40, 0x00, + 0xF1, 0xF7, 0xD8, 0xFC, 0x02, 0x20, 0x8D, 0xF8, 0x00, 0x00, 0x00, 0x20, + 0x8D, 0xF8, 0x01, 0x00, 0xCD, 0xF8, 0x08, 0xD0, 0x01, 0xA9, 0x20, 0x46, + 0xFF, 0xF7, 0xE6, 0xFE, 0x60, 0x88, 0x3B, 0x21, 0xFC, 0xF7, 0x8C, 0xFC, + 0x3E, 0xBD, 0x28, 0x46, 0xFF, 0xF7, 0xF6, 0xF9, 0x04, 0x00, 0xF9, 0xD0, + 0x04, 0xF1, 0x08, 0x00, 0xF1, 0xF7, 0xBE, 0xFC, 0x03, 0xB0, 0x20, 0x46, + 0xBD, 0xE8, 0x30, 0x40, 0x00, 0x22, 0x4F, 0xF4, 0x40, 0x71, 0xFE, 0xF7, + 0x19, 0xBE, 0x00, 0x00, 0x2C, 0x19, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x2D, 0xE9, 0xF8, 0x43, 0x0D, 0x46, 0x49, 0x68, 0x11, 0xF8, 0x01, 0x2B, + 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB, 0x03, 0x22, 0x1F, 0xFA, + 0x82, 0xF9, 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, + 0x02, 0xEB, 0x03, 0x22, 0x1F, 0xFA, 0x82, 0xF8, 0x11, 0xF8, 0x01, 0x2B, + 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB, 0x03, 0x22, 0x96, 0xB2, + 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B, 0x69, 0x60, 0x02, 0xEB, + 0x03, 0x22, 0x97, 0xB2, 0x11, 0xF8, 0x01, 0x2B, 0x11, 0xF8, 0x01, 0x3B, + 0x02, 0xEB, 0x03, 0x22, 0xAD, 0xF8, 0x00, 0x20, 0x69, 0x60, 0x69, 0x78, + 0xFF, 0xF7, 0xA0, 0xF9, 0x04, 0x00, 0x0F, 0xD0, 0x04, 0xF1, 0x08, 0x00, + 0x00, 0xF0, 0x28, 0xFE, 0xBD, 0xF8, 0x00, 0x00, 0x80, 0xB1, 0x30, 0x30, + 0x40, 0xF4, 0x00, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x6A, 0x46, 0x40, 0xF2, + 0x03, 0x21, 0x19, 0xE0, 0x6B, 0x78, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48, + 0xE8, 0xF7, 0xBD, 0xDE, 0xBD, 0xE8, 0xF8, 0x83, 0xA4, 0xF8, 0x0E, 0x90, + 0x0B, 0x48, 0xA4, 0xF8, 0x12, 0x80, 0xA4, 0xF8, 0x46, 0x70, 0xB0, 0xF8, + 0xA4, 0x01, 0x80, 0x1E, 0xB0, 0x42, 0x01, 0xDA, 0xE0, 0x82, 0x00, 0xE0, + 0xE6, 0x82, 0x00, 0x22, 0x40, 0xF2, 0x01, 0x21, 0x20, 0x46, 0xFE, 0xF7, + 0xB3, 0xFD, 0xE7, 0xE7, 0x88, 0x1F, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, + 0x64, 0x01, 0x20, 0x00, 0x38, 0xB5, 0x4A, 0x68, 0x12, 0xF8, 0x01, 0x3B, + 0x12, 0xF8, 0x01, 0x4B, 0x4A, 0x60, 0x03, 0xEB, 0x04, 0x23, 0x12, 0xF8, + 0x01, 0x4B, 0x9B, 0xB2, 0x12, 0xF8, 0x01, 0x5B, 0x4A, 0x60, 0x04, 0xEB, + 0x05, 0x25, 0x19, 0x46, 0xFF, 0xF7, 0x74, 0xF9, 0x04, 0x00, 0x1C, 0xD0, + 0x2B, 0x46, 0x01, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x83, 0xDE, + 0xB4, 0xF8, 0x46, 0x00, 0x28, 0x44, 0xB0, 0xF5, 0x80, 0x3F, 0x06, 0xD2, + 0xA4, 0xF8, 0x46, 0x00, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, + 0xB5, 0xBB, 0x4F, 0xF4, 0x3C, 0x70, 0xAD, 0xF8, 0x00, 0x00, 0x6A, 0x46, + 0x40, 0xF2, 0x07, 0x11, 0x20, 0x46, 0xFE, 0xF7, 0x79, 0xFD, 0x38, 0xBD, + 0xB8, 0x1F, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x13, 0xB5, 0x01, 0xAA, + 0x01, 0x21, 0xFE, 0xF7, 0x6F, 0xFD, 0x1C, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, + 0x2B, 0x4A, 0x2C, 0x49, 0x10, 0x1F, 0xF0, 0xF7, 0xA9, 0xFD, 0x00, 0x28, + 0x4D, 0xD0, 0x28, 0x48, 0x0C, 0x30, 0xF3, 0xF7, 0xAD, 0xDD, 0x26, 0x4E, + 0x27, 0x4F, 0x1E, 0x20, 0x30, 0x76, 0x97, 0xF8, 0xCA, 0x01, 0x48, 0xB1, + 0x81, 0x00, 0x4F, 0xF4, 0xB1, 0x63, 0x24, 0x4A, 0x00, 0x20, 0xF3, 0xF7, + 0xDB, 0xDB, 0x70, 0x60, 0x00, 0x28, 0x38, 0xD0, 0x97, 0xF8, 0x98, 0x01, + 0x28, 0xB3, 0x00, 0xEB, 0x00, 0x10, 0x81, 0x00, 0x40, 0xF2, 0xA4, 0x53, + 0x1C, 0x4A, 0x00, 0x20, 0xF3, 0xF7, 0xCC, 0xDB, 0x30, 0x60, 0x00, 0x28, + 0x29, 0xD0, 0x00, 0x24, 0x4F, 0xF0, 0x14, 0x08, 0x4F, 0xF0, 0x1C, 0x09, + 0x0F, 0xE0, 0x04, 0xEB, 0x04, 0x15, 0x30, 0x68, 0x08, 0xEB, 0x85, 0x01, + 0x08, 0x44, 0xF1, 0xF7, 0x7C, 0xF9, 0x31, 0x68, 0x09, 0xEB, 0x85, 0x00, + 0x08, 0x44, 0xF1, 0xF7, 0x76, 0xF9, 0x64, 0x1C, 0xA4, 0xB2, 0x97, 0xF8, + 0x98, 0x01, 0xA0, 0x42, 0xEB, 0xD8, 0x97, 0xF8, 0x99, 0x01, 0x58, 0xB1, + 0x4C, 0x21, 0x10, 0xFB, 0x01, 0xF1, 0x40, 0xF2, 0xB4, 0x53, 0x08, 0x4A, + 0x00, 0x20, 0xF3, 0xF7, 0xA3, 0xDB, 0xB0, 0x60, 0x00, 0x28, 0x00, 0xD0, + 0x01, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00, + 0x15, 0xE5, 0x81, 0x00, 0x64, 0x01, 0x20, 0x00, 0x3E, 0xA8, 0x82, 0x00, + 0x01, 0x46, 0x01, 0x48, 0xF3, 0xF7, 0x59, 0x9D, 0x74, 0x76, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x08, 0x48, 0x17, 0x46, 0x0D, 0x46, + 0xC0, 0x68, 0x07, 0xE0, 0xD0, 0xE9, 0x00, 0x41, 0xB1, 0x42, 0x02, 0xD1, + 0x0D, 0xB1, 0x39, 0x46, 0xA8, 0x47, 0x20, 0x46, 0x00, 0x28, 0xF5, 0xD1, + 0xBD, 0xE8, 0xF0, 0x81, 0x68, 0x76, 0x20, 0x00, 0x38, 0xB5, 0x04, 0x68, + 0x05, 0x46, 0x03, 0x46, 0x02, 0x22, 0x0F, 0x49, 0x0F, 0x48, 0x00, 0x94, + 0xE8, 0xF7, 0xD9, 0xDD, 0x4F, 0xF4, 0x3C, 0x72, 0x0D, 0x49, 0x28, 0x46, + 0xF0, 0xF7, 0x56, 0xFC, 0x94, 0xF8, 0x34, 0x00, 0x01, 0x28, 0x0D, 0xD1, + 0x20, 0x7F, 0x06, 0x28, 0x0A, 0xD1, 0x60, 0x68, 0xA1, 0x89, 0x00, 0x22, + 0x40, 0x88, 0xF3, 0xF7, 0x10, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0x38, 0x40, + 0x00, 0xF0, 0x00, 0xBB, 0x38, 0xBD, 0x00, 0x00, 0x60, 0x20, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x80, 0xA8, 0x82, 0x00, 0x00, 0xF0, 0xF6, 0xBA, + 0x10, 0xB5, 0x04, 0x46, 0x03, 0x46, 0x01, 0x22, 0x09, 0x49, 0x0A, 0x48, + 0xE8, 0xF7, 0xAF, 0xDD, 0x20, 0x7F, 0x06, 0x28, 0x0A, 0xD1, 0x60, 0x68, + 0xA1, 0x89, 0x00, 0x22, 0x40, 0x88, 0xF3, 0xF7, 0xF0, 0xFC, 0x20, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xE0, 0xBA, 0x10, 0xBD, 0x00, 0x00, + 0x8C, 0x20, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x38, 0xB5, 0x05, 0x68, + 0x04, 0x46, 0x03, 0x46, 0x02, 0x22, 0x08, 0x49, 0x08, 0x48, 0x00, 0x95, + 0xE8, 0xF7, 0x91, 0xDD, 0x4F, 0xF4, 0x91, 0x72, 0x06, 0x49, 0x20, 0x46, + 0xF0, 0xF7, 0x0E, 0xFC, 0x28, 0x46, 0xBD, 0xE8, 0x38, 0x40, 0x00, 0xF0, + 0x99, 0xB8, 0x00, 0x00, 0xFC, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x86, 0xA7, 0x82, 0x00, 0x40, 0xF2, 0x23, 0x42, 0x01, 0x49, 0xF0, 0xF7, + 0xFD, 0xBB, 0x00, 0x00, 0x0C, 0xA8, 0x82, 0x00, 0x2D, 0xE9, 0xFF, 0x41, + 0x1E, 0x46, 0x17, 0x46, 0x80, 0x46, 0x0D, 0x46, 0x0B, 0x46, 0x02, 0xAC, + 0x01, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE8, 0xF7, 0x6A, 0xDD, 0x28, 0x0A, + 0x8D, 0xF8, 0x08, 0x50, 0x8D, 0xF8, 0x09, 0x00, 0xA4, 0x1C, 0xB5, 0xB1, + 0x38, 0x0A, 0xF9, 0xB2, 0x01, 0x2D, 0x02, 0xD0, 0x02, 0x2D, 0x10, 0xD1, + 0x05, 0xE0, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x00, 0xA4, 0x1C, + 0x09, 0xE0, 0x8D, 0xF8, 0x0A, 0x10, 0x8D, 0xF8, 0x0B, 0x00, 0x30, 0x0A, + 0x8D, 0xF8, 0x0C, 0x60, 0x8D, 0xF8, 0x0D, 0x00, 0x24, 0x1D, 0x02, 0xA8, + 0x20, 0x1A, 0x00, 0x21, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB, + 0x01, 0x22, 0x41, 0x46, 0x00, 0x20, 0x00, 0xF0, 0xDB, 0xFB, 0xBD, 0xE8, + 0xFF, 0x81, 0x00, 0x00, 0x58, 0x16, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, + 0x3E, 0xB5, 0x04, 0x46, 0x80, 0x89, 0x00, 0x90, 0xE3, 0x89, 0x02, 0x22, + 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x2F, 0xDD, 0xE0, 0x89, 0x8D, 0xF8, + 0x08, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x20, 0x7B, 0x8D, 0xF8, + 0x0A, 0x00, 0xA0, 0x89, 0x00, 0x21, 0x00, 0x0A, 0x8D, 0xF8, 0x0B, 0x00, + 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB, 0x06, 0x22, 0x20, 0x46, + 0x00, 0xF0, 0xB4, 0xFB, 0x3E, 0xBD, 0x00, 0x00, 0x7C, 0x16, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0xC0, 0x89, 0x00, 0x90, + 0xA3, 0x89, 0x02, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x09, 0xDD, + 0xA0, 0x89, 0x8D, 0xF8, 0x08, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00, + 0xA0, 0x7B, 0x8D, 0xF8, 0x0A, 0x00, 0xE0, 0x89, 0x00, 0x21, 0x00, 0x0A, + 0x8D, 0xF8, 0x0B, 0x00, 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB, + 0x07, 0x22, 0x20, 0x46, 0x00, 0xF0, 0x8E, 0xFB, 0x3E, 0xBD, 0x00, 0x00, + 0xAC, 0x16, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F, + 0x04, 0x46, 0x00, 0x79, 0x8B, 0xB0, 0x80, 0xB1, 0x01, 0x28, 0x0E, 0xD0, + 0x67, 0x48, 0x00, 0x27, 0x4F, 0xF0, 0x18, 0x08, 0x45, 0x8B, 0x66, 0x48, + 0x90, 0xF8, 0x00, 0xA0, 0x05, 0xF1, 0x18, 0x00, 0x1F, 0xFA, 0x80, 0xFB, + 0x60, 0x6B, 0x40, 0xB1, 0x34, 0xE0, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, + 0x60, 0x49, 0x61, 0x48, 0xE8, 0xF7, 0xCF, 0xDC, 0xB5, 0xE0, 0x40, 0xF2, + 0x5D, 0x13, 0x5F, 0x4A, 0x01, 0xA9, 0x04, 0xF1, 0x1C, 0x00, 0xF1, 0xF7, + 0x69, 0xF8, 0x48, 0xB9, 0x40, 0xF2, 0x5F, 0x13, 0x5A, 0x4A, 0x01, 0xA9, + 0x04, 0xF1, 0x14, 0x00, 0xF1, 0xF7, 0x60, 0xF8, 0x00, 0x28, 0x7D, 0xD0, + 0xBD, 0xF8, 0x0C, 0x00, 0xA8, 0x42, 0x05, 0xD8, 0x60, 0x88, 0x01, 0x22, + 0x01, 0xA9, 0x00, 0xF0, 0xAB, 0xF8, 0xD7, 0xE7, 0x04, 0x98, 0x60, 0x63, + 0xBD, 0xF8, 0x0A, 0x00, 0x20, 0x87, 0xBD, 0xF8, 0x0C, 0x00, 0x60, 0x87, + 0xBD, 0xF8, 0x0E, 0x00, 0xA0, 0x87, 0xBD, 0xF8, 0x08, 0x00, 0x20, 0xF0, + 0x02, 0x00, 0xE0, 0x87, 0x94, 0xF8, 0x3E, 0x00, 0x40, 0xF3, 0x40, 0x00, + 0x00, 0xF1, 0x01, 0x09, 0x60, 0x8F, 0xA8, 0x42, 0x3E, 0xD9, 0x4F, 0xF4, + 0xBC, 0x73, 0x44, 0x4A, 0x59, 0x46, 0x50, 0x46, 0xF0, 0xF7, 0x26, 0xFA, + 0x06, 0x00, 0x71, 0xD0, 0x40, 0xF2, 0x7F, 0x10, 0x00, 0x90, 0x3F, 0x4B, + 0x22, 0x46, 0x3F, 0x49, 0x30, 0x46, 0xF0, 0xF7, 0xE1, 0xF9, 0x00, 0x28, + 0x6A, 0xD0, 0x39, 0x49, 0x39, 0x48, 0x00, 0x95, 0xA3, 0x8F, 0x02, 0x22, + 0x38, 0x31, 0x80, 0x1C, 0xE8, 0xF7, 0x7B, 0xDC, 0x21, 0x8F, 0x60, 0x6B, + 0x2A, 0x46, 0x01, 0x44, 0x06, 0xF1, 0x18, 0x00, 0x1A, 0xF4, 0x87, 0xF5, + 0x09, 0x96, 0xAD, 0xF8, 0x1E, 0x80, 0xE0, 0x8F, 0xAD, 0xF8, 0x20, 0x50, + 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x60, 0x88, 0x4A, 0x46, + 0x06, 0xA9, 0x00, 0xF0, 0x5D, 0xF8, 0x20, 0x8F, 0x28, 0x44, 0x20, 0x87, + 0x60, 0x8F, 0x40, 0x1B, 0x60, 0x87, 0xE0, 0x8F, 0x40, 0xF0, 0x02, 0x00, + 0xE0, 0x87, 0x7F, 0xE7, 0x40, 0xF2, 0x97, 0x13, 0x24, 0x4A, 0x59, 0x46, + 0x50, 0x46, 0xF0, 0xF7, 0xE7, 0xF9, 0x06, 0x00, 0x32, 0xD0, 0x60, 0x8F, + 0x00, 0x90, 0x1E, 0x49, 0x1E, 0x48, 0xA3, 0x8F, 0x02, 0x22, 0x70, 0x31, + 0x80, 0x1C, 0xE8, 0xF7, 0x46, 0xDC, 0x21, 0x8F, 0x60, 0x6B, 0x62, 0x8F, + 0x01, 0x44, 0x06, 0xF1, 0x18, 0x00, 0x1A, 0xF4, 0x52, 0xF5, 0x00, 0xE0, + 0x1E, 0xE0, 0x60, 0x6B, 0x16, 0x4B, 0x18, 0x49, 0x04, 0x60, 0x40, 0xF2, + 0xA5, 0x10, 0x00, 0x90, 0x30, 0x46, 0x62, 0x6B, 0xF0, 0xF7, 0x8C, 0xF9, + 0xB0, 0xB1, 0x09, 0x96, 0xAD, 0xF8, 0x1E, 0x80, 0xE0, 0x8F, 0x4A, 0x46, + 0x40, 0xF0, 0x01, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x60, 0x8F, 0xAD, 0xF8, + 0x20, 0x00, 0x60, 0x88, 0x06, 0xA9, 0x00, 0xF0, 0x19, 0xF8, 0x67, 0x63, + 0x67, 0x87, 0x43, 0xE7, 0x01, 0x20, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x67, 0x63, 0x00, 0x20, 0xF9, 0xE7, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00, + 0x05, 0x74, 0x20, 0x00, 0x24, 0x14, 0xC0, 0x08, 0x01, 0x3B, 0x10, 0x21, + 0xAC, 0xA7, 0x82, 0x00, 0x79, 0xE6, 0x81, 0x00, 0x21, 0xF5, 0x81, 0x00, + 0x8B, 0x88, 0x23, 0xF0, 0x18, 0x03, 0x8B, 0x80, 0x0A, 0xB1, 0x08, 0x22, + 0x00, 0xE0, 0x10, 0x22, 0x13, 0x43, 0x8B, 0x80, 0x48, 0x81, 0x4F, 0xF4, + 0x00, 0x70, 0x08, 0x80, 0x04, 0x48, 0x4F, 0xF4, 0x97, 0x73, 0x02, 0x4A, + 0x00, 0x78, 0xF0, 0xF7, 0x8D, 0xBC, 0x00, 0x00, 0x97, 0xA7, 0x82, 0x00, + 0xEC, 0x75, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x00, 0x24, 0x06, 0x46, + 0x8D, 0xF8, 0x08, 0x40, 0x8D, 0xF8, 0x0C, 0x40, 0x8D, 0xF8, 0x10, 0x10, + 0x08, 0x0A, 0x8D, 0xF8, 0x09, 0x40, 0x8D, 0xF8, 0x0D, 0x40, 0x8D, 0xF8, + 0x0A, 0x40, 0x8D, 0xF8, 0x0E, 0x40, 0x8D, 0xF8, 0x11, 0x00, 0x0B, 0x46, + 0x0D, 0xF1, 0x12, 0x05, 0x8D, 0xF8, 0x0B, 0x40, 0x8D, 0xF8, 0x0F, 0x40, + 0x01, 0x22, 0x08, 0x49, 0x08, 0x48, 0xE8, 0xF7, 0xCC, 0xDB, 0x02, 0xA8, + 0x28, 0x1A, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x04, 0x02, 0xAB, 0x15, 0x22, + 0x31, 0x46, 0x00, 0x20, 0x00, 0xF0, 0x5C, 0xFA, 0x06, 0xB0, 0x70, 0xBD, + 0xA0, 0x1E, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x30, 0xB5, 0x87, 0xB0, + 0x04, 0x46, 0x00, 0x8B, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x0A, 0x8D, 0xF8, + 0x11, 0x00, 0x20, 0x7B, 0x8D, 0xF8, 0x12, 0x00, 0xA0, 0x89, 0x0D, 0xF1, + 0x1A, 0x05, 0x00, 0x0A, 0x8D, 0xF8, 0x13, 0x00, 0x20, 0x7C, 0x8D, 0xF8, + 0x14, 0x00, 0x20, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x15, 0x00, 0x20, 0x7D, + 0x8D, 0xF8, 0x16, 0x00, 0xA0, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x17, 0x00, + 0x94, 0xF8, 0x44, 0x00, 0x8D, 0xF8, 0x18, 0x00, 0xB4, 0xF8, 0x44, 0x00, + 0x00, 0x0A, 0x8D, 0xF8, 0x19, 0x00, 0xA0, 0x89, 0xB4, 0xF8, 0x44, 0x30, + 0xA2, 0x8A, 0x21, 0x8A, 0x8D, 0xE8, 0x0F, 0x00, 0x23, 0x8B, 0x05, 0x22, + 0x08, 0x49, 0x09, 0x48, 0xE8, 0xF7, 0x85, 0xDB, 0x04, 0xA8, 0x28, 0x1A, + 0x00, 0x21, 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x04, 0xAB, 0x14, 0x22, + 0x20, 0x46, 0x00, 0xF0, 0x15, 0xFA, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00, + 0x44, 0x1E, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x30, 0xB5, 0x87, 0xB0, + 0x04, 0x46, 0x80, 0x89, 0x8D, 0xF8, 0x10, 0x00, 0x00, 0x0A, 0x8D, 0xF8, + 0x11, 0x00, 0x20, 0x7C, 0x8D, 0xF8, 0x12, 0x00, 0x20, 0x8A, 0x0D, 0xF1, + 0x1A, 0x05, 0x00, 0x0A, 0x8D, 0xF8, 0x13, 0x00, 0x20, 0x7D, 0x8D, 0xF8, + 0x14, 0x00, 0xA0, 0x8A, 0x00, 0x0A, 0x8D, 0xF8, 0x15, 0x00, 0x94, 0xF8, + 0x44, 0x00, 0x8D, 0xF8, 0x16, 0x00, 0xB4, 0xF8, 0x44, 0x00, 0x8D, 0xF8, + 0x18, 0x10, 0x00, 0x0A, 0x8D, 0xF8, 0x17, 0x00, 0x08, 0x0A, 0x8D, 0xF8, + 0x19, 0x00, 0xA2, 0x8A, 0xB4, 0xF8, 0x44, 0x00, 0x23, 0x8A, 0xCD, 0xE9, + 0x00, 0x32, 0xCD, 0xE9, 0x02, 0x01, 0xA3, 0x89, 0x05, 0x22, 0x08, 0x49, + 0x08, 0x48, 0xE8, 0xF7, 0x3E, 0xDB, 0x04, 0xA8, 0x28, 0x1A, 0x00, 0x21, + 0x80, 0xB2, 0xCD, 0xE9, 0x00, 0x01, 0x04, 0xAB, 0x15, 0x22, 0x20, 0x46, + 0x00, 0xF0, 0xCE, 0xF9, 0x07, 0xB0, 0x30, 0xBD, 0xC4, 0x1E, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0x80, 0x89, 0xCD, 0xE9, + 0x00, 0x01, 0x0D, 0x46, 0xE3, 0x89, 0x03, 0x22, 0x0C, 0x49, 0x0D, 0x48, + 0xE8, 0xF7, 0x21, 0xDB, 0xA0, 0x89, 0x8D, 0xF8, 0x08, 0x00, 0x00, 0x0A, + 0x8D, 0xF8, 0x09, 0x00, 0x8D, 0xF8, 0x0A, 0x50, 0x28, 0x0A, 0x8D, 0xF8, + 0x0B, 0x00, 0x00, 0x21, 0x04, 0x20, 0xCD, 0xE9, 0x00, 0x01, 0x02, 0xAB, + 0x16, 0x22, 0x20, 0x46, 0x00, 0xF0, 0xA8, 0xF9, 0x3E, 0xBD, 0x00, 0x00, + 0x1C, 0x1F, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, 0x70, 0xB5, 0x06, 0x46, + 0xCB, 0x88, 0xC8, 0x68, 0x0C, 0x46, 0xC5, 0x18, 0x96, 0xF8, 0x34, 0x00, + 0x40, 0xB1, 0x1C, 0x2B, 0x0D, 0xD2, 0x01, 0x22, 0x19, 0x49, 0x1A, 0x48, + 0xE8, 0xF7, 0xF7, 0xDA, 0x00, 0x20, 0x70, 0xBD, 0x03, 0x46, 0x16, 0x49, + 0x16, 0x48, 0x01, 0x22, 0x20, 0x39, 0x40, 0x1C, 0xF4, 0xE7, 0x22, 0x89, + 0xF0, 0x8A, 0x82, 0x42, 0x13, 0xD8, 0xA8, 0x1E, 0x29, 0x46, 0xEE, 0xF7, + 0x1A, 0xFD, 0x20, 0x7A, 0x05, 0xF8, 0x04, 0x0D, 0x20, 0x89, 0x00, 0x0A, + 0x68, 0x70, 0xA0, 0x88, 0x40, 0xF0, 0x04, 0x00, 0xA0, 0x80, 0x20, 0x89, + 0x80, 0x1C, 0x20, 0x81, 0xE0, 0x88, 0x00, 0x1F, 0xE0, 0x80, 0x40, 0xF2, + 0xD6, 0x33, 0x08, 0x4A, 0x21, 0x46, 0x06, 0xF1, 0x20, 0x00, 0xF0, 0xF7, + 0x9B, 0xFE, 0x00, 0x28, 0xD5, 0xD0, 0x30, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0xF0, 0x06, 0xB8, 0xA8, 0x21, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, + 0xAC, 0xA8, 0x82, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x90, 0xF8, 0x34, 0x30, + 0xDF, 0xF8, 0x04, 0x82, 0x8B, 0xB0, 0x04, 0x46, 0x4B, 0xB1, 0x80, 0x4E, + 0x08, 0xF1, 0x02, 0x09, 0x00, 0x25, 0xB4, 0xF8, 0x46, 0x00, 0x40, 0xB1, + 0xA0, 0x6A, 0x70, 0xB1, 0x2D, 0xE0, 0x01, 0x22, 0x7B, 0x49, 0x40, 0x46, + 0xE8, 0xF7, 0xA9, 0xDA, 0xEB, 0xE0, 0x79, 0x49, 0x23, 0x8E, 0x01, 0x22, + 0x24, 0x31, 0x40, 0x46, 0xE8, 0xF7, 0xA1, 0xDA, 0xDE, 0xE0, 0x4F, 0xF4, + 0x4B, 0x73, 0x75, 0x4A, 0x06, 0xA9, 0x04, 0xF1, 0x20, 0x00, 0xF0, 0xF7, + 0x3B, 0xFE, 0x00, 0x28, 0xF4, 0xD0, 0xBD, 0xF8, 0x1C, 0x00, 0x20, 0xF0, + 0x38, 0x00, 0x40, 0xF0, 0x08, 0x00, 0xAD, 0xF8, 0x1C, 0x00, 0x09, 0x98, + 0xA0, 0x62, 0xBD, 0xF8, 0x1E, 0x00, 0xA0, 0x85, 0xBD, 0xF8, 0x20, 0x00, + 0xE0, 0x85, 0xBD, 0xF8, 0x22, 0x00, 0x20, 0x86, 0xBD, 0xF8, 0x1C, 0x00, + 0x60, 0x86, 0x62, 0x8E, 0x50, 0x07, 0x10, 0xD5, 0x09, 0x98, 0x64, 0x4B, + 0x22, 0x46, 0x04, 0x60, 0x40, 0xF2, 0x3F, 0x30, 0x00, 0x90, 0x62, 0x49, + 0x09, 0x98, 0xEF, 0xF7, 0xCD, 0xFF, 0x00, 0x28, 0x7D, 0xD0, 0xE0, 0x89, + 0x06, 0xAA, 0x61, 0x68, 0xA0, 0xE0, 0xE0, 0x8A, 0x12, 0x07, 0x00, 0xF1, + 0x1C, 0x01, 0x89, 0xB2, 0x01, 0xD5, 0x89, 0x1C, 0x89, 0xB2, 0xE2, 0x8D, + 0x82, 0x42, 0x58, 0xD9, 0x4F, 0xF4, 0x56, 0x73, 0x55, 0x4A, 0x30, 0x78, + 0xEF, 0xF7, 0xF0, 0xFF, 0x07, 0x00, 0x67, 0xD0, 0x40, 0xF2, 0x5F, 0x30, + 0x00, 0x90, 0x51, 0x4B, 0x22, 0x46, 0x52, 0x49, 0x38, 0x46, 0xEF, 0xF7, + 0xAB, 0xFF, 0x00, 0x28, 0x5B, 0xD0, 0xE0, 0x8A, 0x00, 0x90, 0x4B, 0x49, + 0x23, 0x8E, 0x02, 0x22, 0x64, 0x31, 0x48, 0x46, 0xE8, 0xF7, 0x45, 0xDA, + 0x1C, 0x20, 0x04, 0x97, 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8E, 0x40, 0xF0, + 0x01, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x8A, 0xAD, 0xF8, 0x0C, 0x00, + 0x94, 0xF8, 0x32, 0x10, 0x07, 0xF1, 0x1C, 0x00, 0x09, 0x07, 0x0C, 0xD5, + 0x94, 0xF8, 0x2E, 0x10, 0x00, 0xF8, 0x01, 0x1B, 0xE1, 0x8D, 0x09, 0x0A, + 0x00, 0xF8, 0x01, 0x1B, 0xBD, 0xF8, 0x0C, 0x10, 0x89, 0x1C, 0xAD, 0xF8, + 0x0C, 0x10, 0xA2, 0x8D, 0xA1, 0x6A, 0x11, 0x44, 0xE2, 0x8A, 0x1A, 0xF4, + 0x34, 0xF3, 0xE0, 0x89, 0x01, 0xAA, 0x61, 0x68, 0x00, 0xF0, 0x70, 0xF8, + 0xB4, 0xF8, 0x46, 0x00, 0x40, 0x1E, 0xA4, 0xF8, 0x46, 0x00, 0xA1, 0x8D, + 0xE0, 0x8A, 0x01, 0x44, 0xA1, 0x85, 0xE1, 0x8D, 0x08, 0x1A, 0xE0, 0x85, + 0x60, 0x8E, 0x20, 0xF0, 0x08, 0x00, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x86, + 0x53, 0xE7, 0x40, 0xF2, 0x83, 0x33, 0x29, 0x4A, 0x30, 0x78, 0xEF, 0xF7, + 0x97, 0xFF, 0x07, 0x00, 0x3E, 0xD0, 0xE0, 0x8D, 0x00, 0x90, 0x24, 0x49, + 0x23, 0x8E, 0x02, 0x22, 0x9C, 0x31, 0x48, 0x46, 0xE8, 0xF7, 0xF7, 0xD9, + 0xA1, 0x8D, 0xA0, 0x6A, 0xE2, 0x8D, 0x01, 0x44, 0x01, 0xE0, 0x33, 0xE0, + 0x2E, 0xE0, 0x07, 0xF1, 0x1C, 0x00, 0x1A, 0xF4, 0x00, 0xF3, 0xA0, 0x6A, + 0x1B, 0x4B, 0x1E, 0x49, 0x04, 0x60, 0x40, 0xF2, 0x91, 0x30, 0x00, 0x90, + 0x38, 0x46, 0xA2, 0x6A, 0xEF, 0xF7, 0x3C, 0xFF, 0x10, 0xB3, 0x60, 0x8E, + 0x01, 0xAA, 0x20, 0xF0, 0x18, 0x00, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x86, + 0x1E, 0x20, 0x04, 0x97, 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8E, 0x40, 0xF0, + 0x01, 0x00, 0xAD, 0xF8, 0x08, 0x00, 0xE0, 0x8D, 0xAD, 0xF8, 0x0C, 0x00, + 0xE0, 0x89, 0x61, 0x68, 0x00, 0xF0, 0x1E, 0xF8, 0xB4, 0xF8, 0x46, 0x00, + 0x40, 0x1E, 0xA4, 0xF8, 0x46, 0x00, 0xA5, 0x62, 0xE5, 0x85, 0x0C, 0xE7, + 0x01, 0x20, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xA5, 0x62, 0x00, 0x20, + 0xF9, 0xE7, 0x00, 0x00, 0x01, 0x3B, 0x10, 0x21, 0x05, 0x74, 0x20, 0x00, + 0xB4, 0x20, 0xC0, 0x08, 0x94, 0xA8, 0x82, 0x00, 0xE9, 0xF4, 0x81, 0x00, + 0xE5, 0xF4, 0x81, 0x00, 0x91, 0xF4, 0x81, 0x00, 0x38, 0xB5, 0x0D, 0x46, + 0x09, 0x79, 0x14, 0x46, 0x51, 0xB3, 0xE2, 0x88, 0xE1, 0x68, 0x11, 0x44, + 0x22, 0x7A, 0x01, 0xF8, 0x04, 0x2D, 0x22, 0x89, 0x12, 0x0A, 0x4A, 0x70, + 0x88, 0x70, 0x02, 0x0A, 0xCA, 0x70, 0x21, 0x89, 0x09, 0x1D, 0x21, 0x81, + 0xE1, 0x88, 0x09, 0x1F, 0xE1, 0x80, 0xA1, 0x88, 0x05, 0x28, 0x21, 0xF0, + 0x18, 0x01, 0xA1, 0x80, 0x4F, 0xF4, 0x00, 0x71, 0x21, 0x80, 0x60, 0x81, + 0x17, 0xD0, 0x4F, 0xF4, 0xF0, 0x73, 0x0E, 0x4A, 0x21, 0x46, 0x05, 0xF1, + 0x14, 0x00, 0xF0, 0xF7, 0x4F, 0xFD, 0x00, 0x28, 0x0C, 0xD0, 0x28, 0x46, + 0xBD, 0xE8, 0x38, 0x40, 0xFF, 0xF7, 0x8E, 0xBC, 0x00, 0x91, 0x2B, 0x46, + 0x02, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE8, 0xF7, 0x74, 0xD9, 0x00, 0x20, + 0x38, 0xBD, 0x4F, 0xF4, 0xEE, 0x73, 0x02, 0x4A, 0x21, 0x46, 0x05, 0xF1, + 0x1C, 0x00, 0xE6, 0xE7, 0xC2, 0xA7, 0x82, 0x00, 0xCC, 0x14, 0xC0, 0x08, + 0x01, 0x3B, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x87, 0xB0, 0x93, 0x46, + 0xDD, 0xE9, 0x14, 0x79, 0x0E, 0x46, 0x05, 0x00, 0x00, 0xD0, 0x6E, 0x68, + 0x3E, 0x4C, 0x76, 0xB1, 0x70, 0x89, 0x07, 0xF1, 0x04, 0x0A, 0x50, 0x45, + 0x10, 0xD2, 0x00, 0x90, 0x02, 0x22, 0x3B, 0x49, 0x20, 0x46, 0x3B, 0x1D, + 0xE8, 0xF7, 0x4D, 0xD9, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x37, 0x49, + 0x00, 0x22, 0x28, 0x39, 0x20, 0x46, 0xE8, 0xF7, 0x44, 0xD9, 0xF5, 0xE7, + 0x1C, 0x30, 0x81, 0xB2, 0x34, 0x48, 0x40, 0xF2, 0x12, 0x23, 0x32, 0x4A, + 0x00, 0x78, 0xEF, 0xF7, 0xCF, 0xFE, 0x5F, 0xEA, 0x00, 0x08, 0xE9, 0xD0, + 0x08, 0xF1, 0x1C, 0x04, 0x00, 0x21, 0x04, 0xF8, 0x01, 0xBB, 0x58, 0x46, + 0xFE, 0xF7, 0x8A, 0xFA, 0x20, 0xB3, 0x2C, 0x4A, 0x30, 0x46, 0x7D, 0xB1, + 0xFE, 0xF7, 0xB1, 0xFC, 0xA8, 0x77, 0x04, 0xF8, 0x01, 0x0B, 0xB9, 0xF1, + 0x00, 0x00, 0x01, 0xD0, 0x03, 0x46, 0x00, 0xE0, 0x13, 0x7E, 0xAA, 0x89, + 0x81, 0x21, 0x05, 0xF1, 0x08, 0x00, 0x0E, 0xE0, 0xFE, 0xF7, 0xA1, 0xFC, + 0xB0, 0x71, 0x04, 0xF8, 0x01, 0x0B, 0xB9, 0xF1, 0x00, 0x00, 0x01, 0xD0, + 0x03, 0x46, 0x00, 0xE0, 0x13, 0x7E, 0x72, 0x88, 0x82, 0x21, 0x06, 0xF1, + 0x40, 0x00, 0x00, 0xF0, 0x3D, 0xF8, 0x0C, 0xE0, 0xBB, 0xF1, 0x16, 0x0F, + 0x02, 0xD0, 0x2D, 0xB1, 0xE8, 0x7F, 0x04, 0xE0, 0x30, 0x46, 0xFE, 0xF7, + 0x88, 0xFC, 0x00, 0xE0, 0xF0, 0x79, 0x04, 0xF8, 0x01, 0x0B, 0x38, 0x0A, + 0x04, 0xF8, 0x01, 0x7B, 0x04, 0xF8, 0x01, 0x0B, 0x00, 0x20, 0x04, 0xE0, + 0x0A, 0x99, 0x09, 0x5C, 0x04, 0xF8, 0x01, 0x1B, 0x40, 0x1C, 0xB8, 0x42, + 0xF8, 0xD3, 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x01, 0x20, 0xAD, 0xF8, + 0x08, 0x00, 0xCD, 0xF8, 0x10, 0x80, 0xAD, 0xF8, 0x0C, 0xA0, 0x05, 0x20, + 0x01, 0xAA, 0x31, 0x46, 0xFF, 0xF7, 0x34, 0xFF, 0x90, 0xE7, 0x00, 0x00, + 0x00, 0x3B, 0x10, 0x21, 0x24, 0x15, 0xC0, 0x08, 0xD3, 0xA7, 0x82, 0x00, + 0x01, 0x74, 0x20, 0x00, 0x68, 0x76, 0x20, 0x00, 0x01, 0x48, 0x41, 0x83, + 0x70, 0x47, 0x00, 0x00, 0x68, 0x76, 0x20, 0x00, 0x30, 0xB4, 0x15, 0x46, + 0x0C, 0x46, 0x81, 0x29, 0x0C, 0xD0, 0x07, 0xA1, 0x09, 0x4A, 0x12, 0x78, + 0x12, 0x06, 0x42, 0xEA, 0x04, 0x42, 0x2A, 0x43, 0x4F, 0xF4, 0x7A, 0x74, + 0x63, 0x43, 0x30, 0xBC, 0xF0, 0xF7, 0x4C, 0xBE, 0x04, 0xA1, 0xF1, 0xE7, + 0x6C, 0x32, 0x63, 0x5F, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, + 0x64, 0x76, 0x20, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x63, 0x68, 0x61, 0x6E, + 0x6E, 0x5F, 0x72, 0x74, 0x78, 0x5F, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00, + 0xF0, 0xF7, 0x4E, 0xBE, 0x1C, 0xB5, 0x44, 0x68, 0x01, 0x22, 0x63, 0x88, + 0xCD, 0xE9, 0x00, 0x12, 0x02, 0x8B, 0x81, 0x89, 0x04, 0xF1, 0x0C, 0x00, + 0x05, 0xF0, 0xA4, 0xFE, 0x1C, 0xBD, 0x00, 0x00, 0x7C, 0xB5, 0x04, 0x46, + 0x40, 0x8A, 0xCD, 0xE9, 0x00, 0x01, 0x0D, 0x46, 0xA3, 0x89, 0x03, 0x22, + 0x06, 0x49, 0x07, 0x48, 0xE8, 0xF7, 0x8B, 0xD8, 0x00, 0x95, 0x60, 0x68, + 0xB4, 0xF8, 0x46, 0x30, 0x62, 0x8A, 0xA1, 0x89, 0x40, 0x88, 0xF3, 0xF7, + 0x67, 0xFC, 0x7C, 0xBD, 0x34, 0x13, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0x83, 0xBC, 0x0A, 0x46, + 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0x98, 0xBC, 0x0A, 0x46, + 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0xAA, 0xBC, 0x0A, 0x46, + 0x81, 0x89, 0x40, 0x68, 0x40, 0x88, 0xF3, 0xF7, 0xC6, 0xBC, 0x00, 0x00, + 0x2D, 0xE9, 0xFC, 0x47, 0xDF, 0xF8, 0x98, 0x80, 0x17, 0x46, 0x0E, 0x46, + 0x81, 0x46, 0x98, 0xF8, 0xCA, 0x41, 0x4B, 0x46, 0x25, 0x46, 0x03, 0x22, + 0x22, 0x49, 0x23, 0x48, 0xCD, 0xE9, 0x00, 0x67, 0xE8, 0xF7, 0x53, 0xD8, + 0xDF, 0xF8, 0x84, 0xC0, 0x00, 0x20, 0x98, 0xF8, 0xCA, 0x11, 0xDC, 0xF8, + 0x04, 0x30, 0x08, 0xE0, 0x33, 0xF8, 0x20, 0x20, 0xB2, 0x42, 0x00, 0xD1, + 0x04, 0x46, 0x02, 0xB9, 0x05, 0x46, 0x40, 0x1C, 0xC0, 0xB2, 0x81, 0x42, + 0xF4, 0xD8, 0x17, 0x48, 0x02, 0x22, 0xC0, 0x1E, 0x8F, 0xB1, 0xA1, 0x42, + 0x0A, 0xD1, 0xA9, 0x42, 0x08, 0xD0, 0x23, 0xF8, 0x25, 0x60, 0xDC, 0xF8, + 0x04, 0x10, 0x02, 0xEB, 0x85, 0x02, 0x01, 0xF8, 0x02, 0x90, 0x0E, 0xE0, + 0x0D, 0x49, 0x01, 0x22, 0x33, 0x46, 0x3C, 0x31, 0x10, 0xE0, 0xA1, 0x42, + 0x0A, 0xD0, 0x00, 0x20, 0x23, 0xF8, 0x24, 0x00, 0xDC, 0xF8, 0x04, 0x10, + 0x02, 0xEB, 0x84, 0x02, 0x88, 0x54, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x87, + 0x04, 0x49, 0x33, 0x46, 0x01, 0x22, 0x74, 0x31, 0xE8, 0xF7, 0x17, 0xD8, + 0x00, 0x20, 0xF5, 0xE7, 0x64, 0x01, 0x20, 0x00, 0x88, 0x12, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x68, 0x76, 0x20, 0x00, 0x13, 0xB5, 0x82, 0xB0, + 0x04, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, + 0x0D, 0x49, 0x0E, 0x48, 0xE8, 0xF7, 0x01, 0xD8, 0x20, 0x46, 0xFE, 0xF7, + 0xD9, 0xFA, 0x28, 0xB1, 0xBD, 0xF8, 0x0C, 0x10, 0x59, 0xB1, 0x03, 0xAA, + 0x07, 0x21, 0x0A, 0xE0, 0x06, 0x49, 0x07, 0x48, 0x23, 0x46, 0x01, 0x22, + 0x30, 0x31, 0xC0, 0x1E, 0xE7, 0xF7, 0xEF, 0xDF, 0x1F, 0xBD, 0x00, 0x22, + 0x06, 0x21, 0xFD, 0xF7, 0xF7, 0xFE, 0x1F, 0xBD, 0x7C, 0x13, 0xC0, 0x08, + 0x03, 0x3B, 0x10, 0x21, 0x7C, 0xB5, 0x04, 0x46, 0x01, 0x89, 0xC0, 0x68, + 0xCD, 0xE9, 0x00, 0x01, 0x63, 0x89, 0x03, 0x22, 0x2B, 0x49, 0x2C, 0x48, + 0xE7, 0xF7, 0xD9, 0xDF, 0x2A, 0x4E, 0x60, 0x89, 0xF6, 0x1E, 0x06, 0x28, + 0x19, 0xD0, 0x04, 0x28, 0x17, 0xD0, 0xFE, 0xF7, 0xAB, 0xFA, 0x05, 0x00, + 0x26, 0xD0, 0x23, 0x89, 0x68, 0x8A, 0x83, 0x42, 0x2A, 0xD9, 0x22, 0x49, + 0x00, 0x90, 0x02, 0x22, 0x94, 0x31, 0x30, 0x46, 0xE7, 0xF7, 0xC3, 0xDF, + 0x20, 0x48, 0xB0, 0xF8, 0x78, 0x01, 0x81, 0x07, 0x01, 0xD4, 0xC0, 0x06, + 0x1C, 0xD5, 0x00, 0x25, 0x29, 0xE0, 0x20, 0x8A, 0x80, 0xB2, 0xFE, 0xF7, + 0x67, 0xFA, 0x01, 0x00, 0x07, 0xD0, 0x60, 0x89, 0x22, 0x46, 0xFF, 0xF7, + 0x05, 0xFE, 0x05, 0x00, 0x1D, 0xD0, 0x01, 0x20, 0x7C, 0xBD, 0x13, 0x49, + 0x01, 0x22, 0x38, 0x31, 0x23, 0x69, 0x03, 0xE0, 0x10, 0x49, 0x63, 0x89, + 0x01, 0x22, 0x68, 0x31, 0x30, 0x46, 0xE7, 0xF7, 0xA0, 0xDF, 0xE2, 0xE7, + 0x2B, 0x7F, 0x06, 0x2B, 0x05, 0xD0, 0x05, 0x2B, 0x03, 0xD0, 0x0A, 0x49, + 0x01, 0x22, 0xCC, 0x31, 0xF2, 0xE7, 0x21, 0x46, 0x28, 0x46, 0xFF, 0xF7, + 0x8B, 0xFC, 0x05, 0x00, 0x08, 0xD1, 0x20, 0x79, 0xC0, 0x07, 0x05, 0xD0, + 0x40, 0xF2, 0xCD, 0x22, 0x05, 0x49, 0xE0, 0x68, 0xEF, 0xF7, 0x0A, 0xFE, + 0x28, 0x46, 0x7C, 0xBD, 0x60, 0x15, 0xC0, 0x08, 0x03, 0x3B, 0x10, 0x21, + 0x64, 0x01, 0x20, 0x00, 0xE7, 0xA7, 0x82, 0x00, 0x10, 0xB5, 0xFE, 0xF7, + 0x55, 0xFA, 0x00, 0x28, 0x05, 0xD0, 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, + 0x03, 0x21, 0xFD, 0xF7, 0x7F, 0xBE, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, + 0x1E, 0x46, 0x15, 0x46, 0x0C, 0x46, 0x07, 0x46, 0xFE, 0xF7, 0x44, 0xFA, + 0x30, 0xB1, 0xBD, 0xF8, 0x18, 0x10, 0x61, 0xB1, 0x06, 0xAA, 0x40, 0xF2, + 0x03, 0x11, 0x1C, 0xE0, 0x3B, 0x46, 0x01, 0x22, 0x0F, 0x49, 0x10, 0x48, + 0xE7, 0xF7, 0x5B, 0xDF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x0E, 0x49, + 0xB1, 0xF8, 0xA8, 0x11, 0x04, 0x82, 0x89, 0x1F, 0x89, 0xB2, 0x8C, 0x42, + 0x01, 0xD2, 0x84, 0x82, 0x00, 0xE0, 0x81, 0x82, 0xA0, 0xF8, 0x44, 0x50, + 0xA0, 0xF8, 0x48, 0x50, 0xA0, 0xF8, 0x4A, 0x60, 0x00, 0x22, 0x40, 0xF2, + 0x01, 0x11, 0xFD, 0xF7, 0x4F, 0xFE, 0x01, 0x20, 0xE5, 0xE7, 0x00, 0x00, + 0xDC, 0x1F, 0xC0, 0x08, 0x00, 0x3B, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x47, 0x82, 0x46, 0x22, 0x48, 0x98, 0x46, 0x15, 0x46, + 0xB0, 0xF8, 0xA8, 0x01, 0x0F, 0x46, 0x80, 0x1F, 0x86, 0xB2, 0x50, 0x46, + 0xDD, 0xF8, 0x20, 0x90, 0xFE, 0xF7, 0xDA, 0xF9, 0x04, 0x46, 0x17, 0x2D, + 0x11, 0xD3, 0x87, 0xB1, 0x7C, 0xB1, 0x38, 0x46, 0xFE, 0xF7, 0x1A, 0xFA, + 0x70, 0xB1, 0x00, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0xD1, 0xF8, 0x04, 0x00, + 0x0B, 0xD0, 0x27, 0x83, 0x25, 0x82, 0xB5, 0x42, 0x10, 0xD2, 0xA5, 0x82, + 0x0F, 0xE0, 0x40, 0xF2, 0x05, 0x22, 0x04, 0xE0, 0x40, 0xF2, 0x02, 0x22, + 0x01, 0xE0, 0x40, 0xF2, 0xF3, 0x22, 0x00, 0x21, 0x50, 0x46, 0xF3, 0xF7, + 0x2E, 0xFB, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0xA6, 0x82, 0xA4, 0xF8, + 0x44, 0x80, 0xA4, 0xF8, 0x48, 0x80, 0xA4, 0xF8, 0x4A, 0x90, 0x01, 0x20, + 0x60, 0x77, 0x00, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0x80, 0xFE, 0x00, 0x22, + 0x04, 0x21, 0x20, 0x46, 0xFD, 0xF7, 0x00, 0xFE, 0x01, 0x20, 0xE9, 0xE7, + 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, 0x00, 0x25, 0xFE, 0xF7, + 0xC5, 0xF9, 0x10, 0x4B, 0x04, 0x00, 0x0B, 0xD0, 0x20, 0x7F, 0x06, 0x28, + 0x11, 0xD0, 0x00, 0x22, 0x0D, 0x49, 0x18, 0x46, 0xE7, 0xF7, 0xDF, 0xDE, + 0x4F, 0xF4, 0x3D, 0x75, 0x28, 0x46, 0x70, 0xBD, 0x09, 0x49, 0x00, 0x22, + 0x2C, 0x39, 0x18, 0x46, 0xE7, 0xF7, 0xD5, 0xDE, 0x40, 0xF2, 0x05, 0x20, + 0x70, 0xBD, 0x31, 0x46, 0x20, 0x46, 0xFF, 0xF7, 0xA1, 0xFB, 0x34, 0xF8, + 0x44, 0x0F, 0x30, 0x44, 0x20, 0x80, 0xEB, 0xE7, 0x00, 0x3B, 0x10, 0x21, + 0x38, 0x20, 0xC0, 0x08, 0x10, 0xB5, 0xFE, 0xF7, 0x9D, 0xF9, 0x28, 0xB1, + 0x00, 0x22, 0x05, 0x21, 0xFD, 0xF7, 0xCA, 0xFD, 0x00, 0x20, 0x10, 0xBD, + 0x40, 0xF2, 0x05, 0x20, 0x10, 0xBD, 0x7F, 0xB5, 0x0C, 0x46, 0x06, 0x46, + 0xFE, 0xF7, 0x64, 0xF9, 0x05, 0x00, 0x0F, 0xD0, 0x23, 0x89, 0xE2, 0x88, + 0xA1, 0x88, 0x60, 0x88, 0xFE, 0xF7, 0x33, 0xF8, 0x00, 0x28, 0x05, 0xD1, + 0x28, 0x7A, 0x40, 0xB1, 0xA8, 0x79, 0xA8, 0xB1, 0x40, 0xF2, 0x01, 0x20, + 0x04, 0xB0, 0x70, 0xBD, 0x40, 0xF2, 0x05, 0x20, 0xFA, 0xE7, 0x20, 0x89, + 0xA2, 0x89, 0x61, 0x89, 0x8D, 0xE8, 0x07, 0x00, 0xE3, 0x88, 0xA2, 0x88, + 0x61, 0x88, 0x30, 0x46, 0xFB, 0xF7, 0x47, 0xFC, 0x40, 0xBB, 0x4F, 0xF4, + 0xB4, 0x70, 0xEB, 0xE7, 0xA0, 0x78, 0x8D, 0xF8, 0x08, 0x00, 0x60, 0x88, + 0x00, 0x21, 0x00, 0x0A, 0x8D, 0xF8, 0x09, 0x00, 0x20, 0x79, 0x8D, 0xF8, + 0x0A, 0x00, 0xA0, 0x88, 0x02, 0xAB, 0x00, 0x0A, 0x8D, 0xF8, 0x0B, 0x00, + 0xA0, 0x79, 0x8D, 0xF8, 0x0C, 0x00, 0xE0, 0x88, 0x12, 0x22, 0x00, 0x0A, + 0x8D, 0xF8, 0x0D, 0x00, 0x20, 0x7A, 0x8D, 0xF8, 0x0E, 0x00, 0x20, 0x89, + 0x00, 0x0A, 0x8D, 0xF8, 0x0F, 0x00, 0x08, 0x20, 0xCD, 0xE9, 0x00, 0x01, + 0x29, 0x46, 0x00, 0x20, 0xFF, 0xF7, 0x04, 0xFD, 0x00, 0x20, 0xC3, 0xE7, + 0x2D, 0xE9, 0xFF, 0x5F, 0x98, 0x46, 0xDD, 0xE9, 0x10, 0x64, 0xDD, 0xE9, + 0x0E, 0x57, 0x91, 0x46, 0x8A, 0x46, 0x83, 0x46, 0xFE, 0xF7, 0x0C, 0xF9, + 0x01, 0x00, 0x23, 0xD0, 0x08, 0x7A, 0x00, 0x28, 0x20, 0xD1, 0x8D, 0xF8, + 0x0C, 0x40, 0x20, 0x0A, 0x8D, 0xF8, 0x0D, 0x00, 0x00, 0x22, 0x02, 0x20, + 0xCD, 0xE9, 0x00, 0x02, 0x03, 0xAB, 0x13, 0x22, 0x00, 0x20, 0xFF, 0xF7, + 0xE3, 0xFC, 0x00, 0x2C, 0x10, 0xD1, 0x2B, 0x46, 0x42, 0x46, 0x49, 0x46, + 0x50, 0x46, 0xFD, 0xF7, 0xC8, 0xFF, 0x00, 0x28, 0x08, 0xD1, 0xCD, 0xE9, + 0x00, 0x57, 0x43, 0x46, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0x02, 0x96, + 0xFB, 0xF7, 0xE9, 0xFB, 0xBD, 0xE8, 0xFF, 0x9F, 0x2D, 0xE9, 0xFF, 0x41, + 0x1F, 0x46, 0xCD, 0xE9, 0x00, 0x12, 0x14, 0x46, 0x0D, 0x46, 0x06, 0x46, + 0x43, 0x78, 0x03, 0x22, 0x0D, 0x49, 0x0E, 0x48, 0xE7, 0xF7, 0x25, 0xDE, + 0x60, 0x19, 0x8D, 0xF8, 0x08, 0x00, 0x20, 0x1D, 0xC3, 0xB2, 0x71, 0x78, + 0x38, 0x19, 0x2A, 0x46, 0xF6, 0xF7, 0x02, 0xF9, 0x28, 0xB9, 0x71, 0x78, + 0x04, 0x22, 0x02, 0xA8, 0xF6, 0xF7, 0xEE, 0xFB, 0x18, 0xB1, 0x00, 0x20, + 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x20, 0xFA, 0xE7, 0x00, 0x00, + 0x04, 0x71, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0C, 0x46, + 0x03, 0x46, 0xA0, 0xF5, 0x18, 0x72, 0x00, 0x25, 0x19, 0x48, 0x1A, 0x49, + 0x0A, 0x2A, 0x27, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, 0x05, 0x07, 0x0B, 0x12, + 0x15, 0x17, 0x1D, 0x1F, 0x21, 0x23, 0x00, 0x79, 0x0B, 0xE0, 0x0A, 0x78, + 0x13, 0x49, 0x08, 0x31, 0x02, 0xE0, 0x11, 0x49, 0x02, 0x78, 0x0C, 0x31, + 0x20, 0x46, 0x19, 0xF4, 0x00, 0xF7, 0x19, 0xE0, 0x40, 0x78, 0x20, 0x70, + 0x16, 0xE0, 0x80, 0x78, 0xFB, 0xE7, 0xD0, 0xF8, 0x06, 0x10, 0x21, 0x60, + 0x40, 0x89, 0xA0, 0x80, 0x0E, 0xE0, 0x48, 0x78, 0xF3, 0xE7, 0xC0, 0x78, + 0xF1, 0xE7, 0x88, 0x88, 0x00, 0xE0, 0xC8, 0x88, 0x20, 0x80, 0x05, 0xE0, + 0x03, 0x25, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, 0xE7, 0xF7, 0xD1, 0xDD, + 0x28, 0x46, 0x70, 0xBD, 0x38, 0x79, 0x20, 0x00, 0x88, 0x74, 0x20, 0x00, + 0xD4, 0x81, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x1C, 0xB5, 0x41, 0x88, + 0x4F, 0xF4, 0x9A, 0x73, 0xB1, 0xF5, 0x9B, 0x7F, 0x05, 0xD0, 0x08, 0xDC, + 0xB1, 0xF5, 0x99, 0x7F, 0x10, 0xD0, 0x99, 0x42, 0x28, 0xD1, 0x19, 0x4A, + 0x92, 0x78, 0x82, 0xB1, 0x25, 0xE0, 0xA1, 0xF5, 0x80, 0x71, 0x67, 0x39, + 0x25, 0xD0, 0x1B, 0x29, 0x1E, 0xD1, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D, + 0x00, 0xF0, 0x60, 0xB8, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D, 0x00, 0xF0, + 0x25, 0xB8, 0x10, 0x4A, 0x54, 0x79, 0x94, 0xB1, 0x00, 0x24, 0x54, 0x71, + 0x0E, 0x4A, 0x12, 0x68, 0x00, 0x2A, 0x0B, 0xD0, 0x99, 0x42, 0x01, 0xD1, + 0x80, 0x88, 0x00, 0xE0, 0xC0, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0xCD, 0xF8, + 0x04, 0xD0, 0x01, 0xA9, 0x40, 0x20, 0x90, 0x47, 0x1C, 0xBD, 0xBD, 0xE8, + 0x1C, 0x40, 0x0A, 0xF0, 0x57, 0xB8, 0xBD, 0xE8, 0x1C, 0x40, 0x00, 0x1D, + 0x00, 0xF0, 0x4C, 0xB8, 0x88, 0x74, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x43, 0x88, 0x16, 0x4D, 0x04, 0x46, + 0x4B, 0xB1, 0x01, 0x22, 0x15, 0x49, 0x16, 0x48, 0xE7, 0xF7, 0x77, 0xDD, + 0x20, 0x78, 0xA8, 0xB1, 0x01, 0x28, 0x0E, 0xD1, 0x1D, 0xE0, 0x10, 0x48, + 0x21, 0x78, 0x00, 0x78, 0x20, 0xF0, 0x0C, 0x00, 0x11, 0xB1, 0x01, 0x29, + 0x05, 0xD1, 0x02, 0xE0, 0x20, 0xF0, 0x02, 0x00, 0x00, 0xE0, 0x08, 0x30, + 0x28, 0x70, 0x60, 0x88, 0xBD, 0xE8, 0x70, 0x40, 0xF7, 0xF7, 0xE8, 0xB8, + 0x28, 0x78, 0xC0, 0xF3, 0x81, 0x01, 0x03, 0x29, 0x02, 0xD1, 0x20, 0xF0, + 0x0C, 0x00, 0xF0, 0xE7, 0x20, 0xF0, 0x0C, 0x00, 0xEA, 0xE7, 0x28, 0x78, + 0xFA, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0xF4, 0x82, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x06, 0x49, 0x08, 0x78, 0xC0, 0xF3, 0x81, 0x02, + 0x02, 0x2A, 0x05, 0xD1, 0x20, 0xF0, 0x0E, 0x00, 0x08, 0x70, 0x00, 0x20, + 0xF7, 0xF7, 0xC8, 0xB8, 0x70, 0x47, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, + 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90, + 0x69, 0x46, 0x41, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0xF4, 0xF7, 0x17, 0xF9, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x41, 0x3C, 0x4E, 0x0C, 0x46, + 0x03, 0x46, 0xA0, 0xF5, 0x18, 0x71, 0xB0, 0x78, 0x00, 0x25, 0x38, 0x4F, + 0x94, 0x46, 0x40, 0xF0, 0x02, 0x00, 0x0A, 0x29, 0x0E, 0xD2, 0xDF, 0xE8, + 0x01, 0xF0, 0x05, 0x14, 0x24, 0x31, 0x39, 0x43, 0x4D, 0x55, 0x5D, 0x63, + 0x01, 0x2C, 0x05, 0xD1, 0x9C, 0xF8, 0x00, 0x10, 0x03, 0x29, 0x01, 0xD8, + 0x39, 0x71, 0x12, 0xE0, 0x03, 0x25, 0x01, 0x22, 0x2E, 0x49, 0x2F, 0x48, + 0xE7, 0xF7, 0x03, 0xDD, 0x0C, 0xE0, 0x1F, 0x2C, 0xF6, 0xD8, 0x2A, 0x48, + 0x22, 0x46, 0x61, 0x46, 0x08, 0x30, 0x19, 0xF4, 0x0E, 0xF6, 0x34, 0x70, + 0xB0, 0x78, 0x40, 0xF0, 0x01, 0x00, 0xB0, 0x70, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x81, 0x1F, 0x2C, 0xE6, 0xD8, 0x21, 0x48, 0x22, 0x46, 0x61, 0x46, + 0x0C, 0x30, 0x19, 0xF4, 0xFE, 0xF5, 0x3C, 0x70, 0xB0, 0x78, 0x40, 0xF0, + 0x04, 0x00, 0xEE, 0xE7, 0x01, 0x2C, 0xD9, 0xD1, 0x9C, 0xF8, 0x00, 0x10, + 0x04, 0x29, 0xD5, 0xD8, 0x79, 0x70, 0xE6, 0xE7, 0x01, 0x2C, 0xD1, 0xD1, + 0x9C, 0xF8, 0x00, 0x10, 0x03, 0x29, 0xCD, 0xD8, 0x01, 0xF0, 0x01, 0x01, + 0xB9, 0x70, 0xDC, 0xE7, 0x06, 0x2C, 0xC7, 0xD1, 0xDC, 0xF8, 0x00, 0x10, + 0xC7, 0xF8, 0x06, 0x10, 0xBC, 0xF8, 0x04, 0x10, 0x79, 0x81, 0xD2, 0xE7, + 0x01, 0x2C, 0xBD, 0xD1, 0x9C, 0xF8, 0x00, 0x10, 0x07, 0x29, 0xB9, 0xD8, + 0x71, 0x70, 0xCA, 0xE7, 0x01, 0x2C, 0xB5, 0xD1, 0x9C, 0xF8, 0x00, 0x10, + 0x03, 0x29, 0xB1, 0xD8, 0xF9, 0x70, 0xC2, 0xE7, 0x02, 0x2C, 0xAD, 0xD1, + 0xBC, 0xF8, 0x00, 0x10, 0xB1, 0x80, 0xBC, 0xE7, 0x02, 0x2C, 0xA7, 0xD1, + 0xBC, 0xF8, 0x00, 0x10, 0xF1, 0x80, 0xB6, 0xE7, 0x38, 0x79, 0x20, 0x00, + 0x88, 0x74, 0x20, 0x00, 0xAC, 0x81, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x08, 0xB5, 0x00, 0x22, 0x8D, 0xF8, 0x00, 0x20, 0x8D, 0xF8, 0x01, 0x00, + 0x8D, 0xF8, 0x02, 0x10, 0x6A, 0x46, 0x03, 0x21, 0x4F, 0xF6, 0x80, 0x50, + 0xF4, 0xF7, 0x0C, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x08, 0xBD, 0x07, 0x20, + 0x08, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x00, 0x22, 0x1B, 0x49, 0x1C, 0x48, + 0xE7, 0xF7, 0x8B, 0xDC, 0x1B, 0x4C, 0x1C, 0x4E, 0x1C, 0x4D, 0x20, 0x78, + 0xC0, 0xF3, 0x81, 0x03, 0x70, 0x79, 0x18, 0x43, 0x07, 0xD0, 0x15, 0x49, + 0x01, 0x22, 0x58, 0x31, 0x28, 0x46, 0xE7, 0xF7, 0x7C, 0xDC, 0x02, 0x20, + 0x70, 0xBD, 0x02, 0xF0, 0xAD, 0xFC, 0x28, 0xB9, 0x71, 0x78, 0xA1, 0xB1, + 0x01, 0x29, 0x12, 0xD0, 0x04, 0x29, 0x10, 0xD0, 0x11, 0x48, 0x81, 0x78, + 0x41, 0xF0, 0x08, 0x01, 0x81, 0x70, 0x20, 0x78, 0x20, 0xF0, 0x0C, 0x00, + 0x00, 0x1D, 0x20, 0x70, 0x09, 0xF0, 0x30, 0xFF, 0x00, 0x20, 0xF6, 0xF7, + 0xEB, 0xFF, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x49, 0x00, 0x22, 0x10, 0x31, + 0x28, 0x46, 0xE7, 0xF7, 0x5A, 0xDC, 0x0B, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x20, 0x82, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00, + 0x38, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0x88, 0x74, 0x20, 0x00, + 0x10, 0xB5, 0x00, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE7, 0xF7, 0x45, 0xDC, + 0x12, 0x4C, 0x20, 0x78, 0xC0, 0xF3, 0x81, 0x03, 0x02, 0x2B, 0x02, 0xD1, + 0x10, 0x48, 0x40, 0x79, 0x40, 0xB1, 0x0C, 0x49, 0x0C, 0x48, 0x01, 0x22, + 0x0C, 0x31, 0xC0, 0x1E, 0xE7, 0xF7, 0x35, 0xDC, 0x02, 0x20, 0x10, 0xBD, + 0x00, 0x20, 0xF3, 0xF7, 0x17, 0xF9, 0x40, 0xB1, 0x20, 0x78, 0x40, 0xF0, + 0x0C, 0x00, 0x20, 0x70, 0x00, 0x20, 0xF6, 0xF7, 0xB1, 0xFF, 0x00, 0x20, + 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xC4, 0x82, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00, + 0x12, 0x48, 0x10, 0xB5, 0x80, 0x78, 0x00, 0x24, 0x00, 0xB9, 0x03, 0x24, + 0x10, 0x49, 0x4A, 0x79, 0x02, 0xB1, 0x01, 0x24, 0x82, 0x07, 0x0F, 0x48, + 0x00, 0x78, 0x02, 0xD5, 0x10, 0xF0, 0x0C, 0x0F, 0x05, 0xD1, 0xC0, 0xF3, + 0x81, 0x00, 0x01, 0x28, 0x01, 0xD0, 0x4C, 0xB1, 0x00, 0xE0, 0x02, 0x24, + 0x23, 0x46, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xE7, 0xF7, 0xFD, 0xDB, + 0x20, 0x46, 0x10, 0xBD, 0x01, 0x20, 0x48, 0x71, 0x09, 0xF0, 0xC2, 0xFE, + 0x00, 0x20, 0x10, 0xBD, 0x88, 0x74, 0x20, 0x00, 0x38, 0x79, 0x20, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x9C, 0x82, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x06, 0x46, 0x17, 0x48, 0x00, 0x23, 0x05, 0x78, + 0x08, 0xE0, 0x47, 0x68, 0x03, 0xEB, 0x43, 0x04, 0x07, 0xEB, 0xC4, 0x04, + 0x27, 0x78, 0x5F, 0xB1, 0x5B, 0x1C, 0xDB, 0xB2, 0xAB, 0x42, 0xF4, 0xD3, + 0x00, 0x22, 0x10, 0x49, 0x10, 0x48, 0xE7, 0xF7, 0xD4, 0xDB, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x25, 0x63, 0x70, 0x25, 0x70, 0x00, 0x20, + 0x60, 0x80, 0xA1, 0x73, 0x31, 0x68, 0xA1, 0x60, 0xB1, 0x88, 0xA1, 0x81, + 0x4A, 0xB1, 0x25, 0x71, 0x06, 0x49, 0x07, 0x48, 0x01, 0x22, 0x20, 0x39, + 0xC0, 0x1C, 0xE7, 0xF7, 0xBE, 0xDB, 0x20, 0x46, 0xE8, 0xE7, 0x20, 0x71, + 0xF4, 0xE7, 0x00, 0x00, 0xBC, 0x78, 0x20, 0x00, 0x10, 0x70, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xF3, 0xF7, 0xE3, 0xF8, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x07, 0x48, 0x10, 0xB5, 0x90, 0xF8, 0x78, 0x01, + 0x00, 0x06, 0x07, 0xD5, 0x00, 0xF0, 0xE8, 0xFD, 0x00, 0x21, 0xBD, 0xE8, + 0x10, 0x40, 0x02, 0x20, 0x00, 0xF0, 0x9E, 0xBC, 0x10, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xF8, 0xB5, 0x06, 0x46, 0x10, 0x48, 0x0D, 0x46, + 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x18, 0xD5, 0x30, 0x46, 0x02, 0xF0, + 0x81, 0xF8, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x46, 0x00, 0x20, 0x00, 0xF0, + 0x89, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xE0, 0xF8, 0x00, 0x20, 0xF8, 0xBD, + 0x31, 0x46, 0x07, 0x48, 0xE7, 0xF7, 0x50, 0xDD, 0x03, 0x46, 0x02, 0x22, + 0x05, 0x49, 0x06, 0x48, 0x00, 0x95, 0xE7, 0xF7, 0x7A, 0xDB, 0x0A, 0x20, + 0xF8, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, + 0xB4, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, + 0x0D, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x13, 0xD5, 0x28, 0x46, + 0x02, 0xF0, 0xDC, 0xF8, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x46, 0x00, 0x20, + 0x00, 0xF0, 0x5E, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xB5, 0xF8, 0x00, 0x20, + 0x70, 0xBD, 0x2B, 0x46, 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE7, 0xF7, + 0x54, 0xDB, 0x0A, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x88, 0x5B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0x01, 0x46, 0x07, 0x48, 0x02, 0xF0, 0x9B, 0xFF, 0x48, 0xB1, + 0x06, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, + 0x80, 0x6A, 0x28, 0x60, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, + 0x1F, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0C, 0x46, + 0x03, 0x46, 0xA0, 0xF5, 0x04, 0x71, 0x00, 0x25, 0x10, 0x48, 0x05, 0x29, + 0x16, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x03, 0x0A, 0x0D, 0x0F, 0x12, 0x00, + 0x0C, 0x49, 0x10, 0x22, 0x0C, 0x31, 0x20, 0x46, 0x19, 0xF4, 0x33, 0xF4, + 0x10, 0xE0, 0x80, 0x68, 0x20, 0x60, 0x0D, 0xE0, 0x40, 0x78, 0x00, 0xE0, + 0x00, 0x78, 0x20, 0x70, 0x08, 0xE0, 0x80, 0x88, 0x20, 0x80, 0x05, 0xE0, + 0x03, 0x25, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE7, 0xF7, 0x0D, 0xDB, + 0x28, 0x46, 0x70, 0xBD, 0x0C, 0x78, 0x20, 0x00, 0x38, 0x5C, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x8A, 0xB0, 0x0C, 0x46, 0x00, 0x21, + 0x21, 0x70, 0x09, 0xAA, 0x07, 0xA9, 0x02, 0xF0, 0xAB, 0xF9, 0xB8, 0xB1, + 0x9D, 0xF8, 0x24, 0x10, 0x07, 0xA8, 0x01, 0xF0, 0xE7, 0xFF, 0x88, 0xB1, + 0x6A, 0x46, 0x11, 0x21, 0x02, 0xF0, 0x2A, 0xFB, 0x60, 0xB1, 0x9D, 0xF8, + 0x1B, 0x30, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, 0xE7, 0xF7, 0xE9, 0xDA, + 0x9D, 0xF8, 0x1B, 0x00, 0x20, 0x70, 0x00, 0x20, 0x0A, 0xB0, 0x10, 0xBD, + 0x03, 0x20, 0xFB, 0xE7, 0xEC, 0x5B, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, + 0x2D, 0xE9, 0xFF, 0x41, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0x94, 0xFF, + 0x05, 0x00, 0x7D, 0xD0, 0xE0, 0x79, 0x00, 0x26, 0x4B, 0x4F, 0xC0, 0x1E, + 0x07, 0x28, 0x77, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x04, 0x27, 0x09, 0x3E, + 0x90, 0x90, 0x49, 0x00, 0x2E, 0x71, 0x00, 0x22, 0xE8, 0x78, 0x11, 0x46, + 0x2F, 0xE0, 0xA0, 0x89, 0x38, 0xB9, 0x40, 0xF2, 0xED, 0x50, 0xA0, 0x81, + 0x00, 0x22, 0x42, 0x49, 0x42, 0x48, 0xE7, 0xF7, 0xBA, 0xDA, 0x97, 0xF8, + 0x78, 0x01, 0x00, 0x06, 0x0C, 0xD5, 0xA0, 0x89, 0xB0, 0xF5, 0x83, 0x7F, + 0x08, 0xD1, 0xA1, 0x79, 0x20, 0x46, 0x01, 0xF0, 0x9F, 0xFF, 0x01, 0x00, + 0x02, 0xD0, 0x04, 0x20, 0x00, 0xF0, 0xA8, 0xFB, 0xA2, 0x89, 0xE8, 0x78, + 0x10, 0xE0, 0x97, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x0A, 0xD5, 0x28, 0x79, + 0x40, 0xB1, 0xA1, 0x79, 0x20, 0x46, 0x01, 0xF0, 0x8D, 0xFF, 0x01, 0x00, + 0x02, 0xD0, 0x01, 0x20, 0x00, 0xF0, 0x96, 0xFB, 0xE8, 0x78, 0x00, 0x22, + 0x01, 0x21, 0x04, 0xB0, 0xBD, 0xE8, 0xF0, 0x41, 0xF6, 0xF7, 0xAC, 0xBD, + 0x97, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x4D, 0xD5, 0xA9, 0x79, 0x04, 0xB0, + 0xE8, 0x1D, 0xBD, 0xE8, 0xF0, 0x41, 0x04, 0xF0, 0xD5, 0xB8, 0x97, 0xF8, + 0x78, 0x01, 0x00, 0x06, 0x42, 0xD5, 0x04, 0xF1, 0x08, 0x01, 0x0D, 0x46, + 0x23, 0x48, 0xE7, 0xF7, 0x49, 0xDC, 0x03, 0x46, 0xA0, 0x7B, 0x00, 0x90, + 0x1E, 0x49, 0x1F, 0x48, 0x02, 0x22, 0x28, 0x31, 0xC0, 0x1C, 0xE7, 0xF7, + 0x70, 0xDA, 0x01, 0x96, 0x02, 0x96, 0x06, 0x22, 0x01, 0xA9, 0x28, 0x46, + 0x03, 0x96, 0x19, 0xF4, 0x31, 0xF3, 0x00, 0x28, 0x28, 0xD0, 0x06, 0x22, + 0x29, 0x46, 0x20, 0x46, 0x19, 0xF4, 0x2A, 0xF3, 0x00, 0x28, 0x21, 0xD0, + 0xA0, 0x7B, 0x00, 0x26, 0x80, 0x1C, 0xC1, 0xB2, 0x28, 0x46, 0x01, 0xF0, + 0x49, 0xFF, 0x00, 0xE0, 0x18, 0xE0, 0x05, 0x46, 0xA1, 0x79, 0x20, 0x46, + 0x02, 0xF0, 0x0E, 0xFF, 0x00, 0xB1, 0x46, 0x79, 0x00, 0x2D, 0x0F, 0xD0, + 0x06, 0x22, 0x21, 0x46, 0x05, 0xF1, 0x08, 0x00, 0x19, 0xF4, 0x10, 0xF3, + 0x10, 0xB9, 0x28, 0x79, 0xB0, 0x42, 0x05, 0xD0, 0xA2, 0x79, 0x33, 0x46, + 0x21, 0x46, 0x28, 0x46, 0x04, 0xF0, 0x66, 0xF9, 0xBD, 0xE8, 0xFF, 0x81, + 0x64, 0x01, 0x20, 0x00, 0x64, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x00, 0x00, 0x30, 0x21, 0x70, 0xB5, 0x8A, 0xB0, 0x04, 0x46, 0x00, 0x26, + 0x02, 0x25, 0x81, 0x79, 0x01, 0xF0, 0x1C, 0xFF, 0x20, 0xB9, 0xA1, 0x79, + 0x20, 0x46, 0x01, 0xF0, 0xA5, 0xFE, 0x30, 0xB1, 0xE1, 0x79, 0x02, 0xAA, + 0x02, 0xF0, 0x5A, 0xFA, 0x06, 0x00, 0x00, 0xD0, 0x01, 0x25, 0xE0, 0x79, + 0xCD, 0xE9, 0x00, 0x05, 0xA1, 0x79, 0x02, 0xAB, 0x32, 0x46, 0x20, 0x46, + 0xF0, 0xF7, 0x26, 0xF8, 0x0A, 0xB0, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, + 0x04, 0x46, 0x00, 0x7A, 0x11, 0x28, 0x09, 0xD0, 0x12, 0x28, 0x07, 0xD0, + 0x13, 0x28, 0x05, 0xD0, 0x14, 0x28, 0x03, 0xD0, 0x15, 0x28, 0x01, 0xD0, + 0x16, 0x28, 0x5A, 0xD1, 0x94, 0xF8, 0x06, 0x90, 0x02, 0x26, 0x4F, 0xF0, + 0x00, 0x08, 0x49, 0x46, 0x20, 0x46, 0x02, 0xF0, 0xB7, 0xFE, 0x05, 0x00, + 0x01, 0xD0, 0x95, 0xF8, 0x05, 0x80, 0x49, 0x46, 0x20, 0x46, 0x01, 0xF0, + 0xE3, 0xFE, 0x28, 0xBB, 0x42, 0x46, 0x49, 0x46, 0x20, 0x46, 0xFF, 0xF7, + 0x01, 0xFE, 0xF8, 0xB9, 0xDF, 0xF8, 0x8C, 0xA0, 0x00, 0x22, 0x21, 0x49, + 0x50, 0x46, 0xE7, 0xF7, 0xE4, 0xD9, 0x21, 0x48, 0x80, 0x78, 0x20, 0xB1, + 0x00, 0x21, 0x03, 0x20, 0x00, 0xF0, 0xDC, 0xFA, 0x0A, 0xE0, 0x02, 0xF0, + 0x61, 0xFA, 0x07, 0x00, 0x06, 0xD0, 0x01, 0x46, 0x00, 0x20, 0x00, 0xF0, + 0xD3, 0xFA, 0x38, 0x46, 0x00, 0xF0, 0x2A, 0xFF, 0x42, 0x46, 0x49, 0x46, + 0x20, 0x46, 0xFF, 0xF7, 0xE1, 0xFD, 0x40, 0xB1, 0xE2, 0x79, 0x21, 0x7A, + 0x04, 0xF1, 0x09, 0x03, 0x03, 0xF0, 0x3C, 0xFC, 0x38, 0xB1, 0x00, 0x26, + 0x05, 0xE0, 0x0E, 0x49, 0x00, 0x22, 0x30, 0x31, 0x50, 0x46, 0xE7, 0xF7, + 0xBC, 0xD9, 0x22, 0x7A, 0xA1, 0x79, 0x33, 0x46, 0x20, 0x46, 0xEF, 0xF7, + 0xEF, 0xFF, 0x00, 0x2E, 0x0B, 0xD1, 0x20, 0x7A, 0x11, 0x28, 0x01, 0xD0, + 0x12, 0x28, 0x06, 0xD1, 0x00, 0x2D, 0x04, 0xD0, 0x28, 0x79, 0x00, 0x28, + 0x01, 0xD1, 0x01, 0x20, 0x28, 0x71, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00, + 0xD8, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x0C, 0x78, 0x20, 0x00, + 0x2D, 0x4A, 0x41, 0x88, 0xB2, 0xF8, 0x78, 0x21, 0x1F, 0x29, 0x4E, 0xD0, + 0x12, 0xDC, 0x17, 0x29, 0x3B, 0xD0, 0x06, 0xDC, 0x08, 0x29, 0x2F, 0xD0, + 0x12, 0x29, 0x4C, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0xC6, 0xB9, 0x19, 0x29, + 0x36, 0xD0, 0x1B, 0x29, 0x3C, 0xD0, 0x1E, 0x29, 0x43, 0xD1, 0x00, 0x1D, + 0x00, 0xF0, 0x22, 0xB9, 0xB1, 0xF5, 0x96, 0x7F, 0x1B, 0xD0, 0x0E, 0xDC, + 0xB1, 0xF5, 0x80, 0x7F, 0x1D, 0xD0, 0xB1, 0xF5, 0x92, 0x7F, 0x1D, 0xD0, + 0xA1, 0xF5, 0x80, 0x71, 0x25, 0x39, 0x32, 0xD1, 0x11, 0x06, 0x30, 0xD5, + 0x00, 0x1D, 0x00, 0xF0, 0x61, 0xB8, 0xB1, 0xF5, 0xDC, 0x7F, 0x27, 0xD0, + 0xA1, 0xF5, 0x80, 0x71, 0xB9, 0x39, 0x1A, 0xD0, 0x02, 0x29, 0x24, 0xD1, + 0x00, 0x1D, 0x00, 0xF0, 0x8A, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x22, 0xB8, + 0x00, 0x1D, 0xFF, 0xF7, 0x83, 0xBE, 0x00, 0x1D, 0x00, 0xF0, 0x5A, 0xB9, + 0x00, 0x1D, 0x00, 0xF0, 0x29, 0xB8, 0x11, 0x06, 0x13, 0xD5, 0x00, 0x1D, + 0xFF, 0xF7, 0x42, 0xBF, 0x11, 0x06, 0x0E, 0xD5, 0x00, 0x1D, 0xFF, 0xF7, + 0x1D, 0xBF, 0x00, 0x1D, 0x00, 0xF0, 0xBE, 0xB8, 0x00, 0x1D, 0x00, 0xF0, + 0x5A, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xCA, 0xB8, 0x00, 0x1D, 0x00, 0xF0, + 0xFB, 0xB8, 0x70, 0x47, 0x64, 0x01, 0x20, 0x00, 0x05, 0x49, 0x0A, 0x78, + 0x01, 0x2A, 0x05, 0xD1, 0x04, 0x4A, 0x40, 0x88, 0x89, 0x88, 0x12, 0x78, + 0xF0, 0xF7, 0x1E, 0xBE, 0x70, 0x47, 0x00, 0x00, 0x0C, 0x78, 0x20, 0x00, + 0x4E, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x81, 0x88, 0x04, 0x46, 0xA1, 0xF5, + 0xA0, 0x60, 0xE6, 0x38, 0x0B, 0xD0, 0xA1, 0xF5, 0xA0, 0x60, 0xE3, 0x38, + 0x07, 0xD0, 0xA1, 0xF5, 0xA0, 0x60, 0xEF, 0x38, 0x03, 0xD0, 0xA1, 0xF5, + 0xA0, 0x60, 0xE7, 0x38, 0x0B, 0xD1, 0x20, 0x88, 0x02, 0xF0, 0x10, 0xFE, + 0x00, 0x28, 0x06, 0xD0, 0xA2, 0x88, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, + 0x01, 0x21, 0xF6, 0xF7, 0x2F, 0xBC, 0x10, 0xBD, 0x2D, 0xE9, 0xFC, 0x47, + 0x04, 0x46, 0x3D, 0x48, 0x4F, 0xF0, 0x00, 0x09, 0x04, 0x21, 0x90, 0xF8, + 0xC1, 0x01, 0xC8, 0x46, 0x01, 0xEB, 0x80, 0x01, 0x4F, 0xF4, 0x89, 0x63, + 0x38, 0x4A, 0x48, 0x46, 0xF1, 0xF7, 0x68, 0xDE, 0x05, 0x00, 0x4F, 0xF0, + 0x02, 0x07, 0x4F, 0xF0, 0x00, 0x06, 0x04, 0xD0, 0x20, 0x78, 0x70, 0xB1, + 0x01, 0x28, 0x0C, 0xD0, 0x16, 0xE0, 0x03, 0x21, 0x00, 0x20, 0xCD, 0xE9, + 0x00, 0x01, 0x62, 0x78, 0x20, 0x78, 0x00, 0x23, 0xA1, 0x1C, 0xF0, 0xF7, + 0xF7, 0xFD, 0xBD, 0xE8, 0xFC, 0x87, 0x61, 0x78, 0xA0, 0x1C, 0x01, 0xF0, + 0xD5, 0xFD, 0x06, 0x00, 0x04, 0xD1, 0x61, 0x78, 0xA0, 0x1C, 0x01, 0xF0, + 0x5D, 0xFD, 0x06, 0x46, 0x20, 0x78, 0x10, 0xB1, 0x01, 0x28, 0x31, 0xD1, + 0x0A, 0xE0, 0x7E, 0xB3, 0x29, 0x46, 0x30, 0x46, 0x01, 0xF0, 0x72, 0xFF, + 0x50, 0xB3, 0x95, 0xF8, 0x00, 0x90, 0x05, 0xF1, 0x04, 0x08, 0x24, 0xE0, + 0x26, 0xB3, 0x29, 0x46, 0x30, 0x46, 0x01, 0xF0, 0x67, 0xFF, 0x90, 0xB1, + 0x2A, 0x78, 0x82, 0xB1, 0x20, 0x7A, 0x82, 0x42, 0x0D, 0xD2, 0x28, 0x1D, + 0xE1, 0x68, 0x19, 0xF4, 0x87, 0xF1, 0x40, 0xB9, 0x20, 0x7A, 0x2A, 0x78, + 0xE3, 0x68, 0x80, 0x1A, 0xC1, 0xB2, 0x30, 0x46, 0xFF, 0xF7, 0x82, 0xFA, + 0x58, 0xB9, 0x20, 0x7A, 0x28, 0x70, 0x22, 0x7A, 0x28, 0x1D, 0xE1, 0x68, + 0x19, 0xF4, 0xC1, 0xF1, 0x29, 0x46, 0x30, 0x46, 0x03, 0xF0, 0x0C, 0xFB, + 0x00, 0xB1, 0x00, 0x27, 0xE0, 0x68, 0x18, 0xB1, 0x21, 0x7A, 0x09, 0xB1, + 0xEF, 0xF7, 0x26, 0xFF, 0xCD, 0xE9, 0x00, 0x87, 0x62, 0x78, 0x20, 0x78, + 0x4B, 0x46, 0xA1, 0x1C, 0xF0, 0xF7, 0xA6, 0xFD, 0x28, 0x46, 0xBD, 0xE8, + 0xFC, 0x47, 0xF1, 0xF7, 0x88, 0x9E, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x84, 0xB1, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, + 0x47, 0xFD, 0x20, 0xB1, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0xF6, 0xF7, + 0x77, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0x22, + 0xF2, 0xF7, 0xDE, 0xBB, 0x1C, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, + 0x35, 0xFD, 0x00, 0x28, 0x0E, 0xD0, 0x08, 0x49, 0x0A, 0x68, 0x00, 0x2A, + 0x0A, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xE0, 0x79, 0x8D, 0xF8, + 0x01, 0x00, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9, 0x22, 0x20, 0x90, 0x47, + 0x1C, 0xBD, 0x00, 0x00, 0x48, 0x78, 0x20, 0x00, 0x1C, 0xB5, 0x04, 0x46, + 0x01, 0x7A, 0x80, 0x1C, 0x02, 0xF0, 0x1A, 0xFD, 0x00, 0x28, 0x0E, 0xD0, + 0x07, 0x49, 0x0A, 0x68, 0x00, 0x2A, 0x0A, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, + 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xCD, 0xF8, 0x04, 0xD0, + 0x01, 0xA9, 0x21, 0x20, 0x90, 0x47, 0x1C, 0xBD, 0x48, 0x78, 0x20, 0x00, + 0x30, 0xB5, 0x04, 0x46, 0x85, 0xB0, 0x00, 0x88, 0x02, 0xF0, 0x38, 0xFD, + 0x05, 0x00, 0x1E, 0xD0, 0x60, 0x88, 0xF0, 0xB1, 0x00, 0x90, 0x23, 0x88, + 0x02, 0x22, 0x18, 0x49, 0x18, 0x48, 0xE7, 0xF7, 0x38, 0xD8, 0x18, 0x48, + 0x02, 0x68, 0x00, 0x2A, 0x11, 0xD0, 0xE8, 0x78, 0x8D, 0xF8, 0x00, 0x00, + 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x04, 0x00, + 0xA0, 0x68, 0x02, 0x90, 0xE0, 0x68, 0x03, 0x90, 0xCD, 0xF8, 0x10, 0xD0, + 0x04, 0xA9, 0x23, 0x20, 0x90, 0x47, 0x05, 0xB0, 0x30, 0xBD, 0x0D, 0x48, + 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0xE2, 0xD5, 0xA9, 0x79, 0xE8, 0x1D, + 0x01, 0xF0, 0x08, 0xFD, 0x00, 0x28, 0xDC, 0xD0, 0x21, 0x79, 0x19, 0xB1, + 0xA1, 0x68, 0x03, 0xF0, 0x0D, 0xFF, 0xD6, 0xE7, 0xE1, 0x68, 0x03, 0xF0, + 0x69, 0xFF, 0xD2, 0xE7, 0x3C, 0x5D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x48, 0x78, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, + 0x20, 0x21, 0x02, 0xF0, 0xBB, 0xFC, 0x20, 0xB1, 0xC0, 0x78, 0xBD, 0xE8, + 0x10, 0x40, 0xF6, 0xF7, 0x5F, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0x02, 0x23, + 0xBD, 0xE8, 0x10, 0x40, 0x00, 0x22, 0xF3, 0xF7, 0xCF, 0xBF, 0x10, 0xB5, + 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0xA8, 0xFC, 0x30, 0xB1, 0xA1, 0x68, + 0x81, 0x62, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0xF6, 0xF7, 0x98, 0xBC, + 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x02, 0x22, 0xF4, 0xF7, + 0xB1, 0xB8, 0x10, 0xB5, 0x04, 0x46, 0x81, 0x79, 0x02, 0xF0, 0x94, 0xFC, + 0x30, 0xB1, 0xA1, 0x68, 0x81, 0x62, 0xC0, 0x78, 0xBD, 0xE8, 0x10, 0x40, + 0xF6, 0xF7, 0x4E, 0xBC, 0xA1, 0x79, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, + 0x02, 0x22, 0xF4, 0xF7, 0xC9, 0xB8, 0x70, 0xB5, 0x04, 0x46, 0x81, 0x79, + 0x02, 0xF0, 0x80, 0xFC, 0x05, 0x46, 0xA1, 0x79, 0x01, 0x22, 0x20, 0x46, + 0xF4, 0xF7, 0x00, 0xF9, 0x00, 0x2D, 0x05, 0xD0, 0xE1, 0x79, 0xE8, 0x78, + 0xBD, 0xE8, 0x70, 0x40, 0xF6, 0xF7, 0x4E, 0xBC, 0x70, 0xBD, 0x00, 0x00, + 0x03, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x01, 0xD5, 0x02, 0xF0, + 0x7B, 0xBB, 0x70, 0x47, 0x64, 0x01, 0x20, 0x00, 0x0A, 0x46, 0x00, 0xEB, + 0x40, 0x01, 0x07, 0x48, 0x10, 0xB5, 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, + 0x01, 0x78, 0x29, 0xB1, 0x81, 0x79, 0xC0, 0x1D, 0xF2, 0xF7, 0xFC, 0xFA, + 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0x64, 0x78, 0x20, 0x00, + 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0, + 0xE5, 0xFB, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46, + 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF2, 0xF7, + 0x39, 0xFB, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x6C, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0, 0xC9, 0xFB, 0x68, 0xB1, + 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2B, 0x46, 0x00, 0x68, 0x07, 0x4A, + 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF3, 0xF7, 0x44, 0xFF, + 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x05, 0xB1, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x18, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, + 0x01, 0x46, 0x0A, 0x48, 0x02, 0xF0, 0xAC, 0xFB, 0x70, 0xB1, 0x09, 0x49, + 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x07, 0x49, + 0x00, 0x8A, 0x0A, 0x78, 0x06, 0x49, 0x89, 0x88, 0xF0, 0xF7, 0x2E, 0xFC, + 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0xDA, 0xB0, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x4E, 0x74, 0x20, 0x00, 0x0C, 0x78, 0x20, 0x00, + 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0, + 0x8B, 0xFB, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46, + 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF4, 0xF7, + 0x29, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x4C, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, + 0x04, 0x46, 0x01, 0x46, 0x15, 0x46, 0x0A, 0x48, 0x02, 0xF0, 0x6E, 0xFB, + 0x68, 0xB1, 0x09, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2B, 0x46, 0x00, 0x68, + 0x32, 0x46, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF4, 0xF7, + 0x65, 0xF8, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0xE7, 0xB0, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x0E, 0xB5, 0x08, 0x4A, + 0x12, 0x78, 0xD2, 0x07, 0x0B, 0xD0, 0x07, 0x4A, 0x12, 0x68, 0x00, 0x2A, + 0x07, 0xD0, 0x8D, 0xF8, 0x00, 0x00, 0x68, 0x46, 0xCD, 0xE9, 0x01, 0x10, + 0x02, 0xA9, 0x20, 0x20, 0x90, 0x47, 0x0E, 0xBD, 0x38, 0x78, 0x20, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x03, 0x46, 0xA0, 0xF5, + 0x04, 0x72, 0x00, 0x24, 0x34, 0x48, 0x0A, 0x2A, 0x0D, 0xD2, 0xDF, 0xE8, + 0x02, 0xF0, 0x05, 0x26, 0x13, 0x1A, 0x21, 0x40, 0x4A, 0x51, 0x39, 0x5A, + 0x10, 0x29, 0x04, 0xD1, 0x2E, 0x48, 0x10, 0x22, 0x29, 0x46, 0x0C, 0x30, + 0x4A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x2C, 0x49, 0x2C, 0x48, 0xE6, 0xF7, + 0xCE, 0xDE, 0x4F, 0xE0, 0x01, 0x29, 0xF6, 0xD1, 0x29, 0x78, 0x01, 0x29, + 0xF3, 0xD8, 0x41, 0x70, 0x48, 0xE0, 0x01, 0x29, 0xEF, 0xD1, 0x29, 0x78, + 0x01, 0x29, 0xEC, 0xD8, 0x01, 0x70, 0x41, 0xE0, 0x02, 0x29, 0xE8, 0xD1, + 0x29, 0x88, 0x81, 0x80, 0x3C, 0xE0, 0x04, 0x29, 0xE3, 0xD1, 0x21, 0x4A, + 0x29, 0x68, 0x91, 0x42, 0xDF, 0xD8, 0x20, 0x4A, 0x81, 0x60, 0x12, 0x78, + 0xD2, 0x07, 0x31, 0xD0, 0x40, 0x78, 0x08, 0xB1, 0x41, 0xF0, 0x00, 0x41, + 0x08, 0x46, 0xF2, 0xF7, 0xDD, 0xFB, 0x29, 0xE0, 0x01, 0x29, 0xD0, 0xD1, + 0x29, 0x78, 0x01, 0x29, 0xCD, 0xD8, 0x81, 0x70, 0x22, 0xE0, 0x01, 0x29, + 0xC9, 0xD1, 0x28, 0x78, 0x10, 0x28, 0xC6, 0xD8, 0x07, 0x28, 0xC4, 0xD3, + 0x13, 0x49, 0x08, 0x70, 0x18, 0xE0, 0x01, 0x29, 0xBF, 0xD1, 0x29, 0x78, + 0x01, 0x29, 0xBC, 0xD8, 0xC1, 0x70, 0x11, 0xE0, 0x10, 0x29, 0xB8, 0xD1, + 0x08, 0x48, 0x10, 0x22, 0x29, 0x46, 0x1C, 0x30, 0x18, 0xF4, 0x9B, 0xF7, + 0x08, 0xE0, 0x01, 0x29, 0xAF, 0xD1, 0x28, 0x78, 0x01, 0x28, 0xAC, 0xD8, + 0x00, 0xB1, 0x01, 0x20, 0xF2, 0xF7, 0xC3, 0xFB, 0x20, 0x46, 0x70, 0xBD, + 0x0C, 0x78, 0x20, 0x00, 0x0C, 0x5C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x3F, 0x42, 0x0F, 0x00, 0x38, 0x78, 0x20, 0x00, 0x4E, 0x74, 0x20, 0x00, + 0x70, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0x02, 0xF0, + 0xBF, 0xFA, 0x60, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x2A, 0x46, + 0x00, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF3, 0xF7, + 0x31, 0xFF, 0x00, 0x20, 0x70, 0xBD, 0x04, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x37, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0xF2, 0xF7, + 0x69, 0xFB, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0x04, 0x46, 0x40, 0x79, 0x01, 0x22, 0x8C, 0xB0, 0xB2, 0xEB, + 0x90, 0x1F, 0x33, 0xD1, 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, + 0x03, 0x90, 0x60, 0x79, 0x8D, 0xF8, 0x0D, 0x00, 0x20, 0x79, 0x8D, 0xF8, + 0x0E, 0x00, 0xE0, 0x78, 0x8D, 0xF8, 0x0F, 0x00, 0x00, 0x20, 0x08, 0xAA, + 0xC0, 0xF1, 0x0F, 0x03, 0xCB, 0x5C, 0x13, 0x54, 0x40, 0x1C, 0xC0, 0xB2, + 0x10, 0x28, 0xF7, 0xD3, 0x04, 0xAA, 0x08, 0xA9, 0x68, 0x46, 0xE7, 0xF7, + 0x97, 0xDF, 0x9D, 0xF8, 0x1D, 0x00, 0xA1, 0x78, 0x88, 0x42, 0x11, 0xD1, + 0x9D, 0xF8, 0x1E, 0x00, 0x61, 0x78, 0x88, 0x42, 0x0C, 0xD1, 0x9D, 0xF8, + 0x1F, 0x00, 0x21, 0x78, 0x88, 0x42, 0x07, 0xD1, 0x00, 0x22, 0x0A, 0x49, + 0x0A, 0x48, 0xE6, 0xF7, 0x12, 0xDE, 0x01, 0x20, 0x0C, 0xB0, 0x10, 0xBD, + 0x21, 0x46, 0x08, 0x48, 0xE6, 0xF7, 0xDA, 0xDF, 0x03, 0x46, 0x04, 0x49, + 0x04, 0x48, 0x01, 0x22, 0x2C, 0x31, 0x80, 0x1E, 0xE6, 0xF7, 0x03, 0xDE, + 0x00, 0x20, 0xEF, 0xE7, 0x90, 0x71, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, + 0x00, 0x00, 0x30, 0x21, 0x30, 0xB5, 0x17, 0x4D, 0x87, 0xB0, 0x04, 0x00, + 0x02, 0xD0, 0x20, 0x78, 0x01, 0x28, 0x08, 0xD0, 0x01, 0x23, 0x01, 0x22, + 0x13, 0x49, 0x28, 0x46, 0xE6, 0xF7, 0xED, 0xDD, 0x00, 0x20, 0x07, 0xB0, + 0x30, 0xBD, 0xA0, 0x78, 0x00, 0x07, 0x18, 0xD5, 0x6A, 0x46, 0x14, 0x21, + 0x20, 0x46, 0x01, 0xF0, 0x1B, 0xFE, 0x80, 0xB1, 0x10, 0x22, 0x0C, 0x49, + 0x68, 0x46, 0x18, 0xF4, 0xA5, 0xF6, 0x40, 0xB1, 0x08, 0x49, 0x63, 0x78, + 0x01, 0x22, 0x30, 0x39, 0x28, 0x46, 0xE6, 0xF7, 0xD4, 0xDD, 0x01, 0x20, + 0xE5, 0xE7, 0x05, 0x23, 0xDD, 0xE7, 0x04, 0x23, 0xDB, 0xE7, 0x02, 0x23, + 0xD9, 0xE7, 0x00, 0x00, 0x02, 0x35, 0x10, 0x21, 0xFC, 0x73, 0xC0, 0x08, + 0xC2, 0xB3, 0x82, 0x00, 0x02, 0x4A, 0x10, 0x5C, 0x08, 0x40, 0x00, 0xD0, + 0x01, 0x20, 0x70, 0x47, 0x58, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x00, 0x22, + 0x0D, 0x49, 0x0E, 0x48, 0xE6, 0xF7, 0xB7, 0xDD, 0x00, 0x24, 0x0D, 0x4D, + 0x0B, 0xE0, 0x69, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB, 0xC0, 0x00, + 0x01, 0x78, 0x01, 0x29, 0x01, 0xD1, 0x00, 0xF0, 0x11, 0xFB, 0x64, 0x1C, + 0xE4, 0xB2, 0x28, 0x78, 0x84, 0x42, 0xF0, 0xD3, 0xBD, 0xE8, 0x70, 0x40, + 0x01, 0x20, 0xEE, 0xF7, 0xC5, 0xB9, 0x00, 0x00, 0xEC, 0x70, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00, 0xF8, 0xB5, 0x0C, 0x46, + 0x05, 0x46, 0x03, 0x46, 0x00, 0x91, 0x02, 0x22, 0x20, 0x49, 0x21, 0x48, + 0xE6, 0xF7, 0x8F, 0xDD, 0x20, 0x49, 0x1F, 0x4B, 0x00, 0x20, 0xDB, 0x1E, + 0x0A, 0x78, 0x8F, 0x68, 0x17, 0xE0, 0x00, 0xEB, 0x40, 0x01, 0x01, 0xEB, + 0xC0, 0x01, 0x07, 0xEB, 0x41, 0x06, 0x31, 0x78, 0x69, 0xB1, 0x71, 0x78, + 0xA9, 0x42, 0x0A, 0xD1, 0xF1, 0x88, 0xA1, 0x42, 0x07, 0xD1, 0x14, 0x49, + 0x00, 0x22, 0x2C, 0x31, 0x18, 0x46, 0xE6, 0xF7, 0x74, 0xDD, 0x30, 0x46, + 0xF8, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0x90, 0x42, 0xE5, 0xD3, 0x00, 0x21, + 0x09, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x00, 0xEB, 0xC1, 0x00, 0x07, 0xEB, + 0x40, 0x00, 0x06, 0x78, 0x5E, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, + 0xF3, 0xD3, 0x07, 0x49, 0x00, 0x22, 0x54, 0x31, 0x18, 0x46, 0xE6, 0xF7, + 0x5A, 0xDD, 0x00, 0x20, 0xF8, 0xBD, 0x01, 0x21, 0x01, 0x70, 0x45, 0x70, + 0xC4, 0x80, 0x00, 0x21, 0x81, 0x70, 0xF8, 0xBD, 0x24, 0x86, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x70, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x0F, 0x49, + 0x03, 0x46, 0x00, 0x20, 0x0C, 0x78, 0x8A, 0x68, 0x0E, 0xE0, 0x00, 0xEB, + 0x40, 0x01, 0x01, 0xEB, 0xC0, 0x01, 0x02, 0xEB, 0x41, 0x01, 0x0D, 0x78, + 0x25, 0xB1, 0xCD, 0x88, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, + 0x40, 0x1C, 0xC0, 0xB2, 0xA0, 0x42, 0xEE, 0xD3, 0x01, 0x22, 0x04, 0x49, + 0x04, 0x48, 0xE6, 0xF7, 0x2E, 0xDD, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x70, 0x79, 0x20, 0x00, 0xC0, 0x86, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x70, 0xB5, 0x05, 0x46, 0x0F, 0x48, 0x00, 0x22, 0x03, 0x78, 0x84, 0x68, + 0x0F, 0xE0, 0x02, 0xEB, 0x42, 0x00, 0x00, 0xEB, 0xC2, 0x00, 0x04, 0xEB, + 0x40, 0x00, 0x06, 0x78, 0x2E, 0xB1, 0xC6, 0x88, 0x8E, 0x42, 0x02, 0xD1, + 0x86, 0x88, 0xAE, 0x42, 0x0A, 0xD0, 0x52, 0x1C, 0xD2, 0xB2, 0x9A, 0x42, + 0xED, 0xD3, 0x0B, 0x46, 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE6, 0xF7, + 0x06, 0xDD, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, + 0xF4, 0x86, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x00, + 0x0B, 0xD0, 0xE3, 0x88, 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE6, 0xF7, + 0xF4, 0xDC, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0x16, 0x21, 0x18, 0xF4, + 0x81, 0xB6, 0x10, 0xBD, 0x9C, 0x86, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0xF8, 0xB5, 0x0E, 0x46, 0x05, 0x46, 0x01, 0x46, 0x19, 0x48, 0x02, 0xF0, + 0x39, 0xF9, 0x20, 0xB3, 0x00, 0xF0, 0x78, 0xF8, 0x18, 0xB3, 0x00, 0x21, + 0x28, 0x46, 0xFF, 0xF7, 0x41, 0xFF, 0x04, 0x00, 0x1F, 0xD0, 0x14, 0x49, + 0x01, 0x20, 0xA0, 0x70, 0x09, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, + 0x00, 0x10, 0x11, 0x49, 0x00, 0x8A, 0xA0, 0x80, 0xE6, 0x81, 0x0A, 0x78, + 0x00, 0x92, 0x8B, 0x78, 0x8A, 0x88, 0x31, 0x46, 0xF2, 0xF7, 0xE8, 0xFB, + 0x68, 0xB1, 0x00, 0x23, 0xA2, 0x78, 0x19, 0x46, 0x28, 0x46, 0x00, 0xF0, + 0x79, 0xF8, 0x00, 0x20, 0xF8, 0xBD, 0x04, 0x20, 0xF8, 0xBD, 0x0B, 0x20, + 0xF8, 0xBD, 0x08, 0x20, 0xF8, 0xBD, 0x20, 0x46, 0xFF, 0xF7, 0xB6, 0xFF, + 0x07, 0x20, 0xF8, 0xBD, 0xB2, 0xB5, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, + 0xB6, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0xFF, 0xF7, 0x5C, 0xFF, + 0x20, 0xB1, 0x81, 0x78, 0x02, 0x29, 0x03, 0xD0, 0x02, 0x20, 0x10, 0xBD, + 0x03, 0x20, 0x10, 0xBD, 0x03, 0x21, 0x81, 0x70, 0x80, 0x88, 0x21, 0x46, + 0xF2, 0xF7, 0x2A, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x00, 0x26, + 0x10, 0x46, 0xFF, 0xF7, 0x41, 0xFF, 0x20, 0xB1, 0x81, 0x78, 0x02, 0x29, + 0x03, 0xD0, 0x02, 0x20, 0x70, 0xBD, 0x03, 0x20, 0x70, 0xBD, 0xB5, 0xF5, + 0x82, 0x6F, 0x0E, 0xD0, 0xA5, 0xF5, 0x80, 0x61, 0x11, 0x39, 0x0C, 0xD0, + 0x01, 0x29, 0x0D, 0xD0, 0x03, 0x26, 0x2B, 0x46, 0x01, 0x22, 0x06, 0x49, + 0x06, 0x48, 0xE6, 0xF7, 0x74, 0xDC, 0x30, 0x46, 0x70, 0xBD, 0x80, 0x89, + 0x00, 0xE0, 0x80, 0x8A, 0x20, 0x80, 0xF8, 0xE7, 0x00, 0x89, 0xFB, 0xE7, + 0x58, 0x88, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x0D, 0x48, + 0x00, 0x24, 0x21, 0x46, 0x02, 0x78, 0x83, 0x68, 0x0A, 0xE0, 0x01, 0xEB, + 0x41, 0x00, 0x00, 0xEB, 0xC1, 0x00, 0x13, 0xF8, 0x10, 0x00, 0x08, 0xB9, + 0x64, 0x1C, 0xE4, 0xB2, 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, 0xF2, 0xD3, + 0x23, 0x46, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x4D, 0xDC, + 0x20, 0x46, 0x10, 0xBD, 0x70, 0x79, 0x20, 0x00, 0x2C, 0x87, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x3E, 0xB5, 0x09, 0x4C, 0x64, 0x68, 0x00, 0x2C, + 0x0C, 0xD0, 0xAD, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x00, 0x00, 0xAD, 0xF8, + 0x06, 0x30, 0x8D, 0xF8, 0x04, 0x20, 0xCD, 0xF8, 0x08, 0xD0, 0x02, 0xA9, + 0x01, 0x20, 0xA0, 0x47, 0x3E, 0xBD, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, + 0xF8, 0xB5, 0x04, 0x46, 0x16, 0x20, 0x14, 0xFB, 0x00, 0xF6, 0x17, 0x48, + 0x02, 0xF0, 0x2A, 0xFC, 0x15, 0x4A, 0x16, 0x4D, 0x92, 0xF8, 0x41, 0x00, + 0xA0, 0x42, 0x07, 0xD2, 0x00, 0x90, 0x23, 0x46, 0x02, 0x22, 0x13, 0x49, + 0x28, 0x46, 0xE6, 0xF7, 0x1A, 0xDC, 0x1A, 0xE0, 0x11, 0x49, 0xB2, 0xF8, + 0x4E, 0x00, 0x0D, 0x4F, 0x88, 0x80, 0x92, 0xF8, 0x47, 0x00, 0x48, 0x70, + 0x88, 0x70, 0x10, 0x3F, 0xB6, 0x23, 0x3C, 0x70, 0x0C, 0x4A, 0x31, 0x46, + 0x00, 0x20, 0xF1, 0xF7, 0x9D, 0xD9, 0xB8, 0x60, 0x08, 0xB1, 0x01, 0x20, + 0xF8, 0xBD, 0x06, 0x49, 0x00, 0x22, 0x38, 0x31, 0x28, 0x46, 0xE6, 0xF7, + 0xFE, 0xDB, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x00, 0x80, 0x79, 0x20, 0x00, + 0x00, 0x35, 0x10, 0x21, 0x44, 0x87, 0xC0, 0x08, 0xB6, 0x74, 0x20, 0x00, + 0xA6, 0xB5, 0x82, 0x00, 0x10, 0xB5, 0xF2, 0xF7, 0x8F, 0xFB, 0x08, 0xB1, + 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x01, 0x49, 0x48, 0x60, + 0x70, 0x47, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, + 0x17, 0x46, 0x88, 0x46, 0x81, 0x46, 0xFF, 0xF7, 0x91, 0xFE, 0x04, 0x00, + 0x24, 0x48, 0x06, 0x88, 0x24, 0x48, 0x03, 0x88, 0x24, 0x48, 0x09, 0xD0, + 0xA1, 0x78, 0x02, 0x29, 0x0C, 0xD0, 0x00, 0x22, 0x22, 0x49, 0xE6, 0xF7, + 0xCE, 0xDB, 0x02, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x1F, 0x49, 0x00, 0x22, + 0x24, 0x39, 0xE6, 0xF7, 0xC6, 0xDB, 0x28, 0xE0, 0x21, 0x89, 0xB9, 0x42, + 0x06, 0xD2, 0x1B, 0x49, 0x00, 0x22, 0x24, 0x31, 0xE6, 0xF7, 0xBD, 0xDB, + 0x09, 0x20, 0xED, 0xE7, 0xB8, 0xF1, 0x00, 0x0F, 0x1B, 0xD0, 0xD7, 0xB1, + 0xA1, 0x89, 0xD1, 0xB1, 0x32, 0x46, 0x39, 0x46, 0x18, 0x46, 0xEF, 0xF7, + 0x27, 0xFA, 0x05, 0x00, 0x18, 0xD0, 0xA8, 0x19, 0x3A, 0x46, 0x41, 0x46, + 0x18, 0xF4, 0xBD, 0xF4, 0x00, 0x96, 0xA1, 0x88, 0x3B, 0x46, 0x4A, 0x46, + 0x28, 0x46, 0xF2, 0xF7, 0x03, 0xFB, 0x68, 0xB1, 0xA0, 0x89, 0x40, 0x1E, + 0xA0, 0x81, 0x00, 0x20, 0xCE, 0xE7, 0x03, 0x20, 0xCC, 0xE7, 0x07, 0x49, + 0x00, 0x22, 0x4C, 0x31, 0xE6, 0xF7, 0x95, 0xDB, 0x08, 0x20, 0xC5, 0xE7, + 0x07, 0x20, 0xC3, 0xE7, 0x46, 0x78, 0x20, 0x00, 0x44, 0x78, 0x20, 0x00, + 0x00, 0x35, 0x10, 0x21, 0xE8, 0x87, 0xC0, 0x08, 0x70, 0xB5, 0x00, 0x24, + 0x11, 0x4B, 0xB0, 0xF5, 0x80, 0x6F, 0x04, 0xD0, 0xA0, 0xF5, 0x80, 0x65, + 0x01, 0x3D, 0x08, 0xD1, 0x0F, 0xE0, 0x01, 0x29, 0x05, 0xD1, 0x11, 0x78, + 0x5A, 0x78, 0x91, 0x42, 0x01, 0xD8, 0x19, 0x70, 0x0F, 0xE0, 0x03, 0x46, + 0x03, 0x24, 0x01, 0x22, 0x08, 0x49, 0x09, 0x48, 0xE6, 0xF7, 0x6F, 0xDB, + 0x07, 0xE0, 0x02, 0x29, 0xF5, 0xD1, 0x11, 0x88, 0x06, 0x4A, 0x52, 0x88, + 0x91, 0x42, 0xF0, 0xD8, 0x99, 0x80, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, + 0xB6, 0x74, 0x20, 0x00, 0x9C, 0x87, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x70, 0x79, 0x20, 0x00, 0x10, 0xB5, 0xF2, 0xF7, 0x1D, 0xFB, 0x08, 0xB1, + 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x4F, + 0x8F, 0xB0, 0x99, 0x46, 0x93, 0x46, 0x0F, 0x46, 0x05, 0x46, 0x00, 0x24, + 0xDD, 0xF8, 0x60, 0xA0, 0x01, 0xF0, 0x7C, 0xFB, 0x08, 0xB1, 0x4F, 0xB1, + 0x09, 0xE0, 0x00, 0x22, 0x21, 0x49, 0x22, 0x48, 0xE6, 0xF7, 0x3F, 0xDB, + 0x0B, 0x20, 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1F, 0x4F, 0xDF, 0xF8, + 0x80, 0x80, 0x03, 0xAE, 0x98, 0xF8, 0x00, 0x00, 0x70, 0xB3, 0x0D, 0xB1, + 0x07, 0x2D, 0x01, 0xD9, 0x03, 0x20, 0xF0, 0xE7, 0xE8, 0x07, 0x06, 0xD0, + 0x18, 0x49, 0x30, 0x46, 0x10, 0x22, 0x89, 0x1D, 0x18, 0xF4, 0x3B, 0xF4, + 0x01, 0x24, 0xA8, 0x07, 0x07, 0xD5, 0x14, 0x49, 0x06, 0xEB, 0x04, 0x10, + 0x10, 0x22, 0x16, 0x31, 0x18, 0xF4, 0x31, 0xF4, 0x64, 0x1C, 0x68, 0x07, + 0x06, 0xD5, 0x0F, 0x49, 0x06, 0xEB, 0x04, 0x10, 0x10, 0x22, 0x26, 0x31, + 0x18, 0xF4, 0x27, 0xF4, 0xCD, 0xF8, 0x00, 0xA0, 0xCD, 0xE9, 0x01, 0x96, + 0x98, 0xF8, 0x00, 0x00, 0x00, 0xB1, 0x01, 0x20, 0x5B, 0x46, 0x3A, 0x46, + 0x29, 0x46, 0x00, 0xF0, 0x0F, 0xF8, 0xC6, 0xE7, 0x04, 0x49, 0x10, 0x22, + 0x30, 0x46, 0x89, 0x1D, 0xEA, 0xE7, 0x00, 0x00, 0xAC, 0x60, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x68, 0x78, 0x20, 0x00, 0x41, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xFF, 0x4F, 0x23, 0x4E, 0x83, 0xB0, 0x00, 0x25, 0x30, 0x78, + 0xDD, 0xF8, 0x40, 0xB0, 0xDD, 0xF8, 0x48, 0xA0, 0x98, 0x46, 0x89, 0x46, + 0x80, 0x09, 0x0A, 0xD0, 0x02, 0x25, 0x2B, 0x46, 0x01, 0x22, 0x1D, 0x49, + 0x1D, 0x48, 0xE6, 0xF7, 0xE2, 0xDA, 0x07, 0xB0, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x8F, 0x19, 0x46, 0x05, 0x98, 0x01, 0xF0, 0x97, 0xFF, 0x08, 0xB1, + 0x01, 0x25, 0xEE, 0xE7, 0x05, 0x98, 0x01, 0xF0, 0xD1, 0xFE, 0x04, 0x00, + 0x1D, 0xD0, 0x84, 0xF8, 0x06, 0x80, 0x01, 0x27, 0xA7, 0x70, 0xCD, 0xE9, + 0x00, 0x9B, 0xCD, 0xF8, 0x08, 0xA0, 0x42, 0x46, 0x11, 0x9B, 0x05, 0x99, + 0x03, 0x98, 0xF2, 0xF7, 0xE1, 0xF8, 0x80, 0xB1, 0x30, 0x78, 0x00, 0x22, + 0x20, 0xF0, 0xC0, 0x00, 0x40, 0x30, 0x30, 0x70, 0x67, 0x70, 0xE0, 0x78, + 0x01, 0x21, 0xF5, 0xF7, 0x1D, 0xFE, 0x00, 0x20, 0xF5, 0xF7, 0x3E, 0xFE, + 0xD1, 0xE7, 0x08, 0x25, 0xC9, 0xE7, 0x20, 0x46, 0x02, 0xF0, 0x9E, 0xFA, + 0x07, 0x25, 0xC4, 0xE7, 0x38, 0x78, 0x20, 0x00, 0x88, 0x60, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x00, 0x08, 0xD0, 0x61, 0x78, + 0x01, 0x20, 0xED, 0xF7, 0xDB, 0xFE, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, + 0x00, 0xF0, 0x02, 0xB8, 0x10, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x04, 0x46, + 0x43, 0x78, 0x8B, 0xB0, 0x01, 0x22, 0x20, 0x49, 0x20, 0x48, 0xE6, 0xF7, + 0x90, 0xDA, 0x00, 0x25, 0x08, 0x95, 0x09, 0x95, 0x61, 0x78, 0x08, 0xA8, + 0xF5, 0xF7, 0xE8, 0xF8, 0xA0, 0x78, 0x80, 0x07, 0x06, 0xD5, 0x8D, 0xF8, + 0x00, 0x50, 0x61, 0x78, 0x04, 0x22, 0x68, 0x46, 0xF5, 0xF7, 0xB2, 0xF8, + 0xA0, 0x78, 0x40, 0x07, 0x06, 0xD5, 0x8D, 0xF8, 0x00, 0x50, 0x61, 0x78, + 0x04, 0x22, 0x68, 0x46, 0xF5, 0xF7, 0x5C, 0xF9, 0xA0, 0x78, 0x00, 0x07, + 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0xE4, 0xFD, 0xA0, 0x78, 0xC0, 0x06, + 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0x82, 0xFD, 0xA0, 0x78, 0x80, 0x06, + 0x02, 0xD5, 0x60, 0x78, 0xF4, 0xF7, 0xAA, 0xFD, 0xA0, 0x78, 0x40, 0x06, + 0x06, 0xD5, 0x8D, 0xF8, 0x00, 0x50, 0x61, 0x78, 0x04, 0x22, 0x68, 0x46, + 0xF5, 0xF7, 0x32, 0xF8, 0x18, 0x21, 0x20, 0x46, 0x18, 0xF4, 0xE8, 0xF3, + 0x0B, 0xB0, 0x30, 0xBD, 0xD0, 0x70, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0x38, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x01, 0x46, 0x13, 0x48, 0x01, 0xF0, + 0x9F, 0xFE, 0x00, 0xB3, 0x12, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x09, 0x68, + 0x01, 0xEB, 0x00, 0x10, 0x01, 0x21, 0x00, 0x8A, 0x8D, 0xF8, 0x00, 0x10, + 0x8D, 0xF8, 0x01, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x1D, 0xB1, + 0x00, 0x20, 0x8D, 0xF8, 0x03, 0x00, 0x01, 0xE0, 0x8D, 0xF8, 0x03, 0x10, + 0x6A, 0x46, 0x04, 0x21, 0x4F, 0xF6, 0x80, 0x50, 0xF3, 0xF7, 0xA0, 0xFB, + 0x08, 0xB1, 0x00, 0x20, 0x38, 0xBD, 0x07, 0x20, 0x38, 0xBD, 0x04, 0x20, + 0x38, 0xBD, 0x00, 0x00, 0xD8, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x18, 0x4E, 0x04, 0x46, 0x18, 0x4F, 0x70, 0x78, + 0x40, 0x1E, 0x84, 0x42, 0x08, 0xDD, 0x23, 0x46, 0x01, 0x22, 0x16, 0x49, + 0x38, 0x46, 0xE6, 0xF7, 0x10, 0xDA, 0x03, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x70, 0x68, 0x04, 0xEB, 0x44, 0x05, 0x00, 0xEB, 0x05, 0x10, 0x43, 0x78, + 0x02, 0x2B, 0x09, 0xD0, 0x01, 0x2B, 0x07, 0xD0, 0x0D, 0x49, 0x01, 0x22, + 0x2C, 0x31, 0x38, 0x46, 0xE6, 0xF7, 0xFD, 0xD9, 0x04, 0x20, 0xEB, 0xE7, + 0x00, 0x8A, 0x06, 0x21, 0xF2, 0xF7, 0x82, 0xFA, 0x71, 0x68, 0x03, 0x20, + 0x01, 0xEB, 0x05, 0x11, 0x00, 0x22, 0x48, 0x70, 0x01, 0x46, 0x20, 0x46, + 0xF5, 0xF7, 0x52, 0xFD, 0x00, 0x20, 0xDB, 0xE7, 0x60, 0x78, 0x20, 0x00, + 0x00, 0x35, 0x10, 0x21, 0x38, 0x60, 0xC0, 0x08, 0x10, 0xB5, 0xF2, 0xF7, + 0xB5, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0xF2, 0xF7, 0xBF, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x41, 0x88, 0x01, 0x24, 0x40, 0xF2, + 0x65, 0x13, 0xA1, 0xF2, 0x65, 0x12, 0x99, 0x42, 0x16, 0xD0, 0x06, 0xDC, + 0xA1, 0xF5, 0x80, 0x71, 0x61, 0x39, 0x09, 0xD0, 0x02, 0x29, 0x04, 0xD1, + 0x0A, 0xE0, 0x2F, 0x2A, 0x10, 0xD0, 0x31, 0x2A, 0x12, 0xD0, 0x00, 0x24, + 0x20, 0x46, 0x10, 0xBD, 0x00, 0x1D, 0xF5, 0xF7, 0xC1, 0xFA, 0xF9, 0xE7, + 0x00, 0x1D, 0xF5, 0xF7, 0xFD, 0xFA, 0xF5, 0xE7, 0x00, 0x1D, 0xF5, 0xF7, + 0xED, 0xFA, 0xF1, 0xE7, 0x00, 0x1D, 0xF5, 0xF7, 0x53, 0xFA, 0xED, 0xE7, + 0x00, 0x1D, 0xF5, 0xF7, 0x5D, 0xFA, 0xE9, 0xE7, 0x10, 0xB5, 0xF2, 0xF7, + 0x49, 0xFE, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0xF3, 0xF7, 0x34, 0xF8, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xF3, 0xF7, 0x48, 0xF8, 0x08, 0xB1, + 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0x14, 0x4C, + 0xA0, 0x68, 0x28, 0xB9, 0x06, 0x20, 0x00, 0xF0, 0x45, 0xFB, 0x08, 0xB1, + 0x00, 0x20, 0x10, 0xBD, 0x00, 0x23, 0x61, 0x78, 0xA0, 0x68, 0x07, 0xE0, + 0xC3, 0xEB, 0x03, 0x12, 0x00, 0xEB, 0x82, 0x04, 0x22, 0x78, 0x4A, 0xB1, + 0x5B, 0x1C, 0xDB, 0xB2, 0x8B, 0x42, 0xF5, 0xD3, 0x00, 0x22, 0x09, 0x49, + 0x09, 0x48, 0xE6, 0xF7, 0x74, 0xD9, 0xE9, 0xE7, 0x01, 0x20, 0x20, 0x70, + 0x02, 0x46, 0x05, 0x49, 0x05, 0x48, 0x63, 0x70, 0x20, 0x39, 0xC0, 0x1C, + 0xE6, 0xF7, 0x69, 0xD9, 0x20, 0x46, 0x10, 0xBD, 0xF8, 0x79, 0x20, 0x00, + 0x54, 0x8A, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x13, 0x49, + 0x8C, 0x68, 0x14, 0xB1, 0x00, 0x20, 0x4B, 0x78, 0x0E, 0xE0, 0x03, 0x20, + 0x38, 0xBD, 0xC0, 0xEB, 0x00, 0x11, 0x04, 0xEB, 0x81, 0x01, 0x0A, 0x78, + 0x22, 0xB1, 0xCA, 0x78, 0x01, 0x2A, 0x0B, 0xD0, 0x02, 0x2A, 0x09, 0xD0, + 0x40, 0x1C, 0xC0, 0xB2, 0x98, 0x42, 0xF0, 0xD3, 0x00, 0x21, 0x08, 0x46, + 0xF2, 0xF7, 0x72, 0xFC, 0x00, 0x20, 0x38, 0xBD, 0xD0, 0xB2, 0x00, 0x90, + 0x4B, 0x78, 0x02, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x3B, 0xD9, + 0x02, 0x20, 0x38, 0xBD, 0xF8, 0x79, 0x20, 0x00, 0x94, 0x8B, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xFF, 0xF7, 0x9F, 0xFF, 0x08, 0xB1, + 0x40, 0x78, 0x10, 0xBD, 0xFF, 0x20, 0x10, 0xBD, 0x2D, 0xE9, 0xF0, 0x47, + 0x86, 0xB0, 0x88, 0x46, 0x05, 0x00, 0x4F, 0xF0, 0x00, 0x06, 0x01, 0xD0, + 0x04, 0x2D, 0x03, 0xD9, 0x03, 0x20, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, + 0xDF, 0xF8, 0x84, 0xA0, 0x9A, 0xF8, 0x03, 0x00, 0x08, 0xB1, 0x01, 0x20, + 0xF5, 0xE7, 0x00, 0x24, 0xE9, 0x46, 0x0E, 0xE0, 0x18, 0xF8, 0x04, 0x70, + 0x38, 0x46, 0x00, 0xF0, 0xB3, 0xF8, 0x60, 0xB1, 0x80, 0x78, 0xC0, 0x07, + 0x0B, 0xD0, 0x04, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0x09, 0xF8, 0x11, 0x70, + 0xE4, 0xB2, 0xAC, 0x42, 0xEE, 0xD3, 0x26, 0xB1, 0x23, 0xE0, 0x0A, 0x26, + 0x21, 0xE0, 0x03, 0x26, 0x1F, 0xE0, 0x00, 0x24, 0x4F, 0xF0, 0x03, 0x09, + 0x11, 0xE0, 0x18, 0xF8, 0x04, 0x70, 0x38, 0x46, 0x00, 0xF0, 0x98, 0xF8, + 0x48, 0xB1, 0xC1, 0x78, 0x02, 0x29, 0x06, 0xD1, 0x80, 0xF8, 0x03, 0x90, + 0x49, 0x46, 0x00, 0x22, 0x38, 0x46, 0x00, 0xF0, 0x59, 0xFC, 0x64, 0x1C, + 0xE4, 0xB2, 0xAC, 0x42, 0xEB, 0xD3, 0x01, 0x21, 0x8A, 0xF8, 0x03, 0x10, + 0x6A, 0x46, 0x29, 0x46, 0x00, 0x20, 0xF2, 0xF7, 0x27, 0xFA, 0x30, 0x46, + 0xB9, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, + 0x86, 0xB0, 0x88, 0x46, 0x05, 0x00, 0x4F, 0xF0, 0x00, 0x06, 0x01, 0xD0, + 0x04, 0x2D, 0x03, 0xD9, 0x03, 0x20, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, + 0xDF, 0xF8, 0x88, 0xA0, 0x9A, 0xF8, 0x03, 0x00, 0x08, 0xB1, 0x01, 0x20, + 0xF5, 0xE7, 0x00, 0x24, 0xE9, 0x46, 0x15, 0xE0, 0x18, 0xF8, 0x04, 0x70, + 0x38, 0x46, 0x00, 0xF0, 0x5F, 0xF8, 0x98, 0xB1, 0x81, 0x78, 0xC9, 0x07, + 0x12, 0xD0, 0x04, 0xEB, 0x44, 0x01, 0x64, 0x1C, 0x09, 0xF8, 0x11, 0x70, + 0x09, 0xEB, 0x41, 0x01, 0x03, 0x8F, 0x4B, 0x80, 0x90, 0xF8, 0x36, 0x00, + 0x08, 0x71, 0xE4, 0xB2, 0xAC, 0x42, 0xE7, 0xD3, 0x26, 0xB1, 0x1F, 0xE0, + 0x0A, 0x26, 0x1D, 0xE0, 0x03, 0x26, 0x1B, 0xE0, 0x00, 0x24, 0x01, 0x27, + 0x0F, 0xE0, 0x18, 0xF8, 0x04, 0x00, 0x81, 0x46, 0x00, 0xF0, 0x3E, 0xF8, + 0x38, 0xB1, 0xC1, 0x78, 0x29, 0xB9, 0xC7, 0x70, 0x39, 0x46, 0x00, 0x22, + 0x48, 0x46, 0x00, 0xF0, 0x01, 0xFC, 0x64, 0x1C, 0xE4, 0xB2, 0xAC, 0x42, + 0xED, 0xD3, 0x8A, 0xF8, 0x03, 0x70, 0x6A, 0x46, 0x29, 0x46, 0x01, 0x20, + 0xF2, 0xF7, 0xD0, 0xF9, 0x30, 0x46, 0xB6, 0xE7, 0xF8, 0x79, 0x20, 0x00, + 0x70, 0xB5, 0x0F, 0x49, 0x03, 0x46, 0x8C, 0x68, 0x14, 0xB1, 0x00, 0x20, + 0x4A, 0x78, 0x0E, 0xE0, 0x00, 0x20, 0x70, 0xBD, 0xC0, 0xEB, 0x00, 0x11, + 0x04, 0xEB, 0x81, 0x01, 0x0D, 0x78, 0x25, 0xB1, 0x4D, 0x8F, 0x9D, 0x42, + 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0x90, 0x42, + 0xF0, 0xD3, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE6, 0xF7, 0x63, 0xD8, + 0xE8, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0xD8, 0x8A, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0F, 0x49, 0x03, 0x46, 0x8C, 0x68, + 0x14, 0xB1, 0x00, 0x20, 0x4A, 0x78, 0x0E, 0xE0, 0x00, 0x20, 0x70, 0xBD, + 0xC0, 0xEB, 0x00, 0x11, 0x04, 0xEB, 0x81, 0x01, 0x0D, 0x78, 0x25, 0xB1, + 0x4D, 0x78, 0x9D, 0x42, 0x01, 0xD1, 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, + 0xC0, 0xB2, 0x90, 0x42, 0xF0, 0xD3, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, + 0xE6, 0xF7, 0x3D, 0xD8, 0xE8, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, + 0x9C, 0x8A, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, + 0x02, 0x46, 0x69, 0x46, 0x40, 0xF2, 0x7B, 0x20, 0x00, 0xF0, 0x3C, 0xFF, + 0x30, 0xB9, 0xBD, 0xF8, 0x00, 0x00, 0xFF, 0xF7, 0xA7, 0xFF, 0x08, 0xB1, + 0xC1, 0x78, 0x39, 0xB1, 0x23, 0x46, 0x01, 0x22, 0x03, 0x49, 0x04, 0x48, + 0xE6, 0xF7, 0x1F, 0xD8, 0xFF, 0x20, 0x38, 0xBD, 0x40, 0x78, 0x38, 0xBD, + 0x58, 0x8B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, + 0xFF, 0xF7, 0xB8, 0xFF, 0x40, 0xB1, 0xC1, 0x78, 0x31, 0xB9, 0x40, 0x8F, + 0x20, 0xB1, 0x01, 0xF0, 0x01, 0xFD, 0x08, 0xB1, 0xC0, 0x78, 0x10, 0xBD, + 0x23, 0x46, 0x01, 0x22, 0x02, 0x49, 0x03, 0x48, 0xE6, 0xF7, 0x03, 0xD8, + 0xFF, 0x20, 0x10, 0xBD, 0x18, 0x8B, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x10, 0xB5, 0x00, 0x24, 0x0B, 0x4A, 0xB0, 0xF5, 0x4C, 0x7F, 0x0C, 0xD0, + 0xA0, 0xF5, 0x40, 0x73, 0x31, 0x3B, 0x0B, 0xD0, 0x03, 0x46, 0x03, 0x24, + 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE5, 0xF7, 0xEC, 0xDF, 0x20, 0x46, + 0x10, 0xBD, 0x90, 0x88, 0x08, 0x80, 0xFA, 0xE7, 0x10, 0x78, 0x08, 0x70, + 0xF7, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x08, 0x8A, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x25, 0x49, 0x10, 0xB5, 0x89, 0x68, 0x01, 0x24, + 0x89, 0xB1, 0x41, 0x88, 0xB1, 0xF5, 0xC5, 0x7F, 0x2B, 0xD0, 0x0E, 0xDC, + 0xB1, 0xF5, 0xC1, 0x7F, 0x33, 0xD0, 0xB1, 0xF5, 0xC2, 0x7F, 0x1C, 0xD0, + 0xB1, 0xF5, 0xC3, 0x7F, 0x11, 0xD0, 0xB1, 0xF5, 0xC4, 0x7F, 0x31, 0xD1, + 0x11, 0xE0, 0x00, 0x20, 0x10, 0xBD, 0xB1, 0xF5, 0xCF, 0x7F, 0x14, 0xD0, + 0xA1, 0xF5, 0x80, 0x71, 0xB1, 0x39, 0x18, 0xD0, 0x01, 0x29, 0x1A, 0xD0, + 0x04, 0x29, 0x23, 0xD1, 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xEA, 0xF8, + 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x70, 0xF8, 0x1B, 0xE0, 0x00, 0x1D, + 0x00, 0xF0, 0x52, 0xF9, 0x17, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xF8, 0xF8, + 0x13, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x7E, 0xF8, 0x0F, 0xE0, 0x00, 0x1D, + 0x00, 0xF0, 0x34, 0xF8, 0x0B, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x36, 0xF9, + 0x07, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x0A, 0xF8, 0x02, 0xE0, 0x00, 0x1D, + 0x00, 0xF0, 0x48, 0xF8, 0x00, 0x24, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00, + 0xF8, 0x79, 0x20, 0x00, 0x0F, 0x4A, 0x30, 0xB4, 0x94, 0x68, 0x00, 0x21, + 0x52, 0x78, 0x15, 0xE0, 0xC1, 0xEB, 0x01, 0x13, 0x04, 0xEB, 0x83, 0x03, + 0x1D, 0x78, 0x6D, 0xB1, 0xDD, 0x78, 0x02, 0x2D, 0x0A, 0xD1, 0x9D, 0x79, + 0x2D, 0x07, 0x07, 0xD5, 0x00, 0x21, 0xD9, 0x70, 0x59, 0x87, 0x02, 0x88, + 0x58, 0x78, 0x30, 0xBC, 0x00, 0xF0, 0xE6, 0xBA, 0x49, 0x1C, 0xC9, 0xB2, + 0x91, 0x42, 0xE7, 0xD3, 0x30, 0xBC, 0x70, 0x47, 0xF8, 0x79, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x80, 0x78, 0xFF, 0xF7, 0x0D, 0xFF, 0x58, 0xB1, + 0x00, 0x21, 0xC1, 0x70, 0x23, 0x88, 0x7B, 0xB1, 0x0A, 0x46, 0x42, 0x87, + 0x22, 0x88, 0x40, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0xCC, 0xBA, + 0xA3, 0x78, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x22, 0x02, 0x49, 0x03, 0x48, + 0xE5, 0xF7, 0x53, 0x9F, 0xA2, 0x88, 0xEE, 0xE7, 0x50, 0x8C, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x01, 0x88, 0x00, 0x29, 0x04, 0xD1, 0x03, 0x49, + 0x42, 0x88, 0x8A, 0x80, 0x00, 0x79, 0x08, 0x70, 0x70, 0x47, 0x00, 0x00, + 0xF8, 0x79, 0x20, 0x00, 0x01, 0x78, 0x31, 0xB1, 0x04, 0x22, 0x0A, 0x4B, + 0x40, 0x88, 0xD9, 0x68, 0x18, 0xB1, 0x49, 0x78, 0x0B, 0xE0, 0x02, 0x22, + 0xF7, 0xE7, 0x88, 0x78, 0x10, 0x43, 0x88, 0x70, 0x98, 0x78, 0x08, 0xB1, + 0x00, 0xF0, 0xB0, 0xB9, 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0, + 0x43, 0xB9, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, + 0x04, 0x46, 0x00, 0x78, 0x4F, 0xF0, 0x00, 0x09, 0x28, 0x4E, 0x02, 0x27, + 0x4D, 0x46, 0xB0, 0xB1, 0xB8, 0x46, 0x4F, 0x46, 0x2C, 0xE0, 0xB1, 0x68, + 0xC5, 0xEB, 0x05, 0x10, 0x01, 0xEB, 0x80, 0x00, 0x01, 0x78, 0x51, 0xB1, + 0xC1, 0x78, 0x03, 0x29, 0x07, 0xD1, 0x61, 0x88, 0x29, 0xB1, 0xC7, 0x70, + 0x39, 0x46, 0x62, 0x88, 0x40, 0x78, 0x00, 0xF0, 0x79, 0xFA, 0x6D, 0x1C, + 0xED, 0xB2, 0x70, 0x78, 0x85, 0x42, 0xE8, 0xD3, 0x17, 0xE0, 0xB1, 0x68, + 0xC5, 0xEB, 0x05, 0x10, 0x01, 0xEB, 0x80, 0x00, 0x01, 0x78, 0x59, 0xB1, + 0xC1, 0x78, 0x01, 0x29, 0x08, 0xD1, 0x61, 0x88, 0xD9, 0xB1, 0xC7, 0x70, + 0x47, 0x87, 0xC1, 0x78, 0x62, 0x88, 0x40, 0x78, 0x00, 0xF0, 0x60, 0xFA, + 0x6D, 0x1C, 0xED, 0xB2, 0x70, 0x78, 0x85, 0x42, 0xE7, 0xD3, 0x0E, 0x48, + 0x86, 0xF8, 0x03, 0x90, 0x21, 0x78, 0x02, 0x68, 0x61, 0xB1, 0x00, 0x2A, + 0x05, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, 0x63, 0x20, + 0x90, 0x47, 0xBD, 0xE8, 0xF8, 0x83, 0x80, 0xF8, 0x03, 0x80, 0xE2, 0xE7, + 0x00, 0x2A, 0xF8, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x69, 0x46, + 0x64, 0x20, 0xF1, 0xE7, 0xF8, 0x79, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00, + 0x0B, 0x4B, 0x02, 0x46, 0x40, 0x88, 0xD9, 0x68, 0x10, 0xB1, 0x49, 0x78, + 0x01, 0x22, 0x0C, 0xE0, 0x88, 0x78, 0x40, 0xF0, 0x01, 0x00, 0x88, 0x70, + 0x10, 0x78, 0x08, 0x71, 0x98, 0x78, 0x08, 0xB1, 0x00, 0xF0, 0x3A, 0xB9, + 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0, 0xCD, 0xB8, 0x00, 0x00, + 0xF8, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, 0x1E, 0x4F, 0x04, 0x46, + 0x01, 0x78, 0x3D, 0x78, 0x40, 0x88, 0x1D, 0x4E, 0x02, 0x29, 0x01, 0xD0, + 0xF8, 0xB1, 0x26, 0xE0, 0xFF, 0x21, 0x39, 0x70, 0x28, 0xB9, 0x28, 0x46, + 0xFF, 0xF7, 0x44, 0xFE, 0x70, 0xB1, 0x00, 0xF0, 0x7F, 0xF8, 0x32, 0x68, + 0x00, 0x2A, 0x25, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, + 0x02, 0x50, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9, 0x61, 0x20, 0x1A, 0xE0, + 0x3B, 0x78, 0x02, 0xB0, 0x01, 0x22, 0xBD, 0xE8, 0xF0, 0x41, 0x0E, 0x49, + 0x0E, 0x48, 0xE5, 0xF7, 0x86, 0x9E, 0x0E, 0x4A, 0x50, 0x78, 0xC0, 0xEB, + 0x00, 0x10, 0x81, 0x00, 0x90, 0x68, 0x18, 0xF4, 0x33, 0xF0, 0x32, 0x68, + 0x00, 0x2A, 0x07, 0xD0, 0x60, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0x01, 0xA8, + 0x00, 0x90, 0x69, 0x46, 0x62, 0x20, 0x90, 0x47, 0xBD, 0xE8, 0xFC, 0x81, + 0xBC, 0x74, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00, 0x0C, 0x8C, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0xF8, 0x79, 0x20, 0x00, 0x04, 0x49, 0x08, 0xB5, + 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90, 0x69, 0x46, 0x65, 0x20, + 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x09, 0x4A, 0x00, 0x88, + 0xD1, 0x68, 0x10, 0xB1, 0x49, 0x78, 0x08, 0x22, 0x0A, 0xE0, 0x88, 0x78, + 0x40, 0xF0, 0x08, 0x00, 0x88, 0x70, 0x90, 0x78, 0x08, 0xB1, 0x00, 0xF0, + 0xCD, 0xB8, 0x00, 0x22, 0x49, 0x78, 0x10, 0x46, 0x00, 0xF0, 0x60, 0xB8, + 0xF8, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x0F, 0x4D, 0x04, 0x46, 0xA8, 0x68, + 0x08, 0xB1, 0x00, 0x20, 0x70, 0xBD, 0x0C, 0xB1, 0x0A, 0x2C, 0x07, 0xD9, + 0x23, 0x46, 0x01, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xE5, 0xF7, 0x35, 0xDE, + 0x03, 0x20, 0x70, 0xBD, 0xC4, 0xEB, 0x04, 0x10, 0x81, 0x00, 0x88, 0x23, + 0x07, 0x4A, 0x00, 0x20, 0xF0, 0xF7, 0xC0, 0xDB, 0xA8, 0x60, 0x08, 0xB1, + 0x6C, 0x70, 0xE6, 0xE7, 0x08, 0x20, 0x70, 0xBD, 0xF8, 0x79, 0x20, 0x00, + 0xDC, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0xC0, 0xB5, 0x82, 0x00, + 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0x63, 0x78, 0x01, 0x22, 0x05, 0x49, + 0x05, 0x48, 0xE5, 0xF7, 0x14, 0xDE, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, + 0x3C, 0x21, 0x17, 0xF4, 0xC3, 0xB7, 0x10, 0xBD, 0x74, 0x8A, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46, 0xFF, 0xF7, 0xAA, 0xFD, + 0x10, 0xB1, 0xC1, 0x78, 0x61, 0xB9, 0x01, 0xE0, 0x0A, 0x20, 0x70, 0xBD, + 0x09, 0x4D, 0x29, 0x78, 0xFF, 0x29, 0x01, 0xD0, 0x01, 0x20, 0x70, 0xBD, + 0x07, 0x49, 0xC9, 0x68, 0x81, 0x42, 0x01, 0xD1, 0x02, 0x20, 0x70, 0xBD, + 0x21, 0x46, 0x02, 0x20, 0xF2, 0xF7, 0x1C, 0xF9, 0x2C, 0x70, 0x00, 0x20, + 0x70, 0xBD, 0x00, 0x00, 0xBC, 0x74, 0x20, 0x00, 0xF8, 0x79, 0x20, 0x00, + 0x1C, 0xB5, 0x0A, 0x4B, 0x00, 0x24, 0xDC, 0x60, 0x9C, 0x70, 0x09, 0x4B, + 0x1B, 0x68, 0x00, 0x2B, 0x0A, 0xD0, 0xAD, 0xF8, 0x00, 0x00, 0x8D, 0xF8, + 0x02, 0x10, 0x8D, 0xF8, 0x03, 0x20, 0xCD, 0xF8, 0x04, 0xD0, 0x01, 0xA9, + 0x60, 0x20, 0x98, 0x47, 0x1C, 0xBD, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x0C, 0x46, 0xFF, 0xF7, + 0x6D, 0xFD, 0x20, 0xB1, 0xB4, 0xF5, 0x80, 0x6F, 0x03, 0xD9, 0x03, 0x20, + 0x70, 0xBD, 0x0A, 0x20, 0x70, 0xBD, 0x45, 0x62, 0x04, 0x84, 0x00, 0x20, + 0x70, 0xBD, 0x70, 0xB5, 0x14, 0x46, 0x0D, 0x46, 0xFF, 0xF7, 0x5C, 0xFD, + 0x20, 0xB1, 0x05, 0x87, 0x80, 0xF8, 0x36, 0x40, 0x00, 0x20, 0x70, 0xBD, + 0x0A, 0x20, 0x70, 0xBD, 0x2D, 0xE9, 0xF0, 0x5F, 0x1D, 0x46, 0xDD, 0xE9, + 0x0C, 0xB4, 0xDD, 0xE9, 0x0F, 0x98, 0x16, 0x46, 0x0F, 0x46, 0xDD, 0xF8, + 0x4C, 0xA0, 0xFF, 0xF7, 0x47, 0xFD, 0xF8, 0xB1, 0xC7, 0x80, 0xC0, 0xE9, + 0x02, 0x65, 0x0A, 0x99, 0x01, 0x74, 0x0B, 0x99, 0x41, 0x74, 0x80, 0xF8, + 0x12, 0xB0, 0x0E, 0x99, 0x41, 0x76, 0x80, 0xF8, 0x1A, 0x90, 0x80, 0xF8, + 0x1B, 0x80, 0x12, 0x99, 0x41, 0x77, 0x11, 0x99, 0x01, 0x77, 0x80, 0xF8, + 0x1E, 0xA0, 0x14, 0x99, 0xC1, 0x77, 0x24, 0xB1, 0x21, 0x68, 0x40, 0xF8, + 0x13, 0x1F, 0xA1, 0x88, 0x81, 0x80, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x9F, + 0x0A, 0x20, 0xFB, 0xE7, 0x70, 0xB5, 0x4D, 0x4C, 0x8C, 0xB0, 0x02, 0x22, + 0xA0, 0x78, 0x00, 0x90, 0xE0, 0x68, 0x4B, 0x49, 0x43, 0x78, 0x4B, 0x48, + 0xE5, 0xF7, 0x73, 0xDD, 0xA0, 0x78, 0xC1, 0x07, 0x1E, 0xD0, 0xE0, 0x68, + 0x07, 0xAE, 0x01, 0x7F, 0xC5, 0x7F, 0x83, 0x7F, 0x42, 0x7F, 0x86, 0xE8, + 0x2E, 0x00, 0x03, 0xAE, 0xC5, 0x7E, 0x83, 0x7E, 0x42, 0x7E, 0x00, 0xF1, + 0x13, 0x01, 0x86, 0xE8, 0x2E, 0x00, 0x01, 0x7C, 0x83, 0x7C, 0x42, 0x7C, + 0x8D, 0xE8, 0x0E, 0x00, 0xD0, 0xE9, 0x02, 0x23, 0xC1, 0x88, 0x40, 0x78, + 0xF1, 0xF7, 0xCE, 0xFE, 0xA0, 0x78, 0x20, 0xF0, 0x01, 0x00, 0x6A, 0xE0, + 0x41, 0x07, 0x4F, 0xF0, 0x00, 0x05, 0x2D, 0xD5, 0xE1, 0x68, 0x4B, 0x8D, + 0x4B, 0xB1, 0xC8, 0x6A, 0xC6, 0x18, 0x08, 0x8D, 0xC0, 0x1A, 0x80, 0xB2, + 0xC8, 0x28, 0x0C, 0xD9, 0xC8, 0x20, 0x00, 0x22, 0x0A, 0xE0, 0x08, 0x8D, + 0xCE, 0x6A, 0xC8, 0x28, 0x02, 0xD9, 0xC8, 0x20, 0x01, 0x22, 0x00, 0xE0, + 0x03, 0x22, 0x48, 0x85, 0x02, 0xE0, 0x02, 0x22, 0x03, 0x44, 0x4B, 0x85, + 0xC0, 0xB2, 0xCD, 0xE9, 0x00, 0x06, 0x01, 0x23, 0x49, 0x78, 0x18, 0x46, + 0xF1, 0xF7, 0x24, 0xFE, 0xE0, 0x68, 0x01, 0x8D, 0x42, 0x8D, 0x91, 0x42, + 0x04, 0xD1, 0xA1, 0x78, 0x21, 0xF0, 0x04, 0x01, 0xA1, 0x70, 0x45, 0x85, + 0x0C, 0xB0, 0x70, 0xBD, 0x81, 0x07, 0x2C, 0xD5, 0xE1, 0x68, 0x4B, 0x8C, + 0x4B, 0xB1, 0x48, 0x6A, 0xC6, 0x18, 0x08, 0x8C, 0xC0, 0x1A, 0x80, 0xB2, + 0xC8, 0x28, 0x0C, 0xD9, 0xC8, 0x20, 0x00, 0x22, 0x0A, 0xE0, 0x08, 0x8C, + 0x4E, 0x6A, 0xC8, 0x28, 0x02, 0xD9, 0xC8, 0x20, 0x01, 0x22, 0x00, 0xE0, + 0x03, 0x22, 0x48, 0x84, 0x02, 0xE0, 0x02, 0x22, 0x03, 0x44, 0x4B, 0x84, + 0xC0, 0xB2, 0xCD, 0xE9, 0x00, 0x06, 0x49, 0x78, 0x01, 0x23, 0x00, 0x20, + 0xF1, 0xF7, 0xF4, 0xFD, 0xE0, 0x68, 0x01, 0x8C, 0x42, 0x8C, 0x91, 0x42, + 0xD4, 0xD1, 0xA1, 0x78, 0x21, 0xF0, 0x02, 0x01, 0xA1, 0x70, 0x45, 0x84, + 0xCE, 0xE7, 0x00, 0x07, 0xCC, 0xD5, 0xE0, 0x68, 0x41, 0x78, 0x30, 0x30, + 0xF2, 0xF7, 0x5E, 0xFA, 0xA0, 0x78, 0x20, 0xF0, 0x08, 0x00, 0xA0, 0x70, + 0xC2, 0xE7, 0x00, 0x00, 0xF8, 0x79, 0x20, 0x00, 0xD4, 0x8B, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0x7E, 0xFC, + 0x28, 0xB1, 0x21, 0x68, 0x01, 0x63, 0xA1, 0x88, 0x81, 0x86, 0x00, 0x20, + 0x10, 0xBD, 0x0A, 0x20, 0x10, 0xBD, 0x70, 0xB5, 0x15, 0x46, 0x0C, 0x46, + 0xFF, 0xF7, 0x70, 0xFC, 0x20, 0xB1, 0xB4, 0xF5, 0x80, 0x6F, 0x03, 0xD9, + 0x03, 0x20, 0x70, 0xBD, 0x0A, 0x20, 0x70, 0xBD, 0xC5, 0x62, 0x04, 0x85, + 0x00, 0x20, 0x70, 0xBD, 0x10, 0xB5, 0x0C, 0x46, 0xFF, 0xF7, 0x60, 0xFC, + 0x08, 0xB1, 0x14, 0xB1, 0x12, 0xE0, 0x0A, 0x20, 0x10, 0xBD, 0xC1, 0x88, + 0x01, 0x24, 0xCA, 0x06, 0x07, 0xD5, 0x4A, 0x07, 0x00, 0xD4, 0x03, 0x24, + 0x89, 0x07, 0x07, 0xD5, 0x44, 0xF0, 0x04, 0x04, 0x04, 0xE0, 0x89, 0x07, + 0x01, 0xD5, 0x05, 0x24, 0x00, 0xE0, 0x03, 0x24, 0x09, 0x4A, 0xD1, 0x68, + 0x09, 0xB1, 0x01, 0x20, 0x10, 0xBD, 0xC1, 0x78, 0x31, 0xB1, 0x02, 0x29, + 0x02, 0xD1, 0x14, 0xF0, 0x09, 0x0F, 0x01, 0xD0, 0x02, 0x20, 0x10, 0xBD, + 0x94, 0x70, 0xD0, 0x60, 0xFF, 0xF7, 0x14, 0xFF, 0x00, 0x20, 0x10, 0xBD, + 0xF8, 0x79, 0x20, 0x00, 0x1C, 0xB5, 0x01, 0x23, 0x8D, 0xF8, 0x04, 0x00, + 0x8D, 0xF8, 0x00, 0x30, 0x8D, 0xF8, 0x05, 0x10, 0xAD, 0xF8, 0x02, 0x20, + 0x68, 0x46, 0xF5, 0xF7, 0x5D, 0xF8, 0x1C, 0xBD, 0x70, 0xB5, 0x00, 0x24, + 0xA0, 0xF5, 0x50, 0x73, 0x0F, 0x4A, 0x10, 0x4D, 0x06, 0x2B, 0x12, 0xD2, + 0xDF, 0xE8, 0x03, 0xF0, 0x03, 0x05, 0x08, 0x0A, 0x0C, 0x0E, 0x50, 0x78, + 0x00, 0xE0, 0x10, 0x78, 0x08, 0x70, 0x0F, 0xE0, 0x68, 0x78, 0xFB, 0xE7, + 0x28, 0x78, 0xF9, 0xE7, 0x50, 0x88, 0x00, 0xE0, 0x90, 0x88, 0x08, 0x80, + 0x06, 0xE0, 0x03, 0x46, 0x03, 0x24, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xE5, 0xF7, 0x5F, 0xDC, 0x20, 0x46, 0x70, 0xBD, 0x08, 0x7A, 0x20, 0x00, + 0xBE, 0x74, 0x20, 0x00, 0xCC, 0x8C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x41, 0x88, 0xB1, 0xF5, 0xC6, 0x7F, 0x0D, 0xD0, 0xB1, 0xF5, 0xC7, 0x7F, + 0x07, 0xD0, 0xB1, 0xF5, 0xD6, 0x7F, 0x0A, 0xD0, 0xB1, 0xF5, 0xD8, 0x7F, + 0x0A, 0xD1, 0x02, 0xF0, 0x71, 0xB8, 0x00, 0x1D, 0x02, 0xF0, 0x0A, 0xB8, + 0x00, 0x1D, 0x01, 0xF0, 0xE5, 0xBF, 0x00, 0x1D, 0x01, 0xF0, 0xCC, 0xBF, + 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x03, 0x46, 0x00, 0x24, + 0xA0, 0xF5, 0x50, 0x70, 0x01, 0x27, 0x1A, 0x4E, 0x1A, 0x4D, 0x06, 0x28, + 0x0B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x11, 0x17, 0x1E, 0x23, 0x28, + 0x01, 0x29, 0x04, 0xD1, 0x10, 0x78, 0x03, 0x28, 0x01, 0xD8, 0x70, 0x70, + 0x0A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x13, 0x49, 0x13, 0x48, 0xE5, 0xF7, + 0x1E, 0xDC, 0x1A, 0xE0, 0x01, 0x29, 0xF6, 0xD1, 0x10, 0x78, 0x30, 0x70, + 0xAF, 0x70, 0x14, 0xE0, 0x01, 0x29, 0xF0, 0xD1, 0x10, 0x78, 0x05, 0x28, + 0xED, 0xD8, 0x68, 0x70, 0xF6, 0xE7, 0x01, 0x29, 0xE9, 0xD1, 0x10, 0x78, + 0x28, 0x70, 0x08, 0xE0, 0x02, 0x29, 0xE4, 0xD1, 0x10, 0x88, 0x70, 0x80, + 0x03, 0xE0, 0x02, 0x29, 0xDF, 0xD1, 0x10, 0x88, 0xB0, 0x80, 0x20, 0x46, + 0xBD, 0xE8, 0xF0, 0x81, 0x08, 0x7A, 0x20, 0x00, 0xBE, 0x74, 0x20, 0x00, + 0x9C, 0x8C, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x06, 0x4A, 0x00, 0xEB, + 0x40, 0x00, 0x02, 0xEB, 0x40, 0x00, 0x0A, 0x68, 0x02, 0x60, 0x89, 0x88, + 0x81, 0x80, 0x02, 0x49, 0x01, 0x20, 0x09, 0x1F, 0x88, 0x70, 0x70, 0x47, + 0xC2, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x17, 0x4D, 0x02, 0x24, 0x28, 0x78, + 0x10, 0xF0, 0x30, 0x0F, 0x08, 0xD0, 0xC0, 0xF3, 0x01, 0x13, 0x01, 0x22, + 0x13, 0x49, 0x14, 0x48, 0xE5, 0xF7, 0xD9, 0xDB, 0x20, 0x46, 0x70, 0xBD, + 0x12, 0x48, 0x13, 0x4E, 0x81, 0x78, 0xA1, 0xB1, 0x42, 0x78, 0x03, 0x1D, + 0x04, 0x2A, 0x00, 0xD1, 0x9B, 0x1D, 0x31, 0x78, 0x70, 0x78, 0xF1, 0xF7, + 0x47, 0xFE, 0x00, 0x28, 0xEE, 0xD0, 0x28, 0x78, 0x00, 0x24, 0x20, 0xF0, + 0x30, 0x00, 0x10, 0x30, 0x28, 0x70, 0x20, 0x46, 0xF4, 0xF7, 0x48, 0xFF, + 0xE4, 0xE7, 0x01, 0x78, 0xB3, 0x88, 0x72, 0x88, 0x01, 0x20, 0xF1, 0xF7, + 0x66, 0xFE, 0xEC, 0xE7, 0x38, 0x78, 0x20, 0x00, 0xFC, 0x8C, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0xBE, 0x74, 0x20, 0x00, 0x08, 0x7A, 0x20, 0x00, + 0x70, 0xB5, 0x10, 0x4D, 0x02, 0x24, 0x28, 0x78, 0xC0, 0xF3, 0x01, 0x13, + 0x02, 0x2B, 0x06, 0xD0, 0x01, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0xE5, 0xF7, + 0xA0, 0xDB, 0x20, 0x46, 0x70, 0xBD, 0x0C, 0x48, 0x83, 0x88, 0x42, 0x88, + 0x0B, 0x48, 0x01, 0x78, 0x00, 0x20, 0xF1, 0xF7, 0x44, 0xFE, 0x00, 0x28, + 0xF3, 0xD0, 0x28, 0x78, 0x00, 0x24, 0x40, 0xF0, 0x30, 0x00, 0x28, 0x70, + 0x20, 0x46, 0xF4, 0xF7, 0x15, 0xFF, 0xEA, 0xE7, 0x38, 0x78, 0x20, 0x00, + 0x24, 0x8D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x08, 0x7A, 0x20, 0x00, + 0xBE, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x93, 0xB0, 0x0F, 0x46, + 0x04, 0x46, 0x01, 0x29, 0x61, 0xD1, 0x60, 0x79, 0xB1, 0xEB, 0x90, 0x1F, + 0x5D, 0xD1, 0x00, 0x26, 0xDF, 0xF8, 0xBC, 0x90, 0xDF, 0xF8, 0xBC, 0x80, + 0x53, 0xE0, 0xD8, 0xF8, 0x04, 0x00, 0x06, 0xEB, 0x46, 0x01, 0x00, 0xEB, + 0xC1, 0x05, 0x28, 0x78, 0x01, 0x28, 0x48, 0xD1, 0xA8, 0x78, 0x00, 0x07, + 0x45, 0xD5, 0x69, 0x78, 0x04, 0xA8, 0xF4, 0xF7, 0x53, 0xF8, 0x00, 0x20, + 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x03, 0x90, 0x60, 0x79, 0x8D, 0xF8, + 0x0D, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x0E, 0x00, 0xE0, 0x78, 0x8D, 0xF8, + 0x0F, 0x00, 0x00, 0x20, 0x04, 0xAA, 0x0E, 0xA9, 0xC0, 0xF1, 0x0F, 0x03, + 0xD3, 0x5C, 0x0B, 0x54, 0x40, 0x1C, 0xC0, 0xB2, 0x10, 0x28, 0xF7, 0xD3, + 0x0A, 0xAA, 0x68, 0x46, 0xE6, 0xF7, 0xB4, 0xDC, 0x9D, 0xF8, 0x35, 0x00, + 0xA1, 0x78, 0x88, 0x42, 0x18, 0xD1, 0x9D, 0xF8, 0x36, 0x00, 0x61, 0x78, + 0x88, 0x42, 0x13, 0xD1, 0x9D, 0xF8, 0x37, 0x00, 0x21, 0x78, 0x88, 0x42, + 0x0E, 0xD1, 0x6B, 0x78, 0x01, 0x22, 0x10, 0x49, 0x48, 0x46, 0xE5, 0xF7, + 0x2E, 0xDB, 0x20, 0x68, 0xA8, 0x60, 0xA0, 0x88, 0xA8, 0x81, 0xAF, 0x73, + 0x28, 0x46, 0x13, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0x09, 0x49, 0x6B, 0x78, + 0x01, 0x22, 0x2C, 0x31, 0x48, 0x46, 0xE5, 0xF7, 0x1E, 0xDB, 0x76, 0x1C, + 0xF6, 0xB2, 0x98, 0xF8, 0x00, 0x10, 0x8E, 0x42, 0xA7, 0xD3, 0x00, 0x20, + 0xED, 0xE7, 0x00, 0x00, 0x02, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00, + 0x38, 0x71, 0xC0, 0x08, 0x2D, 0xE9, 0xF8, 0x43, 0xDF, 0xF8, 0xF4, 0x80, + 0x3D, 0x4E, 0x81, 0x46, 0x0C, 0x46, 0x02, 0x29, 0x03, 0xD0, 0x03, 0x2C, + 0x01, 0xD0, 0x00, 0x25, 0x35, 0xE0, 0x8C, 0x1E, 0xE4, 0xB2, 0x00, 0x25, + 0x17, 0xE0, 0x71, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07, + 0x38, 0x78, 0x01, 0x28, 0x0D, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1, + 0x10, 0x00, 0x17, 0xF4, 0xB9, 0xF3, 0x30, 0xB9, 0xB8, 0x7D, 0xA0, 0x42, + 0x03, 0xD1, 0x2B, 0x46, 0x01, 0x22, 0x2E, 0x49, 0x3B, 0xE0, 0x6D, 0x1C, + 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xE4, 0xD3, 0x40, 0xE0, 0x71, 0x68, + 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07, 0x38, 0x78, 0x01, 0x28, + 0x0B, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1, 0x08, 0x00, 0x17, 0xF4, + 0x9D, 0xF3, 0x20, 0xB9, 0xB8, 0x7B, 0xA0, 0x42, 0x08, 0xD0, 0x20, 0x2C, + 0x06, 0xD0, 0x6D, 0x1C, 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xE6, 0xD3, + 0x00, 0x25, 0x22, 0xE0, 0x1C, 0x49, 0x01, 0x22, 0x2B, 0x46, 0x28, 0x31, + 0x15, 0xE0, 0x71, 0x68, 0x05, 0xEB, 0x45, 0x00, 0x01, 0xEB, 0xC0, 0x07, + 0x38, 0x78, 0x01, 0x28, 0x13, 0xD1, 0x06, 0x22, 0x49, 0x46, 0x07, 0xF1, + 0x10, 0x00, 0x17, 0xF4, 0x7D, 0xF3, 0x60, 0xB9, 0xB8, 0x7D, 0xA0, 0x42, + 0x09, 0xD1, 0x11, 0x49, 0x01, 0x22, 0x2B, 0x46, 0x44, 0x31, 0x40, 0x46, + 0xE5, 0xF7, 0xA9, 0xDA, 0x38, 0x46, 0xBD, 0xE8, 0xF8, 0x83, 0x6D, 0x1C, + 0xED, 0xB2, 0x30, 0x78, 0x85, 0x42, 0xDE, 0xD3, 0x49, 0x46, 0x0A, 0x48, + 0xE5, 0xF7, 0x6C, 0xDC, 0x03, 0x46, 0x07, 0x49, 0x04, 0x48, 0x02, 0x22, + 0x6C, 0x31, 0xC0, 0x1E, 0x00, 0x94, 0xE5, 0xF7, 0x94, 0xDA, 0x00, 0x20, + 0xE9, 0xE7, 0x00, 0x00, 0x03, 0x35, 0x10, 0x21, 0xBC, 0x78, 0x20, 0x00, + 0x4C, 0x6F, 0xC0, 0x08, 0x00, 0x00, 0x30, 0x21, 0x07, 0x4A, 0x01, 0x46, + 0x00, 0x20, 0x13, 0x78, 0x99, 0x42, 0x08, 0xD2, 0x52, 0x68, 0x01, 0xEB, + 0x41, 0x01, 0x12, 0xF8, 0x31, 0x30, 0x01, 0x2B, 0x01, 0xD1, 0x02, 0xEB, + 0xC1, 0x00, 0x70, 0x47, 0xBC, 0x78, 0x20, 0x00, 0x41, 0x88, 0x40, 0xF2, + 0x6F, 0x13, 0xA1, 0xF2, 0x6F, 0x12, 0x99, 0x42, 0x3A, 0xD0, 0x18, 0xDC, + 0x40, 0xF2, 0x3D, 0x13, 0xA1, 0xF2, 0x3D, 0x12, 0x99, 0x42, 0x3C, 0xD0, + 0x08, 0xDC, 0x05, 0x29, 0x24, 0xD0, 0x0C, 0x29, 0x28, 0xD0, 0x0E, 0x29, + 0x42, 0xD1, 0x00, 0x1D, 0xF4, 0xF7, 0xB4, 0xBB, 0x20, 0x2A, 0x3A, 0xD0, + 0x22, 0x2A, 0x22, 0xD0, 0x2C, 0x2A, 0x39, 0xD1, 0x00, 0x1D, 0xF4, 0xF7, + 0x39, 0xBC, 0x1C, 0x49, 0x0F, 0x2A, 0x09, 0x78, 0x28, 0xD0, 0x06, 0xDC, + 0x02, 0x2A, 0x1C, 0xD0, 0x03, 0x2A, 0x1D, 0xD0, 0x0D, 0x2A, 0x2B, 0xD1, + 0x23, 0xE0, 0x21, 0x2A, 0x21, 0xD0, 0x44, 0x2A, 0x07, 0xD0, 0x46, 0x2A, + 0x24, 0xD1, 0x00, 0x1D, 0xF4, 0xF7, 0xCC, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, + 0x6D, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, 0xFC, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, + 0xFD, 0xBB, 0x00, 0x1D, 0xF4, 0xF7, 0x1C, 0xBB, 0x00, 0x1D, 0xF4, 0xF7, + 0x5B, 0xBC, 0x00, 0x1D, 0xF4, 0xF7, 0x44, 0xBB, 0x00, 0x1D, 0xF4, 0xF7, + 0x73, 0xBA, 0x00, 0x1D, 0xF4, 0xF7, 0x04, 0xBB, 0x00, 0x1D, 0xF4, 0xF7, + 0x91, 0xBA, 0xC8, 0x07, 0x04, 0xD1, 0xF4, 0xF7, 0x87, 0xBC, 0x00, 0x1D, + 0xF4, 0xF7, 0x4E, 0xBB, 0x70, 0x47, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, + 0x38, 0xB5, 0x04, 0x46, 0xEE, 0xF7, 0xDA, 0xF8, 0x01, 0x00, 0x16, 0x48, + 0x09, 0xD0, 0x16, 0x4B, 0xB3, 0xF8, 0x78, 0x11, 0xCA, 0x05, 0x10, 0xD5, + 0x14, 0x4A, 0x95, 0x78, 0x08, 0x2D, 0x05, 0xD0, 0x0B, 0xE0, 0x00, 0x22, + 0x12, 0x49, 0xE5, 0xF7, 0x06, 0xDA, 0x11, 0xE0, 0x15, 0x89, 0xC1, 0xF3, + 0x42, 0x21, 0x45, 0xF4, 0x80, 0x75, 0x15, 0x81, 0x91, 0x70, 0x93, 0xF8, + 0x98, 0x11, 0xA1, 0x42, 0x08, 0xD2, 0x00, 0x91, 0x0A, 0x49, 0x23, 0x46, + 0x02, 0x22, 0x28, 0x31, 0xE5, 0xF7, 0xF3, 0xD9, 0x00, 0x20, 0x38, 0xBD, + 0x20, 0x46, 0x01, 0xF0, 0xA1, 0xF9, 0xFE, 0xF7, 0x39, 0xFA, 0x01, 0x20, + 0x38, 0xBD, 0x00, 0x00, 0x00, 0x35, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, + 0x50, 0x74, 0x20, 0x00, 0x80, 0x5D, 0xC0, 0x08, 0x01, 0x49, 0xC8, 0x70, + 0x70, 0x47, 0x00, 0x00, 0x50, 0x74, 0x20, 0x00, 0x01, 0x4A, 0xC2, 0xE9, + 0x00, 0x01, 0x70, 0x47, 0x68, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x87, 0xB0, 0x2C, 0x4E, 0xDD, 0xE9, 0x11, 0x87, 0x1D, 0x46, 0x91, 0x46, + 0x8A, 0x46, 0x83, 0x46, 0x10, 0x2B, 0x06, 0xD8, 0x28, 0x49, 0x38, 0x78, + 0x91, 0xF8, 0xC1, 0x11, 0xB0, 0xEB, 0x81, 0x0F, 0x02, 0xD9, 0x00, 0x22, + 0x25, 0x49, 0x3F, 0xE0, 0x51, 0x46, 0x58, 0x46, 0xFF, 0xF7, 0xAC, 0xFE, + 0x04, 0x00, 0x12, 0xD1, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0xFD, 0xF7, + 0xC9, 0xFD, 0x04, 0x00, 0x0B, 0xD1, 0x00, 0xF0, 0x37, 0xFA, 0x60, 0xB3, + 0xFE, 0xF7, 0x06, 0xFF, 0x4A, 0x46, 0x51, 0x46, 0x58, 0x46, 0xFD, 0xF7, + 0xBD, 0xFD, 0x04, 0x00, 0x23, 0xD0, 0x1C, 0x21, 0x68, 0x46, 0x17, 0xF4, + 0x57, 0xF3, 0x8D, 0xF8, 0x1A, 0x50, 0x8D, 0xF8, 0x1B, 0x80, 0x2A, 0x46, + 0x68, 0x46, 0x10, 0x99, 0x17, 0xF4, 0xAD, 0xF2, 0x6B, 0x46, 0x1C, 0x22, + 0x11, 0x21, 0x20, 0x46, 0x01, 0xF0, 0x0A, 0xFC, 0x78, 0xB1, 0x39, 0x46, + 0x20, 0x46, 0x01, 0xF0, 0xF1, 0xFB, 0x50, 0xB1, 0x6B, 0x46, 0x1C, 0x22, + 0x12, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xFE, 0xFB, 0x18, 0xB1, 0x01, 0x20, + 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x06, 0x49, 0x00, 0x22, 0x30, 0x31, + 0x30, 0x46, 0xE5, 0xF7, 0x7C, 0xD9, 0x00, 0x20, 0xF4, 0xE7, 0x00, 0x00, + 0x00, 0x35, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0xD0, 0x72, 0xC0, 0x08, + 0x10, 0xB5, 0xF1, 0xF7, 0x32, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0x01, 0x20, 0x00, 0xF0, 0x81, 0xBE, 0x00, 0x00, + 0x01, 0x48, 0x00, 0x78, 0x70, 0x47, 0x00, 0x00, 0xCC, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0x0A, 0x46, 0x00, 0x28, 0x07, 0xD0, 0x81, 0x78, 0x49, 0x06, + 0x05, 0xD5, 0x41, 0x78, 0x10, 0x46, 0xF3, 0xF7, 0x63, 0xFD, 0x01, 0x20, + 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x30, 0xB5, 0x0D, 0x4C, + 0x63, 0x78, 0x5B, 0x1E, 0x98, 0x42, 0x12, 0xDC, 0x00, 0xEB, 0x40, 0x03, + 0x60, 0x68, 0x00, 0xEB, 0x03, 0x10, 0x05, 0x78, 0x5D, 0xB1, 0x80, 0x79, + 0x10, 0x70, 0x60, 0x68, 0x00, 0xEB, 0x03, 0x10, 0x50, 0xF8, 0x07, 0x2F, + 0x0A, 0x60, 0x80, 0x88, 0x88, 0x80, 0x01, 0x20, 0x30, 0xBD, 0x00, 0x20, + 0x30, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x14, 0x46, + 0x00, 0xF0, 0xEC, 0xFD, 0x18, 0xB1, 0xC0, 0x78, 0x20, 0x70, 0x01, 0x20, + 0x10, 0xBD, 0xFF, 0x20, 0x20, 0x70, 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, + 0x0C, 0x46, 0x00, 0xF0, 0x17, 0xFE, 0x18, 0xB1, 0xC0, 0x78, 0x20, 0x70, + 0x01, 0x20, 0x10, 0xBD, 0xFF, 0x20, 0x20, 0x70, 0x00, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0x12, 0x4B, 0x00, 0x22, 0x0A, 0x70, 0x5A, 0x78, 0x52, 0x1E, + 0x90, 0x42, 0x1B, 0xDC, 0x5A, 0x68, 0x00, 0xEB, 0x40, 0x00, 0x02, 0xEB, + 0x00, 0x12, 0x14, 0x78, 0xA4, 0xB1, 0x52, 0x78, 0x0A, 0x70, 0x5A, 0x68, + 0x02, 0xEB, 0x00, 0x12, 0x92, 0x78, 0x4A, 0x70, 0x5A, 0x68, 0x02, 0xEB, + 0x00, 0x10, 0x82, 0x79, 0x0A, 0x72, 0xD0, 0xF8, 0x07, 0x20, 0xC1, 0xF8, + 0x02, 0x20, 0xB0, 0xF8, 0x0B, 0x00, 0xC8, 0x80, 0x01, 0x20, 0x10, 0xBD, + 0x00, 0x20, 0x10, 0xBD, 0x60, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x0C, 0x46, 0x06, 0x46, 0x17, 0x46, 0x00, 0x25, 0x11, 0x46, 0x32, 0x48, + 0x00, 0xF0, 0x3E, 0xFD, 0x70, 0xB1, 0xA6, 0xF5, 0x1C, 0x72, 0x30, 0x49, + 0x07, 0xEB, 0x47, 0x00, 0x0C, 0x2A, 0x50, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, + 0x09, 0x12, 0x1C, 0x22, 0x27, 0x17, 0x2C, 0x32, 0x37, 0x41, 0x3C, 0x4A, + 0x04, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, + 0x50, 0xF8, 0x07, 0x1F, 0x21, 0x60, 0x80, 0x88, 0xA0, 0x80, 0x43, 0xE0, + 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x80, 0x79, 0x18, 0xE0, 0x49, 0x68, + 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8A, 0x03, 0xE0, 0x49, 0x68, 0x01, 0xEB, + 0x00, 0x10, 0x80, 0x8A, 0x20, 0x80, 0x33, 0xE0, 0x49, 0x68, 0x01, 0xEB, + 0x00, 0x10, 0xC0, 0x8A, 0xF8, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, + 0x00, 0x8B, 0xF3, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x79, + 0x20, 0x70, 0x23, 0xE0, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x80, 0x7B, + 0xF8, 0xE7, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x7B, 0xF3, 0xE7, + 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0xC0, 0x7B, 0xEE, 0xE7, 0x49, 0x68, + 0x01, 0xEB, 0x00, 0x10, 0x50, 0xF8, 0x1A, 0x1F, 0x21, 0x60, 0x40, 0x68, + 0x60, 0x60, 0x0B, 0xE0, 0x49, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x00, 0x8A, + 0xD0, 0xE7, 0x03, 0x25, 0x33, 0x46, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xE5, 0xF7, 0x87, 0xD8, 0x28, 0x46, 0xAE, 0xE7, 0x13, 0xB2, 0x82, 0x00, + 0x60, 0x78, 0x20, 0x00, 0x10, 0x60, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x2D, 0xE9, 0xF8, 0x4F, 0x0F, 0x46, 0x05, 0x00, 0x06, 0xD0, 0x28, 0x78, + 0x1C, 0x4B, 0x01, 0x28, 0x05, 0xD0, 0x00, 0x22, 0x1B, 0x49, 0x0B, 0xE0, + 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x1A, 0x48, 0x69, 0x78, 0x00, 0x78, + 0x40, 0x1E, 0x81, 0x42, 0x06, 0xDD, 0x16, 0x49, 0x00, 0x22, 0x28, 0x39, + 0x18, 0x46, 0xE5, 0xF7, 0x62, 0xD8, 0xEF, 0xE7, 0xDF, 0xF8, 0x50, 0x80, + 0x38, 0x46, 0xB8, 0xF8, 0x00, 0x10, 0x8E, 0x08, 0x17, 0xF4, 0xEC, 0xF1, + 0x00, 0x24, 0xDF, 0xF8, 0x44, 0x90, 0xDF, 0xF8, 0x44, 0xA0, 0x11, 0xE0, + 0x68, 0x78, 0x00, 0x90, 0xB9, 0xF8, 0x00, 0x10, 0xBA, 0xF8, 0x00, 0x00, + 0x04, 0x23, 0x08, 0x44, 0x00, 0xEB, 0x84, 0x00, 0x81, 0xB2, 0x07, 0xEB, + 0x84, 0x00, 0xB8, 0xF8, 0x00, 0x20, 0xFA, 0xF7, 0xFD, 0xFE, 0x64, 0x1C, + 0xB4, 0x42, 0xEB, 0xDB, 0x01, 0x20, 0xCC, 0xE7, 0x00, 0x35, 0x10, 0x21, + 0x5C, 0x74, 0xC0, 0x08, 0xBC, 0x78, 0x20, 0x00, 0xEE, 0x78, 0x20, 0x00, + 0xF0, 0x78, 0x20, 0x00, 0xE0, 0x78, 0x20, 0x00, 0x01, 0x48, 0x00, 0x88, + 0x70, 0x47, 0x00, 0x00, 0xEE, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x03, 0x46, + 0xA0, 0xF5, 0x08, 0x75, 0x00, 0x24, 0x1E, 0x48, 0x1E, 0x4A, 0x17, 0x2D, + 0x30, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x0C, 0x0E, 0x2F, 0x2F, 0x1D, 0x2F, + 0x15, 0x1A, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x22, 0x10, + 0x13, 0x27, 0x29, 0x2B, 0x2D, 0x00, 0x00, 0x78, 0x0C, 0xE0, 0x40, 0x89, + 0x00, 0xE0, 0x80, 0x89, 0x08, 0x80, 0x21, 0xE0, 0xC0, 0x89, 0xFB, 0xE7, + 0xD0, 0xF8, 0x1A, 0x20, 0x0A, 0x60, 0xC0, 0x8B, 0x05, 0xE0, 0x80, 0x78, + 0x08, 0x70, 0x17, 0xE0, 0x42, 0x69, 0x0A, 0x60, 0x00, 0x8B, 0x88, 0x80, + 0x12, 0xE0, 0x02, 0x6A, 0x0A, 0x60, 0x40, 0x6A, 0x48, 0x60, 0x0D, 0xE0, + 0x09, 0x48, 0xE2, 0xE7, 0x40, 0x79, 0xEF, 0xE7, 0x10, 0x78, 0xED, 0xE7, + 0x50, 0x78, 0xEB, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x05, 0x49, 0x06, 0x48, + 0xE4, 0xF7, 0xEB, 0xDF, 0x20, 0x46, 0x70, 0xBD, 0x38, 0x78, 0x20, 0x00, + 0x50, 0x74, 0x20, 0x00, 0x60, 0x78, 0x20, 0x00, 0x08, 0x5E, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x01, 0x20, 0xEC, 0xF7, 0x66, 0xFB, + 0x06, 0x49, 0x0A, 0x78, 0x90, 0x42, 0x07, 0xD2, 0x49, 0x68, 0x00, 0xEB, + 0x40, 0x00, 0x01, 0xEB, 0xC0, 0x00, 0x01, 0x78, 0x00, 0x29, 0x00, 0xD1, + 0x00, 0x20, 0x10, 0xBD, 0xBC, 0x78, 0x20, 0x00, 0x00, 0x20, 0x00, 0xF0, + 0xE1, 0xBC, 0x00, 0x00, 0xF0, 0xB5, 0x05, 0x46, 0x0E, 0x46, 0xA1, 0xF1, + 0x11, 0x00, 0x00, 0x24, 0x69, 0x78, 0x89, 0xB0, 0x17, 0x46, 0x06, 0x28, + 0x33, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x03, 0x0A, 0x32, 0x1C, 0x23, 0x2A, + 0xA8, 0x78, 0x80, 0x07, 0x2B, 0xD5, 0x68, 0x46, 0xF3, 0xF7, 0x26, 0xFC, + 0x05, 0xE0, 0xA8, 0x78, 0x40, 0x07, 0x24, 0xD5, 0x68, 0x46, 0xF3, 0xF7, + 0xC9, 0xFC, 0x00, 0xBB, 0x9D, 0xF8, 0x00, 0x20, 0x1C, 0x2A, 0x1C, 0xD8, + 0x38, 0x46, 0x01, 0xA9, 0x17, 0xF4, 0xB5, 0xF0, 0x9D, 0xF8, 0x00, 0x40, + 0x15, 0xE0, 0xA8, 0x78, 0x00, 0x07, 0x12, 0xD5, 0x38, 0x46, 0xF3, 0xF7, + 0x8B, 0xFC, 0x0C, 0xE0, 0xA8, 0x78, 0xC0, 0x06, 0x0B, 0xD5, 0x38, 0x46, + 0xF3, 0xF7, 0xDA, 0xFB, 0x05, 0xE0, 0xA8, 0x78, 0x80, 0x06, 0x04, 0xD5, + 0x38, 0x46, 0xF3, 0xF7, 0x51, 0xFC, 0x00, 0xB9, 0x18, 0x24, 0xCD, 0xE9, + 0x00, 0x64, 0x6B, 0x78, 0x03, 0x22, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7, + 0x80, 0xDF, 0x09, 0xB0, 0x20, 0x46, 0xF0, 0xBD, 0x34, 0x70, 0xC0, 0x08, + 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x01, 0x20, 0xEC, 0xF7, 0x2C, 0xFB, + 0x05, 0x49, 0x0A, 0x78, 0x90, 0x42, 0x05, 0xD2, 0x49, 0x68, 0x00, 0xEB, + 0x40, 0x00, 0x01, 0xEB, 0xC0, 0x00, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, + 0xBC, 0x78, 0x20, 0x00, 0x01, 0x48, 0x90, 0xF8, 0x98, 0x01, 0x70, 0x47, + 0x64, 0x01, 0x20, 0x00, 0x1C, 0xB5, 0x10, 0xB3, 0x02, 0x78, 0x01, 0x2A, + 0x1F, 0xD1, 0xC2, 0x7B, 0x4F, 0xF0, 0x00, 0x03, 0xD4, 0x06, 0x4F, 0xF0, + 0x01, 0x02, 0x01, 0xD5, 0x0A, 0x70, 0x00, 0xE0, 0x0B, 0x70, 0xC4, 0x7B, + 0xA4, 0x06, 0x01, 0xD5, 0x4A, 0x70, 0x00, 0xE0, 0x4B, 0x70, 0xC0, 0x7B, + 0x40, 0x06, 0x01, 0xD5, 0x8A, 0x70, 0x00, 0xE0, 0x8B, 0x70, 0x8A, 0x78, + 0x48, 0x78, 0xCD, 0xE9, 0x00, 0x02, 0x0B, 0x78, 0x03, 0x22, 0x03, 0x49, + 0x03, 0x48, 0xE4, 0xF7, 0x3C, 0xDF, 0x00, 0x20, 0x1C, 0xBD, 0x00, 0x00, + 0x78, 0x73, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x42, 0x88, + 0x04, 0x46, 0x01, 0x25, 0x40, 0xF2, 0x4D, 0x10, 0xA2, 0xF2, 0x4D, 0x11, + 0x82, 0x42, 0x7A, 0xD0, 0x56, 0xDC, 0x40, 0xF2, 0x1B, 0x11, 0xA2, 0xF2, + 0x1B, 0x10, 0x8A, 0x42, 0x74, 0xD0, 0x33, 0xDC, 0xB2, 0xF5, 0x80, 0x7F, + 0x11, 0xD0, 0x1E, 0xDC, 0x17, 0x2A, 0x0E, 0xD0, 0x0E, 0xDC, 0x0E, 0x2A, + 0x06, 0xD0, 0x06, 0xDC, 0x05, 0x2A, 0x03, 0xD0, 0x08, 0x2A, 0x06, 0xD0, + 0x0C, 0x2A, 0x7D, 0xD1, 0xA1, 0xE0, 0x12, 0x2A, 0x01, 0xD0, 0x15, 0x2A, + 0x78, 0xD1, 0xB9, 0xE0, 0x1E, 0x2A, 0x04, 0xD0, 0x04, 0xDC, 0x19, 0x2A, + 0x01, 0xD0, 0x1B, 0x2A, 0x70, 0xD1, 0xB1, 0xE0, 0x1F, 0x2A, 0x6E, 0xD0, + 0x24, 0x2A, 0x6B, 0xD1, 0xA4, 0xE0, 0xA2, 0xF2, 0x03, 0x12, 0x15, 0x2A, + 0x66, 0xD2, 0xDF, 0xE8, 0x02, 0xF0, 0xAF, 0xCF, 0xAF, 0xAF, 0xCF, 0xAF, + 0xCF, 0xAF, 0xCF, 0xAF, 0xCF, 0xAF, 0xCF, 0xAF, 0xAF, 0xCF, 0xB3, 0xB3, + 0xCF, 0xCF, 0xB3, 0x00, 0x80, 0x1E, 0x2E, 0x28, 0x56, 0xD2, 0xDF, 0xE8, + 0x00, 0xF0, 0xA3, 0xBF, 0xA3, 0xA3, 0xBF, 0xA3, 0xBF, 0x97, 0x97, 0xBF, + 0x8F, 0xBF, 0x8F, 0x8F, 0xBF, 0x9B, 0xBF, 0x93, 0x93, 0xBF, 0xBF, 0x85, + 0xBF, 0x85, 0xBF, 0x85, 0xBF, 0x8B, 0xBF, 0x8B, 0x8B, 0xBF, 0x7A, 0xBF, + 0x8F, 0x8F, 0xBF, 0x8F, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xB8, 0xB8, + 0x34, 0x29, 0x71, 0xD0, 0x30, 0xDC, 0x18, 0x29, 0x6D, 0xD0, 0x0F, 0xDC, + 0x17, 0x29, 0x35, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x9E, 0x97, 0x9E, 0x9E, + 0x97, 0x9E, 0x97, 0x97, 0x9E, 0x97, 0x97, 0x9E, 0x97, 0x9E, 0x97, 0x9E, + 0x59, 0x9E, 0x59, 0x9E, 0x9B, 0x9E, 0x9B, 0x00, 0x29, 0x29, 0x51, 0xD0, + 0x10, 0xDC, 0x24, 0x29, 0x47, 0xD0, 0x08, 0xDC, 0x1A, 0x29, 0x4F, 0xD0, + 0x1C, 0x29, 0x42, 0xD0, 0x22, 0x29, 0x1B, 0xD1, 0x3F, 0xE0, 0x7C, 0xE0, + 0x66, 0xE0, 0x25, 0x29, 0x3B, 0xD0, 0x27, 0x29, 0x7E, 0xD1, 0x3F, 0xE0, + 0x2B, 0x39, 0x09, 0x29, 0x7A, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x3B, 0x79, + 0x3B, 0x79, 0x38, 0x79, 0x34, 0x79, 0x3B, 0x00, 0x5E, 0x29, 0x41, 0xD0, + 0x1E, 0xDC, 0x41, 0x29, 0x57, 0xD0, 0x0E, 0xDC, 0xA1, 0xF1, 0x35, 0x01, + 0x0B, 0x29, 0x01, 0xE0, 0x26, 0xE0, 0x3F, 0xE0, 0x66, 0xD2, 0xDF, 0xE8, + 0x01, 0xF0, 0x56, 0x65, 0x52, 0x65, 0x52, 0x65, 0x52, 0x65, 0x52, 0x65, + 0x4E, 0x00, 0x47, 0x29, 0x59, 0xD0, 0x04, 0xDC, 0x43, 0x29, 0x14, 0xD0, + 0x45, 0x29, 0x57, 0xD1, 0x26, 0xE0, 0x49, 0x29, 0x51, 0xD0, 0x51, 0x29, + 0x52, 0xD1, 0x3E, 0xE0, 0x5F, 0x39, 0x10, 0x29, 0x4E, 0xD2, 0xDF, 0xE8, + 0x01, 0xF0, 0x36, 0x4D, 0x4D, 0x4D, 0x36, 0x3A, 0x3A, 0x0C, 0x4D, 0x42, + 0x1D, 0x2D, 0x25, 0x25, 0x4D, 0x25, 0x20, 0x46, 0xFF, 0xF7, 0xF6, 0xFB, + 0x40, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0xF2, 0xFB, 0x20, 0x46, 0x00, 0xF0, + 0xA5, 0xFE, 0x39, 0xE0, 0x20, 0x46, 0xFD, 0xF7, 0x9B, 0xF8, 0x35, 0xE0, + 0x00, 0xE0, 0x30, 0xE0, 0x20, 0x46, 0x01, 0xF0, 0xBB, 0xF9, 0x2F, 0xE0, + 0x20, 0x46, 0x00, 0xF0, 0x99, 0xFB, 0x2B, 0xE0, 0x20, 0x46, 0xF2, 0xF7, + 0x05, 0xFB, 0xF7, 0xE7, 0x20, 0x46, 0xFD, 0xF7, 0xB1, 0xFC, 0x23, 0xE0, + 0x20, 0x46, 0x00, 0xF0, 0x8D, 0xFB, 0xF7, 0xE7, 0x20, 0x46, 0x01, 0xF0, + 0x4F, 0xFF, 0x02, 0xE0, 0x20, 0x46, 0xF2, 0xF7, 0xF5, 0xFA, 0x05, 0x46, + 0x16, 0xE0, 0x20, 0x46, 0xFF, 0xF7, 0xEA, 0xF9, 0x12, 0xE0, 0x20, 0x46, + 0xFE, 0xF7, 0x5E, 0xFE, 0x0E, 0xE0, 0x20, 0x46, 0xFD, 0xF7, 0x70, 0xF8, + 0xF7, 0xE7, 0x20, 0x46, 0xFF, 0xF7, 0xBC, 0xFB, 0xF3, 0xE7, 0x20, 0x46, + 0x00, 0xF0, 0x06, 0xF8, 0x02, 0xE0, 0x20, 0x46, 0xFE, 0xF7, 0x56, 0xFC, + 0x28, 0x46, 0x70, 0xBD, 0x38, 0xB5, 0x1F, 0x4A, 0x43, 0x88, 0x01, 0x24, + 0x01, 0x1D, 0x52, 0x68, 0xA3, 0xF2, 0x49, 0x13, 0x13, 0x2B, 0x32, 0xD2, + 0xDF, 0xE8, 0x03, 0xF0, 0x0A, 0x0E, 0x31, 0x31, 0x12, 0x16, 0x31, 0x31, + 0x32, 0x31, 0x1E, 0x1A, 0x31, 0x22, 0x32, 0x31, 0x26, 0x31, 0x2B, 0x00, + 0x00, 0x1D, 0x00, 0xF0, 0x97, 0xF8, 0x23, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0x5B, 0xF8, 0x1F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x2B, 0xF9, 0x1B, 0xE0, + 0x00, 0x1D, 0x00, 0xF0, 0x05, 0xF9, 0x17, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0x9F, 0xF8, 0x13, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0xCF, 0xF8, 0x0F, 0xE0, + 0x00, 0x1D, 0x00, 0xF0, 0x11, 0xF8, 0x0B, 0xE0, 0x52, 0xB1, 0x00, 0x91, + 0x69, 0x46, 0x03, 0x20, 0x03, 0xE0, 0x2A, 0xB1, 0x00, 0x91, 0x69, 0x46, + 0x02, 0x20, 0x90, 0x47, 0x00, 0xE0, 0x00, 0x24, 0x20, 0x46, 0x38, 0xBD, + 0x70, 0x79, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x81, 0x88, 0x40, 0x88, + 0xFE, 0xF7, 0xBC, 0xF8, 0x68, 0xB1, 0x45, 0x78, 0x21, 0x88, 0x89, 0xB1, + 0x00, 0x26, 0xFE, 0xF7, 0xDD, 0xF8, 0x23, 0x88, 0xA1, 0x88, 0x32, 0x46, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0xFE, 0xF7, 0x8D, 0xB9, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xE4, 0xF7, 0xCB, 0x9D, + 0x21, 0x89, 0x41, 0x82, 0xE1, 0x88, 0x0A, 0x4A, 0x01, 0x82, 0xE1, 0x88, + 0x92, 0x88, 0x91, 0x42, 0x00, 0xD3, 0x11, 0x46, 0x01, 0x81, 0x61, 0x89, + 0x81, 0x82, 0x02, 0x21, 0x81, 0x70, 0x61, 0x89, 0x81, 0x81, 0x02, 0x26, + 0xDD, 0xE7, 0x00, 0x00, 0xB8, 0x88, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0xB6, 0x74, 0x20, 0x00, 0x7C, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x25, + 0x00, 0x88, 0xFE, 0xF7, 0x85, 0xF8, 0x20, 0xB1, 0x00, 0x22, 0x14, 0x49, + 0x14, 0x48, 0xE4, 0xF7, 0xA4, 0xDD, 0xFE, 0xF7, 0x3B, 0xF9, 0xF0, 0xB1, + 0x20, 0x88, 0x00, 0xF0, 0x93, 0xFA, 0x78, 0xB1, 0x61, 0x88, 0xC0, 0x78, + 0xFE, 0xF7, 0x00, 0xF8, 0x00, 0x28, 0x13, 0xD0, 0x01, 0x21, 0x81, 0x70, + 0x21, 0x88, 0x81, 0x80, 0x61, 0x88, 0x40, 0x78, 0x00, 0x23, 0x01, 0x22, + 0xFE, 0xF7, 0x48, 0xF9, 0x08, 0x4A, 0x10, 0x78, 0xCD, 0xE9, 0x00, 0x05, + 0x93, 0x78, 0x61, 0x88, 0x20, 0x88, 0x92, 0x88, 0xF0, 0xF7, 0x76, 0xFC, + 0x7C, 0xBD, 0x4F, 0xF4, 0x01, 0x75, 0xF1, 0xE7, 0x84, 0x88, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0xB6, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, + 0x00, 0x88, 0x00, 0x21, 0xFE, 0xF7, 0x4E, 0xF8, 0x00, 0x28, 0x0E, 0xD0, + 0xA1, 0x88, 0x51, 0xB1, 0x45, 0x78, 0xFE, 0xF7, 0x6F, 0xF8, 0xA3, 0x88, + 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x11, 0x46, 0xFE, 0xF7, + 0x1F, 0xB9, 0x61, 0x88, 0xC1, 0x80, 0x70, 0xBD, 0x1F, 0xB5, 0x04, 0x46, + 0x41, 0x88, 0x00, 0x88, 0xFE, 0xF7, 0x36, 0xF8, 0xE8, 0xB1, 0x13, 0x49, + 0x4A, 0x68, 0x92, 0xB1, 0x61, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x40, 0x78, + 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, 0xE1, 0x88, + 0x04, 0xF1, 0x08, 0x00, 0x08, 0x44, 0x02, 0x90, 0xCD, 0xF8, 0x0C, 0xD0, + 0x03, 0xA9, 0x05, 0x20, 0x90, 0x47, 0x61, 0x88, 0x20, 0x88, 0x04, 0xB0, + 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0xF0, 0xF7, 0x8B, 0xBC, 0x04, 0xB0, + 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7, + 0x34, 0x9D, 0x00, 0x00, 0x70, 0x79, 0x20, 0x00, 0x6C, 0x89, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x3E, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88, + 0xFE, 0xF7, 0x02, 0xF8, 0xC0, 0xB1, 0x81, 0x89, 0x49, 0x1C, 0x81, 0x81, + 0x0E, 0x49, 0x4A, 0x68, 0x00, 0x2A, 0x10, 0xD0, 0x61, 0x88, 0xAD, 0xF8, + 0x02, 0x10, 0x41, 0x78, 0x8D, 0xF8, 0x00, 0x10, 0xA1, 0x88, 0xAD, 0xF8, + 0x04, 0x10, 0x00, 0x7B, 0x8D, 0xF8, 0x06, 0x00, 0xCD, 0xF8, 0x08, 0xD0, + 0x02, 0xA9, 0x04, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x03, 0xB0, 0x00, 0x22, + 0xBD, 0xE8, 0x30, 0x40, 0x02, 0x49, 0x03, 0x48, 0xE4, 0xF7, 0x05, 0x9D, + 0x70, 0x79, 0x20, 0x00, 0xA4, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x70, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88, 0xFD, 0xF7, 0xD4, 0xFF, + 0x70, 0xB1, 0x45, 0x78, 0xFD, 0xF7, 0xF8, 0xFF, 0x61, 0x88, 0x20, 0x88, + 0xF0, 0xF7, 0x72, 0xFC, 0xA3, 0x88, 0x61, 0x88, 0x28, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0x22, 0xFE, 0xF7, 0xA4, 0xB8, 0xBD, 0xE8, 0x70, 0x40, + 0x00, 0x22, 0x02, 0x49, 0x02, 0x48, 0xE4, 0xF7, 0xE2, 0x9C, 0x00, 0x00, + 0x30, 0x89, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x04, 0x46, + 0x41, 0x88, 0x00, 0x88, 0xFD, 0xF7, 0xB2, 0xFF, 0x68, 0xB1, 0xA1, 0x88, + 0x00, 0x29, 0x11, 0xD1, 0x45, 0x78, 0xFD, 0xF7, 0xD3, 0xFF, 0xA3, 0x88, + 0x61, 0x88, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0xFE, 0xF7, + 0x83, 0xB8, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x02, 0x49, 0x03, 0x48, + 0xE4, 0xF7, 0xC1, 0x9C, 0x70, 0xBD, 0x00, 0x00, 0xF4, 0x88, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x30, 0xB5, 0xA7, 0xB0, 0x04, 0x00, 0x07, 0xD0, + 0x04, 0xF1, 0x08, 0x00, 0x61, 0x78, 0x05, 0x46, 0xF3, 0xF7, 0x52, 0xF9, + 0x18, 0xB1, 0x14, 0xE0, 0x00, 0x20, 0x27, 0xB0, 0x30, 0xBD, 0xE0, 0x7B, + 0xC1, 0x07, 0x0E, 0xD0, 0x01, 0x21, 0x21, 0x70, 0x62, 0x88, 0x83, 0x07, + 0x42, 0xF0, 0x01, 0x02, 0x62, 0x80, 0x02, 0xD5, 0x42, 0xF0, 0x80, 0x02, + 0x62, 0x80, 0x40, 0x07, 0x04, 0xD5, 0x21, 0x71, 0x02, 0xE0, 0x20, 0x78, + 0x01, 0x28, 0x5C, 0xD1, 0x61, 0x78, 0x0A, 0xA8, 0xF3, 0xF7, 0x08, 0xF9, + 0x30, 0xB9, 0x9D, 0xF8, 0x28, 0x00, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0, + 0x02, 0x00, 0x60, 0x80, 0x61, 0x78, 0x12, 0xA8, 0xF3, 0xF7, 0xA6, 0xF9, + 0x30, 0xB9, 0x9D, 0xF8, 0x48, 0x00, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0, + 0x04, 0x00, 0x60, 0x80, 0x61, 0x78, 0x04, 0xA8, 0xF3, 0xF7, 0x6E, 0xF9, + 0x70, 0xB9, 0x9D, 0xF8, 0x27, 0x00, 0x58, 0xB1, 0x08, 0x98, 0x20, 0x61, + 0xBD, 0xF8, 0x24, 0x00, 0xA0, 0x82, 0x9D, 0xF8, 0x26, 0x00, 0xA0, 0x75, + 0x60, 0x88, 0x40, 0xF0, 0x08, 0x00, 0x60, 0x80, 0x61, 0x78, 0x1A, 0xA8, + 0xF3, 0xF7, 0xB0, 0xF8, 0x30, 0xB9, 0x9D, 0xF8, 0x7D, 0x00, 0x18, 0xB1, + 0x60, 0x88, 0x40, 0xF0, 0x10, 0x00, 0x60, 0x80, 0x61, 0x78, 0x20, 0xA8, + 0xF3, 0xF7, 0x22, 0xF9, 0x30, 0xB9, 0x9D, 0xF8, 0x95, 0x00, 0x18, 0xB1, + 0x60, 0x88, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x80, 0x60, 0x78, 0xF3, 0xF7, + 0xD7, 0xF9, 0x18, 0xB1, 0x60, 0x88, 0x40, 0xF0, 0x40, 0x00, 0x60, 0x80, + 0x29, 0x46, 0x09, 0x48, 0xE4, 0xF7, 0x16, 0xDE, 0x22, 0x79, 0x61, 0x88, + 0xA3, 0x7B, 0xCD, 0xE9, 0x02, 0x12, 0xCD, 0xE9, 0x00, 0x03, 0x63, 0x78, + 0x05, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0x3A, 0xDC, 0x01, 0x20, + 0x89, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xF0, 0x6E, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x13, 0x48, 0x13, 0x4D, 0x7D, 0x23, + 0x90, 0xF8, 0xCB, 0x01, 0x28, 0x70, 0x00, 0xEB, 0x40, 0x00, 0xC1, 0x00, + 0x10, 0x4A, 0x00, 0x20, 0xEF, 0xF7, 0xB8, 0xD9, 0x68, 0x60, 0x00, 0x28, + 0x14, 0xD0, 0xF2, 0xF7, 0xC1, 0xFF, 0x29, 0x78, 0x01, 0x20, 0xEC, 0xF7, + 0xBF, 0xF8, 0x00, 0x24, 0x09, 0xE0, 0x69, 0x68, 0x04, 0xEB, 0x44, 0x00, + 0x01, 0xEB, 0xC0, 0x00, 0x44, 0x70, 0xFF, 0xF7, 0x55, 0xFF, 0x64, 0x1C, + 0xE4, 0xB2, 0x28, 0x78, 0x84, 0x42, 0xF2, 0xD3, 0x70, 0xBD, 0x00, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xBC, 0x78, 0x20, 0x00, 0xD2, 0xB3, 0x82, 0x00, + 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x01, 0x46, 0x26, 0x48, 0xE4, 0xF7, + 0xCB, 0xDD, 0x03, 0x46, 0x01, 0x22, 0x25, 0x49, 0x25, 0x48, 0xE4, 0xF7, + 0xF6, 0xDB, 0xDF, 0xF8, 0x90, 0x80, 0x00, 0x24, 0xA8, 0xF1, 0x03, 0x08, + 0x22, 0x4E, 0x0E, 0xE0, 0x71, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB, + 0x00, 0x17, 0x38, 0x78, 0x28, 0xB1, 0x06, 0x22, 0x29, 0x46, 0xF8, 0x1D, + 0x16, 0xF4, 0xAC, 0xF4, 0x38, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x71, 0x78, + 0x8C, 0x42, 0xED, 0xD3, 0x00, 0x20, 0x73, 0x68, 0x11, 0xE0, 0x15, 0x49, + 0xFB, 0x78, 0x01, 0x22, 0x20, 0x31, 0x40, 0x46, 0xE4, 0xF7, 0xD3, 0xDB, + 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0xEB, 0x40, 0x02, 0x03, 0xEB, + 0x02, 0x12, 0x14, 0x78, 0x5C, 0xB1, 0x40, 0x1C, 0xC0, 0xB2, 0x88, 0x42, + 0xF5, 0xD3, 0x0B, 0x49, 0x00, 0x22, 0x48, 0x31, 0x40, 0x46, 0xE4, 0xF7, + 0xC0, 0xDB, 0x00, 0x20, 0xEB, 0xE7, 0x29, 0x68, 0xC2, 0xF8, 0x07, 0x10, + 0xA9, 0x88, 0xA2, 0xF8, 0x0B, 0x10, 0x01, 0x21, 0x11, 0x70, 0xD0, 0x70, + 0x00, 0x20, 0x50, 0x70, 0x10, 0x46, 0xDE, 0xE7, 0x00, 0x00, 0x30, 0x21, + 0xC8, 0x5E, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x60, 0x78, 0x20, 0x00, + 0x7C, 0xB5, 0x0E, 0x46, 0x01, 0x46, 0x0E, 0x48, 0x01, 0x25, 0x05, 0x24, + 0x42, 0x78, 0x96, 0x42, 0x07, 0xD2, 0x40, 0x68, 0x06, 0xEB, 0x46, 0x02, + 0x00, 0xEB, 0x02, 0x10, 0x44, 0x78, 0x02, 0x2C, 0x0C, 0xD0, 0x00, 0x25, + 0x4F, 0xF0, 0x05, 0x50, 0xE4, 0xF7, 0xAD, 0xDD, 0xCD, 0xE9, 0x00, 0x64, + 0x03, 0x46, 0x03, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0x8B, 0xDB, + 0x28, 0x46, 0x7C, 0xBD, 0x60, 0x78, 0x20, 0x00, 0xDC, 0x5F, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0D, 0x46, 0x00, 0xF0, 0x74, 0xF8, + 0x04, 0x00, 0x28, 0xD0, 0x18, 0x48, 0x01, 0x22, 0x18, 0x49, 0x03, 0x78, + 0x18, 0x48, 0xE4, 0xF7, 0x76, 0xDB, 0x18, 0x49, 0x01, 0x22, 0x08, 0x78, + 0xB2, 0xEB, 0x90, 0x1F, 0x0A, 0xD1, 0x62, 0x78, 0x03, 0x2A, 0x07, 0xD1, + 0xA2, 0x78, 0x01, 0x2A, 0x04, 0xD1, 0x22, 0x8A, 0x12, 0xB9, 0x20, 0xF0, + 0xC0, 0x00, 0x08, 0x70, 0xE0, 0x78, 0x2A, 0x46, 0x00, 0x21, 0xF3, 0xF7, + 0xC5, 0xFE, 0x00, 0x20, 0xF3, 0xF7, 0xE6, 0xFE, 0xE0, 0x6A, 0x08, 0xB1, + 0xEF, 0xF7, 0x4D, 0xD9, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, + 0x43, 0xBB, 0x05, 0x49, 0xBD, 0xE8, 0x70, 0x40, 0x04, 0x48, 0x00, 0x22, + 0x2C, 0x31, 0xC0, 0x1E, 0xE4, 0xF7, 0x4B, 0x9B, 0x60, 0x78, 0x20, 0x00, + 0xE4, 0x61, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xF8, 0x43, 0x0E, 0x46, 0xB0, 0xF1, 0x00, 0x08, 0x25, 0xD0, + 0x00, 0x24, 0x14, 0x4F, 0x13, 0xE0, 0x79, 0x68, 0x04, 0xEB, 0x44, 0x00, + 0x01, 0xEB, 0x00, 0x15, 0x28, 0x78, 0x50, 0xB1, 0x06, 0x22, 0x41, 0x46, + 0xE8, 0x1D, 0x16, 0xF4, 0xF7, 0xF3, 0x20, 0xB9, 0xA8, 0x79, 0xB0, 0x42, + 0x14, 0xD0, 0x20, 0x2E, 0x12, 0xD0, 0x64, 0x1C, 0xE4, 0xB2, 0x78, 0x78, + 0x84, 0x42, 0xE8, 0xD3, 0x41, 0x46, 0x08, 0x48, 0xE4, 0xF7, 0xEE, 0xDC, + 0x03, 0x46, 0x02, 0x22, 0x06, 0x49, 0x07, 0x48, 0x00, 0x96, 0xE4, 0xF7, + 0x18, 0xDB, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x28, 0x46, 0xFB, 0xE7, + 0x60, 0x78, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0x80, 0x5F, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x49, 0x03, 0x46, 0x00, 0x20, + 0x4C, 0x78, 0x4A, 0x68, 0x0C, 0xE0, 0x00, 0xEB, 0x40, 0x01, 0x02, 0xEB, + 0x01, 0x11, 0x0D, 0x78, 0x25, 0xB1, 0x0D, 0x8A, 0x9D, 0x42, 0x01, 0xD1, + 0x08, 0x46, 0x70, 0xBD, 0x40, 0x1C, 0xC0, 0xB2, 0xA0, 0x42, 0xF0, 0xD3, + 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE4, 0xF7, 0xF0, 0xDA, 0x00, 0x20, + 0x70, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x48, 0x5F, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x10, 0x4D, 0x00, 0x24, 0x06, 0x46, + 0x21, 0x46, 0x6A, 0x78, 0x6B, 0x68, 0x09, 0xE0, 0x01, 0xEB, 0x41, 0x00, + 0x03, 0xEB, 0x00, 0x10, 0x00, 0x78, 0x08, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, + 0x49, 0x1C, 0xC9, 0xB2, 0x91, 0x42, 0xF3, 0xD3, 0x23, 0x46, 0x01, 0x22, + 0x06, 0x49, 0x07, 0x48, 0xE4, 0xF7, 0xCD, 0xDA, 0x0E, 0xB1, 0x20, 0x46, + 0x70, 0xBD, 0x68, 0x78, 0x00, 0x1B, 0xC0, 0xB2, 0x70, 0xBD, 0x00, 0x00, + 0x60, 0x78, 0x20, 0x00, 0xC0, 0x5F, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, + 0x41, 0x88, 0x40, 0xF2, 0x2F, 0x13, 0xA1, 0xF2, 0x2F, 0x12, 0x99, 0x42, + 0x34, 0xD0, 0x17, 0xDC, 0xB1, 0xF5, 0x95, 0x7F, 0x27, 0xD0, 0x0A, 0xDC, + 0x24, 0x29, 0x3C, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x27, 0x39, 0x2C, 0xD0, + 0x02, 0x29, 0x39, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0xA9, 0xB8, 0xB1, 0xF5, + 0x96, 0x7F, 0x1E, 0xD0, 0xB1, 0xF5, 0x97, 0x7F, 0x30, 0xD1, 0x00, 0x1D, + 0x00, 0xF0, 0x32, 0xB9, 0x63, 0x2A, 0x22, 0xD0, 0x08, 0xDC, 0x10, 0x2A, + 0x1C, 0xD0, 0x11, 0x2A, 0x0E, 0xD0, 0x13, 0x2A, 0x24, 0xD1, 0x00, 0x1D, + 0x00, 0xF0, 0x46, 0xB9, 0x7C, 0x2A, 0x19, 0xD0, 0x87, 0x2A, 0x1D, 0xD1, + 0x00, 0x1D, 0x00, 0xF0, 0xD1, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xB6, 0xB8, + 0x00, 0x1D, 0x00, 0xF0, 0x4F, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x14, 0xB8, + 0x00, 0x1D, 0x00, 0xF0, 0x07, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x20, 0xB9, + 0x00, 0x1D, 0x00, 0xF0, 0x85, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0xE2, 0xB9, + 0x00, 0x1D, 0x00, 0xF0, 0x93, 0xB9, 0x00, 0x1D, 0x00, 0xF0, 0x00, 0xBA, + 0x70, 0x47, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x01, 0x7A, + 0x09, 0x30, 0x06, 0x46, 0xFF, 0xF7, 0x24, 0xFF, 0x04, 0x00, 0x0A, 0xD1, + 0x20, 0x21, 0x30, 0x46, 0xFF, 0xF7, 0x1E, 0xFF, 0x04, 0x00, 0x04, 0xD1, + 0x20, 0x21, 0x2B, 0x48, 0xFF, 0xF7, 0x18, 0xFF, 0x04, 0x46, 0x2A, 0x88, + 0x29, 0x4F, 0x32, 0xB1, 0x00, 0x26, 0x00, 0x2C, 0x49, 0xD0, 0xA0, 0x78, + 0x01, 0x28, 0x33, 0xD0, 0x33, 0xE0, 0x00, 0x2C, 0x43, 0xD0, 0x68, 0x88, + 0x20, 0x82, 0x02, 0x20, 0x60, 0x70, 0xA8, 0x88, 0x60, 0x82, 0xD5, 0xF8, + 0x09, 0x00, 0xC4, 0xF8, 0x07, 0x00, 0xB5, 0xF8, 0x0D, 0x10, 0xA4, 0xF8, + 0x0B, 0x10, 0x2A, 0x7A, 0xA2, 0x71, 0x2B, 0x8A, 0xA3, 0x82, 0x6B, 0x8A, + 0xE3, 0x82, 0xAB, 0x8A, 0x23, 0x83, 0xEB, 0x79, 0x63, 0x71, 0xAB, 0x7D, + 0x63, 0x73, 0xEB, 0x7D, 0xA3, 0x73, 0x2B, 0x7E, 0xE3, 0x73, 0x16, 0x4B, + 0x18, 0x60, 0x16, 0x48, 0x99, 0x80, 0x02, 0x21, 0x02, 0x70, 0xE0, 0x78, + 0x00, 0x22, 0xF3, 0xF7, 0x8B, 0xFD, 0xA0, 0x78, 0x01, 0x28, 0x18, 0xD1, + 0x38, 0x78, 0x20, 0xF0, 0xC0, 0x00, 0x38, 0x70, 0x00, 0x20, 0x0E, 0xE0, + 0x01, 0x26, 0xE0, 0x78, 0x00, 0x21, 0xF3, 0xF7, 0x7D, 0xFD, 0x20, 0x46, + 0x00, 0xF0, 0x04, 0xFA, 0x00, 0x2E, 0x08, 0xD0, 0x38, 0x78, 0x20, 0xF0, + 0xC0, 0x00, 0x38, 0x70, 0x28, 0x88, 0xBD, 0xE8, 0xF0, 0x41, 0xF3, 0xF7, + 0x93, 0xBD, 0xBD, 0xE8, 0xF0, 0x81, 0x00, 0x00, 0x68, 0x78, 0x20, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x52, 0x78, 0x20, 0x00, 0x3A, 0x78, 0x20, 0x00, + 0x70, 0xB5, 0x05, 0x46, 0x81, 0x79, 0xFF, 0xF7, 0xB7, 0xFE, 0x6A, 0x89, + 0x04, 0x46, 0x8A, 0xB1, 0x0E, 0x48, 0x01, 0x78, 0x21, 0xF0, 0xC0, 0x01, + 0x01, 0x70, 0x34, 0xB1, 0xE0, 0x78, 0x00, 0x21, 0xF3, 0xF7, 0x52, 0xFD, + 0x20, 0x46, 0x00, 0xF0, 0xD9, 0xF9, 0x68, 0x89, 0xBD, 0xE8, 0x70, 0x40, + 0xF3, 0xF7, 0x6E, 0xBD, 0x14, 0xB1, 0x28, 0x89, 0x20, 0x82, 0x70, 0xBD, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x03, 0x49, 0x03, 0x48, 0xE4, 0xF7, + 0xDA, 0x99, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x44, 0x61, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43, 0x06, 0x46, 0x01, 0x25, + 0x81, 0x79, 0xFF, 0xF7, 0x89, 0xFE, 0xDF, 0xF8, 0x90, 0x80, 0x24, 0x4F, + 0x04, 0x00, 0x12, 0xD0, 0xE3, 0x78, 0x01, 0x22, 0x22, 0x49, 0x40, 0x46, + 0xE4, 0xF7, 0xC1, 0xD9, 0x38, 0x78, 0x00, 0x22, 0x20, 0xF0, 0x0C, 0x00, + 0x40, 0xF0, 0x02, 0x00, 0x38, 0x70, 0xE0, 0x78, 0x01, 0x21, 0xF3, 0xF7, + 0x1B, 0xFD, 0x00, 0x20, 0x28, 0xE0, 0x1B, 0x48, 0x40, 0xF6, 0x03, 0x54, + 0x00, 0x78, 0x01, 0x28, 0x08, 0xD1, 0x19, 0x48, 0x02, 0x68, 0x2A, 0xB1, + 0x69, 0x46, 0x16, 0x20, 0x00, 0x96, 0x90, 0x47, 0xA0, 0x42, 0x11, 0xD1, + 0x30, 0x46, 0xFF, 0xF7, 0x9F, 0xFD, 0x04, 0x00, 0x04, 0xD0, 0xB0, 0x79, + 0xA0, 0x71, 0x02, 0x20, 0xA0, 0x70, 0xD9, 0xE7, 0x0D, 0x49, 0x02, 0x25, + 0x00, 0x22, 0x30, 0x39, 0x40, 0x46, 0xE4, 0xF7, 0x94, 0xD9, 0x00, 0xE0, + 0x02, 0x25, 0x38, 0x78, 0x20, 0xF0, 0x0C, 0x00, 0x40, 0xF0, 0x02, 0x00, + 0x38, 0x70, 0x28, 0x46, 0xF3, 0xF7, 0x12, 0xFD, 0x29, 0x46, 0x30, 0x46, + 0xBD, 0xE8, 0xF8, 0x43, 0xEF, 0xF7, 0x1A, 0xBF, 0x00, 0x35, 0x10, 0x21, + 0x38, 0x78, 0x20, 0x00, 0x08, 0x61, 0xC0, 0x08, 0x3C, 0x78, 0x20, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x41, 0x88, 0x00, 0x88, + 0xFF, 0xF7, 0xF0, 0xFD, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF0, 0xF7, + 0xDB, 0xB9, 0x00, 0x00, 0x43, 0x88, 0x23, 0xB1, 0x01, 0x22, 0x04, 0x49, + 0x04, 0x48, 0xE4, 0xF7, 0x66, 0x99, 0x81, 0x88, 0x00, 0x88, 0xFF, 0xF7, + 0xDF, 0xBD, 0x00, 0x00, 0x38, 0x62, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFF, 0xF7, 0x4D, 0xFE, 0x00, 0x28, + 0x07, 0xD0, 0x61, 0x88, 0x41, 0x82, 0x61, 0x88, 0xC0, 0x78, 0xBD, 0xE8, + 0x10, 0x40, 0xF3, 0xF7, 0x97, 0xBD, 0x10, 0xBD, 0x10, 0xB5, 0x04, 0x46, + 0x00, 0x88, 0xFF, 0xF7, 0x3D, 0xFE, 0x00, 0x28, 0x0C, 0xD0, 0x61, 0x88, + 0x81, 0x82, 0xA1, 0x88, 0xC1, 0x82, 0xE1, 0x88, 0x01, 0x83, 0xC0, 0x78, + 0x00, 0x22, 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x46, 0xF3, 0xF7, 0x7A, 0xBC, + 0x10, 0xBD, 0x00, 0x00, 0x7F, 0xB5, 0x1D, 0x4E, 0x04, 0x46, 0x01, 0x25, + 0x30, 0x68, 0x10, 0xB3, 0x20, 0x88, 0xFF, 0xF7, 0x23, 0xFE, 0x28, 0xB3, + 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0xA0, 0x88, 0xAD, 0xF8, 0x04, 0x00, + 0x60, 0x88, 0xAD, 0xF8, 0x02, 0x00, 0xE0, 0x88, 0xAD, 0xF8, 0x06, 0x00, + 0x20, 0x89, 0xAD, 0xF8, 0x08, 0x00, 0xCD, 0xF8, 0x0C, 0xD0, 0x32, 0x68, + 0x03, 0xA9, 0x15, 0x20, 0x90, 0x47, 0xA0, 0xF5, 0x50, 0x61, 0x04, 0x39, + 0x05, 0xD1, 0x02, 0x25, 0x00, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xE4, 0xF7, + 0x0E, 0xD9, 0x20, 0x88, 0x04, 0xB0, 0x29, 0x46, 0xBD, 0xE8, 0x70, 0x40, + 0xEF, 0xF7, 0x90, 0xBF, 0x06, 0x49, 0x07, 0x48, 0x00, 0x22, 0x38, 0x39, + 0x80, 0x1E, 0xE4, 0xF7, 0x00, 0xD9, 0x20, 0x88, 0x02, 0x21, 0xEF, 0xF7, + 0x85, 0xFF, 0x7F, 0xBD, 0x48, 0x78, 0x20, 0x00, 0xAC, 0x61, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x88, 0xFF, 0xF7, + 0xE5, 0xFD, 0x00, 0x28, 0x0A, 0xD0, 0x62, 0x88, 0xC0, 0x78, 0x0A, 0xB1, + 0x01, 0x21, 0x01, 0xE0, 0x00, 0x22, 0x02, 0x21, 0xBD, 0xE8, 0x10, 0x40, + 0xF3, 0xF7, 0x24, 0xBC, 0x10, 0xBD, 0x00, 0x00, 0x3E, 0xB5, 0x04, 0x46, + 0x40, 0x88, 0xFF, 0xF7, 0xD1, 0xFD, 0x00, 0x28, 0x1A, 0xD0, 0x21, 0x88, + 0x19, 0xB9, 0x61, 0x79, 0x81, 0x73, 0x21, 0x79, 0x41, 0x73, 0x0B, 0x49, + 0x0A, 0x68, 0x00, 0x2A, 0x10, 0xD0, 0xC1, 0x78, 0x8D, 0xF8, 0x00, 0x10, + 0x21, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x81, 0x7B, 0x8D, 0xF8, 0x05, 0x10, + 0x40, 0x7B, 0x8D, 0xF8, 0x04, 0x00, 0xCD, 0xF8, 0x08, 0xD0, 0x02, 0xA9, + 0x17, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00, 0x48, 0x78, 0x20, 0x00, + 0x1F, 0xB5, 0x04, 0x46, 0x40, 0x88, 0xFF, 0xF7, 0xAB, 0xFD, 0x00, 0x28, + 0x1A, 0xD0, 0x21, 0x88, 0x29, 0xB9, 0x61, 0x68, 0xC0, 0xF8, 0x1A, 0x10, + 0xA1, 0x68, 0xC0, 0xF8, 0x1E, 0x10, 0x0A, 0x49, 0x0A, 0x68, 0x00, 0x2A, + 0x0E, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x88, 0xAD, 0xF8, + 0x02, 0x00, 0x60, 0x68, 0x01, 0x90, 0xA0, 0x68, 0x02, 0x90, 0xCD, 0xF8, + 0x0C, 0xD0, 0x03, 0xA9, 0x19, 0x20, 0x90, 0x47, 0x1F, 0xBD, 0x00, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x00, 0x88, 0x00, 0x28, + 0x1A, 0xD0, 0x0E, 0x4D, 0x28, 0x68, 0x00, 0x28, 0x16, 0xD0, 0x60, 0x88, + 0xFF, 0xF7, 0x7E, 0xFD, 0x00, 0x28, 0x11, 0xD0, 0xC1, 0x78, 0x8D, 0xF8, + 0x00, 0x10, 0x21, 0x88, 0xAD, 0xF8, 0x02, 0x10, 0x81, 0x7B, 0x8D, 0xF8, + 0x05, 0x10, 0x40, 0x7B, 0x8D, 0xF8, 0x04, 0x00, 0xCD, 0xF8, 0x08, 0xD0, + 0x2A, 0x68, 0x02, 0xA9, 0x17, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00, + 0x48, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x10, 0x4D, 0x04, 0x46, 0x28, 0x68, + 0x00, 0x28, 0x1A, 0xD0, 0xA1, 0x79, 0x20, 0x46, 0xFF, 0xF7, 0x24, 0xFD, + 0x00, 0x28, 0x14, 0xD0, 0xC0, 0x78, 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x89, + 0xAD, 0xF8, 0x02, 0x00, 0xA0, 0x7A, 0x8D, 0xF8, 0x04, 0x00, 0xA0, 0x89, + 0xAD, 0xF8, 0x06, 0x00, 0xE0, 0x89, 0xAD, 0xF8, 0x08, 0x00, 0xCD, 0xF8, + 0x0C, 0xD0, 0x2A, 0x68, 0x03, 0xA9, 0x1B, 0x20, 0x90, 0x47, 0x7F, 0xBD, + 0x48, 0x78, 0x20, 0x00, 0x1F, 0xB5, 0x1B, 0x4C, 0x00, 0xEB, 0x40, 0x01, + 0x09, 0x01, 0x60, 0x70, 0x3E, 0x23, 0x19, 0x4A, 0x00, 0x20, 0xEE, 0xF7, + 0xD7, 0xDD, 0x60, 0x60, 0x0A, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x20, 0x20, + 0xAD, 0xF8, 0x06, 0x00, 0x10, 0x20, 0xAD, 0xF8, 0x00, 0x00, 0xAD, 0xF8, + 0x02, 0x00, 0x4F, 0xF4, 0x7A, 0x70, 0xAD, 0xF8, 0x0A, 0x00, 0x00, 0x20, + 0xAD, 0xF8, 0x08, 0x00, 0x12, 0x20, 0xAD, 0xF8, 0x0C, 0x00, 0x3E, 0x20, + 0xAD, 0xF8, 0x0E, 0x00, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x0E, 0x00, + 0x16, 0xF4, 0x37, 0xF1, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x1E, 0x00, + 0x16, 0xF4, 0x31, 0xF1, 0x10, 0x22, 0x69, 0x46, 0x04, 0xF1, 0x2E, 0x00, + 0x16, 0xF4, 0x2B, 0xF1, 0x1F, 0xBD, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, + 0x06, 0xB2, 0x82, 0x00, 0x10, 0xB5, 0x04, 0x00, 0x0B, 0xD0, 0xE3, 0x78, + 0x01, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE4, 0xF7, 0x08, 0xD8, 0x20, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0x30, 0x21, 0x16, 0xF4, 0xB7, 0xB1, 0x10, 0xBD, + 0x2C, 0x5F, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x10, 0xB5, 0x00, 0x28, + 0x04, 0xD0, 0x78, 0x22, 0x02, 0x49, 0x16, 0xF4, 0x4F, 0xF1, 0x01, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0xBC, 0x02, 0x20, 0x00, 0x10, 0xB5, 0xF0, 0xF7, + 0x7F, 0xFB, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0xEC, 0xF7, 0xAC, 0xBE, 0x10, 0xB5, 0x00, 0x24, 0x03, 0x46, 0xB0, 0xF5, + 0x40, 0x7F, 0x0E, 0xD0, 0xA3, 0xF5, 0x40, 0x70, 0x0A, 0x4A, 0x01, 0x38, + 0x0D, 0xD0, 0x01, 0x28, 0x0D, 0xD0, 0x03, 0x24, 0x01, 0x22, 0x08, 0x49, + 0x08, 0x48, 0xE3, 0xF7, 0xD4, 0xDF, 0x20, 0x46, 0x10, 0xBD, 0x07, 0x48, + 0x00, 0x88, 0x08, 0x80, 0xF9, 0xE7, 0x10, 0x78, 0x00, 0xE0, 0x50, 0x78, + 0x08, 0x70, 0xF4, 0xE7, 0x30, 0x79, 0x20, 0x00, 0xE8, 0x7F, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x86, 0x74, 0x20, 0x00, 0x41, 0x88, 0xB1, 0xF5, + 0xBD, 0x7F, 0x20, 0xD0, 0x0B, 0xDC, 0xB1, 0xF5, 0xBA, 0x7F, 0x16, 0xD0, + 0xB1, 0xF5, 0xBB, 0x7F, 0x16, 0xD0, 0xB1, 0xF5, 0xBC, 0x7F, 0x0F, 0xD1, + 0x00, 0x1D, 0x00, 0xF0, 0x2F, 0xB8, 0xB1, 0xF5, 0xBE, 0x7F, 0x13, 0xD0, + 0xB1, 0xF5, 0xC0, 0x7F, 0x13, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0xB3, 0x39, + 0x02, 0xD1, 0x09, 0x49, 0x80, 0x7C, 0x48, 0x70, 0x70, 0x47, 0x00, 0x1D, + 0x00, 0xF0, 0x14, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x25, 0xB8, 0x00, 0x1D, + 0x00, 0xF0, 0x2C, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x55, 0xB8, 0x00, 0x1D, + 0x00, 0xF0, 0x48, 0xB8, 0x30, 0x79, 0x20, 0x00, 0x01, 0x49, 0x80, 0x7B, + 0x48, 0x70, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68, + 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x02, 0x20, 0x10, 0x47, 0x70, 0x47, + 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0, + 0x01, 0x46, 0x04, 0x20, 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, + 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x03, 0x20, + 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, 0x30, 0xB4, 0x0F, 0x4C, + 0x03, 0x88, 0x03, 0x22, 0x20, 0x78, 0x00, 0x21, 0x23, 0xB1, 0x01, 0x28, + 0x06, 0xD0, 0x02, 0x28, 0x06, 0xD0, 0x06, 0xE0, 0x01, 0x28, 0x03, 0xD0, + 0x02, 0x28, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0, 0x21, 0x70, 0x62, 0x68, + 0x00, 0x2A, 0x07, 0xD0, 0x20, 0x78, 0x30, 0xBC, 0x60, 0xF3, 0x07, 0x01, + 0x63, 0xF3, 0x1F, 0x41, 0x00, 0x20, 0x10, 0x47, 0x30, 0xBC, 0x70, 0x47, + 0x30, 0x79, 0x20, 0x00, 0x03, 0x4A, 0x52, 0x68, 0x00, 0x2A, 0x02, 0xD0, + 0x01, 0x46, 0x05, 0x20, 0x10, 0x47, 0x70, 0x47, 0x30, 0x79, 0x20, 0x00, + 0x05, 0x4A, 0x12, 0x78, 0xD2, 0x07, 0x06, 0xD0, 0x04, 0x4A, 0x52, 0x68, + 0x00, 0x2A, 0x02, 0xD0, 0x01, 0x46, 0x01, 0x20, 0x10, 0x47, 0x70, 0x47, + 0x38, 0x78, 0x20, 0x00, 0x30, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x80, 0x46, 0x2C, 0x48, 0x00, 0x25, 0xDF, 0xF8, 0xB0, 0xC0, 0x03, 0x78, + 0x8A, 0xB0, 0x0F, 0x46, 0x16, 0x46, 0x2C, 0x46, 0xC3, 0xB1, 0x29, 0x48, + 0x00, 0x78, 0x81, 0x06, 0x09, 0x0F, 0x03, 0xD1, 0x01, 0x21, 0xB1, 0xEB, + 0x90, 0x1F, 0x0F, 0xD1, 0x82, 0x09, 0xC0, 0xF3, 0x01, 0x11, 0xC0, 0xF3, + 0x81, 0x00, 0x8D, 0xE8, 0x07, 0x00, 0x04, 0x22, 0x21, 0x49, 0x60, 0x46, + 0xE3, 0xF7, 0x0F, 0xDF, 0x02, 0x20, 0x0A, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, + 0x01, 0x2F, 0x0C, 0xD1, 0x70, 0x79, 0x03, 0x21, 0xB1, 0xEB, 0x90, 0x1F, + 0x07, 0xD0, 0x1A, 0x49, 0x00, 0x22, 0x64, 0x31, 0x60, 0x46, 0xE3, 0xF7, + 0xFE, 0xDE, 0x03, 0x20, 0xED, 0xE7, 0xB8, 0xF1, 0x01, 0x0F, 0x14, 0xD1, + 0x15, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x00, 0x06, 0x19, 0xD5, 0x39, 0x46, + 0x10, 0x46, 0xFE, 0xF7, 0xE1, 0xFB, 0xA0, 0xB1, 0x41, 0x88, 0x0A, 0x06, + 0x00, 0xD5, 0x10, 0x4C, 0x09, 0x07, 0x04, 0xD5, 0x03, 0xAA, 0x14, 0x21, + 0xFE, 0xF7, 0x1E, 0xFF, 0x03, 0xAD, 0x2B, 0x46, 0x32, 0x46, 0x39, 0x46, + 0x40, 0x46, 0x00, 0x94, 0xF0, 0xF7, 0x2A, 0xFA, 0x18, 0xB1, 0x00, 0x20, + 0xCB, 0xE7, 0x0C, 0x20, 0xC9, 0xE7, 0x07, 0x20, 0xC7, 0xE7, 0x00, 0x00, + 0x30, 0x79, 0x20, 0x00, 0x00, 0x35, 0x10, 0x21, 0x38, 0x78, 0x20, 0x00, + 0x10, 0x81, 0xC0, 0x08, 0x64, 0x01, 0x20, 0x00, 0x28, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0xF0, 0xF7, 0xF3, 0xFA, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, + 0x07, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xF0, 0xF7, 0x17, 0xFB, 0x08, 0xB1, + 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0x01, 0x49, 0x48, 0x60, + 0x70, 0x47, 0x00, 0x00, 0x30, 0x79, 0x20, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x1F, 0x4C, 0x1E, 0x4D, 0x06, 0x00, 0x23, 0x78, 0x03, 0xD0, 0x5B, 0xB1, + 0x01, 0x22, 0x1D, 0x49, 0x04, 0xE0, 0x03, 0x2B, 0x06, 0xD0, 0x1B, 0x49, + 0x01, 0x22, 0x3C, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0xA0, 0xDE, 0x15, 0xE0, + 0x18, 0x48, 0x00, 0x78, 0x81, 0x06, 0x09, 0x0F, 0x03, 0xD1, 0x01, 0x27, + 0xB7, 0xEB, 0x90, 0x1F, 0x0F, 0xD1, 0x82, 0x09, 0xC0, 0xF3, 0x01, 0x11, + 0xCD, 0xE9, 0x00, 0x12, 0x10, 0x49, 0xC0, 0xF3, 0x81, 0x03, 0x03, 0x22, + 0x78, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0x89, 0xDE, 0x02, 0x20, 0xBD, 0xE8, + 0xFC, 0x81, 0x30, 0x46, 0xF0, 0xF7, 0xD1, 0xFC, 0x30, 0xB1, 0x16, 0xB1, + 0x02, 0x20, 0x20, 0x70, 0x00, 0xE0, 0x27, 0x70, 0x00, 0x20, 0xF2, 0xE7, + 0x05, 0x49, 0x00, 0x22, 0xD0, 0x31, 0x28, 0x46, 0xE3, 0xF7, 0x75, 0xDE, + 0xFF, 0x20, 0xEA, 0xE7, 0x00, 0x35, 0x10, 0x21, 0x30, 0x79, 0x20, 0x00, + 0x14, 0x80, 0xC0, 0x08, 0x38, 0x78, 0x20, 0x00, 0x10, 0xB5, 0xF0, 0xF7, + 0x89, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x10, 0xB5, 0x00, 0x24, 0x03, 0x46, 0xB0, 0xF5, 0x40, 0x7F, 0x0A, 0xD1, + 0x10, 0x88, 0x4A, 0xF2, 0xB7, 0x12, 0x41, 0x1E, 0x91, 0x42, 0x04, 0xD8, + 0x06, 0x49, 0x08, 0x80, 0x00, 0xF0, 0x06, 0xFC, 0x05, 0xE0, 0x03, 0x24, + 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xE3, 0xF7, 0x4C, 0xDE, 0x20, 0x46, + 0x10, 0xBD, 0x00, 0x00, 0x86, 0x74, 0x20, 0x00, 0xBC, 0x7F, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x04, 0x48, 0x10, 0xB5, 0x00, 0x88, 0xF0, 0xF7, + 0x9A, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x86, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x08, 0x48, + 0xFF, 0xF7, 0x88, 0xFA, 0x50, 0xB1, 0x07, 0x49, 0x04, 0xEB, 0x44, 0x00, + 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x00, 0x8A, 0xF0, 0xF7, 0x2E, 0xFA, + 0x00, 0x20, 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0xC6, 0xB1, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x0A, 0x48, + 0xFF, 0xF7, 0x70, 0xFA, 0x70, 0xB1, 0x09, 0x48, 0x04, 0xEB, 0x44, 0x01, + 0x40, 0x68, 0x00, 0xEB, 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF0, 0xF7, + 0x77, 0xFD, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x04, 0x20, 0x10, 0xBD, 0x25, 0xB2, 0x82, 0x00, 0x60, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0xFF, 0xF7, 0x54, 0xFA, + 0x58, 0xB1, 0x08, 0x48, 0x04, 0xEB, 0x44, 0x01, 0x00, 0x68, 0x00, 0xEB, + 0x01, 0x10, 0x81, 0x79, 0xC0, 0x1D, 0xF0, 0xF7, 0x89, 0xFD, 0x00, 0x20, + 0x10, 0xBD, 0x04, 0x20, 0x10, 0xBD, 0x00, 0x00, 0xB9, 0xB1, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x01, 0x49, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xF8, 0x43, 0x07, 0x46, 0x0D, 0x46, + 0x40, 0x79, 0x01, 0x21, 0xDF, 0xF8, 0x70, 0x80, 0x16, 0x46, 0xB1, 0xEB, + 0x90, 0x1F, 0x2F, 0xD1, 0x38, 0x46, 0xFE, 0xF7, 0xC5, 0xFA, 0x04, 0x00, + 0x05, 0xD1, 0x01, 0x21, 0x38, 0x46, 0xFE, 0xF7, 0x4D, 0xFA, 0x04, 0x00, + 0x18, 0xD0, 0xA0, 0x78, 0x00, 0x07, 0x19, 0xD5, 0x20, 0x69, 0x28, 0x60, + 0xA0, 0x8A, 0xA8, 0x80, 0xA0, 0x7D, 0x30, 0x70, 0x29, 0x46, 0x10, 0x48, + 0xE3, 0xF7, 0x8E, 0xDF, 0x03, 0x46, 0xA0, 0x7D, 0x00, 0x90, 0x0C, 0x48, + 0x02, 0x22, 0x0D, 0x49, 0xC0, 0x1C, 0xE3, 0xF7, 0xB6, 0xDD, 0x01, 0x20, + 0xBD, 0xE8, 0xF8, 0x83, 0x09, 0x49, 0x00, 0x22, 0x30, 0x39, 0x02, 0xE0, + 0x07, 0x49, 0x00, 0x22, 0x44, 0x31, 0x40, 0x46, 0xE3, 0xF7, 0xA9, 0xDD, + 0x00, 0x20, 0xF1, 0xE7, 0x03, 0x49, 0x00, 0x22, 0x74, 0x31, 0xF6, 0xE7, + 0x00, 0x35, 0x10, 0x21, 0x00, 0x00, 0x30, 0x21, 0x24, 0x72, 0xC0, 0x08, + 0x10, 0xB5, 0x04, 0x46, 0x08, 0x78, 0x0B, 0x46, 0x00, 0x1D, 0xC2, 0xB2, + 0x61, 0x78, 0x18, 0x46, 0xF2, 0xF7, 0x6C, 0xFB, 0x08, 0xB1, 0x00, 0x20, + 0x10, 0xBD, 0x60, 0x88, 0x40, 0xF0, 0x40, 0x00, 0x60, 0x80, 0x01, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x59, 0x48, + 0x88, 0x46, 0xA1, 0xF1, 0x11, 0x07, 0x00, 0x25, 0x01, 0x21, 0xB0, 0xF8, + 0xC2, 0x01, 0x89, 0xB0, 0x16, 0x46, 0x04, 0xF1, 0x08, 0x09, 0x06, 0x2F, + 0x70, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x19, 0x41, 0x2D, 0x55, 0x61, + 0x80, 0x07, 0x01, 0xD4, 0x01, 0x25, 0x68, 0xE0, 0x8D, 0xF8, 0x00, 0x60, + 0x32, 0x46, 0x19, 0x46, 0x01, 0xA8, 0x15, 0xF4, 0x7C, 0xF6, 0x61, 0x78, + 0x20, 0x22, 0x68, 0x46, 0xF2, 0xF7, 0x96, 0xFB, 0x00, 0x28, 0x7F, 0xD1, + 0x60, 0x88, 0x40, 0xF0, 0x02, 0x00, 0x52, 0xE0, 0x40, 0x07, 0xE9, 0xD5, + 0x8D, 0xF8, 0x00, 0x60, 0x32, 0x46, 0x19, 0x46, 0x01, 0xA8, 0x15, 0xF4, + 0x68, 0xF6, 0x61, 0x78, 0x20, 0x22, 0x68, 0x46, 0xF2, 0xF7, 0x36, 0xFC, + 0x00, 0x28, 0x6B, 0xD1, 0x60, 0x88, 0x40, 0xF0, 0x04, 0x00, 0x3E, 0xE0, + 0x00, 0x07, 0xD5, 0xD5, 0xD9, 0x75, 0x1F, 0x46, 0x61, 0x78, 0x18, 0x46, + 0xF2, 0xF7, 0xFC, 0xFB, 0x00, 0x28, 0x5D, 0xD1, 0x38, 0x69, 0x20, 0x61, + 0xB8, 0x8A, 0xA0, 0x82, 0xB8, 0x7D, 0xA0, 0x75, 0x60, 0x88, 0x40, 0xF0, + 0x08, 0x00, 0x2A, 0xE0, 0x03, 0x20, 0xE0, 0x73, 0x20, 0x79, 0x01, 0x28, + 0x01, 0xD1, 0x07, 0x20, 0xE0, 0x73, 0x61, 0x78, 0x48, 0x46, 0xF2, 0xF7, + 0x89, 0xFB, 0xD0, 0xBB, 0x61, 0x78, 0x01, 0x20, 0xEB, 0xF7, 0x02, 0xF9, + 0x60, 0x88, 0x40, 0xF0, 0x81, 0x00, 0x16, 0xE0, 0xC0, 0x06, 0xAD, 0xD5, + 0x59, 0x75, 0x18, 0x46, 0x61, 0x78, 0xF2, 0xF7, 0x21, 0xFB, 0x50, 0xBB, + 0x60, 0x88, 0x40, 0xF0, 0x10, 0x00, 0x0A, 0xE0, 0x80, 0x06, 0xA1, 0xD5, + 0x59, 0x75, 0x18, 0x46, 0x61, 0x78, 0xF2, 0xF7, 0x9D, 0xFB, 0xF0, 0xB9, + 0x60, 0x88, 0x40, 0xF0, 0x20, 0x00, 0x60, 0x80, 0x96, 0xE7, 0xFF, 0xE7, + 0xBD, 0xB1, 0x60, 0x88, 0xC1, 0x07, 0x21, 0xD1, 0xE1, 0x7B, 0x00, 0x06, + 0x41, 0xF0, 0x01, 0x01, 0xE1, 0x73, 0x02, 0xD5, 0x41, 0xF0, 0x02, 0x00, + 0xE0, 0x73, 0x20, 0x79, 0x01, 0x28, 0xE0, 0x7B, 0x08, 0xD0, 0x20, 0xF0, + 0x04, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x48, 0x46, 0xF2, 0xF7, 0x4E, 0xFB, + 0x18, 0xB1, 0x0B, 0xE0, 0x40, 0xF0, 0x04, 0x00, 0xF5, 0xE7, 0x61, 0x78, + 0x01, 0x20, 0xEB, 0xF7, 0xC3, 0xF8, 0x60, 0x88, 0x01, 0x25, 0x40, 0xF0, + 0x01, 0x00, 0x60, 0x80, 0xCD, 0xF8, 0x00, 0x80, 0xCD, 0xE9, 0x01, 0x65, + 0x63, 0x78, 0x04, 0x22, 0x04, 0x49, 0x05, 0x48, 0xE3, 0xF7, 0xD7, 0xDC, + 0x09, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x83, 0x64, 0x01, 0x20, 0x00, + 0x60, 0x70, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x70, 0xB5, 0x03, 0x46, + 0xA0, 0xF5, 0x10, 0x75, 0x00, 0x24, 0x0F, 0x48, 0x0F, 0x4A, 0x06, 0x2D, + 0x12, 0xD2, 0xDF, 0xE8, 0x05, 0xF0, 0x03, 0x05, 0x08, 0x0A, 0x0D, 0x0F, + 0x80, 0x78, 0x00, 0xE0, 0x10, 0x78, 0x08, 0x70, 0x0E, 0xE0, 0x50, 0x88, + 0x00, 0xE0, 0x90, 0x88, 0x08, 0x80, 0x09, 0xE0, 0x00, 0x78, 0xF6, 0xE7, + 0x40, 0x78, 0xF4, 0xE7, 0x03, 0x24, 0x01, 0x22, 0x04, 0x49, 0x05, 0x48, + 0xE3, 0xF7, 0xAB, 0xDC, 0x20, 0x46, 0x70, 0xBD, 0x63, 0x79, 0x20, 0x00, + 0xB0, 0x74, 0x20, 0x00, 0x58, 0x83, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x41, 0x88, 0xB1, 0xF5, 0x9C, 0x7F, 0x0B, 0xD0, 0xB1, 0xF5, 0x9D, 0x7F, + 0x0B, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x3B, 0x39, 0x0A, 0xD0, 0x46, 0x29, + 0x0B, 0xD1, 0x00, 0x1D, 0x00, 0xF0, 0x0A, 0xB8, 0x00, 0x1D, 0x00, 0xF0, + 0x9D, 0xB8, 0x00, 0x1D, 0x00, 0xF0, 0x7A, 0xB8, 0x00, 0x1D, 0x00, 0xF0, + 0x6B, 0xB8, 0x70, 0x47, 0x38, 0xB5, 0x04, 0x46, 0x07, 0x49, 0xC0, 0x1D, + 0xFC, 0xF7, 0x36, 0xFE, 0x00, 0x28, 0x07, 0xD0, 0x05, 0x48, 0x02, 0x68, + 0x00, 0x2A, 0x03, 0xD0, 0x69, 0x46, 0x31, 0x20, 0x00, 0x94, 0x90, 0x47, + 0x38, 0xBD, 0x00, 0x00, 0x28, 0x78, 0x20, 0x00, 0x48, 0x78, 0x20, 0x00, + 0x38, 0xB5, 0x04, 0x46, 0x08, 0x48, 0x02, 0x68, 0x1A, 0xB1, 0x69, 0x46, + 0x50, 0x20, 0x00, 0x94, 0x90, 0x47, 0xE0, 0x69, 0x00, 0x28, 0x06, 0xD0, + 0x61, 0x7E, 0x00, 0x29, 0x03, 0xD0, 0xBD, 0xE8, 0x38, 0x40, 0xEC, 0xF7, + 0xE3, 0xBA, 0x38, 0xBD, 0x48, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, + 0x0C, 0x48, 0x00, 0x21, 0x81, 0x70, 0x21, 0x88, 0x41, 0xB9, 0x0B, 0x49, + 0x8B, 0x88, 0x4A, 0x88, 0x01, 0x78, 0x01, 0x20, 0xEF, 0xF7, 0xFB, 0xFE, + 0x00, 0x28, 0x09, 0xD1, 0x07, 0x48, 0x01, 0x78, 0x21, 0xF0, 0x30, 0x01, + 0x01, 0x70, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF2, 0xF7, 0xCA, 0xBF, + 0x10, 0xBD, 0x00, 0x00, 0xBE, 0x74, 0x20, 0x00, 0x08, 0x7A, 0x20, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x30, 0xB4, 0x0C, 0x4C, 0x00, 0x88, 0x21, 0x78, + 0x21, 0xF0, 0x30, 0x02, 0x02, 0xF1, 0x20, 0x03, 0xC1, 0xF3, 0x01, 0x11, + 0x20, 0xB1, 0x01, 0x29, 0x06, 0xD0, 0x03, 0x29, 0x06, 0xD0, 0x06, 0xE0, + 0x01, 0x29, 0x03, 0xD0, 0x03, 0x29, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0, + 0x23, 0x70, 0x30, 0xBC, 0xF2, 0xF7, 0xA8, 0xBF, 0x38, 0x78, 0x20, 0x00, + 0x04, 0x49, 0x08, 0xB5, 0x0A, 0x68, 0x00, 0x2A, 0x03, 0xD0, 0x00, 0x90, + 0x69, 0x46, 0x30, 0x20, 0x90, 0x47, 0x08, 0xBD, 0x48, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0x0C, 0x49, 0x04, 0x46, 0x00, 0x20, 0x48, 0x70, 0x20, 0x88, + 0x30, 0xB9, 0x0A, 0x48, 0x41, 0x78, 0x01, 0x20, 0xF0, 0xF7, 0x0F, 0xF9, + 0x00, 0x28, 0x09, 0xD1, 0x07, 0x48, 0x01, 0x78, 0x21, 0xF0, 0x30, 0x01, + 0x01, 0x70, 0x20, 0x88, 0xBD, 0xE8, 0x10, 0x40, 0xF2, 0xF7, 0x82, 0xBF, + 0x10, 0xBD, 0x00, 0x00, 0xB0, 0x74, 0x20, 0x00, 0x63, 0x79, 0x20, 0x00, + 0x38, 0x78, 0x20, 0x00, 0x30, 0xB4, 0x0C, 0x4C, 0x00, 0x88, 0x21, 0x78, + 0x21, 0xF0, 0x30, 0x02, 0x02, 0xF1, 0x20, 0x03, 0xC1, 0xF3, 0x01, 0x11, + 0x20, 0xB1, 0x01, 0x29, 0x06, 0xD0, 0x03, 0x29, 0x06, 0xD0, 0x06, 0xE0, + 0x01, 0x29, 0x03, 0xD0, 0x03, 0x29, 0x02, 0xD1, 0x22, 0x70, 0x00, 0xE0, + 0x23, 0x70, 0x30, 0xBC, 0xF2, 0xF7, 0x60, 0xBF, 0x38, 0x78, 0x20, 0x00, + 0x10, 0xB5, 0x0A, 0x4C, 0x20, 0x78, 0xC0, 0xF3, 0x01, 0x13, 0x02, 0x2B, + 0x04, 0xD0, 0x01, 0x22, 0x07, 0x49, 0x08, 0x48, 0xE3, 0xF7, 0xC9, 0xDB, + 0x20, 0x78, 0x20, 0xF0, 0x30, 0x00, 0x20, 0x70, 0xBD, 0xE8, 0x10, 0x40, + 0x00, 0x20, 0xF2, 0xF7, 0x49, 0xBF, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, + 0x4C, 0x8D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, + 0x03, 0x46, 0xA0, 0xF5, 0x10, 0x77, 0x00, 0x24, 0x01, 0x25, 0x19, 0x4E, + 0x19, 0x48, 0x06, 0x2F, 0x0B, 0xD2, 0xDF, 0xE8, 0x07, 0xF0, 0x03, 0x11, + 0x17, 0x1C, 0x21, 0x26, 0x01, 0x29, 0x04, 0xD1, 0x11, 0x78, 0x03, 0x29, + 0x01, 0xD8, 0xB1, 0x70, 0x0A, 0xE0, 0x03, 0x24, 0x01, 0x22, 0x12, 0x49, + 0x12, 0x48, 0xE3, 0xF7, 0x9C, 0xDB, 0x18, 0xE0, 0x01, 0x29, 0xF6, 0xD1, + 0x11, 0x78, 0x01, 0x70, 0x45, 0x70, 0x12, 0xE0, 0x02, 0x29, 0xF0, 0xD1, + 0x11, 0x88, 0x41, 0x80, 0xF8, 0xE7, 0x02, 0x29, 0xEB, 0xD1, 0x11, 0x88, + 0x81, 0x80, 0xF3, 0xE7, 0x01, 0x29, 0xE6, 0xD1, 0x11, 0x78, 0x31, 0x70, + 0xEE, 0xE7, 0x01, 0x29, 0xE1, 0xD1, 0x10, 0x78, 0x70, 0x70, 0x20, 0x46, + 0xBD, 0xE8, 0xF0, 0x81, 0x63, 0x79, 0x20, 0x00, 0xB0, 0x74, 0x20, 0x00, + 0x2C, 0x83, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x38, 0xB5, 0x16, 0x4D, + 0x02, 0x24, 0x28, 0x78, 0x10, 0xF0, 0x30, 0x0F, 0x08, 0xD0, 0xC0, 0xF3, + 0x01, 0x13, 0x01, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE3, 0xF7, 0x69, 0xDB, + 0x20, 0x46, 0x38, 0xBD, 0x11, 0x48, 0x12, 0x49, 0x42, 0x78, 0x92, 0xB1, + 0x8A, 0x78, 0x00, 0x92, 0x0B, 0x78, 0x82, 0x88, 0x41, 0x88, 0x00, 0x78, + 0xF0, 0xF7, 0x4E, 0xF8, 0x0D, 0xE0, 0x28, 0x78, 0x00, 0x24, 0x20, 0xF0, + 0x30, 0x00, 0x10, 0x30, 0x28, 0x70, 0x20, 0x46, 0xF2, 0xF7, 0xDA, 0xFE, + 0xE6, 0xE7, 0x49, 0x78, 0x01, 0x20, 0xF0, 0xF7, 0x56, 0xF8, 0x00, 0x28, + 0xEF, 0xD1, 0xDF, 0xE7, 0x38, 0x78, 0x20, 0x00, 0x84, 0x83, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0xB0, 0x74, 0x20, 0x00, 0x63, 0x79, 0x20, 0x00, + 0x70, 0xB5, 0x0F, 0x4D, 0x02, 0x24, 0x28, 0x78, 0xC0, 0xF3, 0x01, 0x13, + 0x02, 0x2B, 0x06, 0xD0, 0x01, 0x22, 0x0C, 0x49, 0x0C, 0x48, 0xE3, 0xF7, + 0x32, 0xDB, 0x20, 0x46, 0x70, 0xBD, 0x0B, 0x48, 0x41, 0x78, 0x00, 0x20, + 0xF0, 0xF7, 0x35, 0xF8, 0x00, 0x28, 0xF6, 0xD0, 0x28, 0x78, 0x00, 0x24, + 0x40, 0xF0, 0x30, 0x00, 0x28, 0x70, 0x20, 0x46, 0xF2, 0xF7, 0xAA, 0xFE, + 0xED, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0xA8, 0x83, 0xC0, 0x08, + 0x00, 0x35, 0x10, 0x21, 0x63, 0x79, 0x20, 0x00, 0x04, 0x4A, 0x10, 0xB5, + 0x02, 0xEB, 0x00, 0x10, 0x10, 0x22, 0x15, 0xF4, 0x24, 0xF4, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x6E, 0x78, 0x20, 0x00, 0x7C, 0xB5, 0x0E, 0x46, + 0x04, 0x46, 0x01, 0x46, 0x15, 0x46, 0x12, 0x48, 0xFE, 0xF7, 0x5A, 0xFF, + 0xE8, 0xB1, 0x11, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x6A, 0x46, 0x09, 0x68, + 0x01, 0xEB, 0x00, 0x10, 0x0C, 0x21, 0x00, 0x8A, 0x8D, 0xF8, 0x00, 0x10, + 0x8D, 0xF8, 0x01, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x02, 0x00, 0x8D, 0xF8, + 0x03, 0x60, 0x8D, 0xF8, 0x04, 0x50, 0x05, 0x21, 0x4F, 0xF6, 0x80, 0x50, + 0xF0, 0xF7, 0x5E, 0xFC, 0x08, 0xB1, 0x00, 0x20, 0x7C, 0xBD, 0x07, 0x20, + 0x7C, 0xBD, 0x04, 0x20, 0x7C, 0xBD, 0x00, 0x00, 0xF1, 0xB1, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46, + 0x15, 0x46, 0x09, 0x48, 0xFE, 0xF7, 0x2C, 0xFF, 0x60, 0xB1, 0x08, 0x49, + 0x04, 0xEB, 0x44, 0x00, 0x2A, 0x46, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, + 0x31, 0x46, 0x00, 0x8A, 0xF0, 0xF7, 0x7B, 0xF8, 0x00, 0x20, 0x70, 0xBD, + 0x04, 0x20, 0x70, 0xBD, 0xA9, 0xB1, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xFE, 0x43, 0x88, 0x46, 0x33, 0x4D, 0x00, 0x21, 0x11, 0x70, + 0x29, 0x88, 0x32, 0x4E, 0x17, 0x46, 0x88, 0x42, 0x02, 0xD0, 0x00, 0x22, + 0x30, 0x49, 0x48, 0xE0, 0xD8, 0xF8, 0x00, 0x10, 0x01, 0x91, 0xD8, 0xF8, + 0x04, 0x00, 0x02, 0x90, 0x9D, 0xF8, 0x0A, 0x10, 0x01, 0xA8, 0xFD, 0xF7, + 0x99, 0xFF, 0x04, 0x00, 0x06, 0xD1, 0x9D, 0xF8, 0x0A, 0x10, 0x01, 0xA8, + 0xFD, 0xF7, 0x20, 0xFF, 0x04, 0x00, 0x08, 0xD0, 0x01, 0x20, 0x25, 0x49, + 0x38, 0x70, 0x00, 0x22, 0x34, 0x31, 0x30, 0x46, 0xE3, 0xF7, 0x97, 0xDA, + 0x38, 0xE0, 0x9D, 0xF8, 0x0B, 0x00, 0x00, 0x27, 0x40, 0x07, 0x00, 0xD5, + 0x01, 0x27, 0x9D, 0xF8, 0x0A, 0x10, 0x3A, 0x46, 0x01, 0xA8, 0xFB, 0xF7, + 0x9F, 0xFE, 0x04, 0x00, 0x0C, 0xD1, 0xFE, 0xF7, 0x0D, 0xFB, 0x48, 0xB3, + 0xFC, 0xF7, 0xDC, 0xFF, 0x9D, 0xF8, 0x0A, 0x10, 0x3A, 0x46, 0x01, 0xA8, + 0xFB, 0xF7, 0x92, 0xFE, 0x04, 0x00, 0x1F, 0xD0, 0x60, 0x78, 0x00, 0x90, + 0x13, 0x48, 0x14, 0x49, 0x2A, 0x88, 0x00, 0x88, 0x09, 0x88, 0xD3, 0xB2, + 0x08, 0x44, 0x81, 0xB2, 0x40, 0x46, 0xF9, 0xF7, 0x3C, 0xF9, 0x40, 0xB1, + 0x0C, 0x49, 0x00, 0x22, 0x64, 0x31, 0x30, 0x46, 0xE3, 0xF7, 0x67, 0xDA, + 0x00, 0x20, 0xBD, 0xE8, 0xFE, 0x83, 0x61, 0x78, 0x01, 0x20, 0xEA, 0xF7, + 0x3D, 0xFE, 0x20, 0x46, 0xFE, 0xF7, 0xA2, 0xFD, 0x20, 0x46, 0xF4, 0xE7, + 0x03, 0x49, 0x00, 0x22, 0xA4, 0x31, 0xEC, 0xE7, 0xEE, 0x78, 0x20, 0x00, + 0x00, 0x35, 0x10, 0x21, 0x90, 0x74, 0xC0, 0x08, 0xF0, 0x78, 0x20, 0x00, + 0xE0, 0x78, 0x20, 0x00, 0x02, 0x48, 0x01, 0x89, 0x41, 0xF0, 0x08, 0x01, + 0x01, 0x81, 0x70, 0x47, 0x50, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x0C, 0x46, 0x46, 0x49, 0x03, 0x46, 0xA0, 0xF2, 0x21, 0x2C, 0x16, 0x46, + 0x08, 0x89, 0x00, 0x25, 0x41, 0x4A, 0x40, 0xF0, 0x40, 0x07, 0xBC, 0xF1, + 0x0F, 0x0F, 0x12, 0xD2, 0xDF, 0xE8, 0x0C, 0xF0, 0x08, 0x2C, 0x18, 0x23, + 0x11, 0x11, 0x11, 0x3E, 0x45, 0x4C, 0x54, 0x5B, 0x72, 0x66, 0x6B, 0x00, + 0x02, 0x2C, 0x06, 0xD1, 0x30, 0x88, 0x50, 0x81, 0x37, 0x4A, 0x02, 0x21, + 0x0A, 0x32, 0x01, 0x20, 0x29, 0xE0, 0x03, 0x25, 0x01, 0x22, 0x36, 0x49, + 0x36, 0x48, 0xE3, 0xF7, 0x1C, 0xDA, 0x56, 0xE0, 0x01, 0x2C, 0xF6, 0xD1, + 0x30, 0x78, 0x01, 0x28, 0xF3, 0xD8, 0xD0, 0x70, 0x00, 0xB1, 0x01, 0x20, + 0xEE, 0xF7, 0x59, 0xFF, 0x4B, 0xE0, 0x06, 0x2C, 0xEB, 0xD1, 0x33, 0x68, + 0x53, 0x61, 0xB3, 0x88, 0x13, 0x83, 0x40, 0xF0, 0x20, 0x00, 0x37, 0xE0, + 0x28, 0x2C, 0x00, 0xD3, 0x27, 0x24, 0x27, 0x48, 0x22, 0x46, 0x31, 0x46, + 0x0A, 0x30, 0x15, 0xF4, 0x12, 0xF3, 0x24, 0x49, 0x00, 0x20, 0x0A, 0x31, + 0x0A, 0x46, 0x08, 0x55, 0x28, 0x21, 0xF3, 0xF7, 0x05, 0xF8, 0x30, 0xE0, + 0x01, 0x2C, 0xD0, 0xD1, 0x30, 0x78, 0x01, 0x28, 0xCD, 0xD8, 0x10, 0x71, + 0x29, 0xE0, 0x01, 0x2C, 0xC9, 0xD1, 0x30, 0x78, 0x03, 0x28, 0xC6, 0xD8, + 0x90, 0x71, 0x05, 0xE0, 0x01, 0x2C, 0xC2, 0xD1, 0x30, 0x78, 0x07, 0x28, + 0xBF, 0xD8, 0xD0, 0x71, 0x0F, 0x81, 0x1A, 0xE0, 0x01, 0x2C, 0xBA, 0xD1, + 0x30, 0x78, 0x07, 0x28, 0xB7, 0xD8, 0x10, 0x72, 0xF6, 0xE7, 0x01, 0x2C, + 0xB3, 0xD1, 0x34, 0x78, 0x01, 0x2C, 0xB0, 0xD8, 0x54, 0x72, 0x0C, 0xD1, + 0x40, 0xF0, 0x80, 0x00, 0x08, 0x81, 0x08, 0xE0, 0x02, 0x2C, 0xA8, 0xD1, + 0x30, 0x88, 0x88, 0x80, 0x03, 0xE0, 0x02, 0x2C, 0xA3, 0xD1, 0x30, 0x88, + 0xC8, 0x80, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x81, 0x01, 0x2C, 0x9C, 0xD1, + 0x32, 0x78, 0x07, 0x2A, 0x99, 0xD8, 0x8A, 0x70, 0x40, 0xF4, 0x80, 0x70, + 0xE8, 0xE7, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, 0x50, 0x74, 0x20, 0x00, + 0xE0, 0x5D, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, 0x10, 0xB5, 0xFD, 0xF7, + 0x9D, 0xFE, 0x00, 0x28, 0x05, 0xD0, 0x41, 0x78, 0xBD, 0xE8, 0x10, 0x40, + 0x01, 0x20, 0xEA, 0xF7, 0x6F, 0xBE, 0x10, 0xBD, 0x10, 0xB5, 0xEF, 0xF7, + 0x41, 0xFF, 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, + 0x2D, 0xE9, 0xF8, 0x43, 0x88, 0x46, 0x04, 0x46, 0x01, 0x46, 0x1D, 0x46, + 0x16, 0x46, 0x0B, 0x48, 0x08, 0x9F, 0xFE, 0xF7, 0xE7, 0xFD, 0x78, 0xB1, + 0x09, 0x49, 0x00, 0x97, 0x04, 0xEB, 0x44, 0x00, 0x49, 0x68, 0x2B, 0x46, + 0x01, 0xEB, 0x00, 0x10, 0x32, 0x46, 0x00, 0x8A, 0x41, 0x46, 0xEF, 0xF7, + 0x7B, 0xFF, 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x83, 0x04, 0x20, 0xFB, 0xE7, + 0x51, 0xB2, 0x82, 0x00, 0x60, 0x78, 0x20, 0x00, 0x3E, 0xB5, 0x0D, 0x46, + 0x04, 0x00, 0x31, 0xD0, 0x20, 0x78, 0x01, 0x28, 0x2E, 0xD1, 0x28, 0x78, + 0xAA, 0x78, 0x69, 0x78, 0x8D, 0xE8, 0x07, 0x00, 0x63, 0x78, 0x04, 0x22, + 0x15, 0x49, 0x16, 0x48, 0xE3, 0xF7, 0x67, 0xD9, 0x28, 0x78, 0x01, 0x28, + 0xE0, 0x7B, 0x09, 0xD0, 0x20, 0xF0, 0x10, 0x00, 0xE0, 0x73, 0x68, 0x78, + 0x00, 0x28, 0xE0, 0x7B, 0x05, 0xD0, 0x40, 0xF0, 0x20, 0x00, 0x04, 0xE0, + 0x40, 0xF0, 0x10, 0x00, 0xF4, 0xE7, 0x20, 0xF0, 0x20, 0x00, 0xE0, 0x73, + 0xA8, 0x78, 0x00, 0x28, 0xE0, 0x7B, 0x02, 0xD0, 0x40, 0xF0, 0x40, 0x00, + 0x01, 0xE0, 0x20, 0xF0, 0x40, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x04, 0xF1, + 0x08, 0x00, 0xF1, 0xF7, 0xA3, 0xFF, 0x08, 0xB1, 0x00, 0x20, 0x3E, 0xBD, + 0x01, 0x20, 0x3E, 0xBD, 0x1C, 0x73, 0xC0, 0x08, 0x02, 0x35, 0x10, 0x21, + 0x70, 0xB5, 0x04, 0x46, 0x00, 0x25, 0xEF, 0xF7, 0x71, 0xFF, 0x28, 0xB1, + 0x04, 0x48, 0x21, 0x68, 0x41, 0x61, 0xA1, 0x88, 0x01, 0x83, 0x00, 0xE0, + 0x07, 0x25, 0x28, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x38, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xFE, 0x4F, 0x8A, 0x46, 0xDD, 0xE9, 0x0D, 0x65, 0x04, 0x46, + 0x01, 0x46, 0x98, 0x46, 0x91, 0x46, 0x0C, 0x48, 0x0C, 0x9F, 0xFE, 0xF7, + 0x73, 0xFD, 0x88, 0xB1, 0x00, 0x97, 0x0A, 0x49, 0xCD, 0xE9, 0x01, 0x65, + 0x49, 0x68, 0x04, 0xEB, 0x44, 0x00, 0x01, 0xEB, 0x00, 0x10, 0x43, 0x46, + 0x00, 0x8A, 0x4A, 0x46, 0x51, 0x46, 0xEE, 0xF7, 0xBC, 0xFF, 0x00, 0x20, + 0xBD, 0xE8, 0xFE, 0x8F, 0x04, 0x20, 0xFB, 0xE7, 0x3C, 0xB2, 0x82, 0x00, + 0x60, 0x78, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46, 0x80, 0x78, 0x87, 0xB0, + 0x0D, 0x46, 0xC0, 0x06, 0x0B, 0xD5, 0x61, 0x78, 0x68, 0x46, 0xF1, 0xF7, + 0x41, 0xFD, 0x04, 0x98, 0xA8, 0x42, 0x07, 0xD0, 0x60, 0x78, 0x29, 0x46, + 0xF2, 0xF7, 0x40, 0xF8, 0x10, 0xB1, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD, + 0x01, 0x20, 0xFB, 0xE7, 0x08, 0xB5, 0x02, 0x21, 0x8D, 0xF8, 0x00, 0x10, + 0x00, 0xB1, 0x01, 0x20, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21, + 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0x52, 0xFA, 0x08, 0xB1, 0x00, 0x20, + 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x00, 0x00, 0x2D, 0xE9, 0xFC, 0x41, + 0x1E, 0x46, 0x17, 0x46, 0x04, 0x00, 0x0D, 0x46, 0x24, 0xD0, 0x13, 0x48, + 0xE3, 0xF7, 0x9C, 0xDA, 0xCD, 0xE9, 0x00, 0x07, 0x63, 0x78, 0x03, 0x22, + 0x10, 0x49, 0x11, 0x48, 0xE3, 0xF7, 0xC5, 0xD8, 0xA7, 0x73, 0x28, 0x68, + 0xA0, 0x60, 0xA8, 0x88, 0xA0, 0x81, 0x6E, 0xB1, 0x01, 0x20, 0x20, 0x71, + 0xE0, 0x7B, 0x40, 0xF0, 0x04, 0x00, 0xE0, 0x73, 0x61, 0x78, 0x04, 0xF1, + 0x08, 0x00, 0xF1, 0xF7, 0x13, 0xFF, 0x01, 0x20, 0xBD, 0xE8, 0xFC, 0x81, + 0x00, 0x20, 0x20, 0x71, 0xE0, 0x7B, 0x20, 0xF0, 0x04, 0x00, 0xF0, 0xE7, + 0x00, 0x20, 0xF5, 0xE7, 0x00, 0x00, 0x30, 0x21, 0x9C, 0x70, 0xC0, 0x08, + 0x02, 0x35, 0x10, 0x21, 0x30, 0xB5, 0x04, 0x46, 0x80, 0x78, 0x87, 0xB0, + 0x0D, 0x46, 0x80, 0x06, 0x0B, 0xD5, 0x61, 0x78, 0x68, 0x46, 0xF1, 0xF7, + 0x5F, 0xFD, 0x04, 0x98, 0xA8, 0x42, 0x07, 0xD0, 0x60, 0x78, 0x29, 0x46, + 0xF2, 0xF7, 0x0E, 0xF8, 0x10, 0xB1, 0x00, 0x20, 0x07, 0xB0, 0x30, 0xBD, + 0x01, 0x20, 0xFB, 0xE7, 0x1C, 0xB5, 0x03, 0x24, 0x8D, 0xF8, 0x00, 0x40, + 0x8D, 0xF8, 0x01, 0x00, 0x8D, 0xF8, 0x02, 0x10, 0x0C, 0x0A, 0x8D, 0xF8, + 0x03, 0x40, 0x14, 0x0A, 0x06, 0x23, 0x8D, 0xF8, 0x04, 0x20, 0x08, 0x43, + 0x8D, 0xF8, 0x05, 0x40, 0x10, 0x43, 0x00, 0xD1, 0x01, 0x23, 0x6A, 0x46, + 0x19, 0x46, 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0xE5, 0xF9, 0x08, 0xB1, + 0x00, 0x20, 0x1C, 0xBD, 0x07, 0x20, 0x1C, 0xBD, 0x08, 0xB5, 0x09, 0x21, + 0x8D, 0xF8, 0x00, 0x10, 0x8D, 0xF8, 0x01, 0x00, 0x6A, 0x46, 0x02, 0x21, + 0x4F, 0xF6, 0x80, 0x50, 0xF0, 0xF7, 0xD4, 0xF9, 0x08, 0xB1, 0x00, 0x20, + 0x08, 0xBD, 0x07, 0x20, 0x08, 0xBD, 0x10, 0xB5, 0xEF, 0xF7, 0x2A, 0xFF, + 0x08, 0xB1, 0x00, 0x20, 0x10, 0xBD, 0x07, 0x20, 0x10, 0xBD, 0xFE, 0xB5, + 0x00, 0x26, 0xDD, 0xE9, 0x08, 0x45, 0x8D, 0xE8, 0x70, 0x00, 0x00, 0xF0, + 0x0B, 0xF8, 0xFE, 0xBD, 0xFE, 0xB5, 0x08, 0xAF, 0x97, 0xE8, 0x70, 0x00, + 0x8D, 0xE8, 0x70, 0x00, 0x00, 0xF0, 0x02, 0xF8, 0xFE, 0xBD, 0x00, 0x00, + 0x2D, 0xE9, 0xF8, 0x4F, 0x1F, 0x46, 0x0A, 0xAB, 0x2A, 0x4E, 0x93, 0xE8, + 0x00, 0x07, 0x96, 0xF8, 0x00, 0xC0, 0x80, 0xF8, 0x00, 0xC0, 0x33, 0x78, + 0xB4, 0x78, 0x01, 0x25, 0x26, 0x48, 0xA3, 0x42, 0x05, 0xD3, 0x02, 0x22, + 0x25, 0x49, 0x00, 0x94, 0xE3, 0xF7, 0x29, 0xD8, 0x06, 0xE0, 0xF4, 0x78, + 0x3C, 0xB1, 0x22, 0x49, 0x00, 0x22, 0x4C, 0x31, 0xE3, 0xF7, 0x21, 0xD8, + 0x00, 0x20, 0xBD, 0xE8, 0xF8, 0x8F, 0x70, 0x68, 0xC3, 0xEB, 0xC3, 0x03, + 0x00, 0xEB, 0x83, 0x03, 0x83, 0xF8, 0x01, 0xC0, 0x33, 0x78, 0xC3, 0xEB, + 0xC3, 0x03, 0x00, 0xEB, 0x83, 0x03, 0x99, 0x60, 0x31, 0x78, 0xC1, 0xEB, + 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x4A, 0x80, 0x31, 0x78, 0xC1, 0xEB, + 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x01, 0x10, 0x31, 0x81, 0xE8, 0x80, 0x03, + 0x31, 0x78, 0xC1, 0xEB, 0xC1, 0x01, 0x00, 0xEB, 0x81, 0x00, 0xA0, 0xF8, + 0x04, 0xA0, 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0x0C, 0x48, 0x00, 0x78, + 0xC0, 0x07, 0x0D, 0xD0, 0x09, 0x49, 0x08, 0x48, 0x00, 0x22, 0x8C, 0x31, + 0x80, 0x1C, 0xE2, 0xF7, 0xEE, 0xDF, 0x00, 0xF0, 0x1B, 0xFC, 0x10, 0xB1, + 0x01, 0x20, 0xF0, 0x70, 0x00, 0xE0, 0x00, 0x25, 0x28, 0x46, 0xC4, 0xE7, + 0xB0, 0x78, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21, 0x18, 0x6A, 0xC0, 0x08, + 0x38, 0x78, 0x20, 0x00, 0x2D, 0xE9, 0xFE, 0x4F, 0x81, 0x46, 0xDD, 0xE9, + 0x0C, 0x67, 0x21, 0x48, 0x0C, 0x46, 0x9B, 0x46, 0x05, 0x88, 0x92, 0x46, + 0x49, 0x46, 0x1F, 0x48, 0xFE, 0xF7, 0x26, 0xFC, 0x00, 0x28, 0x29, 0xD0, + 0x1D, 0x49, 0xC4, 0xEB, 0xC4, 0x00, 0x49, 0x68, 0x01, 0xEB, 0x80, 0x08, + 0x6F, 0xB9, 0x29, 0x46, 0x30, 0x46, 0xEC, 0xF7, 0x63, 0xFE, 0x04, 0x00, + 0x05, 0xD0, 0x60, 0x19, 0x32, 0x46, 0x59, 0x46, 0x15, 0xF4, 0xCF, 0xF0, + 0x03, 0xE0, 0x40, 0xF2, 0x11, 0x47, 0x00, 0x24, 0x26, 0x46, 0xCD, 0xF8, + 0x00, 0xA0, 0xCD, 0xE9, 0x01, 0x65, 0x11, 0x49, 0x09, 0xEB, 0x49, 0x00, + 0xD8, 0xF8, 0x0C, 0x20, 0x09, 0x68, 0x3B, 0x46, 0x01, 0xEB, 0x00, 0x10, + 0x01, 0x8A, 0x20, 0x46, 0xEC, 0xF7, 0x20, 0xF8, 0x10, 0xB1, 0x01, 0x20, + 0xBD, 0xE8, 0xFE, 0x8F, 0x00, 0x22, 0x09, 0x49, 0x09, 0x48, 0xE2, 0xF7, + 0x9C, 0xDF, 0x14, 0xB1, 0x20, 0x46, 0xEB, 0xF7, 0x1D, 0xFE, 0x00, 0x20, + 0xF2, 0xE7, 0x00, 0x00, 0x46, 0x78, 0x20, 0x00, 0x17, 0xB3, 0x82, 0x00, + 0xB0, 0x78, 0x20, 0x00, 0x64, 0x78, 0x20, 0x00, 0xD0, 0x6A, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x46, 0xC1, 0xEB, + 0xC1, 0x00, 0x0F, 0x49, 0x1E, 0x46, 0x90, 0x46, 0x49, 0x68, 0x00, 0x25, + 0x01, 0xEB, 0x80, 0x07, 0x21, 0x46, 0x0C, 0x48, 0xFE, 0xF7, 0xD0, 0xFB, + 0x00, 0x28, 0x0E, 0xD0, 0x0A, 0x4A, 0x04, 0xEB, 0x44, 0x00, 0xF9, 0x68, + 0x12, 0x68, 0x43, 0x46, 0x02, 0xEB, 0x00, 0x10, 0x32, 0x46, 0x00, 0x8A, + 0xEC, 0xF7, 0xCE, 0xF9, 0x00, 0xB1, 0x01, 0x25, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x81, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x30, 0xB3, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, 0x00, 0x22, 0x03, 0x49, + 0x03, 0x48, 0xE2, 0xF7, 0x58, 0xDF, 0x03, 0x48, 0x04, 0x70, 0x10, 0xBD, + 0xD0, 0x69, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, 0x82, 0x74, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x01, 0x46, 0x09, 0x48, 0xFE, 0xF7, 0xA0, 0xFB, + 0x00, 0x28, 0x0B, 0xD0, 0x07, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x00, 0x22, + 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x11, 0x46, 0x00, 0x8A, 0xEB, 0xF7, + 0xF3, 0xFE, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, 0x4A, 0xB3, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x38, 0xB5, 0x0B, 0x49, 0x05, 0x46, 0x00, 0x24, + 0x49, 0x68, 0xC0, 0xEB, 0xC5, 0x00, 0x11, 0xEB, 0x80, 0x00, 0x03, 0xD0, + 0xC0, 0x68, 0xEC, 0xF7, 0xC7, 0xFD, 0x04, 0x46, 0x2B, 0x46, 0x02, 0x22, + 0x04, 0x49, 0x05, 0x48, 0x00, 0x94, 0xE2, 0xF7, 0x20, 0xDF, 0x20, 0x46, + 0x38, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x58, 0x6B, 0xC0, 0x08, + 0x02, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x0E, 0x46, 0x04, 0x46, 0x01, 0x46, + 0x15, 0x46, 0x0A, 0x48, 0xFE, 0xF7, 0x66, 0xFB, 0x00, 0x28, 0x0D, 0xD0, + 0x08, 0x49, 0x04, 0xEB, 0x44, 0x00, 0x0A, 0x68, 0x02, 0xEB, 0x00, 0x12, + 0x52, 0x6A, 0x32, 0x60, 0x09, 0x68, 0x01, 0xEB, 0x00, 0x10, 0x40, 0x8C, + 0x28, 0x80, 0x01, 0x20, 0x70, 0xBD, 0x00, 0x00, 0x75, 0xB3, 0x82, 0x00, + 0x64, 0x78, 0x20, 0x00, 0x10, 0xB5, 0x41, 0x88, 0x01, 0x24, 0xB1, 0xF5, + 0x86, 0x7F, 0x2F, 0xD0, 0x09, 0xDC, 0xA1, 0xF2, 0x03, 0x11, 0x08, 0x29, + 0x31, 0xD2, 0xDF, 0xE8, 0x01, 0xF0, 0x11, 0x30, 0x15, 0x19, 0x30, 0x1D, + 0x30, 0x21, 0xB1, 0xF5, 0x87, 0x7F, 0x25, 0xD0, 0xB1, 0xF5, 0x88, 0x7F, + 0x16, 0xD0, 0xA1, 0xF5, 0x80, 0x71, 0x11, 0x39, 0x16, 0xD0, 0xA6, 0x29, + 0x1F, 0xD1, 0x0F, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x91, 0xFA, 0x1A, 0xE0, + 0x00, 0x1D, 0x00, 0xF0, 0x77, 0xF9, 0x16, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0xB1, 0xF9, 0x12, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x0F, 0xF9, 0x0E, 0xE0, + 0x00, 0xF0, 0xCC, 0xF9, 0x04, 0x46, 0x0A, 0xE0, 0x00, 0x1D, 0x00, 0xF0, + 0x45, 0xFA, 0x06, 0xE0, 0x00, 0x1D, 0x00, 0xF0, 0x75, 0xF8, 0x02, 0xE0, + 0x00, 0x1D, 0x00, 0xF0, 0x03, 0xF8, 0x20, 0x46, 0x10, 0xBD, 0x00, 0x00, + 0x2D, 0xE9, 0xFF, 0x47, 0x00, 0x26, 0x80, 0x46, 0x03, 0x96, 0xB1, 0x46, + 0xB2, 0x46, 0x34, 0x46, 0x37, 0x46, 0x00, 0x88, 0xFE, 0xF7, 0xA2, 0xFB, + 0x05, 0x00, 0x4F, 0xF4, 0x90, 0x61, 0x02, 0xD0, 0x68, 0x78, 0x02, 0x28, + 0x00, 0xD0, 0x0E, 0x46, 0x98, 0xF8, 0x02, 0x00, 0x08, 0xB1, 0x16, 0xB1, + 0x22, 0xE0, 0x00, 0x26, 0x2C, 0xE0, 0xE8, 0x6A, 0x48, 0xB3, 0x04, 0x46, + 0x40, 0x88, 0x18, 0xB1, 0x06, 0x46, 0xB4, 0xF8, 0x06, 0x90, 0x17, 0xE0, + 0x21, 0x49, 0x20, 0x78, 0x49, 0x68, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xEB, + 0x80, 0x07, 0xD7, 0xF8, 0x14, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x17, 0xD0, + 0x20, 0x89, 0x03, 0xAA, 0x04, 0xF1, 0x0A, 0x01, 0x8D, 0xE8, 0x07, 0x00, + 0xA2, 0x88, 0x79, 0x78, 0xE8, 0x78, 0x03, 0x23, 0xE0, 0x47, 0x06, 0x46, + 0xA6, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x07, 0xD1, 0x00, 0x22, 0x14, 0x49, + 0x14, 0x48, 0xE2, 0xF7, 0x74, 0xDE, 0xBD, 0xE8, 0xFF, 0x87, 0x0E, 0x46, + 0xB8, 0xF8, 0x00, 0x00, 0x4A, 0x46, 0x31, 0x46, 0xEB, 0xF7, 0x22, 0xFE, + 0x03, 0x9E, 0x66, 0xB1, 0x00, 0x2D, 0xF2, 0xD0, 0x5F, 0xB1, 0x54, 0xB1, + 0x04, 0xF1, 0x0A, 0x00, 0x00, 0x90, 0x23, 0x89, 0xA2, 0x88, 0x79, 0x78, + 0xE8, 0x78, 0xB0, 0x47, 0x01, 0xE0, 0x00, 0x2D, 0xE5, 0xD0, 0xE8, 0x6A, + 0x00, 0x28, 0xE2, 0xD0, 0xED, 0xF7, 0x49, 0xDC, 0xC5, 0xF8, 0x2C, 0xA0, + 0xDD, 0xE7, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0xC4, 0x6E, 0xC0, 0x08, + 0x02, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F, 0x04, 0x46, 0x41, 0x48, + 0x21, 0x8A, 0x67, 0x89, 0x06, 0x88, 0x04, 0xF1, 0x12, 0x00, 0x08, 0x44, + 0x00, 0x90, 0x4F, 0xF0, 0x00, 0x0A, 0x20, 0x88, 0xFE, 0xF7, 0x30, 0xFB, + 0x80, 0x46, 0x60, 0x68, 0x05, 0xF0, 0x50, 0xF8, 0x5F, 0xEA, 0x00, 0x09, + 0x40, 0xF2, 0x11, 0x4B, 0x45, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x42, 0xD0, + 0xD8, 0xF8, 0x2C, 0x50, 0x5D, 0xB1, 0x29, 0x78, 0x99, 0xF8, 0x01, 0x00, + 0x81, 0x42, 0x03, 0xD1, 0xA8, 0x88, 0x21, 0x89, 0x88, 0x42, 0x15, 0xD0, + 0x4F, 0xF4, 0x90, 0x60, 0x27, 0xE0, 0x40, 0xF2, 0x07, 0x43, 0x2D, 0x4A, + 0x40, 0xF2, 0x0A, 0x21, 0x00, 0x20, 0xED, 0xF7, 0xAD, 0xDB, 0xC8, 0xF8, + 0x2C, 0x00, 0x50, 0xB1, 0x99, 0xF8, 0x01, 0x10, 0x01, 0x70, 0x21, 0x89, + 0x81, 0x80, 0xA1, 0x89, 0x05, 0x46, 0xC1, 0x80, 0x68, 0x88, 0x20, 0xB1, + 0x1D, 0xE0, 0x00, 0x25, 0xDA, 0x46, 0x2F, 0x46, 0x26, 0xE0, 0xE0, 0x89, + 0x4F, 0xF4, 0x00, 0x72, 0x90, 0x42, 0x02, 0xD3, 0x40, 0xF2, 0x07, 0x40, + 0x05, 0xE0, 0x61, 0x89, 0x01, 0x44, 0x91, 0x42, 0x03, 0xD9, 0x40, 0xF2, + 0x0D, 0x40, 0x68, 0x80, 0x09, 0xE0, 0x05, 0xF1, 0x0A, 0x01, 0x08, 0x44, + 0x3A, 0x46, 0x00, 0x99, 0x14, 0xF4, 0x03, 0xF7, 0xE0, 0x89, 0x38, 0x44, + 0x28, 0x81, 0x76, 0x1D, 0xB6, 0xB2, 0x31, 0x46, 0x38, 0x46, 0xEC, 0xF7, + 0x87, 0xFC, 0x05, 0x00, 0xD9, 0xD0, 0xA8, 0x19, 0x3A, 0x46, 0x00, 0x99, + 0x14, 0xF4, 0xF3, 0xF6, 0x20, 0x89, 0xCD, 0xE9, 0x00, 0x07, 0x02, 0x96, + 0x21, 0x88, 0x53, 0x46, 0x28, 0x46, 0x62, 0x68, 0xEB, 0xF7, 0xD8, 0xFD, + 0x00, 0x28, 0x0B, 0xD1, 0x00, 0x22, 0x08, 0x49, 0x08, 0x48, 0xE2, 0xF7, + 0xCE, 0xDD, 0x00, 0x2D, 0x04, 0xD0, 0x28, 0x46, 0xBD, 0xE8, 0xFE, 0x4F, + 0xEB, 0xF7, 0x4C, 0xBC, 0xBD, 0xE8, 0xFE, 0x8F, 0x46, 0x78, 0x20, 0x00, + 0x96, 0xB3, 0x82, 0x00, 0x84, 0x6E, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x86, 0xB0, 0x04, 0x46, 0x4F, 0xF0, 0x00, 0x08, + 0x29, 0x48, 0xAD, 0xF8, 0x0C, 0x80, 0xCD, 0xF8, 0x10, 0x80, 0x07, 0x88, + 0x60, 0x68, 0x04, 0xF0, 0xC7, 0xFF, 0xC0, 0xB1, 0x04, 0xAA, 0x03, 0xA9, + 0xCD, 0xE9, 0x00, 0x12, 0x41, 0x78, 0x63, 0x89, 0x22, 0x89, 0x20, 0x88, + 0x04, 0xF0, 0xE4, 0xFF, 0xA0, 0xF5, 0x50, 0x61, 0x05, 0x46, 0x01, 0x39, + 0x01, 0xD0, 0x5D, 0xB1, 0x1A, 0xE0, 0x00, 0x22, 0x1C, 0x49, 0x1D, 0x48, + 0xE2, 0xF7, 0x97, 0xDD, 0x06, 0xB0, 0xBD, 0xE8, 0xF0, 0x81, 0x4F, 0xF4, + 0x90, 0x65, 0x0F, 0xE0, 0x39, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0xEC, 0xF7, + 0x2D, 0xFC, 0x06, 0x00, 0x06, 0xD0, 0xF0, 0x19, 0xBD, 0xF8, 0x0C, 0x20, + 0x04, 0x99, 0x14, 0xF4, 0x98, 0xF6, 0x04, 0xE0, 0x40, 0xF2, 0x11, 0x45, + 0x00, 0x26, 0xAD, 0xF8, 0x0C, 0x80, 0x20, 0x89, 0xBD, 0xF8, 0x0C, 0x10, + 0x8D, 0xE8, 0x83, 0x00, 0x21, 0x88, 0x2B, 0x46, 0x30, 0x46, 0x62, 0x68, + 0xEB, 0xF7, 0xEE, 0xFD, 0x00, 0x28, 0xD9, 0xD1, 0x07, 0x49, 0x08, 0x48, + 0x00, 0x22, 0x30, 0x31, 0x80, 0x1E, 0xE2, 0xF7, 0x6A, 0xDD, 0x00, 0x2E, + 0xD0, 0xD0, 0x30, 0x46, 0xEB, 0xF7, 0xEA, 0xFB, 0xCC, 0xE7, 0x00, 0x00, + 0x46, 0x78, 0x20, 0x00, 0x48, 0x6D, 0xC0, 0x08, 0x02, 0x33, 0x10, 0x21, + 0xF8, 0xB5, 0x04, 0x46, 0x00, 0x68, 0x04, 0xF0, 0x71, 0xFF, 0x19, 0x4E, + 0x05, 0x46, 0x30, 0x78, 0x40, 0x1C, 0x30, 0x70, 0x20, 0x89, 0xFE, 0xF7, + 0x45, 0xFA, 0xB8, 0xB1, 0xB5, 0xB1, 0xC7, 0x78, 0x30, 0x78, 0x00, 0x90, + 0x3B, 0x46, 0x02, 0x22, 0x12, 0x49, 0x13, 0x48, 0xE2, 0xF7, 0x45, 0xDD, + 0xA3, 0x89, 0xB3, 0xB1, 0xA3, 0xF5, 0x40, 0x60, 0x0C, 0x38, 0x06, 0xD0, + 0x30, 0x78, 0x00, 0x90, 0x62, 0x89, 0x68, 0x78, 0x39, 0x46, 0x04, 0xF0, + 0xE9, 0xFF, 0xF8, 0xBD, 0x33, 0x78, 0x01, 0xB0, 0x08, 0x49, 0xBD, 0xE8, + 0xF0, 0x40, 0x08, 0x48, 0x01, 0x22, 0x44, 0x39, 0xC0, 0x1E, 0xE2, 0xF7, + 0x2C, 0x9D, 0x30, 0x78, 0x00, 0x90, 0x62, 0x89, 0x68, 0x78, 0x00, 0x23, + 0xEA, 0xE7, 0x00, 0x00, 0x60, 0x78, 0x20, 0x00, 0x04, 0x6D, 0xC0, 0x08, + 0x03, 0x33, 0x10, 0x21, 0xF8, 0xB5, 0x04, 0x46, 0x00, 0x68, 0x04, 0xF0, + 0x33, 0xFF, 0x06, 0x46, 0x20, 0x89, 0xFE, 0xF7, 0x0B, 0xFA, 0xD4, 0xE9, + 0x00, 0x12, 0x05, 0x46, 0x63, 0x89, 0x20, 0x89, 0xEB, 0xF7, 0xF1, 0xFE, + 0x00, 0x2D, 0x0C, 0xD0, 0x00, 0x2E, 0x0A, 0xD0, 0x05, 0x48, 0xA3, 0x89, + 0x00, 0x78, 0x00, 0x90, 0x62, 0x89, 0xE9, 0x78, 0x70, 0x78, 0x03, 0xB9, + 0x00, 0x23, 0x04, 0xF0, 0xB1, 0xFF, 0xF8, 0xBD, 0x60, 0x78, 0x20, 0x00, + 0x2D, 0xE9, 0xF0, 0x4F, 0x89, 0xB0, 0x04, 0x46, 0xB0, 0xF8, 0x02, 0x90, + 0x01, 0x1D, 0x14, 0x22, 0x03, 0xA8, 0x14, 0xF4, 0x4B, 0xF6, 0x00, 0x20, + 0x08, 0x90, 0x40, 0xF2, 0x04, 0x46, 0x4F, 0xF0, 0x01, 0x0A, 0x14, 0x22, + 0x21, 0x1D, 0x03, 0xA8, 0x14, 0xF4, 0x40, 0xF6, 0xA1, 0x8A, 0x04, 0xF1, + 0x16, 0x00, 0x01, 0xEB, 0x00, 0x08, 0x04, 0x98, 0x04, 0xF0, 0xF8, 0xFE, + 0x07, 0x46, 0xBD, 0xF8, 0x0C, 0x00, 0xFE, 0xF7, 0xCF, 0xF9, 0x05, 0x46, + 0x4F, 0xF4, 0x85, 0x7B, 0x27, 0xB1, 0x1D, 0xB1, 0xD9, 0x45, 0x04, 0xD1, + 0x00, 0x23, 0x07, 0xE0, 0x4F, 0xF4, 0x90, 0x66, 0x1E, 0xE0, 0xA9, 0xF5, + 0x80, 0x71, 0xB7, 0x39, 0x13, 0xD0, 0x01, 0x23, 0xA8, 0xEB, 0x04, 0x00, + 0x6C, 0x62, 0x68, 0x84, 0x7C, 0x69, 0x74, 0xB1, 0xBD, 0xF8, 0x16, 0x10, + 0x08, 0xAA, 0x00, 0x91, 0xCD, 0xE9, 0x01, 0x82, 0xBD, 0xF8, 0x14, 0x20, + 0x79, 0x78, 0xE8, 0x78, 0xA0, 0x47, 0x06, 0x46, 0x06, 0xE0, 0x02, 0x23, + 0xEA, 0xE7, 0x00, 0x22, 0x17, 0x49, 0x18, 0x48, 0xE2, 0xF7, 0xAF, 0xDC, + 0xD9, 0x45, 0x0C, 0xD1, 0xA6, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x14, 0xD0, + 0xBD, 0xF8, 0x14, 0x30, 0xBD, 0xF8, 0x0C, 0x00, 0x32, 0x46, 0x04, 0x99, + 0xEB, 0xF7, 0x04, 0xFF, 0x0B, 0xE0, 0xA6, 0xF5, 0x50, 0x60, 0x05, 0x38, + 0x07, 0xD1, 0x0C, 0x49, 0x00, 0x22, 0x48, 0x31, 0x0B, 0x48, 0xE2, 0xF7, + 0x96, 0xDC, 0x4F, 0xF0, 0x00, 0x0A, 0x08, 0x9C, 0x4C, 0xB1, 0x45, 0xB1, + 0xCD, 0xF8, 0x00, 0x80, 0xBD, 0xF8, 0x16, 0x30, 0xBD, 0xF8, 0x14, 0x20, + 0x79, 0x78, 0xE8, 0x78, 0xA0, 0x47, 0x09, 0xB0, 0x50, 0x46, 0xBD, 0xE8, + 0xF0, 0x8F, 0x00, 0x00, 0xB4, 0x6D, 0xC0, 0x08, 0x00, 0x33, 0x10, 0x21, + 0x2D, 0xE9, 0xFC, 0x47, 0x07, 0x46, 0x40, 0x68, 0x04, 0xF0, 0x92, 0xFE, + 0x05, 0x46, 0x38, 0x88, 0xFE, 0xF7, 0x6A, 0xF9, 0x80, 0x46, 0x00, 0x2D, + 0x24, 0xD0, 0xB8, 0xF1, 0x00, 0x0F, 0x21, 0xD0, 0x79, 0x89, 0x07, 0xF1, + 0x0C, 0x00, 0x0C, 0x18, 0x00, 0x26, 0x18, 0xE0, 0x34, 0xF8, 0x02, 0xAB, + 0x03, 0x22, 0x34, 0xF8, 0x02, 0x9B, 0x0C, 0x49, 0xCD, 0xE9, 0x00, 0xA9, + 0x6B, 0x78, 0x0B, 0x48, 0xE2, 0xF7, 0x5D, 0xDC, 0xD5, 0xF8, 0x18, 0xC0, + 0xBC, 0xF1, 0x00, 0x0F, 0x05, 0xD0, 0x69, 0x78, 0x98, 0xF8, 0x03, 0x00, + 0x4B, 0x46, 0x52, 0x46, 0xE0, 0x47, 0x76, 0x1C, 0xF6, 0xB2, 0x38, 0x89, + 0xB0, 0x42, 0xE3, 0xD8, 0xBD, 0xE8, 0xFC, 0x87, 0x44, 0x6E, 0xC0, 0x08, + 0x02, 0x33, 0x10, 0x21, 0x70, 0xB5, 0x1E, 0x4C, 0x06, 0x46, 0x00, 0x20, + 0xE1, 0x78, 0x01, 0xB1, 0x02, 0x20, 0x1B, 0x49, 0xB3, 0x88, 0x00, 0x25, + 0x4A, 0x78, 0x53, 0xB1, 0xE5, 0x70, 0x01, 0x21, 0x04, 0xF0, 0xD4, 0xFE, + 0x60, 0x78, 0x61, 0x68, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0xF8, 0x20, 0x50, + 0x70, 0xBD, 0x63, 0x68, 0xC2, 0xEB, 0xC2, 0x02, 0x03, 0xEB, 0x82, 0x02, + 0x31, 0x68, 0xD1, 0x60, 0x61, 0x78, 0x49, 0x1C, 0xC9, 0xB2, 0x61, 0x70, + 0xE2, 0x78, 0x42, 0xB1, 0xE5, 0x70, 0xB3, 0x88, 0xBD, 0xE8, 0x70, 0x40, + 0x49, 0x1E, 0xCA, 0xB2, 0x00, 0x21, 0x04, 0xF0, 0xB7, 0xBE, 0x22, 0x78, + 0x91, 0x42, 0x09, 0xD1, 0x49, 0x1E, 0xCA, 0xB2, 0xB3, 0x88, 0x00, 0x21, + 0x04, 0xF0, 0xAE, 0xFE, 0xBD, 0xE8, 0x70, 0x40, 0xF2, 0xF7, 0x2E, 0xB9, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x38, 0xB8, 0xB0, 0x78, 0x20, 0x00, + 0x70, 0xB5, 0x04, 0x46, 0xEB, 0xF7, 0xC6, 0xFA, 0xC0, 0xB1, 0x10, 0x4D, + 0x28, 0x78, 0x08, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0x0E, 0x4E, 0xC4, 0xEB, + 0xC4, 0x00, 0x81, 0x00, 0xB4, 0x70, 0x53, 0x23, 0x0C, 0x4A, 0x00, 0x20, + 0xED, 0xF7, 0x88, 0xD9, 0x70, 0x60, 0x00, 0x28, 0x0D, 0xD0, 0x28, 0x78, + 0x00, 0x28, 0x0A, 0xD0, 0xBD, 0xE8, 0x70, 0x40, 0xF2, 0xF7, 0x60, 0xBA, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0x22, 0x05, 0x49, 0x05, 0x48, 0xE2, 0xF7, + 0xE2, 0x9B, 0x70, 0xBD, 0x82, 0x74, 0x20, 0x00, 0xB0, 0x78, 0x20, 0x00, + 0x0B, 0xB3, 0x82, 0x00, 0xF0, 0x69, 0xC0, 0x08, 0x00, 0x35, 0x10, 0x21, + 0x01, 0x49, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, + 0xF8, 0xB5, 0x1A, 0x4D, 0x00, 0x24, 0xA8, 0x78, 0x28, 0xB9, 0x19, 0x48, + 0x00, 0x78, 0x50, 0xB3, 0x00, 0x20, 0xFF, 0xF7, 0xBF, 0xFF, 0x6B, 0x78, + 0x69, 0x68, 0xC3, 0xEB, 0xC3, 0x00, 0x01, 0xEB, 0x80, 0x01, 0x14, 0x4E, + 0x88, 0x68, 0x58, 0xB1, 0xA8, 0x78, 0x83, 0x42, 0x01, 0xD2, 0x0A, 0x78, + 0x6A, 0xB1, 0x00, 0x90, 0x02, 0x22, 0x10, 0x49, 0x30, 0x46, 0xE2, 0xF7, + 0xB2, 0xDB, 0x12, 0xE0, 0x0D, 0x49, 0x01, 0x22, 0x54, 0x39, 0x30, 0x46, + 0xE2, 0xF7, 0xAB, 0xDB, 0x0B, 0xE0, 0x01, 0x20, 0x08, 0x70, 0x48, 0x88, + 0x1C, 0x22, 0xB0, 0xFB, 0xF2, 0xF0, 0x8A, 0x88, 0x89, 0x68, 0xEC, 0xF7, + 0x0D, 0xF9, 0x00, 0xB1, 0x01, 0x24, 0x20, 0x46, 0xF8, 0xBD, 0x00, 0x00, + 0xB0, 0x78, 0x20, 0x00, 0x82, 0x74, 0x20, 0x00, 0x00, 0x33, 0x10, 0x21, + 0xEC, 0x6B, 0xC0, 0x08, 0x2D, 0xE9, 0xFF, 0x4F, 0x85, 0xB0, 0x0D, 0x46, + 0x1F, 0x46, 0x3C, 0x48, 0x12, 0x9C, 0x05, 0x99, 0xFD, 0xF7, 0xE0, 0xFF, + 0x78, 0xB1, 0xDF, 0xF8, 0xE8, 0xB0, 0x05, 0x98, 0xDB, 0xF8, 0x00, 0x10, + 0x00, 0xEB, 0x40, 0x09, 0x01, 0xEB, 0x09, 0x10, 0x40, 0x8A, 0xC0, 0x1E, + 0x80, 0xB2, 0x84, 0x42, 0x03, 0xD9, 0x02, 0x23, 0x58, 0xE0, 0x01, 0x23, + 0x56, 0xE0, 0xDF, 0xF8, 0xC8, 0xA0, 0x9A, 0xF8, 0x00, 0x00, 0x28, 0xB1, + 0x30, 0x48, 0x81, 0x78, 0x8D, 0x42, 0x03, 0xD3, 0x04, 0x23, 0x4B, 0xE0, + 0x03, 0x23, 0x49, 0xE0, 0x40, 0x68, 0xC5, 0xEB, 0xC5, 0x01, 0x00, 0xEB, + 0x81, 0x08, 0x2B, 0x48, 0x2B, 0x49, 0x00, 0x25, 0x00, 0x88, 0x0B, 0x88, + 0x1C, 0xB1, 0x17, 0xB1, 0xC0, 0x1C, 0x86, 0xB2, 0x02, 0xE0, 0x00, 0x26, + 0x6F, 0xB1, 0x6C, 0xB1, 0x32, 0x46, 0x21, 0x46, 0x18, 0x46, 0xEB, 0xF7, + 0xC9, 0xF9, 0x05, 0x00, 0x29, 0xD0, 0xA8, 0x19, 0x22, 0x46, 0x39, 0x46, + 0x14, 0xF4, 0x5F, 0xF4, 0x00, 0xE0, 0x00, 0x24, 0x07, 0x99, 0x13, 0x98, + 0xCD, 0xE9, 0x00, 0x14, 0xCD, 0xE9, 0x02, 0x60, 0xDB, 0xF8, 0x00, 0x10, + 0xD8, 0xF8, 0x0C, 0x20, 0x01, 0xEB, 0x09, 0x10, 0x00, 0x23, 0x01, 0x8A, + 0x28, 0x46, 0xEB, 0xF7, 0xBD, 0xFC, 0x90, 0xB1, 0x9A, 0xF8, 0x00, 0x00, + 0x02, 0x22, 0x40, 0x1E, 0xC0, 0xB2, 0x8A, 0xF8, 0x00, 0x00, 0x00, 0x90, + 0x12, 0x49, 0x13, 0x48, 0x05, 0x9B, 0xE2, 0xF7, 0x2A, 0xDB, 0x01, 0x20, + 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x05, 0x23, 0x04, 0xE0, 0x15, 0xB1, + 0x28, 0x46, 0xEB, 0xF7, 0xA5, 0xF9, 0x06, 0x23, 0x0A, 0x49, 0x0B, 0x48, + 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xE2, 0xF7, 0x18, 0xDB, 0x00, 0x20, + 0xEC, 0xE7, 0x00, 0x00, 0x64, 0xB3, 0x82, 0x00, 0x64, 0x78, 0x20, 0x00, + 0x60, 0x78, 0x20, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x46, 0x78, 0x20, 0x00, + 0x44, 0x78, 0x20, 0x00, 0xFC, 0x6A, 0xC0, 0x08, 0x03, 0x33, 0x10, 0x21, + 0x70, 0xB5, 0x04, 0x46, 0x0E, 0x48, 0x00, 0x21, 0xC2, 0x69, 0x0E, 0x48, + 0x90, 0xF8, 0xAA, 0x31, 0x07, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x02, 0xEB, + 0x40, 0x00, 0x05, 0x78, 0x55, 0xB1, 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42, + 0xF5, 0xD8, 0x00, 0x22, 0x07, 0x49, 0x08, 0x48, 0xE2, 0xF7, 0xED, 0xDA, + 0x00, 0x20, 0x70, 0xBD, 0x21, 0x68, 0x01, 0x60, 0xA1, 0x88, 0x81, 0x80, + 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0xE8, 0x42, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, + 0x0F, 0x46, 0x06, 0x46, 0x15, 0x48, 0x16, 0x49, 0x00, 0x24, 0x40, 0x68, + 0x91, 0xF8, 0x98, 0x11, 0x07, 0xE0, 0xC4, 0xEB, 0xC4, 0x02, 0x00, 0xEB, + 0x02, 0x15, 0x2A, 0x79, 0x82, 0xB1, 0x64, 0x1C, 0xE4, 0xB2, 0xA1, 0x42, + 0xF5, 0xD8, 0x31, 0x46, 0x0E, 0x48, 0xE2, 0xF7, 0x93, 0xDC, 0x03, 0x46, + 0x01, 0x22, 0x0D, 0x49, 0x0D, 0x48, 0xE2, 0xF7, 0xBE, 0xDA, 0x00, 0x20, + 0xBD, 0xE8, 0xF0, 0x81, 0x70, 0x21, 0x28, 0x46, 0x14, 0xF4, 0x6C, 0xF4, + 0x01, 0x20, 0x28, 0x71, 0x6C, 0x71, 0xAF, 0x74, 0x30, 0x68, 0xE8, 0x60, + 0xB0, 0x88, 0x28, 0x82, 0x28, 0x46, 0xEF, 0xE7, 0x88, 0x76, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0x00, 0x00, 0x30, 0x21, 0x40, 0x41, 0xC0, 0x08, + 0x00, 0x39, 0x10, 0x21, 0x38, 0xB5, 0x04, 0x46, 0x03, 0x79, 0x00, 0x6A, + 0x03, 0xB1, 0x38, 0xB1, 0x00, 0x90, 0x02, 0x22, 0x27, 0x49, 0x28, 0x48, + 0xE2, 0xF7, 0x97, 0xDA, 0x00, 0x20, 0x38, 0xBD, 0x27, 0x4D, 0x40, 0xF2, + 0x29, 0x23, 0x25, 0x4A, 0x88, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x22, 0xF8, + 0x20, 0x62, 0x38, 0xB3, 0x88, 0x21, 0x14, 0xF4, 0x3D, 0xF4, 0x40, 0xF2, + 0x2E, 0x23, 0x1F, 0x4A, 0x84, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x16, 0xF8, + 0x21, 0x6A, 0x48, 0x60, 0x84, 0x21, 0x14, 0xF4, 0x31, 0xF4, 0x40, 0xF2, + 0x31, 0x23, 0x19, 0x4A, 0x80, 0x21, 0x28, 0x78, 0xEA, 0xF7, 0x0A, 0xF8, + 0x21, 0x6A, 0xC8, 0x63, 0x80, 0x21, 0x14, 0xF4, 0x03, 0xF4, 0x21, 0x6A, + 0x48, 0x68, 0x58, 0xB1, 0xC9, 0x6B, 0x49, 0xB1, 0x84, 0x21, 0x14, 0xF4, + 0x1D, 0xF4, 0x20, 0x6A, 0x80, 0x21, 0xC0, 0x6B, 0x14, 0xF4, 0xF6, 0xF3, + 0x20, 0x6A, 0x38, 0xBD, 0x40, 0xF2, 0x35, 0x22, 0x0B, 0x49, 0xEA, 0xF7, + 0xDF, 0xF8, 0x20, 0x6A, 0x40, 0xF2, 0x36, 0x22, 0x08, 0x49, 0xC0, 0x6B, + 0xEA, 0xF7, 0xD8, 0xF8, 0x40, 0xF2, 0x37, 0x22, 0x05, 0x49, 0x20, 0x6A, + 0xEA, 0xF7, 0xD2, 0xF8, 0x00, 0x20, 0x20, 0x62, 0xE8, 0xE7, 0x00, 0x00, + 0x94, 0x42, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0xA4, 0xAA, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x3E, 0xB5, 0x04, 0x46, 0x0D, 0x46, 0x90, 0xF8, + 0x24, 0x00, 0xA1, 0x68, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95, 0xA3, 0x7C, + 0x04, 0x22, 0x1E, 0x49, 0x1E, 0x48, 0xE2, 0xF7, 0x34, 0xDA, 0x60, 0x8B, + 0xF4, 0xF7, 0xAC, 0xFD, 0x25, 0xB1, 0x2A, 0x46, 0x0A, 0x21, 0x20, 0x46, + 0x00, 0xF0, 0xD0, 0xF8, 0xA0, 0x7C, 0x28, 0xB1, 0x02, 0x28, 0x03, 0xD0, + 0x03, 0x28, 0x01, 0xD0, 0x01, 0x28, 0x12, 0xD1, 0x94, 0xF8, 0x24, 0x00, + 0x02, 0x28, 0x01, 0xD0, 0x03, 0x28, 0x06, 0xD1, 0xE2, 0x79, 0xA1, 0x79, + 0x2B, 0x46, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7, 0x8B, 0xFE, 0x20, 0x46, + 0xEA, 0xF7, 0xBC, 0xFF, 0x20, 0x46, 0x02, 0xF0, 0xCB, 0xFF, 0xA0, 0x68, + 0x0B, 0x49, 0x20, 0xF4, 0x80, 0x50, 0xA0, 0x60, 0x00, 0x20, 0x84, 0xF8, + 0x24, 0x00, 0x84, 0xF8, 0x6B, 0x00, 0x4F, 0xF6, 0xFF, 0x70, 0x88, 0x85, + 0x00, 0xF0, 0x8C, 0xF9, 0x60, 0x8B, 0xBD, 0xE8, 0x3E, 0x40, 0xF7, 0xF7, + 0x43, 0xBE, 0x00, 0x00, 0x40, 0x42, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x88, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x40, 0xF2, 0x03, 0x45, + 0xDD, 0xE9, 0x0A, 0x46, 0xAD, 0xF8, 0x00, 0x50, 0x05, 0x68, 0x01, 0x95, + 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, 0xAD, 0xF8, 0x0E, 0x20, 0xAD, 0xF8, + 0x10, 0x30, 0x09, 0x48, 0xAD, 0xF8, 0x0C, 0x10, 0x8D, 0xF8, 0x0A, 0x40, + 0x8D, 0xF8, 0x12, 0x60, 0x40, 0xF2, 0x6D, 0x13, 0x03, 0x4A, 0x69, 0x46, + 0x00, 0x78, 0xEA, 0xF7, 0x71, 0xFA, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00, + 0xE7, 0xA8, 0x82, 0x00, 0x84, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0D, 0x49, + 0x00, 0x68, 0x08, 0x60, 0x08, 0x88, 0x02, 0x07, 0x11, 0xD5, 0x01, 0x22, + 0x4A, 0x75, 0x80, 0x05, 0x01, 0xD5, 0x02, 0x20, 0x48, 0x75, 0x4B, 0x7D, + 0x01, 0x22, 0x07, 0x49, 0x07, 0x48, 0xE2, 0xF7, 0xBC, 0xD9, 0x00, 0x21, + 0xBD, 0xE8, 0x10, 0x40, 0x11, 0x20, 0xEF, 0xF7, 0xCA, 0xB9, 0x00, 0x20, + 0xF0, 0xE7, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x70, 0x22, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x00, 0x78, 0x00, 0x24, + 0x00, 0x28, 0x28, 0x46, 0x0C, 0xD0, 0x00, 0xF0, 0xF2, 0xF8, 0x30, 0xB1, + 0x28, 0x46, 0xFF, 0xF7, 0x9B, 0xFE, 0x40, 0xB9, 0x40, 0xF2, 0xE2, 0x54, + 0x05, 0xE0, 0x40, 0xF2, 0xE3, 0x54, 0x02, 0xE0, 0x02, 0xF0, 0x3A, 0xFF, + 0x04, 0x46, 0x20, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x41, 0x1C, 0x02, 0xD0, + 0x04, 0x49, 0x88, 0x42, 0x03, 0xD2, 0x04, 0x49, 0x08, 0x62, 0x00, 0x20, + 0x70, 0x47, 0xE3, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x42, 0x0F, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x03, 0x49, 0x02, 0x68, 0xC1, 0xF8, 0x2E, 0x20, + 0x80, 0x88, 0x48, 0x86, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x01, 0x49, 0x88, 0x75, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x0A, 0x4B, 0x19, 0x46, 0x18, 0x76, 0x11, 0xF8, 0x59, 0x2F, 0x49, 0x78, + 0x30, 0xB1, 0x42, 0xF0, 0x04, 0x00, 0x03, 0xF8, 0x59, 0x0F, 0x41, 0xF0, + 0x04, 0x00, 0x05, 0xE0, 0x22, 0xF0, 0x04, 0x00, 0x03, 0xF8, 0x59, 0x0F, + 0x21, 0xF0, 0x04, 0x00, 0x58, 0x70, 0x70, 0x47, 0x88, 0x76, 0x20, 0x00, + 0xFE, 0xB5, 0x15, 0x46, 0x04, 0x00, 0x0E, 0x46, 0x4F, 0xF0, 0x00, 0x07, + 0x35, 0xD0, 0x94, 0xF8, 0x25, 0x00, 0x0B, 0x46, 0xCD, 0xE9, 0x00, 0x50, + 0x03, 0x22, 0x28, 0x49, 0x28, 0x48, 0xE2, 0xF7, 0x4A, 0xD9, 0xA6, 0xF1, + 0x09, 0x00, 0x00, 0x22, 0x04, 0xF1, 0x0C, 0x01, 0x0D, 0x28, 0x2D, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0x24, 0x24, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x07, + 0x07, 0x07, 0x07, 0x1B, 0x14, 0x00, 0x94, 0xF8, 0x25, 0x00, 0x00, 0x28, + 0x17, 0xD1, 0x84, 0xF8, 0x25, 0x60, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92, + 0x00, 0x23, 0xA2, 0x7C, 0x03, 0x20, 0x22, 0xE0, 0x94, 0xF8, 0x25, 0x00, + 0x12, 0x28, 0x15, 0xD0, 0x11, 0x28, 0x13, 0xD0, 0x05, 0xE0, 0x94, 0xF8, + 0x25, 0x00, 0x11, 0x28, 0x0E, 0xD0, 0x13, 0x28, 0x0C, 0xD0, 0x10, 0x28, + 0x0A, 0xD0, 0xFE, 0xBD, 0x94, 0xF8, 0x25, 0x00, 0x00, 0x28, 0xFA, 0xD0, + 0x25, 0xB9, 0x40, 0xF2, 0x05, 0x15, 0x01, 0xE0, 0x00, 0x2F, 0xF4, 0xD0, + 0x84, 0xF8, 0x25, 0x20, 0x45, 0xB1, 0x00, 0x92, 0x01, 0x92, 0x02, 0x92, + 0xA2, 0x7C, 0x2B, 0x46, 0x05, 0x20, 0x04, 0xF0, 0x93, 0xF8, 0xFE, 0xBD, + 0xE0, 0x79, 0xA3, 0x79, 0x00, 0x93, 0xCD, 0xE9, 0x01, 0x02, 0x00, 0x23, + 0xA2, 0x7C, 0x04, 0x20, 0xF3, 0xE7, 0x00, 0x00, 0xF8, 0x41, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x00, 0x6A, 0xCA, 0x07, 0x04, 0xD0, 0x02, 0x68, + 0x13, 0x05, 0x0D, 0xD5, 0x92, 0x04, 0x0B, 0xD5, 0x8A, 0x07, 0x04, 0xD5, + 0x02, 0x68, 0x13, 0x04, 0x06, 0xD5, 0x92, 0x03, 0x04, 0xD5, 0x49, 0x07, + 0x04, 0xD5, 0x00, 0x68, 0x00, 0x03, 0x01, 0xD4, 0x00, 0x20, 0x70, 0x47, + 0x01, 0x20, 0x70, 0x47, 0x00, 0x6A, 0xCA, 0x07, 0x04, 0xD0, 0x02, 0x68, + 0x53, 0x05, 0x0D, 0xD5, 0xD2, 0x04, 0x0B, 0xD5, 0x8A, 0x07, 0x04, 0xD5, + 0x02, 0x68, 0x53, 0x04, 0x06, 0xD5, 0xD2, 0x03, 0x04, 0xD5, 0x49, 0x07, + 0x04, 0xD5, 0x00, 0x68, 0x40, 0x03, 0x01, 0xD4, 0x00, 0x20, 0x70, 0x47, + 0x01, 0x20, 0x70, 0x47, 0x70, 0xB5, 0x00, 0x25, 0x00, 0xF0, 0x8C, 0xF8, + 0x60, 0xB1, 0x04, 0x6A, 0x54, 0xB1, 0x02, 0x7F, 0x21, 0x7A, 0x01, 0x2A, + 0x08, 0xD0, 0xFF, 0xF7, 0xDB, 0xFF, 0x18, 0xB1, 0x20, 0x68, 0x00, 0x01, + 0x00, 0xD5, 0x01, 0x25, 0x28, 0x46, 0x70, 0xBD, 0xFF, 0xF7, 0xBA, 0xFF, + 0xF5, 0xE7, 0x10, 0xB5, 0x01, 0x78, 0x01, 0x24, 0x29, 0xB1, 0x80, 0x88, + 0x10, 0xB1, 0x00, 0xF0, 0x8D, 0xF8, 0x00, 0xB1, 0x00, 0x24, 0x20, 0x46, + 0x10, 0xBD, 0x00, 0x00, 0x08, 0xB5, 0x00, 0xF0, 0x69, 0xF8, 0x68, 0xB1, + 0x90, 0xF8, 0x25, 0x30, 0x53, 0xB1, 0x80, 0x68, 0x41, 0x07, 0x07, 0xD5, + 0x00, 0x90, 0x02, 0x22, 0x03, 0x49, 0x04, 0x48, 0xE2, 0xF7, 0x95, 0xD8, + 0x01, 0x20, 0x08, 0xBD, 0x00, 0x20, 0x08, 0xBD, 0x78, 0x41, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x04, 0x46, 0x03, 0x88, 0x01, 0x22, + 0x05, 0x49, 0x06, 0x48, 0xE2, 0xF7, 0x85, 0xD8, 0x21, 0x46, 0xBD, 0xE8, + 0x10, 0x40, 0x24, 0x23, 0x03, 0x4A, 0x04, 0x48, 0xEA, 0xF7, 0x4A, 0xBC, + 0xF0, 0x40, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x67, 0xAA, 0x82, 0x00, + 0x94, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x86, 0xB0, 0x0D, 0x4E, 0x0E, 0x4C, + 0x0E, 0x4D, 0x0C, 0xE0, 0xBD, 0xF8, 0x00, 0x30, 0x01, 0x22, 0x0D, 0x49, + 0x30, 0x46, 0xE2, 0xF7, 0x68, 0xD8, 0x36, 0x23, 0x0B, 0x4A, 0x69, 0x46, + 0x20, 0x78, 0xEA, 0xF7, 0xFD, 0xF8, 0x33, 0x23, 0x08, 0x4A, 0x69, 0x46, + 0x28, 0x46, 0xEA, 0xF7, 0xFF, 0xFB, 0x00, 0x28, 0xEA, 0xD1, 0x06, 0xB0, + 0x70, 0xBD, 0x00, 0x00, 0x03, 0x39, 0x10, 0x21, 0x84, 0x76, 0x20, 0x00, + 0x94, 0x76, 0x20, 0x00, 0x18, 0x41, 0xC0, 0x08, 0x7C, 0xAA, 0x82, 0x00, + 0x00, 0xB5, 0x08, 0x48, 0x85, 0xB0, 0x21, 0x23, 0x05, 0x4A, 0x69, 0x46, + 0x00, 0x78, 0xEA, 0xF7, 0x8D, 0xF8, 0x00, 0x28, 0x02, 0xD0, 0x68, 0x46, + 0x01, 0xF0, 0x40, 0xFC, 0x05, 0xB0, 0x00, 0xBD, 0xDE, 0xA8, 0x82, 0x00, + 0x84, 0x76, 0x20, 0x00, 0x30, 0xB5, 0x04, 0x46, 0x0A, 0x48, 0x00, 0x21, + 0x42, 0x68, 0x0A, 0x48, 0x90, 0xF8, 0x98, 0x31, 0x0A, 0xE0, 0xC1, 0xEB, + 0xC1, 0x00, 0x02, 0xEB, 0x00, 0x10, 0x05, 0x79, 0x15, 0xB1, 0x45, 0x8B, + 0xA5, 0x42, 0x04, 0xD0, 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42, 0xF2, 0xD8, + 0x00, 0x20, 0x30, 0xBD, 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x30, 0xB5, 0x04, 0x46, 0x0A, 0x48, 0x00, 0x21, 0xC2, 0x69, 0x0A, 0x48, + 0x90, 0xF8, 0xAA, 0x31, 0x0A, 0xE0, 0x01, 0xEB, 0x41, 0x00, 0x02, 0xEB, + 0x40, 0x00, 0x05, 0x78, 0x15, 0xB1, 0x85, 0x88, 0xA5, 0x42, 0x04, 0xD0, + 0x49, 0x1C, 0xC9, 0xB2, 0x8B, 0x42, 0xF2, 0xD8, 0x00, 0x20, 0x30, 0xBD, + 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x47, + 0x0E, 0x46, 0x81, 0x46, 0x00, 0x24, 0x10, 0x4F, 0xDF, 0xF8, 0x40, 0x80, + 0x12, 0xE0, 0x78, 0x68, 0xC4, 0xEB, 0xC4, 0x01, 0x00, 0xEB, 0x01, 0x15, + 0x28, 0x79, 0x48, 0xB1, 0xA8, 0x7C, 0xB0, 0x42, 0x06, 0xD1, 0x06, 0x22, + 0x49, 0x46, 0x05, 0xF1, 0x0C, 0x00, 0x14, 0xF4, 0xB1, 0xF0, 0x40, 0xB1, + 0x64, 0x1C, 0xE4, 0xB2, 0x98, 0xF8, 0x98, 0x01, 0xA0, 0x42, 0xE8, 0xD8, + 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x87, 0x28, 0x46, 0xFB, 0xE7, 0x00, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x08, 0x49, 0x91, 0xF8, + 0x98, 0x11, 0x81, 0x42, 0x09, 0xD9, 0x07, 0x49, 0xC0, 0xEB, 0xC0, 0x00, + 0x49, 0x68, 0x11, 0xEB, 0x00, 0x10, 0x02, 0xD0, 0x01, 0x79, 0x00, 0x29, + 0x00, 0xD1, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0E, 0x4B, 0x00, 0x21, 0x42, 0x18, + 0x54, 0x78, 0x92, 0x78, 0x24, 0x02, 0x04, 0xEB, 0x02, 0x42, 0x44, 0x5C, + 0x22, 0x44, 0xC2, 0xF3, 0x13, 0x04, 0x9C, 0x42, 0x04, 0xD3, 0x12, 0x09, + 0xC2, 0xF3, 0x13, 0x04, 0x9C, 0x42, 0x02, 0xD2, 0xC2, 0xF3, 0x13, 0x00, + 0x10, 0xBD, 0x49, 0x1C, 0x89, 0xB2, 0x06, 0x29, 0xE7, 0xD3, 0x4F, 0xF0, + 0xFF, 0x30, 0x10, 0xBD, 0x40, 0x42, 0x0F, 0x00, 0x10, 0xB5, 0x00, 0x6A, + 0x44, 0x68, 0x50, 0x34, 0x11, 0xF4, 0x44, 0xF1, 0x20, 0x70, 0x01, 0x0A, + 0x61, 0x70, 0x01, 0x0C, 0xA1, 0x70, 0x00, 0x0E, 0xE0, 0x70, 0x11, 0xF4, + 0x3B, 0xF1, 0x20, 0x71, 0x01, 0x0A, 0x61, 0x71, 0x01, 0x0C, 0xA1, 0x71, + 0x00, 0x0E, 0xE0, 0x71, 0x11, 0xF4, 0x32, 0xF1, 0x20, 0x72, 0x01, 0x0A, + 0x61, 0x72, 0x01, 0x0C, 0xA1, 0x72, 0x00, 0x0E, 0xE0, 0x72, 0x11, 0xF4, + 0x29, 0xF1, 0x20, 0x73, 0x01, 0x0A, 0x61, 0x73, 0x01, 0x0C, 0xA1, 0x73, + 0x00, 0x0E, 0xE0, 0x73, 0x10, 0xBD, 0x00, 0x00, 0xF0, 0xB5, 0x8B, 0xB0, + 0x0C, 0x00, 0x07, 0x46, 0x4F, 0xF0, 0x01, 0x06, 0x24, 0xD0, 0x11, 0xF4, + 0x17, 0xF1, 0x20, 0x70, 0x01, 0x0A, 0x61, 0x70, 0x01, 0x0C, 0xA1, 0x70, + 0x00, 0x0E, 0x65, 0x1C, 0xE0, 0x70, 0x11, 0xF4, 0x0D, 0xF1, 0xE8, 0x70, + 0xC0, 0xF3, 0x07, 0x21, 0x29, 0x71, 0xAF, 0xB1, 0x00, 0x20, 0x01, 0x2F, + 0x2E, 0xD0, 0x02, 0x2F, 0x46, 0xD0, 0x00, 0x26, 0x21, 0x46, 0x41, 0x48, + 0xE2, 0xF7, 0x24, 0xD9, 0x03, 0x46, 0x02, 0x22, 0x3F, 0x49, 0x40, 0x48, + 0x00, 0x97, 0xE1, 0xF7, 0x4E, 0xDF, 0x30, 0x46, 0x0B, 0xB0, 0xF0, 0xBD, + 0x00, 0x20, 0xFB, 0xE7, 0x41, 0xF0, 0xC0, 0x00, 0x60, 0x71, 0x3B, 0xA0, + 0x06, 0x22, 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x00, 0x10, 0x3A, 0xA0, + 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x02, 0x10, 0x69, 0x46, 0x20, 0x46, + 0x14, 0xF4, 0x00, 0xF0, 0x30, 0xB1, 0x06, 0x22, 0x02, 0xA9, 0x20, 0x46, + 0x13, 0xF4, 0xFA, 0xF7, 0x00, 0x28, 0xD5, 0xD1, 0x66, 0x20, 0x17, 0xE0, + 0x01, 0xF0, 0x3F, 0x01, 0x61, 0x71, 0x00, 0x90, 0x01, 0x90, 0x30, 0xA0, + 0x06, 0x22, 0xD0, 0xE9, 0x00, 0x10, 0xCD, 0xE9, 0x02, 0x10, 0x69, 0x46, + 0x20, 0x46, 0x13, 0xF4, 0xE7, 0xF7, 0x30, 0xB1, 0x06, 0x22, 0x02, 0xA9, + 0x20, 0x46, 0x13, 0xF4, 0xE1, 0xF7, 0x00, 0x28, 0xBC, 0xD1, 0x77, 0x20, + 0x20, 0x70, 0xB9, 0xE7, 0x01, 0xF0, 0x7F, 0x01, 0x41, 0xF0, 0x40, 0x01, + 0x61, 0x71, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x03, 0x90, 0x04, 0x90, + 0x05, 0x90, 0x06, 0x90, 0x07, 0x90, 0x21, 0xA0, 0x03, 0x22, 0x00, 0x68, + 0x08, 0x90, 0x20, 0xA0, 0x08, 0xA9, 0x00, 0x68, 0x09, 0x90, 0x20, 0x46, + 0x13, 0xF4, 0xC4, 0xF7, 0x28, 0xB1, 0x03, 0x22, 0x09, 0xA9, 0x20, 0x46, + 0x13, 0xF4, 0xBE, 0xF7, 0x08, 0xB9, 0x88, 0x20, 0xE0, 0x70, 0xE0, 0x78, + 0x8D, 0xF8, 0x00, 0x00, 0x20, 0x79, 0x8D, 0xF8, 0x01, 0x00, 0x60, 0x79, + 0x8D, 0xF8, 0x02, 0x00, 0x14, 0x48, 0x90, 0xF8, 0x47, 0x00, 0x30, 0xB1, + 0x12, 0x49, 0x04, 0xAA, 0x49, 0x31, 0x68, 0x46, 0xE3, 0xF7, 0xAB, 0xD8, + 0x00, 0xE0, 0x00, 0x26, 0xBD, 0xF8, 0x10, 0x00, 0x20, 0x80, 0x9D, 0xF8, + 0x12, 0x00, 0xA0, 0x70, 0x7C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0xC0, 0x25, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0xFF, 0xFF, 0x7F, 0x00, 0x88, 0x76, 0x20, 0x00, 0x0F, 0x4B, 0x10, 0xB5, + 0x02, 0x46, 0x19, 0x88, 0x00, 0x20, 0x4C, 0x07, 0x02, 0xD4, 0x14, 0x89, + 0xA4, 0x05, 0x05, 0xD5, 0xDB, 0x78, 0x03, 0xF0, 0x07, 0x03, 0x03, 0x2B, + 0x00, 0xD0, 0x04, 0x20, 0x8B, 0x07, 0x01, 0xD0, 0x40, 0xF0, 0x01, 0x00, + 0x0B, 0x07, 0x02, 0xD4, 0x12, 0x89, 0x52, 0x04, 0x01, 0xD5, 0x40, 0xF0, + 0x08, 0x00, 0xC9, 0x06, 0x01, 0xD5, 0x40, 0xF0, 0x10, 0x00, 0x10, 0xBD, + 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0x97, 0xFE, 0x20, 0xB1, + 0x90, 0xF8, 0x28, 0x10, 0x09, 0xB1, 0x2A, 0x30, 0x10, 0xBD, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x04, 0x4A, 0x00, 0x20, 0x12, 0xF8, 0x59, 0x1F, + 0x40, 0xEA, 0x01, 0x21, 0x50, 0x78, 0x08, 0x43, 0x70, 0x47, 0x00, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0xFF, 0xF7, 0x7F, 0xFE, 0x00, 0x28, + 0x00, 0xD0, 0xC0, 0x6B, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0x78, 0xFE, + 0x20, 0xB1, 0x90, 0xF8, 0x29, 0x10, 0x09, 0xB1, 0x40, 0x30, 0x10, 0xBD, + 0x00, 0x20, 0x10, 0xBD, 0x10, 0xB5, 0xFF, 0xF7, 0x6D, 0xFE, 0x00, 0x28, + 0x00, 0xD0, 0x00, 0x6D, 0x10, 0xBD, 0x00, 0x00, 0x70, 0xB5, 0x08, 0x4C, + 0x00, 0x25, 0x01, 0x22, 0x23, 0x88, 0x07, 0x49, 0x07, 0x48, 0xE1, 0xF7, + 0x60, 0xDE, 0x20, 0x78, 0x80, 0x07, 0x02, 0xD0, 0xFF, 0xF7, 0xCC, 0xFF, + 0x05, 0x46, 0x28, 0x46, 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0xC4, 0x42, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x47, + 0x06, 0x46, 0x81, 0x7A, 0x00, 0x1D, 0xFF, 0xF7, 0x49, 0xFE, 0x04, 0x46, + 0x31, 0x1D, 0xA2, 0x48, 0xE2, 0xF7, 0x14, 0xD8, 0x03, 0x46, 0xF0, 0x7A, + 0xB2, 0x89, 0x31, 0x88, 0x8D, 0xE8, 0x07, 0x00, 0xDF, 0xF8, 0x7C, 0xA2, + 0x04, 0x22, 0x9D, 0x49, 0x50, 0x46, 0xE1, 0xF7, 0x38, 0xDE, 0xAA, 0xF1, + 0x03, 0x05, 0xF4, 0xB1, 0xF0, 0x7A, 0xDF, 0xF8, 0x6C, 0x82, 0x06, 0xF1, + 0x10, 0x07, 0xA8, 0xF1, 0x02, 0x09, 0x11, 0x28, 0x1E, 0xD0, 0x12, 0x28, + 0x57, 0xD0, 0x01, 0x25, 0x15, 0x28, 0x7D, 0xD0, 0x16, 0x28, 0x0C, 0xD1, + 0x30, 0x88, 0x00, 0x28, 0x09, 0xD1, 0x97, 0xE8, 0x0F, 0x00, 0x04, 0xF1, + 0x40, 0x06, 0x86, 0xE8, 0x0F, 0x00, 0x84, 0xF8, 0x29, 0x50, 0x38, 0x69, + 0x20, 0x65, 0xBD, 0xE8, 0xFF, 0x87, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x47, 0x88, 0x49, 0x00, 0x22, 0x54, 0x31, 0xE1, 0xF7, 0x0D, 0x9E, + 0x20, 0x7F, 0x01, 0x28, 0xF1, 0xD1, 0x30, 0x88, 0x40, 0xBB, 0xA0, 0x68, + 0xC1, 0x04, 0x25, 0xD4, 0xB9, 0x7E, 0xE1, 0x71, 0xFB, 0x7E, 0xA3, 0x71, + 0x04, 0x2B, 0x15, 0xD0, 0x05, 0x2B, 0x10, 0xD0, 0x07, 0x2B, 0x18, 0xD0, + 0x08, 0x2B, 0x13, 0xD0, 0x7B, 0x49, 0x01, 0x22, 0x80, 0x31, 0x28, 0x46, + 0xE1, 0xF7, 0xF3, 0xDD, 0x60, 0x8B, 0x04, 0xB0, 0x39, 0x46, 0xBD, 0xE8, + 0xF0, 0x47, 0xF5, 0xF7, 0xB5, 0xBC, 0x40, 0xF0, 0x83, 0x00, 0x01, 0xE0, + 0x40, 0xF0, 0x81, 0x00, 0xA0, 0x60, 0xF1, 0xE7, 0x40, 0xEA, 0x08, 0x00, + 0xFA, 0xE7, 0x40, 0xEA, 0x09, 0x00, 0xF7, 0xE7, 0x6E, 0x49, 0x01, 0x22, + 0xC4, 0x31, 0x28, 0x46, 0xA3, 0x68, 0xE1, 0xF7, 0xD8, 0xDD, 0x60, 0x8B, + 0xF5, 0xF7, 0x99, 0xFC, 0x4F, 0xF4, 0xBD, 0x61, 0x3B, 0xE0, 0x20, 0x7F, + 0x00, 0x28, 0xB6, 0xD1, 0x94, 0xF8, 0x24, 0x00, 0xFB, 0x7E, 0x62, 0x7F, + 0xB9, 0x7E, 0x8D, 0xE8, 0x0F, 0x00, 0x63, 0x49, 0x05, 0x22, 0xF0, 0x31, + 0x50, 0x46, 0xA3, 0x68, 0xE1, 0xF7, 0xC1, 0xDD, 0x30, 0x88, 0xC0, 0xB9, + 0xA0, 0x68, 0xC1, 0x04, 0x15, 0xD4, 0x81, 0x05, 0x04, 0xD5, 0xF9, 0x7E, + 0x04, 0x29, 0x10, 0xD0, 0x07, 0x29, 0x0E, 0xD0, 0x94, 0xF8, 0x24, 0x10, + 0x08, 0x29, 0x04, 0xD1, 0xF9, 0x7E, 0x04, 0x29, 0x07, 0xD0, 0x07, 0x29, + 0x05, 0xD0, 0xB9, 0x7E, 0x62, 0x7F, 0x00, 0xE0, 0x94, 0xE0, 0x91, 0x42, + 0x6A, 0xD2, 0x55, 0x4F, 0xF8, 0x78, 0xC0, 0x06, 0x11, 0xD4, 0x94, 0xF8, + 0x24, 0x00, 0x07, 0x28, 0x01, 0xD0, 0x08, 0x28, 0x03, 0xD1, 0x05, 0x21, + 0x20, 0x46, 0x03, 0xF0, 0x69, 0xFC, 0x40, 0xF2, 0xEA, 0x51, 0x04, 0xB0, + 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xFF, 0xF7, 0x4D, 0xBB, 0x20, 0x6A, + 0x00, 0x26, 0x18, 0xB9, 0x20, 0x46, 0xFF, 0xF7, 0xE7, 0xFA, 0xB8, 0xB1, + 0x20, 0x46, 0xFF, 0xF7, 0xC9, 0xFE, 0x05, 0x46, 0xC0, 0x07, 0x02, 0xD0, + 0xFF, 0xF7, 0x18, 0xFF, 0x06, 0x46, 0x43, 0x48, 0x90, 0xF8, 0x78, 0x01, + 0x80, 0x07, 0x29, 0xD5, 0xB8, 0x68, 0x82, 0x38, 0x08, 0x28, 0x25, 0xD2, + 0xDF, 0xE8, 0x00, 0xF0, 0x0D, 0x10, 0x13, 0x16, 0x19, 0x1C, 0x1F, 0x22, + 0x63, 0x8B, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x01, 0x22, + 0x39, 0x49, 0xE1, 0xF7, 0x68, 0x9D, 0x05, 0xF0, 0x1F, 0x05, 0x13, 0xE0, + 0x45, 0xF0, 0x20, 0x05, 0x10, 0xE0, 0x45, 0xF0, 0x40, 0x05, 0x0D, 0xE0, + 0x45, 0xF0, 0x60, 0x05, 0x0A, 0xE0, 0x45, 0xF0, 0x80, 0x05, 0x07, 0xE0, + 0x45, 0xF0, 0xA0, 0x05, 0x04, 0xE0, 0x45, 0xF0, 0xC0, 0x05, 0x01, 0xE0, + 0x45, 0xF0, 0xE0, 0x05, 0xFA, 0x7D, 0xF1, 0xB2, 0xCD, 0xE9, 0x00, 0x52, + 0x30, 0x0A, 0xCD, 0xE9, 0x02, 0x01, 0xF8, 0x78, 0x01, 0x21, 0xC0, 0xF3, + 0xC0, 0x03, 0x00, 0xF0, 0x07, 0x02, 0x20, 0x46, 0x03, 0xF0, 0x9A, 0xFB, + 0x04, 0xB0, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x03, 0xF0, 0x16, 0xBE, + 0xE1, 0x71, 0xFB, 0x7E, 0xA3, 0x71, 0x04, 0x2B, 0x18, 0xD0, 0x05, 0x2B, + 0x13, 0xD0, 0x07, 0x2B, 0x1B, 0xD0, 0x08, 0x2B, 0x16, 0xD0, 0x1C, 0x49, + 0x01, 0x22, 0x48, 0x31, 0x28, 0x46, 0xE1, 0xF7, 0x2A, 0xDD, 0x3A, 0x8B, + 0x60, 0x8B, 0x04, 0xB0, 0x3B, 0x46, 0x07, 0xF1, 0x10, 0x01, 0xBD, 0xE8, + 0xF0, 0x47, 0xF5, 0xF7, 0x4C, 0xBE, 0x40, 0xF0, 0x83, 0x00, 0x01, 0xE0, + 0x40, 0xF0, 0x81, 0x00, 0xA0, 0x60, 0xEE, 0xE7, 0x40, 0xEA, 0x08, 0x00, + 0xFA, 0xE7, 0x40, 0xEA, 0x09, 0x00, 0xF7, 0xE7, 0x30, 0x88, 0x00, 0x28, + 0x7F, 0xF4, 0xF7, 0xAE, 0x10, 0x22, 0x39, 0x46, 0x04, 0xF1, 0x2A, 0x00, + 0x13, 0xF4, 0x1D, 0xF6, 0x84, 0xF8, 0x28, 0x50, 0x38, 0x69, 0xE0, 0x63, + 0xEB, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0x88, 0x27, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x83, 0x00, 0x01, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xD8, 0x28, 0xC0, 0x08, 0x7F, 0xB5, 0x04, 0x46, + 0x81, 0x7A, 0x00, 0x1D, 0xFF, 0xF7, 0xEE, 0xFC, 0x05, 0x46, 0x21, 0x1D, + 0x2E, 0x48, 0xE1, 0xF7, 0xB9, 0xDE, 0xA2, 0x89, 0x21, 0x88, 0xE3, 0x7A, + 0xCD, 0xE9, 0x02, 0x12, 0xCD, 0xE9, 0x00, 0x03, 0x2B, 0x46, 0x05, 0x22, + 0x29, 0x49, 0x2A, 0x48, 0xE1, 0xF7, 0xDD, 0xDC, 0x7D, 0xB1, 0x28, 0x6A, + 0x68, 0xB1, 0x21, 0x88, 0xB1, 0xB1, 0x08, 0x21, 0x28, 0x46, 0x03, 0xF0, + 0xA5, 0xFB, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x40, 0xF2, + 0xEB, 0x51, 0xFF, 0xF7, 0x89, 0xBA, 0x04, 0xB0, 0x2B, 0x46, 0x1E, 0x49, + 0xBD, 0xE8, 0x70, 0x40, 0x1D, 0x48, 0x01, 0x22, 0x5C, 0x31, 0xC0, 0x1E, + 0xE1, 0xF7, 0xC1, 0x9C, 0xE1, 0x7A, 0x11, 0x39, 0x06, 0x29, 0x2C, 0xD2, + 0xDF, 0xE8, 0x01, 0xF0, 0x03, 0x07, 0x17, 0x1B, 0x21, 0x25, 0x41, 0x68, + 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68, 0x11, 0xF8, 0x81, 0x2F, + 0x42, 0xF0, 0x01, 0x02, 0x0A, 0x70, 0x01, 0x68, 0x21, 0xF0, 0x00, 0x61, + 0x01, 0x60, 0x04, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x02, 0xF0, + 0x0F, 0xB8, 0x41, 0x68, 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68, + 0x11, 0xF8, 0x81, 0x2F, 0x42, 0xF0, 0x02, 0x02, 0xEA, 0xE7, 0x41, 0x68, + 0x11, 0xF8, 0x80, 0x2F, 0x02, 0xE0, 0x41, 0x68, 0x11, 0xF8, 0x81, 0x2F, + 0x42, 0xF0, 0x04, 0x02, 0xE0, 0xE7, 0x7F, 0xBD, 0x00, 0x00, 0x30, 0x21, + 0x64, 0x29, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x47, + 0x96, 0xB0, 0x00, 0x26, 0x04, 0x6A, 0x05, 0x46, 0x09, 0x96, 0x0A, 0x96, + 0x0B, 0x96, 0x0C, 0x96, 0x60, 0x68, 0x10, 0x22, 0x00, 0xF1, 0x30, 0x08, + 0x00, 0xF1, 0x10, 0x0A, 0x09, 0xA8, 0x49, 0x1C, 0x13, 0xF4, 0x89, 0xF5, + 0xD5, 0xF8, 0x13, 0x00, 0x11, 0x90, 0xB5, 0xF8, 0x17, 0x00, 0xAD, 0xF8, + 0x48, 0x00, 0x68, 0x7E, 0x8D, 0xF8, 0x4A, 0x00, 0x68, 0x6D, 0x13, 0x90, + 0xB5, 0xF8, 0x58, 0x00, 0xAD, 0xF8, 0x50, 0x00, 0x95, 0xF8, 0x5A, 0x00, + 0x58, 0x4F, 0x8D, 0xF8, 0x52, 0x00, 0x05, 0xF1, 0x13, 0x01, 0x38, 0x46, + 0xE1, 0xF7, 0x2A, 0xDE, 0x81, 0x46, 0x55, 0x49, 0x38, 0x46, 0xE1, 0xF7, + 0x25, 0xDE, 0xA9, 0x7C, 0x6A, 0x7E, 0xCD, 0xF8, 0x00, 0x90, 0xCD, 0xE9, + 0x01, 0x21, 0x03, 0x46, 0x04, 0x22, 0x50, 0x49, 0x50, 0x48, 0xE1, 0xF7, + 0x4A, 0xDC, 0x28, 0x7F, 0x68, 0xB1, 0xE0, 0x68, 0x04, 0x90, 0x05, 0x96, + 0x06, 0x96, 0x07, 0x96, 0x08, 0x96, 0xA0, 0x7A, 0x02, 0x28, 0x0C, 0xD0, + 0x01, 0x28, 0x0A, 0xD0, 0x03, 0x28, 0x18, 0xD0, 0x1D, 0xE0, 0xB4, 0xF8, + 0x13, 0x00, 0xAD, 0xF8, 0x10, 0x00, 0x60, 0x7D, 0x8D, 0xF8, 0x12, 0x00, + 0xEB, 0xE7, 0xB4, 0xF8, 0x78, 0x00, 0x8D, 0xF8, 0x14, 0x00, 0x00, 0x0A, + 0x8D, 0xF8, 0x15, 0x00, 0xA0, 0x6F, 0x00, 0x0C, 0x8D, 0xF8, 0x16, 0x00, + 0xA0, 0x6F, 0x00, 0x0E, 0x8D, 0xF8, 0x17, 0x00, 0x05, 0xE0, 0x39, 0x48, + 0x05, 0xAF, 0x2E, 0x30, 0x0F, 0xC8, 0x87, 0xE8, 0x0F, 0x00, 0x0D, 0xAB, + 0x11, 0xAA, 0x13, 0xA9, 0x04, 0xA8, 0x8D, 0xE8, 0x0F, 0x00, 0x05, 0xAB, + 0x52, 0x46, 0x41, 0x46, 0x04, 0xF1, 0x60, 0x00, 0x10, 0xF4, 0x2E, 0xF5, + 0x10, 0x22, 0x0D, 0xA9, 0x09, 0xA8, 0x13, 0xF4, 0xD3, 0xF4, 0x58, 0xB3, + 0x2F, 0x4F, 0x05, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x6F, 0xDE, + 0x81, 0x46, 0x52, 0x46, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x69, 0xDE, + 0x06, 0x46, 0x42, 0x46, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x63, 0xDE, + 0x05, 0x46, 0x09, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x5D, 0xDE, + 0x04, 0x46, 0x0D, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xE1, 0xF7, 0x57, 0xDE, + 0x03, 0x46, 0x8D, 0xE8, 0x70, 0x02, 0x1D, 0x49, 0x1D, 0x48, 0x05, 0x22, + 0x70, 0x31, 0x80, 0x1E, 0xE1, 0xF7, 0xE1, 0xDB, 0x0B, 0x20, 0x16, 0xB0, + 0xBD, 0xE8, 0xF0, 0x87, 0xA0, 0x7A, 0x04, 0x28, 0x17, 0xD0, 0xB0, 0xB1, + 0x08, 0x20, 0xA8, 0x71, 0x28, 0x7F, 0x01, 0x28, 0x13, 0xD0, 0x00, 0x96, + 0x01, 0x96, 0x20, 0x68, 0x40, 0xF0, 0x00, 0x50, 0x20, 0x60, 0x28, 0x46, + 0x03, 0xF0, 0xBE, 0xFC, 0x68, 0x8B, 0x05, 0xF1, 0x5B, 0x03, 0x00, 0x22, + 0x69, 0x46, 0xF5, 0xF7, 0xF0, 0xFC, 0x00, 0x20, 0xE1, 0xE7, 0x07, 0x20, + 0xE7, 0xE7, 0x94, 0xF8, 0x74, 0x00, 0x18, 0xB1, 0x01, 0x20, 0x84, 0xF8, + 0x7F, 0x00, 0xF4, 0xE7, 0x28, 0x46, 0x02, 0xF0, 0xF9, 0xFC, 0x20, 0x68, + 0x40, 0xF0, 0x00, 0x50, 0x20, 0x60, 0xEC, 0xE7, 0x00, 0x00, 0x30, 0x21, + 0xB6, 0x76, 0x20, 0x00, 0x60, 0x3C, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x00, 0x00, 0x50, 0x21, 0xF0, 0xB5, 0x49, 0x1C, 0x05, 0x46, 0x0E, 0x46, + 0x0A, 0x46, 0x04, 0x6A, 0x87, 0xB0, 0x10, 0x21, 0x1E, 0x48, 0xE1, 0xF7, + 0x08, 0xDE, 0x07, 0x46, 0x05, 0xF1, 0x0C, 0x01, 0x1C, 0x48, 0xE1, 0xF7, + 0x65, 0xDD, 0x03, 0x46, 0x0D, 0xF1, 0x08, 0x0E, 0x20, 0x68, 0x94, 0xF8, + 0x08, 0xC0, 0x62, 0x7A, 0x29, 0x7F, 0x8E, 0xE8, 0x07, 0x10, 0xA8, 0x68, + 0x07, 0x22, 0xCD, 0xE9, 0x00, 0x70, 0x15, 0x49, 0x15, 0x48, 0xE1, 0xF7, + 0x84, 0xDB, 0x28, 0x7A, 0x40, 0x07, 0x1C, 0xD5, 0x20, 0x88, 0x00, 0x05, + 0x19, 0xD4, 0x28, 0x7F, 0x10, 0xB1, 0x01, 0x28, 0x02, 0xD0, 0x04, 0xE0, + 0x60, 0x7A, 0x00, 0xE0, 0x20, 0x7A, 0xC0, 0x07, 0x0F, 0xD0, 0x60, 0x68, + 0x10, 0x22, 0x31, 0x46, 0x1C, 0x30, 0x13, 0xF4, 0x82, 0xF4, 0x20, 0x68, + 0x40, 0xF4, 0x00, 0x60, 0x20, 0x60, 0x28, 0x46, 0x01, 0xF0, 0xD2, 0xFE, + 0x00, 0x20, 0x07, 0xB0, 0xF0, 0xBD, 0x08, 0x20, 0xFB, 0xE7, 0x00, 0x00, + 0x00, 0x00, 0x50, 0x21, 0x00, 0x00, 0x30, 0x21, 0x84, 0x3E, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x7C, 0xB5, 0x0D, 0x46, 0x06, 0x46, 0xFF, 0xF7, + 0x1B, 0xFB, 0xCD, 0xE9, 0x00, 0x65, 0x04, 0x46, 0x03, 0x46, 0x03, 0x22, + 0x13, 0x49, 0x14, 0x48, 0xE1, 0xF7, 0x4B, 0xDB, 0x00, 0x2C, 0x20, 0xD0, + 0x00, 0x2D, 0x1E, 0xD1, 0xA0, 0x68, 0x40, 0xF0, 0x04, 0x00, 0xA0, 0x60, + 0x20, 0x6A, 0x68, 0xB1, 0x40, 0x68, 0x84, 0x21, 0x13, 0xF4, 0xF2, 0xF4, + 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0, 0x40, 0x51, 0x01, 0x60, 0x20, 0x46, + 0xBD, 0xE8, 0x7C, 0x40, 0x01, 0xF0, 0x9E, 0xBE, 0x00, 0x22, 0x14, 0x21, + 0x20, 0x46, 0xFF, 0xF7, 0xD3, 0xF9, 0x20, 0x46, 0xBD, 0xE8, 0x7C, 0x40, + 0x00, 0x21, 0xFF, 0xF7, 0xE5, 0xB8, 0x7C, 0xBD, 0x5C, 0x2C, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x4F, 0x78, + 0x8E, 0x1C, 0x04, 0x6A, 0x00, 0x22, 0x1B, 0x49, 0x1B, 0x48, 0xE1, 0xF7, + 0x18, 0xDB, 0x28, 0x7A, 0x40, 0x07, 0x0E, 0xD5, 0x20, 0x68, 0x81, 0x03, + 0x0B, 0xD4, 0x01, 0x04, 0x09, 0xD5, 0x29, 0x7F, 0x11, 0xB1, 0x01, 0x29, + 0x02, 0xD0, 0x07, 0xE0, 0x61, 0x7A, 0x00, 0xE0, 0x21, 0x7A, 0x89, 0x07, + 0x02, 0xD4, 0x08, 0x20, 0xBD, 0xE8, 0xF0, 0x81, 0x40, 0xF4, 0x00, 0x30, + 0x20, 0x60, 0xA9, 0x7C, 0x3B, 0x46, 0x32, 0x46, 0x05, 0xF1, 0x0C, 0x00, + 0xEC, 0xF7, 0x5C, 0xFD, 0x60, 0x68, 0x00, 0x21, 0x81, 0x64, 0xA0, 0xF8, + 0x4C, 0x10, 0x60, 0x68, 0x31, 0x68, 0x81, 0x64, 0xB1, 0x88, 0xA0, 0xF8, + 0x4C, 0x10, 0x60, 0x68, 0x80, 0xF8, 0x4E, 0x70, 0x28, 0x46, 0x01, 0xF0, + 0x53, 0xFE, 0x00, 0x20, 0xE0, 0xE7, 0x00, 0x00, 0x30, 0x3F, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x05, 0x46, 0x4E, 0x1C, 0x04, 0x6A, + 0x00, 0x22, 0x12, 0x49, 0x12, 0x48, 0xE1, 0xF7, 0xD8, 0xDA, 0x28, 0x7A, + 0x40, 0x07, 0x0C, 0xD5, 0x20, 0x68, 0x01, 0x04, 0x09, 0xD4, 0x29, 0x7F, + 0x11, 0xB1, 0x01, 0x29, 0x02, 0xD0, 0x06, 0xE0, 0x61, 0x7A, 0x00, 0xE0, + 0x21, 0x7A, 0x89, 0x07, 0x01, 0xD4, 0x08, 0x20, 0x70, 0xBD, 0x40, 0xF4, + 0x00, 0x40, 0x20, 0x60, 0x60, 0x68, 0x10, 0x22, 0x31, 0x46, 0x38, 0x30, + 0x13, 0xF4, 0xD1, 0xF3, 0x28, 0x46, 0x01, 0xF0, 0x25, 0xFE, 0x00, 0x20, + 0x70, 0xBD, 0x00, 0x00, 0x18, 0x3F, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x70, 0xB5, 0x4C, 0x78, 0x05, 0x46, 0x23, 0x46, 0x01, 0x22, 0x06, 0x49, + 0x06, 0x48, 0xE1, 0xF7, 0xAA, 0xDA, 0xAA, 0x7C, 0x21, 0x46, 0x05, 0xF1, + 0x0C, 0x00, 0xEC, 0xF7, 0x46, 0xFE, 0x00, 0x20, 0x70, 0xBD, 0x00, 0x00, + 0x34, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x41, + 0x07, 0x46, 0x05, 0x1D, 0x00, 0x8A, 0xFF, 0xF7, 0x5D, 0xFA, 0x04, 0x00, + 0x4F, 0xF0, 0x00, 0x06, 0x14, 0xD0, 0x68, 0x89, 0xE2, 0x79, 0xA1, 0x79, + 0xA3, 0x68, 0x8D, 0xE8, 0x0F, 0x00, 0x2B, 0x89, 0x05, 0x22, 0x1D, 0x49, + 0x1D, 0x48, 0xE1, 0xF7, 0x86, 0xDA, 0x94, 0xF8, 0x24, 0x00, 0x40, 0xB1, + 0x04, 0xB0, 0x38, 0x46, 0xBD, 0xE8, 0xF0, 0x41, 0xFF, 0xF7, 0xF0, 0xB9, + 0x4F, 0xF4, 0x0D, 0x76, 0x22, 0xE0, 0x68, 0x89, 0xFF, 0xF7, 0x5A, 0xFA, + 0xF0, 0xB1, 0x41, 0x78, 0x01, 0x29, 0x06, 0xD0, 0x02, 0x29, 0x0C, 0xD0, + 0x05, 0x29, 0x10, 0xD1, 0x40, 0xF2, 0x36, 0x26, 0x14, 0xE0, 0xA1, 0x79, + 0x05, 0x29, 0x0A, 0xD0, 0x04, 0x29, 0x08, 0xD0, 0x4F, 0xF4, 0x0E, 0x76, + 0x0C, 0xE0, 0xA1, 0x79, 0x05, 0x29, 0x02, 0xD0, 0x40, 0xF2, 0x35, 0x26, + 0x06, 0xE0, 0xE1, 0x79, 0x21, 0xB1, 0x80, 0x78, 0x88, 0x42, 0x01, 0xD9, + 0x40, 0xF2, 0x37, 0x26, 0x28, 0x89, 0x04, 0xB0, 0x31, 0x46, 0xBD, 0xE8, + 0xF0, 0x41, 0xF9, 0xF7, 0x43, 0xBA, 0x00, 0x00, 0x18, 0x43, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x00, 0x1D, 0x05, 0x46, 0x41, 0x7A, + 0xFF, 0xF7, 0x44, 0xFA, 0x04, 0x00, 0x0C, 0xD0, 0x94, 0xF8, 0x24, 0x30, + 0x63, 0xB1, 0x01, 0x22, 0x41, 0x49, 0x42, 0x48, 0xE1, 0xF7, 0x3B, 0xDA, + 0xE2, 0x79, 0xA1, 0x79, 0x40, 0xF2, 0xE6, 0x53, 0x1D, 0xE0, 0x40, 0xF2, + 0xE3, 0x53, 0x18, 0xE0, 0x3D, 0x49, 0xC8, 0x78, 0xC0, 0x06, 0x02, 0xD4, + 0x20, 0x7F, 0x01, 0x28, 0x0F, 0xD0, 0xA0, 0x68, 0x20, 0xF4, 0x6F, 0x40, + 0xA0, 0x60, 0x0A, 0x78, 0x52, 0x07, 0x02, 0xD4, 0xAA, 0x79, 0x52, 0x07, + 0x0E, 0xD5, 0x03, 0x22, 0x84, 0xF8, 0x24, 0x20, 0x40, 0xF4, 0xE0, 0x60, + 0x0D, 0xE0, 0x40, 0xF2, 0xEF, 0x53, 0x00, 0x22, 0x11, 0x46, 0x28, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0xEB, 0xF7, 0x88, 0xBE, 0x02, 0x22, 0x84, 0xF8, + 0x24, 0x20, 0x40, 0xF4, 0xA0, 0x60, 0xA0, 0x60, 0x08, 0x78, 0x00, 0x07, + 0x02, 0xD4, 0xA8, 0x79, 0x00, 0x07, 0x03, 0xD5, 0xA0, 0x68, 0x40, 0xF4, + 0x80, 0x40, 0xA0, 0x60, 0x08, 0x78, 0xC0, 0x06, 0x02, 0xD4, 0xA8, 0x79, + 0xC0, 0x06, 0x03, 0xD5, 0xA0, 0x68, 0x40, 0xF4, 0x00, 0x40, 0xA0, 0x60, + 0xE8, 0x88, 0xC0, 0x05, 0xA0, 0x68, 0x02, 0xD5, 0x40, 0xF4, 0x80, 0x50, + 0x01, 0xE0, 0x20, 0xF4, 0x80, 0x50, 0xA0, 0x60, 0x28, 0x7A, 0x00, 0xB9, + 0xC8, 0x7D, 0x60, 0x77, 0x00, 0x22, 0x10, 0x21, 0x20, 0x46, 0xFF, 0xF7, + 0x8B, 0xF8, 0x20, 0x7F, 0x10, 0xB1, 0x20, 0x6A, 0x40, 0xB1, 0x0B, 0xE0, + 0xA1, 0x7C, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0x70, 0x40, 0x12, 0x22, + 0xEC, 0xF7, 0x67, 0xBD, 0x20, 0x46, 0xFE, 0xF7, 0x33, 0xFF, 0x40, 0xB1, + 0x20, 0x46, 0xFF, 0xF7, 0x15, 0xFB, 0x01, 0x46, 0x20, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x03, 0xF0, 0x79, 0xB9, 0x00, 0x22, 0x40, 0xF2, 0xE7, 0x53, + 0x11, 0x46, 0x28, 0x46, 0xEB, 0xF7, 0x3A, 0xFE, 0x04, 0x49, 0xBD, 0xE8, + 0x70, 0x40, 0x04, 0x48, 0x00, 0x22, 0x2C, 0x31, 0xC0, 0x1E, 0xE1, 0xF7, + 0xBC, 0x99, 0x00, 0x00, 0x74, 0x43, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x88, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x5F, 0x8B, 0x46, 0xD3, 0xF8, + 0x09, 0x10, 0x02, 0x91, 0xB3, 0xF8, 0x0D, 0x10, 0xAD, 0xF8, 0x0C, 0x10, + 0x1E, 0x7A, 0x1D, 0x46, 0x90, 0x46, 0x89, 0x46, 0x00, 0x28, 0x7A, 0xD1, + 0x31, 0x46, 0x05, 0xF1, 0x09, 0x00, 0xFE, 0xF7, 0xC3, 0xFE, 0x04, 0x00, + 0x73, 0xD0, 0x4F, 0xF0, 0x00, 0x0A, 0xCD, 0xF8, 0x00, 0xA0, 0xCD, 0xF8, + 0x04, 0xA0, 0xA4, 0xF8, 0x1A, 0xB0, 0x28, 0x78, 0x20, 0x77, 0x07, 0x20, + 0x60, 0x77, 0x68, 0x78, 0x01, 0x27, 0x60, 0x76, 0x02, 0x2E, 0x14, 0xD0, + 0x03, 0x2E, 0x12, 0xD0, 0x02, 0x99, 0x61, 0x65, 0xA4, 0xF8, 0x58, 0x90, + 0x84, 0xF8, 0x5A, 0x60, 0x3C, 0x4E, 0xA0, 0xB1, 0xDF, 0xF8, 0xF0, 0x90, + 0x01, 0x28, 0x16, 0xD0, 0x05, 0xF1, 0x0F, 0x01, 0x02, 0x28, 0x29, 0xD0, + 0x03, 0x28, 0x33, 0xD0, 0x5B, 0xE0, 0xD5, 0xF8, 0x15, 0x10, 0x61, 0x65, + 0xB5, 0xF8, 0x19, 0x10, 0xA4, 0xF8, 0x58, 0x10, 0x84, 0xF8, 0x5A, 0x70, + 0xE8, 0xE7, 0xD6, 0xF8, 0x2E, 0x00, 0xC4, 0xF8, 0x13, 0x00, 0x70, 0x8E, + 0x49, 0xE0, 0xB8, 0xF1, 0x00, 0x0F, 0x0E, 0xD0, 0x58, 0x46, 0xED, 0xF7, + 0x47, 0xFC, 0x20, 0xB1, 0x01, 0x68, 0xC4, 0xF8, 0x13, 0x10, 0x80, 0x88, + 0x3D, 0xE0, 0x00, 0x22, 0x29, 0x49, 0x48, 0x46, 0xE1, 0xF7, 0x57, 0xD9, + 0x39, 0xE0, 0x70, 0x6B, 0xC4, 0xF8, 0x13, 0x00, 0x30, 0x8F, 0x32, 0xE0, + 0x06, 0x22, 0x68, 0x46, 0x13, 0xF4, 0x16, 0xF2, 0x08, 0xB1, 0x67, 0x76, + 0x0A, 0xE0, 0x84, 0xF8, 0x19, 0xA0, 0x85, 0xF8, 0x01, 0xA0, 0xD6, 0xE7, + 0x67, 0x76, 0x06, 0x22, 0x68, 0x46, 0x13, 0xF4, 0x09, 0xF2, 0x28, 0xB1, + 0x55, 0xF8, 0x0F, 0x0F, 0xC4, 0xF8, 0x13, 0x00, 0xA8, 0x88, 0x1A, 0xE0, + 0x6F, 0x70, 0xB8, 0xF1, 0x00, 0x0F, 0xDE, 0xD0, 0x58, 0x46, 0xED, 0xF7, + 0x17, 0xFC, 0x38, 0xB1, 0x01, 0x68, 0xC4, 0xF8, 0x13, 0x10, 0x80, 0x88, + 0xA4, 0xF8, 0x17, 0x00, 0x06, 0xE0, 0x1B, 0xE0, 0x10, 0x49, 0x00, 0x22, + 0x3C, 0x31, 0x48, 0x46, 0xE1, 0xF7, 0x23, 0xD9, 0xD6, 0xF8, 0x3A, 0x00, + 0xC4, 0xF8, 0x13, 0x00, 0xF0, 0x8F, 0xA4, 0xF8, 0x17, 0x00, 0x30, 0x7E, + 0x00, 0x28, 0x0B, 0xD0, 0x04, 0xF1, 0x0C, 0x00, 0xA1, 0x7C, 0x16, 0x22, + 0x05, 0x46, 0xEC, 0xF7, 0xA0, 0xFC, 0xA1, 0x7C, 0x15, 0x22, 0x28, 0x46, + 0xEC, 0xF7, 0x9B, 0xFC, 0xBD, 0xE8, 0xFF, 0x9F, 0x88, 0x76, 0x20, 0x00, + 0x00, 0x39, 0x10, 0x21, 0x8C, 0x30, 0xC0, 0x08, 0x38, 0xB5, 0xFF, 0xF7, + 0xC9, 0xF8, 0x04, 0x00, 0x18, 0xD0, 0x94, 0xF8, 0x24, 0x00, 0x00, 0x90, + 0x23, 0x46, 0x02, 0x22, 0x0A, 0x49, 0x0B, 0x48, 0xE1, 0xF7, 0xF7, 0xD8, + 0x94, 0xF8, 0x24, 0x00, 0x20, 0xB1, 0x40, 0xF2, 0xE9, 0x51, 0x20, 0x46, + 0xFE, 0xF7, 0xAC, 0xFE, 0x20, 0x46, 0x01, 0xF0, 0x73, 0xFE, 0x20, 0x46, + 0xBD, 0xE8, 0x38, 0x40, 0x01, 0xF0, 0x96, 0xBE, 0x38, 0xBD, 0x00, 0x00, + 0xC4, 0x26, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0xFE, 0xB5, 0x16, 0x46, + 0x0D, 0x46, 0x07, 0x46, 0xFF, 0xF7, 0xA2, 0xF8, 0xCD, 0xE9, 0x00, 0x76, + 0x28, 0x4F, 0x04, 0x46, 0x03, 0x46, 0x04, 0x22, 0x25, 0x49, 0x02, 0x95, + 0x38, 0x46, 0xE1, 0xF7, 0xD0, 0xD8, 0x00, 0x2C, 0x43, 0xD0, 0x76, 0xB9, + 0xE0, 0x79, 0xA1, 0x79, 0xCD, 0xE9, 0x00, 0x10, 0x02, 0x95, 0xA2, 0x7C, + 0x0D, 0xB1, 0x06, 0x20, 0x00, 0xE0, 0x08, 0x20, 0x33, 0x46, 0x04, 0xF1, + 0x0C, 0x01, 0x03, 0xF0, 0x49, 0xF8, 0xA0, 0x68, 0x45, 0xB3, 0x40, 0xF0, + 0x04, 0x00, 0xA0, 0x60, 0x20, 0x6A, 0x00, 0x90, 0x16, 0x49, 0x94, 0xF8, + 0x6B, 0x30, 0x02, 0x22, 0x58, 0x31, 0x38, 0x46, 0xE1, 0xF7, 0xAF, 0xD8, + 0x20, 0x6A, 0x68, 0xB1, 0x40, 0x68, 0x84, 0x21, 0x13, 0xF4, 0x5E, 0xF2, + 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0, 0x40, 0x51, 0x01, 0x60, 0x20, 0x46, + 0xBD, 0xE8, 0xFE, 0x40, 0x01, 0xF0, 0x0A, 0xBC, 0x00, 0x22, 0x14, 0x21, + 0x20, 0x46, 0xFE, 0xF7, 0x3F, 0xFF, 0x00, 0x21, 0x03, 0xB0, 0x20, 0x46, + 0xBD, 0xE8, 0xF0, 0x40, 0xFE, 0xF7, 0x50, 0xBE, 0x20, 0xF0, 0x04, 0x00, + 0xA0, 0x60, 0xFF, 0x20, 0xA0, 0x71, 0x00, 0x20, 0xE0, 0x71, 0x31, 0x46, + 0xF0, 0xE7, 0xFE, 0xBD, 0xF8, 0x26, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0x01, 0x46, 0x10, 0x22, 0x02, 0xA8, + 0x13, 0xF4, 0x91, 0xF1, 0x79, 0x4E, 0x7A, 0x4D, 0xB3, 0x8D, 0xD8, 0x05, + 0x21, 0xD5, 0xD8, 0xB2, 0xFF, 0xF7, 0x9E, 0xF8, 0x04, 0x00, 0x4F, 0xF6, + 0xFF, 0x79, 0x12, 0xD0, 0xE0, 0x8C, 0xDF, 0xF8, 0xD0, 0xB1, 0xDF, 0xF8, + 0xD0, 0xA1, 0x00, 0x27, 0xC0, 0x1E, 0x25, 0x6A, 0x4F, 0xF0, 0x04, 0x08, + 0x0B, 0xF1, 0x03, 0x0B, 0x05, 0x28, 0x0B, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, + 0x14, 0x17, 0x3F, 0x47, 0x7F, 0x00, 0x96, 0xF8, 0x2C, 0x30, 0x01, 0x22, + 0x6B, 0x49, 0x28, 0x46, 0xE1, 0xF7, 0x57, 0xD8, 0xB4, 0xE0, 0x69, 0x49, + 0x01, 0x22, 0x48, 0x31, 0x28, 0x46, 0xE1, 0xF7, 0x50, 0xD8, 0x0B, 0xB0, + 0xBD, 0xE8, 0xF0, 0x8F, 0xA4, 0xF8, 0x26, 0x80, 0x29, 0xE0, 0x0D, 0xF1, + 0x08, 0x08, 0x68, 0x68, 0x98, 0xE8, 0x0E, 0x10, 0x20, 0x30, 0x80, 0xE8, + 0x0E, 0x10, 0xE7, 0x84, 0x6A, 0x68, 0x10, 0x21, 0x50, 0x46, 0x20, 0x32, + 0xE1, 0xF7, 0xA7, 0xDA, 0x5B, 0x49, 0x03, 0x46, 0x01, 0x22, 0x94, 0x31, + 0x58, 0x46, 0xE1, 0xF7, 0x34, 0xD8, 0x28, 0x68, 0x40, 0xF0, 0x80, 0x50, + 0x28, 0x60, 0x21, 0x7F, 0x09, 0xB1, 0x80, 0x06, 0x08, 0xD5, 0x6A, 0x68, + 0x03, 0x21, 0x20, 0x46, 0x20, 0x32, 0x02, 0xF0, 0x97, 0xFC, 0x20, 0x46, + 0x03, 0xF0, 0xFE, 0xF8, 0x80, 0xE0, 0x06, 0x20, 0xE0, 0x84, 0x02, 0xAA, + 0x06, 0xA9, 0x20, 0x46, 0x01, 0xF0, 0x2A, 0xFB, 0x2F, 0xE0, 0xE7, 0x84, + 0x02, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xE1, 0xF7, 0x80, 0xDA, 0x48, 0x49, + 0x03, 0x46, 0x01, 0x22, 0xCC, 0x31, 0x58, 0x46, 0xE1, 0xF7, 0x0D, 0xD8, + 0x68, 0x68, 0x10, 0x22, 0x02, 0xA9, 0x40, 0x30, 0x13, 0xF4, 0xD0, 0xF0, + 0x48, 0xB1, 0x04, 0x21, 0x20, 0x46, 0x02, 0xF0, 0xD3, 0xFE, 0x40, 0xF2, + 0x04, 0x51, 0x20, 0x46, 0xFE, 0xF7, 0xBA, 0xFD, 0x5A, 0xE0, 0x20, 0x7F, + 0x01, 0x28, 0x08, 0xD1, 0x6A, 0x68, 0x04, 0x21, 0x20, 0x46, 0x10, 0x32, + 0x02, 0xF0, 0x64, 0xFC, 0x20, 0x46, 0x03, 0xF0, 0xCB, 0xF8, 0x07, 0x20, + 0xE0, 0x84, 0x06, 0xA9, 0x20, 0x46, 0x01, 0xF0, 0x3D, 0xFB, 0x60, 0x79, + 0x06, 0xAA, 0x40, 0xF4, 0x80, 0x70, 0x69, 0x68, 0x02, 0xF0, 0xB2, 0xFC, + 0x40, 0xE0, 0xE7, 0x84, 0xE0, 0x79, 0x10, 0x28, 0x05, 0xD2, 0xC0, 0xF1, + 0x10, 0x01, 0x02, 0xAA, 0x10, 0x44, 0x13, 0xF4, 0x6B, 0xF1, 0xA8, 0x7A, + 0x01, 0x28, 0x38, 0xD0, 0x02, 0x28, 0x36, 0xD0, 0x03, 0x28, 0x34, 0xD0, + 0xA0, 0x68, 0x20, 0xF0, 0x80, 0x00, 0x40, 0xF0, 0x01, 0x00, 0xA0, 0x60, + 0x84, 0xF8, 0x06, 0x80, 0x02, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xE1, 0xF7, + 0x30, 0xDA, 0x03, 0x46, 0xE1, 0x79, 0xA0, 0x79, 0xCD, 0xE9, 0x00, 0x01, + 0x03, 0x22, 0x1E, 0x49, 0x58, 0x46, 0xE0, 0xF7, 0xBA, 0xDF, 0x28, 0x68, + 0x40, 0xF0, 0x00, 0x50, 0x28, 0x60, 0x20, 0x7F, 0x00, 0xB3, 0x0D, 0xF1, + 0x08, 0x08, 0x68, 0x68, 0x98, 0xE8, 0x8E, 0x00, 0x80, 0xE8, 0x8E, 0x00, + 0x28, 0x68, 0x40, 0x00, 0x08, 0xD5, 0x20, 0x6A, 0x01, 0x68, 0x21, 0xF0, + 0x80, 0x41, 0x01, 0x60, 0x60, 0x8B, 0x69, 0x68, 0xF4, 0xF7, 0x6A, 0xFE, + 0xA6, 0xF8, 0x2C, 0x90, 0x03, 0xF0, 0x92, 0xF8, 0x4B, 0xE7, 0xA0, 0x68, + 0x20, 0xF0, 0x80, 0x00, 0x40, 0xF0, 0x03, 0x00, 0xA0, 0x60, 0x05, 0x20, + 0xA0, 0x71, 0xC9, 0xE7, 0x06, 0x97, 0x07, 0x97, 0x60, 0x8B, 0x02, 0xAB, + 0x00, 0x22, 0x06, 0xA9, 0xF5, 0xF7, 0xB7, 0xF8, 0xE8, 0xE7, 0x00, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x00, 0x39, 0x10, 0x21, 0x00, 0x00, 0x50, 0x21, + 0xAC, 0x2C, 0xC0, 0x08, 0xB0, 0x2D, 0xC0, 0x08, 0xFE, 0xB5, 0x05, 0x46, + 0x0F, 0x46, 0x16, 0x46, 0x10, 0x46, 0xFE, 0xF7, 0x3F, 0xFF, 0x04, 0x46, + 0x3A, 0x46, 0x08, 0x21, 0x29, 0x48, 0xE1, 0xF7, 0xDE, 0xD9, 0x00, 0x96, + 0xCD, 0xE9, 0x01, 0x50, 0x23, 0x46, 0x04, 0x22, 0x26, 0x49, 0x27, 0x48, + 0xE0, 0xF7, 0x69, 0xDF, 0x00, 0x2C, 0x32, 0xD0, 0x20, 0x7F, 0x01, 0x28, + 0x0D, 0xD0, 0x00, 0x22, 0x13, 0x21, 0x20, 0x46, 0xFE, 0xF7, 0x04, 0xFE, + 0xA1, 0x7C, 0x03, 0xB0, 0x04, 0xF1, 0x0C, 0x00, 0xBD, 0xE8, 0xF0, 0x40, + 0x11, 0x22, 0xEC, 0xF7, 0xE4, 0xBA, 0x00, 0x20, 0x1B, 0x4E, 0x00, 0x90, + 0x76, 0x1C, 0x01, 0x90, 0xE5, 0xB9, 0x08, 0x22, 0x69, 0x46, 0x38, 0x46, + 0x13, 0xF4, 0x14, 0xF0, 0xB0, 0xB9, 0x20, 0x6A, 0xA0, 0xB1, 0x00, 0x68, + 0x80, 0x00, 0x11, 0xD5, 0x12, 0x49, 0x00, 0x22, 0x4C, 0x31, 0x30, 0x46, + 0xE0, 0xF7, 0x3F, 0xDF, 0x94, 0xF8, 0x6B, 0x00, 0x10, 0xB1, 0x04, 0xF1, + 0x5B, 0x01, 0x01, 0xE0, 0x20, 0x6A, 0x41, 0x68, 0x60, 0x8B, 0xF4, 0xF7, + 0xFD, 0xFD, 0xFE, 0xBD, 0x09, 0x49, 0x00, 0x22, 0x98, 0x31, 0x30, 0x46, + 0xE0, 0xF7, 0x2D, 0xDF, 0x00, 0x22, 0x13, 0x21, 0x20, 0x46, 0xFE, 0xF7, + 0xCD, 0xFD, 0xA1, 0x7C, 0x11, 0x22, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7, + 0xB0, 0xFA, 0xFE, 0xBD, 0x00, 0x00, 0x50, 0x21, 0xF4, 0x25, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF0, 0x4F, 0x87, 0xB0, 0x01, 0x68, + 0x05, 0x91, 0xE7, 0x4E, 0x40, 0x68, 0x06, 0x90, 0x00, 0x25, 0xB3, 0x8D, + 0xE5, 0x4F, 0x2C, 0x46, 0xD8, 0x05, 0x4F, 0xF6, 0xFF, 0x7A, 0x0E, 0xD5, + 0xD8, 0xB2, 0xFE, 0xF7, 0x31, 0xFF, 0x05, 0x00, 0x03, 0xD0, 0xB5, 0xF8, + 0x26, 0x80, 0x2C, 0x6A, 0x09, 0xE0, 0x96, 0xF8, 0x2C, 0x30, 0x01, 0x22, + 0xDD, 0x49, 0x38, 0x46, 0xAC, 0xE1, 0x58, 0x05, 0x1F, 0xD5, 0x96, 0xF8, + 0x48, 0x80, 0xDA, 0x49, 0xD8, 0x48, 0x43, 0x46, 0x01, 0x22, 0x8C, 0x31, + 0xC0, 0x1C, 0xE0, 0xF7, 0xF0, 0xDE, 0xDF, 0xF8, 0x5C, 0xB3, 0x4F, 0xF0, + 0x00, 0x09, 0x00, 0x2D, 0x7E, 0xD0, 0xB8, 0xF1, 0x11, 0x0F, 0x7C, 0xD0, + 0x14, 0xDC, 0x4F, 0xF0, 0x02, 0x07, 0xB8, 0xF1, 0x01, 0x0F, 0x19, 0xD0, + 0xB8, 0xF1, 0x02, 0x0F, 0x1D, 0xD0, 0xB8, 0xF1, 0x08, 0x0F, 0x49, 0xD1, + 0xC0, 0xE0, 0xCB, 0x49, 0x01, 0x22, 0x44, 0x31, 0x38, 0x46, 0xE0, 0xF7, + 0xD4, 0xDE, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xB8, 0xF1, 0x12, 0x0F, + 0x7E, 0xD0, 0xB8, 0xF1, 0x13, 0x0F, 0x7C, 0xD0, 0xB8, 0xF1, 0x14, 0x0F, + 0xEB, 0xD1, 0x1B, 0xE1, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9, + 0x04, 0x12, 0xEF, 0x84, 0xD6, 0xE0, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, + 0xC0, 0xE9, 0x06, 0x12, 0x62, 0x68, 0x10, 0x21, 0x58, 0x46, 0x10, 0x32, + 0xE1, 0xF7, 0x21, 0xD9, 0x03, 0x46, 0xB8, 0x49, 0xB6, 0x48, 0x01, 0x22, + 0xB8, 0x31, 0xC0, 0x1C, 0xE0, 0xF7, 0xAD, 0xDE, 0x95, 0xF8, 0x6B, 0x00, + 0x48, 0xB1, 0x84, 0xF8, 0x80, 0x70, 0x94, 0xF8, 0x81, 0x00, 0x04, 0x28, + 0x12, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x11, 0x12, 0x6D, 0x83, 0x03, 0x20, + 0xE8, 0x84, 0x62, 0x68, 0x69, 0x46, 0x28, 0x46, 0x10, 0x32, 0x01, 0xF0, + 0x6B, 0xF9, 0x68, 0x79, 0x6A, 0x46, 0x40, 0xF4, 0x80, 0x70, 0x61, 0x68, + 0x02, 0xF0, 0x60, 0xFB, 0x42, 0xE1, 0x01, 0xA8, 0xCD, 0xF8, 0x04, 0x90, + 0xCD, 0xF8, 0x08, 0x90, 0xCD, 0xF8, 0x0C, 0x90, 0xCD, 0xF8, 0x10, 0x90, + 0x00, 0x90, 0xE0, 0x6B, 0x62, 0x68, 0x4F, 0x46, 0x00, 0xF1, 0x40, 0x01, + 0x00, 0x23, 0x10, 0x32, 0x0F, 0xF4, 0x31, 0xF7, 0x01, 0xAA, 0x10, 0x21, + 0x58, 0x46, 0xE1, 0xF7, 0xE4, 0xD8, 0x03, 0x46, 0x99, 0x49, 0x98, 0x48, + 0x01, 0x22, 0xEC, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0x70, 0xDE, 0x98, 0x48, + 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x01, 0xE0, 0xE9, 0xE0, 0x83, 0xE0, + 0x27, 0xD5, 0xB0, 0x68, 0xB0, 0xF5, 0x87, 0x7F, 0x02, 0xD0, 0xB0, 0xF5, + 0x82, 0x7F, 0x20, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x09, 0x21, + 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8, 0x07, 0x00, + 0x0A, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8, 0x09, 0x00, + 0x0C, 0x20, 0x01, 0xE0, 0x6F, 0xE0, 0x9A, 0xE0, 0x8D, 0xF8, 0x0A, 0x00, + 0x0F, 0x20, 0x8D, 0xF8, 0x0C, 0x00, 0x8D, 0xF8, 0x0D, 0x70, 0x8D, 0xF8, + 0x0E, 0x70, 0x8D, 0xF8, 0x0B, 0x00, 0x8D, 0xF8, 0x0F, 0x70, 0x01, 0xAA, + 0x03, 0x21, 0x28, 0x46, 0x02, 0xF0, 0xAC, 0xFA, 0x28, 0x46, 0x02, 0xF0, + 0x13, 0xFF, 0x84, 0xF8, 0x81, 0x70, 0xE7, 0xE0, 0x62, 0x68, 0x10, 0x21, + 0x58, 0x46, 0x10, 0x32, 0xE1, 0xF7, 0x9B, 0xD8, 0x03, 0x46, 0x74, 0x48, + 0x01, 0x22, 0x77, 0x49, 0x80, 0x1C, 0xE0, 0xF7, 0x28, 0xDE, 0x62, 0x68, + 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0x02, 0xF0, 0x93, 0xFA, 0x28, 0x46, + 0x02, 0xF0, 0xFA, 0xFE, 0x28, 0x46, 0x02, 0xF0, 0x8D, 0xF9, 0x84, 0xF8, + 0x81, 0x90, 0xCB, 0xE0, 0x05, 0xA8, 0xFE, 0xF7, 0x55, 0xFE, 0x07, 0x46, + 0x30, 0x6A, 0x41, 0x1C, 0x08, 0xD0, 0x07, 0x46, 0x69, 0x49, 0x65, 0x48, + 0x3B, 0x46, 0x01, 0x22, 0x34, 0x31, 0xC0, 0x1C, 0xE0, 0xF7, 0x09, 0xDE, + 0x78, 0x1C, 0x1B, 0xD0, 0x95, 0xF8, 0x6B, 0x00, 0x08, 0xB1, 0xA7, 0x67, + 0x07, 0xE0, 0x60, 0x68, 0x07, 0x70, 0x61, 0x68, 0x38, 0x0A, 0x48, 0x70, + 0x61, 0x68, 0x38, 0x0C, 0x88, 0x70, 0x5E, 0x49, 0x59, 0x48, 0x3B, 0x46, + 0x01, 0x22, 0x70, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0xF2, 0xDD, 0xAA, 0x7C, + 0x39, 0x46, 0x05, 0xF1, 0x0C, 0x00, 0xED, 0xF7, 0x07, 0xFF, 0x9D, 0xE0, + 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x76, 0xE0, + 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9, 0x00, 0x12, 0x12, 0x20, + 0xF3, 0xE7, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, 0xC0, 0xE9, 0x02, 0x12, + 0xA5, 0xF8, 0x26, 0x90, 0xE8, 0x79, 0x10, 0x28, 0x06, 0xD2, 0x61, 0x68, + 0x0A, 0x18, 0xC0, 0xF1, 0x10, 0x01, 0x10, 0x46, 0x12, 0xF4, 0x60, 0xF7, + 0x10, 0x21, 0x58, 0x46, 0x62, 0x68, 0xE1, 0xF7, 0x34, 0xD8, 0x03, 0x46, + 0xE8, 0x79, 0x00, 0x90, 0x43, 0x49, 0x3F, 0x48, 0x02, 0x22, 0xA8, 0x31, + 0x80, 0x1C, 0xE0, 0xF7, 0xBE, 0xDD, 0x06, 0x21, 0x28, 0x46, 0x62, 0x68, + 0x02, 0xF0, 0x2A, 0xFA, 0x28, 0x46, 0x02, 0xF0, 0x91, 0xFE, 0x28, 0x46, + 0x01, 0xF0, 0x1E, 0xF9, 0x64, 0xE0, 0xDD, 0xE9, 0x05, 0x12, 0x60, 0x68, + 0xC0, 0xE9, 0x04, 0x12, 0x14, 0x20, 0xC0, 0xE7, 0x9D, 0xF8, 0x14, 0x00, + 0x9D, 0xF8, 0x15, 0x10, 0x00, 0xEB, 0x01, 0x20, 0x61, 0x68, 0x08, 0x83, + 0xA5, 0xF8, 0x26, 0x90, 0x62, 0x68, 0x08, 0x21, 0x58, 0x46, 0x10, 0x32, + 0xE1, 0xF7, 0x07, 0xD8, 0x00, 0x90, 0x60, 0x68, 0x2D, 0x49, 0x02, 0x22, + 0x03, 0x8B, 0x28, 0x48, 0xDC, 0x31, 0x80, 0x1C, 0xE0, 0xF7, 0x91, 0xDD, + 0x60, 0x68, 0x00, 0xF1, 0x10, 0x02, 0x01, 0x8B, 0x28, 0x46, 0x02, 0xF0, + 0x99, 0xFB, 0x28, 0x46, 0x02, 0xF0, 0x62, 0xFE, 0x61, 0x68, 0xE8, 0x79, + 0x88, 0x76, 0x61, 0x68, 0xA8, 0x79, 0xC8, 0x76, 0xC9, 0xE7, 0xB8, 0xF1, + 0x21, 0x0F, 0x03, 0xD0, 0xB8, 0xF1, 0x22, 0x0F, 0x2C, 0xD1, 0x0D, 0xE0, + 0x05, 0x98, 0xC6, 0xF8, 0x49, 0x00, 0x06, 0x98, 0xC6, 0xF8, 0x4D, 0x00, + 0x22, 0x20, 0x86, 0xF8, 0x48, 0x00, 0x4F, 0xF4, 0x80, 0x60, 0x02, 0xF0, + 0x71, 0xFA, 0x1D, 0xE0, 0x05, 0x98, 0xC6, 0xF8, 0x51, 0x00, 0x06, 0x98, + 0xC6, 0xF8, 0x55, 0x00, 0x01, 0x20, 0x0E, 0x4A, 0x86, 0xF8, 0x48, 0x90, + 0x86, 0xF8, 0x47, 0x00, 0x49, 0x32, 0x01, 0x46, 0x14, 0x46, 0x00, 0x20, + 0xEC, 0xF7, 0x74, 0xFA, 0x22, 0x46, 0x10, 0x21, 0x58, 0x46, 0xE0, 0xF7, + 0xC0, 0xDF, 0x03, 0x46, 0x06, 0x48, 0x01, 0x22, 0x0A, 0x49, 0x80, 0x1C, + 0xE0, 0xF7, 0x4D, 0xDD, 0xA6, 0xF8, 0x2C, 0xA0, 0x02, 0xF0, 0x3E, 0xFE, + 0x73, 0xE6, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0x00, 0x39, 0x10, 0x21, + 0x00, 0x2A, 0xC0, 0x08, 0x00, 0x00, 0x50, 0x21, 0x64, 0x01, 0x20, 0x00, + 0x20, 0x2B, 0xC0, 0x08, 0x30, 0x2C, 0xC0, 0x08, 0x2D, 0xE9, 0xF0, 0x47, + 0x34, 0x4E, 0x80, 0x46, 0x00, 0x25, 0xB3, 0x8D, 0xDF, 0xF8, 0xCC, 0x90, + 0x8A, 0x46, 0xD8, 0x05, 0x1B, 0xD5, 0xD8, 0xB2, 0xFE, 0xF7, 0x54, 0xFD, + 0x04, 0x00, 0x4F, 0xF6, 0xFF, 0x77, 0x0E, 0xD0, 0x20, 0x6A, 0x90, 0xF8, + 0x71, 0x30, 0x01, 0x2B, 0x17, 0xD0, 0x2C, 0x49, 0x01, 0x22, 0x48, 0x46, + 0xE0, 0xF7, 0x1D, 0xDD, 0xB7, 0x85, 0xBD, 0xE8, 0xF0, 0x47, 0x02, 0xF0, + 0x0D, 0xBE, 0x27, 0x49, 0x01, 0x22, 0x96, 0xF8, 0x2C, 0x30, 0x44, 0x39, + 0xF1, 0xE7, 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0x22, 0x49, 0x01, 0x22, + 0x38, 0x31, 0xE0, 0xF7, 0x0A, 0x9D, 0xB8, 0xF1, 0x00, 0x0F, 0x1F, 0xD0, + 0x02, 0x21, 0x80, 0xF8, 0x71, 0x10, 0x20, 0x6A, 0x20, 0x22, 0x51, 0x46, + 0x40, 0x30, 0x12, 0xF4, 0x12, 0xF6, 0x20, 0x6A, 0x90, 0xF8, 0x7D, 0x00, + 0x18, 0xB1, 0x20, 0x46, 0x01, 0xF0, 0x3E, 0xFC, 0x05, 0x46, 0x20, 0x6A, + 0x90, 0xF8, 0x72, 0x10, 0x89, 0xB1, 0x41, 0x68, 0x20, 0x46, 0x30, 0x31, + 0x01, 0xF0, 0x70, 0xFD, 0x21, 0x6A, 0x05, 0x46, 0x00, 0x20, 0x81, 0xF8, + 0x72, 0x00, 0x06, 0xE0, 0x0E, 0x49, 0x08, 0x25, 0x00, 0x22, 0x80, 0x31, + 0x48, 0x46, 0xE0, 0xF7, 0xE0, 0xDC, 0xB7, 0x85, 0x02, 0xF0, 0xD2, 0xFD, + 0x00, 0x2D, 0x0A, 0xD0, 0x29, 0x46, 0x20, 0x46, 0x02, 0xF0, 0xA8, 0xFB, + 0x45, 0xF4, 0xA0, 0x61, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x47, 0xFE, 0xF7, + 0x8D, 0xBA, 0xBD, 0xE8, 0xF0, 0x87, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x00, 0x39, 0x10, 0x21, 0xE8, 0x2F, 0xC0, 0x08, 0x2D, 0xE9, 0xF7, 0x4F, + 0xDF, 0xF8, 0xFC, 0xA0, 0x93, 0x46, 0x80, 0x46, 0x03, 0x46, 0x01, 0x22, + 0x3B, 0x49, 0x50, 0x46, 0xE0, 0xF7, 0xBB, 0xDC, 0x3B, 0x4E, 0xAA, 0xF1, + 0x02, 0x09, 0xB3, 0x8D, 0xD8, 0x05, 0x18, 0xD5, 0xD8, 0xB2, 0xFE, 0xF7, + 0xDB, 0xFC, 0x04, 0x00, 0x4F, 0xF6, 0xFF, 0x77, 0x0B, 0xD0, 0x25, 0x6A, + 0x95, 0xF8, 0x70, 0x30, 0x01, 0x2B, 0x15, 0xD0, 0x30, 0x49, 0x01, 0x22, + 0x68, 0x31, 0x48, 0x46, 0xE0, 0xF7, 0xA3, 0xDC, 0x54, 0xE0, 0x2D, 0x49, + 0x01, 0x22, 0x96, 0xF8, 0x2C, 0x30, 0x28, 0x31, 0xF5, 0xE7, 0x03, 0xB0, + 0x48, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x28, 0x49, 0x01, 0x22, 0xA4, 0x31, + 0xE0, 0xF7, 0x93, 0x9C, 0xB8, 0xF1, 0x00, 0x0F, 0x33, 0xD0, 0x40, 0x22, + 0xE8, 0x6B, 0x01, 0x99, 0x12, 0xF4, 0x9F, 0xF5, 0x20, 0x6A, 0x20, 0x22, + 0x59, 0x46, 0x19, 0x30, 0x12, 0xF4, 0x99, 0xF5, 0x02, 0x20, 0x85, 0xF8, + 0x70, 0x00, 0x21, 0x6A, 0x01, 0x20, 0x81, 0xF8, 0x80, 0x00, 0xA9, 0x7A, + 0x01, 0x29, 0x00, 0xD1, 0x08, 0x20, 0xE0, 0x84, 0x60, 0x79, 0x40, 0xF4, + 0x80, 0x70, 0x02, 0xF0, 0x79, 0xF9, 0x95, 0xF8, 0x73, 0x00, 0x18, 0xB3, + 0x20, 0x46, 0x02, 0xF0, 0x41, 0xF8, 0x20, 0x46, 0x02, 0xF0, 0x46, 0xFD, + 0x20, 0x7F, 0x01, 0x28, 0x1A, 0xD1, 0x10, 0x49, 0x00, 0x22, 0xEC, 0x31, + 0x50, 0x46, 0xE0, 0xF7, 0x62, 0xDC, 0x20, 0x46, 0x01, 0xF0, 0xFC, 0xFA, + 0x05, 0x00, 0x06, 0xD1, 0x0E, 0xE0, 0x08, 0x25, 0x00, 0x22, 0x0C, 0x49, + 0x48, 0x46, 0xE0, 0xF7, 0x56, 0xDC, 0x29, 0x46, 0x20, 0x46, 0x02, 0xF0, + 0x23, 0xFB, 0x45, 0xF4, 0xA0, 0x61, 0x20, 0x46, 0xFE, 0xF7, 0x0A, 0xFA, + 0xB7, 0x85, 0xBD, 0xE8, 0xFE, 0x4F, 0x02, 0xF0, 0x3D, 0xBD, 0x00, 0x00, + 0x44, 0x2E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00, + 0x78, 0x2F, 0xC0, 0x08, 0x2D, 0xE9, 0xF0, 0x41, 0x05, 0x46, 0x04, 0x6A, + 0x11, 0xF8, 0x01, 0x0F, 0x8F, 0x1C, 0x4A, 0x78, 0x19, 0x49, 0x00, 0xEB, + 0x02, 0x20, 0x86, 0xB2, 0x00, 0x22, 0x18, 0x48, 0xE0, 0xF7, 0x2F, 0xDC, + 0x28, 0x7A, 0x40, 0x07, 0x26, 0xD5, 0x20, 0x68, 0x81, 0x04, 0x23, 0xD4, + 0x01, 0x05, 0x21, 0xD5, 0x29, 0x7F, 0x11, 0xB1, 0x01, 0x29, 0x02, 0xD0, + 0x04, 0xE0, 0x61, 0x7A, 0x00, 0xE0, 0x21, 0x7A, 0xC9, 0x07, 0x17, 0xD0, + 0x40, 0xF4, 0x00, 0x50, 0x20, 0x60, 0x60, 0x68, 0x39, 0x68, 0xC1, 0x62, + 0x79, 0x68, 0x01, 0x63, 0x60, 0x68, 0x86, 0x86, 0x61, 0x68, 0xE8, 0x79, + 0x81, 0xF8, 0x36, 0x00, 0x61, 0x68, 0xA8, 0x79, 0x81, 0xF8, 0x37, 0x00, + 0x28, 0x46, 0x00, 0xF0, 0x73, 0xFF, 0x00, 0x20, 0xBD, 0xE8, 0xF0, 0x81, + 0x08, 0x20, 0xFB, 0xE7, 0xFC, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x10, 0xB5, 0x03, 0x88, 0x04, 0x46, 0x18, 0x46, 0xB3, 0xF5, 0x81, 0x6F, + 0x27, 0xD0, 0x06, 0xDC, 0xA0, 0xF5, 0x80, 0x63, 0x02, 0x3B, 0x17, 0xD0, + 0x01, 0x2B, 0x08, 0xD1, 0x0F, 0xE0, 0xA0, 0xF5, 0x80, 0x63, 0x09, 0x3B, + 0x26, 0xD0, 0xA3, 0xF5, 0x80, 0x73, 0xF7, 0x3B, 0x11, 0xD0, 0x03, 0x46, + 0xBD, 0xE8, 0x10, 0x40, 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xE0, 0xF7, + 0xE0, 0x9B, 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x3E, 0xB9, + 0x20, 0x46, 0xBD, 0xE8, 0x10, 0x40, 0xFF, 0xF7, 0x8B, 0xB9, 0xE1, 0x88, + 0x60, 0x79, 0xBD, 0xE8, 0x10, 0x40, 0x00, 0xF0, 0x8F, 0xBD, 0xE1, 0x68, + 0x01, 0xF1, 0x41, 0x02, 0x08, 0x78, 0x49, 0x1C, 0xFF, 0xF7, 0x02, 0xFF, + 0x40, 0xF2, 0x3D, 0x12, 0xE0, 0x68, 0x07, 0xE0, 0xE1, 0x68, 0x11, 0xF8, + 0x01, 0x0B, 0xFF, 0xF7, 0x87, 0xFE, 0xE0, 0x68, 0x4F, 0xF4, 0xA3, 0x72, + 0xBD, 0xE8, 0x10, 0x40, 0x03, 0x49, 0xE8, 0xF7, 0x3B, 0xBA, 0x00, 0x00, + 0xC8, 0x41, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x92, 0xAA, 0x82, 0x00, + 0x70, 0xB5, 0x04, 0x6A, 0x05, 0x46, 0x10, 0x22, 0x60, 0x68, 0x49, 0x1C, + 0x40, 0x30, 0x12, 0xF4, 0xBC, 0xF4, 0x20, 0x68, 0x00, 0x22, 0x40, 0xF0, + 0x20, 0x00, 0x20, 0x60, 0x16, 0x49, 0x17, 0x48, 0xE0, 0xF7, 0x9F, 0xDB, + 0x95, 0xF8, 0x6B, 0x00, 0x88, 0xB1, 0x01, 0x20, 0x84, 0xF8, 0x7E, 0x00, + 0x13, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x03, 0xD5, 0x12, 0x48, + 0x80, 0x68, 0xA0, 0x28, 0x03, 0xD0, 0x28, 0x46, 0x01, 0xF0, 0x98, 0xFA, + 0x0F, 0xE0, 0x04, 0x20, 0x70, 0xBD, 0x28, 0x7F, 0x68, 0xB1, 0x20, 0x68, + 0xC0, 0x00, 0x05, 0xD5, 0x62, 0x68, 0x03, 0x21, 0x28, 0x46, 0x20, 0x32, + 0x01, 0xF0, 0xF0, 0xFF, 0x28, 0x46, 0x02, 0xF0, 0x57, 0xFC, 0x00, 0x20, + 0x70, 0xBD, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0xF3, 0xE7, + 0x64, 0x3E, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x38, 0xB5, 0x4C, 0x78, 0x05, 0x46, 0x00, 0xF1, + 0x0C, 0x01, 0x08, 0x48, 0xE0, 0xF7, 0x34, 0xDD, 0x03, 0x46, 0x02, 0x22, + 0x06, 0x49, 0x07, 0x48, 0x00, 0x94, 0xE0, 0xF7, 0x5E, 0xDB, 0x28, 0x6A, + 0x01, 0x68, 0x41, 0xF4, 0x00, 0x71, 0x01, 0x60, 0x20, 0x46, 0x38, 0xBD, + 0x00, 0x00, 0x30, 0x21, 0x04, 0x3E, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, + 0x7F, 0xB5, 0x04, 0x6A, 0x4E, 0x1C, 0x05, 0x46, 0xA1, 0x7A, 0x90, 0xF8, + 0x6B, 0x00, 0xCD, 0xE9, 0x00, 0x01, 0x20, 0x78, 0x03, 0x22, 0x00, 0xF0, + 0x80, 0x03, 0x33, 0x49, 0x33, 0x48, 0xE0, 0xF7, 0x40, 0xDB, 0x20, 0x78, + 0x00, 0x06, 0x0F, 0xD5, 0x95, 0xF8, 0x6B, 0x00, 0x20, 0xB1, 0xA0, 0x7A, + 0x02, 0x28, 0x09, 0xD0, 0x01, 0x28, 0x07, 0xD0, 0x2B, 0x49, 0x2C, 0x48, + 0x00, 0x22, 0x60, 0x31, 0x40, 0x1E, 0xE0, 0xF7, 0x2E, 0xDB, 0x4D, 0xE0, + 0x60, 0x68, 0x10, 0x22, 0x31, 0x46, 0x30, 0x30, 0x12, 0xF4, 0x3B, 0xF4, + 0x20, 0x68, 0x40, 0xF0, 0x80, 0x00, 0x20, 0x60, 0x95, 0xF8, 0x6B, 0x00, + 0x80, 0xB3, 0x23, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x05, 0xD5, + 0x21, 0x48, 0x80, 0x68, 0x9A, 0x28, 0x09, 0xD0, 0xA1, 0x28, 0x0A, 0xD0, + 0x94, 0xF8, 0x71, 0x00, 0x02, 0x28, 0x08, 0xD0, 0x01, 0x20, 0x84, 0xF8, + 0x72, 0x00, 0x2D, 0xE0, 0x02, 0x20, 0x04, 0xB0, 0x70, 0xBD, 0x04, 0x20, + 0xFB, 0xE7, 0x61, 0x68, 0x28, 0x46, 0x30, 0x31, 0x01, 0xF0, 0x86, 0xFB, + 0x04, 0x00, 0x21, 0xD0, 0x03, 0x46, 0x11, 0x49, 0x11, 0x48, 0x01, 0x22, + 0x98, 0x31, 0x80, 0x1E, 0xE0, 0xF7, 0xF9, 0xDA, 0x21, 0x46, 0x28, 0x46, + 0x02, 0xF0, 0xC6, 0xF9, 0x44, 0xF4, 0xA0, 0x61, 0x28, 0x46, 0xFE, 0xF7, + 0xAD, 0xF8, 0x0F, 0xE0, 0xFF, 0xE7, 0x62, 0x68, 0x69, 0x46, 0x28, 0x46, + 0x30, 0x32, 0x00, 0xF0, 0xBB, 0xFD, 0x05, 0x20, 0xE8, 0x84, 0x68, 0x79, + 0x6A, 0x46, 0x40, 0xF4, 0x80, 0x70, 0x61, 0x68, 0x01, 0xF0, 0xAE, 0xFF, + 0x00, 0x20, 0xD0, 0xE7, 0x34, 0x3D, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x64, 0x01, 0x20, 0x00, 0x88, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x89, 0xB0, 0x88, 0x46, 0x05, 0x46, 0x04, 0x6A, 0xFE, 0xF7, 0x64, 0xFC, + 0x81, 0x46, 0x28, 0x46, 0xFE, 0xF7, 0x0C, 0xFC, 0x06, 0x46, 0x04, 0xF1, + 0x0C, 0x00, 0xCD, 0xE9, 0x07, 0x08, 0x98, 0xF8, 0x01, 0x00, 0x98, 0xF8, + 0x02, 0xB0, 0x98, 0xF8, 0x03, 0x70, 0x98, 0xF8, 0x04, 0xA0, 0x98, 0xF8, + 0x05, 0x20, 0x06, 0x92, 0x98, 0xF8, 0x06, 0x80, 0xCD, 0xE9, 0x00, 0x0B, + 0xCD, 0xE9, 0x04, 0x28, 0xCD, 0xE9, 0x02, 0x7A, 0x07, 0x22, 0xD5, 0x49, + 0xD5, 0x48, 0x23, 0x68, 0xE0, 0xF7, 0xAB, 0xDA, 0x28, 0x7F, 0x01, 0x28, + 0x03, 0xD0, 0x08, 0x20, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x20, 0x78, + 0x80, 0x07, 0x01, 0xD5, 0x09, 0x20, 0xF7, 0xE7, 0xCE, 0x48, 0x40, 0x7D, + 0x02, 0x28, 0x03, 0xD1, 0x38, 0x07, 0x01, 0xD4, 0x03, 0x20, 0xEF, 0xE7, + 0xB8, 0x07, 0x05, 0xD1, 0x06, 0x98, 0x50, 0xEA, 0x08, 0x00, 0x01, 0xD0, + 0x0A, 0x20, 0xE7, 0xE7, 0x00, 0x22, 0x12, 0x21, 0x28, 0x46, 0xFE, 0xF7, + 0x2F, 0xF9, 0x08, 0x98, 0x01, 0x68, 0xC4, 0xF8, 0x0B, 0x10, 0x81, 0x88, + 0xA4, 0xF8, 0x0F, 0x10, 0x80, 0x79, 0x60, 0x74, 0x20, 0x68, 0x00, 0x21, + 0x40, 0xF0, 0x02, 0x00, 0x20, 0x60, 0xBD, 0x48, 0x42, 0x7D, 0xC2, 0xB1, + 0x3A, 0x07, 0x16, 0xD5, 0x01, 0x22, 0x85, 0xF8, 0x6B, 0x20, 0x84, 0xF8, + 0x80, 0x10, 0x84, 0xF8, 0x81, 0x10, 0xC2, 0x78, 0x02, 0xF0, 0x07, 0x02, + 0x03, 0x2A, 0x01, 0xD1, 0x06, 0xF0, 0xFB, 0x06, 0x82, 0x7D, 0x46, 0xF0, + 0x08, 0x06, 0x32, 0xB1, 0x4F, 0xF6, 0xFE, 0x63, 0x09, 0xEA, 0x03, 0x09, + 0x01, 0xE0, 0x85, 0xF8, 0x6B, 0x10, 0x95, 0xF8, 0x24, 0x20, 0x32, 0xB9, + 0x09, 0x22, 0x85, 0xF8, 0x24, 0x20, 0xAA, 0x68, 0x42, 0xF4, 0xA8, 0x52, + 0xAA, 0x60, 0x06, 0x9A, 0xA8, 0x48, 0x22, 0x72, 0x84, 0xF8, 0x09, 0x80, + 0xC0, 0x78, 0xC0, 0x06, 0x01, 0xD4, 0x05, 0x20, 0xA2, 0xE7, 0x28, 0x89, + 0x80, 0x05, 0x03, 0xD4, 0xA2, 0x48, 0x00, 0x78, 0x40, 0x07, 0x01, 0xD5, + 0x01, 0x20, 0x00, 0xE0, 0x00, 0x20, 0x84, 0x46, 0x00, 0x20, 0xA0, 0x72, + 0x95, 0xF8, 0x6B, 0x20, 0x03, 0x20, 0xD2, 0xB1, 0xBB, 0xF1, 0x01, 0x0F, + 0x03, 0xD0, 0x9A, 0x49, 0xC9, 0x78, 0x09, 0x07, 0x1B, 0xD5, 0xA0, 0x72, + 0x84, 0xF8, 0x83, 0x00, 0x96, 0x48, 0xBB, 0xF1, 0x01, 0x0F, 0xC0, 0x78, + 0x4F, 0xEA, 0x00, 0x70, 0x05, 0xD0, 0x00, 0x28, 0x20, 0xDA, 0x02, 0x20, + 0x84, 0xF8, 0x83, 0x00, 0x1C, 0xE0, 0x00, 0x28, 0x1A, 0xDB, 0x01, 0x20, + 0xF8, 0xE7, 0xBB, 0xF1, 0x01, 0x0F, 0x04, 0xD1, 0x8C, 0x49, 0xC9, 0x78, + 0x09, 0x07, 0x00, 0xD5, 0x7A, 0xB1, 0x07, 0x98, 0x00, 0x21, 0x00, 0x78, + 0xCD, 0xE9, 0x00, 0x01, 0x87, 0x48, 0xC0, 0x78, 0x00, 0xF0, 0x07, 0x03, + 0x07, 0x98, 0x80, 0x78, 0x00, 0xF0, 0x04, 0x01, 0x60, 0x46, 0x01, 0xF0, + 0x3D, 0xFE, 0xA0, 0x72, 0xF8, 0x06, 0x04, 0xD5, 0xF0, 0x06, 0x02, 0xD5, + 0x01, 0x20, 0x85, 0xF8, 0x6C, 0x00, 0xDF, 0xF8, 0xF8, 0xB1, 0x07, 0x99, + 0xA0, 0x7A, 0x9B, 0xF8, 0x03, 0x20, 0x09, 0x78, 0x02, 0xF0, 0x07, 0x02, + 0x00, 0x92, 0xCD, 0xE9, 0x01, 0x10, 0x76, 0x49, 0x95, 0xF8, 0x6B, 0x30, + 0x04, 0x22, 0x90, 0x31, 0x74, 0x48, 0xE0, 0xF7, 0xEA, 0xD9, 0x95, 0xF8, + 0x6B, 0x00, 0xA8, 0xB1, 0xA0, 0x7A, 0x01, 0x28, 0x02, 0xD0, 0x02, 0x28, + 0x04, 0xD0, 0x0F, 0xE0, 0x00, 0x20, 0x84, 0xF8, 0x7C, 0x00, 0x0B, 0xE0, + 0x00, 0x20, 0xA0, 0x67, 0x84, 0xF8, 0x7C, 0x00, 0x84, 0xF8, 0x74, 0x00, + 0x84, 0xF8, 0x7E, 0x00, 0x84, 0xF8, 0x7F, 0x00, 0x84, 0xF8, 0x7D, 0x00, + 0x69, 0x7F, 0x51, 0x45, 0x02, 0xD8, 0xBA, 0xF1, 0x10, 0x0F, 0x01, 0xD9, + 0x06, 0x20, 0x21, 0xE7, 0x9B, 0xF8, 0x17, 0x00, 0xE8, 0x71, 0x50, 0x45, + 0x01, 0xD9, 0x85, 0xF8, 0x07, 0xA0, 0xB8, 0x07, 0x3C, 0xD0, 0xB0, 0x07, + 0x3A, 0xD0, 0x01, 0x20, 0x84, 0xF8, 0x82, 0x00, 0xCD, 0xE9, 0x00, 0x89, + 0x59, 0x49, 0xDF, 0xF8, 0x68, 0x81, 0x03, 0x22, 0xDC, 0x31, 0x40, 0x46, + 0x06, 0x9B, 0xE0, 0xF7, 0xB0, 0xD9, 0x21, 0x7A, 0x5F, 0x46, 0x01, 0xEA, + 0x19, 0x21, 0x21, 0x72, 0x60, 0x7A, 0x00, 0xEA, 0x09, 0x00, 0x60, 0x72, + 0x9B, 0xF8, 0x17, 0x20, 0xCD, 0xE9, 0x03, 0x10, 0xCD, 0xE9, 0x01, 0x62, + 0x9B, 0xF8, 0x03, 0x00, 0x06, 0x22, 0xC0, 0xF3, 0xC0, 0x01, 0x00, 0xF0, + 0x07, 0x03, 0x00, 0x91, 0x4C, 0x49, 0x40, 0x46, 0xE0, 0xF7, 0x95, 0xD9, + 0x4B, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x27, 0xD5, 0xB8, 0x68, + 0x8C, 0x38, 0x0E, 0x28, 0x23, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x0B, 0x0E, + 0x11, 0x14, 0x17, 0x1A, 0x1D, 0x20, 0x22, 0x22, 0x48, 0x4A, 0x4F, 0x51, + 0x4F, 0xF0, 0x00, 0x09, 0x48, 0x46, 0xC1, 0xE7, 0x06, 0xF0, 0x1F, 0x06, + 0x13, 0xE0, 0x46, 0xF0, 0x20, 0x06, 0x10, 0xE0, 0x46, 0xF0, 0x40, 0x06, + 0x0D, 0xE0, 0x46, 0xF0, 0x60, 0x06, 0x0A, 0xE0, 0x46, 0xF0, 0x80, 0x06, + 0x07, 0xE0, 0x46, 0xF0, 0xA0, 0x06, 0x04, 0xE0, 0x46, 0xF0, 0xC0, 0x06, + 0x01, 0xE0, 0x46, 0xF0, 0xE0, 0x06, 0xFA, 0x7D, 0x61, 0x7A, 0x20, 0x7A, + 0xCD, 0xE9, 0x00, 0x62, 0xCD, 0xE9, 0x02, 0x01, 0xF8, 0x78, 0x02, 0x21, + 0xC0, 0xF3, 0xC0, 0x03, 0x00, 0xF0, 0x07, 0x02, 0x28, 0x46, 0x01, 0xF0, + 0xB1, 0xFF, 0x28, 0x46, 0x02, 0xF0, 0x30, 0xFA, 0x95, 0xF8, 0x6B, 0x10, + 0x05, 0xF1, 0x0C, 0x00, 0x00, 0x29, 0xA1, 0x7A, 0x1E, 0xD0, 0xC9, 0xB1, + 0x03, 0x29, 0x13, 0xD0, 0x00, 0x20, 0x84, 0xF8, 0x73, 0x00, 0x09, 0xB0, + 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x01, 0xF0, 0x1D, 0xB8, 0x03, 0x21, + 0x00, 0xE0, 0x08, 0x21, 0x28, 0x46, 0x02, 0xF0, 0x0D, 0xF8, 0x32, 0xE0, + 0x05, 0x21, 0xF9, 0xE7, 0x09, 0x21, 0xF7, 0xE7, 0x02, 0x20, 0x84, 0xF8, + 0x70, 0x00, 0x2A, 0xE0, 0xA9, 0x7C, 0xEB, 0xF7, 0xAB, 0xFC, 0x26, 0xE0, + 0x01, 0x29, 0x0A, 0xD0, 0x02, 0x29, 0x15, 0xD0, 0x03, 0x29, 0x1D, 0xD0, + 0x62, 0x68, 0x00, 0x21, 0x11, 0x60, 0x51, 0x60, 0x91, 0x60, 0xD1, 0x60, + 0xEE, 0xE7, 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70, + 0x01, 0xF0, 0x20, 0xFE, 0x01, 0x20, 0x04, 0xF8, 0x80, 0x0F, 0x00, 0x20, + 0x60, 0x70, 0x0C, 0xE0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0xED, 0xF7, + 0x24, 0xF8, 0x01, 0x20, 0x04, 0xF8, 0x74, 0x0F, 0x20, 0x74, 0x02, 0xE0, + 0xA9, 0x7C, 0xED, 0xF7, 0x09, 0xF9, 0x00, 0x20, 0x5E, 0xE6, 0x00, 0x00, + 0x84, 0x39, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00, + 0xB0, 0x3A, 0xC0, 0x08, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x04, 0x6A, 0x89, 0xB0, 0x05, 0x46, 0x04, 0xF1, 0x0C, 0x06, 0xF0, 0x1D, + 0x8A, 0x46, 0x07, 0x90, 0x11, 0xF8, 0x01, 0x0F, 0x08, 0x22, 0x91, 0xF8, + 0x01, 0x90, 0x91, 0xF8, 0x02, 0x80, 0xCF, 0x78, 0x91, 0xF8, 0x04, 0xB0, + 0x49, 0x79, 0x08, 0x91, 0xCD, 0xE9, 0x05, 0xB1, 0xA2, 0x49, 0xCD, 0xE9, + 0x03, 0x87, 0x49, 0x7D, 0xCD, 0xE9, 0x00, 0x10, 0xCD, 0xF8, 0x08, 0x90, + 0x9F, 0x49, 0xA0, 0x48, 0x23, 0x68, 0xE0, 0xF7, 0xD6, 0xD8, 0x20, 0x68, + 0xC1, 0x07, 0x01, 0xD0, 0x00, 0x07, 0x0A, 0xD5, 0x9A, 0x49, 0x9B, 0x48, + 0x00, 0x22, 0x98, 0x31, 0x80, 0x1E, 0xE0, 0xF7, 0xCA, 0xD8, 0x08, 0x20, + 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x94, 0x49, 0x48, 0x7D, 0x02, 0x28, + 0x04, 0xD1, 0x5F, 0xEA, 0x08, 0x70, 0x01, 0xD4, 0x03, 0x20, 0xF3, 0xE7, + 0xDA, 0xF8, 0x00, 0x20, 0xC4, 0xF8, 0x12, 0x20, 0xBA, 0xF8, 0x04, 0x20, + 0xE2, 0x82, 0x9A, 0xF8, 0x06, 0x00, 0x20, 0x76, 0xB0, 0x78, 0x4F, 0xF0, + 0x01, 0x0A, 0x02, 0x07, 0x4F, 0xF0, 0x00, 0x00, 0x0F, 0xD5, 0x4A, 0x7D, + 0x6A, 0xB1, 0x5F, 0xEA, 0x08, 0x72, 0x0A, 0xD5, 0x85, 0xF8, 0x6B, 0xA0, + 0x84, 0xF8, 0x80, 0x00, 0x84, 0xF8, 0x81, 0x00, 0xAA, 0x68, 0x42, 0xF4, + 0x00, 0x72, 0xAA, 0x60, 0x01, 0xE0, 0x85, 0xF8, 0x6B, 0x00, 0xB2, 0x78, + 0xD2, 0x06, 0x04, 0xD5, 0x5F, 0xEA, 0xC8, 0x62, 0x01, 0xD5, 0x85, 0xF8, + 0x6C, 0xA0, 0x22, 0x68, 0x79, 0x49, 0x42, 0xF0, 0x08, 0x02, 0x22, 0x60, + 0x84, 0xF8, 0x08, 0xB0, 0x08, 0x9A, 0x62, 0x72, 0xC9, 0x78, 0xC9, 0x06, + 0x01, 0xD4, 0x05, 0x20, 0xBA, 0xE7, 0xA0, 0x72, 0x83, 0x46, 0x95, 0xF8, + 0x6B, 0x20, 0x03, 0x20, 0xDA, 0xB1, 0xB9, 0xF1, 0x01, 0x0F, 0x03, 0xD0, + 0x6E, 0x49, 0xC9, 0x78, 0x09, 0x07, 0x1C, 0xD5, 0xA0, 0x72, 0x84, 0xF8, + 0x83, 0x00, 0x6B, 0x48, 0xB9, 0xF1, 0x01, 0x0F, 0xC0, 0x78, 0x4F, 0xEA, + 0x00, 0x70, 0x05, 0xD0, 0x00, 0x28, 0x1F, 0xDA, 0x02, 0x20, 0x84, 0xF8, + 0x83, 0x00, 0x1B, 0xE0, 0x00, 0x28, 0x19, 0xDB, 0x84, 0xF8, 0x83, 0xA0, + 0x16, 0xE0, 0xB9, 0xF1, 0x01, 0x0F, 0x04, 0xD1, 0x60, 0x49, 0xC9, 0x78, + 0x09, 0x07, 0x00, 0xD5, 0x6A, 0xB1, 0x07, 0x99, 0x07, 0x98, 0x09, 0x78, + 0xCD, 0xE9, 0x00, 0x1A, 0x80, 0x78, 0x33, 0x78, 0x00, 0xF0, 0x04, 0x01, + 0xB0, 0x78, 0x00, 0xF0, 0x04, 0x00, 0x01, 0xF0, 0x83, 0xFC, 0xA0, 0x72, + 0x68, 0x7F, 0xB8, 0x42, 0x01, 0xD8, 0x10, 0x2F, 0x01, 0xD9, 0x06, 0x20, + 0x7A, 0xE7, 0x53, 0x49, 0xC8, 0x7D, 0xE8, 0x71, 0xB8, 0x42, 0x00, 0xD9, + 0xEF, 0x71, 0xB0, 0x78, 0x80, 0x07, 0x13, 0xD0, 0x5F, 0xEA, 0x88, 0x70, + 0x10, 0xD0, 0x84, 0xF8, 0x82, 0xA0, 0x4F, 0x48, 0x90, 0xF8, 0x78, 0x01, + 0x80, 0x07, 0x1D, 0xD5, 0x88, 0x68, 0xA0, 0xF5, 0x8C, 0x70, 0x06, 0x28, + 0x18, 0xD2, 0xDF, 0xE8, 0x00, 0xF0, 0x06, 0x08, 0x0D, 0x0F, 0x11, 0x13, + 0x84, 0xF8, 0x82, 0xB0, 0xED, 0xE7, 0x03, 0x21, 0x00, 0xE0, 0x08, 0x21, + 0x28, 0x46, 0x01, 0xF0, 0xEF, 0xFE, 0x7D, 0xE0, 0x05, 0x21, 0xF9, 0xE7, + 0x09, 0x21, 0xF7, 0xE7, 0x01, 0x21, 0xF5, 0xE7, 0x02, 0x21, 0x28, 0x46, + 0x01, 0xF0, 0xE4, 0xFE, 0x95, 0xF8, 0x6B, 0x10, 0x05, 0xF1, 0x0C, 0x00, + 0x00, 0x29, 0xA1, 0x7A, 0x43, 0xD0, 0xE9, 0xB3, 0x01, 0x29, 0x04, 0xD0, + 0x02, 0x29, 0x07, 0xD0, 0x03, 0x29, 0x19, 0xD1, 0x20, 0xE0, 0xC4, 0xF8, + 0x78, 0xB0, 0x84, 0xF8, 0x7C, 0xB0, 0x13, 0xE0, 0xC4, 0xF8, 0x78, 0xB0, + 0x84, 0xF8, 0x7C, 0xB0, 0x84, 0xF8, 0x7D, 0xB0, 0x84, 0xF8, 0x7E, 0xB0, + 0x84, 0xF8, 0x7F, 0xB0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0x74, 0x34, + 0xEC, 0xF7, 0x03, 0xFF, 0x04, 0xF8, 0x10, 0xAB, 0x04, 0xF8, 0x84, 0xA9, + 0x28, 0x46, 0x84, 0xF8, 0x73, 0xA0, 0x09, 0xB0, 0xBD, 0xE8, 0xF0, 0x4F, + 0x00, 0xF0, 0xBE, 0xBE, 0x02, 0x20, 0x84, 0xF8, 0x70, 0x00, 0x28, 0x46, + 0x01, 0xF0, 0xB0, 0xFB, 0x28, 0x46, 0x02, 0xF0, 0xB5, 0xF8, 0x28, 0x7F, + 0x01, 0x28, 0x37, 0xD1, 0x1D, 0x49, 0x00, 0x22, 0xBC, 0x31, 0x1D, 0x48, + 0xDF, 0xF7, 0xD1, 0xDF, 0x28, 0x46, 0x00, 0xF0, 0x6B, 0xFE, 0x2D, 0xE0, + 0xFF, 0xE7, 0xA9, 0x7C, 0xEB, 0xF7, 0x44, 0xFB, 0x28, 0xE0, 0x01, 0x29, + 0x0D, 0xD0, 0x02, 0x29, 0x17, 0xD0, 0x03, 0x29, 0x1F, 0xD0, 0x62, 0x68, + 0xC2, 0xF8, 0x00, 0xB0, 0xC2, 0xF8, 0x04, 0xB0, 0xC2, 0xF8, 0x08, 0xB0, + 0xC2, 0xF8, 0x0C, 0xB0, 0xEB, 0xE7, 0x08, 0x20, 0xE8, 0x84, 0x68, 0x79, + 0x40, 0xF4, 0x80, 0x70, 0x01, 0xF0, 0xB6, 0xFC, 0x84, 0xF8, 0x80, 0xA0, + 0x84, 0xF8, 0x81, 0xB0, 0x0C, 0xE0, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, + 0xEC, 0xF7, 0xBB, 0xFE, 0x04, 0xF8, 0x74, 0xAF, 0x84, 0xF8, 0x10, 0xA0, + 0x02, 0xE0, 0xA9, 0x7C, 0xEC, 0xF7, 0xA0, 0xFF, 0x00, 0x20, 0xD3, 0xE6, + 0x88, 0x76, 0x20, 0x00, 0x2C, 0x3B, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x64, 0x01, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x40, 0x22, + 0x49, 0x1C, 0xC0, 0x6B, 0x40, 0x30, 0x12, 0xF4, 0xA0, 0xF0, 0x20, 0x6A, + 0x01, 0x25, 0x80, 0xF8, 0x7D, 0x50, 0x27, 0x48, 0x90, 0xF8, 0x78, 0x01, + 0x80, 0x07, 0x04, 0xD5, 0x25, 0x48, 0x80, 0x68, 0xB0, 0xF5, 0x8F, 0x7F, + 0x09, 0xD0, 0x20, 0x6A, 0xC0, 0x6B, 0x40, 0x30, 0x10, 0xF4, 0x72, 0xF0, + 0x28, 0xB1, 0x20, 0x7F, 0x01, 0x28, 0x04, 0xD0, 0x19, 0xE0, 0x02, 0x20, + 0x70, 0xBD, 0x0B, 0x20, 0x70, 0xBD, 0x20, 0x6A, 0x01, 0x22, 0x1C, 0x49, + 0x90, 0xF8, 0x70, 0x30, 0x1B, 0x48, 0xDF, 0xF7, 0x68, 0xDF, 0x20, 0x6A, + 0x90, 0xF8, 0x70, 0x10, 0x02, 0x29, 0x02, 0xD0, 0x80, 0xF8, 0x73, 0x50, + 0x1D, 0xE0, 0x20, 0x46, 0x01, 0xF0, 0x30, 0xFB, 0x20, 0x46, 0x02, 0xF0, + 0x35, 0xF8, 0x20, 0x6A, 0x90, 0xF8, 0x71, 0x10, 0x11, 0xB1, 0x02, 0x29, + 0x15, 0xD0, 0x10, 0xE0, 0x90, 0xF8, 0x70, 0x10, 0x02, 0x29, 0x0C, 0xD1, + 0x00, 0xF1, 0x19, 0x02, 0xC1, 0x6B, 0x60, 0x79, 0x40, 0x31, 0x40, 0xF4, + 0x80, 0x70, 0x01, 0xF0, 0x5D, 0xFE, 0x20, 0xB1, 0x20, 0x6A, 0x80, 0xF8, + 0x71, 0x50, 0x00, 0x20, 0x70, 0xBD, 0x08, 0x20, 0x70, 0xBD, 0x20, 0x46, + 0xBD, 0xE8, 0x70, 0x40, 0x00, 0xF0, 0x80, 0xBE, 0x64, 0x01, 0x20, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x28, 0x3C, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0xFE, 0xB5, 0x4D, 0x78, 0x00, 0xF1, 0x0C, 0x01, 0x04, 0x46, 0x06, 0x6A, + 0x0F, 0x46, 0x1F, 0x48, 0xE0, 0xF7, 0xF6, 0xD8, 0x03, 0x46, 0x21, 0x7F, + 0x30, 0x68, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x10, 0x04, 0x22, 0x1B, 0x49, + 0x1B, 0x48, 0xDF, 0xF7, 0x1C, 0xDF, 0x20, 0x7F, 0x10, 0xB9, 0x30, 0x68, + 0x81, 0x02, 0x01, 0xD5, 0x08, 0x20, 0xFE, 0xBD, 0x17, 0x49, 0x49, 0x7D, + 0x02, 0x29, 0x03, 0xD1, 0x29, 0x07, 0x01, 0xD4, 0x03, 0x20, 0xFE, 0xBD, + 0xC1, 0x07, 0x1C, 0xD1, 0x40, 0xF4, 0x00, 0x10, 0x30, 0x60, 0x94, 0xF8, + 0x24, 0x00, 0xB0, 0xB9, 0x00, 0x22, 0x11, 0x21, 0x20, 0x46, 0xFD, 0xF7, + 0xA5, 0xFD, 0x68, 0x07, 0x01, 0xD5, 0x08, 0x20, 0x00, 0xE0, 0x07, 0x20, + 0x84, 0xF8, 0x24, 0x00, 0xA0, 0x68, 0x12, 0x22, 0x20, 0xF4, 0x80, 0x50, + 0x40, 0xF4, 0xA0, 0x60, 0xA0, 0x60, 0xA1, 0x7C, 0x38, 0x46, 0xEB, 0xF7, + 0x7C, 0xFA, 0x00, 0x20, 0xFE, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0x68, 0x3F, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00, + 0x70, 0xB5, 0x04, 0x46, 0x4E, 0x1C, 0x05, 0x6A, 0x00, 0x22, 0x17, 0x49, + 0x17, 0x48, 0xDF, 0xF7, 0xDA, 0xDE, 0x20, 0x7A, 0x40, 0x07, 0x0C, 0xD5, + 0x28, 0x68, 0x01, 0x03, 0x09, 0xD4, 0x21, 0x7F, 0x11, 0xB1, 0x01, 0x29, + 0x02, 0xD0, 0x06, 0xE0, 0x69, 0x7A, 0x00, 0xE0, 0x29, 0x7A, 0x49, 0x07, + 0x01, 0xD4, 0x08, 0x20, 0x70, 0xBD, 0x40, 0xF4, 0x00, 0x20, 0x28, 0x60, + 0x68, 0x68, 0x10, 0x22, 0x31, 0x46, 0x68, 0x30, 0x11, 0xF4, 0xD3, 0xF7, + 0x10, 0x22, 0x31, 0x46, 0x04, 0xF1, 0x40, 0x00, 0x11, 0xF4, 0xCD, 0xF7, + 0x01, 0x20, 0x84, 0xF8, 0x29, 0x00, 0x00, 0x20, 0x20, 0x65, 0x20, 0x46, + 0x00, 0xF0, 0x1C, 0xFA, 0x00, 0x20, 0x70, 0xBD, 0x50, 0x3F, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xF8, 0x43, 0x0C, 0x46, 0x80, 0x46, + 0xFD, 0xF7, 0x6C, 0xFE, 0x05, 0x00, 0xE1, 0x88, 0xE0, 0x68, 0x2D, 0x4F, + 0x00, 0xEB, 0x01, 0x04, 0x26, 0x78, 0x09, 0xD0, 0x00, 0x96, 0x6B, 0x8B, + 0x02, 0x22, 0x2A, 0x49, 0xB8, 0x1C, 0xDF, 0xF7, 0x96, 0xDE, 0x28, 0x6A, + 0x50, 0xB1, 0x15, 0xE0, 0x01, 0xB0, 0x43, 0x46, 0x38, 0x46, 0xBD, 0xE8, + 0xF0, 0x43, 0x24, 0x49, 0x01, 0x22, 0x40, 0x39, 0xDF, 0xF7, 0x89, 0x9E, + 0x01, 0x2E, 0x05, 0xD0, 0x0B, 0x2E, 0x03, 0xD0, 0x1F, 0x49, 0x00, 0x22, + 0x68, 0x31, 0x14, 0xE0, 0x28, 0x46, 0xFD, 0xF7, 0xDB, 0xFB, 0x68, 0xB1, + 0x10, 0x2E, 0x30, 0xD2, 0x1B, 0x48, 0x21, 0x46, 0x50, 0xF8, 0x26, 0x20, + 0x28, 0x46, 0x90, 0x47, 0x04, 0x46, 0x08, 0x28, 0x0A, 0xD0, 0x09, 0x2C, + 0x08, 0xD0, 0x13, 0xE0, 0x14, 0x49, 0x00, 0x22, 0x34, 0x31, 0x38, 0x46, + 0xDF, 0xF7, 0x69, 0xDE, 0x08, 0x24, 0x0D, 0xE0, 0x05, 0x2E, 0x09, 0xD0, + 0x28, 0x6A, 0x0F, 0x49, 0x02, 0x22, 0x00, 0x68, 0x00, 0x90, 0x2B, 0x7F, + 0x94, 0x31, 0x38, 0x46, 0xDF, 0xF7, 0x5B, 0xDE, 0x00, 0x2C, 0x0E, 0xD0, + 0x05, 0x2E, 0x05, 0xD0, 0x28, 0x6A, 0x18, 0xB1, 0x21, 0x46, 0x28, 0x46, + 0x01, 0xF0, 0x22, 0xFD, 0x44, 0xF4, 0xA0, 0x61, 0x28, 0x46, 0xBD, 0xE8, + 0xF8, 0x43, 0xFD, 0xF7, 0x07, 0xBC, 0xBD, 0xE8, 0xF8, 0x83, 0x00, 0x00, + 0x00, 0x39, 0x10, 0x21, 0x18, 0x40, 0xC0, 0x08, 0x08, 0x74, 0x20, 0x00, + 0x70, 0xB5, 0x05, 0x46, 0xC8, 0xB2, 0xFD, 0xF7, 0x65, 0xFE, 0x04, 0x46, + 0x00, 0x22, 0x0E, 0x49, 0x0E, 0x48, 0xDF, 0xF7, 0x36, 0xDE, 0x00, 0x2C, + 0x15, 0xD0, 0x20, 0x46, 0xE8, 0xF7, 0xDA, 0xFB, 0x02, 0x2D, 0x10, 0xD1, + 0x20, 0x79, 0x00, 0x28, 0x0D, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x0A, 0xD0, + 0x40, 0xF2, 0xEC, 0x51, 0x20, 0x46, 0xFD, 0xF7, 0xE1, 0xFB, 0x60, 0x8B, + 0xBD, 0xE8, 0x70, 0x40, 0x05, 0x21, 0xF3, 0xF7, 0x8B, 0xBB, 0x70, 0xBD, + 0xB0, 0x41, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x0B, 0x78, + 0x01, 0x22, 0x03, 0x49, 0x03, 0x48, 0xDF, 0xF7, 0x12, 0xDE, 0x07, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0xB0, 0x3F, 0xC0, 0x08, 0x01, 0x39, 0x10, 0x21, + 0x70, 0xB5, 0x24, 0x4A, 0x24, 0x49, 0x10, 0x1F, 0xE7, 0xF7, 0x54, 0xFD, + 0x00, 0x28, 0x1E, 0xD0, 0x20, 0x48, 0x0C, 0x30, 0xE8, 0xF7, 0x55, 0xF9, + 0x1E, 0x4C, 0x10, 0x20, 0x1F, 0x4D, 0xE0, 0x75, 0x01, 0x20, 0x60, 0x75, + 0xA0, 0x75, 0x1E, 0x20, 0x20, 0x75, 0x00, 0x26, 0x26, 0x76, 0x95, 0xF8, + 0x98, 0x01, 0x3D, 0x23, 0xC0, 0xEB, 0xC0, 0x00, 0x01, 0x01, 0x19, 0x4A, + 0x30, 0x46, 0xEA, 0xF7, 0x7F, 0xDB, 0x60, 0x60, 0x20, 0xB9, 0x95, 0xF8, + 0x98, 0x01, 0x08, 0xB1, 0x00, 0x20, 0x70, 0xBD, 0x10, 0x48, 0x24, 0x30, + 0xE8, 0xF7, 0x35, 0xF9, 0x84, 0xF8, 0x46, 0x60, 0x4F, 0xF6, 0xFF, 0x70, + 0xA0, 0x85, 0x4F, 0xF0, 0xFF, 0x30, 0x20, 0x62, 0x03, 0x20, 0x84, 0xF8, + 0x59, 0x00, 0x84, 0xF8, 0x5A, 0x00, 0x95, 0xF8, 0xAA, 0x01, 0x50, 0xB1, + 0x00, 0xEB, 0x40, 0x00, 0x41, 0x00, 0x52, 0x23, 0x07, 0x4A, 0x00, 0x20, + 0xEA, 0xF7, 0x5C, 0xDB, 0xE0, 0x61, 0x00, 0x28, 0xDF, 0xD0, 0x01, 0x20, + 0x70, 0xBD, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, 0xBD, 0x5F, 0x82, 0x00, + 0x64, 0x01, 0x20, 0x00, 0xD6, 0xA8, 0x82, 0x00, 0x70, 0xB5, 0x15, 0x46, + 0xFD, 0xF7, 0xB4, 0xFD, 0x04, 0x00, 0x29, 0xD0, 0x20, 0x6A, 0x00, 0x28, + 0x26, 0xD0, 0x01, 0x2D, 0x0A, 0xD0, 0x08, 0x21, 0x20, 0x46, 0x01, 0xF0, + 0x7B, 0xFC, 0x20, 0x46, 0xBD, 0xE8, 0x70, 0x40, 0x4F, 0xF4, 0xA1, 0x61, + 0xFD, 0xF7, 0x60, 0xBB, 0x94, 0xF8, 0x6B, 0x10, 0x01, 0x25, 0x41, 0xB1, + 0x21, 0x7F, 0x09, 0xB9, 0x80, 0xF8, 0x73, 0x50, 0x20, 0x46, 0xBD, 0xE8, + 0x70, 0x40, 0x00, 0xF0, 0x71, 0xBC, 0xE5, 0x84, 0x60, 0x79, 0x40, 0xF4, + 0x80, 0x70, 0x01, 0xF0, 0x95, 0xFA, 0x20, 0x6A, 0x80, 0xF8, 0x80, 0x50, + 0x21, 0x6A, 0x00, 0x20, 0x81, 0xF8, 0x81, 0x00, 0x70, 0xBD, 0x00, 0x00, + 0x2D, 0xE9, 0xFC, 0x41, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x00, 0x24, + 0xFD, 0xF7, 0x7E, 0xFD, 0xDF, 0xF8, 0x54, 0xC0, 0x28, 0xB1, 0x03, 0x6A, + 0xC3, 0xB1, 0x99, 0x7A, 0x02, 0x29, 0x15, 0xD1, 0x06, 0xE0, 0x00, 0x22, + 0x11, 0x49, 0x60, 0x46, 0xDF, 0xF7, 0x71, 0xDD, 0x04, 0x24, 0x05, 0xE0, + 0x90, 0xF8, 0x6C, 0x10, 0x51, 0xB1, 0x29, 0x46, 0x01, 0xF0, 0xA2, 0xF8, + 0x02, 0xB0, 0x32, 0x46, 0x39, 0x46, 0x20, 0x46, 0xBD, 0xE8, 0xF0, 0x41, + 0xEB, 0xF7, 0x30, 0xB9, 0x01, 0x7F, 0x90, 0xF8, 0x6C, 0x00, 0xCD, 0xE9, + 0x00, 0x01, 0x05, 0x49, 0x03, 0x22, 0x2C, 0x31, 0x60, 0x46, 0xDF, 0xF7, + 0x56, 0xDD, 0x05, 0x24, 0xEA, 0xE7, 0x00, 0x00, 0x00, 0x39, 0x10, 0x21, + 0x74, 0x24, 0xC0, 0x08, 0x00, 0xB5, 0x85, 0xB0, 0x8D, 0xF8, 0x0C, 0x30, + 0x8D, 0xF8, 0x0D, 0x10, 0x03, 0x21, 0xAD, 0xF8, 0x0A, 0x20, 0x8D, 0xF8, + 0x0E, 0x10, 0x01, 0x68, 0x01, 0x91, 0x80, 0x88, 0xAD, 0xF8, 0x08, 0x00, + 0x40, 0xF2, 0x02, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x05, 0x48, 0x40, 0xF2, + 0x71, 0x23, 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE7, 0xF7, 0xCE, 0xFD, + 0x05, 0xB0, 0x00, 0xBD, 0xF5, 0xA8, 0x82, 0x00, 0x84, 0x76, 0x20, 0x00, + 0xF8, 0xB5, 0x04, 0x46, 0x07, 0x6A, 0x90, 0xF8, 0x5A, 0x00, 0x00, 0x90, + 0x16, 0x46, 0x0D, 0x46, 0x63, 0x7E, 0x02, 0x22, 0x16, 0x49, 0x17, 0x48, + 0xDF, 0xF7, 0x1F, 0xDD, 0x60, 0x7E, 0x21, 0x7F, 0x29, 0xB1, 0x94, 0xF8, + 0x5A, 0x10, 0x29, 0x70, 0x21, 0x7F, 0x11, 0xB1, 0x03, 0xE0, 0x01, 0x46, + 0xF9, 0xE7, 0x94, 0xF8, 0x5A, 0x00, 0x68, 0x70, 0xD7, 0xF8, 0x0B, 0x00, + 0xC5, 0xF8, 0x02, 0x00, 0xB7, 0xF8, 0x0F, 0x00, 0xE8, 0x80, 0x78, 0x7C, + 0x28, 0x72, 0xD7, 0xF8, 0x12, 0x00, 0xC5, 0xF8, 0x09, 0x00, 0xF8, 0x8A, + 0xA5, 0xF8, 0x0D, 0x00, 0x38, 0x7E, 0xE8, 0x73, 0x00, 0x20, 0x29, 0x5C, + 0x32, 0x5C, 0x51, 0x40, 0x29, 0x54, 0x40, 0x1C, 0x80, 0xB2, 0x10, 0x28, + 0xF7, 0xD3, 0xF8, 0xBD, 0xD8, 0x43, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xFC, 0x47, 0x00, 0xF1, 0x54, 0x06, 0xDF, 0xF8, 0x70, 0x90, + 0x90, 0x46, 0x0C, 0x46, 0x05, 0x46, 0x00, 0xF1, 0x13, 0x07, 0x32, 0x46, + 0x06, 0x21, 0x48, 0x46, 0xDF, 0xF7, 0x4D, 0xDF, 0x82, 0x46, 0x3A, 0x46, + 0x06, 0x21, 0x48, 0x46, 0xDF, 0xF7, 0x47, 0xDF, 0xCD, 0xE9, 0x00, 0x0A, + 0x6B, 0x7E, 0x03, 0x22, 0x12, 0x49, 0x13, 0x48, 0xDF, 0xF7, 0xD3, 0xDC, + 0x28, 0x7F, 0xC8, 0xB1, 0x38, 0x46, 0x01, 0x68, 0x21, 0x60, 0x80, 0x88, + 0xA0, 0x80, 0x28, 0x7F, 0xA0, 0xB1, 0x32, 0x46, 0x10, 0x68, 0xC4, 0xF8, + 0x06, 0x00, 0x90, 0x88, 0x60, 0x81, 0x00, 0x20, 0xE0, 0x60, 0x21, 0x5C, + 0x18, 0xF8, 0x00, 0x20, 0x51, 0x40, 0x21, 0x54, 0x40, 0x1C, 0x80, 0xB2, + 0x10, 0x28, 0xF6, 0xD3, 0xBD, 0xE8, 0xFC, 0x87, 0x30, 0x46, 0xE4, 0xE7, + 0x3A, 0x46, 0xE9, 0xE7, 0x00, 0x00, 0x50, 0x21, 0x20, 0x44, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x10, 0xB5, 0x02, 0x6A, 0x03, 0x7F, 0x52, 0x68, + 0x6B, 0xB1, 0x02, 0xF1, 0x30, 0x03, 0x1C, 0x68, 0x0C, 0x60, 0x5B, 0x68, + 0x4B, 0x60, 0x00, 0x7F, 0x40, 0xB1, 0x10, 0x32, 0x10, 0x68, 0x88, 0x60, + 0x50, 0x68, 0xC8, 0x60, 0x10, 0xBD, 0x02, 0xF1, 0x10, 0x03, 0xF0, 0xE7, + 0x30, 0x32, 0xF5, 0xE7, 0x2D, 0xE9, 0xF0, 0x4F, 0x8B, 0xB0, 0x05, 0x46, + 0x2C, 0x6A, 0x2A, 0x7F, 0x60, 0x7A, 0x27, 0x7A, 0x01, 0x2A, 0x7D, 0xD0, + 0x3E, 0x46, 0x07, 0x46, 0x95, 0xF8, 0x6B, 0x00, 0x38, 0xB3, 0x94, 0xF8, + 0x82, 0x00, 0x20, 0xB3, 0x1C, 0x21, 0x68, 0x46, 0x11, 0xF4, 0x34, 0xF6, + 0xE8, 0x79, 0x8D, 0xF8, 0x1A, 0x00, 0xA8, 0x79, 0x8D, 0xF8, 0x1B, 0x00, + 0x10, 0x22, 0x05, 0xF1, 0x5B, 0x01, 0x68, 0x46, 0x11, 0xF4, 0x87, 0xF5, + 0x28, 0x6A, 0x1C, 0x22, 0x69, 0x46, 0x40, 0x68, 0x11, 0xF4, 0xC6, 0xF5, + 0x28, 0x6A, 0x1C, 0x22, 0x69, 0x46, 0x40, 0x68, 0x1C, 0x30, 0x11, 0xF4, + 0xBF, 0xF5, 0x20, 0x68, 0x26, 0xF0, 0x01, 0x06, 0x40, 0xF4, 0x70, 0x50, + 0x27, 0xF0, 0x01, 0x07, 0x20, 0x60, 0x60, 0x68, 0x05, 0x22, 0x90, 0xF8, + 0x81, 0x10, 0x90, 0xF8, 0x80, 0x00, 0xCD, 0xE9, 0x02, 0x01, 0xCD, 0xE9, + 0x00, 0x67, 0x7B, 0x49, 0x7B, 0x48, 0x23, 0x68, 0xDF, 0xF7, 0x4F, 0xDC, + 0x20, 0x68, 0x01, 0x01, 0x78, 0xD4, 0xDF, 0xF8, 0xE4, 0x91, 0x05, 0xF1, + 0x0C, 0x01, 0x08, 0x91, 0x09, 0xF1, 0x49, 0x01, 0x42, 0x05, 0x4F, 0xF0, + 0x00, 0x08, 0x09, 0xF1, 0x2E, 0x0A, 0x09, 0xF1, 0x40, 0x0B, 0x09, 0x91, + 0x06, 0xD5, 0xC1, 0x04, 0x04, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x80, 0x10, + 0xC9, 0x07, 0x31, 0xD0, 0x01, 0x05, 0x06, 0xD5, 0x81, 0x04, 0x04, 0xD5, + 0x63, 0x68, 0x93, 0xF8, 0x81, 0x10, 0xC9, 0x07, 0x2E, 0xD0, 0x41, 0x04, + 0x36, 0xD5, 0xC1, 0x03, 0x34, 0xD5, 0x61, 0x68, 0x91, 0xF8, 0x80, 0x10, + 0x89, 0x07, 0x2F, 0xD4, 0x18, 0x21, 0x02, 0xA8, 0x11, 0xF4, 0xD4, 0xF5, + 0x10, 0x22, 0x02, 0xA8, 0x09, 0x99, 0x11, 0xF4, 0x2E, 0xF5, 0x99, 0xF8, + 0x46, 0x10, 0x09, 0xB3, 0x58, 0x46, 0x02, 0x68, 0x06, 0x92, 0x80, 0x88, + 0xAD, 0xF8, 0x1C, 0x00, 0x8D, 0xF8, 0x1E, 0x10, 0x13, 0x21, 0x00, 0xE0, + 0x06, 0xE0, 0xCD, 0xE9, 0x00, 0x18, 0xA9, 0x7C, 0x02, 0xAB, 0x17, 0x22, + 0x08, 0x98, 0x40, 0xE0, 0x06, 0x46, 0x79, 0xE7, 0x11, 0x21, 0xCD, 0xE9, + 0x00, 0x18, 0xA9, 0x7C, 0x1C, 0x22, 0xF5, 0xE7, 0x12, 0x21, 0xCD, 0xE9, + 0x00, 0x18, 0x1C, 0x22, 0xA9, 0x7C, 0x1C, 0x33, 0x08, 0x98, 0x30, 0xE0, + 0x50, 0x46, 0xDC, 0xE7, 0x01, 0x04, 0x0E, 0xD5, 0x81, 0x03, 0x0C, 0xD5, + 0x63, 0x68, 0x93, 0xF8, 0x81, 0x10, 0x89, 0x07, 0x07, 0xD4, 0x14, 0x21, + 0xCD, 0xE9, 0x00, 0x18, 0x17, 0x22, 0xA9, 0x7C, 0x38, 0x33, 0x08, 0x98, + 0x1D, 0xE0, 0x41, 0x03, 0x0D, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x80, 0x10, + 0x49, 0x07, 0x08, 0xD4, 0x15, 0x21, 0xCD, 0xE9, 0x00, 0x18, 0x18, 0x22, + 0xA9, 0x7C, 0x50, 0x33, 0x08, 0x98, 0x0E, 0xE0, 0x70, 0xE0, 0x00, 0x03, + 0x13, 0xD5, 0x63, 0x68, 0x93, 0xF8, 0x81, 0x00, 0x40, 0x07, 0x0E, 0xD4, + 0x16, 0x21, 0xCD, 0xE9, 0x00, 0x18, 0xA9, 0x7C, 0x18, 0x22, 0x68, 0x33, + 0x08, 0x98, 0xE8, 0xF7, 0x15, 0xFA, 0x20, 0x68, 0x40, 0xF0, 0x00, 0x60, + 0x20, 0x60, 0x00, 0x01, 0x5A, 0xD4, 0x28, 0x7F, 0x28, 0xB9, 0x39, 0x46, + 0x28, 0x46, 0xFD, 0xF7, 0xBD, 0xFA, 0x00, 0x28, 0x52, 0xD0, 0xF0, 0x07, + 0x10, 0xD0, 0x20, 0x68, 0x41, 0x05, 0x01, 0xD4, 0x11, 0x20, 0x02, 0xE0, + 0xC0, 0x04, 0x09, 0xD4, 0x13, 0x20, 0xE8, 0x84, 0x68, 0x79, 0x0B, 0xB0, + 0x40, 0xF4, 0x80, 0x70, 0xBD, 0xE8, 0xF0, 0x4F, 0x01, 0xF0, 0xA6, 0xB8, + 0xB0, 0x07, 0x23, 0xD5, 0x20, 0x88, 0x40, 0x04, 0x20, 0xD4, 0x28, 0x46, + 0x09, 0x99, 0x01, 0xF0, 0x09, 0xF9, 0x20, 0x68, 0xC0, 0x03, 0x06, 0xD4, + 0x99, 0xF8, 0x46, 0x10, 0xA1, 0xB1, 0x5A, 0x46, 0x28, 0x46, 0x01, 0xF0, + 0xAF, 0xF8, 0x70, 0x07, 0x7F, 0xF5, 0xFA, 0xAE, 0x20, 0x68, 0x40, 0x03, + 0x3F, 0xF5, 0xF6, 0xAE, 0x28, 0x46, 0xFD, 0xF7, 0xE3, 0xFB, 0x28, 0x6A, + 0x41, 0x68, 0x28, 0x46, 0x50, 0x31, 0x01, 0xF0, 0x6F, 0xFB, 0xEB, 0xE6, + 0x52, 0x46, 0xE9, 0xE7, 0x70, 0x07, 0x02, 0xD5, 0x20, 0x68, 0x40, 0x03, + 0xEE, 0xD5, 0x28, 0x7F, 0x01, 0x28, 0x05, 0xD1, 0x39, 0x46, 0x28, 0x46, + 0xFD, 0xF7, 0x76, 0xFA, 0x00, 0x28, 0x0B, 0xD0, 0x00, 0x22, 0x15, 0x21, + 0x28, 0x46, 0xFD, 0xF7, 0x0D, 0xFA, 0x0B, 0xB0, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x4F, 0x00, 0x21, 0xFD, 0xF7, 0x1E, 0xB9, 0x0B, 0xB0, 0xBD, 0xE8, + 0xF0, 0x8F, 0x00, 0x00, 0x30, 0x39, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x00, 0x28, 0x05, 0xD0, 0x01, 0x46, + 0x87, 0x22, 0x02, 0x48, 0x11, 0xF4, 0x63, 0xF4, 0x01, 0x20, 0x10, 0xBD, + 0xE3, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x20, 0xB1, 0x01, 0x46, 0x27, 0x22, + 0x02, 0x48, 0x11, 0xF4, 0x58, 0xF4, 0x01, 0x20, 0x10, 0xBD, 0x00, 0x00, + 0x6A, 0x77, 0x20, 0x00, 0x38, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0xFD, 0xF7, + 0x39, 0xFB, 0x00, 0x28, 0x0A, 0xD1, 0x29, 0x46, 0x05, 0x48, 0xDF, 0xF7, + 0x03, 0xDD, 0x03, 0x46, 0x02, 0x22, 0x04, 0x49, 0x04, 0x48, 0x00, 0x94, + 0xDF, 0xF7, 0x2D, 0xDB, 0x38, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0xE4, 0x22, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, 0x2D, 0xE9, 0xFE, 0x4F, + 0x1D, 0x46, 0x16, 0x46, 0x88, 0x46, 0x82, 0x46, 0x00, 0x27, 0xFD, 0xF7, + 0x1B, 0xFB, 0x04, 0x00, 0x7E, 0xD0, 0x4B, 0x48, 0x90, 0xF8, 0x78, 0x01, + 0x80, 0x07, 0x07, 0xD5, 0x49, 0x48, 0x80, 0x68, 0xFA, 0x28, 0x03, 0xD1, + 0x01, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xDE, 0xF9, 0x20, 0x6A, 0x00, 0x28, + 0x6E, 0xD0, 0x94, 0xF8, 0x6B, 0x10, 0x40, 0xF2, 0x01, 0x59, 0xD9, 0xB3, + 0x90, 0xF8, 0x7D, 0x00, 0x21, 0x7F, 0x00, 0x95, 0xCD, 0xE9, 0x01, 0x10, + 0x33, 0x46, 0x04, 0x22, 0x3E, 0x49, 0x3F, 0x48, 0xDF, 0xF7, 0xF9, 0xDA, + 0x20, 0x6A, 0x00, 0x22, 0x81, 0x7A, 0x02, 0x29, 0x02, 0xD0, 0x05, 0x29, + 0x19, 0xD0, 0x56, 0xE0, 0x3E, 0xBB, 0x80, 0xF8, 0x7C, 0x20, 0x20, 0x6A, + 0x85, 0x67, 0x20, 0x6A, 0x80, 0xF8, 0x74, 0x20, 0x20, 0x7F, 0x01, 0x28, + 0x20, 0x6A, 0x07, 0xD0, 0x90, 0xF8, 0x7D, 0x00, 0x38, 0xB3, 0x0C, 0x21, + 0x20, 0x46, 0x00, 0xF0, 0xEF, 0xFC, 0x42, 0xE0, 0x90, 0xF8, 0x7E, 0x00, + 0xF8, 0xB1, 0x03, 0x21, 0xF6, 0xE7, 0x85, 0x67, 0x20, 0x6A, 0x80, 0xF8, + 0x74, 0x20, 0x20, 0x6A, 0x81, 0x6F, 0x01, 0x29, 0x08, 0xD0, 0x0C, 0x21, + 0x20, 0x46, 0x01, 0xF0, 0x9D, 0xF9, 0x40, 0xF2, 0x0C, 0x51, 0x20, 0xE0, + 0x0E, 0xE0, 0x19, 0xE0, 0x21, 0x7F, 0x01, 0x29, 0x06, 0xD1, 0x90, 0xF8, + 0x7F, 0x10, 0x31, 0xB1, 0x01, 0x68, 0x41, 0xF0, 0x00, 0x51, 0x01, 0x60, + 0x20, 0x46, 0x00, 0xF0, 0xFD, 0xFB, 0x1E, 0xE0, 0x81, 0x7A, 0x02, 0x29, + 0x01, 0xD0, 0x05, 0x29, 0x19, 0xD1, 0x40, 0x68, 0x29, 0x0A, 0x05, 0x70, + 0x41, 0x70, 0x29, 0x0C, 0x81, 0x70, 0x4E, 0xB1, 0x01, 0x21, 0x20, 0x46, + 0x01, 0xF0, 0x7A, 0xF9, 0x49, 0x46, 0x20, 0x46, 0xFD, 0xF7, 0x62, 0xF8, + 0x09, 0xE0, 0x07, 0xE0, 0x01, 0x20, 0xE0, 0x84, 0x60, 0x79, 0x40, 0xF4, + 0x80, 0x70, 0x00, 0xF0, 0xA1, 0xFF, 0x00, 0xE0, 0x05, 0x27, 0x39, 0x46, + 0x15, 0x20, 0xEC, 0xF7, 0xAA, 0xFA, 0x00, 0x2C, 0x0D, 0xD1, 0x51, 0x46, + 0x0B, 0x48, 0xDF, 0xF7, 0x5F, 0xDC, 0x03, 0x46, 0x07, 0x49, 0x08, 0x48, + 0x02, 0x22, 0x68, 0x31, 0xC0, 0x1E, 0xCD, 0xF8, 0x00, 0x80, 0xDF, 0xF7, + 0x86, 0xDA, 0xBD, 0xE8, 0xFE, 0x8F, 0x00, 0x00, 0x64, 0x01, 0x20, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x2C, 0x23, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x00, 0x00, 0x30, 0x21, 0x10, 0xB5, 0x0A, 0x4C, 0xA1, 0x8D, 0xCA, 0x05, + 0x0F, 0xD5, 0x40, 0x79, 0xCB, 0xB2, 0x98, 0x42, 0x0B, 0xD1, 0x01, 0x22, + 0x06, 0x49, 0x07, 0x48, 0xDF, 0xF7, 0x6B, 0xDA, 0x4F, 0xF6, 0xFF, 0x70, + 0xA0, 0x85, 0xBD, 0xE8, 0x10, 0x40, 0x01, 0xF0, 0x59, 0xBB, 0x10, 0xBD, + 0x88, 0x76, 0x20, 0x00, 0xC8, 0x44, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, + 0x00, 0xB5, 0x80, 0x88, 0xFD, 0xF7, 0x3C, 0xFA, 0x18, 0xB1, 0x00, 0x21, + 0x01, 0x70, 0x08, 0x46, 0x00, 0xBD, 0x40, 0xF2, 0xE1, 0x50, 0x00, 0xBD, + 0x10, 0xB5, 0x04, 0x00, 0x06, 0xD0, 0xE7, 0xF7, 0xF5, 0xFF, 0x20, 0x46, + 0x00, 0xF0, 0x04, 0xF8, 0x00, 0x20, 0x20, 0x71, 0x10, 0xBD, 0x00, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x00, 0x28, 0x14, 0xD0, 0x40, 0x68, + 0x40, 0xF2, 0x5D, 0x22, 0x09, 0x49, 0xE7, 0xF7, 0xBD, 0xF8, 0x20, 0x6A, + 0x40, 0xF2, 0x5F, 0x22, 0x06, 0x49, 0xC0, 0x6B, 0xE7, 0xF7, 0xB6, 0xF8, + 0x40, 0xF2, 0x61, 0x22, 0x03, 0x49, 0x20, 0x6A, 0xE7, 0xF7, 0xB0, 0xF8, + 0x00, 0x20, 0x20, 0x62, 0x10, 0xBD, 0x00, 0x00, 0xB6, 0xAA, 0x82, 0x00, + 0x2D, 0xE9, 0xFE, 0x43, 0x90, 0x46, 0x0E, 0x46, 0x07, 0x46, 0x0A, 0x9D, + 0xFD, 0xF7, 0x1E, 0xFA, 0x04, 0x46, 0x39, 0x46, 0x18, 0x48, 0xDF, 0xF7, + 0xE9, 0xDB, 0x03, 0x46, 0x00, 0x96, 0x04, 0x22, 0x16, 0x49, 0x17, 0x48, + 0xCD, 0xE9, 0x01, 0x45, 0xDF, 0xF7, 0x11, 0xDA, 0x00, 0x2C, 0x20, 0xD0, + 0x20, 0x6A, 0x00, 0x28, 0x1D, 0xD0, 0x81, 0x7A, 0x03, 0x29, 0x1A, 0xD1, + 0x40, 0x68, 0x10, 0x22, 0x41, 0x46, 0x11, 0xF4, 0x18, 0xF3, 0x5D, 0xB1, + 0x02, 0x21, 0x20, 0x46, 0x01, 0xF0, 0xD0, 0xF8, 0x03, 0xB0, 0x20, 0x46, + 0xBD, 0xE8, 0xF0, 0x43, 0x40, 0xF2, 0x02, 0x51, 0xFC, 0xF7, 0xB4, 0xBF, + 0x01, 0x20, 0xE0, 0x84, 0x60, 0x79, 0xBD, 0xE8, 0xFE, 0x43, 0x40, 0xF4, + 0x80, 0x70, 0x00, 0xF0, 0xF3, 0xBE, 0xBD, 0xE8, 0xFE, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0x94, 0x22, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x43, 0x04, 0x46, 0x00, 0x6A, 0x21, 0x7F, 0x8F, 0xB0, + 0x00, 0x29, 0x41, 0x68, 0x0A, 0x46, 0x58, 0xD0, 0x63, 0x6D, 0x06, 0x93, + 0xB4, 0xF8, 0x58, 0x30, 0xAD, 0xF8, 0x1C, 0x30, 0x94, 0xF8, 0x5A, 0x30, + 0x8D, 0xF8, 0x1E, 0x30, 0xD4, 0xF8, 0x13, 0x30, 0x08, 0x93, 0xB4, 0xF8, + 0x17, 0x30, 0xAD, 0xF8, 0x24, 0x30, 0x63, 0x7E, 0x30, 0x31, 0x8D, 0xF8, + 0x26, 0x30, 0x10, 0x32, 0x00, 0xF1, 0x60, 0x05, 0x08, 0xAE, 0x0A, 0xAB, + 0x00, 0x96, 0xCD, 0xE9, 0x01, 0x53, 0x40, 0x30, 0x06, 0xAB, 0x07, 0x46, + 0x0E, 0xF4, 0x87, 0xF2, 0x04, 0xF1, 0x5B, 0x00, 0x10, 0x22, 0x0A, 0xA9, + 0x06, 0x46, 0x11, 0xF4, 0xC6, 0xF2, 0x32, 0x46, 0x22, 0x4E, 0x10, 0x21, + 0x30, 0x46, 0xDF, 0xF7, 0x18, 0xDC, 0x80, 0x46, 0x2A, 0x46, 0x10, 0x21, + 0x30, 0x46, 0xDF, 0xF7, 0x12, 0xDC, 0x05, 0x46, 0x3A, 0x46, 0x20, 0x21, + 0x30, 0x46, 0xDF, 0xF7, 0x0C, 0xDC, 0x07, 0x46, 0x04, 0xF1, 0x13, 0x02, + 0x06, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0x05, 0xDC, 0x81, 0x46, 0x17, 0x4A, + 0x06, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0xFF, 0xDB, 0x03, 0x46, 0xA0, 0x7C, + 0xCD, 0xE9, 0x02, 0x07, 0xCD, 0xE9, 0x04, 0x58, 0x61, 0x7E, 0x07, 0x22, + 0xCD, 0xE9, 0x00, 0x91, 0x10, 0x49, 0x11, 0x48, 0xDF, 0xF7, 0x85, 0xD9, + 0x0F, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xD4, 0xF8, 0x13, 0x30, 0x06, 0x93, + 0xB4, 0xF8, 0x17, 0x30, 0xAD, 0xF8, 0x1C, 0x30, 0x63, 0x7E, 0x8D, 0xF8, + 0x1E, 0x30, 0x63, 0x6D, 0x08, 0x93, 0xB4, 0xF8, 0x58, 0x30, 0xAD, 0xF8, + 0x24, 0x30, 0x94, 0xF8, 0x5A, 0x30, 0x10, 0x31, 0x8D, 0xF8, 0x26, 0x30, + 0x30, 0x32, 0xA5, 0xE7, 0x00, 0x00, 0x50, 0x21, 0xB6, 0x76, 0x20, 0x00, + 0x60, 0x34, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x70, 0xB5, 0x02, 0x6A, + 0x04, 0x46, 0x00, 0x25, 0x92, 0xF8, 0x71, 0x00, 0x02, 0x28, 0x01, 0xD0, + 0x28, 0xB1, 0x2D, 0xE0, 0x20, 0x46, 0x00, 0xF0, 0x9D, 0xF8, 0x05, 0x46, + 0x28, 0xE0, 0x60, 0x79, 0xD1, 0x6B, 0x40, 0xF4, 0x80, 0x70, 0x40, 0x31, + 0x19, 0x32, 0x01, 0xF0, 0x63, 0xF8, 0x01, 0x26, 0x38, 0xB1, 0x20, 0x6A, + 0x80, 0xF8, 0x71, 0x60, 0x20, 0x6A, 0x81, 0x7A, 0x02, 0x29, 0x07, 0xD0, + 0x16, 0xE0, 0x00, 0x22, 0x0B, 0x49, 0x0C, 0x48, 0xDF, 0xF7, 0x3D, 0xD9, + 0x08, 0x25, 0xF3, 0xE7, 0x90, 0xF8, 0x84, 0x00, 0x60, 0xB9, 0x94, 0xF8, + 0x6C, 0x20, 0xA1, 0x7C, 0x04, 0xF1, 0x0C, 0x00, 0xEC, 0xF7, 0x45, 0xF8, + 0x20, 0x6A, 0x80, 0xF8, 0x74, 0x60, 0x20, 0x6A, 0x80, 0xF8, 0x84, 0x60, + 0x28, 0x46, 0x70, 0xBD, 0x1C, 0x2E, 0xC0, 0x08, 0x00, 0x39, 0x10, 0x21, + 0x10, 0xB5, 0x04, 0x46, 0x00, 0x6A, 0x01, 0x22, 0x13, 0x49, 0x90, 0xF8, + 0x70, 0x30, 0x13, 0x48, 0xDF, 0xF7, 0x1B, 0xD9, 0x20, 0x6A, 0x90, 0xF8, + 0x70, 0x00, 0x48, 0xB9, 0x60, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x01, 0xF0, + 0x6D, 0xF8, 0x60, 0xB1, 0x21, 0x6A, 0x01, 0x20, 0x81, 0xF8, 0x70, 0x00, + 0x20, 0x6A, 0x90, 0xF8, 0x73, 0x10, 0x61, 0xB1, 0x90, 0xF8, 0x70, 0x00, + 0x02, 0x28, 0x02, 0xD0, 0x07, 0xE0, 0x08, 0x20, 0x10, 0xBD, 0x20, 0x46, + 0x00, 0xF0, 0xD2, 0xFC, 0x20, 0x46, 0x01, 0xF0, 0xD7, 0xF9, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0xF0, 0x2D, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x41, 0x04, 0x6A, 0x05, 0x46, 0xA0, 0x7A, 0x02, 0x28, + 0x0E, 0xD0, 0x01, 0x28, 0x0C, 0xD0, 0x28, 0x7F, 0x00, 0x28, 0x07, 0xD1, + 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x0B, 0xD0, 0x02, 0x26, 0xC8, 0xB1, + 0x84, 0xF8, 0x81, 0x60, 0xBD, 0xE8, 0xF0, 0x81, 0x28, 0x46, 0xBD, 0xE8, + 0xF0, 0x41, 0x03, 0x21, 0x00, 0xF0, 0xEA, 0xBA, 0x00, 0x22, 0x0D, 0x49, + 0x0D, 0x48, 0xDF, 0xF7, 0xD4, 0xD8, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46, + 0x10, 0x32, 0x00, 0xF0, 0x3F, 0xFD, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x41, + 0x01, 0xF0, 0xA4, 0xB9, 0x01, 0x27, 0xEF, 0x84, 0x68, 0x79, 0x40, 0xF4, + 0x80, 0x70, 0x00, 0xF0, 0xC7, 0xFD, 0x04, 0xF8, 0x80, 0x7F, 0x66, 0x70, + 0xDC, 0xE7, 0x00, 0x00, 0x24, 0x37, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x4F, 0xDF, 0xF8, 0x5C, 0x82, 0x04, 0x6A, 0x05, 0x46, + 0x87, 0xB0, 0x04, 0xF1, 0x19, 0x02, 0x20, 0x21, 0x46, 0x46, 0x40, 0x46, + 0xDF, 0xF7, 0x17, 0xDB, 0xE2, 0x6B, 0x81, 0x46, 0x40, 0x21, 0x30, 0x46, + 0x40, 0x32, 0xDF, 0xF7, 0x10, 0xDB, 0x07, 0x46, 0x04, 0xF1, 0x40, 0x02, + 0x20, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0x09, 0xDB, 0xCD, 0xE9, 0x00, 0x79, + 0x03, 0x46, 0x03, 0x22, 0x89, 0x49, 0x8A, 0x48, 0xDF, 0xF7, 0x95, 0xD8, + 0xA0, 0x7A, 0x01, 0x26, 0x02, 0x28, 0x19, 0xD0, 0x01, 0x28, 0x35, 0xD0, + 0x00, 0x27, 0xDF, 0xF8, 0x18, 0x92, 0x03, 0x28, 0x37, 0xD0, 0x28, 0x7F, + 0x00, 0x28, 0x0C, 0xD0, 0x94, 0xF8, 0x80, 0x30, 0x02, 0x2B, 0x71, 0xD0, + 0x7E, 0x49, 0x84, 0xF8, 0x81, 0x60, 0x01, 0x22, 0xD0, 0x31, 0x7D, 0x48, + 0xDF, 0xF7, 0x7B, 0xD8, 0x00, 0x20, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, + 0x28, 0x7F, 0x01, 0x28, 0x0B, 0xD0, 0x94, 0xF8, 0x74, 0x00, 0x00, 0x28, + 0xF4, 0xD1, 0x20, 0x78, 0xC0, 0x06, 0xF1, 0xD4, 0x0C, 0x21, 0x28, 0x46, + 0x00, 0xF0, 0x7A, 0xFA, 0xEC, 0xE7, 0x94, 0xF8, 0x84, 0x00, 0x00, 0x28, + 0xE8, 0xD1, 0x95, 0xF8, 0x6C, 0x20, 0xA9, 0x7C, 0x05, 0xF1, 0x0C, 0x00, + 0xEB, 0xF7, 0x71, 0xFF, 0x04, 0xF8, 0x74, 0x6F, 0x26, 0x74, 0xDD, 0xE7, + 0x07, 0xB0, 0x28, 0x46, 0xBD, 0xE8, 0xF0, 0x4F, 0x0C, 0x21, 0x00, 0xF0, + 0x63, 0xBA, 0x29, 0x6A, 0x91, 0xF8, 0x83, 0x00, 0x02, 0x28, 0x01, 0xD0, + 0x03, 0x28, 0x3A, 0xD1, 0x02, 0xA8, 0x00, 0x90, 0x63, 0x4A, 0xC8, 0x6B, + 0xE3, 0x32, 0x40, 0x30, 0x00, 0x23, 0x93, 0x46, 0x01, 0x46, 0x0E, 0xF4, + 0xF4, 0xF0, 0x02, 0xAA, 0x10, 0x21, 0x46, 0x46, 0x40, 0x46, 0xDF, 0xF7, + 0xA6, 0xDA, 0x82, 0x46, 0x5A, 0x46, 0x10, 0x21, 0x30, 0x46, 0xDF, 0xF7, + 0xA0, 0xDA, 0x80, 0x46, 0x28, 0x6A, 0x10, 0x21, 0xC2, 0x6B, 0x30, 0x46, + 0x40, 0x32, 0xDF, 0xF7, 0x98, 0xDA, 0x53, 0x49, 0xCD, 0xE9, 0x00, 0x8A, + 0x03, 0x46, 0x03, 0x22, 0x4C, 0x31, 0x51, 0x48, 0xDF, 0xF7, 0x23, 0xD8, + 0x50, 0x48, 0x10, 0x22, 0x02, 0xA9, 0xF3, 0x30, 0x11, 0xF4, 0xE6, 0xF0, + 0x58, 0xB1, 0x04, 0x21, 0x28, 0x46, 0x00, 0xF0, 0xE9, 0xFE, 0x40, 0xF2, + 0x04, 0x51, 0x28, 0x46, 0xFC, 0xF7, 0xD0, 0xFD, 0x04, 0x20, 0x96, 0xE7, + 0x3E, 0xE0, 0x28, 0x7F, 0x68, 0xBB, 0x66, 0x68, 0x0E, 0xF4, 0xB4, 0xF1, + 0x30, 0x74, 0x01, 0x0A, 0x71, 0x74, 0x01, 0x0C, 0xB1, 0x74, 0x00, 0x0E, + 0xF0, 0x74, 0x0E, 0xF4, 0xAB, 0xF1, 0x30, 0x75, 0x01, 0x0A, 0x71, 0x75, + 0x01, 0x0C, 0xB1, 0x75, 0x00, 0x0E, 0xF0, 0x75, 0x0E, 0xF4, 0xA2, 0xF1, + 0x30, 0x76, 0x01, 0x0A, 0x71, 0x76, 0x01, 0x0C, 0xB1, 0x76, 0x00, 0x0E, + 0xF0, 0x76, 0x0E, 0xF4, 0x99, 0xF1, 0x30, 0x77, 0x01, 0x0A, 0x71, 0x77, + 0x01, 0x0C, 0xB1, 0x77, 0x00, 0x0E, 0xF0, 0x77, 0x62, 0x68, 0x04, 0x21, + 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0x54, 0xFC, 0x28, 0x46, 0x01, 0xF0, + 0xBB, 0xF8, 0x28, 0x6A, 0x90, 0xF8, 0x83, 0x00, 0x02, 0x28, 0x7F, 0xF4, + 0x71, 0xAF, 0xC9, 0xF8, 0x5C, 0x70, 0xC9, 0xF8, 0x60, 0x70, 0xC9, 0xF8, + 0x64, 0x70, 0xC9, 0xF8, 0x68, 0x70, 0x55, 0xE7, 0x01, 0xA8, 0x00, 0x90, + 0xE0, 0x6B, 0x62, 0x68, 0x00, 0xF1, 0x40, 0x01, 0x00, 0x23, 0x10, 0x32, + 0x0E, 0xF4, 0x7B, 0xF0, 0x01, 0xAA, 0x10, 0x21, 0x40, 0x46, 0xDF, 0xF7, + 0x2E, 0xDA, 0x1E, 0x49, 0x03, 0x46, 0x01, 0x22, 0x9C, 0x31, 0x1D, 0x48, + 0xDE, 0xF7, 0xBB, 0xDF, 0x1D, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, + 0x25, 0xD5, 0xD9, 0xF8, 0x08, 0x00, 0xB0, 0xF5, 0x87, 0x7F, 0x02, 0xD0, + 0xB0, 0xF5, 0x82, 0x7F, 0x1D, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00, + 0x09, 0x21, 0x8D, 0xF8, 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8, + 0x07, 0x00, 0x0A, 0x20, 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8, + 0x09, 0x00, 0x0C, 0x20, 0x8D, 0xF8, 0x0A, 0x00, 0x0F, 0x20, 0x8D, 0xF8, + 0x0C, 0x00, 0x8D, 0xF8, 0x0D, 0x70, 0x8D, 0xF8, 0x0E, 0x70, 0x8D, 0xF8, + 0x0B, 0x00, 0x8D, 0xF8, 0x0F, 0x70, 0x01, 0xAA, 0x03, 0x21, 0x28, 0x46, + 0x00, 0xF0, 0xFC, 0xFB, 0x28, 0x46, 0x01, 0xF0, 0x63, 0xF8, 0x0B, 0xE7, + 0x00, 0x00, 0x50, 0x21, 0x54, 0x37, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x88, 0x76, 0x20, 0x00, 0x64, 0x01, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x41, + 0x86, 0xB0, 0x05, 0x46, 0x04, 0x6A, 0x00, 0x20, 0x05, 0x90, 0xA0, 0x7A, + 0x88, 0x46, 0x02, 0x28, 0x0E, 0xD0, 0x01, 0x28, 0x0C, 0xD0, 0x29, 0x7F, + 0x55, 0x4F, 0x81, 0xB1, 0x00, 0x22, 0x55, 0x49, 0x38, 0x46, 0xDE, 0xF7, + 0x68, 0xDF, 0x28, 0x6A, 0x80, 0x7A, 0x03, 0x28, 0x36, 0xD0, 0x5A, 0xE0, + 0x04, 0x21, 0x28, 0x46, 0x00, 0xF0, 0x70, 0xF9, 0x06, 0xB0, 0xBD, 0xE8, + 0xF0, 0x81, 0x03, 0x28, 0x5C, 0xD0, 0x01, 0xA8, 0x00, 0x90, 0xE0, 0x6B, + 0x00, 0x23, 0x01, 0x46, 0x42, 0x46, 0x40, 0x30, 0x0E, 0xF4, 0x05, 0xF0, + 0x48, 0x4E, 0x01, 0xAA, 0x10, 0x21, 0x30, 0x46, 0xDF, 0xF7, 0xB7, 0xD9, + 0x44, 0x49, 0x03, 0x46, 0x01, 0x22, 0x70, 0x39, 0x38, 0x46, 0xDE, 0xF7, + 0x44, 0xDF, 0x60, 0x68, 0x10, 0x22, 0x01, 0xA9, 0x40, 0x30, 0x11, 0xF4, + 0x07, 0xF0, 0xE0, 0xB3, 0x62, 0x68, 0x10, 0x21, 0x30, 0x46, 0x40, 0x32, + 0xDF, 0xF7, 0xA3, 0xD9, 0x03, 0x46, 0x3A, 0x49, 0x38, 0x48, 0x01, 0x22, + 0x38, 0x39, 0x80, 0x1E, 0xDE, 0xF7, 0x2F, 0xDF, 0x04, 0x20, 0xCD, 0xE7, + 0x66, 0x68, 0x0E, 0xF4, 0xD3, 0xF0, 0x30, 0x74, 0x01, 0x0A, 0x71, 0x74, + 0x01, 0x0C, 0xB1, 0x74, 0x00, 0x0E, 0xF0, 0x74, 0x0E, 0xF4, 0xCA, 0xF0, + 0x30, 0x75, 0x01, 0x0A, 0x71, 0x75, 0x01, 0x0C, 0xB1, 0x75, 0x00, 0x0E, + 0xF0, 0x75, 0x0E, 0xF4, 0xC1, 0xF0, 0x30, 0x76, 0x01, 0x0A, 0x71, 0x76, + 0x01, 0x0C, 0xB1, 0x76, 0x00, 0x0E, 0xF0, 0x76, 0x0E, 0xF4, 0xB8, 0xF0, + 0x30, 0x77, 0x01, 0x0A, 0x71, 0x77, 0x01, 0x0C, 0xB1, 0x77, 0x00, 0x0E, + 0xF0, 0x77, 0x62, 0x68, 0x04, 0x21, 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, + 0x73, 0xFB, 0x28, 0x46, 0x00, 0xE0, 0x01, 0xE0, 0x00, 0xF0, 0xD8, 0xFF, + 0x28, 0x46, 0xFF, 0xF7, 0x15, 0xFD, 0x28, 0x6A, 0x80, 0x7A, 0x28, 0xB3, + 0x04, 0x28, 0x23, 0xD0, 0x03, 0x28, 0x21, 0xD0, 0x29, 0x7F, 0x05, 0xA8, + 0x00, 0x90, 0x21, 0xB3, 0xE1, 0x6B, 0x63, 0x68, 0x01, 0xF1, 0x40, 0x00, + 0x42, 0x46, 0x10, 0x33, 0x0E, 0xF4, 0x4F, 0xF0, 0x28, 0x6A, 0x80, 0x7A, + 0x03, 0x28, 0x0F, 0xD0, 0xA9, 0x7C, 0x05, 0xF1, 0x0C, 0x00, 0x05, 0x9A, + 0xEB, 0xF7, 0xCA, 0xFF, 0x0D, 0x49, 0x01, 0x22, 0x2C, 0x31, 0x38, 0x46, + 0x05, 0x9B, 0xDE, 0xF7, 0xD6, 0xDE, 0x01, 0x20, 0x84, 0xF8, 0x74, 0x00, + 0x00, 0x20, 0x71, 0xE7, 0x28, 0x7F, 0x00, 0x28, 0xFA, 0xD1, 0x28, 0x46, + 0x00, 0xF0, 0x0E, 0xF8, 0xF6, 0xE7, 0xE0, 0x6B, 0x62, 0x68, 0x00, 0xF1, + 0x40, 0x01, 0x43, 0x46, 0x10, 0x32, 0xD9, 0xE7, 0x02, 0x39, 0x10, 0x21, + 0xE4, 0x38, 0xC0, 0x08, 0x00, 0x00, 0x50, 0x21, 0x2D, 0xE9, 0xF0, 0x4F, + 0x05, 0x6A, 0x95, 0xB0, 0x04, 0x46, 0x6E, 0x68, 0x06, 0xF1, 0x30, 0x00, + 0x13, 0x90, 0x00, 0x20, 0x06, 0x90, 0x07, 0x90, 0x08, 0x90, 0x09, 0x90, + 0xA8, 0x7A, 0x10, 0x36, 0x02, 0x28, 0x04, 0xD0, 0x01, 0x28, 0x02, 0xD0, + 0x03, 0x28, 0x10, 0xD0, 0x19, 0xE0, 0xB5, 0xF8, 0x78, 0x00, 0x8D, 0xF8, + 0x18, 0x00, 0x00, 0x0A, 0x8D, 0xF8, 0x19, 0x00, 0xA8, 0x6F, 0x00, 0x0C, + 0x8D, 0xF8, 0x1A, 0x00, 0xA8, 0x6F, 0x00, 0x0E, 0x8D, 0xF8, 0x1B, 0x00, + 0x09, 0xE0, 0x20, 0x6A, 0x90, 0xF8, 0x83, 0x00, 0x01, 0x28, 0x04, 0xD0, + 0x10, 0x22, 0x35, 0x49, 0x06, 0xA8, 0x10, 0xF4, 0xA0, 0xF7, 0xD4, 0xF8, + 0x13, 0x00, 0x0E, 0x90, 0xB4, 0xF8, 0x17, 0x00, 0xAD, 0xF8, 0x3C, 0x00, + 0x60, 0x7E, 0x8D, 0xF8, 0x3E, 0x00, 0x20, 0x7F, 0x00, 0x28, 0x56, 0xD0, + 0xB5, 0xF8, 0x13, 0x00, 0xAD, 0xF8, 0x48, 0x00, 0x68, 0x7D, 0x8D, 0xF8, + 0x4A, 0x00, 0x60, 0x6D, 0x10, 0x90, 0xB4, 0xF8, 0x58, 0x00, 0xAD, 0xF8, + 0x44, 0x00, 0x94, 0xF8, 0x5A, 0x00, 0x26, 0x4F, 0x8D, 0xF8, 0x46, 0x00, + 0x06, 0xAA, 0x10, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xD4, 0xD8, 0x81, 0x46, + 0x10, 0x21, 0x38, 0x46, 0x13, 0x9A, 0xDF, 0xF7, 0xCE, 0xD8, 0x83, 0x46, + 0x32, 0x46, 0x10, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xC8, 0xD8, 0x82, 0x46, + 0x04, 0xF1, 0x13, 0x02, 0x06, 0x21, 0x38, 0x46, 0xDF, 0xF7, 0xC1, 0xD8, + 0x17, 0x4A, 0x80, 0x46, 0xB5, 0x3A, 0x06, 0x21, 0x38, 0x46, 0xDF, 0xF7, + 0xBA, 0xD8, 0x03, 0x46, 0xA7, 0x7C, 0x02, 0xA8, 0xCD, 0xF8, 0x14, 0x90, + 0x80, 0xE8, 0x80, 0x0C, 0x61, 0x7E, 0x07, 0x22, 0xCD, 0xE9, 0x00, 0x81, + 0x10, 0x49, 0x11, 0x48, 0xDE, 0xF7, 0x3F, 0xDE, 0x0A, 0xAB, 0x10, 0xAA, + 0x0E, 0xA9, 0x12, 0xA8, 0x8D, 0xE8, 0x0F, 0x00, 0x06, 0xAB, 0x31, 0x46, + 0x05, 0xF1, 0x60, 0x00, 0x13, 0x9A, 0x0D, 0xF4, 0x51, 0xF7, 0x0A, 0xA9, + 0x20, 0x46, 0x00, 0xF0, 0x1F, 0xF9, 0x20, 0x46, 0x00, 0xF0, 0x06, 0xFF, + 0x15, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0xE8, 0x68, 0x12, 0x90, 0xAC, 0xE7, + 0x6B, 0x77, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, 0xD4, 0x33, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x30, 0xB5, 0x0C, 0x46, 0x05, 0x46, 0x89, 0xB0, + 0x00, 0x22, 0x07, 0x49, 0x07, 0x48, 0xDE, 0xF7, 0x14, 0xDE, 0x6A, 0x46, + 0x21, 0x46, 0x28, 0x46, 0x0E, 0xF4, 0xDF, 0xF6, 0x69, 0x46, 0x00, 0xF0, + 0xC1, 0xFB, 0x09, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x94, 0x8D, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x00, 0xB5, 0x99, 0xB0, 0x00, 0x22, 0x07, 0x49, + 0x07, 0x48, 0xDE, 0xF7, 0xFE, 0xDD, 0x00, 0x22, 0x10, 0xA9, 0x68, 0x46, + 0x0E, 0xF4, 0x30, 0xF6, 0x10, 0xAA, 0x69, 0x46, 0x00, 0xF0, 0xD4, 0xFB, + 0x19, 0xB0, 0x00, 0xBD, 0x84, 0x8D, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x2D, 0xE9, 0xF0, 0x47, 0x04, 0x6A, 0x05, 0x46, 0xDF, 0xF8, 0xA4, 0x91, + 0x94, 0xF8, 0x7C, 0x00, 0x88, 0xB0, 0x14, 0x28, 0x03, 0xD3, 0x00, 0x22, + 0x66, 0x49, 0x48, 0x46, 0x93, 0xE0, 0x03, 0x26, 0x01, 0x27, 0x03, 0x29, + 0x7D, 0xD0, 0x04, 0x29, 0x10, 0xD0, 0x28, 0x7F, 0x01, 0x28, 0x77, 0xD0, + 0x94, 0xF8, 0x80, 0x30, 0x01, 0x22, 0x60, 0x49, 0x48, 0x46, 0xDE, 0xF7, + 0xD0, 0xDD, 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x6E, 0xD0, 0x01, 0x28, + 0x6D, 0xD0, 0xA5, 0xE0, 0xA1, 0x6F, 0xC1, 0x40, 0x01, 0xF0, 0x01, 0x00, + 0x40, 0xF0, 0x80, 0x08, 0x03, 0xA8, 0x00, 0x90, 0xE0, 0x6B, 0x62, 0x68, + 0x01, 0x46, 0x43, 0x46, 0x40, 0x30, 0x30, 0x32, 0x0D, 0xF4, 0x6D, 0xF6, + 0xDF, 0xF8, 0x4C, 0xA1, 0x03, 0xAA, 0x10, 0x21, 0x50, 0x46, 0xDF, 0xF7, + 0x1E, 0xD8, 0x94, 0xF8, 0x7C, 0x10, 0xA2, 0x6F, 0xCD, 0xE9, 0x00, 0x21, + 0x4B, 0x49, 0x02, 0x90, 0x43, 0x46, 0x04, 0x22, 0x38, 0x31, 0x48, 0x46, + 0xDE, 0xF7, 0xA5, 0xDD, 0x60, 0x68, 0x10, 0x22, 0x03, 0xA9, 0x40, 0x30, + 0x10, 0xF4, 0x68, 0xF6, 0x88, 0xB1, 0x62, 0x68, 0x10, 0x21, 0x50, 0x46, + 0x40, 0x32, 0xDF, 0xF7, 0x04, 0xD8, 0x03, 0x46, 0x40, 0x49, 0x3F, 0x48, + 0x01, 0x22, 0x98, 0x31, 0xC0, 0x1E, 0xDE, 0xF7, 0x90, 0xDD, 0x04, 0x20, + 0x08, 0xB0, 0xBD, 0xE8, 0xF0, 0x87, 0x94, 0xF8, 0x7C, 0x00, 0x40, 0x1C, + 0xC0, 0xB2, 0x84, 0xF8, 0x7C, 0x00, 0x14, 0x28, 0x02, 0xD1, 0x28, 0x46, + 0xFF, 0xF7, 0x9C, 0xFB, 0x28, 0x7F, 0x01, 0x28, 0x0A, 0xD0, 0x94, 0xF8, + 0x7C, 0x00, 0x14, 0x28, 0x1E, 0xD0, 0x33, 0x49, 0x00, 0x22, 0xF4, 0x39, + 0x48, 0x46, 0xDE, 0xF7, 0x74, 0xDD, 0x4F, 0xE0, 0x2E, 0x49, 0x00, 0x22, + 0xD0, 0x31, 0x48, 0x46, 0xDE, 0xF7, 0x6D, 0xDD, 0x62, 0x68, 0x04, 0x21, + 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0xD8, 0xF9, 0x28, 0x46, 0x00, 0xF0, + 0x3F, 0xFE, 0x00, 0x20, 0x84, 0xF8, 0x80, 0x00, 0x84, 0xF8, 0x81, 0x00, + 0x43, 0xE0, 0x05, 0xE0, 0x34, 0xE0, 0x20, 0xE0, 0x28, 0x46, 0xFF, 0xF7, + 0x9B, 0xFE, 0x3C, 0xE0, 0xA0, 0x7A, 0x02, 0x28, 0x0A, 0xD1, 0x94, 0xF8, + 0x74, 0x00, 0x38, 0xB1, 0x1E, 0x49, 0x1C, 0x48, 0x00, 0x22, 0xA8, 0x39, + 0x40, 0x1E, 0xDE, 0xF7, 0x4A, 0xDD, 0x2E, 0xE0, 0x28, 0x7F, 0x78, 0xB1, + 0x19, 0x49, 0x94, 0xF8, 0x80, 0x30, 0x01, 0x22, 0x3C, 0x39, 0x48, 0x46, + 0xDE, 0xF7, 0x3F, 0xDD, 0x94, 0xF8, 0x80, 0x00, 0x02, 0x28, 0x13, 0xD0, + 0xB0, 0xB1, 0x84, 0xF8, 0x81, 0x60, 0x1C, 0xE0, 0x11, 0x49, 0x00, 0x22, + 0x7C, 0x39, 0x48, 0x46, 0xDE, 0xF7, 0x31, 0xDD, 0x62, 0x68, 0x04, 0x21, + 0x28, 0x46, 0x10, 0x32, 0x00, 0xF0, 0x9C, 0xF9, 0x28, 0x46, 0x00, 0xF0, + 0x03, 0xFE, 0x0C, 0xE0, 0x28, 0x46, 0x00, 0xF0, 0x95, 0xF8, 0x08, 0xE0, + 0xEF, 0x84, 0x68, 0x79, 0x40, 0xF4, 0x80, 0x70, 0x00, 0xF0, 0x22, 0xFA, + 0x04, 0xF8, 0x80, 0x7F, 0x66, 0x70, 0x00, 0x20, 0x88, 0xE7, 0x00, 0x00, + 0x03, 0x39, 0x10, 0x21, 0xF8, 0x34, 0xC0, 0x08, 0xFC, 0x36, 0xC0, 0x08, + 0x00, 0x00, 0x50, 0x21, 0x30, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x0A, 0x46, + 0x85, 0xB0, 0x10, 0x21, 0x1B, 0x48, 0xDE, 0xF7, 0x72, 0xDF, 0x03, 0x46, + 0x01, 0x22, 0x1A, 0x49, 0x1A, 0x48, 0xDE, 0xF7, 0x00, 0xDD, 0x1B, 0x48, + 0x40, 0xF2, 0x6D, 0x23, 0x18, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xE6, 0xF7, + 0x8D, 0xFA, 0x01, 0x00, 0x21, 0xD0, 0x01, 0xF1, 0x1C, 0x00, 0x0D, 0x22, + 0x00, 0xF8, 0x01, 0x2B, 0x00, 0x23, 0xE2, 0x5C, 0x5B, 0x1C, 0x00, 0xF8, + 0x01, 0x2B, 0x10, 0x2B, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, + 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20, 0xAD, 0xF8, + 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x06, 0x20, 0x03, 0x91, + 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x8B, 0x04, 0x90, 0x68, 0x46, 0xF6, 0xF7, + 0xEF, 0xFC, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21, + 0x64, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x3A, 0xAA, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x05, 0x46, 0x0C, 0x46, 0x0B, 0x46, + 0x85, 0xB0, 0x01, 0x22, 0x14, 0x49, 0x15, 0x48, 0xDE, 0xF7, 0xBD, 0xDC, + 0x15, 0x48, 0x4F, 0xF4, 0x11, 0x73, 0x13, 0x4A, 0x1E, 0x21, 0x00, 0x78, + 0xE6, 0xF7, 0x4A, 0xFA, 0x00, 0x28, 0x18, 0xD0, 0x0E, 0x21, 0x01, 0x77, + 0x44, 0x77, 0x03, 0x90, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x02, 0x20, + 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x4F, 0xF4, + 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x0A, 0x00, + 0x68, 0x8B, 0x04, 0x90, 0x68, 0x46, 0xF6, 0xF7, 0xB5, 0xFC, 0x05, 0xB0, + 0x30, 0xBD, 0x00, 0x00, 0x2C, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x19, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x10, 0xB5, 0x04, 0x46, + 0x00, 0x6A, 0x86, 0xB0, 0x90, 0xF8, 0x7C, 0x20, 0x81, 0x6F, 0xD1, 0x40, + 0x01, 0xF0, 0x01, 0x01, 0x41, 0xF0, 0x80, 0x03, 0x01, 0xA9, 0x00, 0x91, + 0x42, 0x68, 0xC0, 0x6B, 0x10, 0x32, 0x00, 0xF1, 0x40, 0x01, 0x0D, 0xF4, + 0x2E, 0xF5, 0x01, 0xAA, 0x10, 0x21, 0x20, 0x48, 0xDE, 0xF7, 0xE1, 0xDE, + 0x03, 0x46, 0x01, 0x22, 0x1E, 0x49, 0x1F, 0x48, 0xDE, 0xF7, 0x6F, 0xDC, + 0x1E, 0x48, 0x90, 0xF8, 0x78, 0x01, 0x80, 0x07, 0x26, 0xD5, 0x1D, 0x48, + 0x80, 0x68, 0xB0, 0xF5, 0x82, 0x7F, 0x02, 0xD0, 0xB0, 0xF5, 0x87, 0x7F, + 0x1E, 0xD1, 0x0B, 0x20, 0x8D, 0xF8, 0x04, 0x00, 0x09, 0x21, 0x8D, 0xF8, + 0x05, 0x10, 0x8D, 0xF8, 0x06, 0x00, 0x8D, 0xF8, 0x07, 0x00, 0x0A, 0x20, + 0x8D, 0xF8, 0x08, 0x00, 0x0D, 0x20, 0x8D, 0xF8, 0x09, 0x00, 0x0C, 0x20, + 0x8D, 0xF8, 0x0A, 0x00, 0x0F, 0x20, 0x8D, 0xF8, 0x0B, 0x00, 0x8D, 0xF8, + 0x0C, 0x00, 0x00, 0x20, 0x8D, 0xF8, 0x0D, 0x00, 0x8D, 0xF8, 0x0E, 0x00, + 0x8D, 0xF8, 0x0F, 0x00, 0x01, 0xAA, 0x03, 0x21, 0x20, 0x46, 0x00, 0xF0, + 0xAF, 0xF8, 0x20, 0x46, 0x00, 0xF0, 0x16, 0xFD, 0x06, 0xB0, 0x00, 0x20, + 0x10, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21, 0xB4, 0x33, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x64, 0x01, 0x20, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x30, 0xB5, 0x05, 0x46, 0x2B, 0x48, 0x85, 0xB0, 0x40, 0xF2, 0x91, 0x23, + 0x28, 0x4A, 0x5D, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0xB7, 0xF9, 0x00, 0x28, + 0x47, 0xD0, 0x00, 0xF1, 0x1C, 0x04, 0x03, 0x90, 0x1C, 0x20, 0xAD, 0xF8, + 0x06, 0x00, 0x41, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, + 0x04, 0x00, 0x4F, 0xF4, 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x00, 0x10, + 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x8B, 0x04, 0x90, 0x28, 0x6A, 0x81, 0x7A, + 0x03, 0x29, 0x13, 0xD1, 0x20, 0x22, 0x1A, 0x49, 0x19, 0x30, 0x10, 0xF4, + 0x16, 0xF5, 0x28, 0x6A, 0x17, 0x49, 0x40, 0x22, 0xC0, 0x6B, 0x20, 0x31, + 0x10, 0xF4, 0x0F, 0xF5, 0x28, 0x6A, 0x14, 0x49, 0x10, 0x22, 0x40, 0x68, + 0x71, 0x31, 0x40, 0x30, 0x10, 0xF4, 0x07, 0xF5, 0x0C, 0x20, 0x04, 0xF8, + 0x01, 0x0B, 0x00, 0x20, 0x29, 0x6A, 0xC9, 0x6B, 0x09, 0x5C, 0x40, 0x1C, + 0x04, 0xF8, 0x01, 0x1B, 0x40, 0x28, 0xF7, 0xD3, 0x28, 0x6A, 0x40, 0x21, + 0xC2, 0x6B, 0x0A, 0x48, 0xDE, 0xF7, 0x4D, 0xDE, 0x03, 0x46, 0x01, 0x22, + 0x08, 0x49, 0x09, 0x48, 0xDE, 0xF7, 0xDB, 0xDB, 0x68, 0x46, 0xF6, 0xF7, + 0xF3, 0xFB, 0x05, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x51, 0xAA, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x0A, 0x77, 0x20, 0x00, 0x00, 0x00, 0x50, 0x21, + 0x88, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0xF0, 0xB5, 0x87, 0xB0, + 0x06, 0x46, 0xDD, 0xE9, 0x0C, 0x50, 0x56, 0xEA, 0x01, 0x04, 0x06, 0xD0, + 0x04, 0x2B, 0x01, 0xD8, 0x04, 0x2D, 0x04, 0xD9, 0x04, 0x20, 0x07, 0xB0, + 0xF0, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0x05, 0xEB, 0x85, 0x04, 0x1A, 0xB1, + 0x0F, 0x4F, 0x3C, 0x44, 0xE4, 0x5C, 0x05, 0xE0, 0x0D, 0x4F, 0x19, 0x3F, + 0x3C, 0x44, 0xE4, 0x5C, 0x06, 0x2C, 0x02, 0xD0, 0x04, 0x2C, 0x05, 0xD0, + 0x06, 0xE0, 0x08, 0xB1, 0x01, 0x24, 0x03, 0xE0, 0x02, 0x24, 0x01, 0xE0, + 0x00, 0xB1, 0x00, 0x24, 0x8D, 0xE8, 0x2E, 0x00, 0xCD, 0xE9, 0x04, 0x04, + 0x33, 0x46, 0x07, 0x22, 0x03, 0x49, 0x04, 0x48, 0xDE, 0xF7, 0x97, 0xDB, + 0x20, 0x46, 0xD8, 0xE7, 0x56, 0xA9, 0x82, 0x00, 0x28, 0x31, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0xF0, 0xB5, 0x17, 0x46, 0x0D, 0x46, 0x06, 0x46, + 0x04, 0x6A, 0x85, 0xB0, 0x00, 0x22, 0x27, 0x49, 0x27, 0x48, 0xDE, 0xF7, + 0x84, 0xDB, 0x28, 0x48, 0x4F, 0xF4, 0x83, 0x73, 0x25, 0x4A, 0x2D, 0x21, + 0x00, 0x78, 0xE6, 0xF7, 0x11, 0xF9, 0x02, 0x00, 0x32, 0xD0, 0x02, 0xF1, + 0x1C, 0x01, 0x00, 0x20, 0x01, 0xF8, 0x01, 0x5B, 0x3B, 0x5C, 0x40, 0x1C, + 0x01, 0xF8, 0x01, 0x3B, 0x10, 0x28, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, + 0xAD, 0xF8, 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20, + 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, 0x03, 0x92, 0xAD, 0xF8, 0x04, 0x00, + 0x70, 0x8B, 0xED, 0x1E, 0x04, 0x90, 0x09, 0x2D, 0x0E, 0xD2, 0xDF, 0xE8, + 0x05, 0xF0, 0x09, 0x05, 0x0D, 0x15, 0x0D, 0x19, 0x0D, 0x0D, 0x1D, 0x00, + 0x20, 0x68, 0x40, 0xF0, 0x40, 0x00, 0x02, 0xE0, 0x20, 0x68, 0x40, 0xF0, + 0x10, 0x00, 0x20, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x68, 0x46, + 0xF6, 0xF7, 0x62, 0xFB, 0x05, 0xB0, 0xF0, 0xBD, 0x20, 0x68, 0x40, 0xF4, + 0x80, 0x60, 0xF2, 0xE7, 0x20, 0x68, 0x40, 0xF4, 0x80, 0x40, 0xEE, 0xE7, + 0x20, 0x68, 0x40, 0xF4, 0x80, 0x20, 0xEA, 0xE7, 0x2C, 0x32, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x88, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0xF0, 0xB5, 0x85, 0xB0, 0x0F, 0x46, 0x05, 0x46, 0x16, 0x46, 0x14, 0x21, + 0x68, 0x46, 0x10, 0xF4, 0xDD, 0xF4, 0x14, 0x48, 0x40, 0xF2, 0x5C, 0x43, + 0x11, 0x4A, 0x20, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0xB5, 0xF8, 0x04, 0x00, + 0x19, 0xD0, 0x10, 0x22, 0x39, 0x46, 0x10, 0xF4, 0x2E, 0xF4, 0x10, 0x22, + 0x31, 0x46, 0x04, 0xF1, 0x10, 0x00, 0x10, 0xF4, 0x28, 0xF4, 0x40, 0xF2, + 0x06, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, 0xAD, 0xF8, 0x0A, 0x50, + 0x40, 0xF2, 0x69, 0x43, 0x04, 0x4A, 0x69, 0x46, 0x05, 0x48, 0xE6, 0xF7, + 0xD3, 0xFE, 0x00, 0xF0, 0xF9, 0xFB, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0x00, + 0xCA, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0xAC, 0x76, 0x20, 0x00, + 0x10, 0xB5, 0x86, 0xB0, 0x04, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4, + 0xA9, 0xF4, 0x40, 0xF2, 0x07, 0x41, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, + 0x0A, 0x40, 0x40, 0xF2, 0x7E, 0x43, 0x04, 0x4A, 0x69, 0x46, 0x04, 0x48, + 0xE6, 0xF7, 0xB4, 0xFE, 0x00, 0xF0, 0xDA, 0xFB, 0x06, 0xB0, 0x10, 0xBD, + 0xE1, 0xAA, 0x82, 0x00, 0xAC, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x0E, 0x46, + 0x05, 0x46, 0x86, 0xB0, 0x14, 0x46, 0x11, 0x46, 0x1F, 0x48, 0xDE, 0xF7, + 0xA5, 0xDC, 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, 0x1D, 0x49, 0x1E, 0x48, + 0xDE, 0xF7, 0xCF, 0xDA, 0x1E, 0x48, 0x40, 0xF2, 0xFB, 0x13, 0x1C, 0x4A, + 0x24, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0x5C, 0xF8, 0x02, 0x00, 0x28, 0xD0, + 0x02, 0xF1, 0x1C, 0x00, 0x09, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, + 0x00, 0xF8, 0x01, 0x6B, 0x63, 0x5C, 0x49, 0x1C, 0x00, 0xF8, 0x01, 0x3B, + 0x06, 0x29, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x04, 0x00, + 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x08, 0x20, 0xAD, 0xF8, 0x0C, 0x00, + 0x01, 0x20, 0x04, 0x92, 0xAD, 0xF8, 0x08, 0x00, 0x68, 0x8B, 0x05, 0x90, + 0x28, 0x6A, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x31, 0x01, 0x60, 0x06, 0x20, + 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF6, 0xF7, 0xB7, 0xFA, 0x06, 0xB0, + 0x70, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, 0xD0, 0x32, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0xEF, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x30, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x85, 0xB0, 0x00, 0x22, 0x1B, 0x49, + 0x1B, 0x48, 0xDE, 0xF7, 0x86, 0xDA, 0x1C, 0x48, 0x40, 0xF2, 0xCD, 0x13, + 0x19, 0x4A, 0x2D, 0x21, 0x00, 0x78, 0xE6, 0xF7, 0x13, 0xF8, 0x01, 0x00, + 0x26, 0xD0, 0x01, 0xF1, 0x1C, 0x00, 0x08, 0x22, 0x00, 0xF8, 0x01, 0x2B, + 0x00, 0x22, 0xAB, 0x5C, 0x52, 0x1C, 0x00, 0xF8, 0x01, 0x3B, 0x10, 0x2A, + 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x00, 0x00, 0x1C, 0x20, + 0xAD, 0xF8, 0x06, 0x00, 0x11, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x01, 0x20, + 0x03, 0x91, 0xAD, 0xF8, 0x04, 0x00, 0x60, 0x8B, 0x04, 0x90, 0x20, 0x6A, + 0x01, 0x68, 0x41, 0xF4, 0x80, 0x41, 0x01, 0x60, 0x06, 0x20, 0xAD, 0xF8, + 0x0A, 0x00, 0x68, 0x46, 0xF6, 0xF7, 0x70, 0xFA, 0x05, 0xB0, 0x30, 0xBD, + 0xBC, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0xDC, 0xA9, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x05, 0x46, 0x11, 0x48, 0x0E, 0x46, + 0x86, 0xB0, 0x40, 0xF2, 0x8F, 0x23, 0x0E, 0x4A, 0x21, 0x21, 0x00, 0x78, + 0xE5, 0xF7, 0xD4, 0xFF, 0x04, 0x00, 0x12, 0xD0, 0x20, 0x22, 0x31, 0x46, + 0x60, 0x1C, 0x10, 0xF4, 0x4C, 0xF3, 0x25, 0x70, 0x40, 0xF2, 0x09, 0x40, + 0xAD, 0xF8, 0x00, 0x00, 0x07, 0x48, 0x03, 0x94, 0x4F, 0xF4, 0x27, 0x73, + 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE6, 0xF7, 0xC5, 0xFA, 0x06, 0xB0, + 0x70, 0xBD, 0x00, 0x00, 0x21, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x84, 0x76, 0x20, 0x00, 0xF0, 0xB5, 0x05, 0x46, 0x14, 0x48, 0x16, 0x46, + 0x0F, 0x46, 0x85, 0xB0, 0x40, 0xF2, 0x7A, 0x23, 0x10, 0x4A, 0x61, 0x21, + 0x00, 0x78, 0xE5, 0xF7, 0xA9, 0xFF, 0x04, 0x00, 0x18, 0xD0, 0x40, 0x22, + 0x39, 0x46, 0x60, 0x1C, 0x10, 0xF4, 0x21, 0xF3, 0x20, 0x22, 0x31, 0x46, + 0x04, 0xF1, 0x41, 0x00, 0x10, 0xF4, 0x1B, 0xF3, 0x25, 0x70, 0x4F, 0xF4, + 0x81, 0x60, 0xAD, 0xF8, 0x00, 0x00, 0x07, 0x48, 0x03, 0x94, 0x40, 0xF2, + 0x87, 0x23, 0x03, 0x4A, 0x69, 0x46, 0x00, 0x78, 0xE6, 0xF7, 0x94, 0xFA, + 0x05, 0xB0, 0xF0, 0xBD, 0x06, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, + 0x84, 0x76, 0x20, 0x00, 0x70, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x04, 0x46, + 0x86, 0xB0, 0x00, 0x22, 0x1D, 0x49, 0x1E, 0x48, 0xDE, 0xF7, 0xE7, 0xD9, + 0x1E, 0x48, 0x40, 0xF2, 0x77, 0x13, 0x1C, 0x4A, 0x27, 0x21, 0x00, 0x78, + 0xE5, 0xF7, 0x74, 0xFF, 0x02, 0x00, 0x2B, 0xD0, 0x02, 0xF1, 0x1C, 0x00, + 0x07, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x31, 0x0A, 0x00, 0xF8, 0x01, 0x6B, + 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, 0x6B, 0x5C, 0x49, 0x1C, 0x00, 0xF8, + 0x01, 0x3B, 0x08, 0x29, 0xF9, 0xD3, 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, + 0x00, 0x00, 0x1C, 0x20, 0xAD, 0xF8, 0x06, 0x00, 0x0B, 0x20, 0xAD, 0xF8, + 0x08, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x00, 0x06, 0x20, 0x03, 0x92, + 0xAD, 0xF8, 0x0A, 0x00, 0x60, 0x8B, 0x04, 0x90, 0x20, 0x6A, 0x01, 0x68, + 0x41, 0xF4, 0x80, 0x51, 0x01, 0x60, 0x68, 0x46, 0xF6, 0xF7, 0xCC, 0xF9, + 0x06, 0xB0, 0x70, 0xBD, 0x70, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0xB2, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x2D, 0xE9, 0xF0, 0x4F, + 0x8B, 0xB0, 0x0E, 0x46, 0xDD, 0xE9, 0x15, 0xB9, 0x05, 0x46, 0x00, 0xF1, + 0x0C, 0x01, 0x04, 0x6A, 0x1F, 0x46, 0x90, 0x46, 0xDD, 0xF8, 0x50, 0xA0, + 0x2F, 0x48, 0xDE, 0xF7, 0x65, 0xDB, 0x03, 0x46, 0x17, 0x98, 0xCD, 0xF8, + 0x00, 0x80, 0xCD, 0xE9, 0x04, 0x90, 0x0D, 0xF1, 0x04, 0x0C, 0x07, 0x22, + 0x8C, 0xE8, 0x80, 0x0C, 0x29, 0x49, 0x2A, 0x48, 0xDE, 0xF7, 0x87, 0xD9, + 0x2A, 0x48, 0xC9, 0x23, 0x28, 0x4A, 0x23, 0x21, 0x00, 0x78, 0xE5, 0xF7, + 0x15, 0xFF, 0x00, 0x28, 0x40, 0xD0, 0x06, 0x77, 0x80, 0xF8, 0x1D, 0x80, + 0x87, 0x77, 0x80, 0xF8, 0x1F, 0xA0, 0x80, 0xF8, 0x20, 0xB0, 0x22, 0x21, + 0x80, 0xF8, 0x21, 0x90, 0x17, 0x9A, 0x0A, 0x54, 0x4F, 0xF4, 0x80, 0x61, + 0xAD, 0xF8, 0x18, 0x10, 0x1C, 0x21, 0xAD, 0xF8, 0x1E, 0x10, 0x07, 0x21, + 0xAD, 0xF8, 0x20, 0x10, 0x01, 0x21, 0x09, 0x90, 0xAD, 0xF8, 0x1C, 0x10, + 0x69, 0x8B, 0x0A, 0x91, 0x01, 0x2E, 0x02, 0xD0, 0x02, 0x2E, 0x0D, 0xD0, + 0x18, 0xE0, 0xC1, 0x69, 0xC4, 0xF8, 0x0B, 0x10, 0x01, 0x8C, 0xA4, 0xF8, + 0x0F, 0x10, 0x90, 0xF8, 0x22, 0x00, 0x60, 0x74, 0x20, 0x68, 0x40, 0xF0, + 0x01, 0x00, 0x0A, 0xE0, 0xC1, 0x69, 0xC4, 0xF8, 0x12, 0x10, 0x01, 0x8C, + 0xE1, 0x82, 0x90, 0xF8, 0x22, 0x00, 0x20, 0x76, 0x20, 0x68, 0x40, 0xF0, + 0x04, 0x00, 0x20, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x22, 0x00, 0x06, 0xA8, + 0xF6, 0xF7, 0x58, 0xF9, 0x0B, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x21, 0xA4, 0x31, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x6F, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x30, 0xB5, 0x0D, 0x46, + 0x04, 0x46, 0x00, 0xF1, 0x0C, 0x01, 0x87, 0xB0, 0x1A, 0x48, 0xDE, 0xF7, + 0xF5, 0xDA, 0x03, 0x46, 0x02, 0x22, 0x19, 0x49, 0x19, 0x48, 0x00, 0x95, + 0xDE, 0xF7, 0x1F, 0xD9, 0x19, 0x48, 0x4F, 0xF4, 0xA4, 0x73, 0x17, 0x4A, + 0x1E, 0x21, 0x00, 0x78, 0xE5, 0xF7, 0xAC, 0xFE, 0x00, 0x28, 0x1E, 0xD0, + 0x05, 0x21, 0x01, 0x77, 0x45, 0x77, 0x04, 0x90, 0x1C, 0x20, 0xAD, 0xF8, + 0x0A, 0x00, 0x02, 0x20, 0xAD, 0xF8, 0x0C, 0x00, 0x4F, 0xF4, 0x80, 0x61, + 0x01, 0x20, 0xAD, 0xF8, 0x04, 0x10, 0xAD, 0xF8, 0x08, 0x00, 0x60, 0x8B, + 0x05, 0x90, 0x20, 0x6A, 0x18, 0xB1, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x71, + 0x01, 0x60, 0x06, 0x20, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF6, 0xF7, + 0x11, 0xF9, 0x07, 0xB0, 0x30, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x30, 0x21, + 0x44, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, 0x9D, 0xA9, 0x82, 0x00, + 0x00, 0x74, 0x20, 0x00, 0xF0, 0xB5, 0x85, 0xB0, 0x0F, 0x46, 0x05, 0x46, + 0x16, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4, 0x95, 0xF2, 0x19, 0x48, + 0x40, 0xF2, 0xA2, 0x43, 0x16, 0x4A, 0x60, 0x21, 0x00, 0x78, 0xE5, 0xF7, + 0x6D, 0xFE, 0x04, 0x00, 0x23, 0xD0, 0x00, 0x22, 0x14, 0x49, 0x15, 0x48, + 0xDE, 0xF7, 0xD1, 0xD8, 0x40, 0x22, 0x39, 0x46, 0x20, 0x46, 0x10, 0xF4, + 0xE0, 0xF1, 0x20, 0x22, 0x31, 0x46, 0x04, 0xF1, 0x40, 0x00, 0x10, 0xF4, + 0xDA, 0xF1, 0x40, 0xF2, 0x09, 0x40, 0xAD, 0xF8, 0x00, 0x00, 0x03, 0x94, + 0xAD, 0xF8, 0x0A, 0x50, 0x4F, 0xF4, 0x96, 0x63, 0x06, 0x4A, 0x69, 0x46, + 0x09, 0x48, 0xE6, 0xF7, 0x85, 0xFC, 0x04, 0x46, 0x00, 0xF0, 0xAA, 0xF9, + 0x20, 0x46, 0x05, 0xB0, 0xF0, 0xBD, 0x00, 0x20, 0xFB, 0xE7, 0x00, 0x00, + 0x0D, 0xAB, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0xAC, 0x44, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0xAC, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x86, 0xB0, + 0x04, 0x46, 0x14, 0x21, 0x68, 0x46, 0x10, 0xF4, 0x53, 0xF2, 0x4F, 0xF4, + 0x81, 0x61, 0xAD, 0xF8, 0x00, 0x10, 0xAD, 0xF8, 0x0A, 0x40, 0x00, 0x22, + 0x0C, 0x49, 0x0D, 0x48, 0xDE, 0xF7, 0x93, 0xD8, 0x40, 0xF2, 0x8F, 0x43, + 0x0B, 0x4A, 0x69, 0x46, 0x0B, 0x48, 0xE6, 0xF7, 0x59, 0xFC, 0x04, 0x00, + 0x06, 0xD1, 0x06, 0x49, 0x06, 0x48, 0x00, 0x22, 0x18, 0x31, 0xC0, 0x1E, + 0xDE, 0xF7, 0x83, 0xD8, 0x00, 0xF0, 0x76, 0xF9, 0x06, 0xB0, 0x20, 0x46, + 0x10, 0xBD, 0x00, 0x00, 0x70, 0x44, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0xF5, 0xAA, 0x82, 0x00, 0xAC, 0x76, 0x20, 0x00, 0x2D, 0xE9, 0xFF, 0x47, + 0x81, 0x46, 0xDD, 0xE9, 0x0D, 0x50, 0x0C, 0x9C, 0x8D, 0xF8, 0x09, 0x50, + 0x17, 0x46, 0x88, 0x46, 0x8D, 0xF8, 0x08, 0x40, 0x1E, 0x46, 0xAD, 0xF8, + 0x0C, 0x30, 0x8D, 0xF8, 0x0A, 0x00, 0x02, 0xAB, 0x4A, 0x46, 0x39, 0x46, + 0x40, 0x46, 0xE6, 0xF7, 0x09, 0xFE, 0x33, 0x46, 0x3A, 0x46, 0x41, 0x46, + 0x48, 0x46, 0xCD, 0xE9, 0x00, 0x45, 0xEF, 0xF7, 0xD7, 0xFF, 0xBD, 0xE8, + 0xFF, 0x87, 0x00, 0x00, 0x30, 0xB5, 0x0D, 0x46, 0x04, 0x46, 0x00, 0xF1, + 0x0C, 0x01, 0x87, 0xB0, 0x19, 0x48, 0xDE, 0xF7, 0x19, 0xDA, 0x03, 0x46, + 0x02, 0x22, 0x18, 0x49, 0x18, 0x48, 0x00, 0x95, 0xDE, 0xF7, 0x43, 0xD8, + 0x18, 0x48, 0x4F, 0xF4, 0xD2, 0x73, 0x16, 0x4A, 0x1E, 0x21, 0x00, 0x78, + 0xE5, 0xF7, 0xD0, 0xFD, 0x00, 0x28, 0x1D, 0xD0, 0x0B, 0x21, 0x01, 0x77, + 0x45, 0x77, 0x04, 0x90, 0x1C, 0x20, 0xAD, 0xF8, 0x0A, 0x00, 0x02, 0x20, + 0xAD, 0xF8, 0x0C, 0x00, 0x01, 0x20, 0xAD, 0xF8, 0x08, 0x00, 0x4F, 0xF4, + 0x80, 0x61, 0x06, 0x20, 0xAD, 0xF8, 0x04, 0x10, 0xAD, 0xF8, 0x0E, 0x00, + 0x60, 0x8B, 0x05, 0x90, 0x20, 0x6A, 0x01, 0x68, 0x41, 0xF4, 0x80, 0x11, + 0x01, 0x60, 0x01, 0xA8, 0xF6, 0xF7, 0x36, 0xF8, 0x07, 0xB0, 0x30, 0xBD, + 0x00, 0x00, 0x30, 0x21, 0x88, 0x32, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0xC7, 0xA9, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x70, 0xB5, 0x04, 0x46, + 0x0D, 0x46, 0x0A, 0x46, 0x86, 0xB0, 0x10, 0x21, 0x26, 0x48, 0xDE, 0xF7, + 0x72, 0xDA, 0x06, 0x46, 0x04, 0xF1, 0x0C, 0x01, 0x24, 0x48, 0xDE, 0xF7, + 0xCF, 0xD9, 0x03, 0x46, 0x02, 0x22, 0x23, 0x49, 0x23, 0x48, 0x00, 0x96, + 0xDD, 0xF7, 0xF9, 0xDF, 0x23, 0x48, 0x40, 0xF2, 0x1E, 0x23, 0x21, 0x4A, + 0x2D, 0x21, 0x00, 0x78, 0xE5, 0xF7, 0x86, 0xFD, 0x02, 0x00, 0x30, 0xD0, + 0x02, 0xF1, 0x1C, 0x00, 0x0A, 0x21, 0x00, 0xF8, 0x01, 0x1B, 0x00, 0x21, + 0x6B, 0x5C, 0x49, 0x1C, 0x00, 0xF8, 0x01, 0x3B, 0x10, 0x29, 0xF9, 0xD3, + 0x4F, 0xF4, 0x80, 0x60, 0xAD, 0xF8, 0x04, 0x00, 0x1C, 0x20, 0xAD, 0xF8, + 0x0A, 0x00, 0x11, 0x20, 0x01, 0x26, 0x04, 0x92, 0xAD, 0xF8, 0x0C, 0x00, + 0xAD, 0xF8, 0x08, 0x60, 0x60, 0x8B, 0x05, 0x90, 0x20, 0x6A, 0x10, 0x22, + 0x01, 0x68, 0x41, 0xF4, 0x80, 0x21, 0x01, 0x60, 0x29, 0x46, 0x04, 0xF1, + 0x2A, 0x00, 0x10, 0xF4, 0xDC, 0xF0, 0x84, 0xF8, 0x28, 0x60, 0x00, 0x20, + 0xE0, 0x63, 0x06, 0x20, 0xAD, 0xF8, 0x0E, 0x00, 0x01, 0xA8, 0xF5, 0xF7, + 0xD9, 0xFF, 0x06, 0xB0, 0x70, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x50, 0x21, + 0x00, 0x00, 0x30, 0x21, 0x00, 0x33, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x07, 0xAA, 0x82, 0x00, 0x00, 0x74, 0x20, 0x00, 0x0B, 0x46, 0x00, 0x28, + 0x03, 0xD1, 0x11, 0x46, 0x18, 0x46, 0xEA, 0xF7, 0xF3, 0xB9, 0x70, 0x47, + 0x01, 0x49, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0xF8, 0xB5, 0x16, 0x4D, 0x0E, 0x46, 0x04, 0x00, 0x18, 0xD0, 0x01, 0x46, + 0x14, 0x48, 0xDE, 0xF7, 0x67, 0xD9, 0x00, 0x90, 0x33, 0x46, 0x02, 0x22, + 0x12, 0x49, 0x13, 0x48, 0xDD, 0xF7, 0x91, 0xDF, 0xBE, 0xB1, 0x60, 0x79, + 0x03, 0x21, 0xB1, 0xEB, 0x90, 0x1F, 0x10, 0xD1, 0x20, 0x68, 0x45, 0xF8, + 0x40, 0x0F, 0xA0, 0x88, 0xA8, 0x80, 0x01, 0x20, 0xA8, 0x71, 0x0D, 0xE0, + 0x4E, 0xB1, 0x0B, 0x46, 0x08, 0x49, 0x09, 0x48, 0x01, 0x22, 0x34, 0x31, + 0x80, 0x1E, 0xDD, 0xF7, 0x7A, 0xDF, 0x00, 0x20, 0xF8, 0xBD, 0x00, 0x20, + 0x85, 0xF8, 0x46, 0x00, 0x01, 0x20, 0xF8, 0xBD, 0x88, 0x76, 0x20, 0x00, + 0x00, 0x00, 0x30, 0x21, 0x54, 0x25, 0xC0, 0x08, 0x02, 0x39, 0x10, 0x21, + 0x02, 0x4A, 0x02, 0xF8, 0x59, 0x0F, 0x51, 0x70, 0x70, 0x47, 0x00, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x01, 0x49, 0xC8, 0x75, 0x70, 0x47, 0x00, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x00, 0x28, 0x04, 0xD1, 0x02, 0x48, 0x0A, 0x68, + 0x42, 0x63, 0x89, 0x88, 0x01, 0x87, 0x70, 0x47, 0x88, 0x76, 0x20, 0x00, + 0x10, 0xB5, 0x04, 0x46, 0x03, 0x28, 0x09, 0xD2, 0x03, 0x46, 0x01, 0x22, + 0x04, 0x49, 0x05, 0x48, 0xDD, 0xF7, 0x49, 0xDF, 0x04, 0x48, 0x44, 0x75, + 0x01, 0x20, 0x10, 0xBD, 0x00, 0x20, 0x10, 0xBD, 0x08, 0x31, 0xC0, 0x08, + 0x02, 0x39, 0x10, 0x21, 0x88, 0x76, 0x20, 0x00, 0x10, 0xB5, 0x0A, 0x4C, + 0x48, 0xB1, 0x01, 0x46, 0x10, 0x22, 0x04, 0xF1, 0x49, 0x00, 0x10, 0xF4, + 0x48, 0xF0, 0x01, 0x20, 0x84, 0xF8, 0x47, 0x00, 0x10, 0xBD, 0x21, 0x20, + 0x84, 0xF8, 0x48, 0x00, 0xBD, 0xE8, 0x10, 0x40, 0x4F, 0xF4, 0x80, 0x60, + 0xFF, 0xF7, 0x2C, 0xBC, 0x88, 0x76, 0x20, 0x00, 0x08, 0x49, 0x42, 0x79, + 0x4F, 0xF4, 0x00, 0x33, 0x09, 0x78, 0x43, 0xEA, 0x01, 0x61, 0x0A, 0x43, + 0x05, 0x49, 0x4F, 0xF4, 0x7A, 0x73, 0x09, 0x7D, 0x11, 0xFB, 0x03, 0xF3, + 0x03, 0xA1, 0xE6, 0xF7, 0xA5, 0xBC, 0x00, 0x00, 0x84, 0x76, 0x20, 0x00, + 0x88, 0x76, 0x20, 0x00, 0x73, 0x6D, 0x70, 0x00, 0xE6, 0xF7, 0xB4, 0xBC, + 0x2D, 0xE9, 0xF0, 0x43, 0x36, 0x4C, 0x4F, 0xF6, 0xFF, 0x77, 0x87, 0xB0, + 0xA0, 0x8D, 0xB8, 0x42, 0x34, 0xD1, 0x40, 0xF2, 0x06, 0x45, 0x40, 0xF2, + 0xD3, 0x49, 0x04, 0xF1, 0x24, 0x08, 0xEE, 0x1C, 0x4B, 0x46, 0x30, 0x4A, + 0x01, 0xA9, 0x40, 0x46, 0xE6, 0xF7, 0x98, 0xFA, 0x00, 0x28, 0x25, 0xD0, + 0xBD, 0xF8, 0x04, 0x00, 0x00, 0x90, 0x94, 0xF8, 0x2C, 0x30, 0x02, 0x22, + 0x2A, 0x49, 0x2B, 0x48, 0xDD, 0xF7, 0xE9, 0xDE, 0xBD, 0xF8, 0x0E, 0x00, + 0xA0, 0x85, 0xC1, 0x05, 0x03, 0xD5, 0xC0, 0xB2, 0xFB, 0xF7, 0x0A, 0xFF, + 0xA8, 0xB1, 0xBD, 0xF8, 0x04, 0x00, 0xA0, 0xF5, 0x80, 0x61, 0x07, 0x39, + 0x0A, 0xD0, 0xA8, 0x42, 0x27, 0xD1, 0x04, 0x98, 0x00, 0xF1, 0x10, 0x01, + 0xF1, 0xF7, 0x04, 0xFD, 0x40, 0xF2, 0xF4, 0x42, 0x04, 0x98, 0x2B, 0xE0, + 0xF1, 0xF7, 0xC3, 0xFD, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x83, 0xBD, 0xF8, + 0x04, 0x00, 0x00, 0x90, 0x17, 0x49, 0x18, 0x48, 0x94, 0xF8, 0x2C, 0x30, + 0x02, 0x22, 0x34, 0x31, 0xC0, 0x1E, 0xDD, 0xF7, 0xBE, 0xDE, 0xBD, 0xF8, + 0x04, 0x00, 0xA8, 0x42, 0x01, 0xD0, 0xB0, 0x42, 0x05, 0xD1, 0x40, 0xF2, + 0xE4, 0x42, 0x0E, 0x49, 0x04, 0x98, 0xE5, 0xF7, 0x35, 0xFD, 0xA7, 0x85, + 0xB4, 0xE7, 0xB0, 0xF5, 0x81, 0x6F, 0x0D, 0xD0, 0xB0, 0x42, 0xDD, 0xD1, + 0x04, 0x98, 0x00, 0xF1, 0x40, 0x01, 0xFF, 0xF7, 0x89, 0xF8, 0x04, 0x98, + 0x4F, 0xF4, 0xA0, 0x62, 0x04, 0x49, 0xE5, 0xF7, 0x23, 0xFD, 0xD1, 0xE7, + 0xFF, 0xF7, 0x98, 0xF8, 0xCE, 0xE7, 0x00, 0x00, 0x88, 0x76, 0x20, 0x00, + 0x26, 0xAB, 0x82, 0x00, 0xF8, 0x44, 0xC0, 0x08, 0x03, 0x39, 0x10, 0x21, + 0x10, 0xB5, 0x14, 0x46, 0xFB, 0xF7, 0x8E, 0xFE, 0x00, 0x28, 0x00, 0xD0, + 0xC4, 0x63, 0x10, 0xBD, 0x10, 0xB5, 0x14, 0x46, 0xFB, 0xF7, 0x86, 0xFE, + 0x00, 0x28, 0x00, 0xD0, 0x04, 0x65, 0x10, 0xBD, 0x2D, 0xE9, 0xF8, 0x43, + 0x16, 0x46, 0x0F, 0x46, 0x80, 0x46, 0xFB, 0xF7, 0x7B, 0xFE, 0x24, 0x4D, + 0x04, 0x00, 0x37, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x40, 0xD0, 0x94, 0xF8, + 0x6B, 0x10, 0x49, 0xB3, 0x81, 0x7A, 0x05, 0x29, 0x3A, 0xD1, 0x00, 0x21, + 0x80, 0xF8, 0x74, 0x10, 0x33, 0x46, 0x01, 0x22, 0x1C, 0x49, 0xE8, 0x1C, + 0xDD, 0xF7, 0x67, 0xDE, 0x01, 0x2E, 0x0A, 0xD0, 0x0C, 0x21, 0x20, 0x46, + 0xFF, 0xF7, 0x32, 0xFD, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0x40, 0xF2, + 0x0C, 0x51, 0xFB, 0xF7, 0x17, 0xBC, 0x20, 0x7F, 0x01, 0x28, 0x08, 0xD1, + 0x20, 0x6A, 0x90, 0xF8, 0x7F, 0x10, 0x00, 0x29, 0x1C, 0xD0, 0x01, 0x68, + 0x41, 0xF0, 0x00, 0x51, 0x01, 0x60, 0x20, 0x46, 0xBD, 0xE8, 0xF8, 0x43, + 0xFE, 0xF7, 0x8C, 0xBF, 0x28, 0x46, 0xBD, 0xE8, 0xF8, 0x43, 0x0A, 0x49, + 0x00, 0x22, 0x20, 0x31, 0xDD, 0xF7, 0x41, 0x9E, 0x41, 0x46, 0x08, 0x48, + 0xDE, 0xF7, 0x0C, 0xD8, 0x05, 0x49, 0x03, 0x46, 0x02, 0x22, 0x4C, 0x31, + 0x28, 0x46, 0x00, 0x97, 0xDD, 0xF7, 0x35, 0xDE, 0xBD, 0xE8, 0xF8, 0x83, + 0x00, 0x39, 0x10, 0x21, 0xE0, 0x23, 0xC0, 0x08, 0x00, 0x00, 0x30, 0x21, + 0xF8, 0xB5, 0x15, 0x46, 0x0E, 0x46, 0x07, 0x46, 0xFB, 0xF7, 0x26, 0xFE, + 0x04, 0x00, 0x29, 0xD0, 0x20, 0x6A, 0x00, 0x28, 0x33, 0xD0, 0x81, 0x7A, + 0x01, 0x29, 0x30, 0xD1, 0x00, 0x21, 0x80, 0xF8, 0x74, 0x10, 0x2B, 0x46, + 0x01, 0x22, 0x16, 0x49, 0x16, 0x48, 0xDD, 0xF7, 0x16, 0xDE, 0x01, 0x2D, + 0x0A, 0xD0, 0x08, 0x21, 0x20, 0x46, 0xFF, 0xF7, 0xE1, 0xFC, 0x20, 0x46, + 0xBD, 0xE8, 0xF8, 0x40, 0x40, 0xF2, 0x0C, 0x51, 0xFB, 0xF7, 0xC6, 0xBB, + 0x01, 0x25, 0xE5, 0x84, 0x60, 0x79, 0x40, 0xF4, 0x80, 0x70, 0xFF, 0xF7, + 0x07, 0xFB, 0x20, 0x6A, 0x80, 0xF8, 0x80, 0x50, 0xBD, 0xE8, 0xF8, 0x40, + 0xFF, 0xF7, 0xF0, 0xBE, 0x39, 0x46, 0x08, 0x48, 0xDD, 0xF7, 0xC6, 0xDF, + 0x03, 0x46, 0x04, 0x49, 0x04, 0x48, 0x02, 0x22, 0x28, 0x31, 0xC0, 0x1E, + 0x00, 0x96, 0xDD, 0xF7, 0xEE, 0xDD, 0xF8, 0xBD, 0xE0, 0x24, 0xC0, 0x08, + 0x03, 0x39, 0x10, 0x21, 0x00, 0x00, 0x30, 0x21, 0x70, 0xB5, 0x10, 0x4B, + 0x00, 0x21, 0x5A, 0x68, 0x1B, 0x78, 0x10, 0xE0, 0xC1, 0xEB, 0xC1, 0x04, + 0x12, 0xF8, 0x24, 0x50, 0x4D, 0xB1, 0x02, 0xEB, 0x84, 0x04, 0xE4, 0x68, + 0x84, 0x42, 0x04, 0xD1, 0xC1, 0xEB, 0xC1, 0x00, 0x02, 0xEB, 0x80, 0x00, + 0x70, 0xBD, 0x49, 0x1C, 0xC9, 0xB2, 0x99, 0x42, 0xEC, 0xD3, 0x03, 0x46, + 0x01, 0x22, 0x04, 0x49, 0x04, 0x48, 0xDD, 0xF7, 0xC8, 0xDD, 0x00, 0x20, + 0x70, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, 0x94, 0x6C, 0xC0, 0x08, + 0x00, 0x33, 0x10, 0x21, 0x2D, 0xE9, 0xFF, 0x4F, 0x83, 0xB0, 0x8B, 0x46, + 0xDD, 0xE9, 0x10, 0x48, 0x01, 0x46, 0x00, 0x20, 0x20, 0x80, 0x1F, 0x46, + 0x40, 0xF2, 0x04, 0x45, 0x08, 0x46, 0xF9, 0xF7, 0xA5, 0xFA, 0x06, 0x00, + 0x4F, 0xF4, 0x90, 0x69, 0x09, 0xD0, 0x73, 0x78, 0xDF, 0xF8, 0x80, 0xA0, + 0x02, 0x2B, 0x08, 0xD0, 0x01, 0x22, 0x1F, 0x49, 0x50, 0x46, 0xDD, 0xF7, + 0xA2, 0xDD, 0x48, 0x46, 0x07, 0xB0, 0xBD, 0xE8, 0xF0, 0x8F, 0x1C, 0x48, + 0xCB, 0xEB, 0xCB, 0x01, 0x40, 0x68, 0x00, 0xEB, 0x81, 0x00, 0xD0, 0xF8, + 0x10, 0xC0, 0xBC, 0xF1, 0x00, 0x0F, 0x13, 0xD0, 0xCD, 0xE9, 0x00, 0x48, + 0xF0, 0x78, 0x3B, 0x46, 0x59, 0x46, 0x05, 0x9A, 0xE0, 0x47, 0x05, 0x00, + 0x0C, 0xD0, 0xA5, 0xF5, 0x50, 0x60, 0x01, 0x38, 0x06, 0xD0, 0x0F, 0x49, + 0x2B, 0x46, 0x01, 0x22, 0x2C, 0x31, 0x50, 0x46, 0xDD, 0xF7, 0x7F, 0xDD, + 0x28, 0x46, 0xDB, 0xE7, 0x72, 0x8A, 0x21, 0x88, 0x78, 0x1E, 0x10, 0x44, + 0x81, 0x42, 0x00, 0xDD, 0x20, 0x80, 0x20, 0x88, 0xC0, 0x1B, 0x06, 0xD4, + 0x20, 0x80, 0xD8, 0xF8, 0x00, 0x00, 0xC1, 0x19, 0xC8, 0xF8, 0x00, 0x10, + 0xEC, 0xE7, 0x40, 0xF2, 0x07, 0x45, 0xE9, 0xE7, 0x00, 0x33, 0x10, 0x21, + 0x44, 0x6C, 0xC0, 0x08, 0xB0, 0x78, 0x20, 0x00, 0x0E, 0xB5, 0x8D, 0xF8, + 0x00, 0x00, 0x07, 0x48, 0x8D, 0xF8, 0x02, 0x10, 0x8D, 0xF8, 0x03, 0x20, + 0xAD, 0xF8, 0x04, 0x30, 0x82, 0x68, 0x00, 0x2A, 0x02, 0xD0, 0x69, 0x46, + 0xFF, 0x20, 0x90, 0x47, 0x0E, 0xBD, 0x00, 0x00, 0xB0, 0x78, 0x20, 0x00, + 0x3E, 0xB5, 0x01, 0x25, 0x06, 0x9C, 0x8D, 0xF8, 0x05, 0x00, 0x09, 0x48, + 0x8D, 0xF8, 0x00, 0x50, 0xAD, 0xF8, 0x06, 0x20, 0xAD, 0xF8, 0x08, 0x30, + 0xAD, 0xF8, 0x02, 0x40, 0x8D, 0xF8, 0x04, 0x10, 0x82, 0x68, 0x00, 0x2A, + 0x02, 0xD0, 0x69, 0x46, 0xFF, 0x20, 0x90, 0x47, 0x3E, 0xBD, 0x00, 0x00, + 0xB0, 0x78, 0x20, 0x00, 0x7F, 0xB5, 0x1E, 0x4C, 0x01, 0x22, 0x1E, 0x49, + 0xA3, 0x78, 0x1E, 0x48, 0xDD, 0xF7, 0x2D, 0xDD, 0xA0, 0x78, 0x1D, 0x4D, + 0x81, 0x07, 0x0F, 0xD5, 0x28, 0x79, 0x63, 0x78, 0xAA, 0x78, 0xA9, 0x1D, + 0x8D, 0xE8, 0x0F, 0x00, 0xE3, 0x88, 0xA2, 0x88, 0xE9, 0x78, 0x68, 0x78, + 0xE9, 0xF7, 0xDC, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x02, 0x00, 0x0A, 0xE0, + 0x41, 0x07, 0x0A, 0xD5, 0x12, 0x4A, 0x29, 0x78, 0x0C, 0x32, 0x01, 0x20, + 0xE9, 0xF7, 0x8A, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x04, 0x00, 0xA0, 0x70, + 0x7F, 0xBD, 0xC1, 0x07, 0x09, 0xD0, 0x09, 0x4A, 0x21, 0x78, 0x08, 0x32, + 0x00, 0x20, 0xE9, 0xF7, 0x7D, 0xF9, 0xA0, 0x78, 0x20, 0xF0, 0x01, 0x00, + 0xF1, 0xE7, 0x00, 0x07, 0xF0, 0xD5, 0x01, 0x20, 0xE9, 0xF7, 0xE2, 0xF9, + 0xA0, 0x78, 0x20, 0xF0, 0x08, 0x00, 0xE8, 0xE7, 0x88, 0x74, 0x20, 0x00, + 0xFC, 0x81, 0xC0, 0x08, 0x03, 0x35, 0x10, 0x21, 0x38, 0x79, 0x20, 0x00, + 0x62, 0x74, 0x65, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, 0x68, 0x65, 0x61, + 0x70, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65, 0x5F, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, + 0x65, 0x5F, 0x73, 0x79, 0x73, 0x5F, 0x70, 0x6F, 0x6F, 0x6C, 0x5F, 0x69, + 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x70, + 0x6F, 0x6F, 0x6C, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x62, 0x74, 0x65, + 0x5F, 0x74, 0x69, 0x6D, 0x65, 0x72, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, + 0x61, 0x63, 0x6B, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x6C, 0x65, 0x5F, 0x61, + 0x64, 0x76, 0x5F, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, 0x5F, 0x65, 0x76, + 0x74, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, + 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x68, 0x63, 0x69, + 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x6F, 0x77, 0x65, + 0x72, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x68, + 0x63, 0x69, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x75, 0x70, + 0x70, 0x65, 0x72, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x72, 0x65, 0x71, + 0x00, 0x68, 0x63, 0x69, 0x5F, 0x69, 0x66, 0x5F, 0x63, 0x61, 0x6C, 0x6C, + 0x62, 0x61, 0x63, 0x6B, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x70, 0x6B, 0x74, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x65, 0x6E, 0x74, 0x72, + 0x79, 0x00, 0x68, 0x63, 0x69, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x68, + 0x63, 0x69, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x6C, 0x69, 0x6E, 0x6B, + 0x00, 0x68, 0x63, 0x69, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x63, 0x6D, + 0x64, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x70, 0x64, + 0x75, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, 0x61, 0x63, 0x6B, 0x00, 0x6C, + 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63, 0x69, 0x5F, + 0x70, 0x6B, 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x66, 0x72, 0x61, 0x67, 0x6D, 0x65, 0x6E, + 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65, + 0x6E, 0x64, 0x5F, 0x70, 0x64, 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, + 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x69, 0x67, 0x6E, + 0x61, 0x6C, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x75, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x6C, 0x32, + 0x63, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x73, 0x69, 0x67, + 0x6E, 0x61, 0x6C, 0x5F, 0x70, 0x6B, 0x74, 0x00, 0x6C, 0x32, 0x63, 0x5F, + 0x72, 0x65, 0x63, 0x6F, 0x6D, 0x62, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, + 0x61, 0x63, 0x6B, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x68, 0x61, 0x6E, 0x64, + 0x6C, 0x65, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69, 0x6E, 0x64, 0x00, + 0x6C, 0x32, 0x63, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x6C, 0x32, + 0x63, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x66, + 0x72, 0x65, 0x65, 0x5F, 0x61, 0x63, 0x6C, 0x5F, 0x6C, 0x69, 0x6E, 0x6B, + 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x64, 0x65, 0x6C, 0x65, 0x74, 0x65, 0x5F, + 0x63, 0x68, 0x61, 0x6E, 0x6E, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x68, 0x61, + 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x70, 0x64, 0x75, 0x5F, + 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, 0x6C, 0x65, 0x5F, 0x73, + 0x64, 0x75, 0x5F, 0x63, 0x61, 0x6C, 0x6C, 0x62, 0x61, 0x63, 0x6B, 0x00, + 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F, + 0x73, 0x65, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x5F, 0x6D, 0x73, 0x67, 0x00, + 0x6C, 0x32, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F, + 0x73, 0x64, 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x32, 0x63, 0x5F, + 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x64, + 0x75, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x73, 0x6D, 0x5F, 0x69, 0x6E, 0x69, + 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x73, + 0x6D, 0x5F, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6E, 0x5F, 0x69, 0x6E, 0x64, + 0x00, 0x73, 0x6D, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x75, 0x74, 0x68, 0x65, + 0x6E, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, + 0x64, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x63, 0x5F, 0x6D, 0x61, 0x6B, 0x65, + 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x73, 0x6D, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6C, 0x65, 0x5F, 0x73, 0x63, 0x5F, 0x67, + 0x65, 0x6E, 0x5F, 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x73, 0x70, + 0x00, 0x00, 0x04, 0x02, 0x00, 0x02, 0x00, 0x04, 0x02, 0x00, 0x02, 0x01, + 0x01, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x01, 0x02, + 0x00, 0x06, 0x00, 0x04, 0x02, 0x00, 0x02, 0x00, 0x05, 0x02, 0x00, 0x05, + 0x01, 0x01, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, 0x01, 0x05, + 0x02, 0x00, 0x05, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70, + 0x61, 0x69, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x65, 0x78, 0x63, 0x68, 0x61, + 0x6E, 0x67, 0x65, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x5F, 0x76, 0x61, 0x6C, 0x75, 0x65, + 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x69, + 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x66, 0x61, 0x69, 0x6C, 0x00, 0x73, 0x6D, + 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, + 0x5F, 0x69, 0x64, 0x65, 0x6E, 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, + 0x6E, 0x64, 0x5F, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5F, + 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x69, 0x64, 0x65, 0x6E, 0x74, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73, + 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x69, 0x64, 0x65, 0x6E, 0x74, + 0x5F, 0x61, 0x64, 0x64, 0x72, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73, + 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x69, 0x67, 0x6E, 0x5F, + 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73, + 0x65, 0x6E, 0x64, 0x5F, 0x6B, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, + 0x6E, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, + 0x5F, 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x63, 0x68, 0x65, 0x63, 0x6B, + 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x63, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x5F, 0x6B, 0x65, 0x79, 0x00, 0x73, + 0x6D, 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x71, + 0x75, 0x65, 0x75, 0x65, 0x5F, 0x69, 0x6E, 0x00, 0x73, 0x6D, 0x5F, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x71, 0x75, 0x65, 0x75, + 0x65, 0x5F, 0x6F, 0x75, 0x74, 0x00, 0x73, 0x6D, 0x5F, 0x68, 0x61, 0x6E, + 0x64, 0x6C, 0x65, 0x5F, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x00, + 0x73, 0x6D, 0x5F, 0x61, 0x6C, 0x6C, 0x6F, 0x63, 0x5F, 0x73, 0x6D, 0x70, + 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x73, 0x6D, 0x5F, 0x72, 0x65, 0x6C, + 0x65, 0x61, 0x73, 0x65, 0x5F, 0x73, 0x6D, 0x70, 0x5F, 0x64, 0x61, 0x74, + 0x61, 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63, + 0x69, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x00, 0x73, 0x6D, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x68, 0x63, 0x69, + 0x5F, 0x6C, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x64, 0x00, 0x73, 0x6D, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x63, 0x5F, 0x6D, 0x61, 0x6B, 0x65, + 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x73, 0x63, 0x5F, 0x67, 0x65, 0x6E, 0x5F, + 0x64, 0x68, 0x6B, 0x65, 0x79, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x73, 0x6D, + 0x5F, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x5F, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x5F, 0x71, 0x75, 0x65, 0x75, 0x65, 0x00, 0x61, 0x74, 0x74, + 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x00, 0x61, + 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00, + 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x5F, 0x72, 0x65, 0x71, 0x5F, 0x63, 0x6D, 0x64, 0x00, 0x61, + 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x65, 0x78, 0x65, 0x63, + 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x61, + 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x61, 0x64, + 0x5F, 0x62, 0x79, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x5F, 0x72, 0x73, 0x70, + 0x00, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x70, 0x72, + 0x65, 0x70, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72, 0x73, 0x70, + 0x00, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6E, 0x6F, + 0x74, 0x69, 0x66, 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, + 0x74, 0x5F, 0x65, 0x6E, 0x74, 0x72, 0x79, 0x00, 0x67, 0x61, 0x74, 0x74, + 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, + 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69, + 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, + 0x5F, 0x64, 0x65, 0x76, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x69, 0x6E, + 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x63, 0x63, 0x63, 0x64, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, + 0x74, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, + 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74, + 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x72, 0x65, + 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, + 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, + 0x63, 0x66, 0x6D, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, + 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, + 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x76, 0x65, + 0x72, 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, + 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x6D, + 0x70, 0x6C, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, + 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, + 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x64, 0x76, + 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, 0x61, + 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x65, + 0x6E, 0x64, 0x65, 0x64, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x72, 0x65, 0x71, + 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x5F, 0x63, + 0x68, 0x61, 0x6E, 0x6E, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x66, 0x72, + 0x65, 0x65, 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, + 0x6D, 0x73, 0x67, 0x5F, 0x6C, 0x6C, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, + 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, + 0x79, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x68, + 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x66, + 0x69, 0x6E, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, + 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, + 0x5F, 0x72, 0x65, 0x71, 0x00, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x72, 0x65, + 0x61, 0x64, 0x5F, 0x72, 0x65, 0x73, 0x75, 0x6D, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x73, + 0x65, 0x6E, 0x64, 0x5F, 0x63, 0x6D, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66, + 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, 0x67, 0x65, 0x74, 0x00, + 0x62, 0x74, 0x69, 0x66, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5F, + 0x70, 0x75, 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x76, 0x65, 0x6E, + 0x64, 0x6F, 0x72, 0x5F, 0x63, 0x6D, 0x64, 0x5F, 0x72, 0x65, 0x71, 0x00, + 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x63, + 0x66, 0x6D, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74, + 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, + 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, + 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, + 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x70, 0x72, 0x65, 0x70, + 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62, + 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x64, + 0x61, 0x74, 0x61, 0x5F, 0x73, 0x65, 0x74, 0x5F, 0x72, 0x65, 0x71, 0x00, + 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, + 0x61, 0x64, 0x76, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x73, 0x65, 0x74, + 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x65, 0x6E, + 0x74, 0x72, 0x79, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x69, 0x6E, 0x69, + 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, + 0x65, 0x76, 0x65, 0x6E, 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, + 0x63, 0x69, 0x5F, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x5F, 0x63, 0x6D, + 0x64, 0x5F, 0x72, 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, + 0x63, 0x69, 0x5F, 0x76, 0x65, 0x6E, 0x64, 0x6F, 0x72, 0x5F, 0x65, 0x76, + 0x74, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x64, + 0x65, 0x66, 0x65, 0x72, 0x5F, 0x75, 0x70, 0x5F, 0x6D, 0x73, 0x67, 0x00, + 0x62, 0x74, 0x69, 0x66, 0x5F, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, + 0x5F, 0x64, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5F, 0x6D, 0x73, + 0x67, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, + 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x73, + 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x69, 0x6E, 0x66, + 0x6F, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x65, 0x78, + 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x72, 0x65, 0x70, 0x6F, 0x72, 0x74, + 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, + 0x65, 0x5F, 0x73, 0x63, 0x61, 0x6E, 0x5F, 0x72, 0x65, 0x71, 0x5F, 0x72, + 0x63, 0x76, 0x64, 0x5F, 0x69, 0x6E, 0x66, 0x6F, 0x00, 0x62, 0x74, 0x69, + 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, 0x61, 0x74, + 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x5F, 0x72, 0x65, 0x71, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, + 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61, + 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x66, 0x6D, + 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, + 0x5F, 0x67, 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5F, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x63, 0x66, 0x6D, 0x00, 0x62, + 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x63, + 0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, + 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, + 0x70, 0x72, 0x65, 0x70, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x72, + 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x68, 0x61, 0x6E, 0x64, + 0x6C, 0x65, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, + 0x5F, 0x72, 0x73, 0x70, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, + 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65, 0x74, + 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x72, 0x61, 0x6E, 0x64, + 0x5F, 0x61, 0x64, 0x64, 0x72, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, + 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65, + 0x74, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x6F, 0x77, 0x6E, + 0x5F, 0x61, 0x64, 0x64, 0x72, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x62, + 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x6D, 0x6F, 0x76, + 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x73, 0x65, + 0x74, 0x00, 0x62, 0x74, 0x69, 0x66, 0x5F, 0x6C, 0x65, 0x5F, 0x63, 0x6C, + 0x65, 0x61, 0x72, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, + 0x73, 0x65, 0x74, 0x00, 0x67, 0x61, 0x70, 0x5F, 0x62, 0x74, 0x69, 0x66, + 0x5F, 0x6D, 0x73, 0x67, 0x5F, 0x63, 0x62, 0x00, 0x67, 0x61, 0x70, 0x5F, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5F, 0x62, 0x74, 0x5F, 0x73, 0x74, 0x61, + 0x63, 0x6B, 0x00, 0x67, 0x61, 0x70, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, + 0x65, 0x5F, 0x6D, 0x73, 0x67, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, + 0x64, 0x5F, 0x70, 0x61, 0x69, 0x72, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, + 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x6B, 0x65, 0x79, 0x5F, 0x69, + 0x6E, 0x70, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, + 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x6F, 0x6F, 0x62, + 0x5F, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, + 0x72, 0x6D, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x67, + 0x65, 0x74, 0x5F, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, 0x6B, + 0x65, 0x79, 0x00, 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x75, + 0x73, 0x65, 0x72, 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, + 0x6C, 0x65, 0x5F, 0x62, 0x6F, 0x6E, 0x64, 0x5F, 0x70, 0x61, 0x73, 0x73, + 0x6B, 0x65, 0x79, 0x5F, 0x64, 0x69, 0x73, 0x70, 0x6C, 0x61, 0x79, 0x5F, + 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x6C, 0x65, 0x5F, 0x62, + 0x6F, 0x6E, 0x64, 0x5F, 0x6B, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, + 0x5F, 0x6E, 0x6F, 0x74, 0x69, 0x66, 0x79, 0x00, 0x6C, 0x65, 0x5F, 0x62, + 0x6F, 0x6E, 0x64, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, + 0x61, 0x74, 0x74, 0x5F, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x73, + 0x74, 0x6F, 0x72, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00, 0x6C, 0x65, 0x5F, + 0x73, 0x65, 0x74, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x6C, 0x65, 0x6E, + 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x73, 0x73, + 0x69, 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x68, + 0x61, 0x6E, 0x6E, 0x5F, 0x6D, 0x61, 0x70, 0x00, 0x6C, 0x65, 0x5F, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x5F, 0x73, 0x6C, 0x61, 0x76, 0x65, + 0x5F, 0x6C, 0x61, 0x74, 0x65, 0x6E, 0x63, 0x79, 0x00, 0x6C, 0x65, 0x5F, + 0x73, 0x65, 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x5F, 0x74, 0x78, 0x5F, + 0x70, 0x6F, 0x77, 0x65, 0x72, 0x00, 0x6C, 0x65, 0x5F, 0x6C, 0x69, 0x6E, + 0x6B, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x65, 0x5F, 0x67, 0x65, + 0x74, 0x5F, 0x63, 0x6F, 0x6E, 0x6E, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, + 0x00, 0x6C, 0x65, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x72, 0x65, 0x6D, + 0x6F, 0x74, 0x65, 0x5F, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x00, + 0x6C, 0x65, 0x5F, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5F, 0x63, 0x6F, + 0x6E, 0x6E, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x00, 0x6C, 0x65, 0x5F, + 0x73, 0x65, 0x74, 0x5F, 0x70, 0x68, 0x79, 0x00, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x5F, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x5F, 0x70, 0x61, 0x72, + 0x61, 0x6D, 0x00, 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x61, 0x74, + 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x00, 0x63, 0x6C, 0x69, + 0x65, 0x6E, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x69, 0x6E, 0x64, + 0x5F, 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x63, 0x6C, 0x69, + 0x65, 0x6E, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, 0x67, + 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, + 0x64, 0x5F, 0x62, 0x79, 0x5F, 0x75, 0x75, 0x69, 0x64, 0x00, 0x63, 0x6C, + 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, + 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x00, 0x63, 0x6C, 0x69, + 0x65, 0x6E, 0x74, 0x5F, 0x67, 0x65, 0x74, 0x5F, 0x6E, 0x6F, 0x74, 0x69, + 0x66, 0x79, 0x5F, 0x64, 0x61, 0x74, 0x61, 0x5F, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x69, 0x6E, + 0x69, 0x74, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x61, 0x74, + 0x74, 0x72, 0x5F, 0x72, 0x65, 0x61, 0x64, 0x5F, 0x63, 0x6F, 0x6E, 0x66, + 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x61, + 0x74, 0x74, 0x72, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x6F, + 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x5F, 0x65, 0x78, 0x65, 0x63, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, + 0x63, 0x6F, 0x6E, 0x66, 0x69, 0x72, 0x6D, 0x00, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x64, 0x61, 0x74, 0x61, + 0x00, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5F, 0x67, 0x65, 0x74, 0x5F, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x63, 0x6D, 0x64, 0x5F, 0x64, 0x61, + 0x74, 0x61, 0x5F, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5F, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x5F, + 0x67, 0x61, 0x74, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x5F, 0x70, 0x72, + 0x65, 0x5F, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5F, 0x69, 0x6E, 0x64, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x65, + 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x00, 0x00, + 0x02, 0x08, 0x00, 0x28, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x05, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x02, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x28, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x84, 0x74, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x83, 0x74, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x03, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0xFC, 0x78, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xA6, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xF4, 0x78, 0x20, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x28, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, 0x2A, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x2C, 0x79, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x29, 0x7B, 0x81, 0x00, 0x79, 0x7B, 0x81, 0x00, 0x41, 0x7C, 0x81, 0x00, + 0xA4, 0x01, 0x67, 0x61, 0x70, 0x5F, 0x73, 0x65, 0x6E, 0x64, 0x5F, 0x6D, + 0x73, 0x67, 0x5F, 0x74, 0x6F, 0x5F, 0x61, 0x70, 0x70, 0x00, 0x6C, 0x65, + 0x5F, 0x63, 0x6F, 0x63, 0x5F, 0x69, 0x6E, 0x69, 0x74, 0x00, 0x6C, 0x65, + 0x5F, 0x63, 0x6F, 0x63, 0x5F, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, + 0x6C, 0x65, 0x5F, 0x65, 0x78, 0x74, 0x5F, 0x61, 0x64, 0x76, 0x5F, 0x69, + 0x6E, 0x69, 0x74, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x25, 0x84, 0x82, 0x00, 0xAD, 0x7A, 0x82, 0x00, 0x61, 0x7E, 0x82, 0x00, + 0xF5, 0x78, 0x82, 0x00, 0xB5, 0x79, 0x82, 0x00, 0x7D, 0x79, 0x82, 0x00, + 0x09, 0x69, 0x82, 0x00, 0xD9, 0x77, 0x82, 0x00, 0x95, 0x6A, 0x82, 0x00, + 0x11, 0x6A, 0x82, 0x00, 0x91, 0x82, 0x82, 0x00, 0xF5, 0x81, 0x82, 0x00, + 0x2D, 0x81, 0x82, 0x00, 0x45, 0x67, 0x82, 0x00, 0xF1, 0x6A, 0x82, 0x00, + 0x25, 0x84, 0x82, 0x00, 0x1C, 0x00, 0x01, 0x03, 0x01, 0x00, 0x07, 0x00, + 0x7F, 0x7F, 0x08, 0x01, 0xFB, 0x00, 0x48, 0x08, 0x07, 0x02, 0x47, 0x41, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x84, 0x03, 0x03, 0x07, 0x07, 0x00, + 0x20, 0x00, 0x00, 0x04, 0x02, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x10, 0x00, 0x10, 0x00, 0x02, 0x08, 0x08, 0x00, 0xC8, 0x00, + 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x40, 0x00, 0x20, 0x00, + 0x01, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, +}; +const unsigned long upperstack_lib_img_termination = 0x00000000; +const unsigned long upperstack_lib_img_start = 0x00000000; +const unsigned long upperstack_lib_img_finish = 0x0001D2A0; +const unsigned long upperstack_lib_img_length = 0x0001D2A0; + +#define UPPERSTACK_LIB_IMG_TERMINATION 0x00000000 +#define UPPERSTACK_LIB_IMG_START 0x00000000 +#define UPPERSTACK_LIB_IMG_FINISH 0x0001D2A0 +#define UPPERSTACK_LIB_IMG_LENGTH 0x0001D2A0 diff --git a/src/ble/upperstack_lib.h b/src/ble/upperstack_lib.h new file mode 100644 index 0000000..d506b89 --- /dev/null +++ b/src/ble/upperstack_lib.h @@ -0,0 +1,10 @@ +#ifndef ______SDK_SRC_BLE_UPPERSTACK_LIB_H +#define ______SDK_SRC_BLE_UPPERSTACK_LIB_H + +extern const unsigned long upperstack_lib_img_termination; +extern const unsigned long upperstack_lib_img_start; +extern const unsigned long upperstack_lib_img_finish; +extern const unsigned long upperstack_lib_img_length; +extern const unsigned char upperstack_lib_img[]; + +#endif /* ______SDK_SRC_BLE_UPPERSTACK_LIB_H */ diff --git a/src/dfu/dfu_application.c b/src/dfu/dfu_application.c new file mode 100644 index 0000000..83c4d2c --- /dev/null +++ b/src/dfu/dfu_application.c @@ -0,0 +1,661 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file dfu_application.c +* @brief dfu task application implementation +* @details dfu task application implementation +* @author +* @date +* @version +* ********************************************************************************************************* +*/ +#include +#include +#include "app_msg.h" +#include "gap.h" +#include "gap_adv.h" +#include "gap_bond_le.h" +#include "gap_conn_le.h" +#include "gap_msg.h" +#include "profile_server.h" +#include "os_timer.h" +#include "otp.h" +#include "otp_config.h" +#include "dfu_api.h" +#include "dfu_service.h" +//#include "ota_service.h" +#include "dfu_main.h" +#include "dfu_flash.h" +#include "dfu_application.h" +#include "dfu_task.h" +#include "board.h" + +#if (SUPPORT_NORMAL_OTA == 1) +/*============================================================================* + * Macros + *============================================================================*/ + + +/*============================================================================* + * Local Variables + *============================================================================*/ +T_GAP_DEV_STATE dfu_gap_cur_state = {0, 0, 0, 0}; +T_GAP_CONN_STATE dfu_gap_conn_state = GAP_CONN_STATE_DISCONNECTED; +static bool rtk_dfu_active_reset_pending = false; +static uint8_t rtk_active_reset_mode = 0; + +void dfu_peripheral_handle_gap_msg(T_IO_MSG *p_gap_msg); + +/*============================================================================* + * External Variables + *============================================================================*/ + + +/*============================================================================* + * Functions + *============================================================================*/ +/* + * @fn app_handle_io_msg + * @brief All the application events are pre-handled in this function. + * All the IO MSGs are sent to this function, Then the event handling function + * shall be called according to the MSG type. + * + * @param io_msg - bee io msg data + * @return void + */ +void dfu_handle_io_msg(T_IO_MSG io_msg) +{ + uint16_t msg_type = io_msg.type; + + switch (msg_type) + { + case IO_MSG_TYPE_BT_STATUS: + { + dfu_peripheral_handle_gap_msg(&io_msg); + } + break; + case IO_MSG_TYPE_DFU_VALID_FW: + { + APP_PRINT_INFO0("IO_MSG_TYPE_DFU_VALID_FW"); + dfu_service_handle_valid_fw(io_msg.u.param); + } + break; + default: + break; + } +} + +/****************************************************************** + * @fn peripheral_HandleBtDevStateChangeEvt + * @brief All the gaprole_States_t events are pre-handled in this function. + * Then the event handling function shall be called according to the newState. + * + * @param newState - new gap state + * @return void + */ +void dfu_periph_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause) +{ + DFU_PRINT_INFO4("dfu_periph_handle_dev_state_evt: init state %d, adv state %d, conn state %d, cause 0x%x", + new_state.gap_init_state, new_state.gap_adv_state, + new_state.gap_conn_state, cause); + if (dfu_gap_cur_state.gap_init_state != new_state.gap_init_state) + { + if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY) + { + dfu_set_rand_addr(); + + /*stack ready*/ + le_adv_start(); + } + } + + if (dfu_gap_cur_state.gap_adv_state != new_state.gap_adv_state) + { + if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE) + { + if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN) + { + DFU_PRINT_INFO0("GAP adv stoped: because connection created"); + } + else + { + DFU_PRINT_INFO0("GAP adv stoped"); + } + } + else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING) + { + DFU_PRINT_INFO0("GAP adv start"); + } + } + + if (dfu_gap_cur_state.gap_conn_state != new_state.gap_conn_state) + { + DFU_PRINT_INFO2("conn state: %d -> %d", + dfu_gap_cur_state.gap_conn_state, + new_state.gap_conn_state); + } + dfu_gap_cur_state = new_state; +} + +void dfu_periph_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, + uint16_t disc_cause) +{ + DFU_PRINT_INFO3("dfu_periph_handle_conn_state_evt: conn_id = %d old_state = %d new_state = %d", + conn_id, dfu_gap_conn_state, new_state); + switch (new_state) + { + case GAP_CONN_STATE_DISCONNECTED: + { + if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE)) + && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE))) + { + DFU_PRINT_ERROR1("connection lost: cause 0x%x", disc_cause); + } + + if (rtk_dfu_active_reset_pending) + { + rtk_dfu_active_reset_pending = false; + + /*when muti image in temp, need goto OTA mode*/ + if (rtk_active_reset_mode) + { + DBG_DIRECT("comb Mormal OTA, Reset to OTA Mode"); + rtk_active_reset_mode = false; + dfu_switch_to_ota_mode(); + } + else + { + //unlock_flash_bp_all(); + dfu_fw_reboot(true); + } + + } + else + { + if (OTP->ota_link_loss_reset) + { + dfu_fw_reboot(false); + } + else + { + le_adv_start(); + } + } + + } + break; + + case GAP_CONN_STATE_CONNECTED: + { + uint16_t conn_interval; + uint16_t conn_latency; + uint16_t conn_supervision_timeout; + uint8_t remote_bd[6]; + T_GAP_REMOTE_ADDR_TYPE remote_bd_type; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + le_get_conn_addr(conn_id, remote_bd, (unsigned char *)&remote_bd_type); + DFU_PRINT_INFO5("GAPSTATE_CONN_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x", + TRACE_BDADDR(remote_bd), remote_bd_type, + conn_interval, conn_latency, conn_supervision_timeout); + + g_dfu_para.dfu_conn_para_update_in_progress = false; + g_dfu_para.dfu_conn_interval = conn_interval; + g_dfu_para.dfu_conn_lantency = conn_latency; + + os_timer_stop(&wait4_conn_timer_handle); + os_timer_start(&image_transfer_timer_handle); + if (timeout_value_ctittv && (OTP->ota_timeout_ctittv != 0xFF)) + { + os_timer_start(&ctittv_timer_handle); + } + } + break; + + default: + break; + } + dfu_gap_conn_state = new_state; +} + +/****************************************************************** + * @fn peripheral_HandleBtGapAuthenStateChangeEvt + * @brief All the bonding state change events are pre-handled in this function. + * Then the event handling function shall be called according to the newState. + * + * @param newState - new bonding state + * @return void + */ +void dfu_periph_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause) +{ + DFU_PRINT_INFO1("dfu_periph_handle_authen_state_evt:conn_id=%d", conn_id); + + switch (new_state) + { + case GAP_AUTHEN_STATE_STARTED: + { + DFU_PRINT_INFO0("GAPSEC_AUTHEN_STATE_STARTED"); + } + break; + + case GAP_AUTHEN_STATE_COMPLETE: + { + DFU_PRINT_INFO0("GAPSEC_AUTHEN_STATE_COMPLETE"); + if (cause == 0) + { + DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE pair success"); + } + else + { + DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE pair failed"); + } + } + break; + + default: + { + DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_AUTHEN_STATE_CHANGE: unknown newstate=%d!", new_state); + } + break; + } +} + +/****************************************************************** + * @fn peripheral_HandleBtGapConnParaChangeEvt + * @brief All the connection parameter update change events are pre-handled in this function. + * Then the event handling function shall be called according to the status. + * + * @param status - connection parameter result, 0 - success, otherwise fail. + * @return void + */ +void dfu_periph_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause) +{ + switch (status) + { + case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS: + { + uint16_t conn_interval; + uint16_t conn_slave_latency; + uint16_t conn_supervision_timeout; + + le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id); + le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id); + le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id); + DFU_PRINT_INFO3("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE success(Normal OTA): interval=0x%x, slave_latency=0x%x, supervision_timeout=0x%x", + conn_interval, conn_slave_latency, conn_supervision_timeout); + + g_dfu_para.dfu_conn_interval = conn_interval; + g_dfu_para.dfu_conn_lantency = conn_slave_latency; + dfu_notify_conn_para_update_req(conn_id, DFU_ARV_SUCCESS); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_FAIL: + { + DFU_PRINT_ERROR1("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE failed(Normal OTA): cause 0x%x", cause); + dfu_notify_conn_para_update_req(conn_id, DFU_ARV_FAIL_OPERATION); + } + break; + + case GAP_CONN_PARAM_UPDATE_STATUS_PENDING: + { + DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_CONN_PARA_UPDATE_CHANGE Request success but pending(Normal OTA)."); + } + break; + + default: + break; + } +} +/** + * @brief Handle msg LE_GAP_MSG_TYPE_CONN_MTU_INFO + * @note This msg is used to inform APP that exchange mtu procedure is completed. + * @param[in] conn_id Connection ID + * @param[in] mtu_size New mtu size + * @return void + */ +void dfu_periph_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size) +{ + DFU_PRINT_INFO2("dfu_periph_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size); +} +/****************************************************************** + * @fn peripheral_HandleBtGapMessage + * @brief All the bt gap msg events are pre-handled in this function. + * Then the event handling function shall be called according to the subType + * of BEE_IO_MSG. + * + * @param pBeeIoMsg - pointer to bee io msg + * @return void + */ +void dfu_peripheral_handle_gap_msg(T_IO_MSG *p_gap_msg) +{ + T_LE_GAP_MSG gap_msg; + uint8_t conn_id; + memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param)); + + DFU_PRINT_TRACE1("dfu_peripheral_handle_gap_msg: subtype %d", p_gap_msg->subtype); + switch (p_gap_msg->subtype) + { + case GAP_MSG_LE_DEV_STATE_CHANGE: + { + dfu_periph_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state, + gap_msg.msg_data.gap_dev_state_change.cause); + } + break; + + case GAP_MSG_LE_CONN_STATE_CHANGE: + { + dfu_periph_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id, + (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state, + gap_msg.msg_data.gap_conn_state_change.disc_cause); + } + break; + + case GAP_MSG_LE_CONN_MTU_INFO: + { + dfu_periph_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id, + gap_msg.msg_data.gap_conn_mtu_info.mtu_size); + } + break; + + case GAP_MSG_LE_CONN_PARAM_UPDATE: + { + dfu_periph_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id, + gap_msg.msg_data.gap_conn_param_update.status, + gap_msg.msg_data.gap_conn_param_update.cause); + } + break; + + case GAP_MSG_LE_AUTHEN_STATE_CHANGE: + { + dfu_periph_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id, + gap_msg.msg_data.gap_authen_state.new_state, + gap_msg.msg_data.gap_authen_state.status); + } + break; + + case GAP_MSG_LE_BOND_JUST_WORK: + { + conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id; + le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_BOND_JUST_WORK"); + } + break; + + case GAP_MSG_LE_BOND_PASSKEY_DISPLAY: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id; + le_bond_get_display_key(conn_id, &display_value); + DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_PASSKEY_DISPLAY:passkey %d", display_value); + le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT); + } + break; + + case GAP_MSG_LE_BOND_USER_CONFIRMATION: + { + uint32_t display_value = 0; + conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id; + le_bond_get_display_key(conn_id, &display_value); + DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_USER_CONFIRMATION: passkey %d", display_value); + } + break; + + case GAP_MSG_LE_BOND_PASSKEY_INPUT: + { + uint32_t passkey = 888888; + conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id; + DFU_PRINT_INFO1("LE_GAP_MSG_TYPE_BOND_PASSKEY_INPUT: conn_id %d", conn_id); + le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT); + } + break; + + case GAP_MSG_LE_BOND_OOB_INPUT: + { + DFU_PRINT_INFO0("LE_GAP_MSG_TYPE_BOND_OOB_INPUT"); + conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id; + } + break; + + default: + DFU_PRINT_ERROR1("dfu_peripheral_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype); + break; + } +} +/** @defgroup DFU_GAP_CALLBACK GAP Callback Event Handler + * @brief Handle GAP callback event + * @{ + */ +/** + * @brief Callback for gap le to notify app + * @param[in] cb_type callback msy type @ref GAP_LE_MSG_Types. + * @param[in] p_cb_data point to callback data @ref T_LE_CB_DATA. + * @retval result @ref T_APP_RESULT + */ +T_APP_RESULT dfu_gap_callback(uint8_t cb_type, void *p_cb_data) +{ + T_APP_RESULT result = APP_RESULT_SUCCESS; + T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data; + + switch (cb_type) + { + case GAP_MSG_LE_DATA_LEN_CHANGE_INFO: + DFU_PRINT_INFO3("GAP_MSG_LE_DATA_LEN_CHANGE_INFO: conn_id %d, tx octets 0x%x, max_tx_time 0x%x", + p_data->p_le_data_len_change_info->conn_id, + p_data->p_le_data_len_change_info->max_tx_octets, + p_data->p_le_data_len_change_info->max_tx_time); + break; + + case GAP_MSG_LE_BOND_MODIFY_INFO: + DFU_PRINT_INFO1("GAP_MSG_LE_BOND_MODIFY_INFO: type 0x%x", + p_data->p_le_bond_modify_info->type); + break; + + case GAP_MSG_LE_MODIFY_WHITE_LIST: + DFU_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x", + p_data->p_le_modify_white_list_rsp->operation, + p_data->p_le_modify_white_list_rsp->cause); + break; + case GAP_MSG_LE_SET_RAND_ADDR: + DFU_PRINT_INFO1("GAP_MSG_LE_SET_RAND_ADDR: cause 0x%x", + p_data->p_le_set_rand_addr_rsp->cause); + break; + default: + DFU_PRINT_INFO1("app_gap_callback: unhandled cb_type 0x%x", cb_type); + break; + } + return result; +} + +/****************************************************************** + * @fn app_profile_callback + * @brief All the bt profile callbacks are handled in this function. + * Then the event handling function shall be called according to the serviceID + * of BEE_IO_MSG. + * + * @param serviceID - service id of profile + * @param pData - pointer to callback data + * @return void + */ + +T_APP_RESULT dfu_profile_callback(T_SERVER_ID service_id, void *p_data) +{ + T_APP_RESULT app_result = APP_RESULT_SUCCESS; + if (service_id == SERVICE_PROFILE_GENERAL_ID) + { + T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data; + switch (p_param->eventId) + { + case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event. + DFU_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d", + p_param->event_data.service_reg_result); + break; + + case PROFILE_EVT_SEND_DATA_COMPLETE: + DFU_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits = %d", + p_param->event_data.send_data_result.conn_id, + p_param->event_data.send_data_result.cause, + p_param->event_data.send_data_result.service_id, + p_param->event_data.send_data_result.attrib_idx, + p_param->event_data.send_data_result.credits); + if (p_param->event_data.send_data_result.cause == GAP_SUCCESS) + { + DFU_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success"); + } + else + { + DFU_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed"); + } + break; + + default: + break; + } + } + else if (service_id == rtk_dfu_service_id) + { + T_DFU_CALLBACK_DATA *p_dfu_cb_data = (T_DFU_CALLBACK_DATA *)p_data; + switch (p_dfu_cb_data->msg_type) + { + case SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION: + { + if (p_dfu_cb_data->msg_data.notification_indification_index == DFU_NOTIFY_ENABLE) + { + DFU_PRINT_INFO0("dfu notification enable"); + } + else if (p_dfu_cb_data->msg_data.notification_indification_index == + DFU_NOTIFY_DISABLE) + { + DFU_PRINT_INFO0("dfu notification disable"); + } + } + break; + case SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE: + { + uint8_t dfu_write_opcode = p_dfu_cb_data->msg_data.write.opcode; + if (DFU_WRITE_ATTR_EXIT == dfu_write_opcode) + { + if (p_dfu_cb_data->msg_data.write.write_attrib_index == INDEX_DFU_CONTROL_POINT_CHAR_VALUE) + { + uint8_t control_point_opcode = *p_dfu_cb_data->msg_data.write.p_value; + switch (control_point_opcode) + { + case DFU_OPCODE_START_DFU: + { +#if OTA_TIMEOUT_WAIT_PACKET + if (timeout_value_wait_packet) + { + os_timer_start(&wait_packet_timer_handle); + } +#endif + } + break; + + case DFU_OPCODE_VALID_FW: + { + T_IO_MSG dfu_valid_fw_msg; +#if OTA_TIMEOUT_WAIT_PACKET + if (timeout_value_wait_packet) + { + os_timer_stop(&wait_packet_timer_handle); + } +#endif + + dfu_valid_fw_msg.type = IO_MSG_TYPE_DFU_VALID_FW; + dfu_valid_fw_msg.u.param = p_dfu_cb_data->conn_id; + if (app_send_msg_to_dfutask(&dfu_valid_fw_msg) == false) + { + DBG_DIRECT("DFU send Valid FW msg fail!"); + } + } + break; + case DFU_OPCODE_ACTIVE_IMAGE_RESET: + { + DFU_PRINT_INFO1("DFU_OPCODE_ACTIVE_IMAGE_RESET cmd length=%d", + p_dfu_cb_data->msg_data.write.length); + if (DFU_LENGTH_ACTIVE_IMAGE_RESET_TO_OTA_MODE == p_dfu_cb_data->msg_data.write.length) + { + /*Optional, 0:Reset to Normal Mode, 1: Reset to OTA mode*/ + rtk_active_reset_mode = *(p_dfu_cb_data->msg_data.write.p_value + 1); + } +#if (ENABLE_AUTO_BANK_SWITCH == 1) + if (is_ota_support_bank_switch()) + { + uint32_t ota_addr; + ota_addr = get_header_addr_by_img_id(OTA); + DFU_PRINT_INFO1("DFU_OPCODE_ACTIVE_IMAGE_RESET: Bank switch erase ota_addr=0x%x", ota_addr); + unlock_flash_bp_all(); + flash_erase_locked(FLASH_ERASE_SECTOR, ota_addr); + lock_flash_bp(); + } +#endif + le_disconnect(0); + rtk_dfu_active_reset_pending = true; + } + break; + default: + break; + } + } + else if (p_dfu_cb_data->msg_data.write.write_attrib_index == INDEX_DFU_PACKET_VALUE) + { +#if OTA_TIMEOUT_WAIT_PACKET + if (timeout_value_wait_packet) + { + os_timer_restart(&wait_packet_timer_handle, timeout_value_wait_packet); + } +#endif + } + else + { + } + } + else if (DFU_WRITE_START == dfu_write_opcode) + { + T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) + p_dfu_cb_data->msg_data.write.p_value; + if ((T_IMG_ID)p_header->image_id >= OTA && (T_IMG_ID)p_header->image_id < IMAGE_MAX && + (p_header->payload_len + IMG_HEADER_SIZE) < get_temp_ota_bank_size_by_img_id(( + T_IMG_ID)p_header->image_id)) + { + uint32_t total_period = timeout_value_total * ((p_header->payload_len + IMG_HEADER_SIZE) / 102400 + + 1); + os_timer_restart(&total_timer_handle, total_period); + uint32_t transfer_period = timeout_value_image_transfer * ((p_header->payload_len + + IMG_HEADER_SIZE) / 102400 + + 1); + os_timer_restart(&image_transfer_timer_handle, transfer_period); + DBG_DIRECT("[Normal OTA] restart timer, total=%dms, transfer=%dms!", total_period, transfer_period); + } + + if (timeout_value_ctittv) + { + os_timer_stop(&ctittv_timer_handle); + } + + } + else if (DFU_WRITE_FAIL == dfu_write_opcode) + { + DBG_DIRECT("DFU FAIL! reason=%d", *p_dfu_cb_data->msg_data.write.p_value); + } + else + { + } + } + break; + default: + break; + } + } + else + { + } + + + return app_result; +} + +#endif //end SUPPORT_NORMAL_OTA diff --git a/src/dfu/dfu_application.h b/src/dfu/dfu_application.h new file mode 100644 index 0000000..af50dda --- /dev/null +++ b/src/dfu/dfu_application.h @@ -0,0 +1,33 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************* +* @file simple_ble_peripheral_application.h +* @brief simple_ble_peripheral_application +* @details simple_ble_peripheral_application +* @author jane +* @date 2015-12-22 +* @version v0.1 +* ********************************************************************************************************* +*/ + +#ifndef _PERIPHERAL_APPLICATION__ +#define _PERIPHERAL_APPLICATION__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "app_msg.h" +//#include +#include "profile_server.h" + +void dfu_handle_io_msg(T_IO_MSG io_driver_msg_recv); +T_APP_RESULT dfu_profile_callback(T_SERVER_ID service_id, void *p_data); +T_APP_RESULT dfu_gap_callback(uint8_t cb_type, void *p_cb_data); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/dfu/dfu_main.c b/src/dfu/dfu_main.c new file mode 100644 index 0000000..f0a85fe --- /dev/null +++ b/src/dfu/dfu_main.c @@ -0,0 +1,325 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include +#include "gap.h" +#include "gap_adv.h" +#include "gap_bond_le.h" +#include "profile_server.h" +#include "os_timer.h" +#include "otp_config.h" +#include "otp.h" +#include "trace.h" +#include "dfu_api.h" +#include "dfu_flash.h" +#include "dfu_service.h" +#include "dfu_main.h" +#include "dfu_task.h" +#include "dfu_application.h" +#include "board.h" +#if (AON_WDG_ENABLE == 1) +#include "rtl876x_aon_wdg.h" +#endif + +#if (SUPPORT_NORMAL_OTA == 1) +/*============================================================================* + * Macros + *============================================================================*/ +#define TIMER_ID_DFU_TOTAL 1 +#define TIMER_ID_DFU_WAIT4_CONN 2 +#define TIMER_ID_DFU_IMAGE_TRANSFER 3 +#define TIMER_ID_DFU_CTITTV 4 +#define TIMER_ID_DFU_WAIT_PACKET 5 + +#define BD_ADDR_SIZE 6 + +/* What is the advertising interval when device is discoverable (units of 625us, 160=100ms)*/ +#define DEFAULT_ADVERTISING_INTERVAL_MIN 160 /* 100ms */ +#define DEFAULT_ADVERTISING_INTERVAL_MAX 176 /* 110ms */ + +/*============================================================================* + * Types + *============================================================================*/ + + +/*============================================================================* + * Variables + *============================================================================*/ +void *total_timer_handle; +void *wait4_conn_timer_handle; +void *image_transfer_timer_handle; +void *ctittv_timer_handle; +uint32_t timeout_value_total; +uint32_t timeout_value_wait4_conn; +uint32_t timeout_value_image_transfer; +uint32_t timeout_value_ctittv; +#if OTA_TIMEOUT_WAIT_PACKET +void *wait_packet_timer_handle; +uint32_t timeout_value_wait_packet; +#endif + +T_SERVER_ID rtk_dfu_service_id; + +/*============================================================================* + * Local Functions + *============================================================================*/ +/* + * @fn Initial gap parameters + * @brief Initialize peripheral and gap bond manager related parameters + * + * @return void + */ +void dfu_le_gap_init(void) +{ + + uint8_t bt_bd_addr[6]; + gap_get_param(GAP_PARAM_BD_ADDR, bt_bd_addr); //get OTP->bt_bd_addr + + //device name and device appearance + char fmt[] = "%02x%02x%02x%02x%02x%02x"; + char device_name[GAP_DEVICE_NAME_LEN]; + sprintf(device_name, fmt, + bt_bd_addr[5], bt_bd_addr[4], bt_bd_addr[3], + bt_bd_addr[2], bt_bd_addr[1], bt_bd_addr[0] + ); + uint16_t appearance = GAP_GATT_APPEARANCE_KEYBOARD; + uint8_t slave_init_mtu_req = true; + + //advertising parameters + uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND; + uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC; + uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0}; + uint8_t adv_chann_map = GAP_ADVCHAN_ALL; + uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY; + uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN; + uint8_t local_bd_type = GAP_LOCAL_ADDR_LE_RANDOM; + //advertising data + uint8_t adv_data_uuid128[31] = + { + /* Flags */ + 0x02, /* length */ + GAP_ADTYPE_FLAGS, /* type="flags" */ + GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, + + /* Service */ + 0x11, /* length */ + GAP_ADTYPE_128BIT_COMPLETE, /* type="Complete list of 128-bit UUIDs" */ + GATT_UUID128_DFU_SERVICE, + + 9, + 0xFF, + 0x5D, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + }; + adv_data_uuid128[25] = bt_bd_addr[5]; + adv_data_uuid128[26] = bt_bd_addr[4]; + adv_data_uuid128[27] = bt_bd_addr[3]; + adv_data_uuid128[28] = bt_bd_addr[2]; + adv_data_uuid128[29] = bt_bd_addr[1]; + adv_data_uuid128[30] = bt_bd_addr[0]; + + //scan response data + uint8_t scan_rsp_data[] = + { + /*Complete local name*/ + 7, /* default target name length */ + GAP_ADTYPE_LOCAL_NAME_COMPLETE, /* type="Complete local name" */ + '\0', + '\0', + '\0', + '\0', + '\0', + '\0', + '\0', + '\0', + }; + + scan_rsp_data[2] = OTP->ota_rst_tgt_name[0]; + scan_rsp_data[3] = OTP->ota_rst_tgt_name[1]; + scan_rsp_data[4] = OTP->ota_rst_tgt_name[2]; + scan_rsp_data[5] = OTP->ota_rst_tgt_name[3]; + scan_rsp_data[6] = OTP->ota_rst_tgt_name[4]; + scan_rsp_data[7] = OTP->ota_rst_tgt_name[5]; + scan_rsp_data[8] = OTP->ota_rst_tgt_name[6]; + scan_rsp_data[9] = OTP->ota_rst_tgt_name[7]; + if (scan_rsp_data[9] != '\0') + { + scan_rsp_data[0] = 0x09; /* target name length */ + } + else + { + scan_rsp_data[0] = strlen((char *)(scan_rsp_data + 2)) + 1; + } + + //GAP Bond Manager parameters + uint8_t gap_param_cccd_storage = false; + uint8_t auth_pair_mode = GAP_PAIRING_MODE_NO_PAIRING; + uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG | GAP_AUTHEN_BIT_MITM_FLAG; + uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT; + uint8_t auth_use_fix_passkey = false; + uint32_t auth_fix_passkey = 0; + uint8_t auth_sec_req_enalbe = false; + uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_NONE; + + //Register gap callback + le_register_app_cb(dfu_gap_callback); + + //Set device name and device appearance + le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name); + le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance); + le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req), + &slave_init_mtu_req); + + //Set advertising parameters + le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type); + le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr); + le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map); + le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min); + le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max); + le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type); + le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(adv_data_uuid128), adv_data_uuid128); + le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, scan_rsp_data[0] + 1, scan_rsp_data); + + // Setup the GAP Bond Manager + le_bond_set_param(GAP_PARAM_BOND_CCCD_STORAGE, sizeof(gap_param_cccd_storage), + &gap_param_cccd_storage); + gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode); + gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags); + gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey), + &auth_use_fix_passkey); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enalbe), &auth_sec_req_enalbe); + le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags), + &auth_sec_req_flags); + +} + +/****************************************************************** + * @fn Initial profile + * @brief Add simple profile service and register callbacks + * + * @return void + */ +void dfu_le_profile_init(void) +{ + server_init(1); + rtk_dfu_service_id = dfu_add_service(dfu_profile_callback); + server_register_app_cb(dfu_profile_callback); +} + +void dfu_monitor_timeout_handler(void *p_xtimer) +{ + uint32_t timer_id = 0; + + os_timer_id_get(&p_xtimer, &timer_id); + + APP_PRINT_ERROR1("dfu_monitor_timeout_handler, TimerID(%u)", timer_id); + + switch (timer_id) + { + case TIMER_ID_DFU_TOTAL: + case TIMER_ID_DFU_WAIT4_CONN: + case TIMER_ID_DFU_IMAGE_TRANSFER: + case TIMER_ID_DFU_CTITTV: + case TIMER_ID_DFU_WAIT_PACKET: + dfu_fw_reboot(false); + break; + } +} + +void dfu_timer_init(void) +{ + timeout_value_total = OTP->ota_timeout_total * 1000; + timeout_value_wait4_conn = OTP->ota_timeout_wait4_conn * 1000; + timeout_value_image_transfer = OTP->ota_timeout_wait4_image_transfer * 1000; + timeout_value_ctittv = OTP->ota_timeout_ctittv * 1000; +#if OTA_TIMEOUT_WAIT_PACKET + timeout_value_wait_packet = OTP->ota_timeout_wait_packet * 1000; +#endif + + os_timer_create(&total_timer_handle, "dfuTotalTimer", TIMER_ID_DFU_TOTAL, + timeout_value_total, false, dfu_monitor_timeout_handler); + + os_timer_create(&wait4_conn_timer_handle, "dfuWait4ConTimer", TIMER_ID_DFU_WAIT4_CONN, + timeout_value_wait4_conn, false, dfu_monitor_timeout_handler); + + os_timer_create(&image_transfer_timer_handle, "dfuImageTransferTimer", + TIMER_ID_DFU_IMAGE_TRANSFER, timeout_value_image_transfer, + false, dfu_monitor_timeout_handler); + + os_timer_create(&ctittv_timer_handle, "dfuCtittvTimer", TIMER_ID_DFU_CTITTV, + timeout_value_ctittv, false, dfu_monitor_timeout_handler); + +#if OTA_TIMEOUT_WAIT_PACKET + if (timeout_value_wait_packet) + { + os_timer_create(&wait_packet_timer_handle, "dfuWaitPacketTimer", TIMER_ID_DFU_WAIT_PACKET, + timeout_value_wait_packet, false, dfu_monitor_timeout_handler); + } +#endif + + os_timer_start(&total_timer_handle); + + os_timer_start(&wait4_conn_timer_handle); +} + +void dfu_init(void) +{ + WDG_Disable(); + +#if (AON_WDG_ENABLE == 1) + aon_wdg_disable(); +#endif + + if (unlock_flash_bp_all()) + { + DFU_PRINT_INFO0("[==>dfu_init: Flash unlock BP all success!"); + } + else + { + DBG_DIRECT("dfu init unlock BP fail!"); + } +} +/*============================================================================* + * Local Functions + *============================================================================*/ +void dfu_set_rand_addr(void) +{ + T_GAP_RAND_ADDR_TYPE rand_addr_type = GAP_RAND_ADDR_NON_RESOLVABLE; + uint8_t random_bd[BD_ADDR_SIZE] = {0}; + le_gen_rand_addr(rand_addr_type, random_bd); + DFU_PRINT_INFO1("dfu_set_rand_addr: rand_addr %b", TRACE_BDADDR(random_bd)); + le_set_rand_addr(random_bd); +} + +void dfu_main(void) +{ + DBG_DIRECT("Enter DFU mode"); + le_gap_init(1); + gap_lib_init(); + dfu_le_gap_init(); + dfu_le_profile_init(); + dfu_init(); + dfu_task_init(); +} + +#endif //end SUPPORT_NORMAL_OTA + + + diff --git a/src/dfu/dfu_main.h b/src/dfu/dfu_main.h new file mode 100644 index 0000000..b947cf9 --- /dev/null +++ b/src/dfu/dfu_main.h @@ -0,0 +1,39 @@ +/** +************************************************************************************************************ +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +************************************************************************************************************ +* @file dfu_main.h +* @brief Normal ota APIs +* @details +* @author +* @date +* @version +************************************************************************************************************* +*/ + +#ifndef _DFU_MAIN_H_ +#define _DFU_MAIN_H_ + +#include +#include +#include "profile_server.h" + +extern void *total_timer_handle; +extern void *wait4_conn_timer_handle; +extern void *image_transfer_timer_handle; +extern void *ctittv_timer_handle; +extern void *wait_packet_timer_handle; +extern uint32_t timeout_value_total; +extern uint32_t timeout_value_wait4_conn; +extern uint32_t timeout_value_image_transfer; +extern uint32_t timeout_value_ctittv; +extern uint32_t timeout_value_wait_packet; +extern T_SERVER_ID rtk_dfu_service_id; + +void dfu_timer_init(void); + +void dfu_set_rand_addr(void); + +void dfu_main(void); + +#endif diff --git a/src/dfu/dfu_task.c b/src/dfu/dfu_task.c new file mode 100644 index 0000000..d98b15b --- /dev/null +++ b/src/dfu/dfu_task.c @@ -0,0 +1,104 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file dfu_task.c + * @brief dfu task for normal ota. + * @details + * @author + * @date + * @version + ****************************************************************************** + * @attention + *

    © COPYRIGHT 2016 Realtek Semiconductor Corporation

    + ****************************************************************************** + */ +#include "os_msg.h" +#include "os_task.h" +#include "gap_msg.h" +#include "app_msg.h" +#include "trace.h" +#include "dfu_application.h" +#include "dfu_main.h" +#include "dfu_task.h" +#include "board.h" + +#if (SUPPORT_NORMAL_OTA == 1) +/*============================================================================* + * Macros + *============================================================================*/ +#define DFU_TASK_PRIORITY 1 +#define DFU_TASK_STACK_SIZE 512 * 8 //todo: sync with bee2, may modify + +#define MAX_NUMBER_OF_GAP_MESSAGE 0x20 +#define MAX_NUMBER_OF_IO_MESSAGE 0x20 +#define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) + +void *dfu_task_handle; +void *dfu_evt_queue_handle; +void *dfu_io_queue_handle; + +void dfu_main_task(void *p_param); + +bool app_send_msg_to_dfutask(T_IO_MSG *p_msg) +{ + uint8_t event = EVENT_IO_TO_APP; + + if (os_msg_send(dfu_io_queue_handle, p_msg, 0) == false) + { + APP_PRINT_ERROR0("send_io_msg_to_app fail"); + return false; + } + if (os_msg_send(dfu_evt_queue_handle, &event, 0) == false) + { + APP_PRINT_ERROR0("send_evt_msg_to_app fail"); + return false; + } + return true; +} + +void dfu_task_init() +{ + os_task_create(&dfu_task_handle, "dfu", dfu_main_task, 0, DFU_TASK_STACK_SIZE, + DFU_TASK_PRIORITY); +} + +/** +* @brief +* +* +* @param pvParameters +* @return void +*/ +void dfu_main_task(void *p_param) +{ + uint8_t event; + + os_msg_queue_create(&dfu_io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&dfu_evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t)); + + gap_start_bt_stack(dfu_evt_queue_handle, dfu_io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + dfu_timer_init(); + + while (true) + { + if (os_msg_recv(dfu_evt_queue_handle, &event, 0xFFFFFFFF) == true) + { + //DBG_DIRECT("***os_msg_recv***"); + if (event == EVENT_IO_TO_APP) + { + T_IO_MSG io_msg; + if (os_msg_recv(dfu_io_queue_handle, &io_msg, 0) == true) + { + dfu_handle_io_msg(io_msg); + } + } + else + { + gap_handle_msg(event); + } + } + } +} +#endif //end SUPPORT_NORMAL_OTA diff --git a/src/dfu/dfu_task.h b/src/dfu/dfu_task.h new file mode 100644 index 0000000..0d65697 --- /dev/null +++ b/src/dfu/dfu_task.h @@ -0,0 +1,21 @@ + +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#ifndef _DFU_TASK_H_ +#define _DFU_TASK_H_ +#include +#include +#include "app_msg.h" + + +void dfu_task_init(void); +bool app_send_msg_to_dfutask(T_IO_MSG *p_msg); + +#endif + diff --git a/src/mcu/module/data_uart_cmd/data_uart.c b/src/mcu/module/data_uart_cmd/data_uart.c new file mode 100644 index 0000000..f71a1ff --- /dev/null +++ b/src/mcu/module/data_uart_cmd/data_uart.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *h_event_q; +static void *h_io_q; + +int data_uart_send_char(int ch) +{ + UART_SendData(UART0, (uint8_t *)&ch, 1); + /* wait tx fifo empty */ + while (UART_GetFlagState(UART0, UART_FLAG_THR_TSR_EMPTY) != SET); + + return ch; +} + +int data_uart_vsprintf(char *buf, const char *fmt, const int *dp) +{ + char *p, *s; + + s = buf; + for (; *fmt != '\0'; ++fmt) + { + if (*fmt != '%') + { + buf ? *s++ = *fmt : data_uart_send_char(*fmt); + continue; + } + if (*++fmt == 's') + { + for (p = (char *)*dp++; *p != '\0'; p++) + { + buf ? *s++ = *p : data_uart_send_char(*p); + } + } + else /* Length of item is bounded */ + { + char tmp[20], *q = tmp; + int shift = 28; + + if ((*fmt >= '0') && (*fmt <= '9')) + { + int width; + unsigned char fch = *fmt; + for (width = 0; (fch >= '0') && (fch <= '9'); fch = *++fmt) + { + width = width * 10 + fch - '0'; + } + shift = (width - 1) * 4; + } + /* + * Before each format q points to tmp buffer + * After each format q points past end of item + */ + + if ((*fmt == 'x') || (*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) + { + /* With x86 gcc, sizeof(long) == sizeof(int) */ + const long *lp = (const long *)dp; + long h = *lp++; + int ncase = (*fmt & 0x20); + int alt = 0; + + dp = (const int *)lp; + if ((*fmt == 'p') || (*fmt == 'P')) + { + alt = 1; + } + if (alt) + { + *q++ = '0'; + *q++ = 'X' | ncase; + } + for (; shift >= 0 && shift < 32; shift -= 4) + { + * q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase; + } + } + else if (*fmt == 'd') + { + int i = *dp++; + char *r; + if (i < 0) + { + *q++ = '-'; + i = -i; + } + p = q; /* save beginning of digits */ + do + { + *q++ = '0' + (i % 10); + i /= 10; + } + while (i); + /* reverse digits, stop in middle */ + r = q; /* don't alter q */ + while (--r > p) + { + i = *r; + *r = *p; + *p++ = i; + } + } + else if (*fmt == 'c') + { + *q++ = *dp++; + } + else + { + *q++ = *fmt; + } + /* now output the saved string */ + for (p = tmp; p < q; ++p) + { + buf ? *s++ = *p : data_uart_send_char(*p); + } + } + } + if (buf) + { + *s = '\0'; + } + return (s - buf); +} + +/** + * @brief Print the trace information through data uart. + * @param[in] fmt Print parameters. + * @return void + * + * Example usage + * \code{.c} + void test(void) + { + data_uart_print("GAP scan stop\r\n"); + } + * \endcode + */ +void data_uart_print(char *fmt, ...) +{ + (void)data_uart_vsprintf(0, fmt, ((const int *)&fmt) + 1); +} + +/****************************************************************************/ +/* UART interrupt */ +/****************************************************************************/ +void UART0_Handler(void) +{ + uint8_t rx_char; + T_IO_MSG io_driver_msg_send; + uint8_t event = EVENT_IO_TO_APP; + io_driver_msg_send.type = IO_MSG_TYPE_UART; + + uint32_t interrupt_id = 0; + /* read interrupt id */ + interrupt_id = UART_GetIID(UART0); + + /* disable interrupt */ + UART_INTConfig(UART0, UART_INT_RD_AVA | UART_INT_LINE_STS, DISABLE); + + switch (interrupt_id) + { + /* tx fifo empty, not enable */ + case UART_INT_ID_TX_EMPTY: + break; + + /* rx data valiable */ + case UART_INT_ID_RX_LEVEL_REACH: + UART_ReceiveData(UART0, &rx_char, 1); + io_driver_msg_send.subtype = rx_char; + + if (os_msg_send(h_io_q, &io_driver_msg_send, 0) == false) + { + } + else if (os_msg_send(h_event_q, &event, 0) == false) + { + } + break; + + case UART_INT_ID_RX_TMEOUT: + break; + + /* receive line status interrupt */ + case UART_INT_ID_LINE_STATUS: + { + DBG_DIRECT("Line status error!!!!\n"); + } + break; + + default: + break; + } + + /* enable interrupt again */ + UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + + return; +} + +/** + * @brief Initializes the Data UART. + * + * When data uart receives data, data uart will send an event IO_MSG_TYPE_UART to evt_queue_handle and send the data to io_queue_handle. + * @param[in] event_queue_handle Event queue handle which is created by APP. + * @param[in] io_queue_handle IO message queue handle which is created by APP. + * @return void + * + * Example usage + * \code{.c} + void app_main_task(void *p_param) + { + char event; + + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + data_uart_init(evt_queue_handle, io_queue_handle); + ...... + } + void app_handle_io_msg(T_IO_MSG io_msg) + { + uint16_t msg_type = io_msg.type; + uint8_t rx_char; + + switch (msg_type) + { + case IO_MSG_TYPE_UART: + // We handle user command informations from Data UART in this branch. + rx_char = (uint8_t)io_msg.subtype; + user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table); + break; + default: + break; + } + } + * \endcode + */ +void data_uart_init(void *event_queue_handle, void *io_queue_handle) +{ + + h_event_q = event_queue_handle; + h_io_q = io_queue_handle; + + RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + Pinmux_Config(DATA_UART_TX_PIN, UART0_TX); + Pinmux_Config(DATA_UART_RX_PIN, UART0_RX); + Pad_Config(DATA_UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, + PAD_OUT_HIGH); + Pad_Config(DATA_UART_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, + PAD_OUT_LOW); + + /* uart init */ + UART_InitTypeDef uartInitStruct; + UART_StructInit(&uartInitStruct); + uartInitStruct.rxTriggerLevel = 1; + UART_Init(UART0, &uartInitStruct); + UART_INTConfig(UART0, UART_INT_RD_AVA, ENABLE); + + /* Enable UART IRQ */ + NVIC_InitTypeDef nvic_init_struct; + nvic_init_struct.NVIC_IRQChannel = UART0_IRQn; + nvic_init_struct.NVIC_IRQChannelCmd = ENABLE; + nvic_init_struct.NVIC_IRQChannelPriority = 5; + NVIC_Init(&nvic_init_struct); +} + diff --git a/src/mcu/module/data_uart_cmd/data_uart.h b/src/mcu/module/data_uart_cmd/data_uart.h new file mode 100644 index 0000000..a3a7666 --- /dev/null +++ b/src/mcu/module/data_uart_cmd/data_uart.h @@ -0,0 +1,115 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file data_uart.h +* @brief Data uart operations for testing multilink. +* @details Data uart init and print data through data uart. +* @author jane +* @date 2016-02-18 +* @version v0.1 +********************************************************************************************************* +*/ +#ifndef _DATA_UART_H_ +#define _DATA_UART_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @defgroup DATA_UART_CMD Data Uart Command Module + * @brief Application uses this module to receive user command and send infomation through data uart. + * @{ + */ +/** @defgroup DATA_UART_APIs Data Uart Interface + * @{ + */ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DATA_UART_APIs_Exported_Functions Data Uart Interface Exported Functions + * @{ + */ +/** + * @brief Initializes the Data UART. + * + * When data uart receives data, data uart will send an event IO_MSG_TYPE_UART to evt_queue_handle and send the data to io_queue_handle. + * @param[in] event_queue_handle Event queue handle which is created by APP. + * @param[in] io_queue_handle IO message queue handle which is created by APP. + * @return void + * + * Example usage + * \code{.c} + void app_main_task(void *p_param) + { + char event; + + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + data_uart_init(evt_queue_handle, io_queue_handle); + ...... + } + void app_handle_io_msg(T_IO_MSG io_msg) + { + uint16_t msg_type = io_msg.type; + uint8_t rx_char; + + switch (msg_type) + { + case IO_MSG_TYPE_UART: + // We handle user command informations from Data UART in this branch. + rx_char = (uint8_t)io_msg.subtype; + user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table); + break; + default: + break; + } + } + * \endcode + */ +void data_uart_init(void *event_queue_handle, void *io_queue_handle); + +/** + * @brief send one char through data uart. + * @param[in] ch the char + * @return the char + * + * Example usage + * \code{.c} + void test(void) + { + data_uart_send_char('y'); + } + * \endcode + */ +int data_uart_send_char(int ch); + +/** + * @brief Print the trace information through data uart. + * @param[in] fmt Print parameters. + * @return void + * + * Example usage + * \code{.c} + void test(void) + { + data_uart_print("GAP scan stop\r\n"); + } + * \endcode + */ +void data_uart_print(char *fmt, ...); +/** End of DATA_UART_APIs_Exported_Functions + * @} + */ + +/** @} */ /* End of group DATA_UART_APIs */ +/** @} */ /* End of group DATA_UART_CMD */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/src/mcu/module/data_uart_cmd/data_uart_dlps.c b/src/mcu/module/data_uart_cmd/data_uart_dlps.c new file mode 100644 index 0000000..ac3d1a3 --- /dev/null +++ b/src/mcu/module/data_uart_cmd/data_uart_dlps.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include "rtl876x_io_dlps.h" +#include + +#if F_BT_DLPS_EN +bool can_enter_dlps = true; + +void data_uart_dlps_exit_cb(void) +{ + Pad_ControlSelectValue(DATA_UART_TX_PIN, PAD_PINMUX_MODE); + Pad_ControlSelectValue(DATA_UART_RX_PIN, PAD_PINMUX_MODE); + +} + +void data_uart_dlps_enter_cb(void) +{ + Pad_ControlSelectValue(DATA_UART_TX_PIN, PAD_SW_MODE); + Pad_ControlSelectValue(DATA_UART_RX_PIN, PAD_SW_MODE); + System_WakeUpPinEnable(DATA_UART_RX_PIN, PAD_WAKEUP_POL_LOW, 0, 0); +} + +bool data_uart_dlps_check_cb(void) +{ + if (can_enter_dlps) + { + return true; + } + else + { + return false; + } +} + +void System_Handler(void) +{ + if (System_WakeUpInterruptValue(DATA_UART_RX_PIN) == SET) + { + can_enter_dlps = false; + } + Pad_ClearAllWakeupINT(); +} + +void data_uart_can_enter_dlps(bool enter) +{ + can_enter_dlps = enter; +} + +void data_uart_dlps_init(void) +{ + DLPS_IORegister(); + if (dlps_check_cb_reg(data_uart_dlps_check_cb) == false) + { + APP_PRINT_ERROR0("data_uart_dlps_init: dlps_check_cb_reg register failed"); + } + DLPS_IORegUserDlpsEnterCb(data_uart_dlps_enter_cb); + DLPS_IORegUserDlpsExitCb(data_uart_dlps_exit_cb); +} +#endif + diff --git a/src/mcu/module/data_uart_cmd/data_uart_dlps.h b/src/mcu/module/data_uart_cmd/data_uart_dlps.h new file mode 100644 index 0000000..82da32e --- /dev/null +++ b/src/mcu/module/data_uart_cmd/data_uart_dlps.h @@ -0,0 +1,91 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file data_uart_dlps.h +* @brief Data uart dlps reference api. +* @details +* @author jane +* @date 2016-02-18 +* @version v0.1 +********************************************************************************************************* +*/ +#ifndef _DATA_UART_DLPS_H_ +#define _DATA_UART_DLPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/** @defgroup DATA_UART_CMD + * @{ + */ +/** @defgroup DATA_UART_DLPS Data Uart DLPS + * @{ + */ +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup DATA_UART_DLPS_Exported_Functions Data Uart DLPS Exported Functions + * @{ + */ + +/** + * @brief Initializes the Data uart dlps. + * @return void + * + * Example usage + * \code{.c} + void pwr_mgr_init(void) + { +#if F_BT_DLPS_EN + data_uart_dlps_init(); + lps_mode_set(LPM_DLPS_MODE); + lps_mode_pause(); +#endif + } + * \endcode + */ +void data_uart_dlps_init(void); + +/** + * @brief Set data uart dlps + * + * @param[in] enter Whether allow data uart to enter dlps. + * @arg true Allow data uart to enter dlps + * @arg false Not allow data uart to enter dlps + * @return void + * + * Example usage + * \code{.c} + static T_USER_CMD_PARSE_RESULT cmd_dlps(T_USER_CMD_PARSED_VALUE *p_parse_value) + { +#if F_BT_DLPS_EN + if (p_parse_value->dw_param[0] == 0) + { + lps_mode_pause(); + data_uart_print("Active Mode\r\n"); + } + else + { + lps_mode_resume(); + data_uart_can_enter_dlps(true); + data_uart_print("LPS Mode\r\n"); + } +#endif + return (RESULT_SUCESS); + } + * \endcode + */ +void data_uart_can_enter_dlps(bool enter); +/** End of DATA_UART_DLPS_Exported_Functions + * @} + */ + +/** @} */ /* End of group DATA_UART_DLPS */ +/** @} */ /* End of group DATA_UART_CMD */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/src/mcu/module/data_uart_cmd/user_cmd_parse.c b/src/mcu/module/data_uart_cmd/user_cmd_parse.c new file mode 100644 index 0000000..e7b1560 --- /dev/null +++ b/src/mcu/module/data_uart_cmd/user_cmd_parse.c @@ -0,0 +1,642 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file user_cmd_parse.c +* @brief Parse user command from lower Data UART data. +* @details Parse user commands and execute right commands. +* @author +* @date 2016-02-18 +* @version v0.1 +********************************************************************************************************* +*/ +#include +#include +#include +#if F_BT_DLPS_EN +#include +#endif + +/** + * @brief Check if a character is a white space. + * + * @param c Char data to check. + * @return Check result. + * @retval 1 true. + * @retval 0 false. + */ +static bool user_cmd_is_white_space(char c) +{ + return (((c >= 9) && (c <= 13)) || (c == 32)); +} + +/** + * @brief Skip white spaces in buffer. + * + * @param buffer Address of the buffer. + * @return pointer to skipped white spaces' new buffer. + */ +static char *user_cmd_skip_spaces(char *buffer) +{ + char *p = buffer; + + while (user_cmd_is_white_space(*p)) /* white space */ + { + p++; + } + return p; +} + +/** + * @brief Find end of a word. + * + * @param buffer Address of the buffer. + * @return + */ +static char *user_cmd_find_end_of_word(char *buffer) +{ + char *p = buffer; + + while (!user_cmd_is_white_space(*p) && (*p != '\0')) + { + p++; + } + return p; +} + +/** + * @brief Read ASCII string and convert to uint32_t. + * + * @param p String address. + * @return + */ +static uint32_t user_cmd_str_to_uint32(char *p) +{ + uint32_t result = 0; + bool hex = false; + + /* check if value is dec */ + if (p[0] == 'x') + { + hex = true; + p = &p[1]; + } + else if ((p[0] == '0') && (p[1] == 'x')) + { + hex = true; + p = &p[2]; + } + + for (;;) + { + char ch; + ch = *(p++) | 0x20; /* convert to lower case */ + + if (hex) /* dec value */ + { + /* hex value */ + if ((ch >= 'a') && (ch <= 'f')) + { + ch -= ('a' - 10); + } + else if ((ch >= '0') && (ch <= '9')) + { + ch -= '0'; + } + else + { + break; + } + result = (result << 4); + result += (ch & 0x0f); + } + else + { + if (ch < '0' || ch > '9') + { + break; /* end of string reached */ + } + result = 10 * result + ch - '0'; + } + } + return (result); +} + +/** + * @brief Send result, display in UART Assitant. + * + * @param result Command parse result. + * @return none +*/ +static void cmd_send_result(T_USER_CMD_PARSE_RESULT result) +{ + switch (result) + { + case RESULT_ERR: + data_uart_print("%s\r\n", "CMD:Error"); + break; + case RESULT_GAP_CAUSE_ALREADY_IN_REQ: + data_uart_print("%s\r\n", "GAP_CAUSE_ALREADY_IN_REQ"); + break; + case RESULT_GAP_CAUSE_INVALID_STATE: + data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_STATE"); + break; + case RESULT_GAP_CAUSE_INVALID_PARAM: + data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_PARAM"); + break; + case RESULT_GAP_CAUSE_NON_CONN: + data_uart_print("%s\r\n", "GAP_CAUSE_NON_CONN"); + break; + case RESULT_GAP_CAUSE_NOT_FIND_IRK: + data_uart_print("%s\r\n", "GAP_CAUSE_NOT_FIND_IRK"); + break; + case RESULT_GAP_CAUSE_ERROR_CREDITS: + data_uart_print("%s\r\n", "GAP_CAUSE_ERROR_CREDITS"); + break; + case RESULT_GAP_CAUSE_SEND_REQ_FAILED: + data_uart_print("%s\r\n", "GAP_CAUSE_SEND_REQ_FAILED"); + break; + case RESULT_GAP_CAUSE_NO_RESOURCE: + data_uart_print("%s\r\n", "GAP_CAUSE_NO_RESOURCE"); + break; + case RESULT_GAP_CAUSE_INVALID_PDU_SIZE: + data_uart_print("%s\r\n", "GAP_CAUSE_INVALID_PDU_SIZE"); + break; + case RESULT_GAP_CAUSE_NOT_FIND: + data_uart_print("%s\r\n", "GAP_CAUSE_NOT_FIND"); + break; + case RESULT_GAP_CAUSE_CONN_LIMIT: + data_uart_print("%s\r\n", "GAP_CAUSE_CONN_LIMIT"); + break; + case RESULT_CMD_NOT_FOUND: + data_uart_print("%s\r\n", "CMD:Command not found"); + break; + case RESULT_CMD_ERR_PARAM_NUM: + data_uart_print("%s\r\n", "CMD:Wrong number of parameters"); + break; + case RESULT_CMD_ERR_PARAM: + data_uart_print("%s\r\n", "CMD:Wrong parameter"); + break; + case RESULT_CMD_OUT_OF_RANGE: + data_uart_print("%s\r\n", "CMD:Value out of range"); + break; + case RESULT_CMD_NOT_SUPPORT: + data_uart_print("%s\r\n", "CMD:Not support"); + break; + case RESULT_GAP_CAUSE_ERROR_UNKNOWN: + data_uart_print("%s\r\n", "GAP_CAUSE_ERROR_UNKNOWN"); + break; + default: + break; + } +} + +/** + * @brief List cmd. + * + * @param p_cmd_table Command table, include user self-definition command function. + * @return Command execute result. +*/ +static T_USER_CMD_PARSE_RESULT user_cmd_list(const T_USER_CMD_TABLE_ENTRY *p_cmd_table) +{ + int32_t i = 0; + T_USER_CMD_PARSE_RESULT result = RESULT_CMD_NOT_FOUND; + + /* find command in table */ + while ((p_cmd_table + i)->p_cmd != NULL) + { + data_uart_print("%s", (p_cmd_table + i)->p_option); + data_uart_print("%s", " *"); + data_uart_print("%s", (p_cmd_table + i)->p_help); + result = RESULT_SUCESS; + i++; + }; + + data_uart_print(",.\r\n *up down\r\n"); + data_uart_print("[]\r\n *left right\r\n"); + data_uart_print("/\\\r\n *home end\r\n"); + data_uart_print("backspace\r\n *delete\r\n"); + + return result; +} + +/** + * @brief Execute command. + * + * @param p_parse_value Command parse value. + * @param p_cmd_table Command table, include user self-definition command function. + * @return Command execute result. +*/ +static T_USER_CMD_PARSE_RESULT user_cmd_execute(T_USER_CMD_PARSED_VALUE *p_parse_value, + const T_USER_CMD_TABLE_ENTRY *p_cmd_table) +{ + int32_t i = 0; + T_USER_CMD_PARSE_RESULT result = RESULT_CMD_NOT_FOUND; + + if (strcmp((const char *)p_parse_value->p_cmd, (const char *)"?") == 0) + { + user_cmd_list(p_cmd_table); + return RESULT_SUCESS; + } + + /* find command in table */ + while ((p_cmd_table + i)->p_cmd != NULL) + { + if (strcmp((const char *)(p_cmd_table + i)->p_cmd, (const char *)p_parse_value->p_cmd) == 0) + { + /* check if user wants help */ + if (p_parse_value->param_count && *p_parse_value->p_param[0] == '?') + { + data_uart_print("%s", (p_cmd_table + i)->p_option); + data_uart_print("%s", " *"); + data_uart_print("%s", (p_cmd_table + i)->p_help); + result = RESULT_SUCESS; + } + else + { + /* execute command function */ + result = (p_cmd_table + i)->func(p_parse_value); + } + /* exit while */ + break; + } + i++; + }; + + return result; +} + +/** + * @brief Parse a command line and return the found command and parameters in "p_parse_value" + * + * @param p_user_cmd_if Command parsed. + * @param p_parse_value Command parse value. + * @return Command parse result. +*/ +static T_USER_CMD_PARSE_RESULT user_cmd_parse(T_USER_CMD_IF *p_user_cmd_if, + T_USER_CMD_PARSED_VALUE *p_parse_value) +{ + int32_t i; + char *p, *q; + + /* clear all results */ + p_parse_value->p_cmd = NULL; + p_parse_value->param_count = 0; + for (i = 0 ; i < USER_CMD_MAX_PARAMETERS; i++) + { + p_parse_value->p_param[i] = NULL; + p_parse_value->dw_param[i] = 0; + } + + /* Parse line */ + p = p_user_cmd_if->cmdline_buf; + + /*ignore leading spaces */ + p = user_cmd_skip_spaces(p); + if (*p == '\0') /* empty command line ? */ + { + return RESULT_CMD_EMPTY_LINE; + } + + /* find end of word */ + q = user_cmd_find_end_of_word(p); + if (p == q) /* empty command line ? */ + { + return RESULT_CMD_EMPTY_LINE; + } + + p_parse_value->p_cmd = p; + *q = '\0'; /* mark end of command */ + p = q + 1; + + /* parse parameters */ + if (*p != '\0') /* end of line ? */ + { + int32_t j; + + j = 0; + do + { + uint32_t d; + /* ignore leading spaces */ + p = user_cmd_skip_spaces(p); + d = user_cmd_str_to_uint32(p); + + p_parse_value->p_param[j] = p; + p_parse_value->dw_param[j++] = d; + + if (j >= USER_CMD_MAX_PARAMETERS) + { + break; + } + + /* find next parameter */ + p = user_cmd_find_end_of_word(p); + *p++ = '\0'; /* mark end of parameter */ + } + while (*p != '\0'); + + p_parse_value->param_count = j; + } + + return RESULT_SUCESS; +} + +/** + * @brief Clear command line buffer. + * + * @param p_user_cmd_if Command parsed. + * @return none. +*/ +static void cmd_clear(T_USER_CMD_IF *p_user_cmd_if) +{ + p_user_cmd_if->accum_cmd_len = 0; + p_user_cmd_if->cmd_cur = 0; + memset(p_user_cmd_if->cmdline_buf, 0, sizeof(p_user_cmd_if->cmdline_buf)); +} + +static void cmd_move_back(T_USER_CMD_IF *p_user_cmd_if) +{ + for (uint8_t loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop ++) + { + p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len - loop] = + p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len - loop - 1]; + } +} + +static void cmd_move_forward(T_USER_CMD_IF *p_user_cmd_if) +{ + for (uint8_t loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop ++) + { + p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur + loop - 1] = + p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur + loop]; + } +} +static void cmd_clear_screen(T_USER_CMD_IF *p_user_cmd_if) +{ + if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len) + { + data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur); + } + + while (p_user_cmd_if->accum_cmd_len != 0) + { + p_user_cmd_if->accum_cmd_len--; + p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0'; + data_uart_print("\b \b"); + } + p_user_cmd_if->cmd_cur = 0; +} + +/** + * @brief Collect command characters. + * + * @param[in] p_user_cmd_if Store parsed commands. + * @param[in] p_data Data to be parsed. + * @param[in] len Length of data to be command parsed. + * @param[in] p_cmd_table Command table to execute function. + * @return Command collect result. + * @retval 1 true. + * @retval 0 false. + * + * Example usage + * \code{.c} + void app_handle_io_msg(T_IO_MSG io_msg) + { + uint16_t msg_type = io_msg.type; + uint8_t rx_char; + + switch (msg_type) + { + case IO_MSG_TYPE_UART: + // We handle user command informations from Data UART in this branch. + rx_char = (uint8_t)io_msg.subtype; + user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table); + break; + default: + break; + } + } + * \endcode + */ +bool user_cmd_collect(T_USER_CMD_IF *p_user_cmd_if, uint8_t *p_data, int32_t len, + const T_USER_CMD_TABLE_ENTRY *p_cmd_table) +{ + T_USER_CMD_PARSED_VALUE parse_result; + + while (len--) + { + char c = *p_data++; + + if (c != 0x0) /* not ESC character received */ + { + switch (c) /* Normal handling */ + { + case '\n': + case '\r': /* end of line */ + data_uart_print("\r\n"); + p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE; +#if F_BT_DLPS_EN + data_uart_can_enter_dlps(true); +#endif + if (p_user_cmd_if->accum_cmd_len > 0) /* at least one character in command line ? */ + { + T_USER_CMD_PARSE_RESULT result; + + // save cmd first + if (p_user_cmd_if->history_head == USER_CMD_MAX_HISTORY_LINE) + { + p_user_cmd_if->history_head = 0; + p_user_cmd_if->history_tail = 0; + } + else + { + p_user_cmd_if->history_tail = (p_user_cmd_if->history_tail + 1) % USER_CMD_MAX_HISTORY_LINE; + if (p_user_cmd_if->history_tail == p_user_cmd_if->history_head) + { + p_user_cmd_if->history_head = (p_user_cmd_if->history_head + 1) % USER_CMD_MAX_HISTORY_LINE; + } + } + p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_tail] = p_user_cmd_if->accum_cmd_len; + memcpy(p_user_cmd_if->cmd_history[p_user_cmd_if->history_tail], p_user_cmd_if->cmdline_buf, + p_user_cmd_if->accum_cmd_len); + + p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0'; + result = user_cmd_parse(p_user_cmd_if, &parse_result); + if (result == RESULT_SUCESS) + { + result = user_cmd_execute(&parse_result, p_cmd_table); + } + + if (result != RESULT_SUCESS) + { + cmd_send_result(result); + } + } + + cmd_clear(p_user_cmd_if); + break; + + case '\b': /* backspace */ + if (p_user_cmd_if->accum_cmd_len > 0 && p_user_cmd_if->cmd_cur > 0) + { + uint8_t loop; + + cmd_move_forward(p_user_cmd_if); + p_user_cmd_if->accum_cmd_len--; + p_user_cmd_if->cmd_cur--; + p_user_cmd_if->cmdline_buf[p_user_cmd_if->accum_cmd_len] = '\0'; + data_uart_print("\b%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur); + data_uart_print(" \b"); + for (loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop++) + { + data_uart_print("\b"); + } + } + break; + + case 44: /* up: < */ + if (p_user_cmd_if->history_head != USER_CMD_MAX_HISTORY_LINE) + { + cmd_clear_screen(p_user_cmd_if); + if (p_user_cmd_if->history_cur == USER_CMD_MAX_HISTORY_LINE) + { + p_user_cmd_if->history_cur = p_user_cmd_if->history_tail; + } + else + { + if (p_user_cmd_if->history_cur != p_user_cmd_if->history_head) + { + p_user_cmd_if->history_cur = (p_user_cmd_if->history_cur + USER_CMD_MAX_HISTORY_LINE - 1) % + USER_CMD_MAX_HISTORY_LINE; + } + else + { + p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE; + break; + } + } + p_user_cmd_if->accum_cmd_len = p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_cur]; + p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len; + memcpy(p_user_cmd_if->cmdline_buf, p_user_cmd_if->cmd_history[p_user_cmd_if->history_cur], + p_user_cmd_if->accum_cmd_len); + data_uart_print("%s", p_user_cmd_if->cmdline_buf); + } + break; + + case 46: /* down: > */ + if (p_user_cmd_if->history_head != USER_CMD_MAX_HISTORY_LINE) + { + cmd_clear_screen(p_user_cmd_if); + if (p_user_cmd_if->history_cur == USER_CMD_MAX_HISTORY_LINE) + { + p_user_cmd_if->history_cur = p_user_cmd_if->history_head; + } + else + { + if (p_user_cmd_if->history_cur != p_user_cmd_if->history_tail) + { + p_user_cmd_if->history_cur = (p_user_cmd_if->history_cur + 1) % USER_CMD_MAX_HISTORY_LINE; + } + else + { + p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE; + break; + } + } + p_user_cmd_if->accum_cmd_len = p_user_cmd_if->cmd_history_len[p_user_cmd_if->history_cur]; + p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len; + memcpy(p_user_cmd_if->cmdline_buf, p_user_cmd_if->cmd_history[p_user_cmd_if->history_cur], + p_user_cmd_if->accum_cmd_len); + data_uart_print("%s", p_user_cmd_if->cmdline_buf); + } + break; + + case 91: /* left: { */ + if (p_user_cmd_if->cmd_cur > 0) + { + data_uart_print("\b"); + p_user_cmd_if->cmd_cur--; + } + break; + + case 93: /* right: } */ + if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len) + { + data_uart_print("%c", p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur]); + p_user_cmd_if->cmd_cur++; + } + break; + + case 92: /* end: \ */ + if (p_user_cmd_if->cmd_cur < p_user_cmd_if->accum_cmd_len) + { + data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur); + p_user_cmd_if->cmd_cur = p_user_cmd_if->accum_cmd_len; + } + break; + + case 47: /* begin: / */ + while (p_user_cmd_if->cmd_cur > 0) + { + data_uart_print("\b"); + p_user_cmd_if->cmd_cur--; + } + break; + + default: + /* Put character in command buffer */ + if (p_user_cmd_if->accum_cmd_len < USER_CMD_MAX_COMMAND_LINE) + { + uint8_t loop; + + cmd_move_back(p_user_cmd_if); + p_user_cmd_if->cmdline_buf[p_user_cmd_if->cmd_cur] = c; + data_uart_print("%s", p_user_cmd_if->cmdline_buf + p_user_cmd_if->cmd_cur); + p_user_cmd_if->accum_cmd_len++; + p_user_cmd_if->cmd_cur++; + for (loop = 0; loop < p_user_cmd_if->accum_cmd_len - p_user_cmd_if->cmd_cur; loop++) + { + data_uart_print("\b"); + } + } + break; + } + } + } + + return true; +} + +/** + * @brief Initiate command interface structure + * @param[in] p_user_cmd_if Store parsed commands. + * @param[in] project_name Initiate project name. + * @return void + * + * Example usage + * \code{.c} + void app_main_task(void *p_param) + { + char event; + + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + data_uart_init(evt_queue_handle, io_queue_handle); + user_cmd_init(&user_cmd_if, "central"); + ...... + } + * \endcode + */ +void user_cmd_init(T_USER_CMD_IF *p_user_cmd_if, char *project_name) +{ + memset(p_user_cmd_if, 0, sizeof(T_USER_CMD_IF)); + p_user_cmd_if->history_head = USER_CMD_MAX_HISTORY_LINE; + p_user_cmd_if->history_tail = USER_CMD_MAX_HISTORY_LINE; + p_user_cmd_if->history_cur = USER_CMD_MAX_HISTORY_LINE; + data_uart_print(">> Command Parse Init (%s) <<\r\n", project_name); +} + diff --git a/src/mcu/module/data_uart_cmd/user_cmd_parse.h b/src/mcu/module/data_uart_cmd/user_cmd_parse.h new file mode 100644 index 0000000..04aed64 --- /dev/null +++ b/src/mcu/module/data_uart_cmd/user_cmd_parse.h @@ -0,0 +1,202 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file user_cmd_parse.h +* @brief Parse user command from lower Data UART data. +* @details Structure of command parse results. +* @author +* @date 2016-02-18 +* @version v0.1 +********************************************************************************************************* +*/ +#ifndef __USER_CMD_PARSE_CMD_H +#define __USER_CMD_PARSE_CMD_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include + +/** @defgroup DATA_UART_CMD Data Uart Command Module + * @{ + */ +/** @defgroup USER_CMD_PARSE User Command Parse Module + * @{ + */ +/*============================================================================* + * Micros + *============================================================================*/ +/** @defgroup USER_CMD_PARSE_Exported_Micros User Command Parse Module Exported Micros + @brief command parse related macros. + * @{ + */ + +#define USER_CMD_MAX_COMMAND_LINE 80 /**< max. length of command line in bytes */ +#define USER_CMD_MAX_HISTORY_LINE 3 /**< max. num of history command line */ +#define USER_CMD_MAX_PARAMETERS 20 /**< max. number of parameters that the parser will scan */ +/** End of USER_CMD_PARSE_Exported_Micros + * @} + */ + + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup USER_CMD_PARSE_Exported_Types User Command Parse Module Exported Types + * @{ + */ + +/** +* @brief Data UART command parse result. +* +* This is the structure where the command line parser puts its result. +*/ +typedef enum +{ + RESULT_SUCESS, //!< Operation success. + RESULT_GAP_CAUSE_ALREADY_IN_REQ = 0x01,//!< Operation already in progress. + RESULT_GAP_CAUSE_INVALID_STATE = 0x02,//!< Invalid state. + RESULT_GAP_CAUSE_INVALID_PARAM = 0x03,//!< Invalid parameter. + RESULT_GAP_CAUSE_NON_CONN = 0x04,//!< No connection establishment. + RESULT_GAP_CAUSE_NOT_FIND_IRK = 0x05,//!< IRK not found. + RESULT_GAP_CAUSE_ERROR_CREDITS = 0x06,//!< Credits error. + RESULT_GAP_CAUSE_SEND_REQ_FAILED = 0x07,//!< Send Request failed. + RESULT_GAP_CAUSE_NO_RESOURCE = 0x08,//!< No resource. + RESULT_GAP_CAUSE_INVALID_PDU_SIZE = 0x09,//!< Invalid PDU size. + RESULT_GAP_CAUSE_NOT_FIND = 0x0a,//!< Not Found. + RESULT_GAP_CAUSE_CONN_LIMIT = 0x0b,//!< Connection reachs limited count. + + RESULT_ERR = 0x20, + RESULT_CMD_EMPTY_LINE = 0x21, + RESULT_CMD_NOT_FOUND = 0x22, + RESULT_CMD_ERR_PARAM = 0x23, + RESULT_CMD_ERR_PARAM_NUM = 0x24, + RESULT_CMD_OUT_OF_RANGE = 0x25, + RESULT_CMD_NOT_SUPPORT = 0x26, + RESULT_GAP_CAUSE_ERROR_UNKNOWN = 0xFF,//!< Unknown error. +} T_USER_CMD_PARSE_RESULT; + +/** + * @brief Data UART command parse value. + * + * This is the structure where the command line parser puts its values. + */ +typedef struct +{ + char *p_cmd; /**< pointer to command */ + int32_t param_count; /**< number of found parameters */ + uint32_t dw_param[USER_CMD_MAX_PARAMETERS]; /**< automatically parsed parameters */ + char *p_param[USER_CMD_MAX_PARAMETERS]; /**< automatically parsed parameters */ +} T_USER_CMD_PARSED_VALUE; + +/** @brief Command interface. */ +typedef struct +{ + char cmdline_buf[USER_CMD_MAX_COMMAND_LINE + 2]; + uint8_t cmd_cur; + uint8_t cmd_history[USER_CMD_MAX_HISTORY_LINE][USER_CMD_MAX_COMMAND_LINE + 2]; + uint8_t cmd_history_len[USER_CMD_MAX_HISTORY_LINE]; + uint8_t history_head; + uint8_t history_tail; + uint8_t history_cur; + int32_t accum_cmd_len; /**< accumulated length of command */ +} T_USER_CMD_IF; + +/** @brief Prototype of functions that can be called from command table. */ +typedef T_USER_CMD_PARSE_RESULT(*T_USER_CMD_FUNC)(T_USER_CMD_PARSED_VALUE *p_parse_value); + +/** + * @brief Command table entry. + * + */ +typedef struct +{ + char *p_cmd; + char *p_option; + char *p_help; + T_USER_CMD_FUNC func; +} T_USER_CMD_TABLE_ENTRY; +/** End of USER_CMD_PARSE_Exported_Types + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup USER_CMD_PARSE_Exported_Functions User Command Parse Module Exported Functions + * @{ + */ + +/** + * @brief Initiate command interface structure + * @param[in] p_user_cmd_if Store parsed commands. + * @param[in] project_name Initiate project name. + * @return void + * + * Example usage + * \code{.c} + void app_main_task(void *p_param) + { + char event; + + os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG)); + os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(unsigned char)); + + gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE); + + data_uart_init(evt_queue_handle, io_queue_handle); + user_cmd_init(&user_cmd_if, "central"); + ...... + } + * \endcode + */ +void user_cmd_init(T_USER_CMD_IF *p_user_cmd_if, char *project_name); + +/** + * @brief Collect command characters. + * + * @param[in] p_user_cmd_if Store parsed commands. + * @param[in] p_data Data to be parsed. + * @param[in] len Length of data to be command parsed. + * @param[in] p_cmd_table Command table to execute function. + * @return Command collect result. + * @retval 1 true. + * @retval 0 false. + * + * Example usage + * \code{.c} + void app_handle_io_msg(T_IO_MSG io_msg) + { + uint16_t msg_type = io_msg.type; + uint8_t rx_char; + + switch (msg_type) + { + case IO_MSG_TYPE_UART: + // We handle user command informations from Data UART in this branch. + rx_char = (uint8_t)io_msg.subtype; + user_cmd_collect(&user_cmd_if, &rx_char, sizeof(rx_char), user_cmd_table); + break; + default: + break; + } + } + * \endcode + */ +bool user_cmd_collect(T_USER_CMD_IF *p_user_cmd_if, uint8_t *p_data, int32_t len, + const T_USER_CMD_TABLE_ENTRY *p_cmd_table); +/** End of USER_CMD_PARSE_Exported_Functions + * @} + */ + +/** @} */ /* End of group USER_CMD_PARSE */ +/** @} */ /* End of group DATA_UART_CMD */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __USER_CMD_PARSE_CMD_H */ + diff --git a/src/mcu/peripheral/readme b/src/mcu/peripheral/readme new file mode 100644 index 0000000..e69de29 diff --git a/src/mcu/peripheral/rtl876x_3wire_spi.c b/src/mcu/peripheral/rtl876x_3wire_spi.c new file mode 100644 index 0000000..664adf1 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_3wire_spi.c @@ -0,0 +1,301 @@ +/** +********************************************************************************************************* +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_3wire_spi.c +* @brief This file provides all the 3 wire SPI firmware functions. +* @details +* @author elliot chen +* @date 2016-12-13 +* @version v1.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_3wire_spi.h" + +/** + * @brief Deinitializes the 3WIRE SPI peripheral registers to their default reset values. + * @retval None + */ +void SPI3WIRE_DeInit(void) +{ + RCC_PeriphClockCmd(APBPeriph_SPI2W, APBPeriph_SPI2W_CLOCK, DISABLE); +} + +/** + * @brief Initializes the SPI_3WIRE peripheral according to the specified + * parameters in the SPI_3WIRE_InitStruct + * @param SPI3WIRE_InitStruct: pointer to a SPI3WIRE_InitTypeDef structure that + * contains the configuration information for the specified SPI_3WIRE peripheral + * @retval None + */ +void SPI3WIRE_Init(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_SPI3WIRE_MODE(SPI3WIRE_InitStruct->SPI3WIRE_Mode)); + assert_param(IS_SPI3WIRE_OE_DELAY_CFG(SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay)); + assert_param(IS_SPI3WIRE_END_EXTEND_MODE(SPI3WIRE_InitStruct->SPI3WIRE_ExtMode)); + assert_param(IS_SPI3WIRE_READ_CYCLE_DELAY(SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay)); + + uint32_t divValue = 0; + + divValue = (((SPI3WIRE_InitStruct->SPI3WIRE_SysClock) / (SPI3WIRE_InitStruct->SPI3WIRE_Speed * 2) - + 1)) & 0xFF; + + /* Initialize the parameters */ + SPI3WIRE->CFGR = (SPI3WIRE_InitStruct->SPI3WIRE_Mode) | \ + (SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay) | \ + (SPI3WIRE_InitStruct->SPI3WIRE_ExtMode) | \ + (divValue << SPI3WIRE_SSI_DIV_NUM_Pos) | \ + (SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay << SPI3WIRE_SSI_DLY_CYCLE_Pos); + + /* Clear all read data registers, read number and interrupt */ + SPI3WIRE->INTCR = SPI3WIRE_FIFO_INT_ALL_CLR; +} + +/** + * @brief Fills each SPI3WIRE_InitStruct member with its default value. + * @param SPI3WIRE_InitStruct: pointer to an SPI3WIRE_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI3WIRE_StructInit(SPI3WIRE_InitTypeDef *SPI3WIRE_InitStruct) +{ + SPI3WIRE_InitStruct->SPI3WIRE_SysClock = 20000000; + SPI3WIRE_InitStruct->SPI3WIRE_Speed = 1000000; + SPI3WIRE_InitStruct->SPI3WIRE_Mode = SPI3WIRE_2WIRE_MODE; + SPI3WIRE_InitStruct->SPI3WIRE_ReadDelay = + 0;/* Delay time = (SPI3WIRE_ReadDelay+1)/(2*SPI3WIRE_Speed) */ + SPI3WIRE_InitStruct->SPI3WIRE_OutputDelay = SPI3WIRE_OE_DELAY_1T; + SPI3WIRE_InitStruct->SPI3WIRE_ExtMode = SPI3WIRE_NORMAL_MODE; +} + +/** + * @brief Enables or disables the specified SPI3WIRE peripheral. + * @param NewState: new state of the SPI3WIRE peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI3WIRE_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI3WIRE peripheral */ + SPI3WIRE->CFGR |= SPI3WIRE_SSI_EN_Msk; + } + else + { + /* Disable the selected SPI3WIRE peripheral */ + SPI3WIRE->CFGR &= SPI3WIRE_SSI_EN_CLR; + } +} + +/** + * @brief Enables or disables the specified SPI3WIRE interrupts. + * @param SPI3WIRE_INT: specifies the SPI3WIRE interrupts sources to be enabled or disabled. + * This parameter can be only be the following value: + * @arg SPI3WIRE_INT_BIT: enable SPI3WIRE interrupt. + * @param NewState: new state of the specified SPI3WIRE interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI3WIRE_INTConfig(uint32_t SPI3WIRE_INT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(newState)); + assert_param(IS_SPI3WIRE_INT(SPI3WIRE_INT)); + + if (newState == ENABLE) + { + /* Enable the selected 3WIRE_SPI interrupts */ + SPI3WIRE->CFGR |= SPI3WIRE_INT; + } + else + { + /* Disable the selected 3WIRE_SPI interrupts */ + SPI3WIRE->CFGR &= (uint32_t)(~SPI3WIRE_INT); + } +} + +/** + * @brief Configure resync signal time value. + * @param value: Resync signal time value whose uint is 1/(2*SPI3WIRE_Speed). + * This parameter can be only be the following value: 0x0 to 0xf. + * @retval None + */ +void SPI3WIRE_SetResyncTime(uint32_t value) +{ + SPI3WIRE->CFGR &= SPI3WIRE_SSI_RESYNC_TIME_CLR; + SPI3WIRE->CFGR |= value << SPI3WIRE_SSI_RESYNC_TIME_Pos; +} + +/** + * @brief Send resync signal or not .Must send when SPI3WIRE is disable. + * @param NewState: new state of the SPI3WIRE peripheral. + * This parameter can be only be the following value: + * @param ENABLE: trigger resync signal. + * @param ENABLE: disable resync signal. + * @retval None + */ +void SPI3WIRE_ResyncSignalCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + SPI3WIRE->INTCR |= SPI3WIRE_RESYNV_EN_Msk; + } + else + { + SPI3WIRE->INTCR &= SPI3WIRE_RESYNV_EN_CLR; + } +} + +/** + * @brief Get total number of data byte in each SPI reading. + * @param None. + * @retval The total number of data byte in each SPI reading. + */ +uint8_t SPI3WIRE_GetRxDataLen(void) +{ + return (uint8_t)(SPI3WIRE->SR & SPI3WIRE_RDATA_NUM_Msk); +} + +/** + * @brief Clear read data number status. + * @param None. + * @retval None + */ +void SPI3WIRE_ClearRxDataLen(void) +{ + SPI3WIRE->INTCR |= SPI3WIRE_RD_NUM_CLEAR_Msk; +} + +/** + * @brief Clear all read data registers. + * @param None. + * @retval None. + */ +void SPI3WIRE_ClearRxFIFO(void) +{ + SPI3WIRE->INTCR |= SPI3WIRE_RD_DATA_CLEAR_Msk; +} + +/** + * @brief start to write data. + * @param address: write address. + * @param data: write data. + * @retval None + */ +void SPI3WIRE_StartWrite(uint8_t address, uint8_t data) +{ + SPI3WIRE->CR = (uint32_t)(SPI3WIRE_RW_MODE_Msk) | ((uint32_t)address << SPI3WIRE_ADDRESS_Pos) | + (uint32_t)data; +} + +/** + * @brief start read. + * @param address: read address. + * @param readNum: number of data to read.This value can be 0x1 to 0xf. + * @retval None. + */ +void SPI3WIRE_StartRead(uint8_t address, uint32_t len) +{ + if (len == 1) + { + /* Disable burst read */ + SPI3WIRE->CFGR &= SPI3WIRE_SSI_BURST_READ_EN_CLR; + /* Read address */ + SPI3WIRE->CR = ((uint32_t)address << SPI3WIRE_ADDRESS_Pos); + } + else + { + /* Enable burst read */ + SPI3WIRE->CFGR |= SPI3WIRE_SSI_BURST_READ_EN_Msk; + /* Read num */ + SPI3WIRE->CFGR &= SPI3WIRE_SSI_BURST_READ_NUM_CLR; + SPI3WIRE->CFGR |= (len << SPI3WIRE_SSI_BURST_READ_NUM_Pos); + /* Set read command and read address */ + SPI3WIRE->CR = ((uint32_t)address << SPI3WIRE_ADDRESS_Pos); + } +} + +/** + * @brief write data. + * @param outBuf: buffer to store read datas. + * @param readNum: read number. + * @retval None + */ +void SPI3WIRE_ReadBuf(uint8_t *pBuf, uint8_t readNum) +{ + uint8_t i = 0; + uint8_t j = 0; + uint32_t regVal = 0; + uint8_t regIndex = readNum / 4; + + for (i = 0; i < regIndex; i++) + { + regVal = *((volatile uint32_t *)(&(SPI3WIRE->RD0) + i)); + + for (j = 0; j < 4; j++) + { + *pBuf++ = (uint8_t)(regVal >> (8 * j)); + } + } + + if (readNum > regIndex * 4) + { + regVal = *((volatile uint32_t *)(&(SPI3WIRE->RD0) + regIndex)); + + for (j = 0; j < (readNum - regIndex * 4); j++) + { + *pBuf++ = (uint8_t)(regVal >> (8 * j)); + } + } +} + +/** + * @brief Checks whether the specified 3WIRE_SPI flag is set or not. + * @param SPI3WIRE_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPI3WIRE_FLAG_BUSY: 3wire spi is busy. + * @arg SPI3WIRE_FLAG_INT_IND: there is 3wire spi interrupt. + * @arg SPI3WIRE_FLAG_RESYNC_BUSY: resync busy or not. + * @retval The new state of UART_FLAG (SET or RESET). + */ +FlagStatus SPI3WIRE_GetFlagStatus(uint32_t SPI3WIRE_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_SPI3WIRE_FLAG(SPI3WIRE_FLAG)); + + if (SPI3WIRE->SR & SPI3WIRE_FLAG) + { + bitstatus = SET; + } + return bitstatus; +} + +/** + * @brief Clears the 3WIRE_SPI interrupt pending bits. + * @param SPI3WIRE_INT: specifies the SPI3WIRE interrupts sources to be enabled or disabled. + * This parameter can be only be the following value: + * @arg SPI3WIRE_INT_BIT: enable SPI3WIRE interrupt. + * @retval None + */ +void SPI3WIRE_ClearINTPendingBit(uint32_t SPI3WIRE_INT) +{ + /* Check the parameters */ + assert_param(IS_SPI3WIRE_INT(SPI3WIRE_INT)); + + SPI3WIRE->INTCR |= SPI3WIRE_INT; +} + +/******************* (C) COPYRIGHT 2016 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_adc.c b/src/mcu/peripheral/rtl876x_adc.c new file mode 100644 index 0000000..826df7d --- /dev/null +++ b/src/mcu/peripheral/rtl876x_adc.c @@ -0,0 +1,575 @@ +/** +********************************************************************************************************* +* Copyright(c) 2021, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_adc.c +* @brief This file provides all the ADC firmware functions. +* @details +* @author yuan +* @date 2021-05-10 +* @version v1.0.2 +********************************************************************************************************* +*/ +#include "rtl876x_rcc.h" +#include "rtl876x_adc.h" + + +/** + * @brief Deinitializes the ADC peripheral registers to their default reset values(turn off ADC clock). + * + * @param ADCx: selected ADC peripheral. + * @return None. + */ +void ADC_DeInit(ADC_TypeDef *ADCx) +{ + assert_param(IS_ADC_PERIPH(ADCx)); + + RCC_PeriphClockCmd(APBPeriph_ADC, APBPeriph_ADC_CLOCK, DISABLE); + + return; +} + +/** + * @brief Initializes the ADC peripheral according to the specified + * parameters in the ADC_InitStruct + * @param ADCx: selected ADC peripheral. + * @param ADC_InitStruct: pointer to a ADCInitTypeDef structure that + * contains the configuration information for the specified ADC peripheral + * @return None. + */ +void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct) +{ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_DATA_WRITE_TO_FIFO_CMD(ADC_InitStruct->ADC_DataWriteToFifo)); + assert_param(IS_ADC_FIFO_THRESHOLD(ADC_InitStruct->ADC_FifoThdLevel)); + assert_param(IS_ADC_WATER_LEVEL_CONFIG(ADC_InitStruct->ADC_WaterLevel)); + assert_param(IS_ADC_OVERWRITE_MODE(ADC_InitStruct->ADC_FifoOverWriteEn)); + assert_param(IS_ADC_LATCH_DATA_EDGE(ADC_InitStruct->ADC_DataLatchEdge)); + assert_param(IS_ADC_DATA_AVG_NUM(ADC_InitStruct->ADC_DataAvgSel)); + assert_param(IS_ADC_DATA_AVG_EN(ADC_InitStruct->ADC_DataAvgEn)); + assert_param(IS_ADC_POWER_ON_MODE(ADC_InitStruct->ADC_PowerOnMode)); + assert_param(IS_ADC_RG2X_0_DELAY_TIME(ADC_InitStruct->ADC_RG2X0Dly)); + assert_param(IS_ADC_RG0X_1_DELAY_TIME(ADC_InitStruct->ADC_RG0X1Dly)); + assert_param(IS_ADC_RG0X_0_DELAY_TIME(ADC_InitStruct->ADC_RG0X0Dly)); + assert_param(IS_ADC_DATA_MINUS_CMD(ADC_InitStruct->ADC_DataMinusEn)); + assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign)); + assert_param(IS_ADC_TIMER_TRIGGER_CMD(ADC_InitStruct->ADC_TimerTriggerEn)); + assert_param(IS_ADC_POWER_ALWAYS_ON(ADC_InitStruct->ADC_PowerAlwaysOnEn)); + assert_param(IS_ADC_CONVERT_TIME(ADC_InitStruct->ADC_ConvertTime)); + + + /* Added to stabilize the power supply! */ + uint16_t reg_value = 0; + + /* enable cmp low noise for 3 bit */ + reg_value = btaon_fast_read_safe(0x116); + btaon_fast_write_safe(0x116, reg_value | BIT(10)); + + /* vref_sel = 0.85V */ + reg_value = btaon_fast_read_safe(0x116); + btaon_fast_write_safe(0x116, reg_value | BIT(5) | BIT(4)); + + /*Disable all interrupt.*/ + ADCx->INTCR &= (~0x1f); + + /* Set power mode first */ + ADCx->PWRDLY = (((ADC_InitStruct->ADC_DataLatchDly & 0x7) << 6) | + ADC_InitStruct->ADC_PowerAlwaysOnEn | + ADC_InitStruct->ADC_PowerOnMode); + + if (ADC_InitStruct->ADC_PowerOnMode == ADC_POWER_ON_AUTO) + { + ADCx->PWRDLY |= (ADC_InitStruct->ADC_RG2X0Dly \ + | ADC_InitStruct->ADC_RG0X1Dly \ + | ADC_InitStruct->ADC_RG0X0Dly); + } + + if (ADC_InitStruct->ADC_DataAvgEn == ADC_DATA_AVERAGE_ENABLE) + { + ADCx->PWRDLY |= (ADC_InitStruct->ADC_DataAvgEn | ADC_InitStruct->ADC_DataAvgSel); + /* Disable schedule table */ + ADCx->SCHCR &= (~0xffff); + /* Set schedule table */ + ADCx->SCHTAB0 = ADC_InitStruct->ADC_SchIndex[0]; + ADCx->SCHCR |= (uint16_t)0x0001; + } + else + { + /* Disable schedule table */ + ADCx->SCHCR &= (~0xffff); + + /* Set schedule table */ + for (uint8_t index = 0; index < MAX_ADC_SCH_NUM; index++) + { + *(__IO uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + index) = ((ADC_InitStruct->ADC_SchIndex[index * 2] + & 0x1F) + | ((ADC_InitStruct->ADC_SchIndex[index * 2 + 1] & 0x1F) << 16)); + } + ADCx->SCHCR = ADC_InitStruct->ADC_Bitmap; + } + + /* Set ADC mode */ + ADCx->CR = ((ADC_InitStruct->ADC_DataWriteToFifo) + | ((ADC_InitStruct->ADC_FifoThdLevel & 0x3F) << 20) + | ((ADC_InitStruct->ADC_WaterLevel & 0x3F) << 14) + | (ADC_InitStruct->ADC_FifoOverWriteEn) + | (ADC_InitStruct->ADC_DataLatchEdge)); + + ADCx->DATCLK = ((ADC_InitStruct->ADC_DataMinusEn) + | (ADC_InitStruct->ADC_DataAlign) + | ((ADC_InitStruct->ADC_DataMinusOffset & 0xFFF) << 16)); + + ADCx->ANACTL |= (0x03 << 10); + if ((ADC_InitStruct->ADC_SampleTime & 0x3FFF) < 19) + { + /* adc sample period max 400kHz */ + ADC_InitStruct->ADC_SampleTime = 19; + } + ADCx->SAMTIM = ((ADC_InitStruct->ADC_ConvertTime) + | (ADC_InitStruct->ADC_SampleTime & 0x3FFF)); + + /*clear adc fifo*/ + ADCx->CR |= BIT26; + + /*clear all interrupt*/ + ADCx->INTCR |= (0x1f << 8); + + return; +} + +/** + * @brief Fills each ADC_InitStruct member with its default value. + * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will be initialized. + * @retval None + */ +void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct) +{ + ADC_InitStruct->ADC_SampleTime = 255; /* (n + 1) cycle of 10MHz,n = 0 to 16383 */ + ADC_InitStruct->ADC_ConvertTime = ADC_CONVERT_TIME_500NS; + + ADC_InitStruct->ADC_DataWriteToFifo = ADC_DATA_WRITE_TO_FIFO_DISABLE; + ADC_InitStruct->ADC_FifoThdLevel = 0x0A; + ADC_InitStruct->ADC_WaterLevel = 0x1; + ADC_InitStruct->ADC_FifoOverWriteEn = ADC_FIFO_OVER_WRITE_ENABLE; + ADC_InitStruct->ADC_DataLatchEdge = ADC_LATCH_DATA_Positive; + + ADC_InitStruct->ADC_SchIndex[0] = 0; + ADC_InitStruct->ADC_SchIndex[1] = 0; + ADC_InitStruct->ADC_SchIndex[2] = 0; + ADC_InitStruct->ADC_SchIndex[3] = 0; + ADC_InitStruct->ADC_SchIndex[4] = 0; + ADC_InitStruct->ADC_SchIndex[5] = 0; + ADC_InitStruct->ADC_SchIndex[6] = 0; + ADC_InitStruct->ADC_SchIndex[7] = 0; + ADC_InitStruct->ADC_SchIndex[8] = 0; + ADC_InitStruct->ADC_SchIndex[9] = 0; + ADC_InitStruct->ADC_SchIndex[10] = 0; + ADC_InitStruct->ADC_SchIndex[11] = 0; + ADC_InitStruct->ADC_SchIndex[12] = 0; + ADC_InitStruct->ADC_SchIndex[13] = 0; + ADC_InitStruct->ADC_SchIndex[14] = 0; + ADC_InitStruct->ADC_SchIndex[15] = 0; + ADC_InitStruct->ADC_Bitmap = 0x0; + + ADC_InitStruct->ADC_DataAlign = ADC_DATA_ALIGN_LSB; + ADC_InitStruct->ADC_DataMinusEn = ADC_DATA_MINUS_DISABLE; + ADC_InitStruct->ADC_DataMinusOffset = 0; + + ADC_InitStruct->ADC_DataAvgEn = ADC_DATA_AVERAGE_DISABLE; + ADC_InitStruct->ADC_DataAvgSel = ADC_DATA_AVERAGE_OF_2; + /* Reserved parameter, please do not change values*/ + ADC_InitStruct->ADC_PowerOnMode = ADC_POWER_ON_AUTO; + ADC_InitStruct->ADC_PowerAlwaysOnEn = ADC_POWER_ALWAYS_ON_DISABLE; + ADC_InitStruct->ADC_DataLatchDly = 0x1; + ADC_InitStruct->ADC_RG2X0Dly = ADC_RG2X_0_DELAY_10_US; + ADC_InitStruct->ADC_RG0X1Dly = ADC_RG0X_1_DELAY_20_US; + ADC_InitStruct->ADC_RG0X0Dly = ADC_RG0X_0_DELAY_30_US; + + return; +} + +/** + * @brief Enables or disables the ADC peripheral. + * @param ADCx: selected ADC peripheral. + * @param adcMode: adc mode select. + This parameter can be one of the following values: + * @arg ADC_ONE_SHOT_MODE: one shot mode. + * @arg ADC_CONTINUOUS_MODE: continuous mode. + * @param NewState: new state of the ADC peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_Cmd(ADC_TypeDef *ADCx, uint8_t adcMode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_SAMPLE_MODE(adcMode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + uint8_t reg_value = 0; + + if (NewState == ENABLE) + { + reg_value = btaon_fast_read_safe(0x113); + btaon_fast_write_safe(0x113, reg_value & ~BIT2); + /* In case manual mode */ + if (ADCx->PWRDLY & ADC_POWER_ON_MANUAL) + { + ADCx->PWRDLY |= 0x3C00; +// ADC_DelayUs(80); + platform_delay_us(80); + ADCx->PWRDLY |= (BIT14 | BIT15); +// ADC_DelayUs(320); + platform_delay_us(320); + ADCx->PWRDLY |= (BIT16 | BIT17); +// ADC_DelayUs(240); + platform_delay_us(240); + ADCx->PWRDLY |= BIT18; + } + /* Reset ADC mode first */ + ADCx->CR &= ~0x03; + /* Enable ADC */ + ADCx->CR |= adcMode; + } + else + { + ADCx->CR &= ~0x03; + reg_value = btaon_fast_read_safe(0x113); + btaon_fast_write_safe(0x113, reg_value | BIT2); + } + + return; +} + +/** + * @brief Enables or disables the specified ADC interrupts. + * @param ADCx: selected ADC peripheral. + * @param ADC_INT: specifies the ADC interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ADC_INT_FIFO_RD_REQ :FIFO read request + * @arg ADC_INT_FIFO_RD_ERR :FIFO read error + * @arg ADC_INT_FIFO_THD :ADC FIFO size > thd + * @arg ADC_INT_FIFO_FULL :ADC FIFO overflow + * @arg ADC_INT_ONE_SHOT_DONE :ADC one shot mode done + * @param NewState: new state of the specified ADC interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_INTConfig(ADC_TypeDef *ADCx, uint32_t ADC_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_INT(ADC_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected ADC interrupts */ + ADCx->INTCR |= ADC_INT; + } + else + { + /* Disable the selected ADC interrupts */ + ADCx->INTCR &= (uint32_t)~ADC_INT; + } +} + +/** + * @brief Read ADC data according to specific channel. + * @param ADCx: selected ADC peripheral. + * @param index: can be 0 to 15 + * @retval The 10-bit converted ADC data. + */ +uint16_t ADC_ReadRawData(ADC_TypeDef *ADCx, uint8_t index) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(index < 16); + + if (index & BIT(0)) + { + return ((*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1))) >> 16); + } + else + { + return (*(uint32_t *)((uint32_t *)(&ADCx->SCHD0) + (index >> 1))); + } +} + +/** + * @brief Read ADC average data from ADC schedule table0. + * @param ADCx: selected ADC peripheral. + * @param[out] OutBuf: buffer to save data read from ADC FIFO. + * @retval The 10-bit converted ADC data. + */ +uint16_t ADC_ReadAvgRawData(ADC_TypeDef *ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + uint16_t data = 0; + data = (uint16_t)ADCx->SCHD0; + + return data; +} + +/** + * @brief Get one data from ADC FIFO. + * @param ADCx: selected ADC peripheral. + * @retval adc FIFO data. + */ +uint16_t ADC_ReadFIFO(ADC_TypeDef *ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + return (uint16_t)((ADCx->FIFO) & 0xFFF); +} + +/** + * @brief Read data from ADC FIFO. + * @param ADCx: selected ADC peripheral. + * @param[out] outBuf: buffer to save data read from ADC FIFO. + * @param num: number of data to be read. + * @retval None + */ +void ADC_ReadFIFOData(ADC_TypeDef *ADCx, uint16_t *outBuf, uint16_t num) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + while (num--) + { + *outBuf++ = (uint16_t)ADCx->FIFO; + } + + return; +} + +/** + * @brief Get ADC fifo data number. + * @param ADCx: selected ADC peripheral. + * @retval current data number in adc fifo. + */ +uint8_t ADC_GetFIFODataLen(ADC_TypeDef *ADCx) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + + return ((uint8_t)(((ADCx->SCHCR) >> 16) & 0x3F)); +} + +/** + * @brief Config ADC schedule table. + * @param ADCx: selected ADC peripheral. + * @param adcMode: ADC mode. + * This parameter can be one of the following values: + * @arg EXT_SINGLE_ENDED(index) + * @arg EXT_DIFFERENTIAL(index) + * @arg INTERNAL_VBAT_MODE + * @param Index: Schedule table index. + * @return none. + */ +void ADC_SchIndexConfig(ADC_TypeDef *ADCx, uint8_t adcMode, uint16_t index) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_SCHEDULE_INDEX_CONFIG(adcMode)); + + if (index & BIT0) + { + *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (index >> 1)) |= (adcMode << 16); + } + else + { + *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (index >> 1)) |= adcMode; + } + + return; +} + +/** + * @brief Same as function ADC_SchIndexConfig,this function is version bee2. + * @param ADCx: selected ADC peripheral. + * @param adcMode: ADC mode. + * This parameter can be one of the following values: + * @arg EXT_SINGLE_ENDED(index) + * @arg EXT_DIFFERENTIAL(index) + * @arg INTERNAL_VBAT_MODE + * @param Index: Schedule table index. + * @return none. + */ +void ADC_SchTableConfig(ADC_TypeDef *ADCx, uint16_t Index, uint8_t adcMode) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_SCHEDULE_INDEX_CONFIG(adcMode)); + + if (Index & BIT0) + { + *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (Index >> 1)) |= (adcMode << 16); + } + else + { + *(uint32_t *)((uint32_t *)(&ADCx->SCHTAB0) + (Index >> 1)) |= adcMode; + } + + return; +} + +/** + * @brief Set adc schedule table. + * @param ADCx: selected ADC peripheral. + * @param channelMap: ADC channel map. + * @param NewState: new state of the ADC peripheral. + * This parameter can be: ENABLE or DISABLE. + * @return none. + */ +void ADC_BitMapConfig(ADC_TypeDef *ADCx, uint16_t bitMap, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + ADCx->SCHCR |= bitMap; + } + else + { + ADCx->SCHCR &= (~bitMap); + } + + return; +} + +/** + * @brief Power on ADC manually. + * @param ADCx: selected ADC peripheral. + * @param NewState: new state of the ADC power on. + * This parameter can be: ENABLE or DISABLE. + * @note If enable, ADC power will always on. + * @retval None + */ +void ADC_ManualPowerOnCmd(ADC_TypeDef *ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + ADCx->PWRDLY |= BIT19; + } + else + { + ADCx->PWRDLY &= ~(BIT19); + } +} + +/** + * @brief Enbale or disable stop fifo from writing data. + * @param ADCx: selected ADC peripheral. + * @param NewState: new state of the ADC fifo write. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void ADC_WriteFIFOCmd(ADC_TypeDef *ADCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == DISABLE) + { + ADCx->PWRDLY |= BIT21; + } + else + { + ADCx->PWRDLY &= ~(BIT21); + } +} + +/** + * @brief Config ADC bypass resistor.Attention!!!Channels using bypass mode cannot over 0.9V!!!! + * @param channelNum: external channel number, can be 0~3. + * @param NewState: ENABLE or DISABLE. + * @retval None + */ +void ADC_BypassCmd(uint8_t ChannelNum, FunctionalState NewState) +{ + assert_param(ChannelNum <= 3); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (ChannelNum > 3) + { + return; + } + + uint16_t reg_value = 0; + + if (NewState != DISABLE) + { + reg_value = btaon_fast_read_safe(0x118); + reg_value |= BIT(ChannelNum); + btaon_fast_write_safe(0x118, reg_value); + } + else + { + reg_value = btaon_fast_read_safe(0x118); + reg_value &= ~BIT(ChannelNum); + btaon_fast_write_safe(0x118, reg_value); + } +} + +/** + * @brief Checks whether the specified ADC interrupt status flag is set or not. + * @param ADCx: selected ADC peripheral. + * @param ADC_INT_FLAG: specifies the interrupt status flag to check. + * This parameter can be one of the following values: + * @arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt + * @arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt + * @arg ADC_INT_FIFO_THD: fifo larger than threshold + * @arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt + * @arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt + * @retval The new state of ADC_INT (SET or RESET). + */ +ITStatus ADC_GetINTStatus(ADC_TypeDef *ADCx, uint32_t ADC_INT) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_INT(ADC_INT)); + + FlagStatus bitstatus = RESET; + + if ((ADCx->INTCR & (ADC_INT << 16)) != 0) + { + bitstatus = SET; + } + + return bitstatus; +} + +/** + * @brief Clear the ADC interrupt pending bit. + * @param ADCx: selected ADC peripheral. + * @param ADC_INT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg ADC_INT_ONE_SHOT_DONE: ADC once convert end interrupt + * @arg ADC_INT_FIFO_OVERFLOW: ADC FIFO overflow interrupt + * @arg ADC_INT_FIFO_THD: fifo larger than threshold + * @arg ADC_INT_FIFO_RD_ERR: ADC read FIFO error interrupt + * @arg ADC_INT_FIFO_RD_REQ: ADC read FIFO request interrupt + * @retval None + */ +void ADC_ClearINTPendingBit(ADC_TypeDef *ADCx, uint32_t ADC_INT) +{ + /* Check the parameters */ + assert_param(IS_ADC_PERIPH(ADCx)); + assert_param(IS_ADC_INT(ADC_INT)); + + ADCx->INTCR |= (ADC_INT << 8); + + return; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/mcu/peripheral/rtl876x_aon_wdg.c b/src/mcu/peripheral/rtl876x_aon_wdg.c new file mode 100644 index 0000000..ee654f9 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_aon_wdg.c @@ -0,0 +1,157 @@ +/** +*************************************************************************************************** +* Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved. +*************************************************************************************************** +* @file rtl876x_aon_wdg.c +* @brief This file provides all the AON Watch Dog firmware functions. +* @details +* @author Serval Li +* @date 2017-06-27 +* @version v0.1 +*************************************************************************************************** +*/ + +#include "rtl876x.h" +#include "rtl876x_aon_wdg.h" + + +#define REG_RTC_FAST_WRITE_BASE_ADDR (0x40000100UL) +#define REG_RTC_FAST_WDATA (0x400001f0UL) +#define REG_RTC_FAST_ADDR (0x400001f4UL) +#define REG_RTC_WR_STROBE (0x400001f8UL) + +/* Enable Write to CRT register */ +#define AON_WDG_EnableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP | BIT0) + +/* Disable Write to CRT register */ +#define AON_WDG_DisableWriteCRT() AON_WDG_WriteReg((uint32_t)&AON_WDG->WP - SYSTEM_REG_BASE, AON_WDG->WP & ~BIT0); + +/** + * @brief Fast write RTC register. + * @param offset: the offset of RTC register. + * @param data: data which write to register. + * @retval None + */ +static void AON_WDG_WriteReg(uint32_t offset, uint32_t data) +{ + static bool is_called = false; + + if (is_called == false) + { + *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time + is_called = true; + } + + /* Write data */ + *((volatile uint32_t *)REG_RTC_FAST_WDATA) = data; + /* Write RTC register address. Only offset */ + *((volatile uint32_t *)REG_RTC_FAST_ADDR) = offset - REG_RTC_FAST_WRITE_BASE_ADDR; + *((volatile uint32_t *)REG_RTC_WR_STROBE) = 1; +} + +void AON_WDG_Config(T_AON_WDG_MODE reset_level, uint32_t comp, uint8_t cnt_ctl, uint8_t cnt_reload) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + + aon_wdg.u.CRT_BITS.RST_LVL = reset_level; + aon_wdg.u.CRT_BITS.COMP = comp; + aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl; + aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_ConfigResetLevel(uint8_t reset_level) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.RST_LVL = reset_level; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_ConfigComp(uint32_t comp) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.COMP = comp; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_ConfigCntCtl(uint8_t cnt_ctl) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.CNT_CTL = cnt_ctl; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_ConfigCntReload(uint8_t cnt_reload) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.CNT_RELOAD = cnt_reload; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_Enable(void) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.EN = 1; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_Disable(void) +{ + AON_WDG_TypeDef aon_wdg; + + aon_wdg.u.CRT = AON_WDG->u.CRT; + aon_wdg.u.CRT_BITS.EN = 2; + + AON_WDG_EnableWriteCRT(); + AON_WDG_WriteReg((uint32_t)&AON_WDG->u.CRT - SYSTEM_REG_BASE, aon_wdg.u.CRT); + AON_WDG_DisableWriteCRT(); +} + +void AON_WDG_Restart(void) +{ + AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 1); + AON_WDG_WriteReg((uint32_t)&AON_WDG->CNT_CLR, 0); +} + +void AON_WDG_SystemReset(void) +{ + AON_WDG_Config(AON_WDT_RESET_ALL, 1, 1, 0); + AON_WDG_Enable(); + + while (1); /* wait until reset */ +} + +bool AON_WDG_IsEnable(void) +{ + return (AON_WDG->u.CRT_BITS.EN == 1); +} diff --git a/src/mcu/peripheral/rtl876x_captouch.c b/src/mcu/peripheral/rtl876x_captouch.c new file mode 100644 index 0000000..f160dc7 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_captouch.c @@ -0,0 +1,352 @@ +/** +********************************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_captouch.c +* @brief This file provides all the Cap Touch functions. +* @details +* @author Yuan +* @date 2020.09.29 +* @version v1.0.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_captouch.h" +#include "platform_utils.h" + +#define CTC_FUNC_EN_REG 0x26 +#define CTC_CLK_SRC_REG (*((volatile uint32_t *)0x4000020CUL)) +#define CTC_CLK_EN_REG (*((volatile uint32_t *)0x40000234UL)) +#define CTC_CLK_SRC_SEL_REG (*((volatile uint32_t *)0x400003F8UL)) +#define CTC_WK_EN_REG (*((volatile uint32_t *)0x40009000UL)) +#define CTC_WK_EN_REG_1 (*((volatile uint32_t *)0x40009048UL)) + +/** + * @brief Enable the CTCx peripheral IP clock and function.. + * @param None. + * @retval None. + */ +void CTC_RCCConfig(uint32_t clock_source) +{ + /* Enable Cap Touch IP clock and function */ + if (clock_source == CTC_CLOCK_SOURCE_1M) + { + CTC_CLK_SRC_REG |= BIT29; + CTC_CLK_SRC_SEL_REG |= BIT0; + } + else if (clock_source == CTC_CLOCK_SOURCE_40M) + { + CTC_CLK_SRC_SEL_REG &= ~BIT0; + } + + CTC_CLK_EN_REG |= BIT12; + + /* Enable CTC function */ + uint16_t reg_value = btaon_fast_read_safe(CTC_FUNC_EN_REG); + reg_value |= BIT(15); + btaon_fast_write_safe(CTC_FUNC_EN_REG, reg_value); +} + +/** + * @brief Deinitializes the CTCx peripheral registers to their default reset values. + * @param None. + * @retval None. + */ +void CTC_DeInit() +{ + /* Enable Cap Touch IP clock and function */ + CTC_CLK_EN_REG &= ~BIT12; + + uint16_t reg_value = btaon_fast_read_safe(CTC_FUNC_EN_REG); + reg_value &= ~BIT(15); + btaon_fast_write_safe(CTC_FUNC_EN_REG, reg_value); +} + +/** + * @brief Initializes the CTCx peripheral according to + * the specified parameters in the CTC_InitStruct. + * @param CTCx: CTC peripheral. + * @param CTC_InitStruct: pointer to a CTC_InitTypeDef structure that + * contains the configuration information for the specified CTC peripheral. + * @retval None. + */ +void CTC_Init(CTC_TypeDef *CTCx, CTC_InitTypeDef *CTC_InitStruct) +{ + uint32_t temp = 0; + + /* Check the parameters */ + assert_param(IS_CTC_ALL_PERIPH(CTCx)); + + /* Disable CTC */ + CTCx->CR &= CTC_CT_EN_Clr; + + temp |= ((CTC_InitStruct->CTC_DebounceEn & 0x01) << CTC_DEBOUNCE_EN_Pos) | + (CTC_InitStruct->CTC_DebounceTime & 0x03) << CTC_DEBOUNCE_TIME_Pos; + CTCx->CR = temp; + + temp = ((CTC_InitStruct->CTC_SampleTime & 0x07) << 16) + | (CTC_InitStruct->CTC_ScanInterval & 0xFFF); + CTCx->SCAN_PERIOD = temp; + + temp = ((CTC_InitStruct->CTC_BaselineUpdateStep & 0x0F) << 12) + | ((CTC_InitStruct->CTC_BaselineWeightFactor & 0x0F) << 8) + | ((CTC_InitStruct->CTC_ETCScanInterval & 0x7F) << 1) + | ((CTC_InitStruct->CTC_ETCEn & 0x01) << 0); + CTCx->ETC_CR = temp; + + temp = ((CTC_InitStruct->CTC_DelayGuardInterval & 0x1F) << 16) + | ((CTC_InitStruct->CTC_AdvancedGuardInterval & 0x1F) << 0); + CTCx->GUARD_CNT = temp; + + temp = ((CTC_InitStruct->CTC_FastMatchCnt & 0x07) << 16) + | ((CTC_InitStruct->CTC_FastScanInerval & 0xFFF) << 0); + CTC_FAST->SCAN_INI = temp; + + temp = ((CTC_InitStruct->CTC_FalseTouchCnt & 0x3FF) << 16) + | ((CTC_InitStruct->CTC_FalseAlarmCnt & 0xF) << 10) + | ((CTC_InitStruct->CTC_ReleaseActiveCnt & 0x3FF) << 0); + CTC_FAST->SET_CNT = temp; + + uint16_t reg_value = btaon_fast_read_safe(0x116); + btaon_fast_write_safe(0x116, reg_value | BIT(10) | BIT(15)); + + /* vref_sel = 0.85V */ + reg_value = btaon_fast_read_safe(0x116); + btaon_fast_write_safe(0x116, reg_value | BIT(5) | BIT(4)); +} + +/** + * @brief Initializes the specified channel. + * @param channel: specified channel + * @retval None + */ +void CTC_ChannelInit(CTC_ChannelTypeDef *CTC_Channelx, + CTC_ChannelInitTypeDef *CTC_ChannelInitStruct) +{ + /* Check the parameters */ + assert_param(IS_CTC_CHANNEL(CH)); + + CTC_Channelx->TOUCH_TH |= ((CTC_ChannelInitStruct->CTC_NNoiseThd & 0xFF) << 24) + | ((CTC_ChannelInitStruct->CTC_PNoiseThd & 0xFF) << 16); + CTC_Channelx->CR |= ((CTC_ChannelInitStruct->CTC_DifferenceTouchThd & 0xFFF) << 16) | \ + ((CTC_ChannelInitStruct->CTC_ChannelEn & 0x1) << 0); + CTC_Channelx->MBIAS |= ((CTC_ChannelInitStruct->CTC_MBias & 0x3F) << 0); +} + + +/** + * @brief Fills each CTC_InitStruct member with its default value. + * @param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized. + * @return None. + */ +void CTC_StructInit(CTC_InitTypeDef *CTC_InitStruct) +{ + CTC_InitStruct->CTC_BaselineIniEn = CTC_BASELINEINI_ENABLE; + CTC_InitStruct->CTC_DebounceEn = CTC_DEBOUNCE_ENABLE; + CTC_InitStruct->CTC_DebounceTime = CTC_DEBOUNCE_TIMES_2; + CTC_InitStruct->CTC_SampleTime = CTC_SAMPLE_TIME_AVE_256; + CTC_InitStruct->CTC_ScanInterval = CTC_SCAN_INTERVAL_60ms;//60ms + CTC_InitStruct->CTC_BaselineUpdateStep = 0x0001; + CTC_InitStruct->CTC_BaselineWeightFactor = 0x0002; + CTC_InitStruct->CTC_ETCScanInterval = 0x02; + CTC_InitStruct->CTC_ETCEn = ENABLE; + CTC_InitStruct->CTC_SNRUpdateMode = 0x0; + CTC_InitStruct->CTC_ScanChannel = 0x0; + CTC_InitStruct->CTC_ScanChannelSwitchMode = 0x1; + CTC_InitStruct->CTC_DelayGuardInterval = 0x0; + CTC_InitStruct->CTC_AdvancedGuardInterval = 0x203; + + CTC_InitStruct->CTC_FastMatchCnt = + CTC_FS_Match_Cnt_1DB; /*!< FS_MATCH_CNT must smaller than debounce time. */ + CTC_InitStruct->CTC_FastScanInerval = 0x1D; + CTC_InitStruct->CTC_FalseTouchCnt = 0x3FF; + CTC_InitStruct->CTC_FalseAlarmCnt = 0x5; + CTC_InitStruct->CTC_ReleaseActiveCnt = 0xFF; +} + +/** + * @brief Fills each CTC_InitStruct member with its default value. + * @param CTC_InitStruct: Pointer to a CTC_InitStruct structure which will be initialized. + * @return None. + */ +void CTC_ChannelStructInit(CTC_ChannelInitTypeDef *CTC_ChannelInitStruct) +{ + CTC_ChannelInitStruct->CTC_ChannelEn = DISABLE; + CTC_ChannelInitStruct->CTC_BaselineData = 0x0; + CTC_ChannelInitStruct->CTC_DifferenceTouchThd = 0x64; + CTC_ChannelInitStruct->CTC_AbsoluteTouchThd = 0x0; + CTC_ChannelInitStruct->CTC_PNoiseThd = 0xFF; + CTC_ChannelInitStruct->CTC_NNoiseThd = 0xFF; + CTC_ChannelInitStruct->CTC_MBias = CTC_MBIAS_8uA; +} + +/** + * @brief Enable or disable the specified Cap Touch interrupt. + * \param[in] CTCx: The Cap Touch peripheral. + * \param[in] CTC_INT: Specifies the Cap Touch interrupt source which to be enabled or disabled. + * This parameter can be any combination of the following values: + * \arg CTC_INT_FALSE_TOUCH_CH1: Channel 1 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_FALSE_TOUCH_CH0: Channel 0 Touch cnt reach false touch cnt interrupt. + * \arg CTC_INT_N_NOISE_THD: Negative noise threshold overflow interrupt. + * \arg CTC_INT_FIFO_OVERFLOW: Raw code FIFO over flow interrupt + * \arg CTC_INT_P_NOISE_THD: Positive noise threshold overflow interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH1: Channel x release interrupt. + * \arg CTC_INT_TOUCH_RELEASE_CH0: Channel x release interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH1: Channel x press interrupt. + * \arg CTC_INT_TOUCH_PRESS_CH0: Channel x press interrupt. + * @param NewState: New state of the Cap Touch interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void CTC_INTConfig(uint32_t CTC_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CTC_INT(CTC_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected GPIO pin interrupts */ + CTC->INT_EN |= CTC_INT; + } + else + { + /* Disable the selected GPIO pin interrupts */ + CTC->INT_EN &= ~CTC_INT; + } +} + +/** + * @brief Enables or disables the specified Cap Touch peripheral. + * @param CTCx: Cap Touch peripheral. + * @param NewState: New state of the Cap Touch peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retutn None. + */ +void CTC_Cmd(CTC_TypeDef *CTCx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CTC_ALL_PERIPH(CTCx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the Cap Touch */ + CTCx->CR |= CTC_BASELINE_INI_Msk | CTC_CT_EN_Msk; + } + else + { + /* Disable the Cap Touch */ + CTCx->CR &= CTC_CT_EN_Clr; + CTCx->CR &= CTC_BASELINE_INI_CLR; + } +} + +/** + * @brief Enable or disable system wake up of CTC. + * @param NewState: new state of the wake up function. + * This parameter can be: ENABLE or DISABLE. + * @return None + */ +void CTC_SystemWakeupConfig(E_CTC_CH channel, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable system wake up */ + if (channel == CTC_CH0) + { + CTC_WK_EN_REG |= BIT16; + } + else + { + CTC_WK_EN_REG_1 |= BIT(channel); + } + } + else + { + /* Disable system wake up */ + if (channel == CTC_CH0) + { + CTC_WK_EN_REG &= ~BIT16; + } + else + { + CTC_WK_EN_REG_1 &= ~BIT(channel); + } + } +} + +/** + * @brief Check the fast mode scan interval param to be set is in avalible range. + * @param fast_scan_interval: fast scan interval in units of ms. + * @retval "TRUE" for in avalible range; "FALSE" for out of avalible range. + */ +bool CTC_CheckFastScanIntervalGuardTime(uint8_t fast_scan_interval) +{ + uint8_t adv_guard_interval = CTC->GUARD_CNT & 0x3FF; + uint8_t dly_guard_interval = (CTC->GUARD_CNT >> 16) & 0x3FF; + return (fast_scan_interval * 125 > ((adv_guard_interval + dly_guard_interval + 2)) * 4); +} + +/** + * @brief Set CTC scan interval for slow mode or fast mode. + * @param scan_interval: scan interval in units of 1s/1.024KHz (= 0.9765625 ms) + * Configurable range: 0x0~0xFFF (0~4095) + * @param CTCMode: CTC_SLOW_MODE or CTC_FAST_MODE. + * @retval ture: success, false: interval is out of range. + * @note Note that slow mode interval should not be lower then fast mode interval, + * Fast mode interval should be greater then total guard time for AUXADC. + */ +bool CTC_SetScanInterval(uint16_t scan_interval, E_CTC_MODE CTC_Mode) +{ + /* Check the parameters */ + assert_param(interval <= 4095); + assert_param(IS_CTC_MODE(CTC_Mode)); + + if (CTC_Mode == CTC_SLOW_MODE) + { + CTC->SCAN_PERIOD |= scan_interval & 0xFFF; + } + else + { +// if (CTC_CheckFastScanIntervalGuardTime(scan_interval)) +// { +// return false; +// } + CTC_FAST->SCAN_INI |= scan_interval & 0xFFF; + } + + if (((CTC->SCAN_PERIOD & 0xFFF) < (CTC_FAST->SCAN_INI & 0xFFF))) + { + return false; + } + + return true; +} + +/** + * @brief Get touch active count from specified channel under fast mode. + * @param channel: specified channel + * @retval touch active count + */ +uint16_t CTC_GetChannelTouchCount(E_CTC_CH channel) +{ + /* Set strobe signal for the Touch active count value. */ + CTC_FAST->SCAN_INI |= BIT(24); + platform_delay_us(2); + + FS_TOUCH_CNT_TYPE fs_touch_cnt = {0}; + + /* Read touch active count */ + fs_touch_cnt.fs_touch_cnt_01.d32 = CTC_FAST->TOUCH_CNT01; + + /* Return touch active count of specified channel(10 bit) */ + return (fs_touch_cnt.d16[channel] & 0x3FF); +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ diff --git a/src/mcu/peripheral/rtl876x_codec.c b/src/mcu/peripheral/rtl876x_codec.c new file mode 100644 index 0000000..5a4d05b --- /dev/null +++ b/src/mcu/peripheral/rtl876x_codec.c @@ -0,0 +1,329 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_codec.c +* @brief This file provides all the CODEC firmware functions. +* @details +* @author Yuan +* @date 2020-11-16 +* @version v1.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_codec.h" +//#include "rtl876x_pinmux.h" +#include "platform_utils.h" + +/** + * @brief Initialize the CODEC analog registers in AON area. + * @param None. + * @retval None + */ +void CODEC_AnalogCircuitInit(void) +{ + uint16_t reg_value = 0; + + /* Enable ADC 1V1 power cut */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | 0x01); +} + +/** + * @brief Deinitialize the CODEC analog registers in AON area. + * @param None. + * @retval None + */ +void CODEC_AnalogCircuitDeInit(void) +{ + uint16_t reg_value = 0; + + /* Disable 1V1 power cut */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value & (~0x01)); +} + +/** + * @brief Deinitializes the CODEC peripheral registers to their default reset values(turn off CODEC clock). + * @param CODECx: selected CODEC peripheral. + * @retval None + */ +void CODEC_DeInit(CODEC_TypeDef *CODECx) +{ + /* Check the parameters */ + assert_param(IS_CODEC_PERIPH(CODECx)); + + CODECx->ADC0_CTRL1 &= ~0x7F; + + platform_delay_ms(30); + + CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK; + + CODECx->CLK_CR1 &= ~0x3FFF; + + CODECx->I2S_CTRL &= ~BIT0; + + CODECx->CR0 &= ~BIT0; + + if (CODEC->ADC0_CTRL0 & CODEC_AMIC_DMIC_CH0_SEL_MSK) + { + CODEC_ANA->ANA_CR0 &= CODEC_ADC_ANA_POW_CLR; + CODEC_ANA->ANA_CR1 &= ~0x3000000; + CODEC_ANA->ANA_CR1 &= ~BIT15; + CODEC_ANA->ANA_CR1 &= ~BIT10; + CODECx->ANA_CR1 &= ~BIT3; + CODEC_ANA->ANA_CR0 &= CODEC_DAC_ADDACK_POW_CLR; + } + else + { + CODEC_ANA->ANA_CR1 &= ~BIT15; + CODEC_ANA->ANA_CR1 &= ~BIT10; + CODECx->ANA_CR1 &= ~BIT3; + CODECx->CLK_CR2 &= ~BIT3; + } + + RCC_PeriphClockCmd(APBPeriph_CODEC, APBPeriph_CODEC_CLOCK, DISABLE); + CODEC_AnalogCircuitDeInit(); +} + +/** + * @brief Initializes the CODEC peripheral according to the specified + * parameters in the CODEC_InitStruct + * @param CODECx: selected CODEC peripheral. + * @param CODEC_InitStruct: pointer to a CODEC_InitTypeDef structure that + * contains the configuration information for the specified CODEC peripheral + * @retval None + */ +void CODEC_Init(CODEC_TypeDef *CODECx, CODEC_InitTypeDef *CODEC_InitStruct) +{ + /* Check the parameters */ + /* MIC initialization parameters for input */ + assert_param(IS_CODEC_PERIPH(CODECx)); + assert_param(IS_SAMPLE_RATE(CODEC_InitStruct->CODEC_SampleRate)); + assert_param(IS_CODEC_I2S_DATA_FORMAT(CODEC_InitStruct->CODEC_I2SFormat)); + assert_param(IS_CODEC_I2S_DATA_WIDTH(CODEC_InitStruct->CODEC_I2SDataWidth)); + assert_param(IS_MICBIAS_CONFIG(CODEC_InitStruct->CODEC_MicBIAS)); + assert_param(IS_MICBST_MODE(CODEC_InitStruct->CODEC_MicBstMode)); + assert_param(IS_MICBST_GAIN(CODEC_InitStruct->CODEC_MicBstGain)); + assert_param(IS_CODEC_DMIC_CLOCK(CODEC_InitStruct->CODEC_DmicClock)); + /* MIC channel 0 initialization parameters */ + assert_param(IS_CODEC_CH0_MIC_MUTE(CODEC_InitStruct->CODEC_Ch0Mute)); + assert_param(IS_CODEC_CH0_MIC_TYPE(CODEC_InitStruct->CODEC_Ch0MicType)); + assert_param(IS_DMIC_CH0_LATCH_EDGE(CODEC_InitStruct->CODEC_Ch0DmicDataLatch)); + assert_param(IS_AD_GAIN(CODEC_InitStruct->CODEC_Ch0AdGain)); + assert_param(IS_CH0_BOOST_GAIN(CODEC_InitStruct->CODEC_Ch0BoostGain)); + assert_param(IS_CH0_ADC_ZERO_DET_TIMEOUT(CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout)); + + uint16_t reg_value = 0; + + /* Enable ADC 1V8 LDO current limit */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | BIT3); + + /* Smaller LDO BW for LDO PSRR improvement */ + reg_value = btaon_fast_read_safe(0x112); + btaon_fast_write_safe(0x112, reg_value & (~0x6000)); + + /* Enable ADC 1V8 LDO */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | BIT2); + + /* Delay 15ms */ + platform_delay_us(15000); + + /* Power on Vref */ + CODEC_ANA->ANA_CR1 |= CODEC_MICBST_VREF_POW_MSK; + + /* MICBIAS voltage selection (default 1.8V) */ + CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_VSET_CLR; +// CODEC_ANA->ANA_CR1 |= (3 << CODEC_MICBIAS_VSET_POS); + CODEC_ANA->ANA_CR1 |= CODEC_InitStruct->CODEC_MicBIAS; + + /* Enable MICBIAS current limit & OCP */ + CODEC_ANA->ANA_CR2 |= CODEC_MICBIAS_LIMIT_MSK; + + /* Delay 1.5 ms */ + platform_delay_us(1500); + + /* Power on MICBIAS & chopper */ + CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_POW_MSK; + CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_ENCHX_MSK; + + /* Enable ckx_micbias 312.5KHz */ + CODECx->ANA_CR1 |= CODEC_CKX_MICBIAS_EN_MSK; + + /* Delay 5 ms */ + platform_delay_ms(5); + + /* Disable MICBIAS current limit */ + CODEC_ANA->ANA_CR2 &= CODEC_MICBIAS_LIMIT_CLR; + + /* Disable ADC 1V8 LDO current limit */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value & (~(BIT3))); + + /* Enable Vref RC bypass mode */ + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | (BIT5)); + + /* Enable audio IP*/ + CODECx->CR0 |= CODEC_AUDIO_IP_EN_MSK; + + /* Sample Rate selection. */ + CODECx->CLK_CR3 &= CODEC_SAMPLE_RATE_CLR; +// CODECx->CLK_CR3 |= 0x5; + CODECx->CLK_CR3 |= CODEC_InitStruct->CODEC_SampleRate; + +// /* I2S rx data length select to 16bits */ +// CODECx->I2S_CTRL &= CODEC_I2S_RX_DATA_LEN_CLR; + +// /* I2S rx data format select to I2S */ +// CODECx->I2S_CTRL &= CODEC_I2S_RX_DATA_FORMAT_CLR; + +// /* Enable digital codec */ +// CODECx->I2S_CTRL |= CODEC_AUDIO_RST_N_MSK; + + /* Configure I2S parameters */ + CODECx->I2S_CTRL = CODEC_InitStruct->CODEC_I2SChSequence | \ + CODEC_InitStruct->CODEC_I2SDataWidth | \ + CODEC_InitStruct->CODEC_I2SFormat | \ + CODEC_AUDIO_RST_N_MSK; + + if (CODEC_InitStruct->CODEC_Ch0MicType == CODEC_CH0_AMIC) + { + /* Enable AD/DA clock and ADC analog power */ + CODEC_ANA->ANA_CR0 = CODEC_DAC_ADDACK_POW_MSK | \ + CODEC_ADC_ANA_POW_MSK | \ + CODEC_DTSDM_CLK_EN_MSK; + + CODEC_ANA->ANA_CR1 &= ~0x3000000; + CODEC_ANA->ANA_CR1 |= CODEC_MICBST_POW_MSK; + + CODEC_ANA->ANA_CR1 &= ~0x30000; + CODEC_ANA->ANA_CR1 |= CODEC_InitStruct->CODEC_MicBstGain; + + CODEC_ANA->ANA_CR1 |= CODEC_MICBST_MUTE_MIC_MSK; + + if (CODEC_InitStruct->CODEC_MicBstMode == MICBST_Mode_Single) + { + CODEC_ANA->ANA_CR1 &= CODEC_MICBST_ENDFL_CLR; + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | (BIT4)); + } + else if (CODEC_InitStruct->CODEC_MicBstMode == MICBST_Mode_Differential) + { + CODEC_ANA->ANA_CR1 |= CODEC_MICBST_ENDFL_MSK; + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value & (~BIT4)); + } + CODECx->ADC0_CTRL0 |= CODEC_AMIC_DMIC_CH0_SEL_MSK; +// CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK; + } + else if (CODEC_InitStruct->CODEC_Ch0MicType == CODEC_CH0_DMIC) + { + CODECx->CLK_CR2 = CODEC_DMIC1_CLK_EN_MSK | \ + CODEC_InitStruct->CODEC_DmicClock; + CODECx->ADC0_CTRL0 &= CODEC_AMIC_DMIC_CH0_SEL_CLR; + CODECx->ADC0_CTRL0 &= CODEC_ADC0_DMIC_SRC_SEL_CLR; + CODECx->ADC0_CTRL0 |= CODEC_InitStruct->CODEC_Ch0DmicDataLatch; +// CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK; + } + CODECx->ADC0_CTRL0 |= CODEC_ADC_CH0_AD_MUTE_MSK; + + /* AD LPF clock 10M(default 5M) */ + CODECx->CLK_CR3 &= CODEC_AD_LPF_CLK_SEL_CLR; + + /* ADC HPF FC sel */ + CODECx->ADC0_CTRL0 &= CODEC_ADC0_DCHPF_FC_SEL_CLR; + + /* Enable ADC0 HPF */ + CODECx->ADC0_CTRL0 |= CODEC_ADC0_DCHPF_EN_MSK; + + /* Configuer mic channel 0 parameters */ + CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_BOOST_GAIN_CLR; + CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_ZDET_TOUT_CLR; + CODECx->ADC0_CTRL0 |= CODEC_InitStruct->CODEC_Ch0BoostGain | \ + CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout; + CODECx->ADC0_CTRL1 &= ~0x7F; + CODECx->ADC0_CTRL1 |= CODEC_InitStruct->CODEC_Ch0AdGain; + + /* Enable codec clock control */ + CODECx->CLK_CR1 &= ~0x3FFF; +// CODECx->CLK_CR1 = 0x1C40; + + /* Clock configuration */ + CODECx->CLK_CR1 = CODEC_AD_ANA_CLK_EN_MSK | \ + CODEC_AD_FIFO_CLK_EN_MSK; + if (CODEC_InitStruct->CODEC_Ch0Mute == CODEC_CH0_UNMUTE) + { + CODECx->CLK_CR1 |= CODEC_AD_FILTER_CH0_CLK_MSK | \ + CODEC_AD_CH0_CLK_MSK; + platform_delay_ms(60); + CODECx->ADC0_CTRL0 &= CODEC_ADC_CH0_AD_MUTE_CLR; + } +} + +/** + * @brief Fills each CODEC_InitStruct member with its default value. + * @param CODEC_InitStruct: pointer to an CODEC_InitTypeDef structure which will be initialized. + * @retval None + */ +void CODEC_StructInit(CODEC_InitTypeDef *CODEC_InitStruct) +{ + /* Basic parameters section */ + CODEC_InitStruct->CODEC_SampleRate = SAMPLE_RATE_16KHz; + CODEC_InitStruct->CODEC_I2SFormat = CODEC_I2S_DataFormat_I2S; + CODEC_InitStruct->CODEC_I2SDataWidth = CODEC_I2S_DataWidth_16Bits; + CODEC_InitStruct->CODEC_I2SChSequence = CODEC_I2S_CH_L_L; + CODEC_InitStruct->CODEC_MicBIAS = MICBIAS_VOLTAGE_1_8; + CODEC_InitStruct->CODEC_MicBstMode = MICBST_Mode_Single; + CODEC_InitStruct->CODEC_MicBstGain = MICBST_Gain_0dB; + CODEC_InitStruct->CODEC_DmicClock = DMIC_Clock_2500KHz; + /* MIC channel 0 initialization parameters section */ + CODEC_InitStruct->CODEC_Ch0MicType = CODEC_CH0_AMIC; + CODEC_InitStruct->CODEC_Ch0BoostGain = Ch0_Boost_Gain_0dB; + CODEC_InitStruct->CODEC_Ch0Mute = CODEC_CH0_UNMUTE; + CODEC_InitStruct->CODEC_Ch0ZeroDetTimeout = Ch0_ADC_Zero_DetTimeout_1024_32_Sample; + CODEC_InitStruct->CODEC_Ch0DmicDataLatch = DMIC_Ch0_Rising_Latch; + CODEC_InitStruct->CODEC_Ch0AdGain = 0x2F; +} + +/** + * @brief Enable or disable mic_bias output. + * @param CODECx: selected CODEC peripheral. + * @param NewState: new state of MICBIAS. + * This parameter can be: ENABLE or DISABLE. + * @return none. + */ +void CODEC_MICBIASCmd(CODEC_TypeDef *CODECx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_CODEC_PERIPH(CODECx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + if (!(CODEC_ANA->ANA_CR1 & CODEC_MICBIAS_POW_MSK)) + { + /* Analog initialization in AON register */ + CODEC_AnalogCircuitInit(); + + /* MICBIAS power on */ + CODEC_ANA->ANA_CR1 |= CODEC_MICBIAS_ENCHX_MSK | \ + CODEC_MICBST_VREF_POW_MSK | \ + CODEC_MICBIAS_POW_MSK; + + /* Clock enable */ + CODECx->ANA_CR1 = CODEC_CKX_MICBIAS_EN_MSK; + } + } + else + { + CODEC_ANA->ANA_CR1 &= CODEC_MICBIAS_POW_CLR; + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_enh_tim.c b/src/mcu/peripheral/rtl876x_enh_tim.c new file mode 100644 index 0000000..5867e38 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_enh_tim.c @@ -0,0 +1,456 @@ +/** +********************************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_enh_tim.c +* @brief This file provides all the Timer firmware functions. +* @details +* @author Yuan +* @date 2020.09.29 +* @version v1.0.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_enh_tim.h" + +/* ENHTIM Private Defines */ +#define TIMER_CLK_SOURCE_REG_35C (*((volatile uint32_t *)0x4000035CUL)) +#define TIMER_CLK_SOURCE_REG_360 (*((volatile uint32_t *)0x40000360UL)) + +/** + * @brief Initializes the ENHTIMx peripheral according to + * the specified parameters in the ENHTIM_InitStruct. + * @param ENHTIMx: where x can be 0 to 1 to select the ENHTIM peripheral. + * @param ENHTIM_InitStruct: pointer to a ENHTIM_InitTypeDef structure + * that contains the configuration information for the specified ENHTIM peripheral. + * @retval None + */ +void ENHTIM_Init(ENHTIM_TypeDef *ENHTIMx, ENHTIM_InitTypeDef *ENHTIM_InitStruct) +{ + uint32_t enhtim_id = 0; + uint32_t temp = 0; + + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0x24; + + ENH_TIM_SHARE->CMD &= ~BIT(enhtim_id); + ENH_TIM_SHARE->INT_CMD &= ~BIT(enhtim_id); + + /* Clock source config */ + if (TIMER_CLK_SOURCE_REG_360 & BIT(10)) + { + TIMER_CLK_SOURCE_REG_360 &= ~(BIT(10)); + } + + TIMER_CLK_SOURCE_REG_360 |= ((ENHTIM_InitStruct->ENHTIM_ClockDiv & 0x07) << (enhtim_id * 3 + 25)); + + if (ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource == ENHTIM_PWM_DZCLKSRCE_32K) + { + TIMER_CLK_SOURCE_REG_360 |= BIT8; + } + + TIMER_CLK_SOURCE_REG_35C |= ((ENHTIM_InitStruct->ENHTIM_ClockSource & 0x01) << (enhtim_id + 1)); + + temp = 0; + for (uint8_t i = 0; i < 3; i++) + { + temp |= ((ENHTIM_InitStruct->ENHTIM_LatchCountEn[i] & 0x01) << (i + 10)) \ + | ((ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[i] & 0x03) << (i * 2 + 4)); + } + ENHTIMx->CR |= temp; + + /*Config latch count2. */ + temp = 0x3F; + if (ENHTIM_InitStruct->ENHTIM_LatchCountEn[2] == ENHTIM_LATCH_COUNT_ENABLE) + { + /* Clear Latch Count2 thd */ + ENHTIMx->CR &= ~(0x1F << 23); + ENHTIMx->CR |= (ENHTIM_InitStruct->ENHTIM_LatchCount2Thd & 0x1F) << 23; + + /* Config Latch Count2 trigger GPIO pin. */ + if ((ENHTIM_InitStruct->ENHTIM_LatchTriggerPad >= P1_6) && + (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad <= P3_6)) + { + temp = (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad - 4); + } + else if ((ENHTIM_InitStruct->ENHTIM_LatchTriggerPad >= P4_0) && + (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad <= P5_2)) + { + temp = (ENHTIM_InitStruct->ENHTIM_LatchTriggerPad - 5); + } + } + + ENHTIM_LATCH_COUNT_CR &= ~(0x1FF); + ENHTIM_LATCH_COUNT_CR |= (ENHTIM_InitStruct->ENHTIM_TimerGPIOTriggerEn << 8) | \ + (ENHTIM_InitStruct->ENHTIM_BTGPIOTriggerEn << 7) | \ + ((enhtim_id & 0x01) << 6) | ((temp) & 0x3F); + + /* Config PWM mode. */ + temp = 0; + if ((ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_AUTO) || + (ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_MANUAL)) + { + temp = (ENHTIM_InitStruct->ENHTIM_PWMStartPolarity & 0x04) | + (ENHTIM_InitStruct->ENHTIM_PWMOutputEn & 0x08) | + ENHTIM_InitStruct->ENHTIM_Mode; + ENHTIMx->CR |= temp; + temp = 0; + ENHTIMx->MAX_CNT = ENHTIM_InitStruct->ENHTIM_MaxCount; + } + + if (ENHTIM_InitStruct->ENHTIM_Mode == ENHTIM_MODE_PWM_MANUAL) + { + ENHTIMx->CCR = ENHTIM_InitStruct->ENHTIM_CCValue; + } + + /* Set pwm1 deadzone mode, pwm1_pn based on enhance timer0 */ + if (ENHTIM_InitStruct->ENHTIM_PWMDeadZoneEn == ENHTIM_PWM_DEADZONE_ENABLE) + { + if (enhtim_id == 0) + { + /* Set pwm deadzone time. */ + ENHTIM_PWM_DEADZONE_CR |= ((ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource & 0x90000) \ + | ((ENHTIM_InitStruct->ENHTIM_PWMStopStateP << 10) & (BIT10)) \ + | ((ENHTIM_InitStruct->ENHTIM_PWMStopStateN << 9) & (BIT9)) \ + | (ENHTIM_InitStruct->ENHTIM_DeadZoneSize & 0xFF) \ + | BIT12 | BIT17 | BIT18); + } + } + else + { + if (enhtim_id == 0) + { + /* Disable pwm1 deadzone mode. */ + ENHTIM_PWM_DEADZONE_CR &= ~(BIT12 | BIT17 | BIT18); + } + } + + /* Clear the IT status */ + ENH_TIM_SHARE->FIFO_SR0 |= BIT(16 + enhtim_id); + ENH_TIM_SHARE->FIFO_SR2 |= BIT(16 + enhtim_id * 2); + ENH_TIM_SHARE->INT_SR |= BIT(enhtim_id); +} + +/** + * @brief Fills each ENHTIM_InitStruct member with its default value. + * @param ENHTIM_InitStruct: Pointer to a ENHTIM_InitStruct structure which will be initialized. + * @return None. + */ +void ENHTIM_StructInit(ENHTIM_InitTypeDef *ENHTIM_InitStruct) +{ + ENHTIM_InitStruct->ENHTIM_ClockSource = ENHTIM_DIVIDER_CLOCK; + ENHTIM_InitStruct->ENHTIM_ClockDiv = ENHTIM_CLOCK_DIVIDER_1; + ENHTIM_InitStruct->ENHTIM_Mode = ENHTIM_MODE_FreeRun; + ENHTIM_InitStruct->ENHTIM_PWMOutputEn = ENHTIM_PWM_DISABLE; + ENHTIM_InitStruct->ENHTIM_PWMStartPolarity = ENHTIM_PWM_START_WITH_LOW; + ENHTIM_InitStruct->ENHTIM_LatchCountEn[0] = ENHTIM_LATCH_COUNT_DISABLE; + ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[0] = ENHTIM_LATCH_TRIGGER_RISING_EDGE; + ENHTIM_InitStruct->ENHTIM_LatchCountEn[1] = ENHTIM_LATCH_COUNT_DISABLE; + ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[1] = ENHTIM_LATCH_TRIGGER_RISING_EDGE; + ENHTIM_InitStruct->ENHTIM_LatchCountEn[2] = ENHTIM_LATCH_COUNT_DISABLE; + ENHTIM_InitStruct->ENHTIM_LatchCountTrigger[2] = ENHTIM_LATCH_TRIGGER_RISING_EDGE; + ENHTIM_InitStruct->ENHTIM_LatchCount2Thd = 3; + ENHTIM_InitStruct->ENHTIM_TimerGPIOTriggerEn = DISABLE; + ENHTIM_InitStruct->ENHTIM_BTGPIOTriggerEn = DISABLE; + ENHTIM_InitStruct->ENHTIM_MaxCount = 0xFFFFFFFE;//range 0x1~0xFFFFFFFE + ENHTIM_InitStruct->ENHTIM_CCValue = 0x0; + + ENHTIM_InitStruct->ENHTIM_PWMDeadZoneClockSource = ENHTIM_PWM_DZCLKSRCE_32K; + ENHTIM_InitStruct->ENHTIM_PWMDeadZoneEn = ENHTIM_PWM_DEADZONE_DISABLE; + ENHTIM_InitStruct->ENHTIM_PWMStopStateP = ENHTIM_PWM_STOP_AT_HIGH; + ENHTIM_InitStruct->ENHTIM_PWMStopStateN = ENHTIM_PWM_STOP_AT_LOW; + ENHTIM_InitStruct->ENHTIM_DeadZoneSize = 0xFF;/*!< range 0x1 ~ 0xFF */ +} + +/** + * @brief Enables or disables the specified ENHTIM peripheral. + * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * @param NewState: New state of the ENHTIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retutn None. + */ +void ENHTIM_Cmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + ENH_TIM_SHARE->CMD |= BIT(enhtim_id); + } + else + { + /* Disable the TIM Counter */ + ENH_TIM_SHARE->CMD &= ~(BIT(enhtim_id)); + } +} + +/** + * @brief Mask or unmask the latch count2 fifo interrupt. + * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * @param NewState: New state of the specified ENHTIMx peripheral latch count2 fifo interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None. + */ +void ENHTIM_LCFIFOMaskConfig(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + if (NewState != DISABLE) + { + ENH_TIM_SHARE->INT_CMD |= BIT(24) << enhtim_id; + } + else + { + ENH_TIM_SHARE->INT_CMD &= ~(BIT(24) << enhtim_id); + } +} + +/** + * @brief Enables or disables ENHTIMx interrupt. + * @param ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count0 interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 interrupt source. + * @param NewState: New state of the ENHTIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void ENHTIM_INTConfig(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + assert_param(IS_ENHTIM_INT(ENHTIM_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + if (NewState != DISABLE) + { + /* Enable the ENHTIM Interrupt */ + if (ENHTIM_INT & 0x40) + { + *((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_INT_CMD0) + (ENHTIM_INT & 0xF))) |= BIT( + 24) << enhtim_id; + } + else + { + ENH_TIM_SHARE->INT_CMD |= BIT(enhtim_id); + } + } + else + { + /* Disable the ENHTIM Interrupt */ + if (ENHTIM_INT & 0x40) + { + *((volatile uint32_t *)(&(ENH_TIM_SHARE->LC_INT_CMD0) + (ENHTIM_INT & 0xF))) &= ~(BIT( + 24) << enhtim_id);; + } + else + { + ENH_TIM_SHARE->INT_CMD &= ~BIT(enhtim_id); + } + } +} + +/** + * \brief Read ENHTIMx latch counter2 fifo data. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] length: Latch count2 fifo length, max 4. + * \pBuf[out] pBuf: FIFO data out buffer. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * uint8_t length = ENHTIM_GetLatchCount2FIFOLength(ENH_TIM0); + * } + * \endcode + */ +void ENHTIM_ReadLatchCount2FIFO(ENHTIM_TypeDef *ENHTIMx, uint32_t *pBuf, uint8_t length) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + if ((pBuf == 0) || (length > 4)) + { + return; + } + + for (uint8_t i = 0; i < length; i++) + { + pBuf[i] = ENHTIMx->LATCH_CNT2; + } +} + +/** + * \brief Check whether the ENHTIM latch count2 fifo has data or not. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return The new state of the specified ENHTIMx peripheral + * latch count2 fifo (SET or RESET). + */ +ITStatus ENHTIM_GetLCFIFOStatus(ENHTIM_TypeDef *ENHTIMx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + ITStatus itstatus = RESET; + + if (ENH_TIM_SHARE->INT_SR & ((BIT(24) << enhtim_id))) + { + itstatus = SET; + } + + return itstatus; +} + +/** + * \brief Check whether the ENHTIM latch count2 fifo interrupt has occurred or not. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \return The new state of the specified ENHTIMx peripheral + * latch count2 fifo interrupt(SET or RESET). + */ +ITStatus ENHTIM_GetLCFIFOMaskStatus(ENHTIM_TypeDef *ENHTIMx) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + ITStatus itstatus = RESET; + + if (ENH_TIM_SHARE->MASK_INT_SR & ((BIT(24) << enhtim_id))) + { + itstatus = SET; + } + + return itstatus; +} + +/** + * \brief Check whether the ENHTIM interrupt has occurred or not. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY: Enhance Timer latch count2 fifo empty interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source. + * \return The new state of the ENHTIM_INT(SET or RESET). + */ +ITStatus ENHTIM_GetINTStatus(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + assert_param(IS_ENHTIM_INT(INT)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + ITStatus itstatus = RESET; + + if (ENHTIM_INT == ENHTIM_INT_TIM) + { + itstatus = (ITStatus)((ENH_TIM_SHARE->INT_SR) >> (enhtim_id)); + } + else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_FULL) + { + itstatus = (ITStatus)(((ENH_TIM_SHARE->FIFO_SR2) >> (16 + enhtim_id * 2)) & 0x01); + } + else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_THD) + { + itstatus = (ITStatus)(((ENH_TIM_SHARE->FIFO_SR0) >> (16 + enhtim_id)) & 0x01); + } + else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_EMPTY) + { + itstatus = (ITStatus)(((ENH_TIM_SHARE->FIFO_SR2) >> (17 + enhtim_id * 2)) & 0x01); + } + + return itstatus; +} + +/** + * \brief Clear ENHTIM interrupt. + * \param[in] ENHTIMx: Where x can be 0 to 1 to select the ENHTIMx peripheral. + * \param[in] ENHTIM_INT: Specifies the ENHTIMx interrupt source which to be enabled or disabled. + * This parameter can be one of the following values: + * \arg ENHTIM_INT_TIM: Enhance Timer interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_FULL: Enhance Timer latch count2 fifo full interrupt source. + * \arg ENHTIM_INT_LATCH_CNT2_FIFO_THD: Enhance Timer latch count2 fifo threshold interrupt source. + * \return None. + * + * Example usage + * \code{.c} + * + * void enhance_timer_demo(void) + * { + * ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_TIM); + * } + * \endcode + */ +void ENHTIM_ClearINTPendingBit(ENHTIM_TypeDef *ENHTIMx, uint8_t ENHTIM_INT) +{ + /* Check the parameters */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + uint32_t enhtim_id = ((uint32_t)ENHTIMx - (uint32_t)ENH_TIM0) / 0X24; + + /* Clear the IT */ + if (ENHTIM_INT == ENHTIM_INT_TIM) + { + ENH_TIM_SHARE->INT_SR |= BIT(enhtim_id); + } + else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_FULL) + { + ENH_TIM_SHARE->FIFO_SR2 |= BIT(16 + enhtim_id * 2); + } + else if (ENHTIM_INT == ENHTIM_INT_LATCH_CNT2_FIFO_THD) + { + ENH_TIM_SHARE->FIFO_SR0 |= BIT(16 + enhtim_id); + } +} + +/** + * \brief Enable or disable bypass dead zone function of PWM complementary output. + * After enabling, PWM_P = ~PWM_N. + * \param[in] ENHTIMx: ENHTIM0. + * \param[in] NewState: New state of the ENHTIMx peripheral. + * \ref DISABLE: Disable bypass dead zone function. + * \ref ENABLE: Enable bypass dead zone function. + * \note To use this function, need to configure the corresponding enhtimer. + * ENHTIMx can be only ENHTIM0. + * \return None. + */ +void ENHTIM_PWMDZBypassCmd(ENHTIM_TypeDef *ENHTIMx, FunctionalState NewState) +{ + /* Check the parameters. */ + assert_param(IS_ENHTIM_ALL_PERIPH(ENHTIMx)); + + if (NewState != DISABLE) + { + /* Enable bypass dead zone function. */ + ENHTIM_PWM_DEADZONE_CR |= BIT13; + } + else + { + /* Disable bypass dead zone function. */ + ENHTIM_PWM_DEADZONE_CR &= (~BIT13); + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_gdma.c b/src/mcu/peripheral/rtl876x_gdma.c new file mode 100644 index 0000000..1d8601d --- /dev/null +++ b/src/mcu/peripheral/rtl876x_gdma.c @@ -0,0 +1,403 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_gdma.c +* @brief This file provides all the DMA firmware functions. +* @details +* @author Yuan +* @date 2020-11-09 +* @version v1.0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_gdma.h" + +/*fifo depth*/ +#define UART_RX_FIFO_DEPTH 32 +#define UART_TX_FIFO_DEPTH 16 +#define SPI_RX_FIFO_DEPTH 36 +#define SPI_TX_FIFO_DEPTH 36 +#define I2C_RX_FIFO_DEPTH 16 +#define I2C_TX_FIFO_DEPTH 24 + +#define REG_GDMA_TIMER *((volatile uint32_t *)0x40006024UL) + +/** + * @brief Deinitializes the GDMA registers to their default reset values. + * @param None + * @return None + */ +void GDMA_DeInit(void) +{ + /* Disable GDMA block in REG_SOC_FUNC_EN */ + RCC_PeriphClockCmd(APBPeriph_GDMA, APBPeriph_GDMA_CLOCK, DISABLE); +} + +/** + * @brief Initializes the GDMA Channelx according to the specified + * parameters in the GDMA_InitStruct. + * @param GDMA_Channelx: where x can be 0 to 3 to select the DMA Channel. + * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that + * contains the configuration information for the specified DMA Channel. + * @return None + */ +void GDMA_Init(GDMA_ChannelTypeDef *GDMA_Channelx, GDMA_InitTypeDef *GDMA_InitStruct) +{ + uint32_t temp_bit = 0; + uint32_t autoreload_temp; + uint32_t llp_temp; + + /* Check the parameters */ + assert_param(IS_GDMA_ALL_PERIPH(GDMA_Channelx)); + assert_param(IS_GDMA_ChannelNum(GDMA_InitStruct->GDMA_ChannelNum)); + assert_param(IS_GDMA_DIR(GDMA_InitStruct->GDMA_DIR)); + assert_param(IS_GDMA_SourceInc(GDMA_InitStruct->GDMA_SourceInc)); + assert_param(IS_GDMA_DestinationInc(GDMA_InitStruct->GDMA_DestinationInc)); + assert_param(IS_GDMA_DATA_SIZE(GDMA_InitStruct->GDMA_SourceDataSize)); + assert_param(IS_GDMA_DATA_SIZE(GDMA_InitStruct->GDMA_DestinationDataSize)); + + /*------------------configure source and destination address of GDMA---------*/ + /* program SARx register to set source address */ + GDMA_Channelx->SAR = GDMA_InitStruct->GDMA_SourceAddr; + /* program DARx register to set destination address */ + GDMA_Channelx->DAR = GDMA_InitStruct->GDMA_DestinationAddr; + + /* Enable GDMA in DmaCfgReg*/ + GDMA_BASE->DmaCfgReg = 0x01; + + /* read ChEnReg to check channel is busy or not */ + if (GDMA_BASE->ChEnReg & BIT(GDMA_InitStruct->GDMA_ChannelNum)) + { + //channel is be used + //error handle code + //while (1); + } + + /*--------------------------- GDMA Configuration -----------------*/ + /* clear pending interrupts of corresponding GDMA channel */ + temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum); + GDMA_BASE->CLEAR_TFR |= temp_bit; + GDMA_BASE->CLEAR_BLOCK |= temp_bit; + GDMA_BASE->CLEAR_DST_TRAN |= temp_bit; + GDMA_BASE->CLEAR_SRC_TRAN |= temp_bit; + GDMA_BASE->CLEAR_ERR |= temp_bit; + + /* mask pending interrupts of corresponding GDMA channel */ + temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum + 8); + GDMA_BASE->MASK_TFR = temp_bit; + GDMA_BASE->MASK_BLOCK = temp_bit; + GDMA_BASE->MASK_DST_TRAN = temp_bit; + GDMA_BASE->MASK_SRC_TRAN = temp_bit; + GDMA_BASE->MASK_ERR = temp_bit; + + /*---------------------------- configure CTL register --------------------------------*/ + + /* configure low 32 bit of CTL register */ + GDMA_Channelx->CTL_LOW = BIT(0) + | (GDMA_InitStruct->GDMA_DestinationDataSize << 1) + | (GDMA_InitStruct->GDMA_SourceDataSize << 4) + | (GDMA_InitStruct->GDMA_DestinationInc << 7) + | (GDMA_InitStruct->GDMA_SourceInc << 9) + | (GDMA_InitStruct->GDMA_DestinationMsize << 11) + | (GDMA_InitStruct->GDMA_SourceMsize << 14) + | (GDMA_InitStruct->GDMA_DIR << 20); + /* configure high 32 bit of CTL register */ + GDMA_Channelx->CTL_HIGH = GDMA_InitStruct->GDMA_BufferSize; + + /*---------------------------- configure CFG register --------------------------------*/ + + switch (GDMA_InitStruct->GDMA_DIR) + { + case GDMA_DIR_MemoryToMemory: + GDMA_Channelx->CFG_LOW = (0x03 << 10); + break; + case GDMA_DIR_MemoryToPeripheral: + GDMA_Channelx->CFG_LOW = BIT11; + break; + case GDMA_DIR_PeripheralToMemory: + GDMA_Channelx->CFG_LOW = BIT10; + break; + case GDMA_DIR_PeripheralToPeripheral: + GDMA_Channelx->CFG_LOW = 0; + break; + default: + GDMA_Channelx->CFG_LOW = 0; + break; + } + + if (GDMA_InitStruct->GDMA_Multi_Block_En == 1 && + ((GDMA_Channelx == GDMA_Channel0) | (GDMA_Channelx == GDMA_Channel1))) + { + /* Config multi-block mode */ + GDMA_Channelx->CFG_LOW &= ~AUTO_RELOAD_SELECTED_BIT; + GDMA_Channelx->CTL_LOW &= ~LLP_SELECTED_BIT; + autoreload_temp = (GDMA_InitStruct->GDMA_Multi_Block_Mode & AUTO_RELOAD_SELECTED_BIT); + llp_temp = (GDMA_InitStruct->GDMA_Multi_Block_Mode & LLP_SELECTED_BIT); + if (llp_temp) + { + GDMA_Channelx->LLP = GDMA_InitStruct->GDMA_Multi_Block_Struct; + GDMA_Channelx->CTL_LOW |= llp_temp; + } + GDMA_Channelx->CFG_LOW |= autoreload_temp; + } + + /* Set Vendor register about timer handshake */ + if ((GDMA_InitStruct->GDMA_DestHandshake == 2) || (GDMA_InitStruct->GDMA_DestHandshake == 3)) + { + REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake + 20); + } + else if ((GDMA_InitStruct->GDMA_DestHandshake >= 24) && (GDMA_InitStruct->GDMA_DestHandshake <= 26)) + { + REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake - 8); + } + else if ((GDMA_InitStruct->GDMA_DestHandshake >= 29) && (GDMA_InitStruct->GDMA_DestHandshake <= 31)) + { + REG_GDMA_TIMER |= BIT(GDMA_InitStruct->GDMA_DestHandshake - 10); + } + + /* configure peripheral parameters and configure source or destination hardware handshaking interface */ + GDMA_Channelx->CFG_HIGH &= ~(0x03ff << 7); + + GDMA_Channelx->CFG_HIGH |= (((((GDMA_InitStruct->GDMA_SourceHandshake) & 0x10) << 4) \ + | ((GDMA_InitStruct->GDMA_SourceHandshake) & 0x0f)) << 7); + GDMA_Channelx->CFG_HIGH |= (((((GDMA_InitStruct->GDMA_DestHandshake) & 0x10) << 1) \ + | ((GDMA_InitStruct->GDMA_DestHandshake) & 0x0f)) << 11); + + /* Enable FIFO mode and Flow control mode */ + GDMA_Channelx->CFG_HIGH &= ~0x03; + GDMA_Channelx->CFG_HIGH |= 0x02; + + /* ---------------clear pending interrupts of corresponding GDMA channel------------------ */ + temp_bit = BIT(GDMA_InitStruct->GDMA_ChannelNum); + GDMA_BASE->CLEAR_TFR |= temp_bit; + GDMA_BASE->CLEAR_BLOCK |= temp_bit; + GDMA_BASE->CLEAR_DST_TRAN |= temp_bit; + GDMA_BASE->CLEAR_SRC_TRAN |= temp_bit; + GDMA_BASE->CLEAR_ERR |= temp_bit; +} + +/** + * @brief Fills each GDMA_InitStruct member with its default value. + * @param GDMA_InitStruct : pointer to a GDMA_InitTypeDef structure which will + * be initialized. + * @return None + */ +void GDMA_StructInit(GDMA_InitTypeDef *GDMA_InitStruct) +{ + /*-------------- Reset DMA init structure parameters values ------------------*/ + GDMA_InitStruct->GDMA_ChannelNum = 0; + GDMA_InitStruct->GDMA_DIR = GDMA_DIR_PeripheralToMemory; + GDMA_InitStruct->GDMA_BufferSize = 200; + GDMA_InitStruct->GDMA_SourceInc = DMA_SourceInc_Fix; + GDMA_InitStruct->GDMA_DestinationInc = DMA_DestinationInc_Inc; + GDMA_InitStruct->GDMA_SourceDataSize = GDMA_DataSize_Byte; + GDMA_InitStruct->GDMA_DestinationDataSize = GDMA_DataSize_Byte; + GDMA_InitStruct->GDMA_SourceMsize = GDMA_Msize_1; + GDMA_InitStruct->GDMA_DestinationMsize = GDMA_Msize_1; + GDMA_InitStruct->GDMA_SourceAddr = 0; + GDMA_InitStruct->GDMA_DestinationAddr = 0; + GDMA_InitStruct->GDMA_SourceHandshake = 0; + GDMA_InitStruct->GDMA_DestHandshake = 0; + GDMA_InitStruct->GDMA_ChannelPriority = 0; + + GDMA_InitStruct->GDMA_Multi_Block_En = DISABLE; + GDMA_InitStruct->GDMA_Multi_Block_Mode = LLI_TRANSFER; +} + +/** + * @brief Enables or disables the specified GDMA Channelx. + * @param GDMA_Channelx: x can be 0 to 3 to select the DMA Channel. + * @param NewState: new state of the DMA Channelx. + * This parameter can be: ENABLE or DISABLE. + * @return None + */ +void GDMA_Cmd(uint8_t GDMA_ChannelNum, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + GDMA_ChannelTypeDef *GDMA_Channelx; + GDMA_Channelx = (GDMA_ChannelTypeDef *)DMA_CH_BASE(GDMA_ChannelNum); + + uint8_t bit_need_set_times = 10; + uint8_t bit_need_check_times = 50; + uint8_t timeout = bit_need_check_times ; + uint8_t bit_set_time = 0; + + if (NewState != DISABLE) + { + /* Enable the selected DMAy Channelx */ + GDMA_BASE->ChEnReg |= BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8); + } + else + { + /*gdma transfor not finished */ + if (GDMA_BASE->ChEnReg & BIT(GDMA_ChannelNum)) + /* suspend gdma channel */ + { + GDMA_Channelx->CFG_LOW |= GDMA_SUSPEND_TRANSMISSSION; + } + /* Disable the selected DMAy Channelx */ + /* polling fifo empty */ + while ((GDMA_GetSuspendChannelStatus(GDMA_Channelx) != SET) && --timeout); + /*cfg bit0 not set */ + if (GDMA_GetSuspendChannelStatus(GDMA_Channelx) != SET) + { + timeout = bit_need_check_times; + /*polling cfg[1:2] 10 times set in 100timer check */ + while (--timeout) + { + if ((GDMA_Channelx->CFG_LOW & BIT1) && (GDMA_Channelx->CFG_LOW & BIT2)) + { + bit_set_time++; + if (bit_set_time >= bit_need_set_times) + { + break; + } + } + } +// if (timeout == 0) +// { +// /*abort disable dma return fail*/ +// return GDMA_DISABLE_FAIL; +// } + } + + /* Disable the selected DMAy Channelx */ + GDMA_BASE->ChEnReg = BIT(GDMA_ChannelNum + 8); + /* unsuspend dma channel */ + GDMA_Channelx->CFG_LOW &= ~(GDMA_SUSPEND_TRANSMISSSION); + } +} + +/** + * @brief Enables or disables the specified DMA Channelx interrupts. + * @param GDMA_Channelx: where x can be 0 to 3 to select the GDMA Channel. + * @param GDMA_IT: specifies the GDMA interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg GDMA_INT_Transfer: Transfer complete interrupt unmask + * @arg GDMA_INT_Block: Block transfer interrupt unmask + * @arg GDMA_INT_SrcTransfer: SourceTransfer interrupt unmask + * @arg GDMA_INT_DstTransfer: Destination Transfer interrupt unmask + * @arg GDMA_INT_Error: Transfer error interrupt unmask + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @return None + */ +void GDMA_INTConfig(uint8_t GDMA_ChannelNum, uint32_t GDMA_IT, FunctionalState NewState) +{ + uint32_t temp_bit = 0; + + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum)); + assert_param(IS_GDMA_CONFIG_IT(GDMA_IT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected DMA interrupts */ + temp_bit = BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8); + + if (GDMA_IT & GDMA_INT_Transfer) + { + GDMA_BASE->MASK_TFR |= temp_bit; + } + if (GDMA_IT & GDMA_INT_Block) + { + GDMA_BASE->MASK_BLOCK |= temp_bit; + } + if (GDMA_IT & GDMA_INT_SrcTransfer) + { + GDMA_BASE->MASK_SRC_TRAN |= temp_bit; + } + if (GDMA_IT & GDMA_INT_DstTransfer) + { + GDMA_BASE->MASK_DST_TRAN |= temp_bit; + } + if (GDMA_IT & GDMA_INT_Error) + { + GDMA_BASE->MASK_ERR |= temp_bit; + } + } + else + { + /* Disable the selected DMA interrupts */ + temp_bit = BIT(GDMA_ChannelNum + 8); + if (GDMA_IT & GDMA_INT_Transfer) + { + GDMA_BASE->MASK_TFR = temp_bit; + } + if (GDMA_IT & GDMA_INT_Block) + { + GDMA_BASE->MASK_BLOCK = temp_bit; + } + if (GDMA_IT & GDMA_INT_SrcTransfer) + { + GDMA_BASE->MASK_SRC_TRAN = temp_bit; + } + if (GDMA_IT & GDMA_INT_DstTransfer) + { + GDMA_BASE->MASK_DST_TRAN = temp_bit; + } + if (GDMA_IT & GDMA_INT_Error) + { + GDMA_BASE->MASK_ERR = temp_bit; + } + } +} + +/** + * @brief Enables or disables the specified DMA Channelx interrupts. + * @param GDMA_Channelx: where x can be 0 to 3 to select the GDMA Channel. + * @param GDMA_IT: specifies the GDMA interrupts sources to be enabled + * or disabled. + * This parameter can be any combination of the following values: + * @arg GDMA_INT_Transfer: clear transfer complete interrupt + * @arg GDMA_INT_Block: clear Block transfer interrupt + * @arg GDMA_INT_SrcTransfer: clear SourceTransfer interrupt + * @arg GDMA_INT_DstTransfer: clear Destination Transfer interrupt + * @arg GDMA_INT_Error: clear Transfer error interrupt + * @param NewState: new state of the specified DMA interrupts. + * This parameter can be: ENABLE or DISABLE. + * @return None + */ +void GDMA_ClearINTPendingBit(uint8_t GDMA_ChannelNum, uint32_t GDMA_IT) +{ + uint32_t temp_bit = 0; + + /* Check the parameters */ + assert_param(IS_GDMA_ChannelNum(GDMA_ChannelNum)); + assert_param(IS_GDMA_CONFIG_IT(GDMA_IT)); + + /* clear the selected DMA interrupts */ + //temp_bit = BIT(GDMA_ChannelNum) | BIT(GDMA_ChannelNum + 8); + temp_bit = BIT(GDMA_ChannelNum); + + if (GDMA_IT & GDMA_INT_Transfer) + { + GDMA_BASE->CLEAR_TFR = temp_bit; + } + if (GDMA_IT & GDMA_INT_Block) + { + GDMA_BASE->CLEAR_BLOCK = temp_bit; + } + if (GDMA_IT & GDMA_INT_SrcTransfer) + { + GDMA_BASE->CLEAR_SRC_TRAN = temp_bit; + } + if (GDMA_IT & GDMA_INT_DstTransfer) + { + GDMA_BASE->CLEAR_DST_TRAN = temp_bit; + } + if (GDMA_IT & GDMA_INT_Error) + { + GDMA_BASE->CLEAR_ERR = temp_bit; + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_gpio.c b/src/mcu/peripheral/rtl876x_gpio.c new file mode 100644 index 0000000..2e9b18c --- /dev/null +++ b/src/mcu/peripheral/rtl876x_gpio.c @@ -0,0 +1,313 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_gpio.c +* @brief This file provides all the GPIO firmware functions. +* @details +* @author Yuan +* @date 2020-10-13 +* @version v1.0.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_gpio.h" + +#ifdef _IS_ASIC_ +#define GPIO_CLOCK_SOURCE (40000000) +#define GPIO_CLOCK_SOURCE_KHZ (40000) +#else +#define GPIO_CLOCK_SOURCE (20000000) +#define GPIO_CLOCK_SOURCE_KHZ (20000) +#endif + +/** + * @brief Deinitializes the GPIO peripheral registers to their default reset values. + * @param None. + * @retval None. + */ +void GPIO_DeInit(void) +{ + RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, DISABLE); +} + +/** + * @brief Initializes the GPIO peripheral according to the specified + * parameters in the GPIO_InitStruct. + * @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that + * contains the configuration information for the specified GPIO peripheral. + * @retval None + */ +void GPIO_Init(GPIO_InitTypeDef *GPIO_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin)); + assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode)); + assert_param(IS_GPIOIT_LEVEL_TYPE(GPIO_InitStruct->GPIO_ITTrigger)); + assert_param(IS_GPIOIT_POLARITY_TYPE(GPIO_InitStruct->GPIO_ITPolarity)); + assert_param(IS_GPIOIT_DEBOUNCE_TYPE(GPIO_InitStruct->GPIO_ITDebounce)); + + /* GPIO configure */ + if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_OUT) + { + GPIO->DATADIR |= GPIO_InitStruct->GPIO_Pin; + + if (GPIO_InitStruct->GPIO_ControlMode == GPIO_SOFTWARE_MODE) + { + /* Config GPIO control software mode */ + GPIO->DATASRC &= (~GPIO_InitStruct->GPIO_Pin); + } + else + { + /* Config GPIO hardware control mode */ + GPIO->DATASRC |= (GPIO_InitStruct->GPIO_Pin); + } + + } + else + { + /*Configure GPIO input mode */ + GPIO->DATADIR = GPIO->DATADIR & (~GPIO_InitStruct->GPIO_Pin); + + if (GPIO_InitStruct->GPIO_ITCmd == ENABLE) + { + + GPIO->INTMASK = ~GPIO_Pin_All; + + /* configure GPIO interrupt trigger type */ + if (GPIO_InitStruct->GPIO_ITTrigger == GPIO_INT_Trigger_LEVEL) + { + GPIO->INTBOTHEDGE &= ~GPIO_InitStruct->GPIO_Pin; + GPIO->INTTYPE = GPIO->INTTYPE & (~GPIO_InitStruct->GPIO_Pin); + + /* Level-sensitive synchronization enable register */ + GPIO->LSSYNC |= GPIO_InitStruct->GPIO_Pin; + } + else if (GPIO_InitStruct->GPIO_ITTrigger == GPIO_INT_Trigger_EDGE) + { + GPIO->INTBOTHEDGE &= ~GPIO_InitStruct->GPIO_Pin; + GPIO->INTTYPE = (GPIO->INTTYPE & (~GPIO_InitStruct->GPIO_Pin)) + | GPIO_InitStruct->GPIO_Pin; + } + else + { + GPIO->INTBOTHEDGE |= GPIO_InitStruct->GPIO_Pin; + } + + /* configure Interrupt polarity register */ + if (GPIO_InitStruct->GPIO_ITPolarity == GPIO_INT_POLARITY_ACTIVE_LOW) + { + GPIO->INTPOLARITY = GPIO->INTPOLARITY & (~GPIO_InitStruct->GPIO_Pin); + } + else + { + GPIO->INTPOLARITY = (GPIO->INTPOLARITY & (~GPIO_InitStruct->GPIO_Pin)) + | GPIO_InitStruct->GPIO_Pin; + } + /* Configure Debounce enable register */ + if (GPIO_InitStruct->GPIO_ITDebounce == GPIO_INT_DEBOUNCE_DISABLE) + { + GPIO->DEBOUNCE = GPIO->DEBOUNCE & (~GPIO_InitStruct->GPIO_Pin); + } + else + { + GPIO->DEBOUNCE = (GPIO->DEBOUNCE & (~GPIO_InitStruct->GPIO_Pin)) + | GPIO_InitStruct->GPIO_Pin; + +#ifdef _IS_ASIC_ + /* Config debounce time , default debounce DIV is 14*/ + GPIO_DBCLK_DIV = (((0xd) << 8) | (1 << 12)); + GPIO_DBCLK_DIV |= ((((GPIO_InitStruct->GPIO_DebounceTime) * (GPIO_CLOCK_SOURCE_KHZ) >> + (14)) - 1) & 0xff); +#else + /* Config debounce time , default debounce DIV is 13*/ + GPIO_DBCLK_DIV = (((0x3) << 10) | (1 << 12)); + GPIO_DBCLK_DIV |= ((((GPIO_InitStruct->GPIO_DebounceTime) * (GPIO_CLOCK_SOURCE_KHZ) >> + (13)) - 1) & 0xff); +#endif + } + + /* Configure Interrupt enable register */ + //GPIO->INTEN |= GPIO_InitStruct->GPIO_Pin; + } + } +} + +/** + * @brief Fills each GPIO_InitStruct member with its default value. + * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will + * be initialized. + * @retval None + */ +void GPIO_StructInit(GPIO_InitTypeDef *GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All; + GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStruct->GPIO_ITCmd = DISABLE; + GPIO_InitStruct->GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL; + GPIO_InitStruct->GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW; + GPIO_InitStruct->GPIO_ITDebounce = GPIO_INT_DEBOUNCE_DISABLE; + GPIO_InitStruct->GPIO_ControlMode = GPIO_SOFTWARE_MODE; + GPIO_InitStruct->GPIO_DebounceTime = 20; /* ms , can be 1~64 ms */ +} + +/** + * @brief enable the specified GPIO interrupt. + * @param GPIO_Pin_x: where x can be 0 or 31. + * @retval None + */ +void GPIO_INTConfig(uint32_t GPIO_Pin, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected GPIO pin interrupts */ + GPIO->INTEN |= GPIO_Pin; + } + else + { + /* Disable the selected GPIO pin interrupts */ + GPIO->INTEN &= ~GPIO_Pin; + } +} + +/** + * @brief clear the specified GPIO interrupt. + * @param GPIO_Pin_x: where x can be 0 or 31. + * @retval None + */ +void GPIO_ClearINTPendingBit(uint32_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIO->INTCLR = GPIO_Pin; +} + +/** + * @brief mask the specified GPIO interrupt. + * @param GPIO_Pin_x: where x can be 0 or 31. + * @retval None + */ +void GPIO_MaskINTConfig(uint32_t GPIO_Pin, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + GPIO->INTMASK |= GPIO_Pin; + } + else + { + GPIO->INTMASK &= ~(GPIO_Pin); + } +} + +/** + * \brief Get the GPIO_Pin through the given PAD num. + * \param[in] Pin_num: Pad num which can be from P0_0 to P5_2, please refer to rtl876x.h "Pin_Number" part. + * \return GPIO_Pin for GPIO initialization. + */ +uint32_t GPIO_GetPin(uint8_t Pin_num) +{ + /* Check the parameters */ + assert_param(IS_PIN_NUM(Pin_num)); + + if (Pin_num <= P3_6) + { + return BIT(Pin_num); + } +#if (IC_TYPE == IC_TYPE_BEE3) + else if (Pin_num == P4_0) + { + return BIT(13); + } + else if ((Pin_num <= P4_3) && (Pin_num >= P4_1)) + { + return BIT(Pin_num - 4); + } + else if ((Pin_num <= P5_2) && (Pin_num >= H_0)) + { + return BIT(Pin_num - 26); + } +#else + else if ((Pin_num <= P4_3) && (Pin_num >= P4_0)) + { + return BIT(Pin_num - 4); + } + else if ((Pin_num == H_0) || (Pin_num == H_1) || (Pin_num == H_2)) + { + return BIT(Pin_num - 11); + } +#endif + return 0xFF; +} + +/** + * \brief Get GPIOx(x is 0~31) value through the given pad. + * \param[in] Pin_num: Pad num which can be from P0_0 to P5_2, please refer to rtl876x.h "Pin_Number" part. + * \return GPIOx(x is 0~31) value. + */ +uint8_t GPIO_GetNum(uint8_t Pin_num) +{ + /* Check the parameters */ + assert_param(IS_PIN_NUM(Pin_num)); + + if (Pin_num <= P3_6) + { + return (Pin_num); + } +#if (IC_TYPE == IC_TYPE_BEE3) + else if (Pin_num == P4_0) + { + return 13; + } + else if ((Pin_num <= P4_3) && (Pin_num >= P4_1)) + { + return (Pin_num - 4); + } + else if ((Pin_num <= P5_2) && (Pin_num >= H_0)) + { + return (Pin_num - 26); + } +#else + else if ((Pin_num <= P4_3) && (Pin_num >= P4_0)) + { + return (Pin_num - 4); + } + else if ((Pin_num == H_0) || (Pin_num == H_1) || (Pin_num == H_2)) + { + return (Pin_num - 11); + } +#endif + + return 0xFF; +} + +/** + * \brief Enable GPIO debounce clock. + * \param[in] NewState: Disable or enable debounce clock. + * \return None. + */ +void GPIO_DBClkCmd(FunctionalState NewState) +{ + if (NewState != DISABLE) + { + GPIO_DBCLK_DIV |= BIT12; + } + else + { + GPIO_DBCLK_DIV &= ~BIT12; + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_i2c.c b/src/mcu/peripheral/rtl876x_i2c.c new file mode 100644 index 0000000..c05d533 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_i2c.c @@ -0,0 +1,622 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_i2c.c +* @brief This file provides all the I2C firmware functions. +* @details +* @author elliot chen +* @date 2015-04-29 +* @version v0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_i2c.h" + +uint32_t I2C_TimeOut = 0xFFFFF; + +/** + * @brief Initializes the I2Cx peripheral according to the specified + * parameters in the I2C_InitStruct. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param I2C_InitStruct: pointer to a I2C_InitTypeDef structure that + * contains the configuration information for the specified I2C peripheral. + * @retval None + */ +void I2C_Init(I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_I2C_CLOCK_SPEED(I2C_InitStruct->I2C_ClockSpeed)); + + volatile uint32_t I2CSrcClk; + + I2CSrcClk = I2C_InitStruct->I2C_Clock; + /* Disable I2C device before change configuration */ + I2Cx->IC_ENABLE &= ~0x0001; + + /* ------------------------------ Initialize I2C device ------------------------------*/ + if (I2C_DeviveMode_Master == I2C_InitStruct->I2C_DeviveMode) + { + /*configure I2C device mode which can be selected for master or slave*/ + I2Cx->IC_CON = I2C_InitStruct->I2C_DeviveMode | (I2C_InitStruct->I2C_AddressMode << 4) | BIT(5); + + /*set target address*/ + I2Cx->IC_TAR = (I2C_InitStruct->I2C_SlaveAddress & 0x3ff) + | (I2C_InitStruct->I2C_AddressMode << 12); + /*set SDA hold time in master mode*/ + I2Cx->IC_SDA_HOLD = 0x01; + + } + else + { + /* set to slave mode */ + I2Cx->IC_CON = (I2C_InitStruct->I2C_DeviveMode) | (I2C_InitStruct->I2C_AddressMode << 3); + /* set Ack in slave mode */ + I2Cx->IC_ACK_GENERAL_CALL &= I2C_InitStruct->I2C_Ack; + /* set slave address */ + I2Cx->IC_SAR = I2C_InitStruct->I2C_SlaveAddress; + /* set SDA hold time in slave mode */ + I2Cx->IC_SDA_HOLD = 0x08; + /* set SDA setup time delay only in slave transmitter mode(greater than 2) ,delay time:[(IC_SDA_SETUP - 1) * (ic_clk_period)]*/ + I2Cx->IC_SDA_SETUP = 0x02; + } + +#if 1 + /*set Tx empty level*/ + I2Cx->IC_TX_TL = I2C_InitStruct->I2C_TxThresholdLevel; + /*set Rx full level*/ + I2Cx->IC_RX_TL = I2C_InitStruct->I2C_RxThresholdLevel; +#endif + + /*------------------------------ configure I2C speed ------------------------------*/ + /*Configure I2C speed in standard mode*/ + if (I2C_InitStruct->I2C_ClockSpeed <= 100000) + { + I2Cx->IC_CON |= (0x3 << 1); + I2Cx->IC_CON &= 0xfffb; + /*configure I2C speed*/ + I2Cx->IC_SS_SCL_HCNT = 20 + (4000 * (I2CSrcClk / 10000)) / (I2C_InitStruct->I2C_ClockSpeed); + I2Cx->IC_SS_SCL_LCNT = 20 + (4700 * (I2CSrcClk / 10000)) / (I2C_InitStruct->I2C_ClockSpeed); + } + /*Configure I2C speed in fast mode*/ + else if (I2C_InitStruct->I2C_ClockSpeed <= 400000) + { + + I2Cx->IC_CON |= (0x3 << 1); + I2Cx->IC_CON &= 0xfffd; + if (I2C_InitStruct->I2C_ClockSpeed == 200000) + { + /*configure I2C speed*/ + I2Cx->IC_FS_SCL_HCNT = 32 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + I2Cx->IC_FS_SCL_LCNT = (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + } + else if (I2C_InitStruct->I2C_ClockSpeed == 400000) + { + /*configure I2C speed*/ + I2Cx->IC_FS_SCL_HCNT = 8 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + I2Cx->IC_FS_SCL_LCNT = 1 + (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + } + else + { + I2Cx->IC_FS_SCL_HCNT = 20 + (600 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + I2Cx->IC_FS_SCL_LCNT = (1300 * (I2CSrcClk / 10000) * 4) / (I2C_InitStruct->I2C_ClockSpeed); + } + } + /*Configure I2C speed in high mode*/ + else + { + if (I2C_InitStruct->I2C_ClockSpeed > 3400000) + { + I2C_InitStruct->I2C_ClockSpeed = 3400000; + } + + I2Cx->IC_CON |= (0x3 << 1); + /*configure I2C speed*/ + I2Cx->IC_HS_SCL_HCNT = 8 + (60 * (I2CSrcClk / 10000) * 30) / (I2C_InitStruct->I2C_ClockSpeed); + I2Cx->IC_HS_SCL_LCNT = 1 + (120 * (I2CSrcClk / 10000) * 30) / (I2C_InitStruct->I2C_ClockSpeed); + + } + + /*Config I2C dma mode*/ + I2Cx->IC_DMA_CR = ((I2C_InitStruct->I2C_RxDmaEn)\ + | ((I2C_InitStruct->I2C_TxDmaEn) << 1)); + + /*Config I2C waterlevel*/ + I2Cx->IC_DMA_RDLR = I2C_InitStruct->I2C_RxWaterlevel; + I2Cx->IC_DMA_TDLR = I2C_InitStruct->I2C_TxWaterlevel; + + I2Cx->IC_INTR_MASK = 0; +} + +/** + * @brief Deinitializes the I2Cx peripheral registers to their default reset values. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @retval None + */ +void I2C_DeInit(I2C_TypeDef *I2Cx) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /*Disable I2C IP*/ + if (I2Cx == I2C0) + { + RCC_PeriphClockCmd(APBPeriph_I2C0, APBPeriph_I2C0_CLOCK, DISABLE); + } + else if (I2Cx == I2C1) + { + RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, DISABLE); + } +} + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param I2C_InitStruct : pointer to a I2C_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2C_StructInit(I2C_InitTypeDef *I2C_InitStruct) +{ + I2C_InitStruct->I2C_Clock = 40000000; /* depend on clock divider */ + I2C_InitStruct->I2C_ClockSpeed = 400000; + I2C_InitStruct->I2C_DeviveMode = I2C_DeviveMode_Master; /* Master mode */ + I2C_InitStruct->I2C_AddressMode = I2C_AddressMode_7BIT; /* 7-bit address mode */ + I2C_InitStruct->I2C_SlaveAddress = 0; + I2C_InitStruct->I2C_Ack = I2C_Ack_Enable; + I2C_InitStruct->I2C_TxThresholdLevel = 0x00; /* tx fifo depth: 24 * 8bits */ + I2C_InitStruct->I2C_RxThresholdLevel = 0x00; /* rx fifo depth: 16 * 8bits */ + I2C_InitStruct->I2C_TxDmaEn = DISABLE; + I2C_InitStruct->I2C_RxDmaEn = DISABLE; + I2C_InitStruct->I2C_RxWaterlevel = 1; /* Best to equal GDMA Source MSize */ + I2C_InitStruct->I2C_TxWaterlevel = 15; /* Best to equal Tx fifo minus + GDMA Source MSize */ +} + + +/** + * @brief Enables or disables the specified I2C peripheral. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param NewState: new state of the I2Cx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2C_Cmd(I2C_TypeDef *I2Cx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C peripheral */ + I2Cx->IC_ENABLE |= 0x0001; + } + else + { + /* Disable the selected I2C peripheral */ + I2Cx->IC_ENABLE &= ~0x0001; + } +} + + +/** + * @brief Checks whether the last I2Cx abort status. + * @param I2Cx: where x can be 1 or 2 to select the I2C peripheral. + * @retval I2C_Status: the status of I2Cx. + */ +I2C_Status I2C_CheckAbortStatus(I2C_TypeDef *I2Cx) +{ + uint32_t abort_status = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Get abort status */ + abort_status = I2Cx->IC_TX_ABRT_SOURCE; + + if (abort_status & MS_ALL_ABORT) + { + /* Clear abort status */ + I2Cx->IC_CLR_TX_ABRT; + + /* Check abort type */ + if (abort_status & ABRT_TXDATA_NOACK) + { + return I2C_ABRT_TXDATA_NOACK; + } + + if (abort_status & ABRT_7B_ADDR_NOACK) + { + return I2C_ABRT_7B_ADDR_NOACK; + } + + if (abort_status & ARB_LOST) + { + return I2C_ARB_LOST; + } + + if (abort_status & ABRT_MASTER_DIS) + { + return I2C_ABRT_MASTER_DIS; + } + + if (abort_status & ABRT_10ADDR1_NOACK) + { + return I2C_ABRT_10ADDR1_NOACK; + } + + if (abort_status & ABRT_10ADDR2_NOACK) + { + return I2C_ABRT_10ADDR2_NOACK; + } + } + + return I2C_Success; +} + +/** + * @brief Send data in master mode through the I2Cx peripheral. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +I2C_Status I2C_MasterWrite(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len) +{ + uint16_t cnt = 0; + uint32_t time_out = I2C_TimeOut; + I2C_Status abort_status = I2C_Success; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* Write in the DR register the data to be sent */ + for (cnt = 0; cnt < len; cnt++) + { + if (cnt >= len - 1) + { + /*generate stop signal*/ + I2Cx->IC_DATA_CMD = (*pBuf++) | (1 << 9); + } + else + { + I2Cx->IC_DATA_CMD = *pBuf++; + } + + /* wait for flag of I2C_FLAG_TFNF */ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & (1 << 1)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + } + + return abort_status; +} + +/** + * @brief Read data in master mode through the I2Cx peripheral. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval None + */ +I2C_Status I2C_MasterRead(I2C_TypeDef *I2Cx, uint8_t *pBuf, uint16_t len) +{ + uint16_t cnt = 0; + uint32_t reg_value = 0; + uint32_t time_out = I2C_TimeOut; + I2C_Status abort_status = I2C_Success; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /* read in the DR register the data to be sent */ + for (cnt = 0; cnt < len; cnt++) + { + if (cnt >= len - 1) + { + /* generate stop singal */ + I2Cx->IC_DATA_CMD = (reg_value) | (0x0003 << 8); + } + else + { + I2Cx->IC_DATA_CMD = (reg_value) | (0x0001 << 8); + } + + /* read data */ + if (cnt > 0) + { + /* wait for I2C_FLAG_RFNE flag */ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & (1 << 3)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + *pBuf++ = (uint8_t)I2Cx->IC_DATA_CMD; + } + } + + /* wait for I2C_FLAG_RFNE flag */ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & (1 << 3)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + *pBuf = (uint8_t)I2Cx->IC_DATA_CMD; + + return abort_status; +} + +/** + * @brief Sends data and read data in master mode through the I2Cx peripheral.Attention:Read data with time out mechanism. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param Data: Byte to be transmitted.. + * @retval Actual length of read data + */ +I2C_Status I2C_RepeatRead(I2C_TypeDef *I2Cx, uint8_t *pWriteBuf, uint16_t Writelen, + uint8_t *pReadBuf, uint16_t Readlen) +{ + uint16_t cnt = 0; + uint32_t reg_value = 0; + uint32_t time_out = I2C_TimeOut; + I2C_Status abort_status = I2C_Success; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + + /*------------------------------ write data section ------------------------------*/ + /* write data in the IC_DATA_CMD register */ + for (cnt = 0; cnt < Writelen; cnt++) + { + I2Cx->IC_DATA_CMD = *pWriteBuf++; + + /*wait for I2C_FLAG_TFNF flag that Tx FIFO is not full*/ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & BIT(1)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + } + + /*------------------------------ read data section ------------------------------*/ + for (cnt = 0; cnt < Readlen; cnt++) + { + if (cnt >= Readlen - 1) + { + /*generate stop singal in last byte which to be sent*/ + I2Cx->IC_DATA_CMD = reg_value | BIT(8) | BIT(9); + } + else + { + I2Cx->IC_DATA_CMD = reg_value | BIT(8); + } + + /*read data */ + if (cnt > 0) + { + /*wait for I2C_FLAG_RFNE flag*/ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & BIT(3)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + *pReadBuf++ = (uint8_t)I2Cx->IC_DATA_CMD; + } + } + + /*read data*/ + time_out = I2C_TimeOut; + while (((I2Cx->IC_STATUS & BIT(3)) == 0) && (time_out != 0)) + { + /* Check abort status */ + abort_status = I2C_CheckAbortStatus(I2Cx); + if (abort_status != I2C_Success) + { + return abort_status; + } + + time_out--; + if (time_out == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + *pReadBuf = (uint8_t)I2Cx->IC_DATA_CMD; + + return abort_status; +} + +/** + * @brief mask the specified I2C interrupt. + * @param I2Cx: where x can be 0 or 1 + * @param I2C_INT + * This parameter can be one of the following values: + * @arg I2C_INT_GEN_CALL: Set only when a General Call address is received and it is acknowledged. + * @arg I2C_INT_START_DET: Indicates whether a START or RESTART condition has occurred on the I2C + interface regardless of whether I2C is operating in slave or master mode. + * @arg I2C_INT_STOP_DET: Indicates whether a STOP condition has occurred on the I2C interface regardless + of whether I2C is operating in slave or master mode + * @arg I2C_INT_ACTIVITY: This bit captures I2C activity and stays set until it is cleared. + * @arg I2C_INT_RX_DONE: When the I2C is acting as a slave-transmitter, this bit is set to 1 if the + master does not acknowledge a transmitted byte. This occurs on the last byte of + the transmission, indicating that the transmission is done. + * @arg I2C_INT_TX_ABRT: This bit indicates if I2C as an I2C transmitter, is unable to complete the + intended actions on the contents of the transmit FIFO. + * @arg I2C_INT_RD_REQ: This bit is set to 1 when acting as a slave and another I2C master + is attempting to read data. + * @arg I2C_INT_TX_EMPTY: This bit is set to 1 when the transmit buffer is at or below the threshold value set + in the IC_TX_TL register. + * @arg I2C_INT_TX_OVER: Set during transmit if the transmit buffer is filled to IC_TX_BUFFER_DEPTH and + the processor attempts to issue another I2C command. + * @arg I2C_INT_RX_FULL: Set when the receive buffer reaches or goes above the RX_TL threshold in the + IC_RX_TL register + * @arg I2C_INT_RX_OVER: Set if the receive buffer is completely filled to IC_RX_BUFFER_DEPTH and an + additional byte is received from an external I2C device. + * @arg I2C_INT_RX_UNDER: Set if the processor attempts to read the receive buffer when it is empty by reading. + * @retval None. + */ +void I2C_INTConfig(I2C_TypeDef *I2Cx, uint16_t I2C_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(I2C_GET_INT(I2C_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected I2C interrupts */ + I2Cx->IC_INTR_MASK |= I2C_INT; + } + else + { + /* Disable the selected I2C interrupts */ + I2Cx->IC_INTR_MASK &= (uint16_t)~I2C_INT; + } +} + +/** + * @brief clear the specified I2C interrupt. + * @param I2Cx: where x can be 0 or 1 + * @retval None. + */ +void I2C_ClearINTPendingBit(I2C_TypeDef *I2Cx, uint16_t I2C_IT) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_PERIPH(I2Cx)); + assert_param(I2C_GET_INT(I2C_IT)); + + switch (I2C_IT) + { + case I2C_INT_RX_UNDER: + { + I2Cx->IC_CLR_RX_UNDER; + break; + } + case I2C_INT_RX_OVER: + { + I2Cx->IC_CLR_RX_OVER; + break; + } + case I2C_INT_TX_OVER: + { + I2Cx->IC_CLR_TX_OVER; + break; + } + case I2C_INT_RD_REQ: + { + I2Cx->IC_CLR_RD_REQ; + break; + } + case I2C_INT_TX_ABRT: + { + I2Cx->IC_CLR_TX_ABRT; + break; + } + case I2C_INT_RX_DONE: + { + I2Cx->IC_CLR_RX_DONE; + break; + } + case I2C_INT_ACTIVITY: + { + I2Cx->IC_CLR_ACTIVITY; + break; + } + case I2C_INT_STOP_DET: + { + I2Cx->IC_CLR_STOP_DET; + break; + } + case I2C_INT_START_DET: + { + I2Cx->IC_CLR_START_DET; + break; + } + case I2C_INT_GEN_CALL: + { + I2Cx->IC_CLR_GEN_CALL; + break; + } + default: + { + break; + } + } +} + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_i2s.c b/src/mcu/peripheral/rtl876x_i2s.c new file mode 100644 index 0000000..48ccf86 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_i2s.c @@ -0,0 +1,226 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_i2s.c +* @brief This file provides all the I2S interface firmware functions. +* @details +* @author elliot chen +* @date 2020-11-30 +* @version v1.0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_i2s.h" + +/** + * @brief Initializes the I2S peripheral according to the specified + * parameters in the I2S_InitStruct + * @param I2S: selected I2S peripheral. + * @param I2S_InitStruct: pointer to a I2S_InitTypeDef structure that + * contains the configuration information for the specified I2S peripheral + * @retval None + */ +void I2S_Init(I2S_TypeDef *I2Sx, I2S_InitTypeDef *I2S_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_I2S_CLK_SOURCE(I2S_InitStruct->I2S_ClockSource)); + assert_param(IS_I2S_DEVICE_MODE(I2S_InitStruct->I2S_DeviceMode)); + assert_param(IS_I2S_CHANNEL_TYPE(I2S_InitStruct->I2S_ChannelType)); + assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat)); + assert_param(IS_I2S_DATA_WIDTH(I2S_InitStruct->I2S_DataWidth)); + assert_param(IS_I2S_MCLK_OUTPUT_TYPE(I2S_InitStruct->I2S_MCLKOutput)); + assert_param(IS_I2S_DMA_CMD(I2S_InitStruct->I2S_DMACmd)); + + /* Reset I2S module */ + I2Sx->CTRL0 |= I2S_RESET_MSK; + I2Sx->CTRL0 &= I2S_RESET_CLR; + + /* Configure BCLK parameters */ + I2Sx->BCLK_DIV = I2S_InitStruct->I2S_BClockMi | (I2S_InitStruct->I2S_BClockNi << I2S_BCLK_NI_POS) | + I2S_MI_NI_UPDATE_MSK; + + /* Configure I2S initialization parameters */ + I2Sx->CTRL0 = I2S_InitStruct->I2S_MCLKOutput | I2S_InitStruct->I2S_TxChSequence | I2S_RX_DISABLE_MSK + | \ + I2S_InitStruct->I2S_RxBitSequence | I2S_InitStruct->I2S_TxBitSequence | \ + I2S_InitStruct->I2S_RxChSequence | I2S_TX_DISABLE_MSK | \ + I2S_InitStruct->I2S_DataWidth | I2S_InitStruct->I2S_ChannelType | \ + I2S_InitStruct->I2S_DataFormat | I2S_InitStruct->I2S_DeviceMode | I2S_InitStruct->I2S_DMACmd; + + /* Configure I2S Clock Source parameters */ + I2Sx->CTRL1 = I2S_InitStruct->I2S_ClockSource | I2S_CLR_RX_ERR_CNT_MSK | \ + I2S_CLR_TX_ERR_CNT_MSK | I2S_FRAME_SYNC_OFFSET_DEFAULT; + /* Clear error counter */ + I2Sx->CTRL1 &= I2S_CLR_RX_ERR_CNT_CLR & I2S_CLR_TX_ERR_CNT_CLR; + + /* Configure GDMA burst size */ + I2Sx->DMA_TRDLR = (I2S_InitStruct->I2S_RxWaterlevel << I2S_RX_DMA_BURST_SIZE_POS) | \ + (I2S_InitStruct->I2S_TxWaterlevel << I2S_TX_DMA_BURST_SIZE_POS); +} + +/** + * @brief Deinitializes the I2S peripheral registers to their default values. + * @param None. + * @retval None + */ +void I2S_DeInit(I2S_TypeDef *I2Sx) +{ + if (I2Sx == I2S0) + { + RCC_PeriphClockCmd(APBPeriph_I2S0, APBPeriph_I2S0_CLOCK, DISABLE); + } +} + +/** + * @brief Fills each I2S_InitStruct member with its default value. + * @param I2S_InitStruct: pointer to an I2S_InitTypeDef structure which will be initialized. + * @retval None + */ +void I2S_StructInit(I2S_InitTypeDef *I2S_InitStruct) +{ + I2S_InitStruct->I2S_ClockSource = I2S_CLK_40M; + I2S_InitStruct->I2S_BClockMi = 0x271;/* I2S_BClockNi = 0x10; + I2S_InitStruct->I2S_DeviceMode = I2S_DeviceMode_Master; + I2S_InitStruct->I2S_ChannelType = I2S_Channel_Mono; + I2S_InitStruct->I2S_TxChSequence = I2S_TX_CH_L_R; + I2S_InitStruct->I2S_RxChSequence = I2S_RX_CH_L_R; + I2S_InitStruct->I2S_DataFormat = I2S_Mode; + I2S_InitStruct->I2S_TxBitSequence = I2S_TX_MSB_First; + I2S_InitStruct->I2S_RxBitSequence = I2S_RX_MSB_First; + I2S_InitStruct->I2S_DataWidth = I2S_Width_16Bits; + I2S_InitStruct->I2S_MCLKOutput = I2S_MCLK_128fs; + I2S_InitStruct->I2S_DMACmd = I2S_DMA_ENABLE; + I2S_InitStruct->I2S_TxWaterlevel = 1; + I2S_InitStruct->I2S_RxWaterlevel = 1; +} + +/** + * @brief Enable or disable the selected I2S mode. + * @param I2S: selected I2S peripheral. + * @param mode: selected I2S operation mode. + * This parameter can be the following values: + * @arg I2S_MODE_TX: transmission mode. + * @arg I2S_MODE_RX: receiving mode. + * @param NewState: new state of the operation mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_Cmd(I2S_TypeDef *I2Sx, uint32_t mode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_ALL_PERIPH(I2Sx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + if (mode & I2S_MODE_TX) + { + I2Sx->CTRL0 &= I2S_TX_DISABLE_CLR; + } + + if (mode & I2S_MODE_RX) + { + I2Sx->CTRL0 &= I2S_RX_DISABLE_CLR; + } + I2Sx->CTRL0 |= mode; + } + else + { + if (mode & I2S_MODE_TX) + { + I2Sx->CTRL0 |= I2S_TX_DISABLE_MSK; + } + + if (mode & I2S_MODE_RX) + { + I2Sx->CTRL0 |= I2S_RX_DISABLE_MSK; + } + I2Sx->CTRL0 &= ~(mode); + } +} + +/** + * @brief Enable or disable the specified I2S interrupts. + * @param I2S_INT: specifies the I2S interrupts sources to be enable or disable. + * This parameter can be the following values: + * @arg I2S_INT_TX_IDLE: Transmit idle interrupt. + * @arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt. + * @arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt. + * @arg I2S_INT_RF_FULL: Receive FIFO full interrupt. + * @arg I2S_INT_TF_FULL: Transmit FIFO full interrupt. + * @arg I2S_INT_RX_READY: Ready to receive interrupt. + * @arg I2S_INT_TX_READY: Ready to transmit interrupt. + * @param NewState: new state of the specified I2S interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void I2S_INTConfig(I2S_TypeDef *I2Sx, uint32_t I2S_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_I2S_INT_CONFIG(I2S_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + I2Sx->CTRL1 |= I2S_INT; + } + else + { + I2Sx->CTRL1 &= ~(I2S_INT); + } +} + +/** + * @brief Get the specified I2S flag status. + * @param I2S_INT: the specified I2S interrupt. + * This parameter can be one of the following values: + * This parameter can be the following values: + * @arg I2S_INT_TX_IDLE: Transmit idle interrupt. + * @arg I2S_INT_RF_EMPTY: Receive FIFO empty interrupt. + * @arg I2S_INT_TF_EMPTY: Transmit FIFO empty interrupt. + * @arg I2S_INT_RF_FULL: Receive FIFO full interrupt. + * @arg I2S_INT_TF_FULL: Transmit FIFO full interrupt. + * @arg I2S_INT_RX_READY: Ready to receive interrupt. + * @arg I2S_INT_TX_READY: Ready to transmit interrupt. + * @retval The new state of LCD_FLAG (SET or RESET). + */ +ITStatus I2S_GetINTStatus(I2S_TypeDef *I2Sx, uint32_t I2S_INT) +{ + ITStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_I2S_INT_CONFIG(I2S_INT)); + + if (I2Sx->SR & (I2S_INT >> I2S_READY_TO_TX_POS)) + { + bit_status = SET; + } + + /* Return the I2S_INT status */ + return bit_status; +} + +/** + * @brief Clears the I2S interrupt pending bits. + * @param I2S_CLEAR_INT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg I2S_CLEAR_INT_RX_READY: Clear ready to receive interrupt. + * @arg I2S_CLEAR_INT_TX_READY: Clear ready to transmit interrupt. + * @retval None + */ +void I2S_ClearINTPendingBit(I2S_TypeDef *I2Sx, uint32_t I2S_CLEAR_INT) +{ + /* Check the parameters */ + assert_param(IS_I2S_INT_CONFIG(I2S_CLEAR_INT)); + + I2Sx->DSP_INT_CR |= I2S_CLEAR_INT; + I2Sx->DSP_INT_CR &= ~I2S_CLEAR_INT; +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_io_dlps.c b/src/mcu/peripheral/rtl876x_io_dlps.c new file mode 100644 index 0000000..1851f54 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_io_dlps.c @@ -0,0 +1,1677 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_io_dlps.c +* @brief This file provides all the IO DLPS control firmware functions. +* @details +* @author +* @date 2020-06-02 +* @version v1.0 +********************************************************************************************************* +*/ + +#include +#include "rtl876x_io_dlps.h" +#include "rtl876x_nvic.h" +#include "rtl876x_pinmux.h" +#include "rtl876x_rcc.h" +#include "app_section.h" +#include "board.h" +#include "dlps.h" +#include "otp.h" +#include "platform_autoconf.h" +#include "trace.h" +#include "test_mode.h" + +/*============================================================================* + * IO DLPS + *============================================================================*/ + +/********************************************** ********************************************************/ +/**************************************** [PINMUX DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +__STATIC_INLINE void Pinmux_DLPS_Enter(void); +__STATIC_INLINE void Pinmux_DLPS_Exit(void); + +volatile uint32_t +Pinmux_StoreReg[10]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief PINMUX enter dlps callback function(Save PINMUX register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void Pinmux_DLPS_Enter(void) DATA_RAM_FUNCTION; +void Pinmux_DLPS_Enter(void) +{ + uint8_t i = 0; + + for (i = 0; i < 10; i++) + { + Pinmux_StoreReg[i] = PINMUX->CFG[i]; + } + + return; +} + +/** + * @brief PINMUX exit dlps callback function(Resume PINMUX register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void Pinmux_DLPS_Exit(void) DATA_RAM_FUNCTION; +void Pinmux_DLPS_Exit(void) +{ + uint8_t i; + + for (i = 0; i < 10; i++) + { + PINMUX->CFG[i] = Pinmux_StoreReg[i]; + } + + return; +} + +/********************************************** ********************************************************/ +/**************************************** [ADC DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +#if USE_ADC_DLPS +__STATIC_INLINE void ADC_DLPS_Enter(void); +__STATIC_INLINE void ADC_DLPS_Exit(void); + +volatile uint32_t +ADC_StoreReg[15]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief ADC enter dlps callback function(Save ADC register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void ADC_DLPS_Enter(void) DATA_RAM_FUNCTION; +void ADC_DLPS_Enter(void) +{ + /*Open 10M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28; + + PERIPH->PERI_FUNC1_EN |= (1 << 0); + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_ADC_EN_Msk | SYSBLK_SLPCK_ADC_EN_Msk); + + ADC_StoreReg[0] = ADC->CR; //0x04 + ADC_StoreReg[1] = ADC->SCHCR; //0x08 + ADC_StoreReg[2] = ADC->INTCR; //0x0C + ADC_StoreReg[3] = ADC->SCHTAB0; //0x10 + ADC_StoreReg[4] = ADC->SCHTAB1; //0x14 + ADC_StoreReg[5] = ADC->SCHTAB2; //0x18 + ADC_StoreReg[6] = ADC->SCHTAB3; //0x1C + ADC_StoreReg[7] = ADC->SCHTAB4; //0x20 + ADC_StoreReg[8] = ADC->SCHTAB5; //0x24 + ADC_StoreReg[9] = ADC->SCHTAB6; //0x28 + ADC_StoreReg[10] = ADC->SCHTAB7; //0x2C + ADC_StoreReg[11] = ADC->PWRDLY; + ADC_StoreReg[12] = ADC->DATCLK; + ADC_StoreReg[13] = ADC->ANACTL; + ADC_StoreReg[14] = ADC->SAMTIM; + + uint16_t reg_value = 0; + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value & (~0x04)); + + return; +} + +/** + * @brief ADC exit dlps callback function(Resume ADC register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void ADC_DLPS_Exit(void) DATA_RAM_FUNCTION; +void ADC_DLPS_Exit(void) +{ + /*Open 10M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28; + + PERIPH->PERI_FUNC1_EN |= (1 << 0); + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_ADC_EN_Msk | SYSBLK_SLPCK_ADC_EN_Msk); + +#if 0 + //Todo + ADC->PWRDLY = ADC_StoreReg[10]; + ADC->CR = (ADC_StoreReg[0] & (~((uint32_t)0x03))); + ADC->SCHTAB0 = ADC_StoreReg[3]; + ADC->SCHTAB1 = ADC_StoreReg[4]; + ADC->SCHTAB2 = ADC_StoreReg[5]; + ADC->SCHTAB3 = ADC_StoreReg[6]; + ADC->SCHTAB4 = ADC_StoreReg[7]; + ADC->SCHTAB5 = ADC_StoreReg[8]; + ADC->SCHTAB6 = ADC_StoreReg[9]; + ADC->SCHCR = ADC_StoreReg[1]; + ADC->INTCR = (ADC_StoreReg[2] & 0x1F); +#else + /*Disable all interrupt.*/ + ADC->INTCR &= (~0x1f); + + /* Set power mode first */ + ADC->PWRDLY = ADC_StoreReg[11]; + + /* Disable schedule table */ + ADC->SCHCR &= (~0xffff); + + ADC->SCHTAB0 = ADC_StoreReg[3]; + ADC->SCHTAB1 = ADC_StoreReg[4]; + ADC->SCHTAB2 = ADC_StoreReg[5]; + ADC->SCHTAB3 = ADC_StoreReg[6]; + ADC->SCHTAB4 = ADC_StoreReg[7]; + ADC->SCHTAB5 = ADC_StoreReg[8]; + ADC->SCHTAB6 = ADC_StoreReg[9]; + ADC->SCHTAB7 = ADC_StoreReg[10]; + ADC->SCHCR = ADC_StoreReg[1]; + ADC->CR = (ADC_StoreReg[0] & (~((uint32_t)0x03))); + ADC->DATCLK = ADC_StoreReg[12]; + ADC->ANACTL = ADC_StoreReg[13]; + ADC->SAMTIM = ADC_StoreReg[14]; + + /*Clear ADC FIFO */ + ADC->CR |= BIT26; + /* Clear all interrupt */ + ADC->INTCR |= (0x1f << 8); + + /* Restore specify interrupt */ + ADC->INTCR = ADC_StoreReg[2]; + +#endif + + uint16_t reg_value = 0; + reg_value = btaon_fast_read_safe(0x110); + btaon_fast_write_safe(0x110, reg_value | 0x04); + + return; +} + +#endif + +/********************************************** ********************************************************/ +/**************************************** [CODEC DLPS] ************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_CODEC_DLPS + +volatile uint32_t CODEC_StoreReg[12]; + +/** + * @brief CODEC enter dlps callback function(Save CODEC register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CODEC_DLPS_Enter(void) DATA_RAM_FUNCTION; +void CODEC_DLPS_Enter(void) +{ + /* Enable codec function and clock */ + PERIPH->PERI_BD_FUNC0_EN |= (1 << 0) | (1 << 4); + + CODEC_StoreReg[0] = CODEC->CR0; + CODEC_StoreReg[1] = CODEC->ADC0_CTRL0; + CODEC_StoreReg[2] = CODEC->ADC0_CTRL1; + CODEC_StoreReg[3] = CODEC->ANA_CR1; + CODEC_StoreReg[4] = CODEC->CLK_CR1; + CODEC_StoreReg[5] = CODEC->CLK_CR2; + CODEC_StoreReg[6] = CODEC->CLK_CR3; + CODEC_StoreReg[7] = CODEC->I2S_CTRL; + CODEC_StoreReg[8] = CODEC_ANA->ANA_CR0; + CODEC_StoreReg[9] = CODEC_ANA->ANA_CR1; + CODEC_StoreReg[10] = CODEC_ANA->ANA_CR2; +} + +/** + * @brief CODEC exit dlps callback function(Resume CODEC register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CODEC_DLPS_Exit(void) DATA_RAM_FUNCTION; +void CODEC_DLPS_Exit(void) +{ + /* Enable codec function and clock */ + PERIPH->PERI_BD_FUNC0_EN |= (1 << 0) | (1 << 4); + + /* Initialize CODEC */ + if ((CODEC_StoreReg[3] & 0x900) == 0x900) + { + /* Configure AMIC parameters */ + CODEC->CR0 = CODEC_StoreReg[0]; + } + + CODEC->ADC0_CTRL0 = CODEC_StoreReg[1]; + CODEC->ADC0_CTRL1 = CODEC_StoreReg[2]; + CODEC->ANA_CR1 = CODEC_StoreReg[3]; + CODEC->CLK_CR1 = CODEC_StoreReg[4]; + CODEC->CLK_CR2 = CODEC_StoreReg[5]; + CODEC->CLK_CR3 = CODEC_StoreReg[6]; + CODEC->I2S_CTRL = CODEC_StoreReg[7]; + CODEC_ANA->ANA_CR0 = CODEC_StoreReg[8]; + CODEC_ANA->ANA_CR1 = CODEC_StoreReg[9]; + CODEC_ANA->ANA_CR2 = CODEC_StoreReg[10]; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [GPIO DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_GPIO_DLPS + +__STATIC_INLINE void GPIO_DLPS_Enter(void); +__STATIC_INLINE void GPIO_DLPS_Exit(void); + +volatile uint32_t +GPIO_StoreReg[10]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief GPIO enter dlps callback function(Save GPIO register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void GPIO_DLPS_Enter(void) DATA_RAM_FUNCTION; +void GPIO_DLPS_Enter(void) +{ + PERIPH->PERI_FUNC1_EN |= BIT_PERI_GPIO_EN; + PERIPH->PERI_CLK_CTRL |= (BIT_SOC_ACTCK_GPIO_EN | SYSBLK_SLPCK_GPIO_EN_Msk); + + GPIO_StoreReg[0] = GPIO->DATAOUT; + GPIO_StoreReg[1] = GPIO->DATADIR; + GPIO_StoreReg[2] = GPIO->DATASRC; + GPIO_StoreReg[3] = GPIO->INTEN; + GPIO_StoreReg[4] = GPIO->INTMASK; + GPIO_StoreReg[5] = GPIO->INTTYPE; + GPIO_StoreReg[6] = GPIO->INTPOLARITY; + GPIO_StoreReg[7] = GPIO->DEBOUNCE; + GPIO_StoreReg[8] = *(__IO uint32_t *)(0x40000344UL); + GPIO_StoreReg[9] = GPIO->INTBOTHEDGE; + + return; +} + +/** + * @brief GPIO exit dlps callback function(Resume GPIO register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void GPIO_DLPS_Exit(void) DATA_RAM_FUNCTION; +void GPIO_DLPS_Exit(void) +{ + PERIPH->PERI_FUNC1_EN |= BIT_PERI_GPIO_EN; + PERIPH->PERI_CLK_CTRL |= (BIT_SOC_ACTCK_GPIO_EN | SYSBLK_SLPCK_GPIO_EN_Msk); + + GPIO->DATADIR = GPIO_StoreReg[1]; + GPIO->DATASRC = GPIO_StoreReg[2]; + GPIO->INTMASK = GPIO_StoreReg[4]; + GPIO->INTTYPE = GPIO_StoreReg[5]; + GPIO->INTPOLARITY = GPIO_StoreReg[6]; + GPIO->DEBOUNCE = GPIO_StoreReg[7]; + GPIO->DATAOUT = GPIO_StoreReg[0]; + GPIO->INTCLR = ~(GPIO_StoreReg[1]); + GPIO->INTEN = GPIO_StoreReg[3]; + *(__IO uint32_t *)(0x40000344UL) = GPIO_StoreReg[8]; + GPIO->INTBOTHEDGE = GPIO_StoreReg[9]; + + return; +} +#endif /* USE_GPIO_DLPS */ + +/********************************************** ********************************************************/ +/**************************************** [I2C0 DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_I2C0_DLPS +__STATIC_INLINE void I2C0_DLPS_Enter(void); +__STATIC_INLINE void I2C0_DLPS_Exit(void); + +volatile uint32_t +I2C0_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief I2C0 enter dlps callback function(Save I2C0 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2C0_DLPS_Enter(void) DATA_RAM_FUNCTION; +void I2C0_DLPS_Enter(void) +{ + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C0_EN_Msk | SYSBLK_SLPCK_I2C0_EN_Msk); + PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C0_EN_Msk; + + I2C0_StoreReg[0] = I2C0->IC_CON; + I2C0_StoreReg[1] = I2C0->IC_TAR; + I2C0_StoreReg[2] = I2C0->IC_SAR; + I2C0_StoreReg[3] = I2C0->IC_HS_MADDR; + + I2C0_StoreReg[4] = I2C0->IC_SS_SCL_HCNT; + I2C0_StoreReg[5] = I2C0->IC_SS_SCL_LCNT; + I2C0_StoreReg[6] = I2C0->IC_FS_SCL_HCNT; + I2C0_StoreReg[7] = I2C0->IC_FS_SCL_LCNT; + I2C0_StoreReg[8] = I2C0->IC_HS_SCL_HCNT; + I2C0_StoreReg[9] = I2C0->IC_HS_SCL_LCNT; + + I2C0_StoreReg[10] = I2C0->IC_INTR_MASK; + I2C0_StoreReg[11] = I2C0->IC_RX_TL; + I2C0_StoreReg[12] = I2C0->IC_TX_TL; + I2C0_StoreReg[13] = I2C0->IC_ENABLE; + I2C0_StoreReg[14] = I2C0->IC_SDA_HOLD; + I2C0_StoreReg[15] = I2C0->IC_SLV_DATA_NACK_ONLY; + I2C0_StoreReg[16] = I2C0->IC_DMA_CR; + I2C0_StoreReg[17] = I2C0->IC_DMA_TDLR; + I2C0_StoreReg[18] = I2C0->IC_DMA_RDLR; + + I2C0_StoreReg[19] = I2C0->IC_SDA_SETUP; +} + +/** + * @brief I2C0 exit dlps callback function(Resume I2C0 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2C0_DLPS_Exit(void) DATA_RAM_FUNCTION; +void I2C0_DLPS_Exit(void) +{ + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C0_EN_Msk | SYSBLK_SLPCK_I2C0_EN_Msk); + PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C0_EN_Msk; + + I2C0->IC_CON = I2C0_StoreReg[0]; + I2C0->IC_TAR = I2C0_StoreReg[1]; + I2C0->IC_SAR = I2C0_StoreReg[2]; + I2C0->IC_HS_MADDR = I2C0_StoreReg[3]; + + I2C0->IC_SS_SCL_HCNT = I2C0_StoreReg[4]; + I2C0->IC_SS_SCL_LCNT = I2C0_StoreReg[5]; + I2C0->IC_FS_SCL_HCNT = I2C0_StoreReg[6]; + I2C0->IC_FS_SCL_LCNT = I2C0_StoreReg[7]; + I2C0->IC_HS_SCL_HCNT = I2C0_StoreReg[8]; + I2C0->IC_HS_SCL_LCNT = I2C0_StoreReg[9]; + + I2C0->IC_INTR_MASK = I2C0_StoreReg[10]; + I2C0->IC_RX_TL = I2C0_StoreReg[11]; + I2C0->IC_TX_TL = I2C0_StoreReg[12]; + I2C0->IC_SDA_HOLD = I2C0_StoreReg[14]; + I2C0->IC_SLV_DATA_NACK_ONLY = I2C0_StoreReg[15]; + I2C0->IC_DMA_CR = I2C0_StoreReg[16]; + I2C0->IC_DMA_TDLR = I2C0_StoreReg[17]; + I2C0->IC_DMA_RDLR = I2C0_StoreReg[18]; + I2C0->IC_SDA_SETUP = I2C0_StoreReg[19]; + + I2C0->IC_ENABLE = I2C0_StoreReg[13]; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [I2C1 DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_I2C1_DLPS +__STATIC_INLINE void I2C1_DLPS_Enter(void); +__STATIC_INLINE void I2C1_DLPS_Exit(void); + +volatile uint32_t +I2C1_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief I2C1 enter dlps callback function(Save I2C1 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2C1_DLPS_Enter(void) DATA_RAM_FUNCTION; +void I2C1_DLPS_Enter(void) +{ + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C1_EN_Msk | SYSBLK_SLPCK_I2C1_EN_Msk); + PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C1_EN_Msk; + + I2C1_StoreReg[0] = I2C1->IC_CON; + I2C1_StoreReg[1] = I2C1->IC_TAR; + I2C1_StoreReg[2] = I2C1->IC_SAR; + I2C1_StoreReg[3] = I2C1->IC_HS_MADDR; + + I2C1_StoreReg[4] = I2C1->IC_SS_SCL_HCNT; + I2C1_StoreReg[5] = I2C1->IC_SS_SCL_LCNT; + I2C1_StoreReg[6] = I2C1->IC_FS_SCL_HCNT; + I2C1_StoreReg[7] = I2C1->IC_FS_SCL_LCNT; + I2C1_StoreReg[8] = I2C1->IC_HS_SCL_HCNT; + I2C1_StoreReg[9] = I2C1->IC_HS_SCL_LCNT; + + I2C1_StoreReg[10] = I2C1->IC_INTR_MASK; + I2C1_StoreReg[11] = I2C1->IC_RX_TL; + I2C1_StoreReg[12] = I2C1->IC_TX_TL; + I2C1_StoreReg[13] = I2C1->IC_ENABLE; + I2C1_StoreReg[14] = I2C1->IC_SDA_HOLD; + I2C1_StoreReg[15] = I2C1->IC_SLV_DATA_NACK_ONLY; + I2C1_StoreReg[16] = I2C1->IC_DMA_CR; + I2C1_StoreReg[17] = I2C1->IC_DMA_TDLR; + I2C1_StoreReg[18] = I2C1->IC_DMA_RDLR; + + I2C1_StoreReg[19] = I2C1->IC_SDA_SETUP; +} + +/** + * @brief I2C1 exit dlps callback function(Resume I2C1 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2C1_DLPS_Exit(void) DATA_RAM_FUNCTION; +void I2C1_DLPS_Exit(void) +{ + PERIPH->PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_I2C1_EN_Msk | SYSBLK_SLPCK_I2C1_EN_Msk); + PERIPH->PERI_FUNC0_EN |= SYSBLK_I2C1_EN_Msk; + + I2C1->IC_CON = I2C1_StoreReg[0]; + I2C1->IC_TAR = I2C1_StoreReg[1]; + I2C1->IC_SAR = I2C1_StoreReg[2]; + I2C1->IC_HS_MADDR = I2C1_StoreReg[3]; + + I2C1->IC_SS_SCL_HCNT = I2C1_StoreReg[4]; + I2C1->IC_SS_SCL_LCNT = I2C1_StoreReg[5]; + I2C1->IC_FS_SCL_HCNT = I2C1_StoreReg[6]; + I2C1->IC_FS_SCL_LCNT = I2C1_StoreReg[7]; + I2C1->IC_HS_SCL_HCNT = I2C1_StoreReg[8]; + I2C1->IC_HS_SCL_LCNT = I2C1_StoreReg[9]; + + I2C1->IC_INTR_MASK = I2C1_StoreReg[10]; + I2C1->IC_RX_TL = I2C1_StoreReg[11]; + I2C1->IC_TX_TL = I2C1_StoreReg[12]; + I2C1->IC_SDA_HOLD = I2C1_StoreReg[14]; + I2C1->IC_SLV_DATA_NACK_ONLY = I2C1_StoreReg[15]; + I2C1->IC_DMA_CR = I2C1_StoreReg[16]; + I2C1->IC_DMA_TDLR = I2C1_StoreReg[17]; + I2C1->IC_DMA_RDLR = I2C1_StoreReg[18]; + I2C1->IC_SDA_SETUP = I2C1_StoreReg[19]; + + I2C1->IC_ENABLE = I2C1_StoreReg[13]; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [I2S0 DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_I2S0_DLPS + +volatile uint32_t I2S0_StoreReg[4]; + +/** + * @brief I2S0 enter dlps callback function(Save I2S0 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2S0_DLPS_Enter(void) DATA_RAM_FUNCTION; +void I2S0_DLPS_Enter(void) +{ + PERIPH->PERI_BD_FUNC0_EN |= BIT(1) | BIT(5) | BIT(8); + + I2S0_StoreReg[0] = I2S0->BCLK_DIV; + I2S0_StoreReg[1] = I2S0->CTRL0; + I2S0_StoreReg[2] = I2S0->CTRL1; + I2S0_StoreReg[3] = I2S0->DMA_TRDLR; +} + +/** + * @brief I2S0 exit dlps callback function(Resume I2S0 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void I2S0_DLPS_Exit(void) DATA_RAM_FUNCTION; +void I2S0_DLPS_Exit(void) +{ + PERIPH->PERI_BD_FUNC0_EN |= BIT(1) | BIT(5) | BIT(8); + + /* Reset I2S0 module */ + I2S0->CTRL0 |= 1 << 0; + I2S0->CTRL0 &= ~(1 << 0); + + /* Initialize I2S0 */ + I2S0->BCLK_DIV = I2S0_StoreReg[0]; + I2S0->CTRL1 = I2S0_StoreReg[2]; + I2S0->DMA_TRDLR = I2S0_StoreReg[3]; + I2S0->CTRL0 = I2S0_StoreReg[1]; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [IR DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +#if USE_IR_DLPS +__STATIC_INLINE void IR_DLPS_Enter(void); +__STATIC_INLINE void IR_DLPS_Exit(void); + +volatile uint32_t IR_StoreReg[6]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief IR enter dlps callback function(Save IR register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void IR_DLPS_Enter(void) DATA_RAM_FUNCTION; +void IR_DLPS_Enter(void) +{ + PERIPH->PERI_FUNC0_EN |= (1 << 10); + PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_IR_EN_Msk | SYSBLK_SLPCK_IR_EN_Msk); + + IR_StoreReg[0] = IR->CLK_DIV; + IR_StoreReg[1] = IR->TX_CONFIG; + IR_StoreReg[2] = IR->RX_CONFIG; + IR_StoreReg[3] = IR->RX_CNT_INT_SEL; + + return; +} + +/** + * @brief IR exit dlps callback function(Resume IR register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void IR_DLPS_Exit(void) DATA_RAM_FUNCTION; +void IR_DLPS_Exit(void) +{ + PERIPH->PERI_FUNC0_EN |= (1 << 10); + PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_IR_EN_Msk | SYSBLK_SLPCK_IR_EN_Msk); + + IR->CLK_DIV = IR_StoreReg[0]; + if (IR_StoreReg[1] & BIT31) + { + /* RX MODE */ + IR->TX_CONFIG = IR_StoreReg[1]; + IR->RX_CONFIG = IR_StoreReg[2]; + IR->RX_CNT_INT_SEL = IR_StoreReg[3]; + } + else + { + /* TX MODE */ + IR->TX_CONFIG = IR_StoreReg[1]; + /* If IR TX mode is idle, must write one data firstly */ + IR->TX_FIFO = 0; + } + + return; +} + +#endif + +/********************************************** ********************************************************/ +/**************************************** [KEYSCAN DLPS] ***********************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_KEYSCAN_DLPS + +__STATIC_INLINE void KeyScan_DLPS_Enter(void); +__STATIC_INLINE void KeyScan_DLPS_Exit(void); + +volatile uint32_t +KeyScan_StoreReg[7]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief KEYSCAN enter dlps callback function(Save KEYSCAN register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void KeyScan_DLPS_Enter(void) DATA_RAM_FUNCTION; +void KeyScan_DLPS_Enter(void) +{ + /*Open 5M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29; + + PERIPH->PERI_FUNC0_EN |= BIT_PERI_KEYSCAN_EN; + PERIPH->PERI_CLK_CTRL1 |= (BIT_SOC_ACTCK_KEYSCAN_EN | SYSBLK_SLPCK_KEYSCAN_EN_Msk); + + KeyScan_StoreReg[0] = KEYSCAN->CLKDIV; /* 0x00 */ + KeyScan_StoreReg[1] = KEYSCAN->TIMERCR; /* 0x04 */ + KeyScan_StoreReg[2] = KEYSCAN->CR; /* 0x08 */ + KeyScan_StoreReg[3] = KEYSCAN->COLCR; /* 0x0C */ + KeyScan_StoreReg[4] = KEYSCAN->ROWCR; /* 0x10 */ + KeyScan_StoreReg[6] = KEYSCAN->INTMASK; /* 0x18 */ + + return; +} + +/** + * @brief KEYSCAN exit dlps callback function(Resume KEYSCAN register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void KeyScan_DLPS_Exit(void) DATA_RAM_FUNCTION; +void KeyScan_DLPS_Exit(void) +{ + /*Open 5M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29; + + PERIPH->PERI_FUNC0_EN |= BIT_PERI_KEYSCAN_EN; + PERIPH->PERI_CLK_CTRL1 |= (BIT_SOC_ACTCK_KEYSCAN_EN | SYSBLK_SLPCK_KEYSCAN_EN_Msk); + + /* Set FSM to idle state */ + KEYSCAN->CR &= ~BIT31; + KEYSCAN->CLKDIV = KeyScan_StoreReg[0]; + KEYSCAN->CR = (KeyScan_StoreReg[2] & (~(BIT31))); + KEYSCAN->TIMERCR = KeyScan_StoreReg[1]; + KEYSCAN->COLCR = KeyScan_StoreReg[3]; + KEYSCAN->ROWCR = KeyScan_StoreReg[4]; + KEYSCAN->INTMASK = KeyScan_StoreReg[6]; + KEYSCAN->CR |= (KeyScan_StoreReg[2] & ((BIT31))); + + return; +} +#endif /* USE_KEYSCAN_DLPS */ + +/********************************************** ********************************************************/ +/**************************************** [QDEC DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_QDECODER_DLPS +__STATIC_INLINE void QuadDecoder_DLPS_Enter(void); +__STATIC_INLINE void QuadDecoder_DLPS_Exit(void); + +volatile uint32_t +QuadDecoder_StoreReg[5]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief QDEC enter dlps callback function(Save QDEC register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void QuadDecoder_DLPS_Enter(void) DATA_RAM_FUNCTION; +void QuadDecoder_DLPS_Enter(void) +{ + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_QDECODE_EN_Msk; + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_QDECODE_EN_Msk | + SYSBLK_SLPCK_QDECODE_EN_Msk); + + QuadDecoder_StoreReg[0] = QDEC->REG_DIV; + QuadDecoder_StoreReg[1] = QDEC->REG_CR_X; + QuadDecoder_StoreReg[2] = QDEC->REG_CR_Y; + QuadDecoder_StoreReg[3] = QDEC->REG_CR_Z; + QuadDecoder_StoreReg[4] = QDEC->INT_MASK; + + return; +} + +/** + * @brief QDEC exit dlps callback function(Resume QDEC register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void QuadDecoder_DLPS_Exit(void) DATA_RAM_FUNCTION; +void QuadDecoder_DLPS_Exit(void) +{ + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_QDECODE_EN_Msk; + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_QDECODE_EN_Msk | + SYSBLK_SLPCK_QDECODE_EN_Msk); + + //clear flags + QDEC->REG_DIV = QuadDecoder_StoreReg[0]; + QDEC->REG_CR_X = QuadDecoder_StoreReg[1]; + QDEC->REG_CR_Y = QuadDecoder_StoreReg[2]; + QDEC->REG_CR_Z = QuadDecoder_StoreReg[3]; + QDEC->INT_MASK = QuadDecoder_StoreReg[4]; + + return; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [CAPTOUCH DLPS] **********************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_CTC_DLPS +__STATIC_INLINE void CAPTOUCH_DLPS_Enter(void); +__STATIC_INLINE void CAPTOUCH_DLPS_Exit(void); + +/** + * @brief CAPTOUCH enter dlps callback function(Save CAPTOUCH register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CAPTOUCH_DLPS_Enter(void) DATA_RAM_FUNCTION; +void CAPTOUCH_DLPS_Enter(void) +{ + return; +} + +/** + * @brief CAPTOUCH exit dlps callback function(Resume CAPTOUCH register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CAPTOUCH_DLPS_Exit(void) DATA_RAM_FUNCTION; +void CAPTOUCH_DLPS_Exit(void) +{ + (*((volatile uint32_t *)0x40000234UL)) |= BIT12; + return; +} + +#endif +/********************************************** ********************************************************/ +/**************************************** [SPI0 DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_SPI0_DLPS +__STATIC_INLINE void SPI0_DLPS_Enter(void); +__STATIC_INLINE void SPI0_DLPS_Exit(void); + +volatile uint32_t +SPI0_StoreReg[14]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief SPI0 enter dlps callback function(Save SPI0 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI0_DLPS_Enter(void) DATA_RAM_FUNCTION; +void SPI0_DLPS_Enter(void) +{ + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI0_EN_Msk; + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI0_EN_Msk | + SYSBLK_SLPCK_SPI0_EN_Msk); + + SPI0_StoreReg[0] = SPI0->CTRLR0; + SPI0_StoreReg[1] = SPI0->CTRLR1; + SPI0_StoreReg[2] = SPI0->SSIENR; + SPI0_StoreReg[3] = SPI0->SER; + SPI0_StoreReg[4] = SPI0->BAUDR; + SPI0_StoreReg[5] = SPI0->TXFTLR; + SPI0_StoreReg[6] = SPI0->RXFTLR; + SPI0_StoreReg[7] = SPI0->IMR; + SPI0_StoreReg[8] = SPI0->DMACR; + SPI0_StoreReg[9] = SPI0->DMATDLR; + SPI0_StoreReg[10] = SPI0->DMARDLR; + SPI0_StoreReg[11] = SPI0->RX_SAMPLE_DLY; + SPI0_StoreReg[12] = *(volatile uint32_t *)0x40000308; + SPI0_StoreReg[13] = *(volatile uint32_t *)0x4000035CUL; +} + +/** + * @brief SPI0 exit dlps callback function(Resume SPI0 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI0_DLPS_Exit(void) DATA_RAM_FUNCTION; +void SPI0_DLPS_Exit(void) +{ + *(volatile uint32_t *)0x4000035CUL = SPI0_StoreReg[13]; + *(volatile uint32_t *)0x40000308 = SPI0_StoreReg[12]; + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI0_EN_Msk; + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI0_EN_Msk | + SYSBLK_SLPCK_SPI0_EN_Msk); + + SPI0->CTRLR0 = SPI0_StoreReg[0]; + SPI0->CTRLR1 = SPI0_StoreReg[1]; + SPI0->SER = SPI0_StoreReg[3]; + SPI0->BAUDR = SPI0_StoreReg[4]; + SPI0->TXFTLR = SPI0_StoreReg[5]; + SPI0->RXFTLR = SPI0_StoreReg[6]; + SPI0->IMR = SPI0_StoreReg[7]; + SPI0->DMACR = SPI0_StoreReg[8]; + SPI0->DMATDLR = SPI0_StoreReg[9]; + SPI0->DMARDLR = SPI0_StoreReg[10]; + SPI0->RX_SAMPLE_DLY = SPI0_StoreReg[11]; + + /* Enable the selected SPI peripheral */ + SPI0->SSIENR = SPI0_StoreReg[2]; +} +#endif + + +/********************************************** ********************************************************/ +/**************************************** [SPI1 DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_SPI1_DLPS +__STATIC_INLINE void SPI1_DLPS_Enter(void); +__STATIC_INLINE void SPI1_DLPS_Exit(void); + +volatile uint32_t +SPI1_StoreReg[14]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief SPI1 enter dlps callback function(Save SPI1 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI1_DLPS_Enter(void) DATA_RAM_FUNCTION; +void SPI1_DLPS_Enter(void) +{ + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI1_EN_Msk; + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI1_EN_Msk | + SYSBLK_SLPCK_SPI1_EN_Msk); + + SPI1_StoreReg[0] = SPI1->CTRLR0; + SPI1_StoreReg[1] = SPI1->CTRLR1; + SPI1_StoreReg[2] = SPI1->SSIENR; + SPI1_StoreReg[3] = SPI1->SER; + SPI1_StoreReg[4] = SPI1->BAUDR; + SPI1_StoreReg[5] = SPI1->TXFTLR; + SPI1_StoreReg[6] = SPI1->RXFTLR; + SPI1_StoreReg[7] = SPI1->IMR; + SPI1_StoreReg[8] = SPI1->DMACR; + SPI1_StoreReg[9] = SPI1->DMATDLR; + SPI1_StoreReg[10] = SPI1->DMARDLR; + SPI1_StoreReg[11] = SPI1->RX_SAMPLE_DLY; + SPI1_StoreReg[12] = *(volatile uint32_t *)0x40000308; + SPI1_StoreReg[13] = *(volatile uint32_t *)0x4000035CUL; +} + +/** + * @brief SPI1 exit dlps callback function(Resume SPI1 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI1_DLPS_Exit(void) DATA_RAM_FUNCTION; +void SPI1_DLPS_Exit(void) +{ + *(volatile uint32_t *)0x4000035CUL = SPI1_StoreReg[13]; + *(volatile uint32_t *)0x40000308 = SPI1_StoreReg[12]; + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI1_EN_Msk; + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_SPI1_EN_Msk | + SYSBLK_SLPCK_SPI1_EN_Msk); + + SPI1->CTRLR0 = SPI1_StoreReg[0]; + SPI1->CTRLR1 = SPI1_StoreReg[1]; + SPI1->SER = SPI1_StoreReg[3]; + SPI1->BAUDR = SPI1_StoreReg[4]; + SPI1->TXFTLR = SPI1_StoreReg[5]; + SPI1->RXFTLR = SPI1_StoreReg[6]; + SPI1->IMR = SPI1_StoreReg[7]; + SPI1->DMACR = SPI1_StoreReg[8]; + SPI1->DMATDLR = SPI1_StoreReg[9]; + SPI1->DMARDLR = SPI1_StoreReg[10]; + SPI1->RX_SAMPLE_DLY = SPI1_StoreReg[11]; + + /* Enable the selected SPI peripheral */ + SPI1->SSIENR = SPI1_StoreReg[2]; +} +#endif + +/********************************************** ********************************************************/ +/**************************************** [SPI2W DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_SPI2W_DLPS +__STATIC_INLINE void SPI2W_DLPS_Enter(void); +__STATIC_INLINE void SPI2W_DLPS_Exit(void); + +volatile uint32_t +SPI2W_StoreReg[1]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief SPI2W enter dlps callback function(Save SPI2W register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI2W_DLPS_Enter(void) DATA_RAM_FUNCTION; +void SPI2W_DLPS_Enter(void) +{ + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; + + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI2W_EN_Msk; + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_SPI2WIRE_EN_Msk | + SYSBLK_SLPCK_SPI2WIRE_EN_Msk); + + SPI2W_StoreReg[0] = SPI3WIRE->CFGR; +} + +/** + * @brief SPI2W exit dlps callback function(Resume SPI2W register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void SPI2W_DLPS_Exit(void) DATA_RAM_FUNCTION; +void SPI2W_DLPS_Exit(void) +{ + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; + + SYSBLKCTRL->u_218.PERION_REG_SOC_PERI_FUNC0_EN |= SYSBLK_SPI2W_EN_Msk; + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= (SYSBLK_ACTCK_SPI2WIRE_EN_Msk | + SYSBLK_SLPCK_SPI2WIRE_EN_Msk); + + SPI3WIRE->CFGR = SPI2W_StoreReg[0]; +} +#endif + + +/********************************************** ********************************************************/ +/**************************************** [Timer & PWM DLPS] *******************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#ifdef USE_TIM_DLPS +#undef USE_TIM_DLPS +#endif + +#define USE_TIM_DLPS 1 //ROM WDG use HW Timer, so defined to 1 by default + +#if USE_TIM_DLPS + +#include "rtl876x_tim.h" +__STATIC_INLINE void TIM_DLPS_Enter(void); +__STATIC_INLINE void TIM_DLPS_Exit(void); + +//uint32_t TIM_StoreReg[26]; /* This array should be placed in RAM ON/Buffer ON. */ +volatile uint32_t TIM_StoreReg[28]; +/* PWM, use with timer */ +volatile uint32_t PWM2_StoreReg; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief TIMER enter dlps callback function(Save TIMER register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void TIM_DLPS_Enter(void) DATA_RAM_FUNCTION; +void TIM_DLPS_Enter(void) +{ + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk | + SYSBLK_SLPCK_TIMER_EN_Msk); + + TIM_StoreReg[0] = TIM0->LoadCount; + TIM_StoreReg[1] = TIM0->ControlReg; + TIM_StoreReg[2] = TIMER0_LOAD_COUNT2; + + TIM_StoreReg[3] = TIM1->LoadCount; + TIM_StoreReg[4] = TIM1->ControlReg; + TIM_StoreReg[5] = TIMER1_LOAD_COUNT2; + + TIM_StoreReg[6] = TIM2->LoadCount; + TIM_StoreReg[7] = TIM2->ControlReg; + TIM_StoreReg[8] = TIMER2_LOAD_COUNT2; + + TIM_StoreReg[9] = TIM3->LoadCount; + TIM_StoreReg[10] = TIM3->ControlReg; + TIM_StoreReg[11] = TIMER3_LOAD_COUNT2; + + TIM_StoreReg[12] = TIM4->LoadCount; + TIM_StoreReg[13] = TIM4->ControlReg; + TIM_StoreReg[14] = TIMER4_LOAD_COUNT2; + + TIM_StoreReg[15] = TIM5->LoadCount; + TIM_StoreReg[16] = TIM5->ControlReg; + TIM_StoreReg[17] = TIMER5_LOAD_COUNT2; + + TIM_StoreReg[18] = *((volatile uint32_t *)0x40000360UL); + TIM_StoreReg[19] = *((volatile uint32_t *)0x4000600CUL); + TIM_StoreReg[20] = *((volatile uint32_t *)0x40000384UL); + PWM2_StoreReg = TIMER_PWM2_CR; +} + +/** + * @brief TIMER exit dlps callback function(Resume TIMER register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void TIM_DLPS_Exit(void) DATA_RAM_FUNCTION; +void TIM_DLPS_Exit(void) +{ + /* Enable timer IP clock and function */ + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk | + SYSBLK_SLPCK_TIMER_EN_Msk); + + *((volatile uint32_t *)0x40000360UL) = TIM_StoreReg[18]; + + TIM0->LoadCount = TIM_StoreReg[0]; + TIM0->ControlReg = TIM_StoreReg[1]; + TIMER0_LOAD_COUNT2 = TIM_StoreReg[2]; + + TIM1->LoadCount = TIM_StoreReg[3]; + TIM1->ControlReg = TIM_StoreReg[4]; + TIMER1_LOAD_COUNT2 = TIM_StoreReg[5]; + + TIM2->LoadCount = TIM_StoreReg[6]; + TIM2->ControlReg = TIM_StoreReg[7]; + TIMER2_LOAD_COUNT2 = TIM_StoreReg[8]; + + TIM3->LoadCount = TIM_StoreReg[9]; + TIM3->ControlReg = TIM_StoreReg[10]; + TIMER3_LOAD_COUNT2 = TIM_StoreReg[11]; + + TIM4->LoadCount = TIM_StoreReg[12]; + TIM4->ControlReg = TIM_StoreReg[13]; + TIMER4_LOAD_COUNT2 = TIM_StoreReg[14]; + + TIM5->LoadCount = TIM_StoreReg[15]; + TIM5->ControlReg = TIM_StoreReg[16]; + TIMER5_LOAD_COUNT2 = TIM_StoreReg[17]; + + TIMER_PWM2_CR = PWM2_StoreReg; +} +#endif /* USE_TIM_DLPS */ + +/********************************************** ********************************************************/ +/**************************************** [Enhance Timer & PWM DLPS] *******************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_ENHTIM_DLPS + +#include "rtl876x_enh_tim.h" + +volatile uint32_t +ENHTIM_StoreReg[20]; /* This array should be placed in RAM ON/Buffer ON. */ +/* PWM, use with timer */ +volatile uint32_t +ENHPWM0_StoreReg; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief Enhance TIMER enter dlps callback function(Save TIMER register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void ENHTIM_DLPS_Enter(void) DATA_RAM_FUNCTION; +void ENHTIM_DLPS_Enter(void) +{ + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk | + SYSBLK_SLPCK_TIMER_EN_Msk); + + ENHTIM_StoreReg[0] = ENH_TIM0->CR; + ENHTIM_StoreReg[1] = ENH_TIM0->MAX_CNT; + ENHTIM_StoreReg[2] = ENH_TIM0->CCR; + ENHTIM_StoreReg[3] = ENH_TIM0->CCR_FIFO; + + ENHTIM_StoreReg[4] = ENH_TIM1->CR; + ENHTIM_StoreReg[5] = ENH_TIM1->MAX_CNT; + ENHTIM_StoreReg[6] = ENH_TIM1->CCR; + ENHTIM_StoreReg[7] = ENH_TIM1->CCR_FIFO; + + ENHTIM_StoreReg[8] = ENH_TIM_SHARE->FIFO_CLR; + ENHTIM_StoreReg[9] = ENH_TIM_SHARE->CMD; + ENHTIM_StoreReg[10] = ENH_TIM_SHARE->INT_CMD; + ENHTIM_StoreReg[11] = ENH_TIM_SHARE->INT_SR; + ENHTIM_StoreReg[12] = ENH_TIM_SHARE->LC_INT_CMD0; + ENHTIM_StoreReg[13] = ENH_TIM_SHARE->LC_INT_CMD2; + ENHTIM_StoreReg[14] = ENH_TIM_SHARE->LC_FIFO_LEVEL0; + ENHTIM_StoreReg[15] = ENH_TIM_SHARE->LC_FIFO_LEVEL1; + + ENHTIM_StoreReg[16] = *((volatile uint32_t *)0x40000360UL); + ENHTIM_StoreReg[17] = *((volatile uint32_t *)0x4000600CUL); + ENHTIM_StoreReg[18] = *((volatile uint32_t *)0x40000384UL); + + ENHPWM0_StoreReg = ENHTIM_PWM_DEADZONE_CR; +} + +/** + * @brief Enhance TIMER exit dlps callback function(Resume TIMER register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void ENHTIM_DLPS_Exit(void) DATA_RAM_FUNCTION; +void ENHTIM_DLPS_Exit(void) +{ + /* Enable timer IP clock and function */ + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= BIT(16); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= (SYSBLK_ACTCK_TIMER_EN_Msk | + SYSBLK_SLPCK_TIMER_EN_Msk); + + *((volatile uint32_t *)0x40000360UL) = ENHTIM_StoreReg[16]; + *((volatile uint32_t *)0x4000600CUL) = ENHTIM_StoreReg[17]; + *((volatile uint32_t *)0x40000384UL) = ENHTIM_StoreReg[18]; + + ENH_TIM0->CR = ENHTIM_StoreReg[0]; + ENH_TIM0->MAX_CNT = ENHTIM_StoreReg[1]; + ENH_TIM0->CCR = ENHTIM_StoreReg[2]; + ENH_TIM0->CCR_FIFO = ENHTIM_StoreReg[3]; + + ENH_TIM1->CR = ENHTIM_StoreReg[4]; + ENH_TIM1->MAX_CNT = ENHTIM_StoreReg[5]; + ENH_TIM1->CCR = ENHTIM_StoreReg[6]; + ENH_TIM1->CCR_FIFO = ENHTIM_StoreReg[7]; + + ENH_TIM_SHARE->FIFO_CLR = ENHTIM_StoreReg[8]; + ENH_TIM_SHARE->CMD = ENHTIM_StoreReg[9] ; + ENH_TIM_SHARE->INT_CMD = ENHTIM_StoreReg[10]; + ENH_TIM_SHARE->INT_SR = ENHTIM_StoreReg[11]; + ENH_TIM_SHARE->LC_INT_CMD0 = ENHTIM_StoreReg[12]; + ENH_TIM_SHARE->LC_INT_CMD2 = ENHTIM_StoreReg[13]; + ENH_TIM_SHARE->LC_FIFO_LEVEL0 = ENHTIM_StoreReg[14]; + ENH_TIM_SHARE->LC_FIFO_LEVEL1 = ENHTIM_StoreReg[15]; + + ENHTIM_PWM_DEADZONE_CR = ENHPWM0_StoreReg; +} +#endif /* USE_ENHTIM_DLPS */ + +/********************************************** ********************************************************/ +/**************************************** [UART DLPS] **************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_UART0_DLPS +#include "rtl876x_uart.h" + +__STATIC_INLINE void UART0_DLPS_Enter(void); +__STATIC_INLINE void UART0_DLPS_Exit(void); + +volatile uint32_t +UART0_StoreReg[12]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief UART0 enter dlps callback function(Save UART0 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void UART0_DLPS_Enter(void) DATA_RAM_FUNCTION; +void UART0_DLPS_Enter(void) +{ + PERIPH->PERI_FUNC0_EN |= (1 << 0); + PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_UART0DATA_EN_Msk | SYSBLK_SLPCK_UART0DATA_EN_Msk); + + //access DLH and DLL + UART0->LCR |= (1 << 7); + UART0_StoreReg[0] = UART0->DLL; + UART0_StoreReg[1] = UART0->DLH_INTCR; + UART0->LCR &= (~(1 << 7)); + + //save other registers + UART0_StoreReg[2] = UART0->DLH_INTCR; + UART0_StoreReg[4] = UART0->LCR; + UART0_StoreReg[5] = UART0->MCR; + UART0_StoreReg[6] = UART0->SPR; + UART0_StoreReg[7] = UART0->STSR; + UART0_StoreReg[8] = UART0->RX_IDLE_TOCR; + UART0_StoreReg[9] = UART0->RX_IDLE_INTCR; + UART0_StoreReg[10] = UART0->MISCR; + UART0_StoreReg[11] = UART0->INTMASK; + + return; +} + +/** + * @brief UART0 exit dlps callback function(Resume UART0 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void UART0_DLPS_Exit(void) DATA_RAM_FUNCTION; +void UART0_DLPS_Exit(void) +{ + PERIPH->PERI_FUNC0_EN |= (1 << 0); + PERIPH->PERI_CLK_CTRL0 |= (SYSBLK_ACTCK_UART0DATA_EN_Msk | SYSBLK_SLPCK_UART0DATA_EN_Msk); + + //access DLH and DLL + UART0->LCR |= (1 << 7); + UART0->STSR = UART0_StoreReg[7]; + UART0->SPR = UART0_StoreReg[6]; + UART0->DLL = UART0_StoreReg[0]; + UART0->DLH_INTCR = UART0_StoreReg[1]; + UART0->LCR &= (~(1 << 7)); + + //access other registers + UART0->INTID_FCR = (((UART0_StoreReg[7] & BIT24) >> 21) | ((UART0_StoreReg[7] & 0x7C000000) >> 18) | + (1)); + UART0->LCR = UART0_StoreReg[4]; + UART0->MCR = UART0_StoreReg[5]; + UART0->DLH_INTCR = UART0_StoreReg[2]; + UART0->RX_IDLE_TOCR = UART0_StoreReg[8]; + UART0->RX_IDLE_INTCR = UART0_StoreReg[9]; + UART0->MISCR = UART0_StoreReg[10]; + UART0->INTMASK = UART0_StoreReg[11]; + + return; +} +#endif + + +#if USE_UART1_DLPS +#include "rtl876x_uart.h" + +__STATIC_INLINE void UART1_DLPS_Enter(void); +__STATIC_INLINE void UART1_DLPS_Exit(void); + +volatile uint32_t +UART1_StoreReg[12]; /* This array should be placed in RAM ON/Buffer ON. */ + +/** + * @brief UART1 enter dlps callback function(Save UART1 register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void UART1_DLPS_Enter(void) DATA_RAM_FUNCTION; +void UART1_DLPS_Enter(void) +{ + //enable log uart peripheral & clock + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= (1 << 12); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= ((1 << 12) | (1 << 13)); + + //access DLH and DLL + UART1->LCR |= (1 << 7); + UART1_StoreReg[0] = UART1->DLL; + UART1_StoreReg[1] = UART1->DLH_INTCR; + UART1->LCR &= (~(1 << 7)); + + //save other registers + UART1_StoreReg[2] = UART1->DLH_INTCR; + UART1_StoreReg[4] = UART1->LCR; + UART1_StoreReg[5] = UART1->MCR; + UART1_StoreReg[6] = UART1->SPR; + UART1_StoreReg[7] = UART1->STSR; + UART1_StoreReg[8] = UART1->RX_IDLE_TOCR; + UART1_StoreReg[9] = UART1->RX_IDLE_INTCR; + UART1_StoreReg[10] = UART1->MISCR; + UART1_StoreReg[11] = UART1->INTMASK; + + return; +} + +/** + * @brief UART1 exit dlps callback function(Resume UART1 register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void UART1_DLPS_Exit(void) DATA_RAM_FUNCTION; +void UART1_DLPS_Exit(void) +{ + //enable log uart peripheral & clock + SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN |= (1 << 12); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= ((1 << 12) | (1 << 13)); + + //access DLH and DLL + UART1->LCR |= (1 << 7); + UART1->STSR = UART1_StoreReg[7]; + UART1->SPR = UART1_StoreReg[6]; + UART1->DLL = UART1_StoreReg[0]; + UART1->DLH_INTCR = UART1_StoreReg[1]; + UART1->LCR &= (~(1 << 7)); + + //access other registers + UART1->INTID_FCR = (((UART1_StoreReg[7] & BIT24) >> 21) | ((UART1_StoreReg[7] & 0x7C000000) + >> 18) | (1)); + UART1->LCR = UART1_StoreReg[4]; + UART1->MCR = UART1_StoreReg[5]; + UART1->DLH_INTCR = UART1_StoreReg[2]; + UART1->RX_IDLE_TOCR = UART1_StoreReg[8]; + UART1->RX_IDLE_INTCR = UART1_StoreReg[9]; + UART1->MISCR = UART1_StoreReg[10]; + UART1->INTMASK = UART1_StoreReg[11]; + + return; +} +#endif + + +/*============================================================================* + * Platform DLPS + *============================================================================*/ + +/********************************************** ********************************************************/ +/*********************************** [USER Enter DLPS CALLBACK FUCN] *****************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_USER_DEFINE_DLPS_ENTER_CB + +DLPS_IO_EnterDlpsCB User_IO_EnterDlpsCB = NULL; + +#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */ + +/********************************************** ********************************************************/ +/*********************************** [USER Exit DLPS CALLBACK FUCN] *****************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +#if USE_USER_DEFINE_DLPS_EXIT_CB + +DLPS_IO_ExitDlpsCB User_IO_ExitDlpsCB = NULL; + +#endif /* USE_USER_DEFINE_DLPS_EXIT_CB */ + + +#if USE_IO_DRIVER_DLPS + +/********************************************** ********************************************************/ +/**************************************** [CPU & PINMUX DLPS]*******************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +__STATIC_INLINE void CPU_DLPS_Enter(void); +__STATIC_INLINE void CPU_DLPS_Exit(void); +__STATIC_INLINE void Log_SWD_DLPS_Enter(void); +__STATIC_INLINE void Log_SWD_DLPS_Exit(void); + +volatile uint32_t +CPU_StoreReg[3]; /* This array should be placed in RAM ON/Buffer ON. */ +volatile uint32_t CPU_StoreReg_IP[8]; +volatile uint32_t PeriIntStoreReg = 0; + +/** + * @brief CPU enter dlps callback function(Save CPU register values when system enter DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CPU_DLPS_Enter(void) DATA_RAM_FUNCTION; +void CPU_DLPS_Enter(void) +{ + //NVIC store + uint32_t i; + + CPU_StoreReg[0] = NVIC->ISER[0]; + CPU_StoreReg[1] = NVIC->ISPR[0]; + + for (i = 0; i < 8; ++i) + { + CPU_StoreReg_IP[i] = NVIC->IP[i]; + } + + CPU_StoreReg[2] = SCB->VTOR; + /* Save Vendor register */ + PeriIntStoreReg = PERIPHINT->EN; + + return; +} + +/** + * @brief CPU exit dlps callback function(Resume CPU register values when system exit DLPS) + * @param None + * @retval None + */ +__STATIC_INLINE void CPU_DLPS_Exit(void) DATA_RAM_FUNCTION; +void CPU_DLPS_Exit(void) +{ + //NVIC restore + uint32_t i; + + //Don't restore NVIC pending register, but report warning + //NVIC->ISPR[0] = CPU_StoreReg[1]; + if (CPU_StoreReg[0] & CPU_StoreReg[1]) + { + /* During enter and exit dlps, system will disable all interrupts. If any interrupt occurs during this period, this log will be printed. + Every bit of pending register corresponds to an interrupt. Please refer to IRQn_Type from System_IRQn to UART2_IRQn. + For example: "miss interrupt: pending register: 0x42000" + It means that RTC and ADC interrupt occur during dlps store and restore flow. But because all interrupts are masked, these interrupts are pending. + */ + OS_PRINT_WARN1("miss interrupt: pending register: 0x%x", CPU_StoreReg[1]); + } + + NVIC->IP[0] |= CPU_StoreReg_IP[0] & + 0xFF000000;//skip restore the priority of System_IRQn(#0), WDG_IRQn(#1) and BTMAC_IRQn(#2) + for (i = 1; i < 8; ++i) + { + NVIC->IP[i] = CPU_StoreReg_IP[i]; + } + + SCB->VTOR = CPU_StoreReg[2]; + PERIPHINT->EN = PeriIntStoreReg; + NVIC->ISER[0] = CPU_StoreReg[0]; + + return; +} + +/********************************************** ********************************************************/ +/**************************************** [LOG & SWD DLPS]*******************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/** + * @brief Set Log and SWD pins to SW mode. + * @param void. + * @retval void. + */ +__STATIC_INLINE void Log_SWD_DLPS_Enter(void) DATA_RAM_FUNCTION; +void Log_SWD_DLPS_Enter(void) +{ + if (OTP->SWD_ENABLE) + { + Pad_Config(P1_0, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P1_1, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_DOWN, PAD_OUT_DISABLE, PAD_OUT_LOW); + } + + Pad_Config(OTP->logPin, PAD_SW_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW); +} + +/** + * @brief Set Log and SWD pins to PINMUX mode. + * @param void. + * @retval void. + */ +__STATIC_INLINE void Log_SWD_DLPS_Exit(void) DATA_RAM_FUNCTION; +void Log_SWD_DLPS_Exit(void) +{ + Pad_Config(OTP->logPin, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW); + + if (OTP->SWD_ENABLE) + { + Pad_Config(P1_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P1_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW); + } +} + +/********************************************** ********************************************************/ +/*********************************** [Enter & Exit DLPS CALLBACK FUNC] *********************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +/** + * @brief IO enter dlps callback function + * @param None + * @retval None + */ +void DLPS_IO_EnterDlpsCb(void) DATA_RAM_FUNCTION; +void DLPS_IO_EnterDlpsCb(void) +{ + /* low stack do it instead */ +// Pad_ClearAllWakeupINT(); + +// DBG_DIRECT("DLPS_IO_EnterDlpsCb"); + + if (lps_mode_get() == PLATFORM_POWERDOWN) + { + T_BTAON_FAST_TEST_MODE_TYPE aon; + aon.d16 = btaon_fast_read_safe(BTAON_FAST_TEST_MODE); + aon.s.reset_reason = RESET_REASON_POWERDOWN; + btaon_fast_write_safe(BTAON_FAST_TEST_MODE, aon.d16); + } + + NVIC_DisableIRQ(System_IRQn); + CPU_DLPS_Enter(); + + Pinmux_DLPS_Enter(); + +#if USE_USER_DEFINE_DLPS_ENTER_CB + if (User_IO_EnterDlpsCB) + { + User_IO_EnterDlpsCB(); + } +#endif + +#if USE_ADC_DLPS + ADC_DLPS_Enter(); +#endif + +#if USE_CODEC_DLPS + CODEC_DLPS_Enter(); +#endif + +#if USE_GPIO_DLPS + GPIO_DLPS_Enter(); +#endif + +#if USE_I2C0_DLPS + I2C0_DLPS_Enter(); +#endif + +#if USE_I2C1_DLPS + I2C1_DLPS_Enter(); +#endif + +#if USE_I2S0_DLPS + I2S0_DLPS_Enter(); +#endif + +#if USE_IR_DLPS + IR_DLPS_Enter(); +#endif + +#if USE_KEYSCAN_DLPS + KeyScan_DLPS_Enter(); +#endif + +#if USE_QDECODER_DLPS + QuadDecoder_DLPS_Enter(); +#endif + +#if USE_CTC_DLPS + CAPTOUCH_DLPS_Enter(); +#endif + +#if USE_SPI0_DLPS + SPI0_DLPS_Enter(); +#endif + +#if USE_SPI1_DLPS + SPI1_DLPS_Enter(); +#endif + +#if USE_SPI2W_DLPS + SPI2W_DLPS_Enter(); +#endif + +#if USE_TIM_DLPS + TIM_DLPS_Enter(); +#endif + +#if USE_ENHTIM_DLPS + ENHTIM_DLPS_Enter(); +#endif + +#if USE_UART0_DLPS + UART0_DLPS_Enter(); +#endif + +#if USE_UART1_DLPS + UART1_DLPS_Enter(); +#endif + + Log_SWD_DLPS_Enter(); +} + +/** + * @brief IO exit dlps callback function. + * @param None + * @retval None + */ +void DLPS_IO_ExitDlpsCb(void) DATA_RAM_FUNCTION; +void DLPS_IO_ExitDlpsCb(void) +{ + +// DBG_BUFFER(TYPE_BUMBLEBEE3, SUBTYPE_FORMAT, MODULE_DLPS, LEVEL_INFO, +// "DLPS_IO_ExitDlpsCb",0); + + Pinmux_DLPS_Exit(); + + Log_SWD_DLPS_Exit(); + +#if USE_ADC_DLPS + ADC_DLPS_Exit(); +#endif + +#if USE_CODEC_DLPS + CODEC_DLPS_Exit(); +#endif + +#if USE_GPIO_DLPS + GPIO_DLPS_Exit(); +#endif + +#if USE_I2C0_DLPS + I2C0_DLPS_Exit(); +#endif + +#if USE_I2C1_DLPS + I2C1_DLPS_Exit(); +#endif + +#if USE_I2S0_DLPS + I2S0_DLPS_Exit(); +#endif + +#if USE_IR_DLPS + IR_DLPS_Exit(); +#endif + +#if USE_KEYSCAN_DLPS + KeyScan_DLPS_Exit(); +#endif + +#if USE_QDECODER_DLPS + QuadDecoder_DLPS_Exit(); +#endif + +#if USE_CTC_DLPS + CAPTOUCH_DLPS_Exit(); +#endif + +#if USE_SPI0_DLPS + SPI0_DLPS_Exit(); +#endif + +#if USE_SPI1_DLPS + SPI1_DLPS_Exit(); +#endif + +#if USE_SPI2W_DLPS + SPI2W_DLPS_Exit(); +#endif + +#if USE_TIM_DLPS + TIM_DLPS_Exit(); +#endif + +#if USE_ENHTIM_DLPS + ENHTIM_DLPS_Exit(); +#endif + +#if USE_UART0_DLPS + UART0_DLPS_Exit(); +#endif + +#if USE_UART1_DLPS + UART1_DLPS_Exit(); +#endif + +#if USE_USER_DEFINE_DLPS_EXIT_CB + if (User_IO_ExitDlpsCB) + { + User_IO_ExitDlpsCB(); + } +#endif + + NVIC_InitTypeDef nvic_init_struct; + nvic_init_struct.NVIC_IRQChannel = System_IRQn; + nvic_init_struct.NVIC_IRQChannelCmd = (FunctionalState)ENABLE; + nvic_init_struct.NVIC_IRQChannelPriority = 3; + NVIC_Init(&nvic_init_struct); //Enable SYSTEM_ON Interrupt + + CPU_DLPS_Exit(); +} + +/** + * @brief register IO DLPS callback function + * @param None + * @retval None + */ +void DLPS_IORegister(void) +{ + dlps_hw_control_cb_reg(DLPS_IO_EnterDlpsCb, PLATFORM_PM_STORE); + dlps_hw_control_cb_reg(DLPS_IO_ExitDlpsCb, PLATFORM_PM_PEND); + + return; +} + +#endif /* USE_IO_DRIVER_DLPS */ + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_ir.c b/src/mcu/peripheral/rtl876x_ir.c new file mode 100644 index 0000000..7cbb51d --- /dev/null +++ b/src/mcu/peripheral/rtl876x_ir.c @@ -0,0 +1,596 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_ir.c +* @brief This file provides all the IR firmware functions. +* @details +* @author yuan +* @date 2020-10-13 +* @version v1.0.2 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_ir.h" + +/** + * @brief Deinitializes the IR peripheral registers to their default values. + * @param None + * @retval None + */ +void IR_DeInit(void) +{ + RCC_PeriphClockCmd(APBPeriph_IR, APBPeriph_IR_CLOCK, DISABLE); +} + +/** + * @brief Initializes the IR peripheral according to the specified + * parameters in the IR_InitStruct + * @param IRx: selected IR peripheral. + * @param IR_InitStruct: pointer to a IR_InitTypeDef structure that + * contains the configuration information for the specified IR peripheral + * @retval None + */ +void IR_Init(IR_InitTypeDef *IR_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_IR_CLOCK(IR_InitStruct->IR_Clock)); + + if (IR_InitStruct->IR_Clock == 40000000) + { + assert_param(IS_IR_FREQUENCY_40M(IR_InitStruct->IR_Freq)); + } + else if (IR_InitStruct->IR_Clock == 90000000) + { + assert_param(IS_IR_FREQUENCY_90M(IR_InitStruct->IR_Freq)); + } + else if (IR_InitStruct->IR_Clock == 100000000) + { + assert_param(IS_IR_FREQUENCY_100M(IR_InitStruct->IR_Freq)); + } + assert_param(IS_IR_MODE(IR_InitStruct->IR_Mode)); + + /* Configure IR clock divider. Formula: IR_CLK = IO_CLK/(1+IR_CLK_DIV) */ + uint32_t ir_clk_div_num = (IR_InitStruct->IR_Clock / IR_InitStruct->IR_Freq) - 1; + uint32_t duty_cycle_num = ((double)(ir_clk_div_num + 1.0)) / (IR_InitStruct->IR_DutyCycle) - 1; + + IR->CLK_DIV = ir_clk_div_num; + if (IR_InitStruct->IR_Mode == IR_MODE_TX) + { + /* Check the parameters in TX mode */ + assert_param(IS_IR_IDLE_STATUS(IR_InitStruct->IR_TxIdleLevel)); + assert_param(IS_IR_TX_DATA_TYPE(IR_InitStruct->IR_TxInverse)); + assert_param(IS_IR_TX_THRESHOLD(IR_InitStruct->IR_TxFIFOThrLevel)); + + /* Configure TX mode parameters and disable all TX interrupt */ + IR->TX_CONFIG = (IR_InitStruct->IR_Mode) | \ + (IR_InitStruct->IR_TxIdleLevel) | \ + (IR_InitStruct->IR_TxInverse) | \ + ((IR_InitStruct->IR_TxFIFOThrLevel) << IR_TX_FIFO_THRESHOLD_Pos) | \ + ((duty_cycle_num & 0x3FFF) << IR_TX_DUTY_NUM_Pos); + /* Clear all TX interrupt and TX FIFO */ + IR->TX_INT_CLR = IR_INT_ALL_CLR | IR_TX_FIFO_CLR_Msk; + + if (IR_InitStruct->IR_TxDmaEn != DISABLE) + { + IR->DMA_CONFIG = ((IR_InitStruct->IR_TxDmaEn << IR_TX_DMA_EN_Pos) & IR_TX_DMA_EN_Msk) | \ + ((IR_InitStruct->IR_TxWaterLevel << IR_TX_WATER_LEVEL_Pos) & IR_TX_WATER_LEVEL_Msk); + } + else + { + IR->DMA_CONFIG = ((IR_InitStruct->IR_TxDmaEn << IR_TX_DMA_EN_Pos) & IR_TX_DMA_EN_CLR) | \ + ((IR_InitStruct->IR_TxWaterLevel << IR_TX_WATER_LEVEL_Pos) & IR_TX_WATER_LEVEL_CLR); + } + } + else + { + /* Check the parameters in RX mode */ + assert_param(IS_RX_START_MODE(IR_InitStruct->IR_RxStartMode)); + assert_param(IS_IR_RX_THRESHOLD(IR_InitStruct->IR_RxFIFOThrLevel)); + assert_param(IS_IR_RX_FIFO_FULL_CTRL(IR_InitStruct->IR_RxFIFOFullCtrl)); + assert_param(IS_RX_RX_TRIGGER_EDGE(IR_InitStruct->IR_RxTriggerMode)); + assert_param(IS_IR_RX_FILTER_TIME_CTRL(IR_InitStruct->IR_RxFilterTime)); + assert_param(IS_IR_RX_COUNT_LEVEL_CTRL(IR_InitStruct->IR_RxCntThrType)); + assert_param(IS_IR_RX_COUNTER_THRESHOLD(IR_InitStruct->IR_RxCntThr)); + + /* Enable RX mode */ + IR->TX_CONFIG |= (IR_InitStruct->IR_Mode); + /* Configure RX mode parameters and disable all RX interrupt */ + IR->RX_CONFIG = (IR_InitStruct->IR_RxStartMode) | \ + (IR_InitStruct->IR_RxTriggerMode) | \ + (IR_InitStruct->IR_RxFilterTime) | \ + (IR_InitStruct->IR_RxFIFOFullCtrl) | \ + (IR_InitStruct->IR_RxFIFOThrLevel << IR_RX_FIFO_LEVEL_Pos); + /* Configure IR RX counter threshold parameters */ + IR->RX_CNT_INT_SEL = (IR_InitStruct->IR_RxCntThrType) | (IR_InitStruct->IR_RxCntThr); + /* Clear all RX interrupt and RX FIFO */ + IR->RX_INT_CLR = IR_RX_INT_ALL_CLR | IR_RX_FIFO_CLR_Msk; + IR->RX_EX_INT |= IR_RX_RISING_EDGE_INT_CLR_Msk | IR_RX_FALLING_EDGE_INT_CLR_Msk; + + if (IR_InitStruct->IR_RxDmaEn != DISABLE) + { + IR->DMA_CONFIG = ((IR_InitStruct->IR_RxDmaEn << IR_RX_DMA_EN_Pos) & IR_RX_DMA_EN_Msk) | \ + ((IR_InitStruct->IR_RxWaterLevel << IR_RX_WATER_LEVEL_Pos) & IR_RX_WATER_LEVEL_Msk); + } + else + { + IR->DMA_CONFIG = ((IR_InitStruct->IR_RxDmaEn << IR_RX_DMA_EN_Pos) & IR_RX_DMA_EN_CLR) | \ + ((IR_InitStruct->IR_RxWaterLevel << IR_RX_WATER_LEVEL_Pos) & IR_RX_WATER_LEVEL_CLR); + } + } +} + +/** + * @brief Fills each IR_InitStruct member with its default value. + * @param IR_InitStruct: pointer to an IR_InitTypeDef structure which will be initialized. + * @retval None + */ +void IR_StructInit(IR_InitTypeDef *IR_InitStruct) +{ + IR_InitStruct->IR_Clock = IR_CLOCK_40M; + IR_InitStruct->IR_Freq = 38000; + IR_InitStruct->IR_DutyCycle = 3; + IR_InitStruct->IR_Mode = IR_MODE_TX; + IR_InitStruct->IR_TxIdleLevel = IR_IDLE_OUTPUT_LOW; + IR_InitStruct->IR_TxInverse = IR_TX_DATA_NORMAL; + IR_InitStruct->IR_TxFIFOThrLevel = 0; + IR_InitStruct->IR_RxStartMode = IR_RX_AUTO_MODE; + IR_InitStruct->IR_RxFIFOThrLevel = 0; + IR_InitStruct->IR_RxFIFOFullCtrl = IR_RX_FIFO_FULL_DISCARD_NEWEST; + IR_InitStruct->IR_RxTriggerMode = IR_RX_FALL_EDGE; + IR_InitStruct->IR_RxFilterTime = IR_RX_FILTER_TIME_50ns; + IR_InitStruct->IR_RxCntThrType = IR_RX_Count_Low_Level; + IR_InitStruct->IR_RxCntThr = 0x23a; /* This value can be 0 to 0x7fffffff */ + IR_InitStruct->IR_TxDmaEn = DISABLE; /* */ + IR_InitStruct->IR_TxWaterLevel = 15; /* */ + IR_InitStruct->IR_RxDmaEn = DISABLE; /* */ + IR_InitStruct->IR_RxWaterLevel = 0; /* */ +} + +/** + * @brief Enable or disable the selected IR mode. + * @param mode: selected IR operation mode. + * This parameter can be the following values: + * @arg IR_MODE_TX: Transmission mode. + * @arg IR_MODE_RX: Receiving mode. + * @param NewState: new state of the operation mode. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_Cmd(uint32_t mode, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_IR_MODE(mode)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + if (mode == IR_MODE_TX) + { + /* Start Transmission mode */ + IR->TX_CONFIG |= IR_TX_START_Msk; + } + else + { + /* Start Receiving mode */ + IR->RX_CONFIG |= IR_RX_START_Msk; + } + } + else + { + if (mode == IR_MODE_TX) + { + /* Stop Transmission mode */ + IR->TX_CONFIG &= IR_TX_START_CLR; + } + else + { + /* Stop Receiving mode */ + IR->RX_CONFIG &= IR_RX_START_CLR; + } + } +} + +/** + * @brief Mask or unmask the specified IR interrupts. + * @param IR_INT: specifies the IR interrupts sources to be mask or unmask. + * This parameter can be the following values: + * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt. + * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt. + * @arg IR_INT_TF_OF: TX FIFO overflow interrupt. + * @arg IR_INT_RF_FULL: RX FIFO full interrupt. + * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt. + * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt. + * @arg IR_INT_RF_OF: RX FIFO overflow interrupt. + * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt. + * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * @param NewState: new state of the specified IR interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_MaskINTConfig(uint32_t IR_INT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_IR_INT_CONFIG(IR_INT)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + + if (newState == ENABLE) + { + if ((IR->TX_CONFIG) & IR_MODE_SEL_Msk) + { + /* Enable the selected IR interrupts in RX mode */ + if (IR_INT & IR_RX_EXTENSION_INT) + { + IR->RX_EX_INT |= (IR_INT & 0x03) << 2; + } + else + { + IR->RX_CONFIG |= (IR_INT << IR_RX_MSK_TO_EN_Pos); + } + } + else + { + /* Enable the selected IR interrupts in TX mode */ + if (IR_INT == IR_INT_TF_OF) + { + IR->TX_CONFIG |= (IR_INT << IR_TX_FIFO_OVER_MSK_TO_EN_Pos); + } + else + { + IR->TX_CONFIG |= (IR_INT << IR_TX_MSK_TO_EN_Pos); + } + } + } + else + { + if ((IR->TX_CONFIG) & IR_MODE_SEL_Msk) + { + /* Disable the selected IR interrupts in RX mode */ + if (IR_INT & IR_RX_EXTENSION_INT) + { + IR->RX_EX_INT &= ~((IR_INT & 0x03) << 2); + } + else + { + IR->RX_CONFIG &= (~(IR_INT << IR_RX_MSK_TO_EN_Pos)); + } + } + else + { + /* Disable the selected IR interrupts in TX mode */ + if (IR_INT == IR_INT_TF_OF) + { + IR->TX_CONFIG &= (~(IR_INT << IR_TX_FIFO_OVER_MSK_TO_EN_Pos)); + } + else + { + IR->TX_CONFIG &= (~(IR_INT << IR_TX_MSK_TO_EN_Pos)); + } + } + } +} + +/** + * @brief Enables or disables the specified IR interrupts. + * @param IR_INT: specifies the IR interrupts sources to be enabled or disabled. + * This parameter can be the following values: + * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt. + * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt. + * @arg IR_INT_TF_OF: TX FIFO overflow interrupt. + * @arg IR_INT_RF_FULL: RX FIFO full interrupt. + * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt. + * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt. + * @arg IR_INT_RF_OF: RX FIFO overflow interrupt. + * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt. + * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * @param NewState: new state of the specified IR interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void IR_INTConfig(uint32_t IR_INT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_IR_INT_CONFIG(IR_INT)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + + if (newState == ENABLE) + { + if (IR->TX_CONFIG & IR_MODE_SEL_Msk) + { + /* Enable the selected IR interrupts in RX mode */ + if (IR_INT & IR_RX_EXTENSION_INT) + { + IR->RX_EX_INT |= IR_INT & (~IR_RX_EXTENSION_INT); + } + else + { + IR->RX_CONFIG |= IR_INT; + } + } + else + { + /* Enable the selected IR interrupts in TX mode */ + IR->TX_CONFIG |= IR_INT; + } + } + else + { + if (IR->TX_CONFIG & IR_MODE_SEL_Msk) + { + /* Disable the selected IR interrupts in RX mode */ + if (IR_INT & IR_RX_EXTENSION_INT) + { + IR->RX_EX_INT &= ~(IR_INT & 0x03); + } + else + { + IR->RX_CONFIG &= (~IR_INT); + } + } + else + { + /* Disable the selected IR interrupts in TX mode */ + IR->TX_CONFIG &= (~IR_INT); + } + } +} + +/** + * @brief Start trigger only in manual receive mode. + * @param None. + * @retval None + */ +void IR_StartManualRxTrigger(void) +{ + /* Start Rx manual mode */ + IR->RX_CONFIG |= IR_RX_MAN_START_Msk; +} + +/** + * @brief Configure counter threshold value in receiving mode.You can use it to stop receiving IR data. + * @param IR_RxCntThrType: + * This parameter can be the following values: + * @arg IR_RX_Count_Low_Level: Low level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * @arg IR_RX_Count_High_Level: High level counter value >= IR_RxCntThr, trigger IR_INT_RX_CNT_THR interrupt. + * @param IR_RxCntThr: Configure IR Rx counter threshold value which can be 0 to 0x7fffffffUL. + * @retval None + */ +void IR_SetRxCounterThreshold(uint32_t IR_RxCntThrType, uint32_t IR_RxCntThr) +{ + /* Check the parameters */ + assert_param(IS_IR_RX_COUNT_LEVEL_CTRL(IR_RxCntThrType)); + assert_param(IS_IR_RX_COUNTER_THRESHOLD(IR_RxCntThr)); + + /* Configure IR RX counter threshold parameters */ + IR->RX_CNT_INT_SEL = (IR_RxCntThrType) | (IR_RxCntThr); +} + +/** + * @brief Send data. + * @param buf: data buffer to send. + * @param length: buffer length. + * @param IsLastPacket: + * This parameter can be the following values: + * @arg ENABLE: The last data in IR packet and there is no continous data.In other words, An infrared data transmission is completed. + * @arg DISABLE: There is data to be transmitted continuously. + * @retval None + */ +void IR_SendBuf(uint32_t *pBuf, uint32_t len, FunctionalState IsLastPacket) +{ + uint32_t i = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(IsLastPacket)); + + if (len > 0) + { + i = len - 1; + while (i--) + { + IR->TX_FIFO = *pBuf++; + } + + /* If send the last IR packet, SET the following bit */ + if (IsLastPacket == ENABLE) + { + IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf); + } + else + { + IR->TX_FIFO = *pBuf; + } + } +} + +/** + * @brief Send compensation data. + * @param comp_type: + * @arg IR_COMPEN_FLAG_1_2_CARRIER: 1/2 carrier freqency. + * @arg IR_COMPEN_FLAG_1_4_CARRIER: 1/4 carrier freqency. + * @arg IR_COMPEN_FLAG_1_N_SYSTEM_CLK: MOD((0x48[27:16]+0x00[11:0]), 4095)/40MHz. + User can call function of IR_ConfigCompParam to configure 0x48[27:16]. + * @param buf: data buffer to send. + * @param length: buffer length. + * @param IsLastPacket: + * This parameter can be the following values: + * @arg ENABLE: The last data in IR packet and there is no continous data.In other words, An infrared data transmission is completed. + * @arg DISABLE: There is data to be transmitted continuously. + * @retval None + */ +void IR_SendCompenBuf(IR_TX_COMPEN_TYPE comp_type, uint32_t *pBuf, uint32_t len, + FunctionalState IsLastPacket) +{ + uint32_t i = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(IsLastPacket)); + + if (len > 0) + { + i = len - 1; + while (i--) + { + if (*pBuf & IR_DATA_TYPE_Msk) + { + IR->TX_FIFO = *pBuf++; + } + else + { + IR->TX_FIFO = *pBuf++ | comp_type; + } + } + + /* If send the last IR packet, SET the following bit */ + if (IsLastPacket == ENABLE) + { + if (*pBuf & IR_DATA_TYPE_Msk) + { + IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf); + } + else + { + IR->TX_FIFO = (IR_TX_LAST_PACKEET_Msk | *pBuf | comp_type); + } + } + else + { + if (*pBuf & IR_DATA_TYPE_Msk) + { + IR->TX_FIFO = *pBuf; + } + else + { + IR->TX_FIFO = *pBuf | comp_type; + } + } + } +} + +/** + * @brief Read data From RX FIO. + * @param buf: buffer address to receive data. + * @param length: read data length. + * @retval None + */ +void IR_ReceiveBuf(uint32_t *pBuf, uint32_t len) +{ + while (len--) + { + *pBuf++ = IR->RX_FIFO; + } +} + +/** + * @brief Get the specified IR interrupt status. + * @param IR_INT: the specified IR interrupts. + * This parameter can be one of the following values: + * @arg IR_INT_TF_EMPTY: TX FIFO empty interrupt. + * @arg IR_INT_TF_LEVEL: TX FIFO threshold interrupt. + * @arg IR_INT_TF_OF: TX FIFO overflow interrupt. + * @arg IR_INT_RF_FULL: RX FIFO full interrupt. + * @arg IR_INT_RF_LEVEL: RX FIFO threshold interrupt. + * @arg IR_INT_RX_CNT_OF: RX counter overflow interrupt. + * @arg IR_INT_RF_OF: RX FIFO overflow interrupt. + * @arg IR_INT_RX_CNT_THR: RX counter threshold interrupt. + * @arg IR_INT_RF_ERROR: RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @arg IR_INT_RISING_EDGE: IR RX Rising edge interrupt. + * @arg IR_INT_FALLING_EDGE: IR RX Falling edge interrupt. + * @retval The new state of IR_INT (SET or RESET). + */ +ITStatus IR_GetINTStatus(uint32_t IR_INT) +{ + ITStatus bit_status = RESET; + + /* Check the parameters */ + assert_param(IS_IR_INT_CONFIG(IR_INT)); + + if (IR->TX_CONFIG & IR_MODE_SEL_Msk) + { + /* Get the selected IR interrupts in RX mode */ + if (IR_INT & IR_RX_EXTENSION_INT) + { + if ((IR->RX_EX_INT & ((IR_INT & 0x03) << 4)) != (uint32_t)RESET) + { + bit_status = SET; + } + } + else + { + if ((IR->RX_SR & IR_INT) != (uint32_t)RESET) + { + bit_status = SET; + } + } + } + else + { + /* Get the selected IR interrupts in TX mode */ + if (IR_INT != IR_INT_TF_OF) + { + if ((IR->TX_SR & IR_INT) != (uint32_t)RESET) + { + bit_status = SET; + } + } + else + { + if ((IR->TX_SR & (IR_INT >> IR_TX_STATUS_TO_EN_Pos)) != (uint32_t)RESET) + { + bit_status = SET; + } + } + } + + /* Return the IR_INT status */ + return bit_status; +} + +/** + * @brief Clears the IR interrupt pending bits. + * @param IR_IT: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg IR_INT_TF_EMPTY_CLR: Clear TX FIFO empty interrupt. + * @arg IR_INT_TF_LEVEL_CLR: Clear TX FIFO threshold interrupt. + * @arg IR_INT_TF_OF_CLR: Clear TX FIFO overflow interrupt. + * @arg IR_INT_RF_FULL_CLR: Clear RX FIFO full interrupt. + * @arg IR_INT_RF_LEVEL_CLR: Clear RX FIFO threshold interrupt. + * @arg IR_INT_RX_CNT_OF_CLR: Clear RX counter overflow interrupt. + * @arg IR_INT_RF_OF_CLR: Clear RX FIFO overflow interrupt. + * @arg IR_INT_RX_CNT_THR_CLR: Clear RX counter threshold interrupt. + * @arg IR_INT_RF_ERROR_CLR: Clear RX FIFO error read interrupt. Trigger when RX FIFO empty and read RX FIFO. + * @arg IR_INT_RX_RISING_EDGE_CLR: Clear RX Rising edge interrupt. + * @arg IR_INT_RX_FALLING_EDGE_CLR: Clear RX Falling edge interrupt. + * @retval None + */ +void IR_ClearINTPendingBit(uint32_t IR_CLEAR_INT) +{ + /* Check the parameters */ + assert_param(IS_IR_INT_CLEAR(IR_CLEAR_INT)); + + if (IR->TX_CONFIG & IR_MODE_SEL_Msk) + { + /* Clear the selected IR interrupts in RX mode */ + if (IR_CLEAR_INT & IR_RX_EXTENSION_INT) + { + IR->RX_EX_INT |= (IR_CLEAR_INT & 0xC0); + } + else + { + IR->RX_INT_CLR |= IR_CLEAR_INT; + } + } + else + { + /* Clear the selected IR interrupts in TX mode */ + IR->TX_INT_CLR |= IR_CLEAR_INT; + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_keyscan.c b/src/mcu/peripheral/rtl876x_keyscan.c new file mode 100644 index 0000000..f5a9a18 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_keyscan.c @@ -0,0 +1,266 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_keyscan.c +* @brief This file provides all the KEYSCAN firmware functions. +* @details +* @author tifnan_ge +* @date 2015-04-30 +* @version v0.1 +********************************************************************************************************* +*/ + +#include "rtl876x_rcc.h" +#include "rtl876x_keyscan.h" + +/** + * @brief Initializes the KeyScan peripheral according to the specified + * parameters in the KeyScan_InitStruct + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_InitStruct: pointer to a KEYSCAN_InitTypeDef structure that + * contains the configuration information for the specified KeyScan peripheral + * @retval None + */ +void KeyScan_Init(KEYSCAN_TypeDef *KeyScan, KEYSCAN_InitTypeDef *KeyScan_InitStruct) +{ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_KEYSCAN_ROW_NUM(KeyScan_InitStruct->rowSize)); + assert_param(IS_KEYSCAN_COL_NUM(KeyScan_InitStruct->colSize)); + assert_param(IS_KEYSCAN_DEBOUNCE_EN(KeyScan_InitStruct->debounceEn)); + assert_param(IS_KEYSCAN_DETECT_MODE(KeyScan_InitStruct->detectMode)); + assert_param(IS_KEYSCAN_FIFO_OVR_CTRL(KeyScan_InitStruct->fifoOvrCtrl)); + assert_param(IS_KEYSCAN_MAX_SCAN_DATA(KeyScan_InitStruct->maxScanData)); + + /* Set FSM to idle state */ + KeyScan->CR &= ~BIT31; + + /* Mask all keyscan interrupt */ + KeyScan->INTMASK |= 0x1f; + + /* clock divider config */ + KeyScan->CLKDIV &= ~((0x3FF << 8) | 0x1F); + KeyScan->CLKDIV |= ((KeyScan_InitStruct->clockdiv << 8)\ + | (KeyScan_InitStruct->delayclk)); + + /* Config scan mode and detect mode*/ + KeyScan->CR = (KeyScan_InitStruct-> scanmode | KeyScan_InitStruct-> detectMode | + KeyScan_InitStruct-> manual_sel | KeyScan_InitStruct->fifoOvrCtrl); + /* fifo threshol setting */ + KeyScan->CR |= (KeyScan_InitStruct ->fifotriggerlevel << 5); + /* key limit setting */ + KeyScan->CR |= (KeyScan_InitStruct ->keylimit << 23); + + /* time config */ + KeyScan->TIMERCR = ((KeyScan_InitStruct ->debounceEn)\ + | (KeyScan_InitStruct->detecttimerEn)\ + | (KeyScan_InitStruct->scantimerEn)); + /* time count config */ + KeyScan->TIMERCR |= ((KeyScan_InitStruct->debouncecnt << 18)\ + | (KeyScan_InitStruct->scanInterval << 9)\ + | (KeyScan_InitStruct->releasecnt)); + + /* Set col map, config which col to work */ + KeyScan->COLCR = ((((1 << KeyScan_InitStruct->colSize) - 1) << 8) \ + | (KeyScan_InitStruct->colSize - 1)); + + /* Set col map, config which col to work */ + KeyScan->ROWCR = ((KeyScan_InitStruct->rowSize - 1) << 16\ + | ((1 << KeyScan_InitStruct->rowSize) - 1)); + + /* clear all interrupt status and status flag */ + KeyScan->INTCLR |= 0xff; + /* Unmask all keyscan interrupt */ + KeyScan->INTMASK &= ~0x1f; + + return; +} + +/** + * @brief Deinitializes the Keyscan peripheral registers to their default reset values(turn off keyscan clock). + * @param KeyScan: selected KeyScan peripheral. + * @retval None + */ +void KeyScan_DeInit(KEYSCAN_TypeDef *KeyScan) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + + RCC_PeriphClockCmd(APBPeriph_KEYSCAN, APBPeriph_KEYSCAN_CLOCK, DISABLE); + + return; +} + + +/** + * @brief Fills each I2C_InitStruct member with its default value. + * @param KeyScan_InitStruct: pointer to an KEYSCAN_InitTypeDef structure which will be initialized. + * @retval None + */ +void KeyScan_StructInit(KEYSCAN_InitTypeDef *KeyScan_InitStruct) +{ + KeyScan_InitStruct->colSize = 2; + KeyScan_InitStruct->rowSize = 2; + + KeyScan_InitStruct->scanmode = KeyScan_Auto_Scan_Mode; + KeyScan_InitStruct->detectMode = KeyScan_Detect_Mode_Level; + KeyScan_InitStruct->clockdiv = 0x1f8; + KeyScan_InitStruct->delayclk = 0x01; + KeyScan_InitStruct->fifotriggerlevel = 1; + KeyScan_InitStruct->fifoOvrCtrl = KeyScan_FIFO_OVR_CTRL_DIS_LAST; + + KeyScan_InitStruct->debounceEn = KeyScan_Debounce_Enable; + KeyScan_InitStruct->scantimerEn = KeyScan_ScanInterval_Enable; + KeyScan_InitStruct->detecttimerEn = KeyScan_Release_Detect_Enable; + + KeyScan_InitStruct->scanInterval = 0x10; + KeyScan_InitStruct->debouncecnt = 0x10; + KeyScan_InitStruct->releasecnt = 0x1; + + KeyScan_InitStruct->keylimit = 0x03; + KeyScan_InitStruct->manual_sel = KeyScan_Manual_Sel_Bit; + + return; +} + +/** + * @brief Enables or disables the specified KeyScan interrupts. + * @param KeyScan: selected KeyScan peripheral. + * @param KeyScan_IT: specifies the KeyScan interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg KEYSCAN_INT_TIMEOUT: KeyScan timeout interrupt mask + * @arg KEYSCAN_INT_OVER_THRESHOLD: Kescan FIFO data over threshold interrupt mask + * @arg KEYSCAN_INT_SCAN_END: KeyScan scan end interrupt mask + * @param NewState: new state of the specified KeyScan interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_INTConfig(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + assert_param(IS_KEYSCAN_CONFIG_IT(KeyScan_IT)); + + if (newState == ENABLE) + { + /* Enable the selected KeyScan interrupts */ + KeyScan->CR |= KeyScan_IT; + } + else + { + /* Disable the selected KeyScan interrupts */ + KeyScan->CR &= (uint32_t)~KeyScan_IT; + } +} + +/** + * @brief Enables or disables the specified KeyScan interrupts mask. + * @param KeyScan: selected KeyScan peripheral. + * @param NewState: new state of the specified KeyScan interrupts mask. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_INTMask(KEYSCAN_TypeDef *KeyScan, uint32_t KeyScan_IT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + + if (newState == ENABLE) + { + /* mask KeyScan interrupts */ + KeyScan->INTMASK |= KeyScan_IT; + } + else + { + /* enable KeyScan interrupts */ + KeyScan->INTMASK &= (~KeyScan_IT); + } +} + +/** + * @brief Read data from keyscan FIFO. + * @param KeyScan: selected KeyScan peripheral. + * @param[out] outBuf: buffer to save data read from KeyScan FIFO. + * @param count: number of data to be read. + * @retval None + */ +void KeyScan_Read(KEYSCAN_TypeDef *KeyScan, uint16_t *outBuf, uint16_t count) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + + uint16_t i = 0; + + for (i = 0; i < count; i++) + { + *outBuf++ = (uint16_t)KeyScan->FIFODATA; + } + + return; +} + +/** + * @brief Enables or disables the KeyScan peripheral. + * @param KeyScan: selected KeyScan peripheral. + * @param NewState: new state of the KeyScan peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void KeyScan_Cmd(KEYSCAN_TypeDef *KeyScan, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected KeyScan peripheral */ + /* In manual mode, bit22 must be write 1 to trigger scan, + and will be clear to 0 automatically after scan finish */ + if (((KeyScan->CR & BIT30) == 0) && ((KeyScan->CR & BIT11) == 0)) + { + KeyScan->CR |= BIT22; + } + + KeyScan->CR |= BIT31; + } + else + { + /* Disable the selected KeyScan peripheral */ + KeyScan->CR &= ~BIT31; + } +} + +/** + * @brief Set filter data. + * @param KeyScan: selected KeyScan peripheral. + * @param data: config the data to be filtered. + * This parameter should not be more than 9 bits + * @retval none. + */ +void KeyScan_FilterDataConfig(KEYSCAN_TypeDef *KeyScan, uint16_t data, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_KeyScan_PERIPH(KeyScan)); + + if (NewState == ENABLE) + { + KeyScan->CR &= ~BIT21; + + KeyScan->CR &= ~(0x1ff << 12); + KeyScan->CR |= ((data & 0x1ff) << 12); + + KeyScan->CR |= BIT21; + } + else + { + KeyScan->CR &= ~BIT21; + + KeyScan->CR &= ~(0x1ff << 12); + KeyScan->CR |= ((data & 0x1ff) << 12); + } + + return; +} diff --git a/src/mcu/peripheral/rtl876x_lpc.c b/src/mcu/peripheral/rtl876x_lpc.c new file mode 100644 index 0000000..26c15a3 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_lpc.c @@ -0,0 +1,379 @@ +/** +********************************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_lpc.c +* @brief This file provides all the lpcomp firmware functions. +* @details +* @author yuan +* @date 2020-11-16 +* @version v1.0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_lpc.h" + +/* Internal defines ------------------------------------------------------------*/ +/* Fast operation register address defines */ +#define REG_FAST_WRITE_BASE_ADDR (0x40000100UL) +#define REG_LPC_FAST_WDATA (0x400001f0UL) +#define REG_LPC_FAST_ADDR (0x400001f4UL) +#define REG_LPC_WR_STROBE (0x400001f8UL) +/* AON register address defines */ +#define LPC_AON_52 (0x52) +#define LPC_AON_114 (0x114) + +/** + * @brief Fast write LPC register + * @param address: the address of LPC register . + * @param data: dta which write to LPC register. + * @retval None + */ +void LPC_WriteReg(uint32_t offset, uint32_t data) +{ + static bool is_called = false; + + if (is_called == false) + { + *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time + is_called = true; + } + + /* Write data */ + *((volatile uint32_t *)REG_LPC_FAST_WDATA) = data; + /* Write RTC register address. Only offset */ + *((volatile uint32_t *)REG_LPC_FAST_ADDR) = offset - REG_FAST_WRITE_BASE_ADDR; + *((volatile uint32_t *)REG_LPC_WR_STROBE) = 1; +} + +/** + * @brief Reset LPC. + * @param None + * @return None + */ +void LPC_DeInit(void) +{ + /* Disable the LPC power */ + uint16_t reg_value = btaon_fast_read_safe(LPC_AON_114); + reg_value &= LPC_AON_114_POWER_EN_CLR; + btaon_fast_write_safe(LPC_AON_114, reg_value); + + /* Stop LPC counter */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_COUNTER_START_CLR)); + + /* Disable out signal */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_OUTPUT_EN_CLR)); + + /* Disable int signal */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_AON_EN_CLR)); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_NV_EN_CLR)); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_CNT_EN_CLR)); + + /* Clear LPC comp value */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CMP)), 0); + + /* Reset counter */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 | LPC_COUNTER_RESET_Msk); + __NOP(); + __NOP(); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 & LPC_COUNTER_RESET_CLR); +} + +/** + * @brief Initializes LPC peripheral according to + * the specified parameters in the LPC_InitStruct. + * @param LPC_InitStruct: pointer to a LPC_InitTypeDef + * structure that contains the configuration information for the + * specified LPC peripheral. + * @retval None + */ +void LPC_Init(LPC_InitTypeDef *LPC_InitStruct) +{ + uint16_t reg_value = 0; + + /* Check the parameters */ + assert_param(IS_LPC_CHANNEL(LPC_InitStruct->LPC_Channel)); + assert_param(IS_LPC_EDGE(LPC_InitStruct->LPC_Edge)); + assert_param(IS_LPC_THRESHOLD(LPC_InitStruct->LPC_Threshold)); + + /* Configure parameters */ + reg_value = btaon_fast_read_safe(LPC_AON_52); + reg_value &= LPC_AON_52_THRESHOLD_Clr; + reg_value |= LPC_InitStruct->LPC_Threshold & LPC_AON_52_THRESHOLD_Msk; + btaon_fast_write_safe(LPC_AON_52, reg_value); + + reg_value = btaon_fast_read_safe(LPC_AON_114); + reg_value &= LPC_AON_114_DEFAULT_Clr; + reg_value |= ((LPC_InitStruct->LPC_Channel) << LPC_AON_114_CH_NUM_Pos) | \ + (LPC_InitStruct->LPC_Edge); + btaon_fast_write_safe(LPC_AON_114, reg_value); + + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 | LPC_LPCOMP_CNT_CLEAR_Msk); + __NOP(); + __NOP(); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR); +} + +/** + * @brief Fills each LPC_InitStruct member with its default value. + * @param LPC_InitStruct : pointer to a LPC_InitTypeDef structure which will be initialized. + * @retval None + */ +void LPC_StructInit(LPC_InitTypeDef *LPC_InitStruct) +{ + LPC_InitStruct->LPC_Channel = LPC_CHANNEL_P2_2; + LPC_InitStruct->LPC_Edge = LPC_Vin_Below_Vth; + LPC_InitStruct->LPC_Threshold = LPC_2000_mV; +} + +/** + * @brief Enables or disables LPC peripheral. + * @param NewState: new state of LPC peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LPC_Cmd(FunctionalState NewState) +{ + uint16_t reg_value = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the LPC power */ + reg_value = btaon_fast_read_safe(LPC_AON_114); + reg_value |= LPC_AON_114_POWER_EN_Msk; + btaon_fast_write_safe(LPC_AON_114, reg_value); + } + else + { + /* Disable the LPC power */ + reg_value = btaon_fast_read_safe(LPC_AON_114); + reg_value &= LPC_AON_114_POWER_EN_CLR; + btaon_fast_write_safe(LPC_AON_114, reg_value); + } +} + +/** + * @brief Start or stop the LPC counter. + * @param NewState: new state of the LPC counter. + * This parameter can be one of the following values: + * @arg ENABLE: Start LPCOMP counter. + * @arg DISABLE: Stop LPCOMP counter. + * @retval None + */ +void LPC_CounterCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Start the LPCOMP counter */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_COUNTER_START_Msk)); + } + else + { + /* Stop the LPCOMP counter */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) & (LPC_COUNTER_START_CLR))); + } +} + +/** + * @brief Enables or disables the specified LPC interrupts. + * @param LPC_INT: specifies the LPC interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg LPC_INT_LPCOMP_VOL: voltage detection interrupt. + * @arg LPC_INT_LPCOMP_CNT: low power comparator couter interrupt. + * @param NewState: new state of the specified LPC interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void LPC_INTConfig(uint32_t LPC_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_LPC_CONFIG_INT(LPC_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected LPC interrupt */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_INT)); + } + else + { + /* Disable the selected LPC interrupt */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) & (~LPC_INT))); + } +} + +/** + * @brief Enable interrupt signal to CPU NVIC. + * @param This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void LPC_INTCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_INT_LPCOMP_NV_EN_Msk)); + } + else + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_NV_EN_CLR)); + } +} + +/** + * @brief Enable wakeup signal to power sequence. + * @param This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void LPC_WKCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_INT_LPCOMP_AON_EN_Msk)); + } + else + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_INT_LPCOMP_AON_EN_CLR)); + } +} + +/** + * @brief Configure LPCOMP counter's comparator value. + * @param value: LPCOMP counter's comparator value which can be 0 to 0xfff. + * @retval None + */ +void LPC_SetCompValue(uint32_t value) +{ + LPC_WriteReg((uint32_t) & (LPC->LPC_CMP), (value & 0xFFF)); +} + +/** + * @brief Reset the LPC counter. + * @retval none + */ +void LPC_ResetCounter(void) +{ + /* Reset the LPCOMP counter */ + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 | LPC_COUNTER_RESET_Msk)); + __NOP(); + __NOP(); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_COUNTER_RESET_CLR)); +} + +/** + * @brief Checks whether the specified LPC interrupt is set or not. + * @param LPC_FLAG: specifies the LPC interrupt to check. + * This parameter can be one of the following values: + * @arg LPC_FLAG_LPCOMP_AON: couter comparator AON flag. + * @arg LPC_FLAG_LPCOMP_CNT: couter comparator flag. + * @retval The new state of SPI_IT (SET or RESET). + */ +FlagStatus LPC_GetFlagStatus(uint32_t LPC_FLAG) +{ + ITStatus int_status = RESET; + + /* Check the parameters */ + assert_param(IS_LPC_STATUS_INT(LPC_FLAG)); + + if (LPC_FLAG == LPC_FLAG_LPCOMP_AON) + { + if (((LPC->LPC_SR) & LPC_LPCOMP_OUTPUT_AON_Msk) != (uint32_t)RESET) + { + int_status = SET; + } + } + else if (LPC_FLAG == LPC_FLAG_LPCOMP_CNT) + { + if (((LPC->LPC_SR) & LPC_LPCOMP_CNT_Msk) != (uint32_t)RESET) + { + int_status = SET; + } + } + + /* Return the LPC_FLAG status */ + return int_status; +} + +/** + * @brief Clear the specified LPC interrupt. + * @param LPC_FLAG: specifies the LPC interrupt to clear. + * This parameter can be one of the following values: + * @arg LPC_INT_COUNT_COMP: couter comparator interrupt. + * @retval None + */ +void LPC_ClearFlag(uint32_t LPC_FLAG) +{ + /* Check the parameters */ + assert_param(IS_LPC_CLEAR_INT(LPC_FLAG)); + + /* Clear counter comparator interrupt */ + if (LPC_FLAG == LPC_FLAG_LPCOMP_CNT) + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_LPCOMP_CNT_CLEAR_Msk)); + __NOP(); + __NOP(); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR)); + } +} + +/** + * @brief Checks whether the specified LPC interrupt is set or not. + * @param LPC_INT: specifies the LPC interrupt to check. + * This parameter can be one of the following values: + * @arg LPC_INT_COUNT_COMP: couter comparator interrupt. + * @retval The new state of SPI_IT (SET or RESET). + */ +ITStatus LPC_GetINTStatus(uint32_t LPC_INT) +{ + ITStatus int_status = RESET; + + /* Check the parameters */ + assert_param(IS_LPC_STATUS_INT(LPC_INT)); + + if (LPC_INT == LPC_INT_LPCOMP_CNT) + { + if (((LPC->LPC_SR) & LPC_LPCOMP_CNT_Msk) != (uint32_t)RESET) + { + int_status = SET; + } + } + + /* Return the LPC_INT status */ + return int_status; +} + +/** + * @brief Clear the specified LPC interrupt. + * @param LPC_INT: specifies the LPC interrupt to clear. + * This parameter can be one of the following values: + * @arg LPC_INT_COUNT_COMP: couter comparator interrupt. + * @retval None. + */ +void LPC_ClearINTPendingBit(uint32_t LPC_INT) +{ + /* Check the parameters */ + assert_param(IS_LPC_CLEAR_INT(LPC_INT)); + + /* Clear counter comparator interrupt */ + if (LPC_INT == LPC_INT_LPCOMP_CNT) + { + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), ((LPC->LPC_CR0) | LPC_LPCOMP_CNT_CLEAR_Msk)); + __NOP(); + __NOP(); + LPC_WriteReg((uint32_t)(&(LPC->LPC_CR0)), (LPC->LPC_CR0 & LPC_LPCOMP_CNT_CLEAR_CLR)); + } +} +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_nvic.c b/src/mcu/peripheral/rtl876x_nvic.c new file mode 100644 index 0000000..f438338 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_nvic.c @@ -0,0 +1,64 @@ +/** +********************************************************************************************************** +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_nvic.c +* @brief This file provides all the NVIC firmware functions. +* @details +* @author elliot chen +* @date 2015-05-19 +* @version v0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_nvic.h" + +/** + * @brief Initializes the NVIC peripheral according to the specified + * parameters in the NVIC_InitStruct. + * @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains + * the configuration information for the specified NVIC peripheral. + * @retval None + */ +void NVIC_Init(NVIC_InitTypeDef *NVIC_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd)); + + if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE) + { + if (NVIC_InitStruct->NVIC_IRQChannel >= Peripheral_First_IRQn) + { + PERIPHINT->EN |= BIT(NVIC_InitStruct->NVIC_IRQChannel - Peripheral_First_IRQn); + NVIC_InitStruct->NVIC_IRQChannel = Peripheral_IRQn; + } + + NVIC_ClearPendingIRQ(NVIC_InitStruct->NVIC_IRQChannel); + NVIC_SetPriority(NVIC_InitStruct->NVIC_IRQChannel, + NVIC_InitStruct->NVIC_IRQChannelPriority); + NVIC_EnableIRQ(NVIC_InitStruct->NVIC_IRQChannel); + } + else + { + if (NVIC_InitStruct->NVIC_IRQChannel >= Peripheral_First_IRQn) + { + PERIPHINT->EN &= ~BIT(NVIC_InitStruct->NVIC_IRQChannel - Peripheral_First_IRQn); + + if (PERIPHINT->EN == 0) + { + /* Disable Peripheral IRQ Channel */ + NVIC_DisableIRQ(Peripheral_IRQn); + } + } + else + { + /* Disable the Selected IRQ Channels */ + NVIC_DisableIRQ(NVIC_InitStruct->NVIC_IRQChannel); + } + } +} + + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_pinmux.c b/src/mcu/peripheral/rtl876x_pinmux.c new file mode 100644 index 0000000..d5b233e --- /dev/null +++ b/src/mcu/peripheral/rtl876x_pinmux.c @@ -0,0 +1,517 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_pinmux.c +* @brief This file provides all the PINMUX firmware functions. +* @details +* @author Yuan +* @date 2020-11-09 +* @version v1.0.0 +********************************************************************************************************* +*/ + +#include "rtl876x_rcc.h" +#include "rtl876x_pinmux.h" + +const uint16_t PINADDR_TABLE[MAX_PIN_NUM] = //static +{ + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xa0, 0xa2, 0xa4, + 0xea, 0xec, 0xee, 0xf0, 0xf2, 0x80, 0x82, 0x84, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, + 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x00, + 0xa6, 0xa8, 0xaa, 0xac, 0xd0, 0x96, 0x98 +}; + +const uint16_t WKSTATUS_TABLE[MAX_PIN_NUM] = +{ + // Px-0 Px-1 Px-2 Px-3 Px-4 Px-5 Px-6 Px-7 + ((0 << 12) | 0xf4), ((1 << 12) | 0xf4), ((2 << 12) | 0xf4), ((3 << 12) | 0xf4), ((4 << 12) | 0xf4), ((0 << 12) | 0xae), ((1 << 12) | 0xae), ((2 << 12) | 0xae), + ((5 << 12) | 0xf4), ((6 << 12) | 0xf4), ((7 << 12) | 0xf4), ((8 << 12) | 0xf4), ((9 << 12) | 0xf4), ((0 << 12) | 0x9a), ((1 << 12) | 0x9a), ((2 << 12) | 0x9a), + ((0 << 12) | 0xd2), ((1 << 12) | 0xd2), ((2 << 12) | 0xd2), ((3 << 12) | 0xd2), ((4 << 12) | 0xd2), ((5 << 12) | 0xd2), ((6 << 12) | 0xd2), ((7 << 12) | 0xd2), + ((3 << 12) | 0x9a), ((4 << 12) | 0x9a), ((5 << 12) | 0x9a), ((6 << 12) | 0x9a), ((7 << 12) | 0x9a), ((8 << 12) | 0x9a), ((9 << 12) | 0x9a), ((0 << 00) | 0x00), + ((3 << 12) | 0xae), ((4 << 12) | 0xae), ((5 << 12) | 0xae), ((6 << 12) | 0xae), ((8 << 12) | 0xd2), ((11 << 12) | 0x9a), ((12 << 12) | 0x9a) +}; + +/** + * @brief Reset all pin to default value. + * @param None. + * @note: two SWD pins will also be reset. Please use this function carefully. + * @retval None + */ +void Pinmux_Reset(void) +{ + uint8_t i; + + for (i = 0; i < 10; i++) + { + PINMUX->CFG[i] = 0x00; + } + + return; +} + +/** + * @brief Deinit the IO function of one pin. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @retval None + */ +void Pinmux_Deinit(uint8_t Pin_Num) +{ + uint8_t pinmux_reg_num; + + pinmux_reg_num = Pin_Num >> 2; + PINMUX->CFG[pinmux_reg_num] &= ~(0xff << ((Pin_Num % 4) << 3)); + return; +} + +/** + * @brief Config pin to its corresponding IO function. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @param Pin_Func: mean one IO function, please refer to rtl876x_pinmux.h "Pin_Function_Number" part. + * @retval None + */ +void Pinmux_Config(uint8_t Pin_Num, uint8_t Pin_Func) +{ + uint8_t pinmux_reg_num; + uint8_t reg_offset; + + pinmux_reg_num = Pin_Num >> 2; + reg_offset = (Pin_Num & 0x03) << 3; + + PINMUX->CFG[pinmux_reg_num] = (PINMUX->CFG[pinmux_reg_num] & ~(0xFF << reg_offset)) + | Pin_Func << reg_offset; + + return; +} + +/** + * @brief config the corresponding pad. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @param AON_PAD_MODE: use software mode or pinmux mode. + * This parameter can be one of the following values: + * @arg PAD_SW_MODE: use software mode. + * @arg PAD_PINMUX_MODE: use pinmux mode. + * @param AON_PAD_PwrOn: config power of pad. + * This parameter can be one of the following values: + * @arg PAD_NOT_PWRON: shutdown power of pad. + * @arg PAD_IS_PWRON: enable power of pad. + * @param AON_PAD_Pull: config pad pull mode. + * This parameter can be one of the following values: + * @arg PAD_PULL_NONE: no pull. + * @arg PAD_PULL_UP: pull this pin up. + * @arg PAD_PULL_DOWN: pull thi pin down. + * @param AON_PAD_E: config pad out put function. + * This parameter can be one of the following values: + * @arg PAD_OUT_DISABLE: disable pin output. + * @arg PAD_OUT_ENABLE: enable pad output. + * @param AON_PAD_O: config pin output level. + * This parameter can be one of the following values: + * @arg PAD_OUT_LOW: pad output low. + * @arg PAD_OUT_HIGH: pad output high. + * @retval None + */ + +void Pad_Config(uint8_t Pin_Num, + PAD_Mode AON_PAD_Mode, + PAD_PWR_Mode AON_PAD_PwrOn, + PAD_Pull_Mode AON_PAD_Pull, + PAD_OUTPUT_ENABLE_Mode AON_PAD_E, + PAD_OUTPUT_VAL AON_PAD_O) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + + /* Clear reg value first*/ + tmpVal &= ~0xF; + + /* Pull Config */ + if (AON_PAD_Pull == PAD_PULL_UP) + { + tmpVal |= Pull_En; + } + else if (AON_PAD_Pull == PAD_PULL_DOWN) + { + tmpVal |= (Pull_En | Pull_Direction); + } + + /* Output Config */ + tmpVal |= (AON_PAD_O | (AON_PAD_E << 1)); + + if (AON_PAD_Mode) + { + tmpVal |= Pin_Mode; + } + else + { + tmpVal &= ~Pin_Mode; + } + + btaon_fast_write_safe(addr, tmpVal | SHDN); + + /* Pad control mode */ + if (AON_PAD_PwrOn == PAD_NOT_PWRON) + { + tmpVal &= ~SHDN; + btaon_fast_write_safe(addr, tmpVal); + } + +} + +//1ms~64ms +static void System_WakeUpDebounceTime(uint8_t time) +{ + uint16_t tmpVal; + tmpVal = btaon_fast_read_safe(0x2a); + /* clear reg value first */ + tmpVal &= ~(0x3f00); + /* set value */ + tmpVal |= (time & 0x3f) << 8; + /* clear debounce status */ + tmpVal |= (BIT15 | BIT14); + btaon_fast_write_safe(0x2a, tmpVal); +} +/** + * @brief Enable pin wakeup function. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @param Polarity: PAD_WAKEUP_POL_HIGH--use high level wakeup, PAD_WAKEUP_POL_LOW-- use low level wakeup. + * @param[in] DebounceEn: Enable delay function. + * \arg PAD_WK_DEBOUNCE_DISABLE: Disable delay function. + * \arg PAD_WK_DEBOUNCE_ENABLE: Enable delay function. + * @param[in] DebounceTime: Set debounce time, range from 0~63ms. + * @retval None + */ +void System_WakeUpPinEnable(uint8_t Pin_Num, uint8_t Polarity, uint8_t DebounceEn, + uint8_t DebounceTime) +{ + if (DebounceEn == ENABLE) + { + System_WakeUpPinDisable(Pin_Num); + if (DebounceTime >= 64) + { + DebounceTime = 63; + } + System_WakeUpDebounceTime(DebounceTime); + } + else + { + System_DebounceWakeupStatus(); + } + Pad_WakeupPolarityValue(Pin_Num, Polarity); + Pad_WKDebounceConfig(Pin_Num, DebounceEn); + Pad_WakeupEnableValue(Pin_Num, 1); +} + +/** + * @brief Disable pin wakeup function. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @retval None + */ +void System_WakeUpPinDisable(uint8_t Pin_Num) +{ + Pad_WakeupEnableValue(Pin_Num, 0); +} + +/** + * @brief Check debounce wake up status. + * @note: Call this API will clear the debunce wakeup status bit. + * @param None + * @retval Debounce wakeup status + */ +uint8_t System_DebounceWakeupStatus(void) +{ + return Pad_DebounceWakeupStatus(); +} + +/** + * @brief Check wake up pin interrupt status. + * @param Pin_Num: pin number. + * This parameter is from ADC_0 to P4_1, please refer to rtl876x.h "Pin_Number" part. + * @retval Pin interrupt status + */ +uint8_t System_WakeUpInterruptValue(uint8_t Pin_Num) +{ + return Pad_WakeupInterruptValue(Pin_Num); +} + +void Pad_OutputControlValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Output_Val; + } + else + { + tmpVal &= ~Output_Val; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_OutputEnableValue(uint8_t Pin_Num, uint8_t value)//0xf6 +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Output_En; + } + else + { + tmpVal &= ~Output_En; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_PullEnableValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Pull_En; + } + else + { + tmpVal &= ~Pull_En; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_PullUpOrDownValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Pull_Direction; + } + else + { + tmpVal &= ~Pull_Direction; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_PullConfigValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Pull_Resistance; + } + else + { + tmpVal &= ~(Pull_Resistance); + } + btaon_fast_write_safe(addr, tmpVal); +} + +void Pad_PowerOrShutDownValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= SHDN; + } + else + { + tmpVal &= ~SHDN; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_ControlSelectValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Pin_Mode; + } + else + { + tmpVal &= ~Pin_Mode; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_WakeupEnableValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= WakeUp_En; + } + else + { + tmpVal &= ~WakeUp_En; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_WakeupPolarityValue(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= WKPOL; + } + else + { + tmpVal &= ~WKPOL; + } + btaon_fast_write_safe((addr), tmpVal); +} + +void Pad_WKDebounceConfig(uint8_t Pin_Num, uint8_t value) +{ + uint16_t tmpVal; + uint8_t addr = PINADDR_TABLE[Pin_Num]; + + tmpVal = btaon_fast_read_safe(addr); + if (value) + { + tmpVal |= Pin_Debounce; + } + else + { + tmpVal &= ~Pin_Debounce; + } + btaon_fast_write_safe((addr), tmpVal); +} + +uint8_t Pad_WakeupInterruptValue(uint8_t Pin_Num) +{ + uint16_t reg_temp; + uint16_t bit_temp; + uint16_t temp_value = 0; + uint8_t int_value = RESET; + + reg_temp = (WKSTATUS_TABLE[Pin_Num] & ~(0xf000)); + bit_temp = BIT((WKSTATUS_TABLE[Pin_Num] & (0xf000)) >> 12); + temp_value = btaon_fast_read_safe(reg_temp); + if (temp_value & bit_temp) + { + int_value = SET; + } + return int_value; +} + +uint8_t Pad_DebounceWakeupStatus(void) +{ + uint16_t value16 = 0; + uint8_t status_value = RESET; + + value16 = btaon_fast_read_safe(0x2a); + if (value16 & BIT15) + { + status_value = SET; + } + //Write 1 to clear debounceWakeupStatus + btaon_fast_write_safe(0x2a, (value16 | BIT15)); + return status_value; +} + +void Pad_ClearWakeupINTPendingBit(uint8_t Pin_Num) +{ + uint16_t reg_temp; + uint16_t bit_temp; + uint16_t reg_value = 0; + + reg_temp = (WKSTATUS_TABLE[Pin_Num] & ~(0xf000)); + bit_temp = BIT((WKSTATUS_TABLE[Pin_Num] & (0xf000)) >> 12); + reg_value = btaon_fast_read_safe(reg_temp) | bit_temp; + btaon_fast_write_safe(reg_temp, reg_value); +} + +/** + * @brief Clear all wake up pin interrupt pending bit. + * @retun None + */ +void Pad_ClearAllWakeupINT(void) +{ + uint16_t tmpVal; + + tmpVal = btaon_fast_read_safe(0x9a); + tmpVal |= 0x1BFF; + btaon_fast_write_safe(0x9a, tmpVal); + + tmpVal = btaon_fast_read_safe(0xae); + tmpVal |= 0x7F; + btaon_fast_write_safe(0xae, tmpVal); + + tmpVal = btaon_fast_read_safe(0xd2); + tmpVal |= 0x1FF; + btaon_fast_write_safe(0xd2, tmpVal); + + tmpVal = btaon_fast_read_safe(0xf4); + tmpVal |= 0x3FF; + btaon_fast_write_safe(0xf4, tmpVal); +} + +/** + * @brief Spic0 master enable. + * @param value: 0:Disable 1:Enable . + * @retval None + */ +void Spic0_control(uint8_t value) +{ + if (value) + { + HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) | BIT(24)); + } + else + { + HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, + REG_TEST_MODE) & (~BIT(24))); + } +} +/** + * @brief Spic1 master enable. + * @param value: 0:Disable 1:Enable . + * @retval None + */ +void Spic1_control(uint8_t value) +{ + if (value) + { + HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) | BIT(8)); + } + else + { + HAL_WRITE32(SYSTEM_REG_BASE, REG_TEST_MODE, HAL_READ32(SYSTEM_REG_BASE, REG_TEST_MODE) & (~BIT(8))); + } +} + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor *****END OF FILE****/ diff --git a/src/mcu/peripheral/rtl876x_qdec.c b/src/mcu/peripheral/rtl876x_qdec.c new file mode 100644 index 0000000..76bbf48 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_qdec.c @@ -0,0 +1,362 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_qdec.c +* @brief This file provides all the QDEC firmware functions. +* @details +* @author howie_wang +* @date 2016-05-10 +* @version v0.1 +********************************************************************************************************* +*/ +#include "rtl876x_rcc.h" +#include "rtl876x_qdec.h" + +/** + * @brief Initializes the Qdecoder peripheral according to the specified + * parameters in the QDEC_InitStruct + * @param QDECx: selected Qdecoder peripheral. + * @param QDEC_InitStruct: pointer to a QDEC_InitStruct structure that + * contains the configuration information for the specified Qdecoder peripheral + * @retval None + */ +void QDEC_Init(QDEC_TypeDef *QDECx, QDEC_InitTypeDef *QDEC_InitStruct) +{ + assert_param(IS_QDEC_PERIPH(QDECx)); + + QDECx->REG_DIV = (QDEC_InitStruct->scanClockDiv << 4) | (QDEC_InitStruct->debounceClockDiv); + + /* QDEC configure */ + if (QDEC_InitStruct->axisConfigX == ENABLE) + { + /* Clear REG_CR_X Register*/ + QDECx->REG_CR_X &= ~((0xFF << 4) | BIT13 | BIT12 | (0x3)); + + /* Set Manual Initial Phase*/ + if (QDEC_InitStruct->manualLoadInitPhase == ENABLE) + { + QDECx->REG_CR_X &= ~BIT31; + QDECx->REG_CR_X |= BIT2 | (QDEC_InitStruct->initPhaseX); + QDECx->REG_CR_X &= ~BIT2; + + } + else + { + QDECx->REG_CR_X &= ~BIT2; + } + QDECx->REG_CR_X |= ((QDEC_InitStruct->debounceTimeX << 4) | (QDEC_InitStruct->counterScaleX << 13) | + \ + (QDEC_InitStruct->debounceEnableX << 12)); + } + if (QDEC_InitStruct->axisConfigY == ENABLE) + { + /* Clear REG_CR_Y Register*/ + QDECx->REG_CR_Y &= ~((0xFF << 4) | BIT13 | BIT12 | (0x3)); + + /* Set Manual Initial Phase*/ + if (QDEC_InitStruct->manualLoadInitPhase == ENABLE) + { + QDECx->REG_CR_Y &= ~BIT31; + QDECx->REG_CR_Y |= BIT2 | (QDEC_InitStruct->initPhaseY); + QDECx->REG_CR_Y &= ~BIT2; + + } + else + { + QDECx->REG_CR_Y &= ~BIT2; + } + QDECx->REG_CR_Y |= ((QDEC_InitStruct->debounceTimeY << 4) | (QDEC_InitStruct->counterScaleY << 13) | + \ + (QDEC_InitStruct->debounceEnableY << 12)); + } + if (QDEC_InitStruct->axisConfigZ == ENABLE) + { + /* Clear REG_CR_Z Register*/ + QDECx->REG_CR_Z &= ~((0xFF << 4) | BIT13 | BIT12 | (0x3)); + + /* Set Manual Initial Phase*/ + if (QDEC_InitStruct->manualLoadInitPhase == ENABLE) + { + QDECx->REG_CR_Z &= ~BIT31; + QDECx->REG_CR_Z |= BIT2 | (QDEC_InitStruct->initPhaseZ); + QDECx->REG_CR_Z &= ~BIT2; + + } + else + { + QDECx->REG_CR_Z &= ~BIT2; + } + QDECx->REG_CR_Z |= ((QDEC_InitStruct->debounceTimeZ << 4) | (QDEC_InitStruct->counterScaleZ << 13) | + \ + (QDEC_InitStruct->debounceEnableZ << 12)); + } + return; +} + +/** + * @brief Deinitializes the Qdecoder peripheral registers to their default reset values(turn off Qdecoder clock). + * @param QDECx: selected Qdecoder peripheral. + * @retval None + */ +void QDEC_DeInit(QDEC_TypeDef *QDECx) +{ + RCC_PeriphClockCmd(APBPeriph_QDEC, APBPeriph_QDEC_CLOCK, DISABLE); +} + + +/** + * @brief Fills each QDEC_InitStruct member with its default value. + * @param QDEC_InitStruct: pointer to an QDEC_InitStruct structure which will be initialized. + * @retval None + */ +void QDEC_StructInit(QDEC_InitTypeDef *QDEC_InitStruct) +{ + QDEC_InitStruct->scanClockDiv = 0x7CF;/*!< 20M/(scanClockDiv+1) = 10KHz */ + QDEC_InitStruct->debounceClockDiv = 0x4; /*!< 10KHz/(debounceClockDiv +1) = 2K */ + + QDEC_InitStruct->axisConfigX = DISABLE; + QDEC_InitStruct->debounceTimeX = 2 * 5; /*!< 5ms */ + QDEC_InitStruct->counterScaleX = CounterScale_1_Phase; + QDEC_InitStruct->debounceEnableX = Debounce_Disable; + QDEC_InitStruct->initPhaseX = phaseMode0; + + QDEC_InitStruct->axisConfigY = DISABLE; + QDEC_InitStruct->debounceTimeY = 2 * 5; /*!< 5ms */ + QDEC_InitStruct->counterScaleY = CounterScale_1_Phase; + QDEC_InitStruct->debounceEnableY = Debounce_Disable; + QDEC_InitStruct->initPhaseY = phaseMode0; + + QDEC_InitStruct->axisConfigZ = DISABLE; + QDEC_InitStruct->debounceTimeZ = 2 * 5; /*!< 5ms */ + QDEC_InitStruct->counterScaleZ = CounterScale_1_Phase; + QDEC_InitStruct->debounceEnableZ = Debounce_Disable; + QDEC_InitStruct->initPhaseZ = phaseMode0; + + return; +} + + +/** + * @brief Enables or disables the specified Qdecoder interrupts. + * @param QDECx: selected Qdecoder peripheral. + * @param QDEC_IT: specifies the QDECODER interrupts sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg QDEC_X_INT_NEW_DATA: + * @arg QDEC_X_INT_ILLEAGE: + * @arg QDEC_Y_INT_NEW_DATA: + * @arg QDEC_Y_INT_ILLEAGE: + * @arg QDEC_Z_INT_NEW_DATA: + * @arg QDEC_Z_INT_ILLEAGE: + * @param NewState: new state of the specified QDECODER interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QDEC_INTConfig(QDEC_TypeDef *QDECx, uint32_t QDEC_IT, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + assert_param(IS_QDEC_INT_CONFIG(QDEC_IT)); + + if (newState == ENABLE) + { + /* Enable the selected QDECODER interrupts */ + if (QDEC_IT & QDEC_X_INT_NEW_DATA) + { + QDECx->REG_CR_X |= BIT15; + } + if (QDEC_IT & QDEC_Y_INT_NEW_DATA) + { + QDECx->REG_CR_Y |= BIT15; + } + if (QDEC_IT & QDEC_Z_INT_NEW_DATA) + { + QDECx->REG_CR_Z |= BIT15; + } + if (QDEC_IT & QDEC_X_INT_ILLEAGE) + { + QDECx->REG_CR_X |= BIT14; + } + if (QDEC_IT & QDEC_Y_INT_ILLEAGE) + { + QDECx->REG_CR_Y |= BIT14; + } + if (QDEC_IT & QDEC_Z_INT_ILLEAGE) + { + QDECx->REG_CR_Z |= BIT14; + } + } + else + { + /* Disable the selected QDECODER interrupts */ + if (QDEC_IT & QDEC_X_INT_NEW_DATA) + { + QDECx->REG_CR_X &= ~BIT15; + } + if (QDEC_IT & QDEC_Y_INT_NEW_DATA) + { + QDECx->REG_CR_Y &= ~BIT15; + } + if (QDEC_IT & QDEC_Z_INT_NEW_DATA) + { + QDECx->REG_CR_Z &= ~BIT15; + } + if (QDEC_IT & QDEC_X_INT_ILLEAGE) + { + QDECx->REG_CR_X &= ~BIT14; + } + if (QDEC_IT & QDEC_Y_INT_ILLEAGE) + { + QDECx->REG_CR_X &= ~BIT14; + } + if (QDEC_IT & QDEC_Z_INT_ILLEAGE) + { + QDECx->REG_CR_X &= ~BIT14; + } + } + + return; +} + +/** + * @brief Checks whether the specified Qdecoder flag is set or not. + * @param QDECx: selected Qdecoder peripheral. + * @param QDEC_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg QDEC_FLAG_ILLEGAL_STATUS_X: + * @arg QDEC_FLAG_ILLEGAL_STATUS_Y: + * @arg QDEC_FLAG_ILLEGAL_STATUS_Z: + * @arg QDEC_FLAG_NEW_STATUS_X: + * @arg QDEC_FLAG_NEW_STATUS_Y: + * @arg QDEC_FLAG_NEW_STATUS_Z: + * @retval The new state of QDEC_FLAG (SET or RESET). + */ +FlagStatus QDEC_GetFlagState(QDEC_TypeDef *QDECx, uint32_t QDEC_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_CLR_INT_STATUS(QDEC_FLAG)); + + if (((QDEC_FLAG & 0x7) | (QDEC_FLAG & (0x7 << 12)))) + { + if (QDECx->INT_SR & QDEC_FLAG) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_X) + { + if (QDECx->REG_SR_X & (BIT18)) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_Y) + { + if (QDECx->REG_SR_Y & (BIT18)) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_OVERFLOW_Z) + { + if (QDECx->REG_SR_Z & (BIT18)) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_X) + { + if (QDECx->REG_SR_X & (BIT19)) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_Y) + { + if (QDECx->REG_SR_Y & (BIT19)) + { + bitstatus = SET; + } + } + else if (QDEC_FLAG == QDEC_FLAG_UNDERFLOW_Z) + { + if (QDECx->REG_SR_Z & (BIT19)) + { + bitstatus = SET; + } + } + + return bitstatus; +} + +/** + * @brief Enables or disables mask the specified Qdecoder axis interrupts. + * @param QDECx: selected Qdecoder peripheral. + * @param QDEC_AXIS: specifies the Qdecoder axis. + * This parameter can be one or logical OR of the following values: + * @arg QDEC_X_CT_INT_MASK: The qdecoder X axis. + * @arg QDEC_X_ILLEAGE_INT_MASK: The qdecoder Y axis. + * @arg QDEC_Y_CT_INT_MASK: The qdecoder Z axis. + * @arg QDEC_Y_ILLEAGE_INT_MASK: The qdecoder X axis. + * @arg QDEC_Z_CNT_INT_MASK: The qdecoder Y axis. + * @arg QDEC_Z_ILLEAGE_INT_MASK: The qdecoder Z axis. + * @param NewState: new state of the specified Qdecoder interrupts mask. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void QDEC_INTMask(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_INT_MASK_CONFIG(QDEC_AXIS)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + + if (newState == ENABLE) + { + /* mask the selected QDEC interrupts */ + QDECx->INT_MASK |= (QDEC_AXIS); + } + else + { + /* unmask the selected QDEC interrupts */ + QDEC->INT_MASK &= (~(QDEC_AXIS)); + } + + return; +} + +/** + * @brief Get Qdecoder Axis(x/y/z) direction. + * @param QDECx: selected Qdecoder peripheral. + * @param QDEC_AXIS: specifies the Qdecoder axis. + * This parameter can be one of the following values: + * @arg QDEC_AXIS_X: The qdecoder X axis. + * @arg QDEC_AXIS_Y: The qdecoder Y axis. + * @arg QDEC_AXIS_Z: The qdecoder Z axis. + * @param newState + * This parameter can be one of the following values: + * @arg ENABLE: Pause. + * @arg DISABLE: Resume. + * @retval The count of the axis. + */ +void QDEC_Cmd(QDEC_TypeDef *QDECx, uint32_t QDEC_AXIS, + FunctionalState newState) +{ + /* Check the parameters */ + assert_param(IS_QDEC_PERIPH(QDECx)); + assert_param(IS_QDEC_AXIS_DIR(QDEC_AXIS)); + + if (newState == ENABLE) + { + *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) |= BIT31; + } + else + { + *((volatile uint32_t *)(&QDECx->REG_CR_X) + QDEC_AXIS / 2) &= ~(BIT31); + } +} + diff --git a/src/mcu/peripheral/rtl876x_rcc.c b/src/mcu/peripheral/rtl876x_rcc.c new file mode 100644 index 0000000..befb5b0 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_rcc.c @@ -0,0 +1,462 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_rcc.c +* @brief This file provides all the IO clock firmware functions.. +* @details +* @author tifnan_ge +* @date 2015-05-16 +* @version v1.0 +********************************************************************************************************* +*/ +#include "rtl876x.h" +#include "rtl876x_bitfields.h" +#include "rtl876x_rcc.h" + +/** + * @brief Enables or disables the APB peripheral clock. + * @param APBPeriph: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg APBPeriph_TIMER + * @arg APBPeriph_GDMA + * @arg APBPeriph_IF8080 + * @arg APBPeriph_SPI2W + * @arg APBPeriph_KEYSCAN + * @arg APBPeriph_QDEC + * @arg APBPeriph_I2C1 + * @arg APBPeriph_I2C0 + * @arg APBPeriph_IR + * @arg APBPeriph_SPI1 + * @arg APBPeriph_SPI0 + * @arg APBPeriph_UART0 + * @arg APBPeriph_UART1 + * @arg APBPeriph_UART2 + * @arg APBPeriph_GPIO + * @arg APBPeriph_ADC + * @arg APBPeriph_I2S0 + * @arg APBPeriph_I2S1 + * @arg APBPeriph_CODEC + * @param APBPeriph_Clock: specifies the APB peripheral clock config. + * This parameter can be one of the following values(must be the same with APBPeriph): + * @arg APBPeriph_TIMER_CLOCK + * @arg APBPeriph_GDMA_CLOCK + * @arg APBPeriph_IF8080_CLOCK + * @arg APBPeriph_SPI2W_CLOCK + * @arg APBPeriph_KEYSCAN_CLOCK + * @arg APBPeriph_QDEC_CLOCK + * @arg APBPeriph_I2C1_CLOCK + * @arg APBPeriph_I2C0_CLOCK + * @arg APBPeriph_IR_CLOCK + * @arg APBPeriph_SPI1_CLOCK + * @arg APBPeriph_SPI0_CLOCK + * @arg APBPeriph_UART0_CLOCK + * @arg APBPeriph_UART1_CLOCK + * @arg APBPeriph_UART2_CLOCK + * @arg APBPeriph_GPIO_CLOCK + * @arg APBPeriph_ADC_CLOCK + * @arg APBPeriph_I2S0_CLOCK + * @arg APBPeriph_I2S1_CLOCK + * @arg APBPeriph_CODEC_CLOCK + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PeriphClockCmd(uint32_t APBPeriph, uint32_t APBPeriph_Clock, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_APB_PERIPH(APBPeriph)); + assert_param(IS_APB_PERIPH_CLOCK(APBPeriph_Clock)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t apbRegOff = ((APBPeriph & (0x03 << 26)) >> 26); + uint32_t clkRegOff = ((APBPeriph_Clock & (0x03 << 29)) >> 29); + + /*Open clock gating first*/ + if (NewState == ENABLE) + { + if (APBPeriph_Clock == APBPeriph_KEYSCAN_CLOCK) + { + /*Open 5M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT29; + } + else if ((APBPeriph_Clock == APBPeriph_ADC_CLOCK) || (APBPeriph_Clock == APBPeriph_CTC_CLOCK)) + { + /*Open 10M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT22; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT28; + } + else if ((APBPeriph_Clock == APBPeriph_QDEC_CLOCK) || (APBPeriph_Clock == APBPeriph_SPI2W_CLOCK)) + { + /*Open 20M clock source*/ + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT26; + SYSBLKCTRL->u_20C.PERION_REG_SYS_CLK_SEL_2 |= BIT27; + } + else if ((APBPeriph_Clock == APBPeriph_TIMER_CLOCK) || + (APBPeriph_Clock == APBPeriph_ENHTIMER_CLOCK)) + { + /* Enable Timer fixed 40M */ + CLK_SOURCE_REG_2 |= BIT9; + } + } + + /* Special register handle */ + if (NewState == ENABLE) + { + if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) || + (APBPeriph_Clock == APBPeriph_CODEC_CLOCK)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph | APBPeriph_Clock; +// SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= 0x133; + return; + } + } + else + { + if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) || + (APBPeriph_Clock == APBPeriph_CODEC_CLOCK)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph | APBPeriph_Clock); +// SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(0x13F); + return; + } + } + + /* clear flag */ + APBPeriph &= (~(0x03 << 26)); + APBPeriph_Clock &= (~(0x03 << 29)); + + if (NewState == ENABLE) + { + //enable peripheral + *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) |= APBPeriph; + //enable peripheral clock + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= APBPeriph_Clock; + //enable peripheral clock in sleep mode + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= + (APBPeriph_Clock << 1); + } + else + { + //disable peripheral + *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) &= (~APBPeriph); + //disable peripheral clock + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= + (~APBPeriph_Clock); + //disable peripheral clock in sleep mode + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= (~ + (APBPeriph_Clock << 1)); + } + + return; +} + +/** + * @brief Enables or disables the APB peripheral clock. + * @param APBPeriph: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg APBPeriph_TIMER + * @arg APBPeriph_GDMA + * @arg APBPeriph_IF8080 + * @arg APBPeriph_SPI2W + * @arg APBPeriph_KEYSCAN + * @arg APBPeriph_QDEC + * @arg APBPeriph_I2C1 + * @arg APBPeriph_I2C0 + * @arg APBPeriph_IR + * @arg APBPeriph_SPI1 + * @arg APBPeriph_SPI0 + * @arg APBPeriph_UART0 + * @arg APBPeriph_UART1 + * @arg APBPeriph_UART2 + * @arg APBPeriph_GPIO + * @arg APBPeriph_ADC + * @arg APBPeriph_I2S0 + * @arg APBPeriph_I2S1 + * @arg APBPeriph_CODEC + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PeriFunctionConfig(uint32_t APBPeriph, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_APB_PERIPH(APBPeriph)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t apbRegOff = ((APBPeriph & (0x03 << 26)) >> 26); + + /* Special register handle */ + if (NewState == ENABLE) + { + if ((APBPeriph == APBPeriph_I2S0) || ((APBPeriph == APBPeriph_I2S1)) || + (APBPeriph == APBPeriph_CODEC)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph; + return; + } + } + else + { + if ((APBPeriph == APBPeriph_I2S0) || ((APBPeriph == APBPeriph_I2S1)) || + (APBPeriph == APBPeriph_CODEC)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph); + return; + } + } + + /* clear flag */ + APBPeriph &= (~(0x03 << 26)); + + if (NewState == ENABLE) + { + //enable peripheral + *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) |= APBPeriph; + } + else + { + //disable peripheral + *((uint32_t *)(&(SYSBLKCTRL->u_210.PERION_REG_SOC_FUNC_EN)) + apbRegOff) &= (~APBPeriph); + } + + return; +} + +/** + * @brief Enables or disables the APB peripheral clock. + * @param APBPeriph_Clock: specifies the APB peripheral clock config. + * This parameter can be one of the following values(must be the same with APBPeriph): + * @arg APBPeriph_TIMER_CLOCK + * @arg APBPeriph_GDMA_CLOCK + * @arg APBPeriph_SPI2W_CLOCK + * @arg APBPeriph_KEYSCAN_CLOCK + * @arg APBPeriph_QDEC_CLOCK + * @arg APBPeriph_I2C1_CLOCK + * @arg APBPeriph_I2C0_CLOCK + * @arg APBPeriph_IR_CLOCK + * @arg APBPeriph_SPI1_CLOCK + * @arg APBPeriph_SPI0_CLOCK + * @arg APBPeriph_UART0_CLOCK + * @arg APBPeriph_UART1_CLOCK + * @arg APBPeriph_UART2_CLOCK + * @arg APBPeriph_GPIO_CLOCK + * @arg APBPeriph_ADC_CLOCK + * @arg APBPeriph_I2S0_CLOCK + * @arg APBPeriph_I2S1_CLOCK + * @arg APBPeriph_CODEC_CLOCK + * @param NewState: new state of the specified peripheral clock. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void RCC_PeriClockConfig(uint32_t APBPeriph_Clock, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_APB_PERIPH_CLOCK(APBPeriph_Clock)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + uint32_t clkRegOff = ((APBPeriph_Clock & (0x03 << 29)) >> 29); + + /* Special register handle */ + if (NewState == ENABLE) + { + if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) || + (APBPeriph_Clock == APBPeriph_CODEC_CLOCK)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN |= APBPeriph_Clock; + return; + } + } + else + { + if ((APBPeriph_Clock == APBPeriph_I2S0_CLOCK) || ((APBPeriph_Clock == APBPeriph_I2S1_CLOCK)) || + (APBPeriph_Clock == APBPeriph_CODEC_CLOCK)) + { + SYSBLKCTRL->u_220.PERION_REG_SOC_AUDIO_IF_EN &= ~(APBPeriph_Clock); + return; + } + } + + APBPeriph_Clock &= (~(0x03 << 29)); + + if (NewState == ENABLE) + { + //enable peripheral clock + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= APBPeriph_Clock; + //enable peripheral clock in sleep mode + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) |= + (APBPeriph_Clock << 1); + } + else + { + //disable peripheral clock + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= + (~APBPeriph_Clock); + //disable peripheral clock in sleep mode + *((uint32_t *)(&(SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL)) + clkRegOff - 1) &= (~ + (APBPeriph_Clock << 1)); + } + + return; +} + +/** + * @brief I2C clock divider config. + * @param I2Cx: where x can be 0 or 1 to select the I2C peripheral. + * @param ClockDiv: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg I2C_CLOCK_DIV_1 + * @arg I2C_CLOCK_DIV_2 + * @arg I2C_CLOCK_DIV_4 + * @arg I2C_CLOCK_DIV_8 + * @retval None + */ +void RCC_I2CClkDivConfig(I2C_TypeDef *I2Cx, uint16_t ClockDiv) +{ + assert_param(IS_I2C_DIV(ClockDiv)); + + /* Config I2C clock divider */ + if (I2Cx == I2C0) + { + /* disable clock first */ + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 &= ~SYSBLK_ACTCK_I2C0_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 15); + CLK_SOURCE_REG_1 |= (ClockDiv << 15); + + //platform_delay_us(1); + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= SYSBLK_ACTCK_I2C0_EN_Msk; + } + else if (I2Cx == I2C1) + { + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 &= ~SYSBLK_ACTCK_I2C1_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 17); + CLK_SOURCE_REG_1 |= (ClockDiv << 17); + + //platform_delay_us(1); + SYSBLKCTRL->u_238.PERION_r_PON_PERI_CLK_CTRL1 |= SYSBLK_ACTCK_I2C1_EN_Msk; + } + + return; +} + +/** + * @brief SPI clock divider config. + * @param SPIx: where x can be 0 or 1 to select the SPI peripheral. + * @param ClockDiv: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg SPI_CLOCK_DIV_1 + * @arg SPI_CLOCK_DIV_2 + * @arg SPI_CLOCK_DIV_4 + * @arg SPI_CLOCK_DIV_8 + * @retval None + */ +void RCC_SPIClkDivConfig(SPI_TypeDef *SPIx, uint16_t ClockDiv) +{ + assert_param(IS_SPI_DIV(ClockDiv)); + + /* Config I2C clock divider */ + if (SPIx == SPI0) + { + /* disable clock first */ + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_SPI0_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 19); + CLK_SOURCE_REG_1 |= (ClockDiv << 19); + + //platform_delay_us(1); + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_SPI0_EN_Msk; + } + else if (SPIx == SPI1) + { + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_SPI1_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 21); + CLK_SOURCE_REG_1 |= (ClockDiv << 21); + + //platform_delay_us(1); + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_SPI1_EN_Msk; + } + return; +} + +/** + * @brief TIMER & ENH-TIMER clock divider config. + * @param TIMx: selected TIM number. + * @param ClockDiv: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg TIM_CLOCK_DIV_1 + * @arg TIM_CLOCK_DIV_125 + * @arg TIM_CLOCK_DIV_2 + * @arg TIM_CLOCK_DIV_4 + * @arg TIM_CLOCK_DIV_8 + * @arg TIM_CLOCK_DIV_40 + * @retval None + */ +void RCC_TIMClkDivConfig(E_TIM_NUM TIMx, uint16_t ClockDiv) +{ + assert_param(IS_UART_DIV(ClockDiv)); + + /* Config TIM clock divider */ + /* disable clock first */ + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL &= ~SYSBLK_ACTCK_TIMER_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_2 &= ~(0x07 << (13 + (TIMx - 2) * 3)); + CLK_SOURCE_REG_2 |= (ClockDiv << (13 + (TIMx - 2) * 3)); + + //platform_delay_us(1); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= SYSBLK_ACTCK_TIMER_EN_Msk; + + return; +} + +/** + * @brief UART clock divider config. + * @param UARTx: selected UART peripheral. + * @param ClockDiv: specifies the APB peripheral to gates its clock. + * This parameter can be one of the following values: + * @arg UART_CLOCK_DIV_1 + * @arg UART_CLOCK_DIV_2 + * @arg UART_CLOCK_DIV_4 + * @arg UART_CLOCK_DIV_16 + * @retval None + */ +void RCC_UARTClkDivConfig(UART_TypeDef *UARTx, uint16_t ClockDiv) +{ + assert_param(IS_UART_DIV(ClockDiv)); + + /* Config UART clock divider */ + if (UARTx == UART0) + { + /* disable clock first */ + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 &= ~SYSBLK_ACTCK_UART0DATA_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 9); + CLK_SOURCE_REG_1 |= (ClockDiv << 9); + + //platform_delay_us(1); + SYSBLKCTRL->u_234.PERION_REG_PESOC_PERI_CLK_CTRL0 |= SYSBLK_ACTCK_UART0DATA_EN_Msk; + } + else if (UARTx == UART1) + { + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL &= ~SYSBLK_ACTCK_LOGUART_EN_Msk; + //platform_delay_us(1); + + CLK_SOURCE_REG_1 &= ~(0x03 << 11); + CLK_SOURCE_REG_1 |= (ClockDiv << 11); + + //platform_delay_us(1); + SYSBLKCTRL->u_230.PERION_REG_PESOC_CLK_CTRL |= SYSBLK_ACTCK_LOGUART_EN_Msk; + } + + return; +} diff --git a/src/mcu/peripheral/rtl876x_rtc.c b/src/mcu/peripheral/rtl876x_rtc.c new file mode 100644 index 0000000..30de942 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_rtc.c @@ -0,0 +1,444 @@ +/** +********************************************************************************************************* +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_rtc.c +* @brief This file provides all the RTC firmware functions. +* @details +* @author yuan +* @date 2020-11-11 +* @version v2.1.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rtc.h" + +/* Internal defines ------------------------------------------------------------*/ +#define REG_FAST_WRITE_BASE_ADDR (0x40000100UL) +#define REG_RTC_FAST_WDATA (0x400001F0UL) +#define REG_RTC_FAST_ADDR (0x400001F4UL) +#define REG_RTC_WR_STROBE (0x400001F8UL) + +#define AON_FAST_REG_REG2X_AON_SYS 0x26 + +/** + * @brief Fast write RTC register. + * @param reg_address: the register address. + * @param data: data which write to register. + * @return None + */ +void RTC_WriteReg(uint32_t reg_address, uint32_t data) +{ + static bool is_called = false; + + if (is_called == false) + { + *((volatile uint32_t *)0x40000014) |= BIT(9);//no need run this every time + is_called = true; + } + + /* Write data */ + *((volatile uint32_t *)REG_RTC_FAST_WDATA) = data; + /* Write RTC register address. Only offset */ + *((volatile uint32_t *)REG_RTC_FAST_ADDR) = reg_address - REG_FAST_WRITE_BASE_ADDR; + *((volatile uint32_t *)REG_RTC_WR_STROBE) = 1; +} + +/** + * @brief Reset RTC. + * @param None + * @return None + */ +void RTC_DeInit(void) +{ + /* Stop RTC counter */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_START_CLR)); + + /* Disable wakeup signal */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_NV_EN_CLR)); + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_WAKEUP_EN_CLR)); + + /* Clear all RTC interrupt & wakeup */ + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_ALL_INT_CLR_SET | RTC_ALL_WAKEUP_CLR_SET); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); + + /* Clear prescale register */ + RTC_WriteReg((uint32_t)(&(RTC->PRESCALER)), 0); + /* Clear all comparator register */ + RTC_WriteReg((uint32_t)(&(RTC->COMP0)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP1)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP2)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP3)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP0GT)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP1GT)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP2GT)), 0); + RTC_WriteReg((uint32_t)(&(RTC->COMP3GT)), 0); + RTC_WriteReg((uint32_t)(&(RTC->PRE_COMP)), 0); + + /* Reset prescale counter and counter */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC_PRE_COUNTER_RST_Msk | RTC_COUNTER_RST_Msk); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->CR0)), 0x0); +} + +/** + * @brief Set RTC prescaler value. + * @param value: the prescaler value to be set.Should be no more than 12 bits! + * @return None + */ +void RTC_SetPrescaler(uint16_t value) +{ + RTC_WriteReg((uint32_t)(&(RTC->PRESCALER)), value & 0xFFF); +} + +/** + * @brief Start or stop RTC peripheral. + * @param NewState: new state of RTC peripheral. + * This parameter can be the following values: + * @arg ENABLE: start RTC. + * @arg DISABLE: stop RTC. + * @return None + */ +void RTC_Cmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Start RTC */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC->CR0 | RTC_START_Msk); + } + else + { + /* Stop RTC */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), RTC->CR0 & RTC_START_CLR); + } +} + +/** + * @brief Enable or disable the specified RTC interrupts. + * @param RTC_INT: specifies the RTC interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_INT_TICK: tick interrupt + * @arg RTC_INT_OVF: counter overflow interrupt + * @arg RTC_INT_PRE_CMP: prescale compare interrupt + * @arg RTC_INT_PRE_CMP3: prescale & compare 3 interrupt + * @arg RTC_INT_CMP0: compare 0 interrupt + * @arg RTC_INT_CMP1: compare 1 interrupt + * @arg RTC_INT_CMP2: compare 2 interrupt + * @arg RTC_INT_CMP3: compare 3 interrupt + * @param NewState: new state of the specified RTC interrupt. + * This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void RTC_INTConfig(E_RTC_INT RTC_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_INT(RTC_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable the selected RTC comparator interrupt */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_INT)); + } + else + { + /* Disable the selected RTC comparator interrupt */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & (~RTC_INT))); + } +} + +/** + * @brief Enable or disable the specified RTC wakeup function. + * @param RTC_WK: specifies the RTC wakeup function to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_WK_TICK: tick wakeup function + * @arg RTC_WK_OVF: tick wakeup function + * @arg RTC_WK_PRE_CMP: prescale compare wakeup function + * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * @arg RTC_WK_CMP0: compare 0 wakeup function + * @arg RTC_WK_CMP1: compare 1 wakeup function + * @arg RTC_WK_CMP2: compare 2 wakeup function + * @arg RTC_WK_CMP3: compare 3 wakeup function + * @param NewState: new state of the specified RTC wakeup function. + * This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void RTC_WKConfig(E_RTC_WK RTC_WK, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_RTC_WK(RTC_WK)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable the selected RTC comparator interrupt */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_WK)); + } + else + { + /* Disable the selected RTC comparator interrupt */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & (~RTC_WK))); + } +} + +/** + * @brief Enable interrupt signal to CPU NVIC. + * @param This parameter can be: ENABLE or DISABLE. + * @return None. + */ +void RTC_NvCmd(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_NV_EN_Msk)); + } + else + { + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_NV_EN_CLR)); + } +} + +/** + * @brief Enable or disable system wake up of RTC. + * @param NewState: new state of the wake up function. + * This parameter can be: ENABLE or DISABLE. + * @return None + */ +void RTC_SystemWakeupConfig(FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState == ENABLE) + { + /* Enable system wake up */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 | RTC_WAKEUP_EN_Msk)); + } + else + { + /* Disable system wake up */ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0 & RTC_WAKEUP_EN_CLR)); + } +} + +/** + * @brief Reset counter value of RTC. + * @param None + * @return None + */ +void RTC_ResetCounter(void) +{ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) | RTC_COUNTER_RST_Msk); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) & RTC_COUNTER_RST_CLR); +} + +/** + * @brief Reset prescaler counter value of RTC. + * @param None + * @return None + */ +void RTC_ResetPrescalerCounter(void) +{ + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) | RTC_PRE_COUNTER_RST_Msk); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->CR0)), (RTC->CR0) & RTC_PRE_COUNTER_RST_CLR); +} + +/** + * @brief Checks whether the specified RTC interrupt is set or not. + * @param RTC_INT: specifies the RTC interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_INT_TICK: RTC tick interrupt source + * @arg RTC_INT_PRE_COMP: prescale compare interrupt source + * @arg RTC_INT_PRE_COMP3: prescale & compare 3 interrupt source + * @arg RTC_INT_COMP0: compare 0 interrupt source + * @arg RTC_INT_COMP1: compare 1 interrupt source + * @arg RTC_INT_COMP2: compare 2 interrupt source + * @arg RTC_INT_COMP3: compare 3 interrupt source + * @return The new state of RTC_INT (SET or RESET). + */ +ITStatus RTC_GetINTStatus(E_RTC_INT RTC_INT) +{ + /* Check the parameters */ + assert_param(IS_RTC_CONFIG_INT(RTC_INT)); + + ITStatus int_status = RESET; + + if ((RTC->INT_SR & ((uint32_t)RTC_INT >> 8)) != (uint32_t)RESET) + { + int_status = SET; + } + + /* Return the RTC_INT status */ + return int_status; +} + +/** + * @brief Clear the interrupt pending bits of RTC. + * @param RTC_INT: specifies the RTC interrupt flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_INT_TICK: RTC tick interrupt source + * @arg RTC_INT_OVF: RTC counter overflow interrupt source + * @arg RTC_INT_PRE_COMP: prescale compare interrupt source + * @arg RTC_INT_PRE_COMP3: prescale & compare 3 interrupt source + * @arg RTC_INT_COMP0: compare 0 interrupt source + * @arg RTC_INT_COMP1: compare 1 interrupt source + * @arg RTC_INT_COMP2: compare 2 interrupt source + * @arg RTC_INT_COMP3: compare 3 interrupt source + * @return None + */ +void RTC_ClearINTPendingBit(E_RTC_INT RTC_INT) +{ + /* Check the parameters */ + assert_param(IS_RTC_INT(RTC_INT)); + + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), (uint32_t)RTC_INT >> 8); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); +} + +/** + * @brief Checks whether the specified RTC wakeup state is set or not. + * @param RTC_WK: specifies the RTC interrupt source to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_WK_TICK: tick wakeup function + * @arg RTC_WK_OVF: tick wakeup function + * @arg RTC_WK_PRE_CMP: prescale compare wakeup function + * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * @arg RTC_WK_CMP0: compare 0 wakeup function + * @arg RTC_WK_CMP1: compare 1 wakeup function + * @arg RTC_WK_CMP2: compare 2 wakeup function + * @arg RTC_WK_CMP3: compare 3 wakeup function + * @return The new state of RTC_INT (SET or RESET). + */ +ITStatus RTC_GetWakeupStatus(E_RTC_WK RTC_WK) +{ + /* Check the parameters */ + assert_param(IS_RTC_CONFIG_INT(RTC_WK)); + + ITStatus wakeup_status = RESET; + + if ((RTC->INT_SR & ((uint32_t)RTC_WK >> 8)) != (uint32_t)RESET) + { + wakeup_status = SET; + } + + /* Return the RTC_INT status */ + return wakeup_status; +} + +/** + * @brief Clear the wakeup status bits of RTC. + * @param RTC_WK: specifies the RTC wakeup flag to clear. + * This parameter can be any combination of the following values: + * @arg RTC_WK_TICK: tick wakeup function + * @arg RTC_WK_OVF: tick wakeup function + * @arg RTC_WK_PRE_CMP: prescale compare wakeup function + * @arg RTC_WK_PRE_CMP3: prescale & compare 3 wakeup function + * @arg RTC_WK_COMP0GT: compare 0 gt wakeup function + * @arg RTC_WK_COMP1GT: compare 1 gt wakeup function + * @arg RTC_WK_COMP2GT: compare 2 gt wakeup function + * @arg RTC_WK_COMP3GT: compare 3 gt wakeup function + * @arg RTC_WK_CMP0: compare 0 wakeup function + * @arg RTC_WK_CMP1: compare 1 wakeup function + * @arg RTC_WK_CMP2: compare 2 wakeup function + * @arg RTC_WK_CMP3: compare 3 wakeup function + * @return None + */ +void RTC_ClearWakeupStatusBit(E_RTC_WK RTC_WK) +{ + /* Check the parameters */ + assert_param(IS_RTC_WK(RTC_WK)); + + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), (uint32_t)RTC_WK >> 8); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); +} + +/** + * @brief Clear the interrupt pending bit of the select comparator of RTC. + * @param index: the comparator number 0~3. + * @return None + */ +void RTC_ClearCompINT(E_RTC_COMP_INDEX index) +{ + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), BIT(RTC_COMP0_CLR_Pos + index)); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); +} + +/** + * @brief Clear the overflow interrupt pending bit of RTC. + * @param None + * @return None + */ +void RTC_ClearOverFlowINT(void) +{ + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_OVERFLOW_CLR_SET); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); +} + +/** + * @brief Clear the tick interrupt pending bit of RTC. + * @param None + * @return None + */ +void RTC_ClearTickINT(void) +{ + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), RTC_TICK_CLR_SET); + __NOP(); + __NOP(); + RTC_WriteReg((uint32_t)(&(RTC->INT_CLR)), 0); +} + +/** + * @brief Select source clock to gpio input of RTC. + * @param gpio: the selected gpio. + * @retval None + */ +void RTC_SelectSrcToGpioInput(RTC_32K_GPIO_IN gpio) +{ + // SEL_GPIO_32K_rtc = 1, en_gpio_32k = 1 + btaon_fast_update_safe(AON_FAST_REG_REG2X_AON_SYS, BIT10 | BIT11, (0x3 << 10)); + + if (gpio == RTC_32K_XI) + { + // rtc_in_selsy = 0x1 (PAD_32K_XI) + btaon_fast_update_safe(AON_FAST_REG_REG2X_AON_SYS, BIT8 | BIT9, (0x1 << 8)); + } + else + { + // rtc_in_selsy = 0x2 (PAD_P2_4) + btaon_fast_update_safe(AON_FAST_REG_REG2X_AON_SYS, BIT8 | BIT9, (0x2 << 8)); + } +} + + +/******************* (C) COPYRIGHT 2020 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_spi.c b/src/mcu/peripheral/rtl876x_spi.c new file mode 100644 index 0000000..f831f06 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_spi.c @@ -0,0 +1,352 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_spi.c +* @brief This file provides all the Spi firmware functions. +* @details +* @author elliot chen +* @date 2015-05-06 +* @version v0.1 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_spi.h" +#include "rtl876x_rcc.h" + +/** + * @brief Deinitializes the SPIx peripheral registers to their default reset values. + * @param SPIx: where x can be 0 or 1 to select the SPI peripheral. + * @retval None + */ +void SPI_DeInit(SPI_TypeDef *SPIx) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /*Disable SPI clock */ + if (SPIx == SPI0) + { + RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, DISABLE); + } + else + { + RCC_PeriphClockCmd(APBPeriph_SPI1, APBPeriph_SPI1_CLOCK, DISABLE); + } +} + +/** + * @brief Initializes the SPIx peripheral according to the specified + * parameters in the SPI_InitStruct. + * @param SPIx: where x can be 0 or 1 to select the SPI peripheral. + * @param SPI_InitStruct: pointer to a SPI_InitTypeDef structure that + * contains the configuration information for the specified SPI peripheral. + * @retval None + */ +void SPI_Init(SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + /* Check the SPI parameters */ + assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction)); + assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode)); + assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize)); + assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL)); + assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA)); + assert_param(IS_SPI_FRAME_FORMAT(SPI_InitStruct->SPI_FrameFormat)); + + /* Disable SPI device before change configuration */ + SPIx->SSIENR &= ~0x01; + + /*Set SPI Rx sample delay */ + SPIx->RX_SAMPLE_DLY = 0x01; + + /* Configure SPI0 mode if select SPI0 */ + if (SPIx == SPI0) + { + if (SPI_InitStruct->SPI_Mode == SPI_Mode_Master) + { + /*Enable SPI0 master mode*/ + *((volatile uint32_t *)0x40000308) = *((volatile uint32_t *)0x40000308) | BIT(0); + /* configure SPI parameters */ + SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize << 16)\ + | (SPI_InitStruct->SPI_FrameFormat << 4) \ + | (SPI_InitStruct->SPI_CPHA << 6)\ + | (SPI_InitStruct->SPI_CPOL << 7) \ + | (SPI_InitStruct->SPI_Direction << 8) \ + | (SPI_InitStruct->SPI_ToggleEn << 24); + } + else + { + /*Enable SPI0 slave mode*/ + *((volatile uint32_t *)0x40000308) = *((volatile uint32_t *)0x40000308) & (~(BIT(0))); + /* configure SPI parameters */ + SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize) + | (SPI_InitStruct->SPI_FrameFormat << 4) + | (SPI_InitStruct->SPI_CPHA << 6) + | (SPI_InitStruct->SPI_CPOL << 7) + | (SPI_InitStruct->SPI_Direction << 8) + | (SPI_InitStruct->SPI_SwapTxBitEn << 22) + | (SPI_InitStruct->SPI_SwapRxBitEn << 24) + | (SPI_InitStruct->SPI_SwapTxByteEn << 21) + | (SPI_InitStruct->SPI_SwapRxByteEn << 23) + | (SPI_InitStruct->SPI_ToggleEn << 31); + } + + } + else if (SPIx == SPI1) + { + /* configure SPI parameters */ + SPIx->CTRLR0 = (SPI_InitStruct->SPI_DataSize << 16) + | (SPI_InitStruct->SPI_FrameFormat << 4) + | (SPI_InitStruct->SPI_CPHA << 6) + | (SPI_InitStruct->SPI_CPOL << 7) + | (SPI_InitStruct->SPI_Direction << 8) + | (SPI_InitStruct->SPI_ToggleEn << 24); + } + + /* configure SPI clock speed in master mode or enable slave output in slave mode */ + if (SPI_InitStruct->SPI_Mode == SPI_Mode_Master) + { + SPIx->BAUDR = (SPI_InitStruct->SPI_BaudRatePrescaler) % 0xFFFF; + /* Enable slave Select function in master mode */ + SPIx->SER |= BIT(0); + } + else + { + /* Enable slave output */ + SPIx->CTRLR0 &= ~(BIT(10)); + } + + /*set SPI Tx and Rx threshold level ,below this level or equal this level would trigger Tx and Rx FIFO empty interrupt */ + SPIx->TXFTLR = SPI_InitStruct->SPI_TxThresholdLevel; + SPIx->RXFTLR = SPI_InitStruct->SPI_RxThresholdLevel; + + /* mask SPI interrupt in REG_DW_SSI_IMR */ + SPIx->IMR = 0; + + /* set read length in SPI EEPROM & rx only mode */ + if ((SPI_InitStruct->SPI_Direction == 0x02) || (SPI_InitStruct->SPI_Direction == 0x03)) + { + SPIx->CTRLR1 = SPI_InitStruct->SPI_NDF; + } +#if 1 + + /* Config SPI dma mode */ + SPIx->DMACR = ((SPI_InitStruct->SPI_RxDmaEn)\ + | ((SPI_InitStruct->SPI_TxDmaEn) << 1)); + + /* Config SPI waterlevel */ + SPIx->DMARDLR = SPI_InitStruct->SPI_RxWaterlevel; + SPIx->DMATDLR = SPI_InitStruct->SPI_TxWaterlevel; +#endif +} + +/** + * @brief Fills each SPI_InitStruct member with its default value. + * @param SPI_InitStruct : pointer to a SPI_InitTypeDef structure which will be initialized. + * @retval None + */ +void SPI_StructInit(SPI_InitTypeDef *SPI_InitStruct) +{ + SPI_InitStruct->SPI_Mode = SPI_Mode_Master; + SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b; /* 8-bit serial data transfer */ + SPI_InitStruct->SPI_FrameFormat = 0; /* 0:FRF_MOTOROLA_SPI; 1,2,3:Reserved */ + SPI_InitStruct->SPI_Direction = + 0; /* 0:TX and RX Mode; 1:TX Only Mode; 2:RX Only Mode; + 3:EEPROM Read Mode */ + SPI_InitStruct->SPI_CPOL = + 1; /* 0:inactive state of clock is low; 1:inactive + state of clock is high */ + SPI_InitStruct->SPI_CPHA = + 1; /* 1:Serial clock toggles in first of first data bit; + 0:Serial clock toggles in middle of first data bit*/ + SPI_InitStruct->SPI_BaudRatePrescaler = + SPI_BaudRatePrescaler_128; /* Speed = SPI Clock source/ SPI_ClkDIV*/ + SPI_InitStruct->SPI_TxThresholdLevel = 1; /* Transmit FIFO Threshold */ + SPI_InitStruct->SPI_RxThresholdLevel = 0; /* Receive FIFO Threshold */ + SPI_InitStruct->SPI_NDF = 1; + SPI_InitStruct->SPI_SwapRxBitEn = SPI_SWAP_DISABLE; /* reverse the rx bit or not */ + SPI_InitStruct->SPI_SwapTxBitEn = SPI_SWAP_DISABLE; + SPI_InitStruct->SPI_SwapRxByteEn = SPI_SWAP_DISABLE; + SPI_InitStruct->SPI_SwapTxByteEn = SPI_SWAP_DISABLE; + SPI_InitStruct->SPI_ToggleEn = DISABLE; + + SPI_InitStruct->SPI_RxDmaEn = DISABLE; + SPI_InitStruct->SPI_TxDmaEn = DISABLE; + SPI_InitStruct->SPI_RxWaterlevel = + 1; /* SPI Rx waterlevel, should be less than fifo threshold, the best value is + GDMA Msize */ + SPI_InitStruct->SPI_TxWaterlevel = + 35; /* SPI Tx waterlevel, should be less than fifo threshold, the best value is + SPI FIFO Depth minus GDMA Msize */ +} + +/** + * @brief Enables or disables the specified SPI peripheral. + * @param SPIx: where x can be 0 or 1 to select the SPI peripheral. + * @param NewState: new state of the SPIx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_Cmd(SPI_TypeDef *SPIx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI peripheral */ + SPIx->SSIENR |= 0x01; + } + else + { + /* Disable the selected SPI peripheral */ + SPIx->SSIENR &= ~0x01; + } +} + +/** + * @brief Transmits a number of bytes through the SPIx peripheral. + * @param SPIx: where x can be 0 or 1 + * @param Data : bytes to be transmitted. + * @retval None + */ +void SPI_SendBuffer(SPI_TypeDef *SPIx, uint8_t *pBuf, uint16_t len) +{ + uint16_t i = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + for (i = 0; i < len; i++) + { + SPIx->DR[0] = (*pBuf++); + /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/ + while (!(SPIx->SR & BIT(1))); + } +} + +/** + * @brief Transmits a number of words through the SPIx peripheral. + * @param SPIx: where x can be 0 or 1 + * @param Data : words to be transmitted. + * @retval None + */ +void SPI_SendWord(SPI_TypeDef *SPIx, uint32_t *pBuf, uint16_t len) +{ + uint16_t i = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + for (i = 0; i < len; i++) + { + SPIx->DR[0] = (*pBuf++); + /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/ + while (!(SPIx->SR & BIT(1))); + } +} + +/** + * @brief Transmits a number of halfWords through the SPIx peripheral. + * @param SPIx: where x can be 0 or 1 + * @param Data : Halfwords to be transmitted. + * @retval None + */ +void SPI_SendHalfWord(SPI_TypeDef *SPIx, uint16_t *pBuf, uint16_t len) +{ + uint16_t i = 0; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + + for (i = 0; i < len; i++) + { + SPIx->DR[0] = (*pBuf++); + /*read TFNF bit status in SR register: SET is Tx FIFO is not full*/ + while (!(SPIx->SR & BIT(1))); + } +} + +/** + * @brief Enables or disables the specified SPI/I2S interrupts. + * @param SPIx: where x can be 0 or 1 + * @param SPI_IT: specifies the SPI/I2S interrupt source to be enabled or disabled. + * This parameter can be one of the following values: + * @arg SPI_INT_TXE: Tx buffer empty interrupt mask + * @arg SPI_INT_TXO: Tx buffer overflow interrupt mask + * @arg SPI_INT_RXU: receive FIFO Underflow Interrupt mask + * @arg SPI_INT_RXO: receive FIFO Overflow Interrupt mask + * @arg SPI_INT_RXF: receive FIFO Full Interrupt mask which equal RXNE Interrupt!!! + * @arg SPI_INT_MST: multi-Master Contention Interrupt mask + * @param NewState: new state of the specified SPI interrupt. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void SPI_INTConfig(SPI_TypeDef *SPIx, uint8_t SPI_IT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + assert_param(IS_SPI_CONFIG_IT(SPI_IT)); + + if (NewState != DISABLE) + { + /* Enable the selected SPI interrupt */ + SPIx->IMR |= SPI_IT; + } + else + { + /* Disable the selected SPI interrupt */ + SPIx->IMR &= (uint16_t)~(SPI_IT); + } +} + +/** + * @brief Clear the specified SPI interrupt. + * @param SPIx: where x can be 0 or 1 + * @param SPI_IT: specifies the SPI interrupt to clear. + * This parameter can be one of the following values: + * @arg SPI_INT_MST: Multi-Master Contention Interrupt. + * @arg SPI_INT_RXO: Receive FIFO Overflow Interrupt. + * @arg SPI_INT_RXU: Receive FIFO Underflow Interrupt. + * @arg SPI_INT_TXO: Transmit FIFO Overflow Interrupt . + * @retval None. + */ +void SPI_ClearINTPendingBit(SPI_TypeDef *SPIx, uint16_t SPI_IT) +{ + /* Check the parameters */ + assert_param(IS_SPI_ALL_PERIPH(SPIx)); + assert_param(IS_SPI_CONFIG_IT(SPI_IT)); + + switch (SPI_IT) + { + case SPI_INT_RXO: + SPIx->RXOICR; + break; + case SPI_INT_RXU: + SPIx->RXUICR; + break; + case SPI_INT_TXO: + SPIx->TXOICR; + break; + case SPI_INT_MST: + SPIx->FAEICR; + break; + case SPI_INT_TUF: + SPIx->TXUICR; + break; + case SPI_INT_RIG: + SPIx->SSRICR; + break; + default: + break; + } + +} +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_tim.c b/src/mcu/peripheral/rtl876x_tim.c new file mode 100644 index 0000000..a80b64a --- /dev/null +++ b/src/mcu/peripheral/rtl876x_tim.c @@ -0,0 +1,363 @@ +/** +********************************************************************************************************** +* Copyright(c) 2020, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_tim.c +* @brief This file provides all the Timer firmware functions. +* @details +* @author Yuan +* @date 2020.09.29 +* @version v1.0.0 +********************************************************************************************************* +*/ + +/* Includes ------------------------------------------------------------------*/ +#include "rtl876x_rcc.h" +#include "rtl876x_tim.h" + +/* TIM Private Defines */ +#define TIMER_CLK_SOURCE_REG_35C *((volatile uint32_t *)0x4000035CUL) +#define TIMER_CLK_SOURCE_REG_360 *((volatile uint32_t *)0x40000360UL) + +#define TIMER_INTTERRUPT_TIME_MIN (5) +#define TIMER_INTERRUPT_MASK BIT(2) + +/** + * @brief Deinitializes the TIMx peripheral registers to their default reset values. + * @param None + * @retval None + */ +void TIM_DeInit() +{ + /*enable timer IP clock and function */ + RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, DISABLE); +} + +/** + * @brief Initializes the TIMx Time Base Unit peripheral according to + * the specified parameters in the TIM_TimeBaseInitStruct. + * @param TIMx: where x can be 2 to 5 to select the TIM peripheral. + * @param TIM_TimeBaseInitStruct: pointer to a TIM_TimeBaseInitTypeDef + * structure that contains the configuration information for the + * specified TIM peripheral. + * @retval None + */ +void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct) +{ + uint32_t timerid = 0; + uint32_t tempreg = 0; + volatile uint32_t *count2_address; + + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_TIM_MODE(TIM_TimeBaseInitStruct->TIM_Mode)); + assert_param(IS_TIM_PWM_DeadZone_En(TIM_TimeBaseInitStruct->PWMDeadZone_En)); + + /* Select clock source which can be system clock or 40 MHz or pll*/ + tempreg = (uint32_t)TIMx; + timerid = (tempreg - TIM0_REG_BASE) / 20; + + /*div the clock source,actually it need enable TIM_SOURCE_CLOCK_DIV_EN*/ + TIMER_CLK_SOURCE_REG_360 |= BIT9; + + if (TIMER_CLK_SOURCE_REG_360 & BIT(10)) + { + TIMER_CLK_SOURCE_REG_360 &= ~(BIT(10)); + } + + if (timerid < 2) + { + TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (timerid * 3)); + TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) << (timerid * 3)); + } + else if ((timerid >= 2) && (timerid < 6)) + { + TIMER_CLK_SOURCE_REG_360 &= ~(0x7 << (((timerid - 2) * 3) + 13)); + TIMER_CLK_SOURCE_REG_360 |= ((TIM_TimeBaseInitStruct->TIM_SOURCE_DIV) \ + << (((timerid - 2) * 3) + 13)); + } + + if (timerid == 3 || timerid == 5) + { + if (TIM_TimeBaseInitStruct->ClockDepend == true) + { + TIMER_CLK_SOURCE_REG_35C |= BIT(((timerid - 1) >> 1) - 1); + } + else + { + TIMER_CLK_SOURCE_REG_35C &= ~BIT(((timerid - 1) >> 1) - 1); + } + } + + /* set timer mode and mask interrupt */ + if (TIM_TimeBaseInitStruct->TIM_PWM_En == PWM_DISABLE) + { + TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2); + /* set timer period */ + TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_Period; + } + else + { + TIMx->ControlReg = (TIM_TimeBaseInitStruct->TIM_Mode << 1) | BIT(2) | BIT(3); + count2_address = &TIMER0_LOAD_COUNT2; + count2_address = count2_address + timerid; + *count2_address = TIM_TimeBaseInitStruct->TIM_PWM_High_Count ; + /* set timer period */ + TIMx->LoadCount = TIM_TimeBaseInitStruct->TIM_PWM_Low_Count; + } + + /* set pwm deadzone mode, pwm0_pn based on timer2 */ + if (TIM_TimeBaseInitStruct->PWMDeadZone_En == ENABLE) + { + if (timerid == 2) + { + /* set pwm deadzone time */ + TIMER_PWM2_CR = ((TIM_TimeBaseInitStruct->PWM_Deazone_Size) \ + | (TIM_TimeBaseInitStruct->PWM_Stop_State_N << 9) \ + | (TIM_TimeBaseInitStruct->PWM_Stop_State_P << 10) \ + | BIT12 | BIT17 | BIT18); + } + } + else + { + if (timerid == 2) + { + /*disable pwm2 deadzone mode*/ + TIMER_PWM2_CR &= ~(BIT12 | BIT17 | BIT18); + } + } + + /* Clear the IT status */ + TIMx->EOI; +} + +/** + * @brief Fills each TIM_InitStruct member with its default value. + * @param TIM_InitStruct : pointer to a TIM_InitTypeDef structure which will be initialized. + * @retval None + */ +void TIM_StructInit(TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct) +{ + TIM_TimeBaseInitStruct->TIM_Mode = TIM_Mode_UserDefine; + TIM_TimeBaseInitStruct->TIM_Period = 0xfff; + TIM_TimeBaseInitStruct->TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_1; + TIM_TimeBaseInitStruct->ClockDepend = false; + TIM_TimeBaseInitStruct->TIM_PWM_En = PWM_DISABLE; + TIM_TimeBaseInitStruct->PWM_Stop_State_P = PWM_STOP_AT_LOW; + TIM_TimeBaseInitStruct->PWM_Stop_State_N = PWM_STOP_AT_HIGH; + TIM_TimeBaseInitStruct->PWMDeadZone_En = DEADZONE_DISABLE; +} + +/** + * @brief Enable or disable the specified TIM peripheral. + * Attention: If interrupt status can't be cleared normally after disable TIM by this API, + * you can choose API of TIM_CmdSafe to disable TIM. + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_Cmd(TIM_TypeDef *TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (NewState != DISABLE) + { + /* Enable the TIM Counter */ + TIMx->ControlReg |= BIT(0); + } + else + { + /* Disable the TIM Counter */ + TIMx->ControlReg &= ~(BIT(0)); + } +} + +/** + * @brief Protective measures for turning off the TIM. + * This function should be used after TIM_ClearINT function otherwise it will occur an error. + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @retval None + */ +void TIM_CmdSafe(TIM_TypeDef *TIMx) +{ + uint32_t timerid = 0; + uint32_t tempreg = 0; + tempreg = (uint32_t)TIMx; + timerid = (tempreg - TIM0_REG_BASE) / 20; + uint32_t status = (TIMER_RAWINTSTATUS & BIT(timerid)) >> timerid; + + /* mask interrupt */ + TIMx->ControlReg |= TIMER_INTERRUPT_MASK; + + /* Check whether the Raw IntStatus is cleared */ + if (status == 0x1) + { + /* Determine whether the current value is less than the min value */ + if (TIMx->CurrentValue < TIMER_INTTERRUPT_TIME_MIN) + { + /* Wait for the Raw IntStatus from 1 to 0 */ + while (((TIMER_RAWINTSTATUS & BIT(timerid)) >> timerid) == 0x1); + TIM_Cmd(TIMx, DISABLE); + } + else + { + TIM_Cmd(TIMx, DISABLE); + } + } + else + { + TIM_Cmd(TIMx, DISABLE); + } +} + +/** + * @brief change TIM period value. + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @retval The new state of success or not (SET or RESET). + */ +void TIM_ChangePeriod(TIM_TypeDef *TIMx, uint32_t period) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + TIMx->LoadCount = period; + + return; +} + +/** + * @brief Enables or disables the specified TIMx interrupt. + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @param NewState: new state of the TIMx peripheral. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void TIM_INTConfig(TIM_TypeDef *TIMx, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_TIM_ALL_PERIPH(TIMx)); + + if (NewState != DISABLE) + { + /* Enable the Interrupt sources */ + TIMx->ControlReg &= ~(BIT(2)); + } + else + { + /* Disable the Interrupt sources */ + TIMx->ControlReg |= BIT(2); + } +} + +/** + * @brief Change PWM freq and duty according high_cnt and low_cnt + * @param TIMx: where x can be 2 to 5 to select the TIMx peripheral. + * @param high_count: + * This parameter can be: + * @param low_count: + * This parameter can be: + * @retval None + */ +void TIM_PWMChangeFreqAndDuty(TIM_TypeDef *TIMx, uint32_t high_count, uint32_t low_count) +{ + volatile uint32_t *count2_address; + uint32_t timerid = 0; + uint32_t tempreg = 0; + tempreg = (uint32_t)TIMx; + timerid = (tempreg - TIM0_REG_BASE) / 20; + TIMx->LoadCount = low_count; + count2_address = &TIMER0_LOAD_COUNT2; + count2_address = count2_address + timerid; + *count2_address = high_count; + +} + +/** + * \brief PWM complementary output emergency stop. + * PWM_P emergency stop level state is configured by PWM_Stop_State_P, + * PWM_N emergency stop level state is configured by PWM_Stop_State_N. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of complementary output. + * \ref DISABLE: Resume PWM complementary output. + * \ref ENABLE: PWM complementary output emergency stop. + * \return None. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + */ +void TIM_PWMComplOutputEMCmd(PWM_TypeDef *PWMx, FunctionalState NewState) +{ + /* Check the parameters. */ + assert_param(IS_PWM_ALL_PERIPH(PWMx)); + + if (NewState != DISABLE) + { + /* PWM complementary output emergency stop. */ + PWMx->CR |= BIT8; + } + else + { + /* Resume PWM complementary output. */ + PWMx->CR &= (~BIT8); + } +} + +/** + * \brief Enable or disable bypass dead zone function of PWM complementary output. + * After enabling, PWM_P = ~PWM_N. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of the PWMx peripheral. + * \ref DISABLE: Disable bypass dead zone function. + * \ref ENABLE: Enable bypass dead zone function. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + * \return None. + */ +void TIM_PWMDZBypassCmd(PWM_TypeDef *PWMx, FunctionalState NewState) +{ + /* Check the parameters. */ + assert_param(IS_PWM_ALL_PERIPH(PWMx)); + + if (NewState != DISABLE) + { + /* Enable bypass dead zone function. */ + PWMx->CR |= BIT13; + } + else + { + /* Disable bypass dead zone function. */ + PWMx->CR &= (~BIT13); + } +} + +/** + * \brief Change the PWM dead zone clock source. + * \param[in] PWMx: PWM2. + * \param[in] NewState: New state of the PWMx peripheral. + * \ref DISABLE: Use 32k clock source. + * \ref ENABLE: Use 5M clock source. + * \return None. + * \note To use this function, need to configure the corresponding timer. + * PWM2 ->> TIM2. + */ +void TIM_PWMChangeDZClockSrc(PWM_TypeDef *PWMx, FunctionalState NewState) +{ + /* Check the parameters. */ + assert_param(IS_PWM_ALL_PERIPH(PWMx)); + + if (NewState != DISABLE) + { + /* Use 5M clock source. */ + PWMx->CR |= BIT16; + } + else + { + /* Use 32k clock source. */ + PWMx->CR &= (~BIT16); + } +} + +/******************* (C) COPYRIGHT 2015 Realtek Semiconductor Corporation *****END OF FILE****/ + diff --git a/src/mcu/peripheral/rtl876x_uart.c b/src/mcu/peripheral/rtl876x_uart.c new file mode 100644 index 0000000..77f2088 --- /dev/null +++ b/src/mcu/peripheral/rtl876x_uart.c @@ -0,0 +1,422 @@ +/** +********************************************************************************************************* +* Copyright(c) 2019, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file rtl876x_uart.c +* @brief This file provides all the UART firmware functions. +* @details +* @author yuan +* @date 2019-11-14 +* @version v1.0 +********************************************************************************************************* +*/ +#include "rtl876x_rcc.h" +#include "rtl876x_uart.h" + +#define LCR_DLAB_Set ((uint32_t)(1 << 7)) +#define LCR_DLAB_Reset ((uint32_t)~(1 << 7)) + +/** + * @brief Deinitializes the UART peripheral registers to their default reset values(turn off UART clock). + * @param UARTx: selected UART peripheral. + * @retval None + */ +void UART_DeInit(UART_TypeDef *UARTx) +{ + assert_param(IS_UART_PERIPH(UARTx)); + + if (UARTx == UART0) + { + RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, DISABLE); + } + else if (UARTx == UART1) + { + RCC_PeriphClockCmd(APBPeriph_UART1, APBPeriph_UART1_CLOCK, DISABLE); + } +// else if (UARTx == UART2) +// { +// RCC_PeriphClockCmd(APBPeriph_UART2, APBPeriph_UART2_CLOCK, DISABLE); +// } + return; +} + +/** + * @brief Initializes the UART peripheral according to the specified + * parameters in the UART_InitStruct + * @param UARTx: selected UART peripheral. + * @param UART_InitStruct: pointer to a UART_InitTypeDef structure that + * contains the configuration information for the specified UART peripheral + * @retval None + */ +void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct) +{ + assert_param(IS_UART_PERIPH(UARTx)); + assert_param(IS_UART_WORD_LENGTH(UART_InitStruct->UART_WordLen)); + assert_param(IS_UART_STOPBITS(UART_InitStruct->UART_StopBits)); + assert_param(IS_UART_PARITY(UART_InitStruct->UART_Parity)); + assert_param(IS_UART_RX_FIFO_TRIGGER_LEVEL(UART_InitStruct->UART_RxThdLevel)); + assert_param(IS_UART_IDLE_TIME(UART_InitStruct->UART_IdleTime)); + assert_param(IS_UART_DMA_CFG(UART_InitStruct->UART_DmaEn)); + assert_param(IS_UART_AUTO_FLOW_CTRL(UART_InitStruct->UART_HardwareFlowControl)); + + //clear DLAB bit + UARTx->LCR &= LCR_DLAB_Reset; + //disable all interrupt + UARTx->DLH_INTCR = 0x00; + + //read to clear Line Status Reg + (void)UARTx->LSR; + //clear FIFO + UARTx->INTID_FCR |= (FCR_CLEAR_RX_FIFO_Set | FCR_CLEAR_TX_FIFO_Set); + + //set baudrate, firstly set DLAB bit + UARTx->LCR |= LCR_DLAB_Set; + //set calibration parameters(OVSR) + UARTx->STSR &= ~0xF0; + UARTx->STSR |= (UART_InitStruct->UART_Ovsr << 4); + //set calibration parameters(OVSR_adj) + UARTx->SPR &= (~(0x7ff << 16)); + UARTx->SPR |= (UART_InitStruct->UART_OvsrAdj << 16); + //set DLL and DLH + UARTx->DLL = (UART_InitStruct->UART_Div & 0x00FF); + UARTx->DLH_INTCR = ((UART_InitStruct->UART_Div & 0xFF00) >> 8); + //after set baudrate, clear DLAB bit + UARTx->LCR &= LCR_DLAB_Reset; + + //set LCR reg + UARTx->LCR = (UART_InitStruct->UART_Parity | UART_InitStruct->UART_StopBits | + UART_InitStruct->UART_WordLen); + //set FCR reg, FIFO must enable + UARTx->INTID_FCR = ((1 << 0) | UART_InitStruct->UART_TxThdLevel << 16 \ + | UART_InitStruct->UART_RxThdLevel << 8 | UART_InitStruct->UART_DmaEn); + + /* harware flow control */ + UARTx->MCR &= (~((1 << 5) | (1 << 1))); + UARTx->MCR |= UART_InitStruct->UART_HardwareFlowControl; + + /* set rx idle time */ + UARTx->RX_IDLE_TOCR = (UART_InitStruct->UART_IdleTime); + + if (UART_InitStruct->UART_DmaEn == UART_DMA_ENABLE) + { + /* Config UART Tx dma parameter */ + if (UART_InitStruct->UART_TxDmaEn != DISABLE) + { + /* Mask uart TX threshold value */ + UARTx->MISCR &= ~(0x1f << 3); + UARTx->MISCR |= ((UART_InitStruct->UART_TxWaterLevel) << 3) | BIT(1); + } + /* Config UART Rx dma parameter */ + if (UART_InitStruct->UART_RxDmaEn != DISABLE) + { + /* Mask uart RX threshold value */ + UARTx->MISCR &= ~(0x3f << 8); + UARTx->MISCR |= (UART_InitStruct->UART_RxWaterLevel << 8) | BIT(2); + } + } + + return; +} + +/** + * @brief Fills each UART_InitStruct member with its default value. + * @param UART_InitStruct: pointer to an UART_InitTypeDef structure which will be initialized. + * @retval None + */ +void UART_StructInit(UART_InitTypeDef *UART_InitStruct) +{ + //115200 default + UART_InitStruct->UART_Div = 20; + UART_InitStruct->UART_Ovsr = 12; + UART_InitStruct->UART_OvsrAdj = 0x252; + + UART_InitStruct->UART_WordLen = UART_WORD_LENGTH_8BIT; + UART_InitStruct->UART_StopBits = UART_STOP_BITS_1; + UART_InitStruct->UART_Parity = UART_PARITY_NO_PARTY; + UART_InitStruct->UART_TxThdLevel = 16; //1~29 + UART_InitStruct->UART_RxThdLevel = 16; //1~29 + UART_InitStruct->UART_IdleTime = UART_RX_IDLE_2BYTE; //idle interrupt wait time + UART_InitStruct->UART_HardwareFlowControl = UART_HW_FLOW_CTRL_DISABLE; + UART_InitStruct->UART_DmaEn = UART_DMA_DISABLE; + UART_InitStruct->UART_TxDmaEn = DISABLE; + UART_InitStruct->UART_RxDmaEn = DISABLE; + UART_InitStruct->UART_TxWaterLevel = 15; //Better to equal TX_FIFO_SIZE(16)- GDMA_MSize + UART_InitStruct->UART_RxWaterLevel = 1; //Better to equal GDMA_MSize + return; +} + +/** + * @brief Mask or unmask the specified UART interrupts. + * @param UART_INT: specifies the IR interrupts sources to be mask or unmask. + * This parameter can be the following values: + * @arg UART_INT_MASK_RD_AVA: mask INTCR(erbi). + * @arg UART_INT_MASK_TX_FIFO_EMPTY: mask INTCR(etbei). + * @arg UART_INT_MASK_RX_LINE_STS: mask INTCR(elsi). + * @arg UART_INT_MASK_RX_BREAK: mask rx break interrupt. + * @arg UART_INT_MASK_RX_IDLE: mask rx idle interrupt. + * @arg UART_INT_MASK_TX_DONE: mask the interrupt tx done interrupt. + * @arg UART_INT_MASK_TX_THD: mask tx fifo threshold interrupt. + * @param NewState: new state of the specified UART interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_MaskINTConfig(UART_TypeDef *UARTx, uint32_t UART_INT_MASK, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + assert_param(IS_UART_INT_MASK(UART_INT_MASK)); + assert_param(IS_FUNCTIONAL_STATE(newState)); + + if (NewState != DISABLE) + { + UARTx->INTMASK |= UART_INT_MASK; + } + else + { + UARTx->INTMASK &= ~(UART_INT_MASK); + } +} + +/** + * @brief Enables or disables the specified UART interrupts. + * @param UARTx: selected UARTx peripheral. + * @param UART_INT: specifies the UART interrupts sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg UART_INT_RD_AVA: Rx data avaliable interrupt source. + * @arg UART_INT_TX_FIFO_EMPTY: Tx FIFO empty interrupt source. + * @arg UART_INT_RX_LINE_STS: Rx line status interrupt source. + * @arg UART_INT_TX_DONE: Tx data done interrupt source. + * @arg UART_INT_TX_THD: Tx FIFO data <= thredhold interrupt source. + * @arg UART_INT_RX_BREAK: Rx break signal interrupt source. + * @arg UART_INT_RX_IDLE: Rx idle interrupt source. + * @param NewState: new state of the specified UART interrupts. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +void UART_INTConfig(UART_TypeDef *UARTx, uint32_t UART_INT, FunctionalState NewState) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + assert_param(IS_UART_INT(UART_INT)); + assert_param(IS_FUNCTIONAL_STATE(NewState)); + + if (UART_INT & UART_INT_RX_IDLE) + { + if (NewState == ENABLE) + { + UARTx->RX_IDLE_INTSR |= BIT0; + UARTx->RX_IDLE_INTCR |= BIT0; + UARTx->RX_IDLE_TOCR |= BIT31; + } + else + { + UARTx->RX_IDLE_TOCR &= (~BIT31); + UARTx->RX_IDLE_INTCR &= (~BIT0); + } + } + + if (UART_INT & UART_INT_RX_BREAK) + { + if (NewState == ENABLE) + { + UARTx->SPR |= BIT7; + } + else + { + UARTx->SPR &= (~BIT7); + } + } + + if (UART_INT & 0x3F) + { + if (NewState == ENABLE) + { + /* Enable the selected UARTx interrupts */ + UARTx->DLH_INTCR |= UART_INT; + } + else + { + /* Disable the selected UARTx interrupts */ + UARTx->DLH_INTCR &= (uint32_t)~UART_INT; + } + } + return; +} + +/** + * @brief Send data to tx FIFO. + * @param UARTx: selected UART peripheral. + * @param inBuf: buffer to be written to Tx FIFO. + * @param num: number of data to be written. + * @retval None + */ +void UART_SendData(UART_TypeDef *UARTx, const uint8_t *inBuf, uint16_t num) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + while (num--) + { + UARTx->RB_THR = *inBuf++; + } + + return; +} + +/** + * @brief Receive data from rx FIFO. + * @param UARTx: selected UART peripheral. + * @param[out] outBuf: buffer to save data read from UART FIFO. + * @param count: number of data to be read. + * @retval None + */ +void UART_ReceiveData(UART_TypeDef *UARTx, uint8_t *outBuf, uint16_t count) +{ + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + + while (count--) + { + *outBuf++ = (uint8_t)UARTx->RB_THR; + } + + return; +} + +/** + *@brief Change UART baudrate. + *@param UARTx: selected UART peripheral. + *@param div: parameter of the selected UART baudrate. + *@param ovsr: parameter of the selected UART baudrate. + *@param ovsr_adj: parameter of the selected UART baudrate. + *@retval None. + */ +void UART_SetBaudRate(UART_TypeDef *UARTx, uint16_t div, uint16_t ovsr, uint16_t ovsr_adj) +{ + //set baudrate, firstly set DLAB bit + UARTx->LCR |= LCR_DLAB_Set; + + //set calibration parameters(OVSR) + UARTx->STSR &= ~0xF0; + UARTx->STSR |= (ovsr << 4); + //set calibration parameters(OVSR_adj) + UARTx->SPR &= (~(0x7ff << 16)); + UARTx->SPR |= (ovsr_adj << 16); + //set DLL and DLH + UARTx->DLL = (div & 0x00FF); + UARTx->DLH_INTCR = ((div & 0xFF00) >> 8); + + //after set baudrate, clear DLAB bit + UARTx->LCR &= LCR_DLAB_Reset; +} + +/** + *@brief Set UART parameters. + *@param UARTx: selected UART peripheral. + *@param wordLen: data width of selected UART peripheral. + *@param parity: parity of selected UART peripheral. + *@param stopBits: stop bit of selected UART peripheral. + *@retval None + */ +void UART_SetParams(UART_TypeDef *UARTx, uint16_t wordLen, uint16_t parity, uint16_t stopBits) +{ + //set LCR reg + UARTx->LCR = (wordLen | stopBits | parity); +} + +/** + *@brief UART loop back mode config. + *@param UARTx: selected UART peripheral. + *@param NewState: new state of the DMA Channelx. + * This parameter can be: ENABLE or DISABLE. + *@retval None. + */ +void UART_LoopBackCmd(UART_TypeDef *UARTx, FunctionalState NewState) +{ + assert_param(IS_UART_PERIPH(UARTx)); + + if (NewState == ENABLE) + { + UARTx->MCR |= BIT4; + } + else + { + UARTx->MCR &= ~BIT4; + } +} + +/** + * @brief Checks whether the specified UART flag is set or not. + * @param UARTx: selected UART peripheral. + * @param UART_FLAG: specifies the flag to check. + * This parameter can be one of the following values: + * @arg UART_FLAG_RX_DATA_RDY: rx data is avaliable. + * @arg UART_FLAG_RX_OVERRUN: rx overrun. + * @arg UART_FLAG_PARTY_ERR: parity error. + * @arg UART_FLAG_FRAME_ERR: UARTx frame error. + * @arg UART_FLAG_BREAK_ERR: UARTx break error. + * @arg UART_FLAG_THR_EMPTY: tx FIFO is empty. + * @arg UART_FLAG_THR_TSR_EMPTY: tx FIFO and tx shift reg are both empty. + * @arg UART_FLAG_RX_FIFO_ERR: rx FIFO error. + * @arg UART_FLAG_RX_IDLE. + * @retval The new state of UART_FLAG (SET or RESET). + */ +FlagStatus UART_GetFlagStatus(UART_TypeDef *UARTx, uint32_t UART_FLAG) +{ + FlagStatus bitstatus = RESET; + + /* Check the parameters */ + assert_param(IS_UART_PERIPH(UARTx)); + assert_param(IS_UART_GET_FLAG(UART_FLAG)); + + if (UART_FLAG == UART_FLAG_TX_THD) + { + if (UARTx->TX_THR_INTSR & BIT(0)) + { + bitstatus = SET; + } + } + else if (UART_FLAG == UART_FLAG_TX_DONE) + { + if (UARTx->TX_DONE_INTSR & BIT(0)) + { + bitstatus = SET; + } + } + else if (UART_FLAG == UART_FLAG_RX_IDLE) + { + if (UARTx->RX_IDLE_INTSR & BIT(0)) + { + bitstatus = SET; + } + } + else + { + if (UARTx->LSR & UART_FLAG) + { + bitstatus = SET; + } + } + + return bitstatus; +} + +///** +// * @brief Get interrupt identifier. +// * @param UARTx: selected UART peripheral. +// * @retval The interrupt identifier value. +// * This return value can be one of the following values: +// * @arg UART_INT_ID_LINE_STATUS: interrupt identifier--line status interrupt. +// * @arg UART_INT_ID_RX_LEVEL_REACH: interrupt identifier--rx trigger level reached interrupt. +// * @arg UART_INT_ID_RX_TMEOUT: interrupt identifier--line status interrupt. +// * @arg UART_INT_ID_TX_EMPTY: interrupt identifier--line status interrupt. +// */ +//__STATIC_INLINE uint16_t UART_GetINTStatus(UART_TypeDef *UARTx) +//{ +// /* Check the parameters */ +// assert_param(IS_UART_PERIPH(UARTx)); + +// return (uint16_t)(UARTx->INTID_FCR & (0x0000000E)); +//} + +/******************* (C) COPYRIGHT 2019 Realtek Semiconductor *****END OF FILE****/ diff --git a/src/mcu/rtl876x/arm/startup_rtl876x.s b/src/mcu/rtl876x/arm/startup_rtl876x.s new file mode 100644 index 0000000..5106640 --- /dev/null +++ b/src/mcu/rtl876x/arm/startup_rtl876x.s @@ -0,0 +1,280 @@ + + EXPORT __initial_sp +__initial_sp EQU (0x200000 + 14 * 1024) + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA VECTOR, 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 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD System_Handler ;[0] System On interrupt + DCD WDG_Handler ;[1] Watch dog global insterrupt + DCD BTMAC_Handler ;[2] See Below Table ( an Extension of interrupt ) + DCD Timer3_Handler ;[3] Timer3 global interrupt + DCD Timer2_Handler ;[4] Timer2 global interrupt + DCD HardFault_Handler ;[5] Platform interrupt (platfrom error interrupt) + DCD I2S0_RX_Handler ;[6] I2S0 RX interrupt + DCD I2S0_TX_Handler ;[7] I2S0 TX interrupt + DCD Timer4_5_Handler ;[8] Timer[4:7] global interrupt + DCD GPIO4_Handler ;[9] GPIO 4 interrupt + DCD GPIO5_Handler ;[10] GPIO 5 interrupt + DCD UART1_Handler ;[11] Uart1 interrupt (default for log) + DCD UART0_Handler ;[12] Uart0 interrupt + DCD RTC_Handler ;[13] Realtime counter interrupt + DCD SPI0_Handler ;[14] SPI0 interrupt + DCD SPI1_Handler ;[15] SPI1 interrupt + DCD I2C0_Handler ;[16] I2C0 interrupt + DCD I2C1_Handler ;[17] I2C1 interrupt + DCD ADC_Handler ;[18] ADC global interrupt + DCD Peripheral_Handler ;[19] See Below Table ( an Extension of interrupt ) + DCD GDMA0_Channel0_Handler ;[20] RTK-DMA0 channel 0 global interrupt + DCD GDMA0_Channel1_Handler ;[21] RTK-DMA0 channel 1 global interrupt + DCD GDMA0_Channel2_Handler ;[22] RTK-DMA0 channel 2 global interrupt + DCD GDMA0_Channel3_Handler ;[23] RTK-DMA0 channel 3 global interrupt + DCD Enhanced_Timer0_Handler ;[24] Enhanced Timer0 + DCD Enhanced_Timer1_Handler ;[25] Enhanced Timer1 + DCD GPIO_Group3_Handler ;[26] GPIO(n*4)+3,n={0:7} global interrupt + DCD GPIO_Group2_Handler ;[27] GPIO(n*4)+2,n={0:7} global interrupt + DCD IR_Handler ;[28] IR module global interrupt + DCD GPIO_Group1_Handler ;[29] GPIO(n*4)+1,n={0:7}-{1} global interrupt + DCD GPIO_Group0_Handler ;[30] GPIO(n*4)+0,n={0:7}-{1} global interrupt + DCD 0 ;[31] Reserved + + ;Timer[4:5] interrupt + DCD Timer4_Handler ;8, 0, 48 + DCD Timer5_Handler ;8, 1, 49 + + ;Peripheral Interrupts not special interrupt + ;Interrupt name, Interrupt status bit, Offset in vector + DCD SPI_Flash_Handler ;19, 0, 50 + DCD Qdecode_Handler ;19, 1, 51 + DCD Keyscan_Handler ;19, 2, 52 + DCD SPI2W_Handler ;19, 3, 53 + DCD LPCOMP_Handler ;19, 4, 54 + DCD PTA_Mailbox_Handler ;19, 5, 55 + DCD CAP_Touch_Handler ;19, 6, 56 + DCD TRNG_Handler ;19, 9, 57 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA RESET, CODE, READONLY + +; Reset Handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + LDR R0, =SystemInit + BX R0 + + ENDP ; end of Reset_Handler + + + AREA |.text|, CODE, READONLY +Default_Handler PROC + EXPORT Default_Handler [WEAK] + EXPORT NMI_Handler [WEAK] + EXPORT HardFault_Handler [WEAK] + EXPORT MemManage_Handler [WEAK] + EXPORT BusFault_Handler [WEAK] + EXPORT UsageFault_Handler [WEAK] + EXPORT SVC_Handler [WEAK] + EXPORT PendSV_Handler [WEAK] + EXPORT SysTick_Handler [WEAK] + EXPORT System_Handler [WEAK] + EXPORT WDG_Handler [WEAK] + EXPORT BTMAC_Handler [WEAK] + EXPORT Timer3_Handler [WEAK] + EXPORT Timer2_Handler [WEAK] + EXPORT I2S0_TX_Handler [WEAK] + EXPORT I2S0_RX_Handler [WEAK] + EXPORT Timer4_5_Handler [WEAK] + EXPORT GPIO4_Handler [WEAK] + EXPORT GPIO5_Handler [WEAK] + EXPORT UART1_Handler [WEAK] + EXPORT UART0_Handler [WEAK] + EXPORT RTC_Handler [WEAK] + EXPORT SPI0_Handler [WEAK] + EXPORT SPI1_Handler [WEAK] + EXPORT I2C0_Handler [WEAK] + EXPORT I2C1_Handler [WEAK] + EXPORT ADC_Handler [WEAK] + EXPORT Peripheral_Handler [WEAK] + EXPORT GDMA0_Channel0_Handler [WEAK] + EXPORT GDMA0_Channel1_Handler [WEAK] + EXPORT GDMA0_Channel2_Handler [WEAK] + EXPORT GDMA0_Channel3_Handler [WEAK] + EXPORT Enhanced_Timer0_Handler [WEAK] + EXPORT Enhanced_Timer1_Handler [WEAK] + EXPORT GPIO_Group3_Handler [WEAK] + EXPORT GPIO_Group2_Handler [WEAK] + EXPORT IR_Handler [WEAK] + EXPORT GPIO_Group1_Handler [WEAK] + EXPORT GPIO_Group0_Handler [WEAK] + + ;Extension Interrupts + EXPORT Timer4_Handler [WEAK] + EXPORT Timer5_Handler [WEAK] + EXPORT SPI_Flash_Handler [WEAK] + EXPORT Qdecode_Handler [WEAK] + EXPORT Keyscan_Handler [WEAK] + EXPORT SPI2W_Handler [WEAK] + EXPORT LPCOMP_Handler [WEAK] + EXPORT PTA_Mailbox_Handler [WEAK] + EXPORT CAP_Touch_Handler [WEAK] + EXPORT TRNG_Handler [WEAK] + EXPORT GPIO0_Handler [WEAK] + EXPORT GPIO1_Handler [WEAK] + EXPORT GPIO2_Handler [WEAK] + EXPORT GPIO3_Handler [WEAK] + EXPORT GPIO6_Handler [WEAK] + EXPORT GPIO7_Handler [WEAK] + EXPORT GPIO8_Handler [WEAK] + EXPORT GPIO9_Handler [WEAK] + EXPORT GPIO10_Handler [WEAK] + EXPORT GPIO11_Handler [WEAK] + EXPORT GPIO12_Handler [WEAK] + EXPORT GPIO13_Handler [WEAK] + EXPORT GPIO14_Handler [WEAK] + EXPORT GPIO15_Handler [WEAK] + EXPORT GPIO16_Handler [WEAK] + EXPORT GPIO17_Handler [WEAK] + EXPORT GPIO18_Handler [WEAK] + EXPORT GPIO19_Handler [WEAK] + EXPORT GPIO20_Handler [WEAK] + EXPORT GPIO21_Handler [WEAK] + EXPORT GPIO22_Handler [WEAK] + EXPORT GPIO23_Handler [WEAK] + EXPORT GPIO24_Handler [WEAK] + EXPORT GPIO25_Handler [WEAK] + EXPORT GPIO26_Handler [WEAK] + EXPORT GPIO27_Handler [WEAK] + EXPORT GPIO28_Handler [WEAK] + EXPORT GPIO29_Handler [WEAK] + EXPORT GPIO30_Handler [WEAK] + EXPORT GPIO31_Handler [WEAK] +NMI_Handler +HardFault_Handler +MemManage_Handler +BusFault_Handler +UsageFault_Handler +SVC_Handler +PendSV_Handler +SysTick_Handler +System_Handler +WDG_Handler +BTMAC_Handler +Timer3_Handler +Timer2_Handler +I2S0_RX_Handler +I2S0_TX_Handler +Timer4_5_Handler +GPIO4_Handler +GPIO5_Handler +UART1_Handler +UART0_Handler +RTC_Handler +SPI0_Handler +SPI1_Handler +I2C0_Handler +I2C1_Handler +ADC_Handler +Peripheral_Handler +GDMA0_Channel0_Handler +GDMA0_Channel1_Handler +GDMA0_Channel2_Handler +GDMA0_Channel3_Handler +Enhanced_Timer0_Handler +Enhanced_Timer1_Handler +GPIO_Group3_Handler +GPIO_Group2_Handler +IR_Handler +GPIO_Group1_Handler +GPIO_Group0_Handler + +;Extension Interrupts +Timer4_Handler +Timer5_Handler +SPI_Flash_Handler +Qdecode_Handler +Keyscan_Handler +SPI2W_Handler +LPCOMP_Handler +PTA_Mailbox_Handler +CAP_Touch_Handler +TRNG_Handler +GPIO0_Handler +GPIO1_Handler +GPIO2_Handler +GPIO3_Handler +GPIO6_Handler +GPIO7_Handler +GPIO8_Handler +GPIO9_Handler +GPIO10_Handler +GPIO11_Handler +GPIO12_Handler +GPIO13_Handler +GPIO14_Handler +GPIO15_Handler +GPIO16_Handler +GPIO17_Handler +GPIO18_Handler +GPIO19_Handler +GPIO20_Handler +GPIO21_Handler +GPIO22_Handler +GPIO23_Handler +GPIO24_Handler +GPIO25_Handler +GPIO26_Handler +GPIO27_Handler +GPIO28_Handler +GPIO29_Handler +GPIO30_Handler +GPIO31_Handler + IMPORT log_direct + LDR R0, =0x20000000 + LDR R1, =DEFAULT_HANDLER_TXT + MRS R2, IPSR + LDR R3, =log_direct + BLX R3 + B . + + ENDP + + +; User Initial Stack + EXPORT __user_setup_stackheap +__user_setup_stackheap PROC + BX LR + ENDP + +DEFAULT_HANDLER_TXT + DCB "Error! Please implement your ISR Handler for IRQ %d!\n", 0 ; Null terminated string + ALIGN + + END diff --git a/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s b/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s new file mode 100644 index 0000000..e865d37 --- /dev/null +++ b/src/mcu/rtl876x/arm/startup_rtl876x_gcc.s @@ -0,0 +1,371 @@ +;/*****************************************************************************/ +;/* startup_rtl8762c_gcc.s: Startup file for Realtek RTL8762C device series */ +;/*****************************************************************************/ + +/** +**=========================================================================== +** Definitions +**=========================================================================== +*/ + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + + .global g_pfnVectors + .global Default_Handler + .type Default_Handler, %function + + +.equ _estack, 0x00203800 +/** +**=========================================================================== +** Program - Reset_Handler +** Abstract: This code gets called after a reset event. +**=========================================================================== +*/ + .section RESET + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + LDR R0, = SystemInit + BX R0 + +/** +**=========================================================================== +** Program - Default_Handler +** Abstract: This code gets called when the processor receives an +** unexpected interrupt. +**=========================================================================== +*/ + .section .text,"ax",%progbits + Default_Handler: + b . + .size Default_Handler, .-Default_Handler +/** +**=========================================================================== +** Reset, Exception, and Interrupt vectors +**=========================================================================== +*/ + + .section VECTOR,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + /* Processor exception vectors */ + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word 0 + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + + /* Interrupt Handlers for RTL8762C Peripherals */ + .word System_Handler /*[0] System On interrupt*/ + .word WDG_Handler /*[1] Watch dog global insterrupt*/ + .word BTMAC_Handler /*[2] See Below Table ( an Extension of interrupt )*/ + .word Timer3_Handler /*[3] Timer3 global interrupt*/ + .word Timer2_Handler /*[4] Timer2 global interrupt*/ + .word HardFault_Handler /*[5] Platform interrupt (platfrom error interrupt)*/ + .word I2S0_TX_Handler /*[6] I2S0 TX interrupt*/ + .word I2S0_RX_Handler /*[7] I2S0 RX interrupt*/ + .word Timer4_5_Handler /*[8] Timer[4:7] global interrupt*/ + .word GPIO4_Handler /*[9] GPIO 4 interrupt*/ + .word GPIO5_Handler /*[10] GPIO 5 interrupt*/ + .word UART1_Handler /*[11] Uart1 interrupt*/ + .word UART0_Handler /*[12] Uart0 interrupt*/ + .word RTC_Handler /*[13] Realtime counter interrupt*/ + .word SPI0_Handler /*[14] SPI0 interrupt*/ + .word SPI1_Handler /*[15] SPI1 interrupt*/ + .word I2C0_Handler /*[16] I2C0 interrupt*/ + .word I2C1_Handler /*[17] I2C1 interrupt*/ + .word ADC_Handler /*[18] ADC global interrupt*/ + .word Peripheral_Handler /*[19] See Below Table ( an Extension of interrupt )*/ + .word GDMA0_Channel0_Handler /*[20] RTK-DMA0 channel 0 global interrupt*/ + .word GDMA0_Channel1_Handler /*[21] RTK-DMA0 channel 1 global interrupt*/ + .word GDMA0_Channel2_Handler /*[22] RTK-DMA0 channel 2 global interrupt*/ + .word GDMA0_Channel3_Handler /*[23] RTK-DMA0 channel 3 global interrupt*/ + .word Enhanced_Timer0_Handler /*[24] RTK-DMA0 channel 4 global interrupt*/ + .word Enhanced_Timer1_Handler /*[25] RTK-DMA0 channel 5 global interrupt (default for log)*/ + .word GPIO_Group3_Handler /*[26] GPIO(n*4)+3,n={0:7} global interrupt*/ + .word GPIO_Group2_Handler /*[27] GPIO(n*4)+2,n={0:7} global interrupt*/ + .word IR_Handler /*[28] IR module global interrupt*/ + .word GPIO_Group1_Handler /*[29] GPIO(n*4)+1,n={0:7}-{1} global interrupt*/ + .word GPIO_Group0_Handler /*[30] GPIO(n*4)+0,n={0:7}-{1} global interrupt*/ + .word 0 /*[31] Uart2 interrupt (default for log)*/ + + .word Timer4_Handler /* 8, 0, 48 */ + .word Timer5_Handler /* 8, 1, 49 */ + .word SPI_Flash_Handler /* 19, 0, 52 */ + .word Qdecode_Handler /* 9, 1, 53 */ + .word Keyscan_Handler /* 19, 2, 54 */ + .word SPI2W_Handler /* 19, 3, 55 */ + .word LPCOMP_Handler /* 19, 4, 56 */ + .word PTA_Mailbox_Handler /* 19, 5, 57 */ + .word CAP_Touch_Handler /* 19, 6, 58 */ + .word TRNG_Handler /* 19, 7, 59 */ + + + +/** +**=========================================================================== +** Provide weak aliases for each Exception handler to the Default_Handler. +**=========================================================================== +*/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak System_Handler + .thumb_set System_Handler,Default_Handler + + .weak WDG_Handler + .thumb_set WDG_Handler,Default_Handler + + .weak BTMAC_Handler + .thumb_set BTMAC_Handler,Default_Handler + + .weak Timer3_Handler + .thumb_set Timer3_Handler,Default_Handler + + .weak Timer2_Handler + .thumb_set Timer2_Handler,Default_Handler + + .weak I2S0_TX_Handler + .thumb_set I2S0_TX_Handler,Default_Handler + + .weak I2S0_RX_Handler + .thumb_set I2S0_RX_Handler,Default_Handler + + .weak Timer4_5_Handler + .thumb_set Timer4_5_Handler,Default_Handler + + .weak GPIO4_Handler + .thumb_set GPIO4_Handler,Default_Handler + + .weak GPIO5_Handler + .thumb_set GPIO5_Handler,Default_Handler + + .weak UART1_Handler + .thumb_set UART1_Handler,Default_Handler + + .weak UART0_Handler + .thumb_set UART0_Handler,Default_Handler + + .weak RTC_Handler + .thumb_set RTC_Handler,Default_Handler + + .weak SPI0_Handler + .thumb_set SPI0_Handler,Default_Handler + + .weak SPI1_Handler + .thumb_set SPI1_Handler,Default_Handler + + .weak I2C0_Handler + .thumb_set I2C0_Handler,Default_Handler + + .weak I2C1_Handler + .thumb_set I2C1_Handler,Default_Handler + + .weak ADC_Handler + .thumb_set ADC_Handler,Default_Handler + + .weak Peripheral_Handler + .thumb_set Peripheral_Handler,Default_Handler + + .weak GDMA0_Channel0_Handler + .thumb_set GDMA0_Channel0_Handler,Default_Handler + + .weak GDMA0_Channel1_Handler + .thumb_set GDMA0_Channel1_Handler,Default_Handler + + .weak GDMA0_Channel2_Handler + .thumb_set GDMA0_Channel2_Handler,Default_Handler + + .weak GDMA0_Channel3_Handler + .thumb_set GDMA0_Channel3_Handler,Default_Handler + + .weak Enhanced_Timer0_Handler + .thumb_set Enhanced_Timer0_Handler,Default_Handler + + .weak Enhanced_Timer1_Handler + .thumb_set Enhanced_Timer1_Handler,Default_Handler + + .weak GPIO_Group3_Handler + .thumb_set GPIO_Group3_Handler,Default_Handler + + .weak GPIO_Group2_Handler + .thumb_set GPIO_Group2_Handler,Default_Handler + + .weak IR_Handler + .thumb_set IR_Handler,Default_Handler + + .weak GPIO_Group1_Handler + .thumb_set GPIO_Group1_Handler,Default_Handler + + .weak GPIO_Group0_Handler + .thumb_set GPIO_Group0_Handler,Default_Handler + + .weak UART2_Handler + .thumb_set UART2_Handler,Default_Handler + + .weak Timer4_Handler + .thumb_set Timer4_Handler,Default_Handler + + .weak Timer5_Handler + .thumb_set Timer5_Handler,Default_Handler + + .weak Timer6_Handler + .thumb_set Timer6_Handler,Default_Handler + + .weak Timer7_Handler + .thumb_set Timer7_Handler,Default_Handler + + .weak SPI_Flash_Handler + .thumb_set SPI_Flash_Handler,Default_Handler + + .weak Qdecode_Handler + .thumb_set Qdecode_Handler,Default_Handler + + .weak Keyscan_Handler + .thumb_set Keyscan_Handler,Default_Handler + + .weak SPI2W_Handler + .thumb_set SPI2W_Handler,Default_Handler + + .weak LPCOMP_Handler + .thumb_set LPCOMP_Handler,Default_Handler + + .weak PTA_Mailbox_Handler + .thumb_set PTA_Mailbox_Handler,Default_Handler + + .weak CAP_Touch_Handler + .thumb_set CAP_Touch_Handler,Default_Handler + + .weak TRNG_Handler + .thumb_set TRNG_Handler,Default_Handler + + + .weak GPIO0_Handler + .thumb_set GPIO0_Handler,Default_Handler + + .weak GPIO1_Handler + .thumb_set GPIO1_Handler,Default_Handler + + .weak GPIO2_Handler + .thumb_set GPIO2_Handler,Default_Handler + + .weak GPIO3_Handler + .thumb_set GPIO3_Handler,Default_Handler + + .weak GPIO6_Handler + .thumb_set GPIO6_Handler,Default_Handler + + .weak GPIO7_Handler + .thumb_set GPIO7_Handler,Default_Handler + + .weak GPIO8_Handler + .thumb_set GPIO8_Handler,Default_Handler + + .weak GPIO9_Handler + .thumb_set GPIO9_Handler,Default_Handler + + .weak GPIO10_Handler + .thumb_set GPIO10_Handler,Default_Handler + + .weak GPIO11_Handler + .thumb_set GPIO11_Handler,Default_Handler + + .weak GPIO12_Handler + .thumb_set GPIO12_Handler,Default_Handler + + .weak GPIO13_Handler + .thumb_set GPIO13_Handler,Default_Handler + + .weak GPIO14_Handler + .thumb_set GPIO14_Handler,Default_Handler + + .weak GPIO15_Handler + .thumb_set GPIO15_Handler,Default_Handler + + .weak GPIO16_Handler + .thumb_set GPIO16_Handler,Default_Handler + + .weak GPIO17_Handler + .thumb_set GPIO17_Handler,Default_Handler + + .weak GPIO18_Handler + .thumb_set GPIO18_Handler,Default_Handler + + .weak GPIO19_Handler + .thumb_set GPIO19_Handler,Default_Handler + + .weak GPIO20_Handler + .thumb_set GPIO20_Handler,Default_Handler + + .weak GPIO21_Handler + .thumb_set GPIO21_Handler,Default_Handler + + .weak GPIO22_Handler + .thumb_set GPIO22_Handler,Default_Handler + + .weak GPIO23_Handler + .thumb_set GPIO23_Handler,Default_Handler + + .weak GPIO24_Handler + .thumb_set GPIO24_Handler,Default_Handler + + .weak GPIO25_Handler + .thumb_set GPIO25_Handler,Default_Handler + + .weak GPIO26_Handler + .thumb_set GPIO26_Handler,Default_Handler + + .weak GPIO27_Handler + .thumb_set GPIO27_Handler,Default_Handler + + .weak GPIO28_Handler + .thumb_set GPIO28_Handler,Default_Handler + + .weak GPIO29_Handler + .thumb_set GPIO29_Handler,Default_Handler + + .weak GPIO30_Handler + .thumb_set GPIO30_Handler,Default_Handler + + .weak GPIO31_Handler + .thumb_set GPIO31_Handler,Default_Handler + +.end diff --git a/src/mcu/rtl876x/overlay_mgr.c b/src/mcu/rtl876x/overlay_mgr.c new file mode 100644 index 0000000..f0b131f --- /dev/null +++ b/src/mcu/rtl876x/overlay_mgr.c @@ -0,0 +1,163 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file overlay_mgr.c + * @brief overlay manager + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2016 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include "overlay_mgr.h" + + +/* linker generates symbols for overlay a section */ +extern uint32_t Load$$OVERLAY_A$$RO$$Base; +extern uint32_t Load$$OVERLAY_A$$RW$$Base; + +extern uint32_t Image$$OVERLAY_A$$RO$$Base; +extern uint32_t Image$$OVERLAY_A$$RW$$Base; +extern uint32_t Image$$OVERLAY_A$$ZI$$Base; + +extern uint32_t Image$$OVERLAY_A$$RO$$Length; +extern uint32_t Image$$OVERLAY_A$$RW$$Length; +extern uint32_t Image$$OVERLAY_A$$ZI$$Length; + +/* linker generates symbols for overlay b section */ +extern uint32_t Load$$OVERLAY_B$$RO$$Base; +extern uint32_t Load$$OVERLAY_B$$RW$$Base; + +extern uint32_t Image$$OVERLAY_B$$RO$$Base; +extern uint32_t Image$$OVERLAY_B$$RW$$Base; +extern uint32_t Image$$OVERLAY_B$$ZI$$Base; + +extern uint32_t Image$$OVERLAY_B$$RO$$Length; +extern uint32_t Image$$OVERLAY_B$$RW$$Length; +extern uint32_t Image$$OVERLAY_B$$ZI$$Length; + +/* linker generates symbols for overlay c section */ +extern uint32_t Load$$OVERLAY_C$$RO$$Base; +extern uint32_t Load$$OVERLAY_C$$RW$$Base; + +extern uint32_t Image$$OVERLAY_C$$RO$$Base; +extern uint32_t Image$$OVERLAY_C$$RW$$Base; +extern uint32_t Image$$OVERLAY_C$$ZI$$Base; + +extern uint32_t Image$$OVERLAY_C$$RO$$Length; +extern uint32_t Image$$OVERLAY_C$$RW$$Length; +extern uint32_t Image$$OVERLAY_C$$ZI$$Length; + +char scenario_name[8]; + +#if defined ( __CC_ARM ) +#pragma push +#pragma diag_suppress 1296 +#endif +static T_OVERLAY_SECTION overlay_sections[OVERLAY_SCENARIO_NUM] = +{ + { + "BootOnce", + + &Load$$OVERLAY_A$$RO$$Base, + &Load$$OVERLAY_A$$RW$$Base, + + &Image$$OVERLAY_A$$RO$$Base, + &Image$$OVERLAY_A$$RW$$Base, + &Image$$OVERLAY_A$$ZI$$Base, + + /* warning 1296(extended constant initialiser used) */ + (uint32_t) &Image$$OVERLAY_A$$RO$$Length, + (uint32_t) &Image$$OVERLAY_A$$RW$$Length, + (uint32_t) &Image$$OVERLAY_A$$ZI$$Length, + }, + { + "Scene_B", + + &Load$$OVERLAY_B$$RO$$Base, + &Load$$OVERLAY_B$$RW$$Base, + + &Image$$OVERLAY_B$$RO$$Base, + &Image$$OVERLAY_B$$RW$$Base, + &Image$$OVERLAY_B$$ZI$$Base, + + /* warning 1296(extended constant initialiser used) */ + (uint32_t) &Image$$OVERLAY_B$$RO$$Length, + (uint32_t) &Image$$OVERLAY_B$$RW$$Length, + (uint32_t) &Image$$OVERLAY_B$$ZI$$Length, + }, + { + "Scene_C", + + &Load$$OVERLAY_C$$RO$$Base, + &Load$$OVERLAY_C$$RW$$Base, + + &Image$$OVERLAY_C$$RO$$Base, + &Image$$OVERLAY_C$$RW$$Base, + &Image$$OVERLAY_C$$ZI$$Base, + + /* warning 1296(extended constant initialiser used) */ + (uint32_t) &Image$$OVERLAY_C$$RO$$Length, + (uint32_t) &Image$$OVERLAY_C$$RW$$Length, + (uint32_t) &Image$$OVERLAY_C$$ZI$$Length, + } +}; +#if defined ( __CC_ARM ) +#pragma pop +#endif + +/** + * @brief load overlay + * @param scenario_idx selected overlay section index + * @return none + */ +bool load_overlay(T_OVERLAY_SCENARIO_IDX scenario_idx) +{ + const T_OVERLAY_SECTION *selected_scenario; + + if (scenario_idx >= OVERLAY_SCENARIO_NUM) + { + return false; + } + + selected_scenario = &overlay_sections[scenario_idx]; + + if (memcmp(selected_scenario->signature, scenario_name, 8) == 0) + { + return true; + } + + /* load code */ + memcpy(selected_scenario->image_ro_base, selected_scenario->load_ro_base, + selected_scenario->ro_length); + /* load rw data */ + memcpy(selected_scenario->image_rw_base, selected_scenario->load_rw_base, + selected_scenario->rw_length); + /* clear zi data */ + memset(selected_scenario->image_zi_base, 0x0, selected_scenario->zi_length); + + memcpy(scenario_name, selected_scenario->signature, 8); + + return true; +} + +T_OVERLAY_SCENARIO_IDX get_current_scenario_index(void) +{ + const T_OVERLAY_SECTION *selected_scenario; + + for (int i = 0; i < (int)OVERLAY_SCENARIO_NUM; ++i) + { + selected_scenario = &overlay_sections[i]; + if (memcmp(selected_scenario->signature, scenario_name, 8) == 0) + { + return (T_OVERLAY_SCENARIO_IDX)i; + } + } + + return OVERLAY_SCENARIO_NUM; //not found valid scenario +} diff --git a/src/mcu/rtl876x/system_rtl876x.c b/src/mcu/rtl876x/system_rtl876x.c new file mode 100644 index 0000000..c8b00ad --- /dev/null +++ b/src/mcu/rtl876x/system_rtl876x.c @@ -0,0 +1,1629 @@ +/** +***************************************************************************************** +* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. +***************************************************************************************** + * @file system_rtl8762c.c + * @brief system init file + * @author lory xu + * @date 2017-11-9 + * @version v1.0 + ************************************************************************************** + * @attention + *

    © COPYRIGHT 2016 Realtek Semiconductor Corporation

    + * ************************************************************************************* + */ + +/*============================================================================* + * Header Files + *============================================================================*/ +#include +#include +#include +#include +#include +#include "version.h" +#include "rtl876x.h" +#include "patch_header_check.h" +#include "app_section.h" +#include "rom_uuid.h" +#include "app_define.h" +#include "core_cmFunc.h" +#include "mem_config.h" +#include "otp.h" +#include "platform_autoconf.h" +#include "rtl876x_wdg.h" +#include "overlay_mgr.h" +#include "flash_device.h" +#include "os_sched.h" +#include "os_sync.h" +#include "otp_config.h" +#include "test_mode.h" +#include "platform_utils.h" +#include "os_mem.h" +#include "dfu_flash.h" +#include "rtl876x_wdg.h" +#include "rtl876x_lib_platform.h" +#include "board.h" +#include "dlps.h" +#include "os_timer.h" +#include "trace.h" +#if (SUPPORT_NORMAL_OTA == 1) +#include "dfu_main.h" +#endif +#if (SYSTEM_TRACE_ENABLE == 1) +#include "system_trace.h" +#include "trace_config.h" +#endif + +/** @defgroup SYSTEM_INIT System Init + * @brief Start up code for user application. + * @{ + */ +/*============================================================================* + * Macros + *============================================================================*/ +/** @defgroup SYSTEM_INIT_Exported_Macros System Init Exported Macros + * @brief + * @{ + */ +void show_sdk_lib_version(void); +void SystemInit(void); +#define SHARE_CACHE_RAM_0K 0x82F70000 +#define SHARE_CACHE_RAM_4K 0x2F2D0002 +#define SHARE_CACHE_RAM_8K 0xA2AA0003 + +#define SHUTDOWN_DATARAM_4KB (4 * 1024) +#define SHUTDOWN_DATARAM_8KB (8 * 1024) +#define SHUTDOWN_DATARAM_24KB (24 * 1024) +#define SHUTDOWN_DATARAM_56KB (56 * 1024) + +#define VTOR_RAM_ADDR 0x00200000 //!< vector table address in RAM. +#define APP_FAKE_PAYLOAD_LEN 0x100 + +#define FreeRTOS_portBYTE_ALIGNMENT 8 + +/** End of SYSTEM_INIT_Exported_Macros + * @} + */ + +/*============================================================================* + * Types + *============================================================================*/ +/** @defgroup SYSTEM_INIT_Exported_Types System Init Exported Types + * @{ + */ +typedef struct +{ + uint8_t ic_type; + uint8_t rsvd0[3]; + uint32_t ram_size; + uint32_t check_pattern; + T_VERSION_FORMAT git_ver; + uint8_t rsvd1[64]; +} T_UPPERSTACK_HEADER; + +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize : 28; /*<< The size of the free block. */ + size_t xRamType : 3; + size_t xAllocateBit : 1; +} BlockLink_t; +/** End of SYSTEM_INIT_Exported_Types + * @} + */ + + +/*============================================================================* + * Variables + *============================================================================*/ +/** @defgroup SYSTEM_INIT_Exported_Variables System Init Exported Variables + * @{ + */ +extern void GPIO0_Handler(void); +extern void GPIO1_Handler(void); +extern void GPIO2_Handler(void); +extern void GPIO3_Handler(void); +extern void GPIO4_Handler(void); +extern void GPIO5_Handler(void); +extern void GPIO6_Handler(void); +extern void GPIO7_Handler(void); +extern void GPIO8_Handler(void); +extern void GPIO9_Handler(void); +extern void GPIO10_Handler(void); +extern void GPIO11_Handler(void); +extern void GPIO12_Handler(void); +extern void GPIO13_Handler(void); +extern void GPIO14_Handler(void); +extern void GPIO15_Handler(void); +extern void GPIO16_Handler(void); +extern void GPIO17_Handler(void); +extern void GPIO18_Handler(void); +extern void GPIO19_Handler(void); +extern void GPIO20_Handler(void); +extern void GPIO21_Handler(void); +extern void GPIO22_Handler(void); +extern void GPIO23_Handler(void); +extern void GPIO24_Handler(void); +extern void GPIO25_Handler(void); +extern void GPIO26_Handler(void); +extern void GPIO27_Handler(void); +extern void GPIO28_Handler(void); +extern void GPIO29_Handler(void); +extern void GPIO30_Handler(void); +extern void GPIO31_Handler(void); + +#if defined (__CC_ARM) +extern char Image$$ENCRYPTION_RAM_CODE$$Base[]; +extern char Load$$ENCRYPTION_RAM_CODE$$Base[]; +extern char Load$$ENCRYPTION_RAM_CODE$$Length[]; + +extern char Image$$FLASH_START_ADDR$$RO$$Base[]; +extern char Load$$FLASH_START_ADDR$$RO$$Base[]; +extern char Load$$FLASH_START_ADDR$$RO$$Length[]; +#elif defined ( __GNUC__ ) +extern uint32_t *__encryption_ram_code_exe_ad__; +extern uint32_t *__encryption_ram_code_load_ad__; +extern uint32_t *__encryption_ram_code_length__; +#endif +extern uint32_t upperstack_fake_data; + +BOOL_WDG_CB user_wdg_cb __attribute__((weak)) = NULL; +USER_CALL_BACK app_pre_main_cb __attribute__((weak)) = NULL ; +USER_CALL_BACK os_patch __attribute__((weak)) = NULL ; + +#if (LOG_UART_MULTIPLEXING == 1) + +#include "log_uart_dma.h" +typedef enum +{ + LOG_UART = 0, + DATA_UART +} UART_STATE; + +typedef struct +{ + UART_STATE last_flag; + UART_STATE current_flag; +} T_UART_FLAG; + +PingpongBuffer MCU_Log_user; +PingpongBuffer *pMCU_PPB_user = &MCU_Log_user; + +T_UART_FLAG uart_flag = {LOG_UART, LOG_UART}; +T_UART_FLAG *uart_flag_p = &uart_flag; + +PingpongBuffer *get_tx_buffer_app_cb(void); +T_UART_FLAG *get_uart_flag_app_cb(void); +void get_tx_rx_pin_app_cb(uint8_t *p_tx, uint8_t *p_rx); + +#endif + +#if (LOG_UART_MULTIPLEXING == 1) + +//increase APP_CB_NUMBERS when add new app cb +#define APP_CB_NUMBERS 4 + +typedef enum +{ + APP_CB_ID_WDG_RESET = 0, + APP_CB_ID_RX_BUFFER = 1, + APP_CB_ID_UART_FLAG = 2, + APP_CB_ID_TX_RX_PIN = 3, + //add more app cb id here +} T_APP_CB_ID; + +#elif(SUPPORT_FSBL_GPIO_SET == 1) + +//increase APP_CB_NUMBERS when add new app cb +#define APP_CB_NUMBERS 2 + +typedef enum +{ + APP_CB_ID_WDG_RESET = 0, + APP_CB_ID_GPIO_SET = 1, + //add more app cb id here +} T_APP_CB_ID; + +void gpio_set_app_cb(void); + +#else +//increase APP_CB_NUMBERS when add new app cb +#define APP_CB_NUMBERS 1 + +typedef enum +{ + APP_CB_ID_WDG_RESET = 0, + //add more app cb id here +} T_APP_CB_ID; +#endif + +typedef struct +{ + uint32_t app_cb_signature; + uint32_t app_cb_numbers; + uint32_t app_cb_addr[APP_CB_NUMBERS]; +} T_APP_CB_TABLE; + +const T_APP_CB_TABLE app_cb_table = +{ + .app_cb_signature = SIGNATURE_APP_CB, + .app_cb_numbers = APP_CB_NUMBERS, + .app_cb_addr[0] = (uint32_t)NULL, +#if (LOG_UART_MULTIPLEXING == 1) + .app_cb_addr[1] = (uint32_t)get_tx_buffer_app_cb, + .app_cb_addr[2] = (uint32_t)get_uart_flag_app_cb, + .app_cb_addr[3] = (uint32_t)get_tx_rx_pin_app_cb, +#elif (SUPPORT_FSBL_GPIO_SET == 1) + .app_cb_addr[1] = (uint32_t)gpio_set_app_cb, +#else +#endif + //add more cb here +}; + + +#if FEATURE_ENCRYPTION +#if defined ( __CC_ARM ) || defined ( __GNUC__ ) +#define ENC_ALIGN_SECTION __attribute__((aligned(16), used, section(".enc.dummy.align"))); +const uint8_t enc_dummy_align[16] ENC_ALIGN_SECTION; +#else +//#define ENC_ALIGN_SECTION @ ".enc.dummy.align" +//#pragma data_alignment=16 +//__root const uint8_t enc_dummy_align[16] ENC_ALIGN_SECTION; +#endif +#endif + + +#if defined (__CC_ARM) +#pragma push +#pragma diag_suppress 1296 /* disable warning 1296(extened constant initialiser used)*/ +#endif + +/** +* @brief: application header. +* @note: items in ENCRYPT_RAM_CODE macro is for encrytion solution only +*/ + +const T_IMG_HEADER_FORMAT img_header APP_FLASH_HEADER = +{ + .ctrl_header = + { + .ic_type = DEFINED_IC_TYPE, + .secure_version = 0, +#if FEATURE_ENCRYPTION + .ctrl_flag.flag_value.enc = 1, + .ctrl_flag.flag_value.xip = 0, + .ctrl_flag.flag_value.load_when_boot = 1, + .ctrl_flag.flag_value.enc_key_select = ENC_KEY_OCEK_WITH_OEMCONST, +#else + .ctrl_flag.flag_value.xip = 1, + .ctrl_flag.flag_value.enc = 0, + .ctrl_flag.flag_value.load_when_boot = 0, + .ctrl_flag.flag_value.enc_key_select = 0, +#endif + .ctrl_flag.flag_value.enc_load = 0, + .ctrl_flag.flag_value.not_ready = 0, + .ctrl_flag.flag_value.not_obsolete = 1, + .ctrl_flag.flag_value.compressed_not_ready = 0, + .ctrl_flag.flag_value.compressed_not_obsolete = 1, +#if (BOOT_INTEGRITY_CHECK_EN == 0) + .ctrl_flag.flag_value.integrity_check_en_in_boot = 0, +#else + .ctrl_flag.flag_value.integrity_check_en_in_boot = 1, +#endif + .image_id = AppPatch, + .payload_len = APP_FAKE_PAYLOAD_LEN, //Will modify by build tool later + }, + .uuid = DEFINE_rom_uuid, + +#if FEATURE_ENCRYPTION +#if defined ( __ICCARM__ ) + .exe_base = (uint32_t)__section_begin(".app.encryption.text"), + .load_base = (uint32_t)__section_begin(".app.encryption.text_init"), + .load_len = (uint32_t)__section_size(".app.encryption.text"), +#elif defined (__CC_ARM) + .load_base = (uint32_t)Load$$ENCRYPTION_RAM_CODE$$Base, + .exe_base = (uint32_t)Image$$ENCRYPTION_RAM_CODE$$Base, + .load_len = (uint32_t)Load$$ENCRYPTION_RAM_CODE$$Length, +#else + .exe_base = (uint32_t) &__encryption_ram_code_exe_ad__, //(uint32_t)IMAGE_FLASH_START_ADDR, + .load_base = (uint32_t) &__encryption_ram_code_load_ad__, + .load_len = (uint32_t) &__encryption_ram_code_length__, +#endif +#else +#if defined ( __ICCARM__ ) + .load_base = 0, + .exe_base = (uint32_t)SystemInit, +#elif defined (__CC_ARM) + .load_base = (uint32_t)Load$$FLASH_START_ADDR$$RO$$Base, + .exe_base = (uint32_t)Image$$FLASH_START_ADDR$$RO$$Base, +#else + .load_base = 0, + .exe_base = (uint32_t) SystemInit, +#endif + .load_len = 0, //0 indicates all XIP +#endif +#if (APP_BANK == 0) + .image_base = BANK0_APP_ADDR, +#else + .image_base = BANK1_APP_ADDR, +#endif + + .git_ver = + { + .ver_info.sub_version._version_major = VERSION_MAJOR, + .ver_info.sub_version._version_minor = VERSION_MINOR, + .ver_info.sub_version._version_revision = VERSION_REVISION, + .ver_info.sub_version._version_reserve = VERSION_BUILDNUM % 32, //only 5 bit + ._version_commitid = VERSION_GCID, + ._customer_name = {CN_1, CN_2, CN_3, CN_4, CN_5, CN_6, CN_7, CN_8}, + }, + +#ifdef OTA_MAGIC_PATTERN + .ota_magic_pattern = OTA_MAGIC_PATTERN, +#endif + + .app_cb_signature = SIGNATURE_APP_CB, + .app_cb_table_base_address = (uint32_t) &app_cb_table +}; +#if defined ( __ICCARM__ ) || defined ( __CC_ARM ) +const T_AUTH_HEADER_FORMAT auth_header APP_FLASH_HEADER = +{ +#if defined ( __ICCARM__ ) + .header_mac = {0xFF}, + .payload_mac = {0xFF}, +#else + .header_mac = {[0 ... 15] = 0xFF}, + .payload_mac = {[0 ... 15] = 0xFF}, +#endif +}; +#elif defined ( __GNUC__ ) +const T_AUTH_HEADER_FORMAT auth_header APP_FLASH_HEADER_AUTH = +{ + .header_mac = {[0 ... 15] = 0xFF}, + .payload_mac = {[0 ... 15] = 0xFF}, +}; +#endif +#if defined ( __CC_ARM ) +#pragma pop +#endif +extern void upperstack_loader(void); +void AppUpdateVectorTable(void); +void pre_main(void); +void wdg_system_reset_app_cb(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason); +uint32_t random_seed_value; + +/** End of SYSTEM_INIT_Exported_Variables + * @} + */ + +/*============================================================================* + * Functions + *============================================================================*/ +/** @defgroup SYSTEM_INIT_Exported_Functions System Init Exported Functions + * @{ + */ +void random_seed_init(void) +{ + random_seed_value = platform_random(0xFFFFFFFF); +} + +void common_main(void) +{ +#if (SUPPORT_FTL_IN_APP == 1) + extern void ftl_patch_point_init(void); + ftl_patch_point_init(); + + extern uint32_t ftl_init(uint32_t u32PageStartAddr, uint8_t pagenum); + ftl_init(flash_get_bank_addr(FLASH_FTL), + flash_get_bank_size(FLASH_FTL) / OTP->PageSize); +#else + extern uint32_t ftl_init(uint32_t u32PageStartAddr, uint8_t pagenum); + ftl_init(flash_get_bank_addr(FLASH_FTL), + flash_get_bank_size(FLASH_FTL) / OTP->PageSize); +#endif + + //add common system code here before enter user defined main function +#if (SUPPORT_NORMAL_OTA == 1) + if (dfu_check_ota_mode_flag()) + { + dfu_main(); + dfu_set_ota_mode_flag(false); + goto START_SCHEDULER; + } +#endif + + OTP->run_in_app = 1; + + random_seed_init(); + +#if (RUN_APP_IN_HCIMODE_ENABLE == 0) + if (OTP->stack_en) + { + DBG_DIRECT("In SoC Mode"); + } + else + { + DBG_DIRECT("WARNING: In HCI Mode, will not run APP Task"); + WDG_Disable(); + goto START_SCHEDULER; + } +#endif + +#if (LOG_UART_MULTIPLEXING == 1) + PPB_Init(pMCU_PPB_user); +#endif + + //print sdk lib version + show_sdk_lib_version(); + +#if (SYSTEM_TRACE_ENABLE == 1) + extern void system_trace_init(void); + system_trace_init(); +#endif + +#if defined ( __ICCARM__ ) + extern void __iar_program_start(const int); + __iar_program_start(0); +#elif defined (__CC_ARM) + extern int __main(void); + __main(); +#elif defined (__GNUC__) + extern int main(void); + main(); +#endif + +START_SCHEDULER: + os_sched_start(); + return; +} + + +APP_FLASH_TEXT_SECTION +void ram_init(void) +{ +#if defined ( __CC_ARM ) + //copy data on ro + extern char Image$$RAM_DATA_ON$$RO$$Base[]; + extern char Load$$RAM_DATA_ON$$RO$$Base[]; + extern unsigned int Image$$RAM_DATA_ON$$RO$$Length; + + memcpy(Image$$RAM_DATA_ON$$RO$$Base, + Load$$RAM_DATA_ON$$RO$$Base, + (unsigned int)&Image$$RAM_DATA_ON$$RO$$Length); + + //copy data on rw + extern char Image$$RAM_DATA_ON$$RW$$Base[]; + extern char Load$$RAM_DATA_ON$$RW$$Base[]; + extern unsigned int Image$$RAM_DATA_ON$$RW$$Length; + + memcpy(Image$$RAM_DATA_ON$$RW$$Base, + Load$$RAM_DATA_ON$$RW$$Base, + (unsigned int)&Image$$RAM_DATA_ON$$RW$$Length); + + //clear data on zi + extern char Image$$RAM_DATA_ON$$ZI$$Base[]; + extern unsigned int Image$$RAM_DATA_ON$$ZI$$Length; + + memset(Image$$RAM_DATA_ON$$ZI$$Base, + 0, + (unsigned int)&Image$$RAM_DATA_ON$$ZI$$Length); +#elif defined ( __GNUC__ ) + //copy data on ro + extern uint32_t *__ram_dataon_ro_start__; + extern uint32_t *__ram_ro_load_ad__; + extern uint32_t *__ram_dataon_ro_length__; + + memcpy(&__ram_dataon_ro_start__, + &__ram_ro_load_ad__, + (unsigned int)&__ram_dataon_ro_length__); + //copy data on rw + extern uint32_t *__ram_dataon_rw_start__; + extern uint32_t *__ram_rw_load_ad__; + extern uint32_t *__ram_dataon_rw_length__; + + memcpy(&__ram_dataon_rw_start__, + &__ram_rw_load_ad__, + (unsigned int)&__ram_dataon_rw_length__); + + //clear data on zi + extern uint32_t *__ram_dataon_zi_start__; + extern uint32_t *__ram_dataon_zi_length__; + + memset(&__ram_dataon_zi_start__, + 0, + (unsigned int)&__ram_dataon_zi_length__); +#elif defined (__ICCARM__) + extern void __iar_data_init2(void); + __iar_data_init2(); +#endif + +} + +APP_FLASH_TEXT_SECTION +void ram_cache_init(void) +{ +#if defined ( __CC_ARM ) + //copy cache ro + extern char Image$$CACHE_DATA_ON$$RO$$Base[]; + extern char Load$$CACHE_DATA_ON$$RO$$Base[]; + extern unsigned int Image$$CACHE_DATA_ON$$RO$$Length; + + memcpy(Image$$CACHE_DATA_ON$$RO$$Base, + Load$$CACHE_DATA_ON$$RO$$Base, + (unsigned int)&Image$$CACHE_DATA_ON$$RO$$Length); + + //copy share cache ram rw + extern char Image$$CACHE_DATA_ON$$RW$$Base[]; + extern char Load$$CACHE_DATA_ON$$RW$$Base[]; + extern unsigned int Image$$CACHE_DATA_ON$$RW$$Length; + + memcpy(Image$$CACHE_DATA_ON$$RW$$Base, + Load$$CACHE_DATA_ON$$RW$$Base, + (unsigned int)&Image$$CACHE_DATA_ON$$RW$$Length); + + //clear share cache ram zi + extern char Image$$CACHE_DATA_ON$$ZI$$Base[]; + extern unsigned int Image$$CACHE_DATA_ON$$ZI$$Length; + + memset(Image$$CACHE_DATA_ON$$ZI$$Base, + 0, + (unsigned int)&Image$$CACHE_DATA_ON$$ZI$$Length); +#elif defined ( __GNUC__ ) + //copy share cache ram rw + extern uint32_t *__cache_dataon_start__; + extern uint32_t *__cache_data_load_ad__; + extern uint32_t *__cache_dataon_length__; + + memcpy(&__cache_dataon_start__, + &__cache_data_load_ad__, + (unsigned int)&__cache_dataon_length__); +#endif +} + + +APP_FLASH_TEXT_SECTION +APP_MAIN_FUNC get_image_entry_addr(uint16_t image_id) +{ + + uint32_t active_ota_bank_addr = get_active_ota_bank_addr(); + if (!check_header_valid(active_ota_bank_addr, OTA)) + { + return NULL; + } + + T_OTA_HEADER_FORMAT *ota_header = (T_OTA_HEADER_FORMAT *)active_ota_bank_addr; + uint32_t image_size = + HAL_READ32((uint32_t)&ota_header->secure_boot_size, (image_id - SecureBoot) * 8); + + if (image_size == 0) + { + return NULL; + } + + uint32_t header_addr = get_header_addr_by_img_id((T_IMG_ID)image_id); + + if (!check_header_valid(header_addr, (T_IMG_ID)image_id)) + { + return NULL; + } + + T_IMG_HEADER_FORMAT *header = (T_IMG_HEADER_FORMAT *)header_addr; + + if (header->ctrl_header.image_id != image_id || image_id >= IMAGE_MAX) + { + return NULL; + } + + APP_MAIN_FUNC entry_func = (APP_MAIN_FUNC)(header->exe_base | 1); + + return entry_func; +} + + +void set_os_clock(OS_TICK os_tick) APP_FLASH_TEXT_SECTION; +void set_os_clock(OS_TICK os_tick) +{ + switch (os_tick) + { + case OS_TICK_10MS: + OTP->os_tick_rate_HZ = 100; + break; + case OS_TICK_5MS: + OTP->os_tick_rate_HZ = 200; + break; + case OS_TICK_2MS: + OTP->os_tick_rate_HZ = 500; + break; + case OS_TICK_1MS: + OTP->os_tick_rate_HZ = 1000; + break; + default: + break; + } +} + +#if (SUPPORT_BRANCH_TO_ANOTHER_APP == 1) +#define ANOTHER_APP_IMG_ADDR (get_temp_ota_bank_addr_by_img_id(AppPatch) + 4 * 1024) + +#if defined ( __ICCARM__ ) +#if FEATURE_ENCRYPTION +APP_MAIN_FUNC get_app_image_entry_addr(uint16_t image_id, + uint32_t header_addr) APP_ENCRYPTION_TEXT_SECTION; +#else +APP_MAIN_FUNC get_app_image_entry_addr(uint16_t image_id, + uint32_t header_addr) APP_FLASH_TEXT_SECTION; +#endif +#else +APP_MAIN_FUNC get_app_image_entry_addr(uint16_t image_id, + uint32_t header_addr) APP_FLASH_TEXT_SECTION; +#endif + +APP_MAIN_FUNC get_app_image_entry_addr(uint16_t image_id, uint32_t header_addr) +{ + /*check ic_type, not_ready, image_id, uuid*/ + if (!check_header_valid(header_addr, (T_IMG_ID)image_id)) + { + return NULL; + } + + T_IMG_HEADER_FORMAT *header = (T_IMG_HEADER_FORMAT *)header_addr; + + if (image_id <= OTA || image_id >= IMAGE_MAX) + { + return NULL; + } + + APP_MAIN_FUNC entry_func = (APP_MAIN_FUNC)(header->exe_base | 1); + + return entry_func; +} +#endif + +#if defined ( __ICCARM__ ) +#if FEATURE_ENCRYPTION +void SystemInit(void) APP_ENCRYPTION_TEXT_SECTION; +#else +void SystemInit(void) APP_FLASH_TEXT_SECTION; +#endif +#else +void SystemInit(void) APP_FLASH_TEXT_SECTION; +#endif + +void SystemInit(void) +{ + //hci mode check and bypass app + if (check_hci_mode_flag() || (OTP->stack_en == 0)) + { + return; + } + +#if (SUPPORT_BRANCH_TO_ANOTHER_APP == 1) + APP_MAIN_FUNC entry_func = NULL; + entry_func = (APP_MAIN_FUNC)get_app_image_entry_addr(AppPatch, ANOTHER_APP_IMG_ADDR); + + if (entry_func) + { + entry_func(); + + return; + } +#endif + + if (!check_hci_mode_flag()) + { + Pinmux_Deinit_rom(P3_0); + Pinmux_Deinit_rom(P3_1); + } + + //init pre_main and main functions + app_pre_main = (APP_MAIN_FUNC)pre_main; + upperstack_entry = get_image_entry_addr(UpperStack);; + app_main = (APP_MAIN_FUNC)common_main; + app_cb_wdg_reset = (APP_CB_WDG_RESET_TYPE)wdg_system_reset_app_cb; + + /******** update otp here**********/ + //ram layout update based on App's setting + OTP->appDataAddr = APP_GLOBAL_ADDR; + update_ram_layout(APP_GLOBAL_SIZE, HEAP_DATA_ON_SIZE, SHARE_CACHE_RAM_SIZE); + +#ifdef SHUTDOWN_DATARAM_SIZE + if (SHUTDOWN_DATARAM_SIZE == 0) + { + set_dataram_to_shutdown(NO_DATARAM_SHUTDOWN); + } + else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_4KB) + { + set_dataram_to_shutdown(LAST_4K_DATARAM_SHUTDOWN); + } + else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_8KB) + { + set_dataram_to_shutdown(LAST_8K_DATARAM_SHUTDOWN); + } + else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_24KB) + { + set_dataram_to_shutdown(LAST_24K_DATARAM_SHUTDOWN); + } + else if (SHUTDOWN_DATARAM_SIZE == SHUTDOWN_DATARAM_56KB) + { + set_dataram_to_shutdown(LAST_56K_DATARAM_SHUTDOWN); + } + else + { + DBG_DIRECT("Error! SHUTDOWN_DATARAM_SIZE is not match the size that can be set!"); + } +#endif + +#ifdef SUPPORT_SINGLE_BANK_OTA_USER_DATA + OTP->bkp_data1_addr = USER_DATA_START_ADDR; + OTP->bkp_data1_size = USER_DATA_MAX_SIZE; +#endif + +#if (WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE > 0) && (SYSTEM_TRACE_ENABLE == 1) && (TRACE_HARDFAULT == 1) + patch_hardfault_save_to_flash_init(); +#endif + +#if ((SYSTEM_TRACE_ENABLE == 1) && ((WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0 && TRACE_WDG_TIMEOUT == 1) || (TRACE_TASK_HANG_USE_WDG_ISR == 1))) + patch_wdg_timeout_reason_save_to_flash_init(); +#endif + + + //sw timer config +#ifdef TIMER_MAX_NUMBER + //define TIMER_MAX_NUMBER in otp_config.h + OTP->timerMaxNumber = TIMER_MAX_NUMBER; +#endif + + //timer task stack size config +#ifdef TIMER_TASK_STACK_SIZE + //define TIMER_TASK_STACK_SIZE in otp_config.h + OTP->timer_task_stack_size = TIMER_TASK_STACK_SIZE; +#endif + + //flash config + /*config enable flash block proect depending on flash layout and flash id*/ +#if (FLASH_BLOCK_PROTECT_ENABLE == 1) + OTP->bp_enable = 1; +#else + OTP->bp_enable = 0; +#endif + OTP->delay_10us_after_toggle_cs = AFTER_TOGGLE_CS_DELAY; + +#if (CHK_IMG_INTEGRITY_USE_AUTO_MODE_ACCESS_FLASH == 1) + OTP->image_split_read = 0; //use flash auto mode to check image integrity +#endif + + + //os config + /*config enable check task stack overflow*/ +#if (CHECK_STACK_OVERFLOW_ENABLE == 1) + OTP->checkForStackOverflow = 1; +#else + OTP->checkForStackOverflow = 0; +#endif + + + //platform config + /*config enable platform assert*/ +#if (PLATFORM_ASSERT_ENABLE == 1) + OTP->enableASSERT = 1; +#else + OTP->enableASSERT = 0; +#endif + + /*Print all log in log buffer before entering DLPS */ +#if (CHECK_LOG_BUFFER_BEFORE_DLPS_ENABLE == 1) + OTP->printAllLogBeforeEnterDLPS = 1; +#else + OTP->printAllLogBeforeEnterDLPS = 0; +#endif + + /*config enable log or not*/ +#if (CONFIG_LOG_FUNCTION_ENABLE == 1) + OTP->logDisable = 0; +#else + OTP->logDisable = 1; +#endif + + /*config log baudrate*/ +#ifdef LOG_BAUD_RATE + OTP->logBaudRate = LOG_BAUD_RATE; +#endif + +#if (FTL_REAL_LOGIC_ADDR_SIZE > 0) + if (FTL_REAL_LOGIC_ADDR_SIZE <= (((((FMC_PAGE_SIZE / 8) - 1) * ((OTP->ftl_size / FMC_PAGE_SIZE) - + 1)) - 1) << 2)) + { + OTP->ftl_real_logic_addr_size = FTL_REAL_LOGIC_ADDR_SIZE; + } + else + { + DBG_DIRECT("ERROR! FTL logic addr size is too large!"); + } +#endif + +#if (FTL_BT_STORAGE_SPACE_SIZE > 0) + if (FTL_BT_STORAGE_SPACE_SIZE * 1024 <= OTP->ftl_real_logic_addr_size) + { + OTP->ftl_app_logical_addr_base = FTL_BT_STORAGE_SPACE_SIZE; + } + else + { + DBG_DIRECT("ERROR! FTL BT storage space size is too large!"); + } +#endif + + /*if app don't use CTC, can't switch power domain to avoid leakage*/ +#if ( USE_CTC_DLPS == 1) + OTP->ldo_311_aux_power_domain = PON_DOMAIN; +#endif + + /*to fix bug need disable dump callstack info before WDG_SystemReset, default enable */ +#if (DUMP_INFO_BEFORE_RESET_DISABLE == 1) + OTP->dump_info_before_reset = 0; +#endif + + /*Debug: config enable write hardfault record to flash*/ +#if (WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE > 0) + OTP->write_info_to_flash_when_hardfault = WRITE_HARDFAULT_RECORD_TO_FLASH_ENABLE; + OTP->HardFault_Record_BegAddr = HARDFAULT_RECORD_BEG_ADDR; + OTP->HardFault_Record_EndAddr = HARDFAULT_RECORD_END_ADDR; + OTP->HardFault_Record_CFG = HARDFAULT_RECORD_CFG; +#endif + + /*before wdg system reset, write reset reason to specific flash addr*/ +#if (WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE > 0) + OTP->write_info_to_flash_before_reset = WRITE_REASON_TO_FLASH_BEFORE_RESET_ENABLE; + OTP->reboot_record_address = REBOOT_REASON_RECORD_ADDRESS; + OTP->reboot_record_item_limit_power_2 = REBOOT_REASON_RECORD_LIMIT_POWERT2; +#endif + + /*config enable swd pinmux*/ +#if (SWD_PINMUX_ENABLE == 1) + OTP->SWD_ENABLE = 1; +#else + OTP->SWD_ENABLE = 0; +#endif + + /*config enable watch dog in rom*/ +#if (ROM_WATCH_DOG_ENABLE == 1) + OTP->wdgEnableInRom = 1; +#else + OTP->wdgEnableInRom = 0; +#endif + + /*config watch dog mode in rom, defualt 4s timeout and reset all*/ +#if (ROM_WATCH_DOG_ENABLE == 1) + OTP->wdgConfigDivfactor = ROM_WATCH_DOG_CFG_DIV_FACTOR; + OTP->wdgConfigCntLimit = ROM_WATCH_DOG_CFG_CNT_LIMIT; +#if (TRACE_TASK_HANG_USE_WDG_ISR == 1) + OTP->wdgMode = INTERRUPT_CPU; +#else + OTP->wdgMode = ROM_WATCH_DOG_MODE; +#endif +#endif + + /*config enable write hardfault record to flash*/ +#if (ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH > 0) + OTP->write_info_to_flash_when_hardfault = ENABLE_WRITE_HARDFAULT_RECORD_TO_FLASH; + OTP->HardFault_Record_BegAddr = HARDFAULT_RECORD_BEG_ADDR; + OTP->HardFault_Record_EndAddr = HARDFAULT_RECORD_END_ADDR; + OTP->HardFault_Record_CFG = HARDFAULT_RECORD_CFG; +#endif + +#if (ENABLE_FLASH_READ_TURN_OFF_RF > 0) + OTP->read_turn_on_off_rf = ENABLE_FLASH_READ_TURN_OFF_RF; +#endif + + + //app config + OTP->ota_timeout_total = OTA_TIMEOUT_TOTAL; + OTP->ota_timeout_wait4_conn = OTA_TIMEOUT_WAIT4_CONN; + OTP->ota_timeout_wait4_image_transfer = OTA_TIMEOUT_WAIT4_IMAGE_TRANS; + OTP->ota_timeout_ctittv = OTA_TIMEOUT_CTITTV; + + /*config default value because extended in app*/ + OTP->ota_timeout_wait_packet = 5; +#if OTA_TIMEOUT_WAIT_PACKET + OTP->ota_timeout_wait_packet = OTA_TIMEOUT_WAIT_PACKET; +#endif + +#if ROM_OTA_LINKLOSS_RST + OTP->ota_link_loss_reset = 1; +#endif + +#ifdef OS_TICK_TIME + set_os_clock(OS_TICK_TIME); +#endif + + /*config bt stack parameters in rom*/ +#ifdef BT_STACK_CONFIG_ENABLE + bt_stack_config_init(); +#endif + +//add more otp config here + + ram_init(); + + if (os_patch) + { + os_patch(); + } +} + +void print_reset_reason(void) APP_FLASH_TEXT_SECTION; +void print_reset_reason(void) +{ + uint32_t wdg_reset_pc = (btaon_fast_read_safe(0x1c2) << 17) | (btaon_fast_read_safe(0x1c0) << 1); + uint32_t wdg_reset_lr = (btaon_fast_read_safe(0x1c6) << 16) | (btaon_fast_read_safe(0x1c4)); + uint32_t wdg_reset_psr = (btaon_fast_read_safe(0x1ca) << 16) | (btaon_fast_read_safe(0x1c8)); + + uint32_t aon_wdg_reset_pc = (btaon_fast_read_safe(0x1ce) << 17) | (btaon_fast_read_safe( + 0x1cc) << 1); + uint32_t aon_wdg_reset_lr = (btaon_fast_read_safe(0x1d2) << 16) | (btaon_fast_read_safe(0x1d0)); + uint32_t aon_wdg_reset_psr = (btaon_fast_read_safe(0x1d6) << 16) | (btaon_fast_read_safe(0x1d4)); + + if (wdg_reset_lr == 0) + { + T_SW_RESET_REASON sw_reset_type = reset_reason_get(); + + if (sw_reset_type == RESET_REASON_POWERDOWN) + { + BOOT_PRINT_INFO0("[Debug Info]RESET Reason: Wakeup From Powerdown"); + } + else + { + BOOT_PRINT_INFO0("[Debug Info]RESET Reason: HW"); + } + + uint32_t wdg_reg_backup = WDG->WDG_CTL; + +#if (TRACE_TASK_HANG_USE_WDG_ISR == 1) + T_WDG_MODE reset_mode = (T_WDG_MODE)((wdg_reg_backup >> 29) & 0x3); + if (INTERRUPT_CPU == reset_mode) + { + NVIC_DisableIRQ(WDG_IRQn); + } +#endif + + //trigger wdg reset interrupt to update wdg_reset_lr (register is Read-Only, can't write directly) + WDG_ClockEnable(); + WDG_Config(1, 0, INTERRUPT_CPU); + WDG_Enable(); + platform_delay_ms(1); //add delay to make lr as a stable value (0x7bb5 for RTL8762E A-cut) + + WDG_Disable(); + platform_delay_us(150); //wait for WDG is disabled + +#if (TRACE_TASK_HANG_USE_WDG_ISR == 1) + if (INTERRUPT_CPU == reset_mode) + { + NVIC_ClearPendingIRQ(WDG_IRQn); + NVIC_EnableIRQ(WDG_IRQn); + } +#endif + WDG->WDG_CTL = wdg_reg_backup; + } + else + { + T_SW_RESET_REASON sw_reset_type = reset_reason_get(); + + //fix reset reason error when watchdog timeout and ROM_WATCH_DOG_MODE is RESET_ALL + if (sw_reset_type == RESET_REASON_HW) + { + sw_reset_type = RESET_REASON_WDG_TIMEOUT; + } + + BOOT_PRINT_INFO1("[Debug Info]RESET Reason: SW, TYPE 0x%x", sw_reset_type); + BOOT_PRINT_INFO3("[Debug Info]WDG: pc %x, lr %x, psr %x", wdg_reset_pc, wdg_reset_lr, + wdg_reset_psr); + BOOT_PRINT_INFO3("[Debug Info]AON WDG: pc %x, lr %x, psr %x", aon_wdg_reset_pc, aon_wdg_reset_lr, + aon_wdg_reset_psr); + } +} + +APP_FLASH_TEXT_SECTION +void pre_main(void) +{ + __disable_irq(); + + print_reset_reason(); + + ram_cache_init(); +#if defined ( __CC_ARM ) + load_overlay(OVERLAY_SCENARIO_BOOT_ONCE); +#endif + setlocale(LC_ALL, "C"); + + + BOOT_PRINT_ERROR2("SDK Ver: %s, Build Time: %s", + TRACE_STRING(VERSION_BUILD_STR), + TRACE_STRING(BUILDING_TIME)); + + AppUpdateVectorTable(); + + + + if (app_pre_main_cb) + { + app_pre_main_cb(); + } + + return; +} + +APP_FLASH_TEXT_SECTION +void wdg_system_reset_app_cb(T_WDG_MODE wdg_mode, T_SW_RESET_REASON reset_reason) +{ + //do something necessary before watch dog reset + if (user_wdg_cb) + { + if (user_wdg_cb(wdg_mode, reset_reason)) + { + return; + } + } + +} + +__attribute__((weak)) void show_sdk_lib_version(void) +{ +} + +/** + * @brief update vector table in app + * @param none + * @return none + */ +OVERLAY_SECTION_BOOT_ONCE +void AppUpdateVectorTable(void) +{ +#if defined ( __CC_ARM ) + extern uint32_t Load$$RAM_VECTOR_TABLE$$RO$$Base; + extern uint32_t Image$$RAM_VECTOR_TABLE$$RO$$Length; +#elif defined ( __GNUC__ ) + extern uint32_t *__ram_vector_load_ad__; + extern uint32_t *__ram_vector_table_length__; +#endif + extern void Default_Handler(void); + extern void ROM_Default_Handler(void); + + const char *SysException[] = + { + "InitialSP", "Reset", "NMI", "HardFault", "MemManage", "BusFault", "UsageFault", "Rsvd", + "Rsvd", "Rsvd", "Rsvd", "SVC", "DebugMon", "Rsvd", "PendSV", "SysTick" + }; + const char *ExtIrq[] = + { + "System", "WDG", "BTMAC", "TIM3", "TIM2", "Platform", "I2S0_TX", "I2S0_RX", "Timer4-5", + "GPIO4", "GPIO5", "UART1", "UART0", "RTC", "SPI0", "SPI1", "I2C0", "I2C1", "ADC", + "Peripheral", "GDMA0 Channel0", "GDMA0 Channel1", "GDMA0 Channel2", "GDMA0 Channel3", + "Enhanced_Timer0", "Enhanced_Timer1", "GPIO_Group3", "GPIO_Group2", "IR", "GPIO_Group1", + "GPIO_Group0", "Rsvd", "TIM4", "TIM5", "SPI_Flash", "Qdecode", + "Keyscan", "SPI2W", "LPCOMP", "PTA_Mailbox", "CAP_Touch", "TRNG" + }; + + IRQ_Fun *pRamVector = (IRQ_Fun *)VTOR_RAM_ADDR; +#if defined ( __ICCARM__ ) +#pragma section = ".intvec" + IRQ_Fun *pAppVector = (IRQ_Fun *)__section_begin(".intvec"); + uint32_t AppVectorSize = (uint32_t)__section_size(".intvec"); + DBG_DIRECT("pAppVector = 0x%x, AppVectorSize = %d", pAppVector, AppVectorSize); +#elif defined (__CC_ARM) + IRQ_Fun *pAppVector = (IRQ_Fun *)&Load$$RAM_VECTOR_TABLE$$RO$$Base; + uint32_t AppVectorSize = (uint32_t)&Image$$RAM_VECTOR_TABLE$$RO$$Length; +#elif defined (__GNUC__) + IRQ_Fun *pAppVector = (IRQ_Fun *)(&__ram_vector_load_ad__); + uint32_t AppVectorSize = (uint32_t)&__ram_vector_table_length__; +#endif + uint32_t i = 0; + + if (SCB->VTOR != VTOR_RAM_ADDR) + { + RamVectorTableInit(VTOR_RAM_ADDR); + } + + /* Update APP defined handlers */ + for (i = 0; i < AppVectorSize / 4; ++i) + { + if (i == 0 || i == 1) //skip __initial_sp and reset_handler remap + { + continue; + } + + if (((pAppVector[i] != Default_Handler) && (pAppVector[i] != 0)) || + ((pAppVector[i] == Default_Handler) && (pRamVector[i] == (IRQ_Fun)ROM_Default_Handler))) + { + if (i < System_VECTORn) + { + OS_PRINT_WARN1("Warning! %s is updated by APP!", TRACE_STRING(SysException[i])); + } + else + { + OS_PRINT_WARN1("Warning! ISR %s is updated by APP!", + TRACE_STRING(ExtIrq[i - System_VECTORn])); + } + + pRamVector[i] = pAppVector[i]; + } + } + + __DMB(); + __DSB(); +} +/** + * @brief GPIO Group3 Handler + * @param none + * @return none + */ +DATA_RAM_FUNCTION +void GPIO_Group3_Handler(void) +{ + uint32_t GPIOIrqStatus = GPIO->INTSTATUS; + + //Check exact IRQ function + if (GPIOIrqStatus & BIT3) + { + GPIO3_Handler(); + } + if (GPIOIrqStatus & BIT7) + { + GPIO7_Handler(); + } + if (GPIOIrqStatus & BIT11) + { + GPIO11_Handler(); + } + if (GPIOIrqStatus & BIT15) + { + GPIO15_Handler(); + } + if (GPIOIrqStatus & BIT19) + { + GPIO19_Handler(); + } + if (GPIOIrqStatus & BIT23) + { + GPIO23_Handler(); + } + if (GPIOIrqStatus & BIT27) + { + GPIO27_Handler(); + } + if (GPIOIrqStatus & BIT31) + { + GPIO31_Handler(); + } +} +/** + * @brief GPIO Group2 Handler + * @param none + * @return none + */ +DATA_RAM_FUNCTION +void GPIO_Group2_Handler(void) +{ + uint32_t GPIOIrqStatus = GPIO->INTSTATUS; + + //Check exact IRQ function + if (GPIOIrqStatus & BIT2) + { + GPIO2_Handler(); + } + if (GPIOIrqStatus & BIT6) + { + GPIO6_Handler(); + } + if (GPIOIrqStatus & BIT10) + { + GPIO10_Handler(); + } + if (GPIOIrqStatus & BIT14) + { + GPIO14_Handler(); + } + if (GPIOIrqStatus & BIT18) + { + GPIO18_Handler(); + } + if (GPIOIrqStatus & BIT22) + { + GPIO22_Handler(); + } + if (GPIOIrqStatus & BIT26) + { + GPIO26_Handler(); + } + if (GPIOIrqStatus & BIT30) + { + GPIO30_Handler(); + } +} +/** + * @brief GPIO Group1 Handler + * @param none + * @return none + */ +DATA_RAM_FUNCTION +void GPIO_Group1_Handler(void) +{ + uint32_t GPIOIrqStatus = GPIO->INTSTATUS; + + //Check exact IRQ function + if (GPIOIrqStatus & BIT1) + { + GPIO1_Handler(); + } + if (GPIOIrqStatus & BIT9) + { + GPIO9_Handler(); + } + if (GPIOIrqStatus & BIT13) + { + GPIO13_Handler(); + } + if (GPIOIrqStatus & BIT17) + { + GPIO17_Handler(); + } + if (GPIOIrqStatus & BIT21) + { + GPIO21_Handler(); + } + if (GPIOIrqStatus & BIT25) + { + GPIO25_Handler(); + } + if (GPIOIrqStatus & BIT29) + { + GPIO29_Handler(); + } +} +/** + * @brief GPIO Group0 Handler + * @param none + * @return none + */ +DATA_RAM_FUNCTION +void GPIO_Group0_Handler(void) +{ + uint32_t GPIOIrqStatus = GPIO->INTSTATUS; + + //Check exact IRQ function + if (GPIOIrqStatus & BIT0) + { + GPIO0_Handler(); + } + if (GPIOIrqStatus & BIT8) + { + GPIO8_Handler(); + } + if (GPIOIrqStatus & BIT12) + { + GPIO12_Handler(); + } + if (GPIOIrqStatus & BIT16) + { + GPIO16_Handler(); + } + if (GPIOIrqStatus & BIT20) + { + GPIO20_Handler(); + } + if (GPIOIrqStatus & BIT24) + { + GPIO24_Handler(); + } + if (GPIOIrqStatus & BIT28) + { + GPIO28_Handler(); + } +} + +#if (RETARGET_PRINTF_METHOD == 0) +int __2printf(const char *fmt, ...) +{ + return 0; +} +#endif + +void *malloc(size_t size) +{ + return os_mem_alloc(RAM_TYPE_DATA_ON, size); +} + +void *calloc(size_t n, size_t size) +{ + return os_mem_zalloc(RAM_TYPE_DATA_ON, n * size); +} + +/*only for FreeRTOS*/ +void *realloc(void *ptr, size_t size) +{ + void *new_ptr; + BlockLink_t *pxLink; + size_t old_size, new_size = 0; + + if (ptr == NULL) + { + return os_mem_alloc(RAM_TYPE_DATA_ON, size); + } + + if (size == 0) + { + os_mem_free(ptr); + ptr = NULL; + return NULL; + } + + pxLink = (BlockLink_t *)((uint8_t *)ptr - sizeof(BlockLink_t)); + old_size = pxLink->xBlockSize; + + if ((old_size - sizeof(BlockLink_t)) == + (size + (FreeRTOS_portBYTE_ALIGNMENT - (size & (FreeRTOS_portBYTE_ALIGNMENT - 1))))) + { + return ptr; + } + + os_sched_suspend(); + os_mem_free(ptr); + new_ptr = os_mem_alloc(RAM_TYPE_DATA_ON, size); + if (ptr != new_ptr) + { + pxLink = (BlockLink_t *)((uint8_t *)new_ptr - sizeof(BlockLink_t)); + new_size = pxLink->xBlockSize; + memcpy(new_ptr, ptr, (old_size < new_size) ? (old_size - sizeof(BlockLink_t)) : (new_size - sizeof( + BlockLink_t))); + } + os_sched_resume(); + + return new_ptr; +} + +void free(void *ptr) +{ + os_mem_free(ptr); +} + +#if (ENABLE_FULL_FEATURED_DIRECT_LOG == 1) +/*for full featured direct log print*/ +#define LOG_MESSAGE_SYNC_CODE 0x7E +#define MAX_LOG_MESSAGE_LEN 128 +#define GET_TYPE(info) (uint8_t)((info) >> 24) +#define GET_SUBTYPE(info) (uint8_t)((info) >> 16) + +extern uint8_t log_seq_num; +extern uint32_t log_timestamp_get(void); +extern void LogUartTxChar(const uint8_t ch); +void log_direct_app(uint32_t info, const char *fmt, ...) +{ + char l_msg[MAX_LOG_MESSAGE_LEN]; + uint16_t log_length; + int16_t fmt_length; + uint32_t timestamp; + va_list ap; + uint16_t i; + uint32_t s; + + /** + * Byte: Description + * 0: Sync(0x7E) + * 1: Length + * 2: SeqNum + * 3: CheckSum + * 4-5: Timestamp + * 6: Type + * 7: SubType: SUBTYPE_DIRECT + * 8: Format String + */ + + if (!is_log_init || OTP->logDisable == 1) + { + return; + } + + timestamp = log_timestamp_get(); + + l_msg[0] = LOG_MESSAGE_SYNC_CODE; + l_msg[4] = (uint8_t)timestamp; + l_msg[5] = (uint8_t)(timestamp >> 8); + l_msg[6] = GET_TYPE(info); + l_msg[7] = GET_SUBTYPE(info); + + log_length = 8; + + va_start(ap, fmt); +#if 1 + fmt_length = vsnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ap); +#else //save ROM code space, 20200907 lory + fmt_length = VSnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ((const int *)&fmt) + 1); +#endif + if (fmt_length < 0) /* error occurred */ + { + fmt_length = 0; + } + else if (log_length + fmt_length > MAX_LOG_MESSAGE_LEN) /* truncated */ + { + log_length = MAX_LOG_MESSAGE_LEN; + + } + else + { + log_length += fmt_length; + } + va_end(ap); + + l_msg[1] = log_length; + + s = os_lock(); + l_msg[2] = log_seq_num++; + os_unlock(s); + + l_msg[3] = l_msg[0] ^ l_msg[1] ^ l_msg[2]; + +#ifdef FOR_SIMULATION + for (i = 8; i < log_length; ++ i) + { + *((volatile uint8_t *)(FAKE_UART_ADDRESS)) = l_msg[i]; + } + *((volatile uint8_t *)(FAKE_UART_ADDRESS)) = '\n'; +#else + for (i = 0; i < log_length; ++i) + { + LogUartTxChar(l_msg[i]); + } +#endif +} +#endif + +/** + * @brief get cpu clock + * @param none + * @return uint32, for example 40000000 is 40M, 20000000 is 20M. + */ +uint32_t get_cpu_clock(void) +{ + extern uint32_t SystemCpuClock; + return SystemCpuClock; +} + +/** + * @brief get ic type + * @param none + * @return uint8_t, ic type: + * #define RTL8762ESF 0x1D + * #define RTL8762EGF 0x18 + * #define RTL8762ERF 0x28 + * #define RTL8762EJF 0x29 + * #define RTL8762EMF 0x39 + * #define RS625MF 0x49 + * #define RTL8762EKF 0x5A + * #define RTL8762EKO 0x6C + */ +uint8_t get_ic_type(void) +{ + return *(uint8_t *)0x00202cef; +} + +void *active_timer_handle; +void set_active_timer_callback(void *timer_handle) +{ + lps_mode_resume(); + os_timer_stop(&active_timer_handle); + os_timer_delete(&active_timer_handle); + active_timer_handle = NULL; +} +void set_boot_active_time(uint32_t active_time_ms) +{ + if (active_timer_handle == NULL) + { + lps_mode_pause(); + bool retval = os_timer_create(&active_timer_handle, "SetActiveTimer", 0, \ + active_time_ms, false, set_active_timer_callback); + if (retval) + { + os_timer_start(&active_timer_handle); + } + } + else + { + os_timer_restart(&active_timer_handle, active_time_ms); + } +} + +#if defined ( __CC_ARM ) +#elif defined ( __GNUC__ ) +#include +#include +#undef errno +extern int errno; + +int __attribute__((weak)) _close(int file) +{ + return -1; +} + +int __attribute__((weak)) _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int __attribute__((weak)) _getpid(void) +{ + return 1; +} + +int __attribute__((weak)) _isatty(int file) +{ + return 1; +} + +int __attribute__((weak)) _kill(int pid, int sig) +{ + errno = EINVAL; + return -1; +} + +int __attribute__((weak)) _lseek(int file, int ptr, int dir) +{ + return 0; +} + +int __attribute__((weak)) _read(int file, char *ptr, int len) +{ + return 0; +} + +int __attribute__((weak)) _write(int file, char *ptr, int len) +{ + return len; +} + +DATA_RAM_FUNCTION +void *memset(void *s, int c, size_t n) +{ + extern void *__aeabi_memset(void *s, size_t n, int c); + return __aeabi_memset(s, n, c); +} +#endif + +#if (LOG_UART_MULTIPLEXING == 1) + +APP_FLASH_TEXT_SECTION +PingpongBuffer *get_tx_buffer_app_cb(void) +{ + return pMCU_PPB_user; +} + +APP_FLASH_TEXT_SECTION +T_UART_FLAG *get_uart_flag_app_cb(void) +{ + return uart_flag_p; +} + +APP_FLASH_TEXT_SECTION +void get_tx_rx_pin_app_cb(uint8_t *p_tx, uint8_t *p_rx) +{ + *p_tx = UART_TX_PIN; + *p_rx = UART_RX_PIN; +} + +void data_print_buffer(const uint8_t *source, uint16_t size) +{ + PPB_Write(pMCU_PPB_user, source, size); +} + +#endif + +#if (SUPPORT_FSBL_GPIO_SET == 1) +APP_FLASH_TEXT_SECTION +void gpio_set_app_cb() // in fsbl, ram section bss and data not init +{ + //DBG_DIRECT("GPIO SET"); +} +#endif + +/** @} */ /* End of group SYSTEM_INIT_Exported_Functions */ +/** @} */ /* End of group SYSTEM_INIT */ + diff --git a/src/platform/dfu_flash.c b/src/platform/dfu_flash.c new file mode 100644 index 0000000..81f4a15 --- /dev/null +++ b/src/platform/dfu_flash.c @@ -0,0 +1,1033 @@ +#include +#include "trace.h" +#include "flash_device.h" +#include "patch_header_check.h" +#include "hw_aes.h" +#include "rtl876x_hw_aes.h" +#include "otp.h" +#include "dfu_api.h" +#include "rtl876x_wdg.h" +#include "dfu_flash.h" +#include "sha256.h" +#include "crc16btx.h" +#include "board.h" + + +/*============================================================================* + * Macros + *============================================================================*/ +#define BTAON_FAST_REBOOT_SW_INFO0 0x2 + +#define DECODE_OFFSET (sizeof(T_COMPRESS_IMG_HEADER_FORMAT)) +#define COMPRESS_HEADER_SHA256_OFFSET 36 + +#define CRC_BUFFER_SIZE 128 //may modify to improve performance +#define SHA256_BUFFER_SIZE 128 + +#define SHA256_LENGTH 32 + +#define DFU_UPDATE_LEN 256 + +/*============================================================================* + * Types + *============================================================================*/ +typedef union _BTAON_FAST_REBOOT_SW_INFO0_TYPE +{ + uint16_t d16; + struct + { + uint16_t rsvd0: 5; + uint16_t is_ota: 1; /* bit[5]: enter ota mode after reset */ + uint16_t rsvd1: 10; + } flag; +} BTAON_FAST_REBOOT_SW_INFO0_TYPE; + +/*============================================================================* + * Variables + *============================================================================*/ +uint8_t g_flash_old_bp_lv = 0xff; +/*============================================================================* + * Local Functions + *============================================================================*/ +#if (SUPPORT_PUBLIC_DECODE_OTA == 1) +static bool dfu_check_compressed_image_crc(T_IMG_CTRL_HEADER_FORMAT *p_header) +{ + /* + Image layout is as below, and CRC will include part 2) + 1) Image Compress Header 96 bytes + 2) compressed app + header bytes - CRC + */ + + uint8_t buf[CRC_BUFFER_SIZE]; + uint16_t calced_crc16; + + uint32_t length = p_header->payload_len; + uint8_t *pdata = (uint8_t *) p_header + sizeof(T_COMPRESS_IMG_HEADER_FORMAT); + calced_crc16 = dfu_process_crc(BTXFCS_INIT, buf, CRC_BUFFER_SIZE, pdata, length); + + return (p_header->crc16 == calced_crc16); +} + +static bool dfu_check_compressed_image_sha256(T_IMG_CTRL_HEADER_FORMAT *p_header) +{ + /* + Image layout is as below, and CRC will include part 2) + 1) Image Compress Header 96 bytes + 2) compressed app + header bytes -sha256 + */ + + SHA256_CTX ctx; + uint8_t buf[SHA256_BUFFER_SIZE]; + uint8_t sha256sum[SHA256_LENGTH]; + uint8_t sha256img[SHA256_LENGTH]; + + SHA256_Init(&ctx); + + uint8_t *pdata = (uint8_t *)p_header + sizeof(T_COMPRESS_IMG_HEADER_FORMAT); + dfu_process_sha256(&ctx, buf, SHA256_BUFFER_SIZE, pdata, p_header->payload_len); + + SHA256_Final(&ctx, sha256sum); + + pdata = (uint8_t *)p_header + COMPRESS_HEADER_SHA256_OFFSET; + for (int i = 0; i < SHA256_LENGTH; i++) + { + sha256img[i] = *(pdata++); + } + + return (memcmp(sha256img, sha256sum, SHA256_LENGTH) == 0); +} + +/** + * @brief calculated checksum(CRC16 or SHA256 determined by image) over the image, and compared + * with given checksum value. + * @param p_header image header info of the given image. + * @return true if image integrity check pass via checksum compare, false otherwise. +*/ +static bool check_compressed_image_chksum(T_IMG_CTRL_HEADER_FORMAT *p_header) +{ + bool ret; + + if (p_header->crc16) + { + ret = dfu_check_compressed_image_crc(p_header); + } + else + { + ret = dfu_check_compressed_image_sha256(p_header); + } + + return ret; +} + +#endif +/** + * @brief erase a sector of the flash. + * @param addr flash addr in sector to be erase. + * @return 0 if erase successfully, fail otherwise +*/ +static bool flash_erase_sector(uint32_t addr) +{ + bool result = false; + result = flash_erase_locked(FLASH_ERASE_SECTOR, addr); + DFU_PRINT_INFO2("<==dfu flash erase sector: addr=%x, result=%d(1:success)", addr, result); + return result; +} + +/** +* @brief check flash area is blank +* @param image_id image_id to identify FW. +* @param offset offset of the image. +* @param size size to check. +* @return 0 if blank check successfully, error line number otherwise +*/ +static uint32_t dfu_flash_check_blank(uint16_t image_id, uint32_t offset, uint16_t size) +{ + uint32_t i = 0; + uint32_t result = 0; + uint32_t start_addr = 0; + + if (size & 0x3) + { + result = __LINE__; + goto L_Return; + } + + if ((image_id != IMAGE_USER_DATA) && + (image_id < OTA || image_id >= IMAGE_MAX)) + { + result = __LINE__; + goto L_Return; + } + + if (image_id == IMAGE_USER_DATA) + { + start_addr = flash_get_bank_addr(FLASH_BKP_DATA1) + offset; + } + else + { + start_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id) + offset; + } + + if (start_addr == 0) + { + result = __LINE__; + goto L_Return; + } + + for (i = 0; i < size / 4; i++) + { + uint32_t r_data; + if (flash_auto_read_locked(start_addr, &r_data)) + { + if (r_data != FMC_ERASE_PATTERN) + { + result = __LINE__; + goto L_Return; + } + start_addr += 4; + } + else + { + result = __LINE__; + goto L_Return; + } + } + +L_Return: + DFU_PRINT_INFO4("<==dfu_flash_check_blank: image_id=0x%x, size=%d, addr=%d, result=%d", + image_id, size, start_addr, result); + return result; +} + +/** + * @brief set specified image valid bit.. + * @param p_header specified image. + * @return true if ready bit sets to 0, false otherwise +*/ +void dfu_set_compressed_ready(T_IMG_CTRL_HEADER_FORMAT *p_header) +{ + /* clear not_ready and compressed_not_ready bit */ + uint32_t data; + /*support for 4bit mode silent ota*/ + flash_auto_read_locked((uint32_t)p_header, &data); + data &= ~BIT26; + flash_auto_write_locked((uint32_t)p_header, data); +} + +extern void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header); + +//void dfu_set_ready(T_IMG_CTRL_HEADER_FORMAT *p_header) +//{ +// /* clear not_ready bit */ +// uint32_t data; +// /*support for 4bit mode silent ota*/ +// flash_auto_read_locked((uint32_t)p_header, &data); +// data &= ~BIT23; +// flash_auto_write_locked((uint32_t)p_header, data); +//} + +/** +* @brief check ota image size whether exceed flash layout address. +*/ +static bool check_dfu_update_image_length(uint16_t image_id, uint32_t offset, uint32_t length, + void *p_void, uint32_t *ret) +{ + uint32_t temp_bank_size = 0; + *ret = 0; + + if (p_void == NULL) + { + *ret = DFU_UPDATE_ERROR_EMPTY_BUFFER; + return false; + } + + if (IMAGE_USER_DATA == image_id) + { + temp_bank_size = flash_get_bank_size(FLASH_BKP_DATA1); + } + else + { + temp_bank_size = get_temp_ota_bank_size_by_img_id((T_IMG_ID)image_id); + } + + + if (offset == 0) + { + T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_void; + uint32_t total_length = p_header->payload_len + IMG_HEADER_SIZE; + + if (total_length > temp_bank_size) + { + DBG_DIRECT("New Image too large! total_length=%d, temp_bank_size=%d", total_length, + temp_bank_size); + *ret = DFU_UPDATE_ERROR_IMAGE_SIZE_TOO_LARGE; + return false; + } + } + + if (offset + length > temp_bank_size) + { + DFU_PRINT_ERROR3("New Image single packet too large! offset=%d, length=%d, temp_bank_size=%d", + offset, length, temp_bank_size); + *ret = DFU_UPDATE_ERROR_PACKET_SIZE_TOO_LARGE; + return false; + } + + //check pass + return true; +} + +static uint32_t dfu_write(uint32_t start_addr, uint32_t length, uint8_t *p_void) +{ + uint32_t result = 0; + uint16_t loop_cnt = 0; + uint16_t remain_size = 0; + uint32_t counter = 0; + uint8_t s_val[DFU_UPDATE_LEN]; + + loop_cnt = length / DFU_UPDATE_LEN; + remain_size = length % DFU_UPDATE_LEN; + DFU_PRINT_INFO2("dfu_write: start_addr=0x%x, length=%d", + start_addr, length); + +#if 0 //auto mode access + for (int i = 0; i < length; i = i + 4) + { + uint32_t s_val = 0; + flash_auto_write_locked(start_addr + i, *(uint32_t *)p_void); + flash_auto_read_locked(start_addr + i | FLASH_OFFSET_TO_NO_CACHE, &s_val); + if (s_val != *(uint32_t *)p_void) + { + DFU_PRINT_ERROR3("<==dfu_update: ERROR! w_data=0x%x, r_data=0x%x, addr=0x%x", + *(uint32_t *)p_void, s_val, start_addr + i); + result = __LINE__; //write fail + goto L_Return; + } + else + { + p_void++; + } + } +#endif + + for (int i = 0; i < loop_cnt; i++) + { + if (flash_write_locked(start_addr + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN, + p_void + i * DFU_UPDATE_LEN)) + { + + if (flash_split_read_locked(start_addr + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN, + s_val, &counter)) + { + if (0 != memcmp(s_val, p_void + i * DFU_UPDATE_LEN, DFU_UPDATE_LEN)) + { + return DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH; + } + } + else + { + return DFU_UPDATE_ERROR_FLASH_READBACK_FAIL; + } + } + else + { + return DFU_UPDATE_ERROR_FLASH_WRITE_FAIL; + } + } + + if (remain_size) + { + if (flash_write_locked(start_addr + loop_cnt * DFU_UPDATE_LEN, remain_size, + p_void + loop_cnt * DFU_UPDATE_LEN)) + { + if (flash_split_read_locked(start_addr + loop_cnt * DFU_UPDATE_LEN, + remain_size, s_val, &counter)) + { + //ensure p_void is ram addr + if (0 != memcmp(s_val, p_void + loop_cnt * DFU_UPDATE_LEN, remain_size)) + { + return DFU_UPDATE_ERROR_FLASH_READBACK_MISMATCH; + } + } + else + { + return DFU_UPDATE_ERROR_FLASH_READBACK_FAIL; + } + } + else + { + return DFU_UPDATE_ERROR_FLASH_WRITE_FAIL; + } + } + + return result; +} + +/*============================================================================* + * External Functions + *============================================================================*/ +/** + * @brief check whether in OTA mode. +*/ +//bool dfu_check_ota_mode_flag(void) +//{ +// BTAON_FAST_REBOOT_SW_INFO0_TYPE nFastBoot = +// (BTAON_FAST_REBOOT_SW_INFO0_TYPE)btaon_fast_read_safe(BTAON_FAST_REBOOT_SW_INFO0); +// DFU_PRINT_INFO1("dfu_check_ota_mode_flag: ota(%d)", nFastBoot.flag.is_ota); + +// return nFastBoot.flag.is_ota ? true : false; +//} + +/** + * @brief set aon reg value means whether in OTA mode or not. +*/ +void dfu_set_ota_mode_flag(bool enable) +{ + BTAON_FAST_REBOOT_SW_INFO0_TYPE nFastBoot = + (BTAON_FAST_REBOOT_SW_INFO0_TYPE)btaon_fast_read_safe(BTAON_FAST_REBOOT_SW_INFO0); + if (enable) + { + nFastBoot.flag.is_ota = 1; + } + else + { + nFastBoot.flag.is_ota = 0; + } + btaon_fast_write_safe(BTAON_FAST_REBOOT_SW_INFO0, nFastBoot.d16); + DFU_PRINT_INFO1("dfu_set_ota_mode_flag ota(%d)", nFastBoot.flag.is_ota); +} + +/** + * @brief switch to the OTA mode, if support normal ota app need call it. +*/ +void dfu_switch_to_ota_mode(void) +{ + DFU_PRINT_INFO0("[==>dfu_switch_to_ota_mode"); + dfu_set_ota_mode_flag(true); + WDG_SystemReset(RESET_ALL_EXCEPT_AON, DFU_SWITCH_TO_OTA_MODE); +} + +/** + * @brief OTA procedure do wdg system reset. + * @param is_active_fw true means dfu success! otherwise fail. +*/ +void dfu_fw_reboot(bool is_active_fw) +{ + DFU_PRINT_TRACE1("==>dfu_fw_reboot: is_active_fw=%d", is_active_fw); + if (is_active_fw) + { + WDG_SystemReset(RESET_ALL, DFU_ACTIVE_RESET); + } + else + { + WDG_SystemReset(RESET_ALL, DFU_FAIL_RESET); + } +} + +/** + * @brief OTA image default ecb mode aes decrypt, last less then 16bytes no encrypted. +*/ +void dfu_hw_aes_decrypt_image(uint8_t *input, uint8_t *output, uint32_t length) +{ + uint32_t offset = 0; + hw_aes_init(OTP->aes_key, NULL, AES_MODE_ECB, OTP->ota_with_encryption_use_aes256); + do + { + if ((length - offset) >= 16) + { + hw_aes_decrypt_16byte(input + offset, output + offset); + offset += 16; + } + else + { + break; + } + } + while (1); +} + +/** + * @brief report specified target ic type. + * @param image_id image_id to identify FW. + * @param p_ic_type To store ic type. + * @return 0 if report ic type info successfully, error line number otherwise +*/ +uint32_t dfu_report_target_ic_type(uint16_t image_id, uint8_t *p_ic_type) +{ + uint32_t result = 0; + T_IMG_CTRL_HEADER_FORMAT *p_header; + + if (!p_ic_type) + { + result = __LINE__; + goto L_Return; + } + + if (IMAGE_USER_DATA == image_id) + { + p_header = (T_IMG_CTRL_HEADER_FORMAT *)flash_get_bank_addr(FLASH_BKP_DATA1); + } + else + { + p_header = (T_IMG_CTRL_HEADER_FORMAT *)get_header_addr_by_img_id((T_IMG_ID)image_id); + } + + if (!p_header) + { + result = __LINE__; + goto L_Return; + } + + *p_ic_type = p_header->ic_type; + +L_Return: + DFU_PRINT_INFO1("<==dfu_report_target_ic_type: result=%d", result); + return result; +} + +/** + * @brief report specified FW info and current OTA offset. + * @param image_id image_id to identify FW. + * @param p_origin_fw_version To store current FW version. + * @param p_offset To store current file offset. + * @return 0 if report FW info successfully, error line number otherwise +*/ +uint32_t dfu_report_target_fw_info(uint16_t image_id, uint32_t *p_origin_fw_version, + uint32_t *p_offset) +{ + uint32_t result = 0; + T_IMG_HEADER_FORMAT *p_header; + + if (!p_offset) + { + result = __LINE__; + goto L_Return; + } + + if (!p_origin_fw_version) + { + result = __LINE__; + goto L_Return; + } + + if (IMAGE_USER_DATA == image_id) + { + p_header = (T_IMG_HEADER_FORMAT *)flash_get_bank_addr(FLASH_BKP_DATA1); + } + else + { + p_header = (T_IMG_HEADER_FORMAT *)get_header_addr_by_img_id((T_IMG_ID)image_id); + } + if (!p_header) + { + result = __LINE__; + goto L_Return; + } + + if (image_id == OTA) + { + T_OTA_HEADER_FORMAT *p_ota_header; + p_ota_header = (T_OTA_HEADER_FORMAT *)p_header; + *p_origin_fw_version = p_ota_header->ver_val; + } + else if ((IMAGE_USER_DATA == image_id) || + (image_id >= SecureBoot && image_id < IMAGE_MAX)) + { + *p_origin_fw_version = p_header->git_ver.ver_info.version; + } + else//image_id don't support + { + result = __LINE__; + goto L_Return; + } + + /*bee2 default don't support re-ota*/ + *p_offset = 0; + +L_Return: + DFU_PRINT_INFO1("<==dfu_report_target_fw_info: result=%d", result); + return result; +} + + + +/** +* @brief calculate checksum of lenth of buffer in flash. +* @param buf data. +* @param length length of data, must align 2bytes. +* @param crc_val ret crc value point. +* @return 0 if buffer checksum calcs successfully, error line number otherwise +*/ + +uint32_t dfu_check_buf_crc(uint8_t *buf, uint32_t length, uint16_t crc_val) +{ + uint16_t checksum16 = 0; + uint32_t result = 0; + uint32_t i; + uint16_t *p16; + + if (length & 0x1) + { + result = __LINE__; + goto L_Return; + } + + p16 = (uint16_t *)buf; + for (i = 0; i < length / 2; ++i) + { + checksum16 = checksum16 ^ (*p16); + ++p16; + } + + checksum16 = ((checksum16 & 0xff) << 8) | ((checksum16 & 0xff00) >> 8); + + if (checksum16 != crc_val) + { + result = __LINE__; + goto L_Return; + } + +L_Return: + DFU_PRINT_INFO4("<==dfu_check_buf_crc: length=%d, checksum16=0x%x, crc_val=0x%x, result:%d", + length, checksum16, crc_val, result); + return result; +} + +/** +* @brief: unlock flash is need when erase or write flash. +*/ +bool unlock_flash_bp_all(void) +{ + DFU_PRINT_TRACE0("**********Flash unlock BP***********"); + if (flash_sw_protect_unlock_by_addr_locked(0x00800000, &g_flash_old_bp_lv)) + { + DFU_PRINT_TRACE1("<==Unlock Total Flash Success! prev_bp_lv=%d", g_flash_old_bp_lv); + return true; + } + return false; +} + +/** +* @brief: lock flash after erase or write flash. +*/ +void lock_flash_bp(void) +{ + if (g_flash_old_bp_lv != 0xff) + { + flash_set_block_protect_locked(g_flash_old_bp_lv); + } +} + +/** + * @brief erase a sector of the flash, will retry three times at most + * + * @param image_id image_id to identify FW. + * @param offset offset of the image. + * @return 0 if erase successfully, error line number otherwise, +*/ +uint32_t dfu_flash_erase_sector_with_retry(uint16_t image_id, uint32_t offset) +{ + uint32_t result = 0; + uint32_t cnt = 0; + uint32_t dfu_base_addr = 0; + bool erase_rst = true; //default value must be true + + if (image_id == IMAGE_USER_DATA) + { + dfu_base_addr = flash_get_bank_addr(FLASH_BKP_DATA1);; + } + else + { + dfu_base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id); + } + if (dfu_base_addr == 0) + { + result = __LINE__; + goto L_Return; + } + + do + { + unlock_flash_bp_all(); + erase_rst = flash_erase_sector(dfu_base_addr + offset); + if (!erase_rst) + { + //erase fail + result = __LINE__; + goto L_Return; + } + lock_flash_bp(); + result = dfu_flash_check_blank(image_id, offset, FMC_SEC_SECTION_LEN); + + if (!result) + { + //erase ok + break; + } + else + { + //retry + cnt++; + } + if (cnt >= 3) + { + /*retry three times all fail*/ + goto L_Return; + } + } + while (1); + +L_Return: + DFU_PRINT_INFO2("dfu_flash_erase_with_retry: cnt=%d, result=%d", + cnt, result); + return result; +} + + +/** + * @brief write specified image data with specified length to flash + * @param image_id image_id to identify FW. + * @param offset offset of the image. + * @param length length of data. + * @param p_void pointer to data. + * @return 0 if write FW image successfully, error line number otherwise +*/ +uint32_t dfu_update(uint16_t image_id, uint32_t offset, uint32_t length, + uint32_t *p_void, bool is_new_image) +{ + uint32_t result = 0; + uint32_t dfu_base_addr = 0; + uint32_t start_addr = 0; + bool erase_rst = true; //default value must be true + + DFU_PRINT_INFO2("==>dfu_update: offset=0x%x, length=%d", offset, length); + + if (length % 4) + { + result = DFU_UPDATE_ERROR_LEN_NOT_ALIGN; + goto L_Return; + } + + if (p_void == 0) + { + result = DFU_UPDATE_ERROR_EMPTY_BUFFER; + goto L_Return; + } + + if (IMAGE_USER_DATA != image_id) + { + /*get back up area address*/ + dfu_base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id); + } + else + { + /*get back up area address*/ + dfu_base_addr = flash_get_bank_addr(FLASH_BKP_DATA1); + } + + if (dfu_base_addr == 0) + { + result = DFU_UPDATE_ERROR_BASE_ADDR_INVALID; + goto L_Return; + } + + /* before erase temp image or write image to flash temp, check access length depend flash layout */ + if (!check_dfu_update_image_length(image_id, offset, length, p_void, &result)) + { + goto L_Return; + } + + /*if it's start_packet*/ +// if (offset == 0) + if (is_new_image) + { + T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_void; + /*access ram addr, make sure image is not ready*/ + p_header->ctrl_flag.flag_value.not_ready = 0x1; +#if (SUPPORT_PUBLIC_DECODE_OTA == 1) + if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type) + { + /*access ram addr, make sure image is not ready*/ + p_header->ctrl_flag.flag_value.compressed_not_ready = 0x1; + } + +#endif + + DFU_PRINT_TRACE3("<==dfu_update: New Image Header=0x%x, image_id=0x%x, dfu_base_addr=0x%x", + length, image_id, dfu_base_addr); + } + + start_addr = dfu_base_addr + offset; + + unlock_flash_bp_all(); + + if (0 == (offset & (FMC_SEC_SECTION_LEN - 1))) //new sector starts + { + erase_rst = flash_erase_sector(start_addr); + } + else // only cross two sector + { + /*write space cross two sector. Note: dfu_base_addr have been 4K align*/ + /*if buffer size more than 4K, may cross more than two sectors*/ + if (((offset % FMC_SEC_SECTION_LEN) + length > FMC_SEC_SECTION_LEN) + && (length <= FMC_SEC_SECTION_LEN)) + { + erase_rst = flash_erase_sector((start_addr + length) & ~(FMC_SEC_SECTION_LEN - 1)); + } + } + + if (!erase_rst) + { + //erase fail + result = DFU_UPDATE_ERROR_FLASH_ERASE_FAIL; + goto L_Return; + } + + //write data to flash + result = dfu_write(start_addr, length, (uint8_t *)p_void); + lock_flash_bp(); + +L_Return: + DFU_PRINT_INFO1("<==dfu_update: result=%d", result); + return result; +} + + +/** + * @brief calculate checksum of the image and compare with given checksum value. + * + * @param image_id image id to identify image. + * @return true if the image integrity check passes, false otherwise +*/ +bool dfu_check_checksum(uint16_t image_id, uint32_t offset) +{ + uint32_t error_code = DFU_CHECKSUM_SUCCESS; + bool check_result = false; + uint32_t base_addr = 0; + T_IMG_CTRL_HEADER_FORMAT *p_header; + + if (image_id == IMAGE_USER_DATA) + { + /* because flash_get_bank_addr(FLASH_BKP_DATA1) is not located flash block protect range, needn't unlock bp */ + base_addr = flash_get_bank_addr(FLASH_BKP_DATA1) | FLASH_OFFSET_TO_NO_CACHE; + } + else + { + /* check OTA temp or running bank to see if received image is OK.*/ + base_addr = get_temp_ota_bank_addr_by_img_id((T_IMG_ID)image_id); + } + if (base_addr == 0) + { + error_code = DFU_CHECKSUM_ERROR_BASE_ADDR_INVALID; + goto L_Return; + } + + if (!is_ota_support_bank_switch()) + { + base_addr += offset; + } + + p_header = (T_IMG_CTRL_HEADER_FORMAT *)base_addr; +#if (SUPPORT_PUBLIC_DECODE_OTA == 1) + if (IMAGE_NORMAL == p_header->ctrl_flag.flag_value.image_type) + { + check_result = check_image_chksum(p_header); + + } + else if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type) + { + check_result = check_compressed_image_chksum(p_header); + } + else + { + error_code = DFU_CHECKSUM_ERROR_IMAGE_TYPE_INVALID; + goto L_Return; + } +#else + check_result = check_image_chksum(p_header); +#endif + + if (!check_result) + { + error_code = DFU_CHECKSUM_ERROR_CHECK_FAIL; + goto L_Return; + } + + /*when disable bank switch, set image ready later*/ + if (is_ota_support_bank_switch()) + { + dfu_set_image_ready(p_header); + } + +L_Return: + DFU_PRINT_INFO3("<==dfu_check_checksum: check_result:%d, ota_tmp_addr:0x%x, error_code:%d", + check_result, base_addr, error_code); + return check_result; +} + +void dfu_set_image_ready(T_IMG_CTRL_HEADER_FORMAT *p_header) +{ + unlock_flash_bp_all(); +#if (SUPPORT_PUBLIC_DECODE_OTA == 1) + /*only set compressed_not_reay to 0, and not_ready still is 1 + so that bootlader won't copy compressed image*/ + if (IMAGE_COMPRESSED == p_header->ctrl_flag.flag_value.image_type) + { + dfu_set_compressed_ready(p_header); + } + else if (IMAGE_NORMAL == p_header->ctrl_flag.flag_value.image_type) + { + dfu_set_ready(p_header); + } + else + { + return; + } +#else + dfu_set_ready(p_header); +#endif + lock_flash_bp(); +} + + +#if (ENABLE_BANK_SWITCH_COPY_APP_DATA == 1) +extern uint8_t *p_ota_temp_buffer_head; +/** + * @brief copy appdata from active bank to updating bank. + * + * @param image_id image_id to identify image. + * @param dlAddress address the img copy to. + * @param dlSize copy size. + * @return true if the image copied success, false otherwise +*/ +bool dfu_copy_img(uint16_t image_id, uint32_t dlAddress, uint32_t dlSize) +{ + uint32_t error_code = 0; + uint32_t source_base_addr; + uint32_t dest_base_addr; + int remain_size = dlSize; + uint32_t s_val; + uint32_t dlOffset, tmp_offset; + + if ((image_id < AppData1) || (image_id > AppData6)) + { + error_code = __LINE__; + goto L_Return; + } + if (dlAddress % 4096) + { + error_code = __LINE__; + goto L_Return; + } + + source_base_addr = get_active_ota_bank_addr() & 0xffffff; + + if (flash_get_bank_addr(FLASH_OTA_BANK_0) == get_active_ota_bank_addr()) + { + dest_base_addr = flash_get_bank_addr(FLASH_OTA_BANK_1) & 0xffffff; + } + else + { + dest_base_addr = flash_get_bank_addr(FLASH_OTA_BANK_0) & 0xffffff; + } + if ((source_base_addr % 4096) || (dest_base_addr % 4096)) + { + error_code = __LINE__; + goto L_Return; + } + if (dest_base_addr >= dlAddress) + { + error_code = __LINE__; + goto L_Return; + } + dlOffset = dlAddress - dest_base_addr; + tmp_offset = dlOffset; + if (dlOffset % 4096) + { + error_code = __LINE__; + goto L_Return; + } + T_IMG_HEADER_FORMAT *p_data_header; + p_data_header = (T_IMG_HEADER_FORMAT *)(source_base_addr + dlOffset); + if (p_data_header->ctrl_header.image_id != image_id) + { + error_code = __LINE__; + goto L_Return; + } + + while (remain_size > 0) + { + if (!((dest_base_addr + tmp_offset) % 4096)) //must 4k align + { + flash_erase_sector(dest_base_addr + tmp_offset); + } + if (remain_size > 2048) + { + memcpy(p_ota_temp_buffer_head, (uint8_t *)(source_base_addr + tmp_offset), 2048); + if (remain_size == dlSize) + { + T_IMG_CTRL_HEADER_FORMAT *p_header = (T_IMG_CTRL_HEADER_FORMAT *) p_ota_temp_buffer_head; + p_header->ctrl_flag.flag_value.not_ready = 0x1; /*make sure image is not ready, will use it later*/ + } + for (int i = 0; i < 2048; i = i + 4) + { + flash_auto_write_locked(dest_base_addr + tmp_offset + i, *(uint32_t *)p_ota_temp_buffer_head); + + flash_auto_read_locked(dest_base_addr + tmp_offset + i | FLASH_OFFSET_TO_NO_CACHE, &s_val); + if (s_val != *(uint32_t *)p_ota_temp_buffer_head) + { + DFU_PRINT_TRACE3("s_val:0x%08x, *p_void:0x%08x, i:0x%08x", + s_val, *(uint32_t *)p_ota_temp_buffer_head, i); + error_code = __LINE__; + goto L_Return; + } + else + { + p_ota_temp_buffer_head += 4; + } + } + + + remain_size -= 2048; + } + else + { + memcpy(p_ota_temp_buffer_head, (uint8_t *)(source_base_addr + tmp_offset), remain_size); + for (int i = 0; i < remain_size; i = i + 4) + { + flash_auto_write_locked(dest_base_addr + tmp_offset + i, *(uint32_t *)p_ota_temp_buffer_head); + + flash_auto_read_locked(dest_base_addr + tmp_offset + i | FLASH_OFFSET_TO_NO_CACHE, &s_val); + if (s_val != *(uint32_t *)p_ota_temp_buffer_head) + { + DFU_PRINT_TRACE3("s_val:0x%08x, *p_void:0x%08x, i:0x%08x", + s_val, *(uint32_t *)p_ota_temp_buffer_head, i); + error_code = __LINE__; + goto L_Return; + } + else + { + p_ota_temp_buffer_head += 4; + } + } + remain_size = 0; + } + tmp_offset += 2048; + } + +L_Return: + DFU_PRINT_INFO1("<====dfu_copy_img error_code:%d", error_code); + if (error_code) + { + return false; + } + return true; +} +#endif //end ENABLE_BANK_SWITCH_COPY_APP_DATA + + + + + + + diff --git a/src/platform/psram_platform.c b/src/platform/psram_platform.c new file mode 100644 index 0000000..d139e02 --- /dev/null +++ b/src/platform/psram_platform.c @@ -0,0 +1,513 @@ +#include +#include "psram_platform.h" +#include "rtl876x.h" +#include "rtl876x_rcc.h" +#include "rtl876x_pinmux.h" +#include "flash_device.h" +#include "trace.h" + +#define SPIC_FIFO_SIZE 256 +#define PSRAM_MAGIC_PATTERN 0x5A5A12A5 +#define PSRAM_CAL_ADDR 0x6802030 //0x7002030 +#define DELAY_CNT_MAX 32 +#define FMC_MAIN1 0x6800000 + +/** @defgroup FLASH_DRIVER_Registers_Definitions Flash Driver Registers Definitions + * @brief + * @{ + */ +/***************************************************************************************** +* Registers Definitions --------------------------------------------------------* +******************** Bits definition for SPIC_CTRLR0 register *******************/ +#define BIT_CK_MTIMES(x) (((x) & 0x0000001F) << 23) +#define BIT_FAST_RD(x) (((x) & 0x00000001) << 22) +#define BIT_CMD_CH(x) (((x) & 0x00000003) << 20) +#define BIT_DATA_CH(x) (((x) & 0x00000003) << 18) +#define BIT_ADDR_CH(x) (((x) & 0x00000003) << 16) +#define BIT_TMOD(x) (((x) & 0x00000003) << 8) +#define BIT_SCPOL (0x00000001 << 7) +#define BIT_SCPH (0x00000001 << 6) + +/******************** Bits definition for SPIC_CTRLR1 register *******************/ +#define BIT_NDF(x) ((x) & 0xfffff) + +/******************** Bits definition for SPIC_SSIENR register *******************/ +#define BIT_ATCK_CMD (0x00000001 << 1) +#define BIT_SPIC_EN (0x00000001) + +/******************** Bits definition for SPIC_BAUDR register *******************/ +#define BIT_SCKDV(x) ((x) & 0x0fff) + +/******************** Bits definition for SPIC_SR register *******************/ +#define BIT_TXE (0x00000001 << 5) +#define BIT_RFF (0x00000001 << 4) +#define BIT_RFNE (0x00000001 << 3) +#define BIT_TFE (0x00000001 << 2) +#define BIT_TFNF (0x00000001 << 1) +#define BIT_BUSY (0x00000001) + +/******************** Bits definition for SPIC_IMR register *******************/ +#define BIT_ACSIM (0x00000001 << 11) +#define BIT_RXSIM (0x00000001 << 10) +#define BIT_TXSIM (0x00000001 << 9) +#define BIT_ACEIM (0x00000001 << 8) +#define BIT_BYEIM (0x00000001 << 7) +#define BIT_WBEIM (0x00000001 << 6) +#define BIT_FSEIM (0x00000001 << 5) +#define BIT_RXFIM (0x00000001 << 4) +#define BIT_RXOIM (0x00000001 << 3) +#define BIT_RXUIM (0x00000001 << 2) +#define BIT_TXOIM (0x00000001 << 1) +#define BIT_TXEIM (0x00000001) + +/******************** Bits definition for SPIC_ISR register *******************/ +#define BIT_ACSIS (0x00000001 << 11) +#define BIT_RXSIS (0x00000001 << 10) +#define BIT_TXSIS (0x00000001 << 9) +#define BIT_ACEIS (0x00000001 << 8) +#define BIT_BYEIS (0x00000001 << 7) +#define BIT_WBEIS (0x00000001 << 6) +#define BIT_FSEIS (0x00000001 << 5) +#define BIT_RXFIS (0x00000001 << 4) +#define BIT_RXOIS (0x00000001 << 3) +#define BIT_RXUIS (0x00000001 << 2) +#define BIT_TXOIS (0x00000001 << 1) +#define BIT_TXEIS (0x00000001) + +/******************** Bits definition for SPIC_RISR register *******************/ +#define BIT_ACEIR (0x00000001 << 8) +#define BIT_BYEIR (0x00000001 << 7) +#define BIT_WBEIR (0x00000001 << 6) +#define BIT_FSEIR (0x00000001 << 5) +#define BIT_RXFIR (0x00000001 << 4) +#define BIT_RXOIR (0x00000001 << 3) +#define BIT_RXUIR (0x00000001 << 2) +#define BIT_TXOIR (0x00000001 << 1) +#define BIT_TXEIR (0x00000001) + +/******************** Bits definition for SPIC_CTRLR2 register *******************/ +#define BIT_RX_FIFO_ENTRY(x) (((x) & 0x0000000f) << 8) +#define BIT_FIFO_ENTRY(x) (((x) & 0x0000000f) << 4) +#define BIT_SEQ_EN (0x00000001 << 3) +/* Indicate the WPn input pin of SPI Flash is connected to: + 0(default): WP=spi_sout[2], 1:WP=spi_sout[3]. */ +#define BIT_WPN_DNUM (0x00000001 << 2) +/*write protect function.*/ +#define BIT_WPN_SET (0x00000001 << 1) +/* SO pin of SPI Flash.0: SO connects to spi_sout[0]. 1(default): SO connects to spi_sout[1].*/ +#define BIT_SO_DUM (0x00000001) + +/******************** Bits definition for SPIC_ADDR_LENGTH register *******************/ +#define BIT_ADDR_PHASE_LENGTH(x) ((x) & 0x00000003) + +/******************** Bits definition for SPIC_AUTO_LENGTH register *******************/ +#define BIT_CS_H_WR_DUM_LEN(x) (((x) & 0x0000000f) << 28) +#define BIT_CS_H_RD_DUM_LEN(x) (((x) & 0x00000003) << 26) +#define BIT_AUTO_DUM_LEN(x) (((x) & 0x000000ff) << 18) +#define BIT_AUTO_ADDR_LENGTH(x) (((x) & 0x00000003) << 16) +#define BIT_IN_PHYSICAL_CYC(x) (((x) & 0x0000000f) << 12) +#define BIT_RD_DUMMY_LENGTH(x) (((x) & 0x00000fff)) + +/******************** Bits definition for SPIC_VALID_CMD register *******************/ +#define BIT_SEQ_TRANS_EN (0x00000001 << 14) +#define BIT_CTRLR0_CH (0x00000001 << 12) +#define BIT_PRM_EN (0x00000001 << 11) +#define BIT_WR_AUTOCHECKSTATUS (0x00000001 << 10) +#define BIT_WR_BLOCKING (0x00000001 << 9) +#define BIT_WR_QUAD_II (0x00000001 << 8) +#define BIT_WR_QUAD_I (0x00000001 << 7) +#define BIT_WR_DUAL_II (0x00000001 << 6) +#define BIT_WR_DUAL_I (0x00000001 << 5) +#define BIT_RD_QUAD_IO (0x00000001 << 4) +#define BIT_RD_QUAD_O (0x00000001 << 3) +#define BIT_RD_DUAL_IO (0x00000001 << 2) +#define BIT_RD_DUAL_I (0x00000001 << 1) +#define BIT_FRD_SINGEL (0x00000001) + + +/** End of FLASH_DRIVER_Registers_Definitions + * @} + */ + +typedef enum +{ + CHANN_SINGLE = 0, + CHANN_DUAL = 1, + CHANN_QUAD = 2 +} T_CHANN_TYPE; + +typedef enum +{ + READ_CMD = 0x03, + FAST_READ_QUAD_CMD = 0xEB, + WRITE_CMD = 0x02, + QUAD_WRITE_CMD = 0x38, + RDID_CMD = 0x9F, + RESET_EN_CMD = 0x66, + RESET_CMD = 0x99, +} PSRAM_CMD; + +/** + * @brief PSRAM Init structure definition + */ +typedef struct +{ + uint8_t curr_rd_cmd; /* current used read cmd */ + uint8_t curr_wr_cmd; /* current used write cmd */ + uint8_t rd_data_ch; /* read data channel */ + uint8_t rd_addr_ch; /* read address channel */ + uint8_t rd_st_dummy_cycle; /* read status dummy cycle */ + uint8_t bit_mode; +} T_PSRAM_DEVICE_INFO; + +T_PSRAM_DEVICE_INFO psram_device_info = +{ + .curr_rd_cmd = READ_CMD, + .curr_wr_cmd = WRITE_CMD, + .rd_data_ch = CHANN_SINGLE, + .rd_addr_ch = CHANN_SINGLE, +}; + +extern void spic_enable(SPIC_TypeDef *spic, uint32_t enable); +extern void spic_set_rd_dummy_length(SPIC_TypeDef *spic, uint8_t dummy_len); + +SPIC_TypeDef *spic = NULL; + +static uint16_t g_def_dummy_len[3] = {0x0, 0x8, 0xC};/* default dummy length base for each bit mode */ + +static uint32_t convert_psram_addr_to_offset(uint32_t addr) +{ + return (addr - FMC_MAIN1); +} + +/** + * @brief set spic enable or disable. + * + * @param enable DISABLE to disable cache, ENABLE to enable cache. + * @return + * @note: spic should be disabled before programming any register in user mode +*/ +void spic_enable(SPIC_TypeDef *spic, uint32_t enable) +{ + spic->ssienr = enable; +} + +/** + * @brief set dummy_cycle in autolen register[11:0]. + * + * @return +*/ + +static void spic_set_rd_dummy_length(SPIC_TypeDef *spic, uint8_t dummy_len) +{ + uint32_t data = BIT_RD_DUMMY_LENGTH(dummy_len); + HAL_UPDATE32(&spic->auto_length, 0xfff, data); +} + +void psram_init(void) +{ + RCC_PeriphClockCmd(APBPeriph_FLASH1, APBPeriph_FLASH1_CLOCK, (FunctionalState)ENABLE); + + Pinmux_Config(P1_7, IDLE_MODE); + Pinmux_Config(P3_6, IDLE_MODE); + Pinmux_Config(P3_2, IDLE_MODE); + Pinmux_Config(P3_3, IDLE_MODE); + Pinmux_Config(P3_4, IDLE_MODE); + Pinmux_Config(P3_5, IDLE_MODE); + + Pad_Config(P1_7, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P3_6, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P3_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P3_3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P3_4, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P3_5, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + + /* spic1 enable controller */ + SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN1 = 1; + + /* spic1 master enable */ + SYSBLKCTRL->u_2A8.BITS_2A8.SPIC1_MASTER_EN = 1; + + /* spic1 & spic2 share clock source enable bit */ + HAL_WRITE32(PERIPH_REG_BASE, 0x2D0, HAL_READ32(PERIPH_REG_BASE, 0x2D0) | BIT5); + + /* set cs and baudrate */ + SPIC1->ssienr = 0; + SPIC1->ser = BIT0; + SPIC1->baudr = 1; + + /* ctrlr2[17:16] = 2'b11 to remove WREN+RDSR (i.e., only PP cmd issue) */ + SPIC1->ctrlr2 |= (BIT16 | BIT17); + + /* use ctrlr0 CMD_CH/DATA_CH/ADDR_CH in auto mode */ + //BIT_BAND(SPIC1->valid_cmd, 12) = 1; /* CTRLR0_CH */ + + spic = SPIC1; +} + +/* +What are the differences between 1 bit mode and 4 bit mode? +only 1 bit and 4 bit supported + +address length always 3 +1 bit: + 1-1-1 +4 bit: + 1-4-4 + + +auto mode bit num: +1 bit: + VALID_CMD: no bits or clear 4 bit bits + +4 bit: + VALID_CMD: BIT_WR_QUAD_II(WR) / RD_QUAD_IO(RD) + READ_QUAD_ADDR_DATA[0:7]: 0xEB (PRM_EN disable) + WRITE_QUAD_ADDR_DATA: 0x38 + +user mode bit num: + ctrlr0: CMD_CH, DATA_CH, ADDR_CH + +*/ +void psram_config(T_FLASH_MODE bit_mode) +{ + if (bit_mode == FLASH_MODE_1BIT) + { + spic->ssienr = 0; + spic->ctrlr0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3)); + spic->ssienr = 1; + + psram_device_info.curr_rd_cmd = READ_CMD; + psram_device_info.curr_wr_cmd = WRITE_CMD; + psram_device_info.rd_addr_ch = CHANN_SINGLE; + psram_device_info.rd_data_ch = CHANN_SINGLE; + + psram_device_info.bit_mode = bit_mode; + } + else if (bit_mode == FLASH_MODE_4BIT) + { + spic->ssienr = 0; + spic->ctrlr0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3)); + spic->ctrlr0 |= (BIT_ADDR_CH(bit_mode) | BIT_DATA_CH(bit_mode)); + spic->valid_cmd |= (BIT4 | BIT8); + spic->ssienr = 1; + + psram_device_info.curr_rd_cmd = FAST_READ_QUAD_CMD; + psram_device_info.curr_wr_cmd = QUAD_WRITE_CMD; + psram_device_info.rd_addr_ch = CHANN_QUAD; + psram_device_info.rd_data_ch = CHANN_QUAD; + + psram_device_info.bit_mode = bit_mode; + } + else + { + DBG_DIRECT("PSRAM doesn't support %d bit mode.", 1 << bit_mode); + while (1); + } +} + +void psram_seq_trans_enable(uint8_t enable) +{ + spic->ssienr = 0; + + if (enable) + { + uint8_t bit_mode = psram_device_info.bit_mode; + uint16_t rd_dummy_len = BIT_RD_DUMMY_LENGTH(spic->auto_length); + + if (rd_dummy_len >= g_def_dummy_len[bit_mode]) + { + HAL_UPDATE32(&spic->auto_length, (BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23 | BIT24 | BIT25), + BIT_AUTO_DUM_LEN((spic->baudr * 2) * (8 / (1 << bit_mode)))); + } + + BIT_BAND(spic->valid_cmd, 14) = enable; /* BIT_SEQ_TRANS_EN */ + } + else + { + HAL_UPDATE32(&spic->auto_length, (BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23 | BIT24 | BIT25), + BIT_AUTO_DUM_LEN(psram_device_info.rd_st_dummy_cycle)); + + BIT_BAND(spic->valid_cmd, 14) = enable; /* BIT_SEQ_TRANS_EN */ + } +} + +bool psram_calibration(T_FLASH_MODE bit_mode) +{ + bool ret = false; + uint16_t dly_cnt = g_def_dummy_len[bit_mode]; + + /* adjust AUTO_LENGTH[RD_DUMMY_LENGTH], make sure read data equals magic pattern. */ + for (; dly_cnt < DELAY_CNT_MAX; ++dly_cnt) + { + uint32_t rd_data; + + spic_enable(spic, DISABLE); + spic_set_rd_dummy_length(spic, dly_cnt); + spic_enable(spic, ENABLE); + + rd_data = HAL_READ32(PSRAM_CAL_ADDR, 0); + + DBG_DIRECT("cnt=%d, [%08X]=%08X", dly_cnt, PSRAM_CAL_ADDR, rd_data); + + if (rd_data == PSRAM_MAGIC_PATTERN) + { + /* update to AUTO_DUM_LEN when 1 bit mode */ + if (bit_mode == FLASH_MODE_1BIT) + { + spic_enable(spic, DISABLE); + spic->auto_length &= ~ BIT_AUTO_DUM_LEN(0xFF); + spic->auto_length |= BIT_AUTO_DUM_LEN(dly_cnt); + spic_enable(spic, ENABLE); + psram_device_info.rd_st_dummy_cycle = dly_cnt; + } + + /* update IN_PHYSICAL_CYC */ + if (dly_cnt >= g_def_dummy_len[bit_mode]) + { + spic_enable(spic, DISABLE); + spic->auto_length |= BIT_IN_PHYSICAL_CYC(dly_cnt - g_def_dummy_len[bit_mode]); + spic_enable(spic, ENABLE); + } + + /* get things done, break */ + break; + } + } + + return ret; +} + +void psram_try_high_speed(void) +{ + /* + 1 bit calibration: 1 bit and RDSR rd dummy length + use auto write to write a magic pattern before calibration + */ + uint32_t *p_magic_pattern = (uint32_t *)PSRAM_CAL_ADDR; + + *p_magic_pattern = PSRAM_MAGIC_PATTERN; + + /* start 1 bit calibration and get 1 bit rd dummy length */ + /* do calibration --> + get a rd_dummy_len_val + set AUTO_LENGTH[RD_DUMMY_LENGTH] and AUTO_LENGTH[AUTO_DUM_LEN] = rd_dummy_len_val + set AUTO_LENGTH[IN_PHYSICAL_CYC] = rd_dummy_len_val - g_def_dummy_len + */ + psram_config(FLASH_MODE_1BIT); + + psram_calibration(FLASH_MODE_1BIT); + + DBG_DIRECT("1 bit: [%08X]=%08X", p_magic_pattern, *p_magic_pattern); + + /* start 4 bit calibration and get 4 bit rd dummy length */ + /* switch to 4 bit mode */ + /* do calibration */ + psram_config(FLASH_MODE_4BIT); + + psram_calibration(FLASH_MODE_4BIT); + + DBG_DIRECT("4 bit: [%08X]=%08X", p_magic_pattern, *p_magic_pattern); +} + +bool psram_cmd_rx(uint8_t cmd, uint8_t read_len, uint8_t *read_buf) +{ + return true; +} + +bool psram_cmd_tx(uint8_t cmd, uint8_t data_len, uint8_t *data_buf) +{ + return true; +} + +bool psram_read(uint32_t addr, uint32_t len, uint8_t *data) +{ + return true; +} + +/** + * @brief program data to psram via user mode + * @param start_addr start address where is going to be written in flash + * @param data_len data length to be written + * @param data data buffer to be written + * @return + * @note 1. SPIC only supports SPIC_FIFO_SIZE FIFO, so max SPIC_FIFO_SIZE-4 word allowed to be written. + * 2. start address should be 4 byte align +*/ +static bool psram_write_internal(uint32_t start_addr, uint32_t data_len, uint8_t *data) +{ + bool retval = true; + uint8_t cmd_pp = psram_device_info.curr_wr_cmd, i; + uint32_t wr_addr; + uint32_t *data_word = (uint32_t *)data; + + /* the test show that enable spic before push fifo make transfer faster, but we can't push by + byte. if we want to push by byte, we should disable spic first. */ + spic_enable(spic, ENABLE); + wr_addr = cmd_pp | __REV(start_addr); + spic->dr[0].word = wr_addr; + + for (i = 0; i < data_len / 4; i++) + { + spic->dr[0].word = data_word[i]; + } + + while (spic->sr & BIT_BUSY); + + spic_enable(spic, DISABLE); + return retval; +} + +/** + * @brief program data to flash via user mode + * @param start_addr start address where is going to be written in flash + * @param data_len data length to be written + * @param data data buffer to be written + * @return true if success + * @note start address should be 4 byte align +*/ +bool psram_write(uint32_t addr, uint32_t len, uint8_t *data) +{ + const uint32_t blksize = SPIC_FIFO_SIZE - 4; + uint32_t tmp_addr = convert_psram_addr_to_offset(addr); + uint8_t *tmp_data = data; + int remain_size = len; + + spic_enable(spic, DISABLE); + spic->ctrlr0 &= ~(BIT_TMOD(3)); /* tx mode */ + + while (remain_size > 0) + { + uint32_t write_size = remain_size > blksize ? blksize : remain_size; + + extern bool psram_write_internal(uint32_t start_addr, uint32_t data_len, uint8_t *data); + if (!psram_write_internal(tmp_addr, write_size, tmp_data)) + { + return false; + } + + tmp_addr += write_size; + tmp_data += write_size; + remain_size -= write_size; + } + + return true; +} + +void psram_deinit(void) +{ + /* clock disable */ + RCC_PeriphClockCmd(APBPeriph_FLASH1, APBPeriph_FLASH1_CLOCK, (FunctionalState)DISABLE); + + /* spic1 enable controller */ + SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN1 = 0; + + /* spic1 master enable */ + SYSBLKCTRL->u_2A8.BITS_2A8.SPIC1_MASTER_EN = 0; +} diff --git a/src/platform/qspi_lcd_platform.c b/src/platform/qspi_lcd_platform.c new file mode 100644 index 0000000..24f8e85 --- /dev/null +++ b/src/platform/qspi_lcd_platform.c @@ -0,0 +1,46 @@ +#include "qspi_lcd_platform.h" +#include "rtl876x.h" +#include "rtl876x_rcc.h" +#include "rtl876x_pinmux.h" + +void qspi_lcd_init(void) +{ + /* module init */ + RCC_PeriphClockCmd(APBPeriph_FLASH2, APBPeriph_FLASH2_CLOCK, (FunctionalState)ENABLE); + + Pinmux_Config(P4_3, IDLE_MODE); + Pinmux_Config(P4_0, IDLE_MODE); + Pinmux_Config(P4_2, IDLE_MODE); + Pinmux_Config(P4_1, IDLE_MODE); + Pinmux_Config(P0_7, IDLE_MODE); + Pinmux_Config(P0_6, IDLE_MODE); + + Pad_Config(P4_3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P4_1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P0_7, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P4_2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P4_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + Pad_Config(P0_6, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, + PAD_OUT_DISABLE, PAD_OUT_LOW); + + /* spic2 enable controller */ + SYSBLKCTRL->u_210.BITS_210.BIT_SOC_FLASH_EN2 = 1; + /* spic2 master enable */ + SYSBLKCTRL->u_2A8.BITS_2A8.SPIC2_MASTER_EN = 1; + /* spic2 write enable default (Jimmy) */ + + /* spic1 & spic2 share clock source enable bit */ + HAL_WRITE32(PERIPH_REG_BASE, 0x2D0, HAL_READ32(PERIPH_REG_BASE, 0x2D0) | BIT5); + + /* set cs and baudrate */ + SPIC2->ssienr = 0; + SPIC2->ser = BIT0; + SPIC2->baudr = 1; +} + + diff --git a/src/platform/retarget.c b/src/platform/retarget.c new file mode 100644 index 0000000..4df8af8 --- /dev/null +++ b/src/platform/retarget.c @@ -0,0 +1,188 @@ +/******************************************************************************/ +/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */ +/******************************************************************************/ +/* This file is part of the uVision/ARM development tools. */ +/* Copyright (c) 2005 Keil Software. All rights reserved. */ +/* This software may only be used under the terms of a valid, current, */ +/* end user licence from KEIL for a compatible version of KEIL software */ +/* development tools. Nothing else gives you the right to use this software. */ +/******************************************************************************/ + +/* 0: redifine printf empty function + 1: redifine printf and using except log uart to print log +others: redifine printf just using log uart to print log*/ +#define PRINTF_RETARGET_METHOD 0 + + +#if ( PRINTF_RETARGET_METHOD == 0) +#include +struct __FILE +{ + int handle; + /* Whatever you require here. If the only file you are using is */ + /* standard output using printf() for debugging, no file handling */ + /* is required. */ +}; +/* FILE is typedef in stdio.h. */ +FILE __stdout; +int fputc(int ch, FILE *f) +{ + /* Your implementation of fputc(). */ + return ch; +} +int ferror(FILE *f) +{ + /* Your implementation of ferror(). */ + return 0; +} + +#elif (PRINTF_RETARGET_METHOD == 1) +#include +#include "rtl876x_uart.h" +/* +#include "rtl876x_nvic.h" +#include "rtl876x_uart.h" +#define UART_TX_PIN P4_0 +void board_uart_init(void) +{ + Pad_Config(UART_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH); + Pinmux_Config(UART_TX_PIN, UART0_TX); +} + +void driver_uart_init(void) +{ + UART_DeInit(UART); + + RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE); + + // uart init + UART_InitTypeDef UART_InitStruct; + UART_StructInit(&UART_InitStruct); + + UART_InitStruct.parity = UART_PARITY_NO_PARTY; + UART_InitStruct.stopBits = UART_STOP_BITS_1; + UART_InitStruct.wordLen = UART_WROD_LENGTH_8BIT; + UART_InitStruct.rxTriggerLevel = 16; //1~29 + UART_InitStruct.idle_time = UART_RX_IDLE_2BYTE; //idle interrupt wait time + + UART_Init(UART, &UART_InitStruct); +} +*/ + +struct __FILE +{ + int handle; + /* Whatever you require here. If the only file you are using is */ + /* standard output using printf() for debugging, no file handling */ + /* is required. */ +}; +/* FILE is typedef in stdio.h. */ +FILE __stdout; +int fputc(int ch, FILE *f) +{ + /* Your implementation of fputc(). */ + while (UART_GetFlagState(UART, UART_FLAG_THR_TSR_EMPTY) != SET); + UART_SendData(UART, &ch, 1); + return ch; +} +int ferror(FILE *f) +{ + /* Your implementation of ferror(). */ + return 0; +} + +#else //print log by log_direct +#include +#include +#include "os_sync.h" +#include "trace.h" +#include "otp.h" + +#define LOG_MESSAGE_SYNC_CODE 0x7E +#define MAX_LOG_MESSAGE_LEN 128 +#define MAX_LOG_MESSAGE_LEN_FOR_SNOOP 252 +#define MAX_ARGUMENT_SIZE 20 + +#define GET_TYPE(info) (uint8_t)((info) >> 24) +#define GET_SUBTYPE(info) (uint8_t)((info) >> 16) +#define GET_MODULE(info) (uint8_t)((info) >> 8) +#define GET_LEVEL(info) (uint8_t)((info) >> 0) + +extern uint32_t log_timestamp_get(void); +extern void LogUartTxChar(const uint8_t ch); +extern uint8_t log_seq_num; + +int printf(const char *fmt, ...) +{ + char l_msg[MAX_LOG_MESSAGE_LEN]; + uint16_t log_length; + int16_t fmt_length; + uint32_t timestamp; + va_list ap; + uint16_t i; + uint32_t s; + uint32_t info; + + /** + * Byte: Description + * 0: Sync(0x7E) + * 1: Length + * 2: SeqNum + * 3: CheckSum + * 4-5: Timestamp + * 6: Type + * 7: SubType: SUBTYPE_DIRECT + * 8: Format String + */ + + if (!is_log_init || OTP->logDisable == 1) + { + return 0; + } + + timestamp = log_timestamp_get(); + info = COMBINE_TRACE_INFO(TYPE_BEE2, SUBTYPE_DIRECT, 0, 0); + + timestamp = log_timestamp_get(); + + l_msg[0] = LOG_MESSAGE_SYNC_CODE; + l_msg[4] = (uint8_t)timestamp; + l_msg[5] = (uint8_t)(timestamp >> 8); + l_msg[6] = GET_TYPE(info); + l_msg[7] = GET_SUBTYPE(info); + + log_length = 8; + + va_start(ap, fmt); + fmt_length = vsnprintf(l_msg + 8, MAX_LOG_MESSAGE_LEN - 8, fmt, ap); + if (fmt_length < 0) /* error occurred */ + { + fmt_length = 0; + } + else if (log_length + fmt_length > MAX_LOG_MESSAGE_LEN) /* truncated */ + { + log_length = MAX_LOG_MESSAGE_LEN; + + } + else + { + log_length += fmt_length; + } + va_end(ap); + + l_msg[1] = log_length; + + s = os_lock(); + l_msg[2] = log_seq_num++; + os_unlock(s); + + l_msg[3] = l_msg[0] ^ l_msg[1] ^ l_msg[2]; + + for (i = 0; i < log_length; ++i) + { + LogUartTxChar(l_msg[i]); + } + + return log_length; +} +#endif diff --git a/src/platform/system_trace.c b/src/platform/system_trace.c new file mode 100644 index 0000000..d631e42 --- /dev/null +++ b/src/platform/system_trace.c @@ -0,0 +1,171 @@ +/** +********************************************************************************************************* +* Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved. +********************************************************************************************************** +* @file +* @brief +* @details +* @author +* @date +* @version v0.1 +********************************************************************************************************* +*/ + +#include "trace_config.h" +#include "system_trace.h" +#include "os_timer.h" +#include "otp.h" +#include "trace.h" + +extern void *xTimerQueue; +extern void *io_queue_handle; +extern void *evt_queue_handle; + +extern BOOL_PATCH_FUNC patch_vTaskSwitchContext; +extern void *xTimerQueue; + +#if (TRACE_HEAP_EN == 1) +HEAP_INFO heap_info[TRACE_HEAP_TYPE_NUM]; + +void print_heap_info(void) +{ + for (uint32_t i = 0; i < TRACE_HEAP_TYPE_NUM; ++i) + { + OS_PRINT_TRACE4("heap type: %i, total size: %d, remain size: %d, minumum ever free size: %d", + i, heap_info[i].total_size, heap_info[i].curr_remain_size, heap_info[i].minimum_ever_free_size); + + OS_PRINT_TRACE1("free list: free block %d.", heap_info[i].free_size_list.number); + for (uint32_t j = 0; j < heap_info[i].free_size_list.number; ++j) + { + OS_PRINT_TRACE3("heap type: %i,free block: %d, free size: %d", i, + heap_info[i].free_size_list.number, heap_info[i].free_size_list.size[j]); + } + } +} +#endif + +#if (TRACE_STACK_EN == 1) +STACK_INFO stack_info; + +void print_stack_info(void) +{ + OS_PRINT_TRACE1("task stack: task number %d", stack_info.task_number); + for (uint32_t i = 0; i < stack_info.task_number; ++i) + { + OS_PRINT_TRACE3("task id: %d, name: %s, minimum ever remain size %d bytes", + stack_info.task_stack_info[i].task_id, TRACE_STRING(stack_info.task_stack_info[i].task_name), + stack_info.task_stack_info[i].minimum_ever_remain_size); + } + OS_PRINT_TRACE1("main stack: minimum ever remain size %d bytes", + stack_info.main_stack_minimum_ever_remain_size); +} +#endif + +#if (TRACE_TIMER_EN == 1) +TIMER_INFO timer_info; + +void print_timer_info(void) +{ + OS_PRINT_TRACE3("timer: total %d, current used %d, minimum ever remain %d", + OTP->timerMaxNumber, timer_info.curr_used_num, timer_info.minimum_ever_remain_num); +} +#endif + +#if (TRACE_QUEUE_EN == 1) +extern uint32_t queue_handle_num0; +QUEUE_INFO queue_info[MAX_QUEUE_OBJECTS_NUM]; +void print_queue_info(void) +{ + for (uint32_t i = 0; i < queue_handle_num0; i++) + { + OS_PRINT_TRACE4("queue %d: capacity_num %d, curr_num_in_queue %d, maximum_ever_num_in_queue %d", + i, queue_info[i].capacity_num, queue_info[i].curr_num_in_queue, + queue_info[i].maximum_ever_num_in_queue); + } +} +#endif + +void trace_timer_callback(void *p_timer) +{ +#if (TRACE_HEAP_EN == 1) + trace_heap(); + print_heap_info(); +#endif + +#if (TRACE_STACK_EN == 1) + trace_task_stack(); + print_stack_info(); +#endif + +#if (TRACE_TIMER_EN == 1) + trace_timer(); + print_timer_info(); +#endif +#if (TRACE_QUEUE_EN == 1) + trace_queue(); + print_queue_info(); +#endif +} + +void system_trace_init(void) +{ +#if (TRACE_HEAP_EN == 1 || TRACE_STACK_EN == 1 || TRACE_TIMER_EN == 1) + void *p_trace_timer = NULL; + if (os_timer_create(&p_trace_timer, "trace_timer", 1, \ + TRACE_PERIOD_TIME, true, trace_timer_callback)) + { + os_timer_start(&p_trace_timer); + } +#endif + +#if (TRACE_TIMER_EN == 1) + trace_timer_init(); +#endif + +#if (DEBUG_DLPS_ERROR_EN == 1) + if (!trace_dlps_init(10000, 60000, 0)) + { + OS_PRINT_ERROR0("trace dlps init fail!"); + } +#endif + +#if (DEBUG_TASK_HANG_EN == 1) + trace_task_hang_init(2, &xTimerQueue, 12, &evt_queue_handle, 10); +#endif + +#if (TRACE_QUEUE_EN == 1) + trace_queue_init(2, &xTimerQueue, &evt_queue_handle); +#endif + +#if (TRACE_HARDFAULT == 1) + /** + * extern void *app_task_handle; + * TCB_t *pxTimerTCB =(TCB_t *)xTimerTaskHandle; + * TCB_t *pxLowerTCB =(TCB_t *)low_task_handle; + * TCB_t *pxUpperTCB =(TCB_t *)upperstack_handle; + * TCB_t *pxAppTCB =(TCB_t *)app_task_handle; + */ + /** + * @brief Initializes trace_hardfault save to flash including critical task stack + * @param dump_task_stack_num: number of task + * @return if it is successfully initialized , return true + + * For example + hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024); + @param 2: dump two task stack + @param low_task_handle: lowstack task handler value + @param 1024: dump task stack size + @param app_task_handle: app task handler value + @param 1024: dump task stack size + @note if need dump app task, must call this api after app task created!!! + Upperstack handler address is different when used different upperstack img! + */ + extern void *low_task_handle; + extern void *xTimerTaskHandle; + extern void *xIdleTaskHandle; + extern void *app_task_handle; + hardfault_save_to_flash_init(2, &low_task_handle, 1024, &app_task_handle, 1024); +#endif +} + + diff --git a/tool/AppData/APP Data Tool Quick Start Guide EN.docx b/tool/AppData/APP Data Tool Quick Start Guide EN.docx new file mode 100644 index 0000000..38548ed Binary files /dev/null and b/tool/AppData/APP Data Tool Quick Start Guide EN.docx differ diff --git a/tool/AppData/APP Data Tool Quick Start Guide.docx b/tool/AppData/APP Data Tool Quick Start Guide.docx new file mode 100644 index 0000000..bea98af Binary files /dev/null and b/tool/AppData/APP Data Tool Quick Start Guide.docx differ diff --git a/tool/AppData/AppData1/SampleAppData1.bin b/tool/AppData/AppData1/SampleAppData1.bin new file mode 100644 index 0000000..66b17cd Binary files /dev/null and b/tool/AppData/AppData1/SampleAppData1.bin differ diff --git a/tool/AppData/AppData1/SampleImageAppData1.bin b/tool/AppData/AppData1/SampleImageAppData1.bin new file mode 100644 index 0000000..646743b Binary files /dev/null and b/tool/AppData/AppData1/SampleImageAppData1.bin differ diff --git a/tool/AppData/AppData1/SampleImageAppData1_MP-28c4a797e6e37f6c9b620e252f8c0c79.bin b/tool/AppData/AppData1/SampleImageAppData1_MP-28c4a797e6e37f6c9b620e252f8c0c79.bin new file mode 100644 index 0000000..4efe5a7 Binary files /dev/null and b/tool/AppData/AppData1/SampleImageAppData1_MP-28c4a797e6e37f6c9b620e252f8c0c79.bin differ diff --git a/tool/AppData/AppData1/SampleImageAppData1_MP.bin b/tool/AppData/AppData1/SampleImageAppData1_MP.bin new file mode 100644 index 0000000..4efe5a7 Binary files /dev/null and b/tool/AppData/AppData1/SampleImageAppData1_MP.bin differ diff --git a/tool/AppData/AppData1/mp.ini b/tool/AppData/AppData1/mp.ini new file mode 100644 index 0000000..bd45af9 --- /dev/null +++ b/tool/AppData/AppData1/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA1 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData1/run.bat b/tool/AppData/AppData1/run.bat new file mode 100644 index 0000000..fb7abed --- /dev/null +++ b/tool/AppData/AppData1/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data1 -p "SampleAppData1.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData1.tmp SampleImageAppData1.bin +1>NUL ren SampleAppData1_MP.bin SampleImageAppData1_MP.bin +..\..\md5\md5.exe "SampleImageAppData1_MP.bin" \ No newline at end of file diff --git a/tool/AppData/AppData2/SampleAppData2.bin b/tool/AppData/AppData2/SampleAppData2.bin new file mode 100644 index 0000000..66b17cd Binary files /dev/null and b/tool/AppData/AppData2/SampleAppData2.bin differ diff --git a/tool/AppData/AppData2/SampleImageAppData2.bin b/tool/AppData/AppData2/SampleImageAppData2.bin new file mode 100644 index 0000000..86b4261 Binary files /dev/null and b/tool/AppData/AppData2/SampleImageAppData2.bin differ diff --git a/tool/AppData/AppData2/SampleImageAppData2_MP-a0735c99dc19f71154c1a23243e44e2e.bin b/tool/AppData/AppData2/SampleImageAppData2_MP-a0735c99dc19f71154c1a23243e44e2e.bin new file mode 100644 index 0000000..d91beb3 Binary files /dev/null and b/tool/AppData/AppData2/SampleImageAppData2_MP-a0735c99dc19f71154c1a23243e44e2e.bin differ diff --git a/tool/AppData/AppData2/SampleImageAppData2_MP.bin b/tool/AppData/AppData2/SampleImageAppData2_MP.bin new file mode 100644 index 0000000..d91beb3 Binary files /dev/null and b/tool/AppData/AppData2/SampleImageAppData2_MP.bin differ diff --git a/tool/AppData/AppData2/mp.ini b/tool/AppData/AppData2/mp.ini new file mode 100644 index 0000000..b7c50e7 --- /dev/null +++ b/tool/AppData/AppData2/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA2 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData2/run.bat b/tool/AppData/AppData2/run.bat new file mode 100644 index 0000000..fbb8535 --- /dev/null +++ b/tool/AppData/AppData2/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data2 -p "SampleAppData2.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData2.tmp SampleImageAppData2.bin +1>NUL ren SampleAppData2_MP.bin SampleImageAppData2_MP.bin +..\..\md5\md5.exe "SampleImageAppData2_MP.bin" \ No newline at end of file diff --git a/tool/AppData/AppData3/SampleAppData3.bin b/tool/AppData/AppData3/SampleAppData3.bin new file mode 100644 index 0000000..98e4e2f Binary files /dev/null and b/tool/AppData/AppData3/SampleAppData3.bin differ diff --git a/tool/AppData/AppData3/SampleImageAppData3.bin b/tool/AppData/AppData3/SampleImageAppData3.bin new file mode 100644 index 0000000..376ab20 Binary files /dev/null and b/tool/AppData/AppData3/SampleImageAppData3.bin differ diff --git a/tool/AppData/AppData3/SampleImageAppData3_MP-711ac5f978f4fed56b85110156adfa58.bin b/tool/AppData/AppData3/SampleImageAppData3_MP-711ac5f978f4fed56b85110156adfa58.bin new file mode 100644 index 0000000..c4c1f3c Binary files /dev/null and b/tool/AppData/AppData3/SampleImageAppData3_MP-711ac5f978f4fed56b85110156adfa58.bin differ diff --git a/tool/AppData/AppData3/SampleImageAppData3_MP.bin b/tool/AppData/AppData3/SampleImageAppData3_MP.bin new file mode 100644 index 0000000..c4c1f3c Binary files /dev/null and b/tool/AppData/AppData3/SampleImageAppData3_MP.bin differ diff --git a/tool/AppData/AppData3/mp.ini b/tool/AppData/AppData3/mp.ini new file mode 100644 index 0000000..79968c4 --- /dev/null +++ b/tool/AppData/AppData3/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA3 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData3/run.bat b/tool/AppData/AppData3/run.bat new file mode 100644 index 0000000..f40d1e0 --- /dev/null +++ b/tool/AppData/AppData3/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data3 -p "SampleAppData3.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData3.tmp SampleImageAppData3.bin +1>NUL ren SampleAppData3_MP.bin SampleImageAppData3_MP.bin +..\..\md5\md5.exe "SampleImageAppData3_MP.bin" \ No newline at end of file diff --git a/tool/AppData/AppData4/SampleAppData4.bin b/tool/AppData/AppData4/SampleAppData4.bin new file mode 100644 index 0000000..98e4e2f Binary files /dev/null and b/tool/AppData/AppData4/SampleAppData4.bin differ diff --git a/tool/AppData/AppData4/SampleImageAppData4.bin b/tool/AppData/AppData4/SampleImageAppData4.bin new file mode 100644 index 0000000..02439b8 Binary files /dev/null and b/tool/AppData/AppData4/SampleImageAppData4.bin differ diff --git a/tool/AppData/AppData4/SampleImageAppData4_MP-b1eaec46d230977b2a78503a6829df92.bin b/tool/AppData/AppData4/SampleImageAppData4_MP-b1eaec46d230977b2a78503a6829df92.bin new file mode 100644 index 0000000..9c23b4d Binary files /dev/null and b/tool/AppData/AppData4/SampleImageAppData4_MP-b1eaec46d230977b2a78503a6829df92.bin differ diff --git a/tool/AppData/AppData4/SampleImageAppData4_MP.bin b/tool/AppData/AppData4/SampleImageAppData4_MP.bin new file mode 100644 index 0000000..9c23b4d Binary files /dev/null and b/tool/AppData/AppData4/SampleImageAppData4_MP.bin differ diff --git a/tool/AppData/AppData4/mp.ini b/tool/AppData/AppData4/mp.ini new file mode 100644 index 0000000..4e7172e --- /dev/null +++ b/tool/AppData/AppData4/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA4 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData4/run.bat b/tool/AppData/AppData4/run.bat new file mode 100644 index 0000000..54feed9 --- /dev/null +++ b/tool/AppData/AppData4/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data4 -p "SampleAppData4.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData4.tmp SampleImageAppData4.bin +1>NUL ren SampleAppData4_MP.bin SampleImageAppData4_MP.bin +..\..\md5\md5.exe "SampleImageAppData4_MP.bin" \ No newline at end of file diff --git a/tool/AppData/AppData5/SampleAppData5.bin b/tool/AppData/AppData5/SampleAppData5.bin new file mode 100644 index 0000000..98e4e2f Binary files /dev/null and b/tool/AppData/AppData5/SampleAppData5.bin differ diff --git a/tool/AppData/AppData5/SampleImageAppData5.bin b/tool/AppData/AppData5/SampleImageAppData5.bin new file mode 100644 index 0000000..fa0272d Binary files /dev/null and b/tool/AppData/AppData5/SampleImageAppData5.bin differ diff --git a/tool/AppData/AppData5/SampleImageAppData5_MP-2f29e24649b70681039c3a953119a6e2.bin b/tool/AppData/AppData5/SampleImageAppData5_MP-2f29e24649b70681039c3a953119a6e2.bin new file mode 100644 index 0000000..e4a1f77 Binary files /dev/null and b/tool/AppData/AppData5/SampleImageAppData5_MP-2f29e24649b70681039c3a953119a6e2.bin differ diff --git a/tool/AppData/AppData5/SampleImageAppData5_MP.bin b/tool/AppData/AppData5/SampleImageAppData5_MP.bin new file mode 100644 index 0000000..e4a1f77 Binary files /dev/null and b/tool/AppData/AppData5/SampleImageAppData5_MP.bin differ diff --git a/tool/AppData/AppData5/mp.ini b/tool/AppData/AppData5/mp.ini new file mode 100644 index 0000000..f9d01e8 --- /dev/null +++ b/tool/AppData/AppData5/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA5 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData5/run.bat b/tool/AppData/AppData5/run.bat new file mode 100644 index 0000000..09a5580 --- /dev/null +++ b/tool/AppData/AppData5/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data5 -p "SampleAppData5.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData5.tmp SampleImageAppData5.bin +1>NUL ren SampleAppData5_MP.bin SampleImageAppData5_MP.bin +..\..\md5\md5.exe "SampleImageAppData5_MP.bin" \ No newline at end of file diff --git a/tool/AppData/AppData6/SampleAppData6.bin b/tool/AppData/AppData6/SampleAppData6.bin new file mode 100644 index 0000000..98e4e2f Binary files /dev/null and b/tool/AppData/AppData6/SampleAppData6.bin differ diff --git a/tool/AppData/AppData6/SampleImageAppData6.bin b/tool/AppData/AppData6/SampleImageAppData6.bin new file mode 100644 index 0000000..18b7a25 Binary files /dev/null and b/tool/AppData/AppData6/SampleImageAppData6.bin differ diff --git a/tool/AppData/AppData6/SampleImageAppData6_MP-d3471d180f7db649228a93df7b9ce771.bin b/tool/AppData/AppData6/SampleImageAppData6_MP-d3471d180f7db649228a93df7b9ce771.bin new file mode 100644 index 0000000..b5545d0 Binary files /dev/null and b/tool/AppData/AppData6/SampleImageAppData6_MP-d3471d180f7db649228a93df7b9ce771.bin differ diff --git a/tool/AppData/AppData6/SampleImageAppData6_MP.bin b/tool/AppData/AppData6/SampleImageAppData6_MP.bin new file mode 100644 index 0000000..b5545d0 Binary files /dev/null and b/tool/AppData/AppData6/SampleImageAppData6_MP.bin differ diff --git a/tool/AppData/AppData6/mp.ini b/tool/AppData/AppData6/mp.ini new file mode 100644 index 0000000..9888ebb --- /dev/null +++ b/tool/AppData/AppData6/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA6 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/AppData/AppData6/run.bat b/tool/AppData/AppData6/run.bat new file mode 100644 index 0000000..e623d54 --- /dev/null +++ b/tool/AppData/AppData6/run.bat @@ -0,0 +1,4 @@ +..\..\prepend_header\prepend_header.exe -t app_data6 -p "SampleAppData6.bin" -m 1 -c sha256 -b 12 +1>NUL ren SampleAppData6.tmp SampleImageAppData6.bin +1>NUL ren SampleAppData6_MP.bin SampleImageAppData6_MP.bin +..\..\md5\md5.exe "SampleImageAppData6_MP.bin" \ No newline at end of file diff --git a/tool/CheckSumGen/CheckSum_Gen.exe b/tool/CheckSumGen/CheckSum_Gen.exe new file mode 100644 index 0000000..109e851 Binary files /dev/null and b/tool/CheckSumGen/CheckSum_Gen.exe differ diff --git a/tool/Gadgets/md5.exe b/tool/Gadgets/md5.exe new file mode 100644 index 0000000..8f7d2aa Binary files /dev/null and b/tool/Gadgets/md5.exe differ diff --git a/tool/Gadgets/md5_generate.sh b/tool/Gadgets/md5_generate.sh new file mode 100644 index 0000000..2ccea2e --- /dev/null +++ b/tool/Gadgets/md5_generate.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +SOURCE_BIN="./bin/"$1"_MP.bin" +VERSION_FILE="../../../inc/platform/version.h" +#echo $SOURCE_BIN +MD5_STR=`md5sum.exe $SOURCE_BIN | cut -c 1-32` +#echo $MD5_STR + +FILE_CONTENT= +for LINE in `head -n 5 $VERSION_FILE` +do + FILE_CONTENT=$FILE_CONTENT%$LINE +done +#echo $FILE_CONTENT + +MAJOR=`echo $FILE_CONTENT | awk -F '%' '{print $4}'` +MINOR=`echo $FILE_CONTENT | awk -F '%' '{print $7}'` +REVISION=`echo $FILE_CONTENT | awk -F '%' '{print $10}'` +GCID=`echo $FILE_CONTENT | awk -F '%' '{print $13}' | cut -c 3-` +#CUSTOMER_NAME=`echo $FILE_CONTENT | awk -F '%' '{print $16}'` +#echo $MAJOR +#echo $MINOR +#echo $REVISION +#echo $GCID +#echo $CUSTOMER_NAME + +IMAGE_NAME=$1-v$MAJOR.$MINOR.$REVISION.$GCID-$MD5_STR.bin +echo $IMAGE_NAME +mv $SOURCE_BIN ./bin/$IMAGE_NAME +#rm -f "./bin/"$1".bin" +#git checkout $VERSION_FILE diff --git a/tool/Gadgets/prepend_header.exe b/tool/Gadgets/prepend_header.exe new file mode 100644 index 0000000..9627911 Binary files /dev/null and b/tool/Gadgets/prepend_header.exe differ diff --git a/tool/Gadgets/readme.md b/tool/Gadgets/readme.md new file mode 100644 index 0000000..377e5ce --- /dev/null +++ b/tool/Gadgets/readme.md @@ -0,0 +1,93 @@ +Readme +====== +md5.exe +============== +The *md5.exe* is a PC tool to make the output binary image file meets the +requirement of *MPTool*. + +Usage +-------------- + md5 + Add md5 checksum to file name + +Notes +-------------- +MPTool requires the binary file names should be ended with -[md5sum], it will +use md5sum to check whether the binary file is valid or not. + +Examples +-------------- + 1. Add md5 checksum to Patch binary + D:\>md5 Patch.bin + Output Image: Patch-381b3b002cfa300054142e01c0332e01.bin + + 2. Add md5 checksum to APP binary + D:\>md5 app.bin + Output Image: app-381b6f00f4fc2c0054142e01c0332e01.bin + + +prepend_header.exe +============== +The *prepend_header.exe* is a PC tool to manipulate the image header and +make the output binary image file meets the requirement of OTA or MP. + +Version +-------------- +v1.0.0 + +Usage +-------------- + prepend_header [/s,/c,/mp,/app_data,/dsp_data,/bkp_data1,/bkp_data2, + ,/app_data0,/app_data1,/app_data2,/app_data3] + /s Generate SHA256 and then prepend the image header + /c Generate CRC16 and then prepend the image header + /mp Generate a new image with MP header + /app_data Generate and append header for BBPro APP data + /dsp_data Generate and append header for BBPro DSP data + /bkp_data1 Generate and append header for BBPro bkp data1 + /bkp_data2 Generate and append header for BBPro bkp data2 + /app_data0 Generate and append header for BEE2 APP data0 + /app_data1 Generate and append header for BEE2 APP data1 + /app_data2 Generate and append header for BEE2 APP data2 + /app_data3 Generate and append header for BEE2 APP data3 + +Notes +-------------- + All parameters are incompatible, do not use them at the same time + except "/s /mp". + + The "/s" parameter also calculates CRC16, that is, CRC Check and + SHA Check would both succeed when doing OTA in BBPro. + + The "/mp" parameter will firstly read the MP information from a + initialization file named "mp.ini", and then generate a new image + file with MP header according to it, and then read the image version + pattern if the version.h have defined it, the finally output file + name is "{Image_Name}_MP-{Major}.{Minor}.{Rev}.{Build}_{CommitID}-{md5}.bin". + + The /app_data/dsp_data/bkp_data1/bkp_data2... parameter is used to + insert corresponding image header for BBPro/Bee2 data image. + Note that these parameters do not calculate CRC or SHA checksum, + thus after appending the data image header, please use this tool + again and pass "/c" or "/s" parameter according to your requirement. + +Examples +-------------- + 1) prepend_header /s app.bin + Generate SHA256 and then prepend header of app.bin + 2) prepend_header /c app.bin + Generate CRC16 and then prepend header of app.bin + 3) prepend_header /mp app.bin + Generate a new image file with MP header, which name will be app_mp.bin + 4) prepend_header /s /mp app.bin + Generate SHA256 and prepend header of app.bin, and then generate a new + image file with MP header, which name will be app_MP-{version&md5}.bin + 5) prepend_header /app_data data.bin + prepend_header /c data.bin + Insert BBPro APP data image header and calculate CRC for data.bin + 6) prepend_header /dsp_data data.bin + prepend_header /s data.bin + Insert BBPro DSP data image header and calculate SHA for data.bin + 7) prepend_header /app_data1 data.bin + prepend_header /c data.bin + Insert Bee2 APP data1 image header and calculate CRC for data.bin \ No newline at end of file diff --git a/tool/Gadgets/rtk_rsa.key b/tool/Gadgets/rtk_rsa.key new file mode 100644 index 0000000..0a1eae3 Binary files /dev/null and b/tool/Gadgets/rtk_rsa.key differ diff --git a/tool/Gadgets/version_gen_config.sh b/tool/Gadgets/version_gen_config.sh new file mode 100644 index 0000000..12ba650 --- /dev/null +++ b/tool/Gadgets/version_gen_config.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Paths +VERSION_TOOL_PATH="../../../tool/Gadgets/version_generation/GitGenerateVersion.sh" +TAG_HEADER="bb3-sdk-" +TEMPLATE_FILE_PATH="../../../tool/Gadgets/version_generation" +TARGET_VERSION_FILE_PATH="../../../inc/platform/version.h" + +# Customer Name +CUSTOMER_NAME="sdk-v1" + +# call version generation tool to generate the version file +$VERSION_TOOL_PATH $TAG_HEADER $TEMPLATE_FILE_PATH $TARGET_VERSION_FILE_PATH $CUSTOMER_NAME diff --git a/tool/Gadgets/version_generation/GitGenerateVersion.sh b/tool/Gadgets/version_generation/GitGenerateVersion.sh new file mode 100644 index 0000000..1cdd1af --- /dev/null +++ b/tool/Gadgets/version_generation/GitGenerateVersion.sh @@ -0,0 +1,113 @@ +#!/bin/bash + +# template file +TEMPLATE_FILE="git_version.template" + +TEMPLATE_PATH=$2/$TEMPLATE_FILE +VERSION_PATH=$3 +echo $TEMPLATE_PATH +echo $VERSION_PATH + +# $1 is the prefix of Git Tag, and default is "bb3-v" +if [ ! $1 ]; then + TAG_HEADER="bb3-v" +else + TAG_HEADER=$1v +fi +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +#echo $TAG_HEADER_LEN + +# get full describe version +FULL_VERSION=`git describe` +# set version to 0.0.0 if no tag name +if [ ! $FULL_VERSION ]; then + FULL_VERSION=$TAG_HEADER"0.0.0" +fi +#echo $FULL_VERSION + +# remove tag header +PROJ_VERSION=`echo $FULL_VERSION | cut -c $TAG_HEADER_LEN-` +#echo $PROJ_VERSION + +# split version to five fields +TAG_VERSION=`echo $PROJ_VERSION | awk -F '-' '{print $1}'` +#echo $TAG_VERSION +MAJOR=`echo $TAG_VERSION | awk -F '.' '{print $1}'` +MINOR=`echo $TAG_VERSION | awk -F '.' '{print $2}'` +# App: get revision from SDK tag +#REVISION=`echo $TAG_VERSION | awk -F '.' '{print $3}'` +# Patch: using count number as revision +REVISION=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $REVISION ]; then + REVISION=0 +fi + +#get branch name +CUSTOMER_NAME=$4 +if [ ! $CUSTOMER_NAME ]; then + BRANCH_NAME=`git symbolic-ref --short -q HEAD` + CUSTOMER_NAME=`echo $BRANCH_NAME | awk -F '-' '{print $2}'` + + if [ ! $CUSTOMER_NAME ]; then + CUSTOMER_NAME="unknown" + fi +fi +#echo $CUSTOMER_NAME +CN_1=${CUSTOMER_NAME:0:1} +CN_2=${CUSTOMER_NAME:1:1} +CN_3=${CUSTOMER_NAME:2:1} +if [ ! $CN_3 ]; then + CN_3=# +fi +CN_4=${CUSTOMER_NAME:3:1} +if [ ! $CN_4 ]; then + CN_4=# +fi +CN_5=${CUSTOMER_NAME:4:1} +if [ ! $CN_5 ]; then + CN_5=# +fi +CN_6=${CUSTOMER_NAME:5:1} +if [ ! $CN_6 ]; then + CN_6=# +fi +CN_7=${CUSTOMER_NAME:6:1} +if [ ! $CN_7 ]; then + CN_7=# +fi +CN_8=${CUSTOMER_NAME:7:1} +if [ ! $CN_8 ]; then + CN_8=# +fi + +#get commit ID +GIT_CMTID_RAW=`git log --pretty=oneline -1 | cut -c 1-8` +GIT_CMTID=0x$GIT_CMTID_RAW + +#echo $MAJOR.$MINOR.$REVISION.$BUILDNUM +#echo $GIT_CMTID + +# build time +BUILDING_TIME=`env LANG=en_US.UTF-8 date '+%a %b %e %R:%S %Y'` +#echo $BUILDING_TIME + +# substitute version&time in template +`cat $TEMPLATE_PATH | sed -e "s/MAJOR_T/$MAJOR/g" \ + -e "s/MINOR_T/$MINOR/g" \ + -e "s/REVISION_T/$REVISION/g" \ + -e "s/BUILDTIME_T/$BUILDING_TIME/g" \ + -e "s/GITCMTID_T/$GIT_CMTID/g" \ + -e "s/CUSTOMER_NAME_T/$CUSTOMER_NAME/g" \ + -e "s/CN_1_T/$CN_1/g" \ + -e "s/CN_2_T/$CN_2/g" \ + -e "s/CN_3_T/$CN_3/g" \ + -e "s/CN_4_T/$CN_4/g" \ + -e "s/CN_5_T/$CN_5/g" \ + -e "s/CN_6_T/$CN_6/g" \ + -e "s/CN_7_T/$CN_7/g" \ + -e "s/CN_8_T/$CN_8/g" \ + > $VERSION_PATH` + +# show result +echo "Generated Version File :" +cat $VERSION_PATH diff --git a/tool/Gadgets/version_generation/SvnGenerateVersion.bat b/tool/Gadgets/version_generation/SvnGenerateVersion.bat new file mode 100644 index 0000000..0529ca7 --- /dev/null +++ b/tool/Gadgets/version_generation/SvnGenerateVersion.bat @@ -0,0 +1,18 @@ +@ECHO OFF +SETLOCAL ENABLEEXTENSIONS + +::----------------------------- +::Initialize script arguments +::----------------------------- +SET workDir=./ +SET template=svn_version.template +SET target=version.h + +::----------------------------- +:: Main entry +::----------------------------- + +"SubWCRev.exe" %workDir% %template% %target% >NUL +type %target% + +@ECHO ON diff --git a/tool/Gadgets/version_generation/git_version.template b/tool/Gadgets/version_generation/git_version.template new file mode 100644 index 0000000..aad3788 --- /dev/null +++ b/tool/Gadgets/version_generation/git_version.template @@ -0,0 +1,19 @@ +#define VERSION_MAJOR MAJOR_T +#define VERSION_MINOR MINOR_T +#define VERSION_REVISION REVISION_T +#define VERSION_GCID GITCMTID_T +#define CUSTOMER_NAME CUSTOMER_NAME_T +#define CN_1 'CN_1_T' +#define CN_2 'CN_2_T' +#define CN_3 'CN_3_T' +#define CN_4 'CN_4_T' +#define CN_5 'CN_5_T' +#define CN_6 'CN_6_T' +#define CN_7 'CN_7_T' +#define CN_8 'CN_8_T' +#define BUILDING_TIME BUILDTIME_T +#define NAME2STR(a) #a +#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME) +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILD) diff --git a/tool/Gadgets/version_generation/readme.md b/tool/Gadgets/version_generation/readme.md new file mode 100644 index 0000000..2aae8a4 --- /dev/null +++ b/tool/Gadgets/version_generation/readme.md @@ -0,0 +1,49 @@ +Contents +======== +* Version Generation Tool + * Git Version Generation Tool + * Svn Version Generation Tool + +Git Version Generation Tool +---------------- +Generate version file before build project when using git as version control tool +* Requirements + * Install GIT package (default path: GIT_INSTALL_DIR="C:\Program Files") + * Environment: Add "GIT_INSTALL_DIR\bin" to the system path + +* Add script and version template in Keil + * Copy GitGenerateVersion.sh and git_version.template to the path of the project + * Open project by Keil + * Options for targets... => User tab + * Select Run#1 below "Before Build/Rebuild" + * Add User Command: + bash.exe GitGenerateVersion.sh [Tag_Header] [Template_File_Path] [Version_File_Path] + * Stop on Exit Code: Select ">=1" + + [Tag_Header]: Header of the tag. The format of git tag must be "Tag_headerMAJOR.MINOR.REVISION" (ex. "bb3-v0.9.1"). And the script will + generate the version: "MAJOR.MINOR.REVISION.BUILDNUM-SHORT_SHA1" (ex. 1.0.1.2-0954421d5). Tag_header must be added in the command + line as a parameter to help the script to remove the header from tag. It can be ommitted if the tag header is "bb3-v". + +* Build Error + * Eror Message: "Error: CreatePross failed, Command: 'bash.exe GitGenerateVersion.sh'" + * Should add the "GIT_INSTALL_DIR\bin" to your system path + * GIT_INSTALL_DIR is the git installation path + +SVN Version Generation Tool +---------------- +Generate version file before build project when using svn as version control tool +* Requirements + * Install TortoiseSVN package (default path: SVN_INSTALL_DIR=C:\Program Files) + * Environment: Add "SVN_INSTALL_DIR\TortoiseSVN\bin" to the system path + +* Add script and version template in Keil + * Copy SvnGenerateVersion.sh and svn_version.template to the path of the project + * Open project by Keil + * Options for targets... => User tab + * Select Run#1 below "Before Build/Rebuild" + * Add User Command: + cmd.exe /c SvnGenerateVersion.bat + +* Note: Version format MAJOR.MINOR.REVISION.BUILDDATE + SvnGenerateVersion.bat update the REVISION and BUILDDATE field of the template. If want to change the MAJOR(or MINOR) of the version, + you need to modify the svn_version.template before generate the version file. diff --git a/tool/Gadgets/version_generation/svn_version.template b/tool/Gadgets/version_generation/svn_version.template new file mode 100644 index 0000000..ec08879 --- /dev/null +++ b/tool/Gadgets/version_generation/svn_version.template @@ -0,0 +1,9 @@ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 1 +#define VERSION_REVISION $WCREV$ +#define VERSION_BUILD $WCDATE=%Y%m%d$ +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILD) +#define SRC_TIME "$WCDATE$" +#define BUILDING_TIME "$WCNOW$" diff --git a/tool/UserData/mp.ini b/tool/UserData/mp.ini new file mode 100644 index 0000000..bd45af9 --- /dev/null +++ b/tool/UserData/mp.ini @@ -0,0 +1,5 @@ +[MandatoryInfo] +BinID=ID_APP_DATA1 +Version=0.0.0.1 +PartNumber= +DataLength= \ No newline at end of file diff --git a/tool/UserData/raw_user_data.bin b/tool/UserData/raw_user_data.bin new file mode 100644 index 0000000..d77f259 Binary files /dev/null and b/tool/UserData/raw_user_data.bin differ diff --git a/tool/UserData/raw_user_data1.bin b/tool/UserData/raw_user_data1.bin new file mode 100644 index 0000000..7b5b825 Binary files /dev/null and b/tool/UserData/raw_user_data1.bin differ diff --git a/tool/UserData/raw_user_data2.bin b/tool/UserData/raw_user_data2.bin new file mode 100644 index 0000000..a68c462 Binary files /dev/null and b/tool/UserData/raw_user_data2.bin differ diff --git a/tool/UserData/raw_user_data3.bin b/tool/UserData/raw_user_data3.bin new file mode 100644 index 0000000..4201d9f Binary files /dev/null and b/tool/UserData/raw_user_data3.bin differ diff --git a/tool/UserData/run.bat b/tool/UserData/run.bat new file mode 100644 index 0000000..963ebee --- /dev/null +++ b/tool/UserData/run.bat @@ -0,0 +1,13 @@ +1>NUL del .\user_data.bin +1>NUL del .\user_data_OTA.bin + +..\prepend_header\prepend_header.exe -t app_data1 -p "raw_user_data.bin" -m 1 -c sha256 -b 12 -u 0xFFFE +1>NUL ren raw_user_data_MP.bin user_data_OTA.bin +..\md5\md5.exe "user_data_OTA.bin" + +1>NUL ren raw_user_data.tmp user_data.bin + + + + + diff --git a/tool/UserData/user_data.bin b/tool/UserData/user_data.bin new file mode 100644 index 0000000..c4cc2b8 Binary files /dev/null and b/tool/UserData/user_data.bin differ diff --git a/tool/UserData/user_data_OTA-04204f2ae8b849b501fa505c1dcdbb98.bin b/tool/UserData/user_data_OTA-04204f2ae8b849b501fa505c1dcdbb98.bin new file mode 100644 index 0000000..7a53201 Binary files /dev/null and b/tool/UserData/user_data_OTA-04204f2ae8b849b501fa505c1dcdbb98.bin differ diff --git a/tool/UserData/user_data_OTA.bin b/tool/UserData/user_data_OTA.bin new file mode 100644 index 0000000..7a53201 Binary files /dev/null and b/tool/UserData/user_data_OTA.bin differ diff --git a/tool/after_build_common.bat b/tool/after_build_common.bat new file mode 100644 index 0000000..bb01787 --- /dev/null +++ b/tool/after_build_common.bat @@ -0,0 +1,22 @@ +@echo off +set keil_compiler_include_floder=%1 +set full_name_path=%2 +set linker_output_file_name=%3 +::echo %keil_compiler_include_floder% +::echo %full_name_path% +::echo %linker_output_file_name% + +%keil_compiler_include_floder%\..\bin\fromelf.exe --bin -o "bin/" "%full_name_path%" +REM --------------------------------------------- +REM Optional: Generate a disassembly file for debugging. +REM To enable, remove the "::" at the beginning of the command. +REM Note: The "--interleave=source" flag interleaves source code with disassembled code. +REM This helps in correlating the source with its machine code, but the file will +REM contain your source code. Make sure to protect its confidentiality. +REM --------------------------------------------- +::%keil_compiler_include_floder%\..\bin\fromelf.exe -acd --interleave=source -o "bin\%linker_output_file_name%.disasm" "%full_name_path%" +::..\..\..\..\tool\prepend_header\prepend_header.exe -r "..\..\..\tool\keys\rtk_rsa.pem" -t app_code -p "bin\%linker_output_file_name%.bin" -m 1 -c sha256 -a "..\..\..\..\tool\key.json" +..\..\..\..\tool\prepend_header\prepend_header.exe -t app_code -b 12 -p "bin\%linker_output_file_name%.bin" -m 1 -i "..\mp.ini" -c sha256 -a "..\..\..\..\tool\key.json" +..\..\..\..\tool\MD5\md5.exe "bin\%linker_output_file_name%.bin" +..\..\..\..\tool\MD5\md5.exe "bin\%linker_output_file_name%_MP.bin" +del "bin\%linker_output_file_name%_MP.bin" \ No newline at end of file diff --git a/tool/before_build_common.bat b/tool/before_build_common.bat new file mode 100644 index 0000000..e489057 --- /dev/null +++ b/tool/before_build_common.bat @@ -0,0 +1,2 @@ +@echo off +rem bash.exe ..\..\..\..\tool\version_generation\git_generate_version.sh bee2 ..\..\..\..\tool\version_generation\ ..\..\..\..\inc\platform\version.h diff --git a/tool/findmy_token_decode/TOKEN_DECODE.exe b/tool/findmy_token_decode/TOKEN_DECODE.exe new file mode 100644 index 0000000..31c3e2e Binary files /dev/null and b/tool/findmy_token_decode/TOKEN_DECODE.exe differ diff --git a/tool/findmy_token_decode/TOKEN_DECODE.iobj b/tool/findmy_token_decode/TOKEN_DECODE.iobj new file mode 100644 index 0000000..c50d315 Binary files /dev/null and b/tool/findmy_token_decode/TOKEN_DECODE.iobj differ diff --git a/tool/findmy_token_decode/TOKEN_DECODE.ipdb b/tool/findmy_token_decode/TOKEN_DECODE.ipdb new file mode 100644 index 0000000..b538ff7 Binary files /dev/null and b/tool/findmy_token_decode/TOKEN_DECODE.ipdb differ diff --git a/tool/findmy_token_decode/TOKEN_DECODE.pdb b/tool/findmy_token_decode/TOKEN_DECODE.pdb new file mode 100644 index 0000000..5c68130 Binary files /dev/null and b/tool/findmy_token_decode/TOKEN_DECODE.pdb differ diff --git a/tool/findmy_token_decode/token.bin b/tool/findmy_token_decode/token.bin new file mode 100644 index 0000000..b658d19 Binary files /dev/null and b/tool/findmy_token_decode/token.bin differ diff --git a/tool/flash/Bee3_SPI_FLASH.FLM b/tool/flash/Bee3_SPI_FLASH.FLM new file mode 100644 index 0000000..7892ab0 Binary files /dev/null and b/tool/flash/Bee3_SPI_FLASH.FLM differ diff --git a/tool/flash/RTL876x_LOG_TRACE_16MB.FLM b/tool/flash/RTL876x_LOG_TRACE_16MB.FLM new file mode 100644 index 0000000..c64f7d2 Binary files /dev/null and b/tool/flash/RTL876x_LOG_TRACE_16MB.FLM differ diff --git a/tool/hex2bin/Hex2Bin b/tool/hex2bin/Hex2Bin new file mode 100644 index 0000000..d52b87c Binary files /dev/null and b/tool/hex2bin/Hex2Bin differ diff --git a/tool/hex2bin/Hex2Bin.exe b/tool/hex2bin/Hex2Bin.exe new file mode 100644 index 0000000..afc4b24 Binary files /dev/null and b/tool/hex2bin/Hex2Bin.exe differ diff --git a/tool/key.json b/tool/key.json new file mode 100644 index 0000000..449f6d3 --- /dev/null +++ b/tool/key.json @@ -0,0 +1,3 @@ +{ + "OCEK": "a1a2a3a4a5a6a7a8a9aaabacadaeafb0" +} \ No newline at end of file diff --git a/tool/keys/rtk_rsa.pem b/tool/keys/rtk_rsa.pem new file mode 100644 index 0000000..d4fd7e5 --- /dev/null +++ b/tool/keys/rtk_rsa.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA5XwL87FlpFpxPudHPd6YO8UTXqD3mzPFTirSKd1ROHTHuAKP +hBvyAEt0pnlHOjcytv7ahAx1wYRSovXpT1h/6K1LCl7WgzLAJowPoBcmeyf8chCs +EOwKwKwZuNtMDd+31p9ZevVU8vr3eEl7x88af2A47JqDtIEVNGW/z+Zdvivq3mGC +Cs6JX5yASkeM1TWEWLutPdZNoH/xxbvJV3wd0uOkair3UzLowBSx0Gti3EmWtFb2 +E28m2HNQswjW1lZUrMAOvCUIDlenQV1pSyTDDq4/WhazTmpKsUi9AanMoz9mJUvw +bD0uGaymQ7t7/OtC3cN3nEaMXmcEaHEPB7Qf9QIDAQABAoIBAQDE20t5adTyTu9U +cZuIdFmM9Drwcw7UoW2A53TPmt3gmzT0IaYxQrOvEwtm/yRdyRoFJswWeIXPUo58 +4oyYlydqVrXHmKFVfISezIle4F0PSrbgtnKUNZfnvfp2vBAa2q3eO2XL94Y+xZDi +K882EO//EnDibo3KmuywvRP06P3DclM1mGFZZ/SLUX+/4HLDEgJFObrQrhawR/sI +wQhr7rMAsLx/fGuXbJwM2TnLXBImdHsxDrYsF1GYEQ/P3f+H04SLaDE0+u5DRrIG ++Ppng6go32+cFwjgL08DiCD2Dpw9OmFvEhkhPLBv3BhAO1HgTU6rAfEv00J9Kwsj +n9KSaNrhAoGBAPRhQZncpEVhQHzyAa2S2BdUJM1w3QniLP3vlhxL6ElvTyXzjtwA +FUSgQPAi+pn2IgtzfooQ7bsT7yDvSw+o3DhtYXs+7W7xQu6AvxAgVDn6mn45widm +FLvhkM0qAiCJ8vadQ3G19cGlT8HHk8jLiuknzWfiynzVavzFmYPKVzr9AoGBAPBl +eZmRTh3RwICG1TLvKF2SK6eMRZA7xfK8WcFCR5De5K6xutWPMgHeHNSDXsqEiklJ +f2pxubpZBBuBgVYFXlThmjwgi7rM4yd2KGA9x7dyDn9QodN/ovNGK9MEYxtnWXAT +ZPI7NrMeo3bKlFlPiL7otWBY80u6Or7VlnLx8HZZAoGBAND2hKizEUg+I21zZlns +UZiJG7sLwgYcf0pX3qytf5+jbTNPcx3NeGIpAb4UuuKBo5TVGiOm3BD2t6ga1b07 +L6uUZCGFqnMOG6RjNHzul/bHwekjLFCSKjKJa07zl8QJEVctHCmUZONDntJc/JJa +8ZnyreIh+/EIcKZZtK4Li9FlAoGAcn/ytilWaq+QH+eYvoTY1hCcCFawf21o8B+0 +JG+cRK1VgLuYgMWOjQMs+i+EQ7NzZkrCjIGUc+SYJz28y6sM7iLyYnch9pxGCXKm +8ogaiw6hRxSxr1oY1AR1NTHevpuwJsimCRYZDKGoPBlrJUrTmBKg6T4Uy9nsxx5W +ZXNFFCkCgYEApdrlY5KWrR3EXehUIiYZ3013SdoUZX370KJATjE43GG2XWT4JrjS +qsv1sOk2H2gvRXNLprzTE3i3kn6CAoA8/Nc8uQ4+LzckSe0/KkQ3mJzZWdBv+JHi +gtNmj2SnilOXgwdfxtGismjWbaVVBjOsYpqIeo0gdpYfJJ4jRyPV2ME= +-----END RSA PRIVATE KEY----- diff --git a/tool/md5/md5 b/tool/md5/md5 new file mode 100644 index 0000000..fab98a1 Binary files /dev/null and b/tool/md5/md5 differ diff --git a/tool/md5/md5.exe b/tool/md5/md5.exe new file mode 100644 index 0000000..a1ca903 Binary files /dev/null and b/tool/md5/md5.exe differ diff --git a/tool/md5/readme.md b/tool/md5/readme.md new file mode 100644 index 0000000..d28010c --- /dev/null +++ b/tool/md5/readme.md @@ -0,0 +1,24 @@ +Readme +====== +The *md5.exe* is a PC tool to make the output binary image file meets the +requirement of *MPTool*. + +Usage +-------------- + md5 + Add md5 checksum to file name + +Notes +-------------- +MPTool requires the binary file names should be ended with -[md5sum], it will +use md5sum to check whether the binary file is valid or not. + +Examples +-------------- + 1. Add md5 checksum to Patch binary + D:\>md5 Patch.bin + Output Image: Patch-381b3b002cfa300054142e01c0332e01.bin + + 2. Add md5 checksum to APP binary + D:\>md5 app.bin + Output Image: app-381b6f00f4fc2c0054142e01c0332e01.bin diff --git a/tool/memory_icf/MemDefine b/tool/memory_icf/MemDefine new file mode 100644 index 0000000..5691a88 Binary files /dev/null and b/tool/memory_icf/MemDefine differ diff --git a/tool/memory_icf/MemDefine.exe b/tool/memory_icf/MemDefine.exe new file mode 100644 index 0000000..bc85d2a Binary files /dev/null and b/tool/memory_icf/MemDefine.exe differ diff --git a/tool/prepend_header/prepend_header b/tool/prepend_header/prepend_header new file mode 100644 index 0000000..1c56483 Binary files /dev/null and b/tool/prepend_header/prepend_header differ diff --git a/tool/prepend_header/prepend_header.exe b/tool/prepend_header/prepend_header.exe new file mode 100644 index 0000000..2c47156 Binary files /dev/null and b/tool/prepend_header/prepend_header.exe differ diff --git a/tool/readme b/tool/readme new file mode 100644 index 0000000..e69de29 diff --git a/tool/remove_img_mp_header.bat b/tool/remove_img_mp_header.bat new file mode 100644 index 0000000..354222e --- /dev/null +++ b/tool/remove_img_mp_header.bat @@ -0,0 +1,12 @@ +ECHO off +rem + +::remove 512bytes MP Header +bash.exe -c "dd if=OTAHeader_Bank0_MP.bin of=OTAHeader_Bank0.bin bs=1 skip=512" + +:: convert ota header bin to hex + .\srec_cat ".\OTAHeader_Bank0.bin" -binary -offset 0x802000 -o ".\OTAHeader_Bank0.hex" -intel + +::handle ota header1 +::bash.exe -c "dd if=OTAHeader_Bank1_MP.bin of=OTAHeader_Bank1.bin bs=1 skip=512" +:: .\srec_cat ".\OTAHeader_Bank1.bin" -binary -offset 0x84C000 -o ".\OTAHeader_Bank1.hex" -intel \ No newline at end of file diff --git a/tool/srec_cat.exe b/tool/srec_cat.exe new file mode 100644 index 0000000..31d4d0c Binary files /dev/null and b/tool/srec_cat.exe differ diff --git a/tool/version_generation/git_generate_version.sh b/tool/version_generation/git_generate_version.sh new file mode 100644 index 0000000..2f35aa3 --- /dev/null +++ b/tool/version_generation/git_generate_version.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +# template file +TEMPLATE_FILE="git_version.template" + +TEMPLATE_PATH=$2/$TEMPLATE_FILE +VERSION_PATH=$3 +#echo $TEMPLATE_PATH +#echo $VERSION_PATH + +# $1 is the prefix of Git Tag, and default is "bee3-sdk-v" +if [ ! $1 ]; then + TAG_HEADER="bee3-sdk-v" +else + TAG_HEADER=$1v +fi +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +#echo $TAG_HEADER #bee3-sdk-v +#echo $TAG_HEADER_LEN #11 + + +# get full describe vers +FULL_VERSION=`git describe` +# set version to 0.0.0 if no tag name +if [ ! $FULL_VERSION ]; then + FULL_VERSION=$TAG_HEADER"0.0.0" +fi +#echo $FULL_VERSION + +# modify TAG_HEADER due to multiple version tag exist in bee3 +TAG_HEADER=$(echo $FULL_VERSION | sed 's/v[0-9].*$/v/') +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +# echo $TAG_HEADER +# echo $TAG_HEADER_LEN + +# remove tag header +PROJ_VERSION=`echo $FULL_VERSION | cut -c $TAG_HEADER_LEN-` +#echo $PROJ_VERSION + +# split version to five fields +TAG_VERSION=`echo $PROJ_VERSION | awk -F '-' '{print $1}'` +#echo $TAG_VERSION +MAJOR=`echo $TAG_VERSION | awk -F '.' '{print $1}'` +if [ ! $MAJOR ]; then + MAJOR=0 +fi +#echo $MAJOR +MINOR=`echo $TAG_VERSION | awk -F '.' '{print $2}'` +if [ ! $MINOR ]; then + MINOR=0 +fi +#echo $MINOR +# App: get revision from SDK tag +REVISION=`echo $TAG_VERSION | awk -F '.' '{print $3}'` +# Patch: using count number as revision +#REVISION=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $REVISION ]; then + REVISION=0 +fi +#echo $REVISION +BUILDNUM=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $BUILDNUM ]; then + BUILDNUM=0 +fi +if [ $BUILDNUM -gt 2048 ]; then + echo "Build number: " $BUILDNUM + echo "Build number too large, Need to update revision !!!" + exit -1 +fi +#echo $BUILDNUM + +#get branch name +CUSTOMER_NAME=$4 +if [ ! $CUSTOMER_NAME ]; then + BRANCH_NAME=`git symbolic-ref --short -q HEAD` + CUSTOMER_NAME=`echo $BRANCH_NAME | awk -F '-' '{print $2}'` + + if [ ! $CUSTOMER_NAME ]; then + CUSTOMER_NAME="unknown" + fi +fi +#echo $BRANCH_NAME +#echo $CUSTOMER_NAME +CN_1=${CUSTOMER_NAME:0:1} +CN_2=${CUSTOMER_NAME:1:1} +CN_3=${CUSTOMER_NAME:2:1} +if [ ! $CN_3 ]; then + CN_3=# +fi +CN_4=${CUSTOMER_NAME:3:1} +if [ ! $CN_4 ]; then + CN_4=# +fi +CN_5=${CUSTOMER_NAME:4:1} +if [ ! $CN_5 ]; then + CN_5=# +fi +CN_6=${CUSTOMER_NAME:5:1} +if [ ! $CN_6 ]; then + CN_6=# +fi +CN_7=${CUSTOMER_NAME:6:1} +if [ ! $CN_7 ]; then + CN_7=# +fi +CN_8=${CUSTOMER_NAME:7:1} +if [ ! $CN_8 ]; then + CN_8=# +fi + +#get commit ID +GIT_CMTID_RAW=`git log --pretty=oneline -1 | cut -c 1-8` +GIT_CMTID=0x$GIT_CMTID_RAW +GIT_CMTID2_RAW=`git log --pretty=oneline -1 | cut -c 9-16` +GIT_CMTID2=0x$GIT_CMTID2_RAW + +#echo $MAJOR.$MINOR.$REVISION.$BUILDNUM +#echo $GIT_CMTID_RAW +#echo $GIT_CMTID + +# build time +BUILDING_TIME='"'`env LANG=en_US.UTF-8 date '+%a %b %e %R:%S %Y'`'"' +#echo $BUILDING_TIME + +# substitute version&time in template +`cat $TEMPLATE_PATH | sed -e "s/MAJOR_T/$MAJOR/g" \ + -e "s/MINOR_T/$MINOR/g" \ + -e "s/REVISION_T/$REVISION/g" \ + -e "s/BUILDNUM_T/$BUILDNUM/g" \ + -e "s/BUILDTIME_T/$BUILDING_TIME/g" \ + -e "s/GITCMTID_T/$GIT_CMTID/g" \ + -e "s/GITCMTID2_T/$GIT_CMTID2/g" \ + -e "s/CUSTOMER_NAME_T/$CUSTOMER_NAME/g" \ + -e "s/CN_1_T/$CN_1/g" \ + -e "s/CN_2_T/$CN_2/g" \ + -e "s/CN_3_T/$CN_3/g" \ + -e "s/CN_4_T/$CN_4/g" \ + -e "s/CN_5_T/$CN_5/g" \ + -e "s/CN_6_T/$CN_6/g" \ + -e "s/CN_7_T/$CN_7/g" \ + -e "s/CN_8_T/$CN_8/g" \ + > $VERSION_PATH` + +# show result +echo "Generated Version File :" +cat $VERSION_PATH +exit 0 \ No newline at end of file diff --git a/tool/version_generation/git_generate_version_electric.sh b/tool/version_generation/git_generate_version_electric.sh new file mode 100644 index 0000000..626d303 --- /dev/null +++ b/tool/version_generation/git_generate_version_electric.sh @@ -0,0 +1,146 @@ +#!/bin/bash + +# template file +TEMPLATE_FILE="git_version.template" + +TEMPLATE_PATH=$2/$TEMPLATE_FILE +VERSION_PATH=$3 +#echo $TEMPLATE_PATH +#echo $VERSION_PATH + +# $1 is the prefix of Git Tag, and default is "bee3-sdk-electric-" +if [ ! $1 ]; then + TAG_HEADER="bee3-sdk-electric-" +else + TAG_HEADER=$1v +fi +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +# echo $TAG_HEADER # +# echo $TAG_HEADER_LEN #11 + + +# get full describe vers +MATCH_TAG=$TAG_HEADER +echo MATCH_TAG +FULL_VERSION=`git describe --match $MATCH_TAG[0-9].[0-9].[0-9]` +# set version to 0.0.0 if no tag name +if [ ! $FULL_VERSION ]; then + FULL_VERSION=$TAG_HEADER"0.0.0" +fi +# echo $FULL_VERSION + +# modify TAG_HEADER due to multiple version tag exist in sbee2 +# TAG_HEADER=$(echo $FULL_VERSION | sed 's/v[0-9].*$/v/') +# TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +# echo $TAG_HEADER +# echo $TAG_HEADER_LEN + +# remove tag header +PROJ_VERSION=`echo $FULL_VERSION | cut -c $TAG_HEADER_LEN-` +#echo $PROJ_VERSION + +# split version to five fields +TAG_VERSION=`echo $PROJ_VERSION | awk -F '-' '{print $1}'` +#echo $TAG_VERSION +MAJOR=`echo $TAG_VERSION | awk -F '.' '{print $1}'` +if [ ! $MAJOR ]; then + MAJOR=0 +fi +#echo $MAJOR +MINOR=`echo $TAG_VERSION | awk -F '.' '{print $2}'` +if [ ! $MINOR ]; then + MINOR=0 +fi +#echo $MINOR +# App: get revision from SDK tag +REVISION=`echo $TAG_VERSION | awk -F '.' '{print $3}'` +# Patch: using count number as revision +#REVISION=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $REVISION ]; then + REVISION=0 +fi +#echo $REVISION +BUILDNUM=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $BUILDNUM ]; then + BUILDNUM=0 +fi +if [ $BUILDNUM -gt 2048 ]; then + echo "Build number: " $BUILDNUM + echo "Build number too large, Need to update revision !!!" + exit -1 +fi +# echo $BUILDNUM + +#get branch name +CUSTOMER_NAME=$4 +if [ ! $CUSTOMER_NAME ]; then + BRANCH_NAME=`git symbolic-ref --short -q HEAD` + CUSTOMER_NAME=`echo $BRANCH_NAME | awk -F '-' '{print $2}'` + + if [ ! $CUSTOMER_NAME ]; then + CUSTOMER_NAME="unknown" + fi +fi +#echo $BRANCH_NAME +#echo $CUSTOMER_NAME +CN_1=${CUSTOMER_NAME:0:1} +CN_2=${CUSTOMER_NAME:1:1} +CN_3=${CUSTOMER_NAME:2:1} +if [ ! $CN_3 ]; then + CN_3=# +fi +CN_4=${CUSTOMER_NAME:3:1} +if [ ! $CN_4 ]; then + CN_4=# +fi +CN_5=${CUSTOMER_NAME:4:1} +if [ ! $CN_5 ]; then + CN_5=# +fi +CN_6=${CUSTOMER_NAME:5:1} +if [ ! $CN_6 ]; then + CN_6=# +fi +CN_7=${CUSTOMER_NAME:6:1} +if [ ! $CN_7 ]; then + CN_7=# +fi +CN_8=${CUSTOMER_NAME:7:1} +if [ ! $CN_8 ]; then + CN_8=# +fi + +#get commit ID +GIT_CMTID_RAW=`git log --pretty=oneline -1 | cut -c 1-8` +GIT_CMTID=0x$GIT_CMTID_RAW + +#echo $MAJOR.$MINOR.$REVISION.$BUILDNUM +#echo $GIT_CMTID_RAW +#echo $GIT_CMTID + +# build time +BUILDING_TIME='"'`env LANG=en_US.UTF-8 date '+%a %b %e %R:%S %Y'`'"' +#echo $BUILDING_TIME + +# substitute version&time in template +`cat $TEMPLATE_PATH | sed -e "s/MAJOR_T/$MAJOR/g" \ + -e "s/MINOR_T/$MINOR/g" \ + -e "s/REVISION_T/$REVISION/g" \ + -e "s/BUILDNUM_T/$BUILDNUM/g" \ + -e "s/BUILDTIME_T/$BUILDING_TIME/g" \ + -e "s/GITCMTID_T/$GIT_CMTID/g" \ + -e "s/CUSTOMER_NAME_T/$CUSTOMER_NAME/g" \ + -e "s/CN_1_T/$CN_1/g" \ + -e "s/CN_2_T/$CN_2/g" \ + -e "s/CN_3_T/$CN_3/g" \ + -e "s/CN_4_T/$CN_4/g" \ + -e "s/CN_5_T/$CN_5/g" \ + -e "s/CN_6_T/$CN_6/g" \ + -e "s/CN_7_T/$CN_7/g" \ + -e "s/CN_8_T/$CN_8/g" \ + > $VERSION_PATH` + +# show result +echo "Generated Version File :" +cat $VERSION_PATH +exit 0 \ No newline at end of file diff --git a/tool/version_generation/git_generate_version_sdk_lib.sh b/tool/version_generation/git_generate_version_sdk_lib.sh new file mode 100644 index 0000000..3ad0ebe --- /dev/null +++ b/tool/version_generation/git_generate_version_sdk_lib.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# template file +TEMPLATE_FILE="git_version.template" + +TEMPLATE_PATH=$2/$TEMPLATE_FILE +VERSION_PATH=$3 +#echo $TEMPLATE_PATH +#echo $VERSION_PATH + +# $1 is the prefix of Git Tag, and default is "bee3-sdk-v" +if [ ! $1 ]; then + TAG_HEADER="bee3-sdk-v" +else + TAG_HEADER=$1v +fi + +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +echo $TAG_HEADER #bee3-sdk-v +#echo $TAG_HEADER_LEN #11 + + +# get full describe vers + +MATCH_TAG=$TAG_HEADER +echo MATCH_TAG +FULL_VERSION=`git describe --match $MATCH_TAG[0-9].[0-9].[0-9]` + +# set version to 0.0.0 if no tag name +if [ ! $FULL_VERSION ]; then + FULL_VERSION=$TAG_HEADER"0.0.0" +fi +#echo $FULL_VERSION + +# modify TAG_HEADER due to multiple version tag exist in bee2 +TAG_HEADER=$(echo $FULL_VERSION | sed 's/v[0-9].*$/v/') +TAG_HEADER_LEN=`echo $TAG_HEADER | wc -c` +# echo $TAG_HEADER +# echo $TAG_HEADER_LEN + +# remove tag header +PROJ_VERSION=`echo $FULL_VERSION | cut -c $TAG_HEADER_LEN-` +#echo $PROJ_VERSION + +# split version to five fields +TAG_VERSION=`echo $PROJ_VERSION | awk -F '-' '{print $1}'` +#echo $TAG_VERSION +MAJOR=`echo $TAG_VERSION | awk -F '.' '{print $1}'` +if [ ! $MAJOR ]; then + MAJOR=0 +fi +#echo $MAJOR +MINOR=`echo $TAG_VERSION | awk -F '.' '{print $2}'` + +if [ ! $MINOR ]; then + MINOR=0 +fi +#echo $MINOR +# App: get revision from SDK tag +REVISION=`echo $TAG_VERSION | awk -F '.' '{print $3}'` +# Patch: using count number as revision +#REVISION=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $REVISION ]; then + REVISION=0 +fi +#echo $REVISION +BUILDNUM=`echo $PROJ_VERSION | awk -F '-' '{print $2}'` +if [ ! $BUILDNUM ]; then + BUILDNUM=0 +fi +if [ $BUILDNUM -gt 2048 ]; then + echo "Build number: " $BUILDNUM + echo "Build number too large, Need to update revision !!!" + exit -1 +fi +#echo $BUILDNUM + +#get branch name +CUSTOMER_NAME=$4 +if [ ! $CUSTOMER_NAME ]; then + BRANCH_NAME=`git symbolic-ref --short -q HEAD` + CUSTOMER_NAME=`echo $BRANCH_NAME | awk -F '-' '{print $2}'` + + if [ ! $CUSTOMER_NAME ]; then + CUSTOMER_NAME="unknown" + fi +fi +#echo $BRANCH_NAME +#echo $CUSTOMER_NAME +CN_1=${CUSTOMER_NAME:0:1} +CN_2=${CUSTOMER_NAME:1:1} +CN_3=${CUSTOMER_NAME:2:1} +if [ ! $CN_3 ]; then + CN_3=# +fi +CN_4=${CUSTOMER_NAME:3:1} +if [ ! $CN_4 ]; then + CN_4=# +fi +CN_5=${CUSTOMER_NAME:4:1} +if [ ! $CN_5 ]; then + CN_5=# +fi +CN_6=${CUSTOMER_NAME:5:1} +if [ ! $CN_6 ]; then + CN_6=# +fi +CN_7=${CUSTOMER_NAME:6:1} +if [ ! $CN_7 ]; then + CN_7=# +fi +CN_8=${CUSTOMER_NAME:7:1} +if [ ! $CN_8 ]; then + CN_8=# +fi + +#get commit ID +GIT_CMTID_RAW=`git log --pretty=oneline -1 | cut -c 1-8` +GIT_CMTID=0x$GIT_CMTID_RAW +GIT_CMTID2_RAW=`git log --pretty=oneline -1 | cut -c 9-16` +GIT_CMTID2=0x$GIT_CMTID2_RAW + +#echo $MAJOR.$MINOR.$REVISION.$BUILDNUM +#echo $GIT_CMTID_RAW +#echo $GIT_CMTID + +# build time +BUILDING_TIME='"'`env LANG=en_US.UTF-8 date '+%a %b %e %R:%S %Y'`'"' +#echo $BUILDING_TIME + +# substitute version&time in template +`cat $TEMPLATE_PATH | sed -e "s/MAJOR_T/$MAJOR/g" \ + -e "s/MINOR_T/$MINOR/g" \ + -e "s/REVISION_T/$REVISION/g" \ + -e "s/BUILDNUM_T/$BUILDNUM/g" \ + -e "s/BUILDTIME_T/$BUILDING_TIME/g" \ + -e "s/GITCMTID_T/$GIT_CMTID/g" \ + -e "s/GITCMTID2_T/$GIT_CMTID2/g" \ + -e "s/CUSTOMER_NAME_T/$CUSTOMER_NAME/g" \ + -e "s/CN_1_T/$CN_1/g" \ + -e "s/CN_2_T/$CN_2/g" \ + -e "s/CN_3_T/$CN_3/g" \ + -e "s/CN_4_T/$CN_4/g" \ + -e "s/CN_5_T/$CN_5/g" \ + -e "s/CN_6_T/$CN_6/g" \ + -e "s/CN_7_T/$CN_7/g" \ + -e "s/CN_8_T/$CN_8/g" \ + > $VERSION_PATH` + +# show result +echo "Generated Version File :" +cat $VERSION_PATH +exit 0 \ No newline at end of file diff --git a/tool/version_generation/git_version.template b/tool/version_generation/git_version.template new file mode 100644 index 0000000..9d9f947 --- /dev/null +++ b/tool/version_generation/git_version.template @@ -0,0 +1,21 @@ +#define VERSION_MAJOR MAJOR_T +#define VERSION_MINOR MINOR_T +#define VERSION_REVISION REVISION_T +#define VERSION_BUILDNUM BUILDNUM_T +#define VERSION_GCID GITCMTID_T +#define VERSION_GCID2 GITCMTID2_T +#define CUSTOMER_NAME CUSTOMER_NAME_T +#define CN_1 'CN_1_T' +#define CN_2 'CN_2_T' +#define CN_3 'CN_3_T' +#define CN_4 'CN_4_T' +#define CN_5 'CN_5_T' +#define CN_6 'CN_6_T' +#define CN_7 'CN_7_T' +#define CN_8 'CN_8_T' +#define BUILDING_TIME BUILDTIME_T +#define NAME2STR(a) #a +#define CUSTOMER_NAME_S #NAME2STR(CUSTOMER_NAME) +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILDNUM) diff --git a/tool/version_generation/readme.md b/tool/version_generation/readme.md new file mode 100644 index 0000000..96c4783 --- /dev/null +++ b/tool/version_generation/readme.md @@ -0,0 +1,49 @@ +Contents +======== +* Version Generation Tool + * Git Version Generation Tool + * Svn Version Generation Tool + +Git Version Generation Tool +---------------- +Generate version file before build project when using git as version control tool +* Requirements + * Install GIT package (default path: GIT_INSTALL_DIR="C:\Program Files") + * Environment: Add "GIT_INSTALL_DIR\bin" to the system path + +* Add script and version template in Keil + * Copy GitGenerateVersion.sh and git_version.template to the path of the project + * Open project by Keil + * Options for targets... => User tab + * Select Run#1 below "Before Build/Rebuild" + * Add User Command: + bash.exe GitGenerateVersion.sh [Tag_Header] + * Stop on Exit Code: Select ">=1" + + [Tag_Header]: Header of the tag. The format of git tag must be "Tag_headerMAJOR.MINOR.REVISION" (ex. "bee2-v0.9.1"). And the script will + generate the build version: "MAJOR.MINOR.REVISION.COMMIT_COUNT" (ex. 0.9.1.4535). Tag_header must be added in the command + line as a parameter to help the script to remove the header from tag. It can be ommited if the tag header is "bee2-v". + +* Build Error + * Eror Message: "Error: CreatePross failed, Command: 'bash.exe GitGenerateVersion.sh'" + * Should add the "GIT_INSTALL_DIR\bin" to your system path + * GIT_INSTALL_DIR is the git installation path + +SVN Version Generation Tool +---------------- +Generate version file before build project when using svn as version control tool +* Requirements + * Install TortoiseSVN package (default path: SVN_INSTALL_DIR=C:\Program Files) + * Environment: Add "SVN_INSTALL_DIR\TortoiseSVN\bin" to the system path + +* Add script and version template in Keil + * Copy SvnGenerateVersion.sh and svn_version.template to the path of the project + * Open project by Keil + * Options for targets... => User tab + * Select Run#1 below "Before Build/Rebuild" + * Add User Command: + cmd.exe /c SvnGenerateVersion.bat + +* Note: Version format MAJOR.MINOR.REVISION.BUILDDATE + SvnGenerateVersion.bat update the REVISION and BUILDDATE field of the template. If want to change the MAJOR(or MINOR) of the version, + you need to modify the svn_version.template before generate the version file. diff --git a/tool/version_generation/svn_generate_version.bat b/tool/version_generation/svn_generate_version.bat new file mode 100644 index 0000000..e7064ea --- /dev/null +++ b/tool/version_generation/svn_generate_version.bat @@ -0,0 +1,18 @@ +@ECHO OFF +SETLOCAL ENABLEEXTENSIONS + +::----------------------------- +::Initialize script arguments +::----------------------------- +SET workDir=./ +SET template=svn_version.template +SET target=version.h + +::----------------------------- +:: Main entry +::----------------------------- + +"SubWCRev.exe" %workDir% %template% %target% >NUL +type %target% + +@ECHO ON diff --git a/tool/version_generation/svn_version.template b/tool/version_generation/svn_version.template new file mode 100644 index 0000000..ec08879 --- /dev/null +++ b/tool/version_generation/svn_version.template @@ -0,0 +1,9 @@ +#define VERSION_MAJOR 1 +#define VERSION_MINOR 1 +#define VERSION_REVISION $WCREV$ +#define VERSION_BUILD $WCDATE=%Y%m%d$ +#define NUM4STR(a,b,c,d) #a "." #b "." #c "." #d +#define VERSIONBUILDSTR(a,b,c,d) NUM4STR(a,b,c,d) +#define VERSION_BUILD_STR VERSIONBUILDSTR(VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILD) +#define SRC_TIME "$WCDATE$" +#define BUILDING_TIME "$WCNOW$"